diff options
| author | Amlal El Mahrouss <amlal@nekernel.org> | 2025-05-02 19:38:46 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2025-05-02 19:38:46 +0200 |
| commit | 997be16e5ac9a68d54882ab69529815860d62955 (patch) | |
| tree | 19d6129c2d776bb1edc5d4a7325e39ca176c3403 /dev/kernel/HALKit/AMD64/HalDebugOutput.cc | |
| parent | 618104e74c195d7508a18450524f8ed7f9af8cc6 (diff) | |
| parent | b3b4b1ebdcd6adeac914869017c86d892b7a8ced (diff) | |
Merge pull request #28 from nekernel-org/dev
0.0.2
Diffstat (limited to 'dev/kernel/HALKit/AMD64/HalDebugOutput.cc')
| -rw-r--r-- | dev/kernel/HALKit/AMD64/HalDebugOutput.cc | 287 |
1 files changed, 146 insertions, 141 deletions
diff --git a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc index b69614fd..34b99ffe 100644 --- a/dev/kernel/HALKit/AMD64/HalDebugOutput.cc +++ b/dev/kernel/HALKit/AMD64/HalDebugOutput.cc @@ -1,188 +1,193 @@ /* ------------------------------------------- - Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. + Copyright (C) 2024-2025, Amlal El Mahrouss, all rights reserved. ------------------------------------------- */ #include <ArchKit/ArchKit.h> #include <KernelKit/DebugOutput.h> -#include <NewKit/Utils.h> #include <NewKit/New.h> +#include <NewKit/Utils.h> #include <modules/CoreGfx/CoreGfx.h> #include <modules/CoreGfx/TextGfx.h> -namespace Kernel -{ - enum CommStatus : UInt16 - { - kStateInvalid, - kStateReady = 0xCF, - kStateTransmit = 0xFC, - kStateCnt = 3 - }; - - namespace Detail - { - constexpr const UInt16 kPort = 0x3F8; - static UInt16 kState = kStateInvalid; - - /// @brief Init COM1. - /// @return - template <Int16 PORT> - bool hal_serial_init() noexcept - { - if (kState == kStateReady || kState == kStateTransmit) - return true; - - HAL::rt_out8(PORT + 1, 0x00); // Disable all interrupts - HAL::rt_out8(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) - HAL::rt_out8(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud - HAL::rt_out8(PORT + 1, 0x00); // (hi byte) - HAL::rt_out8(PORT + 3, 0x03); // 8 bits, no parity, one stop bit - HAL::rt_out8(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold - HAL::rt_out8(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set - HAL::rt_out8(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip - HAL::rt_out8(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if - // serial returns same byte) - - // Check if serial is faulty (i.e: not same byte as sent) - if (HAL::rt_in8(PORT) != 0xAE) - { - return false; - } - - kState = kStateReady; - - // If serial is not faulty set it in normal operation mode - // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) - HAL::rt_out8(PORT + 4, 0x0F); - - return true; - } - } // namespace Detail - - TerminalDevice::~TerminalDevice() = default; - - EXTERN_C void ke_io_write(IDeviceObject<const Char*>* obj, const Char* bytes) - { - NE_UNUSED(obj); +namespace Kernel { +enum CommStatus : UInt16 { + kStateInvalid = 0x64, + kStateReady = 0xCF, + kStateTransmit = 0xFC, + kStateCnt = 3 +}; + +namespace Detail { + constexpr ATTRIBUTE(unused) const UInt16 kPort = 0x3F8; + STATIC ATTRIBUTE(unused) UInt16 kState = kStateInvalid; + + /// @brief Init COM1. + /// @return + template <UInt16 PORT> + bool hal_serial_init() noexcept { + if (kState == kStateReady || kState == kStateTransmit) return true; + + HAL::rt_out8(PORT + 1, 0x00); // Disable all interrupts + HAL::rt_out8(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) + HAL::rt_out8(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud + HAL::rt_out8(PORT + 1, 0x00); // (hi byte) + HAL::rt_out8(PORT + 3, 0x03); // 8 bits, no parity, one stop bit + HAL::rt_out8(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold + HAL::rt_out8(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set + HAL::rt_out8(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip + HAL::rt_out8(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if + // serial returns same byte) + + // Check if serial is faulty (i.e: not same byte as sent) + if (HAL::rt_in8(PORT) != 0xAE) { + return false; + } + + kState = kStateReady; + + // If serial is not faulty set it in normal operation mode + // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) + HAL::rt_out8(PORT + 4, 0x0F); + + return true; + } +} // namespace Detail + +TerminalDevice::~TerminalDevice() = default; + +EXTERN_C void ke_io_write(IDeviceObject<const Char*>* obj, const Char* bytes) { + NE_UNUSED(bytes); + NE_UNUSED(obj); #ifdef __DEBUG__ - Detail::hal_serial_init<Detail::kPort>(); + Detail::hal_serial_init<Detail::kPort>(); + + if (!bytes || Detail::kState != kStateReady) return; - if (!bytes || Detail::kState != kStateReady) - return; + if (*bytes == 0) return; - if (*bytes == 0) - return; + Detail::kState = kStateTransmit; - Detail::kState = kStateTransmit; + SizeT index = 0; + SizeT len = 0; - SizeT index = 0; - SizeT len = 0; + index = 0; + len = rt_string_len(bytes, 256U); - index = 0; - len = rt_string_len(bytes, 256U); + static SizeT x = kFontSizeX, y = kFontSizeY; - static SizeT x = kFontSizeX, y = kFontSizeY; + static BOOL not_important = YES; - static BOOL not_important = YES; + while (index < len) { + if (bytes[index] == '\r') HAL::rt_out8(Detail::kPort, '\r'); - while (index < len) - { - if (bytes[index] == '\r') - HAL::rt_out8(Detail::kPort, '\r'); + HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]); - HAL::rt_out8(Detail::kPort, bytes[index] == '\r' ? '\n' : bytes[index]); + char tmp_str[2]; + tmp_str[0] = bytes[index]; + tmp_str[1] = 0; - char tmp_str[2]; - tmp_str[0] = bytes[index]; - tmp_str[1] = 0; + if (bytes[index] == '*') { + if (not_important) + not_important = NO; + else + not_important = YES; - if (bytes[index] == '*') - { - if (not_important) - not_important = NO; - else - not_important = YES; + ++index; - ++index; + continue; + } - continue; - } + fb_render_string(tmp_str, y, x, not_important ? RGB(0xff, 0xff, 0xff) : RGB(0x00, 0x00, 0xff)); - fb_render_string(tmp_str, y, x, not_important ? RGB(0xff, 0xff, 0xff) : RGB(0x00, 0x00, 0xff)); + if (bytes[index] == '\r') { + y += kFontSizeY; + x = kFontSizeX; + } - if (bytes[index] == '\r') - { - y += kFontSizeY; - x = kFontSizeX; - } + x += kFontSizeX; - x += kFontSizeX; + if (x > kHandoverHeader->f_GOP.f_Width) { + x = kFontSizeX; + } - if (y > kHandoverHeader->f_GOP.f_Height) - { - y = kFontSizeY; + if (y > kHandoverHeader->f_GOP.f_Height) { + y = kFontSizeY; - FBDrawInRegion(fb_get_clear_clr(), FB::FBAccessibilty::Height(), FB::FBAccessibilty::Width(), - 0, 0); - } + FBDrawInRegion(fb_get_clear_clr(), FB::FBAccessibilty::Height(), FB::FBAccessibilty::Width(), + 0, 0); + } - ++index; - } + ++index; + } - Detail::kState = kStateReady; -#endif // __DEBUG__ - } + Detail::kState = kStateReady; +#endif // __DEBUG__ +} + +EXTERN_C void ke_io_read(IDeviceObject<const Char*>*, const Char* bytes) { + NE_UNUSED(bytes); - EXTERN_C void ke_io_read(IDeviceObject<const Char*>*, const Char* bytes) - { #ifdef __DEBUG__ - Detail::hal_serial_init<Detail::kPort>(); + Detail::hal_serial_init<Detail::kPort>(); + + if (!bytes || Detail::kState != kStateReady) return; + + Detail::kState = kStateTransmit; + + SizeT index = 0; + + ///! TODO: Look on how to wait for the UART to complete. + while (true) { + auto in = HAL::rt_in8(Detail::kPort); + + ///! If enter pressed then break. + if (in == 0xD) { + break; + } - if (!bytes || Detail::kState != kStateReady) - return; + if (in < '0' || in < 'A' || in < 'a') { + if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || in != ':') { + continue; + } + } - Detail::kState = kStateTransmit; + ((char*) bytes)[index] = in; - SizeT index = 0; + ++index; + } - ///! TODO: Look on how to wait for the UART to complete. - while (true) - { - auto in = HAL::rt_in8(Detail::kPort); + ((char*) bytes)[index] = 0; - ///! If enter pressed then break. - if (in == 0xD) - { - break; - } + Detail::kState = kStateReady; +#endif // __DEBUG__ +} - if (in < '0' || in < 'A' || in < 'a') - { - if (in != '@' || in != '!' || in != '?' || in != '.' || in != '/' || - in != ':') - { - continue; - } - } +TerminalDevice TerminalDevice::The() noexcept { + TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); + return out; +} - ((char*)bytes)[index] = in; +Utf8TerminalDevice::~Utf8TerminalDevice() = default; - ++index; - } +STATIC Void ke_io_write_utf(IDeviceObject<const Utf8Char*>*, const Utf8Char* str) { + auto len = urt_string_len(str); - ((char*)bytes)[index] = 0; + for (auto size = 0ul; size < len; ++size) { + Char buf[2]; + buf[0] = str[size]; + buf[1] = 0; - Detail::kState = kStateReady; -#endif // __DEBUG__ - } + Kernel::ke_io_write(nullptr, buf); + } +} - TerminalDevice TerminalDevice::The() noexcept - { - TerminalDevice out(Kernel::ke_io_write, Kernel::ke_io_read); - return out; - } +Utf8TerminalDevice Utf8TerminalDevice::The() noexcept { + Utf8TerminalDevice out(Kernel::ke_io_write_utf, + [](IDeviceObject<const Utf8Char*>*, const Utf8Char*) -> Void {}); + return out; +} -} // namespace Kernel +} // namespace Kernel |
