diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index c283f05..f8d613a 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -28,9 +28,8 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/hl/fbdev.cc ${XTOSKRNL_SOURCE_DIR}/hl/init.cc ${XTOSKRNL_SOURCE_DIR}/hl/ioreg.cc - ${XTOSKRNL_SOURCE_DIR}/kd/dbginit.c - ${XTOSKRNL_SOURCE_DIR}/kd/dbgio.c - ${XTOSKRNL_SOURCE_DIR}/kd/globals.c + ${XTOSKRNL_SOURCE_DIR}/kd/data.cc + ${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc ${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc diff --git a/xtoskrnl/includes/kd.hh b/xtoskrnl/includes/kd.hh new file mode 100644 index 0000000..e7deaf1 --- /dev/null +++ b/xtoskrnl/includes/kd.hh @@ -0,0 +1,16 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/kd.hh + * DESCRIPTION: Kernel Debugger + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KD_HH +#define __XTOSKRNL_KD_HH + +#include + +#include + +#endif /* __XTOSKRNL_KD_HH */ diff --git a/xtoskrnl/includes/kd/dbgio.hh b/xtoskrnl/includes/kd/dbgio.hh new file mode 100644 index 0000000..923a15f --- /dev/null +++ b/xtoskrnl/includes/kd/dbgio.hh @@ -0,0 +1,40 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/includes/kd/dbgio.hh + * DESCRIPTION: + * DEVELOPERS: Aiken Harris + */ + +#ifndef __XTOSKRNL_KD_DBGIO_HH +#define __XTOSKRNL_KD_DBGIO_HH + +#include + + +/* Kernel Debugger */ +namespace KD +{ + class DebugIo + { + private: + STATIC KD_DEBUG_MODE DebugMode; + STATIC PKD_INIT_ROUTINE IoProvidersInitRoutines[KDBG_PROVIDERS_COUNT]; + STATIC LIST_ENTRY Providers; + STATIC CPPORT SerialPort; + STATIC ULONG SerialPortList[COMPORT_COUNT]; + + public: + STATIC XTCDECL VOID DbgPrint(PCWSTR Format, ...); + STATIC XTAPI XTSTATUS InitializeDebugIoProviders(VOID); + STATIC XTAPI VOID SetPrintRoutine(PKD_PRINT_ROUTINE DebugPrintRoutine); + + private: + STATIC XTAPI XTSTATUS DetectDebugPorts(VOID); + STATIC XTAPI XTSTATUS InitializeFrameBufferProvider(VOID); + STATIC XTAPI XTSTATUS InitializeSerialPortProvider(VOID); + STATIC XTCDECL XTSTATUS SerialWriteCharacter(WCHAR Character); + }; +} + +#endif /* __XTOSKRNL_KD_DBGIO_HH */ diff --git a/xtoskrnl/includes/ke/bootinfo.hh b/xtoskrnl/includes/ke/bootinfo.hh index 61df1d8..a65a0da 100644 --- a/xtoskrnl/includes/ke/bootinfo.hh +++ b/xtoskrnl/includes/ke/bootinfo.hh @@ -21,7 +21,7 @@ namespace KE STATIC PKERNEL_INITIALIZATION_BLOCK InitializationBlock; public: - STATIC XTAPI PVOID GetDebugPrint(VOID); + STATIC XTAPI PKD_PRINT_ROUTINE GetDebugPrint(VOID); STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID); STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName, OUT PCWSTR *Parameter); diff --git a/xtoskrnl/includes/xtos.hh b/xtoskrnl/includes/xtos.hh index ed508ca..3a28f57 100644 --- a/xtoskrnl/includes/xtos.hh +++ b/xtoskrnl/includes/xtos.hh @@ -29,6 +29,7 @@ extern "C" { #include #include #include +#include #include #include #include diff --git a/xtoskrnl/kd/data.cc b/xtoskrnl/kd/data.cc new file mode 100644 index 0000000..21b1bbb --- /dev/null +++ b/xtoskrnl/kd/data.cc @@ -0,0 +1,31 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/kd/globals.cc + * DESCRIPTION: Kernel Debugger global and static data + * DEVELOPERS: Aiken Harris + */ + +#include + + +/* Pointer to DbgPrint() routine */ +PKD_PRINT_ROUTINE KdPrint = nullptr; + +/* Kernel Debugger mode */ +KD_DEBUG_MODE KD::DebugIo::DebugMode; + +/* Debugger I/O providers initialization routines */ +PKD_INIT_ROUTINE KD::DebugIo::IoProvidersInitRoutines[KDBG_PROVIDERS_COUNT] = { + InitializeFrameBufferProvider, + InitializeSerialPortProvider +}; + +/* List of active I/O providers */ +LIST_ENTRY KD::DebugIo::Providers; + +/* Debugger's serial port handle */ +CPPORT KD::DebugIo::SerialPort; + +/* Pre-defined serial port addresses */ +ULONG KD::DebugIo::SerialPortList[COMPORT_COUNT] = COMPORT_ADDRESS; diff --git a/xtoskrnl/kd/dbginit.c b/xtoskrnl/kd/dbginit.c deleted file mode 100644 index a1b598b..0000000 --- a/xtoskrnl/kd/dbginit.c +++ /dev/null @@ -1,192 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/kd/dbginit.c - * DESCRIPTION: Kernel Debugger initialization - * DEVELOPERS: Aiken Harris - */ - -#include - - -/** - * Initializes the kernel's debugger I/O providers. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KdInitializeDebugIoProviders(VOID) -{ - ULONG Index; - XTSTATUS ProviderStatus, Status; - - /* Initialize debug providers list */ - RtlInitializeListHead(&KdpProviders); - - RtlZeroMemory(&KdpDebugMode, sizeof(KD_DEBUG_MODE)); - KdpDetectDebugPorts(); - - /* Iterate over providers initialization routines */ - for(Index = 0; Index < KDBG_PROVIDERS_COUNT; Index++) - { - /* Initialize provider */ - ProviderStatus = KdpIoProvidersInitRoutines[Index](); - Status = (Status || ProviderStatus); - } - - /* Initialize debug print routine */ - KdSetPrintRoutine(KdpDebugPrint); - - /* Return status code */ - return Status; -} - -/** - * Configures the kernel's debug print routine by setting a new output handler. - * - * @param DebugPrintRoutine - * Supplies a pointer to the new debug print routine. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTAPI -VOID -KdSetPrintRoutine(PVOID DebugPrintRoutine) -{ - /* Set debug print routine */ - KdPrint = DebugPrintRoutine; -} - -/** - * Detects and enables the kernel's debug ports based on the 'DEBUG' parameter passed to the kernel. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KdpDetectDebugPorts(VOID) -{ - PCWSTR DebugOption; - XTSTATUS Status; - - /* Get debug parameter */ - Status = KeGetKernelParameter(L"DEBUG", &DebugOption); - if(Status != STATUS_SUCCESS) - { - /* Debug parameter not found, disable debugging */ - KdpDebugMode.Enabled = FALSE; - return Status; - } - - /* Skip parameter name and check if it is set */ - DebugOption += 5; - if(*DebugOption != L'=') - { - /* Debug parameter not set, disable debugging */ - KdpDebugMode.Enabled = FALSE; - return STATUS_INVALID_PARAMETER; - } - - /* Skip '=' symbol */ - DebugOption++; - - /* Iterate over all debug ports */ - while(*DebugOption != L'\0' && *DebugOption != L' ') - { - /* Check what port is set for debugging */ - if(RtlCompareWideStringInsensitive(DebugOption, L"COM", 3) == 0) - { - /* Enable serial port debugging mode */ - KdpDebugMode.Mode |= DEBUG_PROVIDER_COMPORT; - - /* Read COM port number */ - DebugOption += 3; - while(*DebugOption >= '0' && *DebugOption <= '9') - { - /* Get port number */ - KdpDebugMode.ComPortNumber *= 10; - KdpDebugMode.ComPortNumber += *DebugOption - '0'; - DebugOption++; - } - - /* Check if custom COM port address supplied */ - if(KdpDebugMode.ComPortNumber == 0 && RtlCompareWideStringInsensitive(DebugOption, L":0x", 3) == 0) - { - /* COM port address provided */ - DebugOption += 3; - while((*DebugOption >= '0' && *DebugOption <= '9') || - (*DebugOption >= 'A' && *DebugOption <= 'F') || - (*DebugOption >= 'a' && *DebugOption <= 'f')) - { - /* Get port address */ - KdpDebugMode.ComPortAddress *= 16; - if(*DebugOption >= '0' && *DebugOption <= '9') - { - KdpDebugMode.ComPortAddress += *DebugOption - '0'; - } - else if(*DebugOption >= 'A' && *DebugOption <= 'F') - { - KdpDebugMode.ComPortAddress += *DebugOption - 'A' + 10; - } - else if(*DebugOption >= 'a' && *DebugOption <= 'f') - { - KdpDebugMode.ComPortAddress += *DebugOption - 'a' + 10; - } - DebugOption++; - } - } - - /* Look for additional COM port parameters */ - if(*DebugOption == ',') - { - /* Baud rate provided */ - DebugOption++; - while(*DebugOption >= '0' && *DebugOption <= '9') - { - /* Get baud rate */ - KdpDebugMode.ComPortBaudRate *= 10; - KdpDebugMode.ComPortBaudRate += *DebugOption - '0'; - DebugOption++; - } - } - } - else if(RtlCompareWideStringInsensitive(DebugOption, L"SCREEN", 6) == 0) - { - /* Enable framebuffer debugging mode */ - KdpDebugMode.Mode |= DEBUG_PROVIDER_FRAMEBUFFER; - DebugOption += 6; - } - else if(*DebugOption == L';') - { - /* Skip separator */ - DebugOption++; - } - else - { - /* Invalid debug option, skip it */ - while(*DebugOption != L'\0' && *DebugOption != L' ' && *DebugOption != L';') - { - /* Advance debug option */ - DebugOption++; - } - - } - } - - /* Ensure at least one debug port is enabled */ - if(KdpDebugMode.Mode != 0) - { - /* Enable debugging */ - KdpDebugMode.Enabled = TRUE; - } - - /* Return success */ - return STATUS_SUCCESS; -} diff --git a/xtoskrnl/kd/dbgio.c b/xtoskrnl/kd/dbgio.c deleted file mode 100644 index 5b6fcfa..0000000 --- a/xtoskrnl/kd/dbgio.c +++ /dev/null @@ -1,175 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/kd/dbgio.c - * DESCRIPTION: Kernel Debugger I/O routines - * DEVELOPERS: Aiken Harris - */ - -#include - - -/** - * Prints a formatted string using the configured debug output providers. - * - * @param Format - * Supplies the format string. - * - * @param ... - * Supplies the variable argument list. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -KdpDebugPrint(PCWSTR Format, ...) -{ - VA_LIST Arguments; - PLIST_ENTRY DispatchTableEntry; - PKD_DISPATCH_TABLE DispatchTable; - - /* Initialise the va_list */ - VA_START(Arguments, Format); - - DispatchTableEntry = KdpProviders.Flink; - while(DispatchTableEntry != &KdpProviders) - { - DispatchTable = CONTAIN_RECORD(DispatchTableEntry, KD_DISPATCH_TABLE, ListEntry); - - RtlFormatWideString(&DispatchTable->PrintContext, (PWCHAR)Format, Arguments); - - DispatchTableEntry = DispatchTableEntry->Flink; - } - - /* Clean up the va_list */ - VA_END(Arguments); -} - -/** - * Initializes the framebuffer device provider for the kernel debugger. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KdpInitializeFrameBufferProvider(VOID) -{ - STATIC KD_DISPATCH_TABLE DispatchTable; - ULONG Height, Width; - - /* Check if framebuffer provider is enabled */ - if(KdpDebugMode.Enabled && (KdpDebugMode.Mode & DEBUG_PROVIDER_FRAMEBUFFER) == 0) - { - /* Screen is not enabled, no need to initialize provider */ - return STATUS_PORT_DISCONNECTED; - } - - /* Ensure frame buffer is initialized and get FB resolution */ - HlInitializeFrameBuffer(); - HlGetFrameBufferResolution(&Width, &Height); - - /* Print debug message */ - DebugPrint(L"Initializing debug console at framebuffer device (%lu x %lu)\n", Width, Height); - - /* Initialize scroll region to full screen and white font color */ - HlInitializeScrollRegion(0, 0, Width - 1, Height - 1, 0xFFFFFFFF); - - /* Initialize screen dispatch table */ - DispatchTable.PrintContext.WriteWideCharacter = HlDisplayCharacter; - RtlInsertHeadList(&KdpProviders, &DispatchTable.ListEntry); - - /* Return success */ - return STATUS_SUCCESS; -} - -/** - * Initializes the serial port device provider for the kernel debugger. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTAPI -XTSTATUS -KdpInitializeSerialPortProvider(VOID) -{ - STATIC KD_DISPATCH_TABLE DispatchTable; - XTSTATUS Status; - - /* Check if serial port provider is enabled */ - if(KdpDebugMode.Enabled && (KdpDebugMode.Mode & DEBUG_PROVIDER_COMPORT) == 0) - { - /* Serial port is not enabled, no need to initialize provider */ - return STATUS_PORT_DISCONNECTED; - } - - /* Check if custom COM port address supplied */ - if(!KdpDebugMode.ComPortAddress) - { - /* We support only a pre-defined number of ports */ - if(KdpDebugMode.ComPortNumber > COMPORT_COUNT) - { - /* Fail if wrong/unsupported port used */ - return STATUS_INVALID_PARAMETER; - } - - /* Check if serial port is set */ - if(KdpDebugMode.ComPortNumber == 0) - { - /* Use COM1 by default */ - KdpDebugMode.ComPortNumber = 1; - } - - /* Set custom port address based on the port number and print debug message */ - KdpDebugMode.ComPortAddress = KdpSerialPortList[KdpDebugMode.ComPortNumber - 1]; - DebugPrint(L"Initializing debug console at serial port (COM%lu, BaudRate: %lu)\n", - KdpDebugMode.ComPortNumber, KdpDebugMode.ComPortBaudRate); - } - else - { - /* Custom port address supplied, print debug message */ - DebugPrint(L"Initializing debug console at serial port (0x%lX, BaudRate: %lu)\n", - KdpDebugMode.ComPortAddress, KdpDebugMode.ComPortBaudRate); - } - - /* Initialize COM port */ - Status = HlInitializeComPort(&KdpSerialPort, UlongToPtr(KdpDebugMode.ComPortAddress), KdpDebugMode.ComPortBaudRate); - if(Status != STATUS_SUCCESS) - { - /* Serial port initialization failed */ - return Status; - } - - /* Initialize serial port dispatch table */ - DispatchTable.PrintContext.WriteWideCharacter = KdpSerialWriteCharacter; - RtlInsertHeadList(&KdpProviders, &DispatchTable.ListEntry); - - /* Return success */ - return STATUS_SUCCESS; -} - -/** - * Writes a character to the serial console. - * - * @param Character - * The integer promotion of the character to be written. - * - * @return This routine returns a status code. - * - * @since XT 1.0 - */ -XTCDECL -XTSTATUS -KdpSerialWriteCharacter(WCHAR Character) -{ - WCHAR Buffer[2]; - - /* Write character to the serial console */ - Buffer[0] = Character; - Buffer[1] = 0; - return HlWriteComPort(&KdpSerialPort, Buffer[0]); -} diff --git a/xtoskrnl/kd/dbgio.cc b/xtoskrnl/kd/dbgio.cc new file mode 100644 index 0000000..b4d71f9 --- /dev/null +++ b/xtoskrnl/kd/dbgio.cc @@ -0,0 +1,358 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/kd/dbgio.cc + * DESCRIPTION: Kernel Debugger I/O routines + * DEVELOPERS: Aiken Harris + */ + +#include + + +/** + * Prints a formatted string using the configured debug output providers. + * + * @param Format + * Supplies the format string. + * + * @param ... + * Supplies the variable argument list. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +KD::DebugIo::DbgPrint(PCWSTR Format, ...) +{ + VA_LIST Arguments; + PLIST_ENTRY DispatchTableEntry; + PKD_DISPATCH_TABLE DispatchTable; + + /* Initialise the va_list */ + VA_START(Arguments, Format); + + DispatchTableEntry = Providers.Flink; + while(DispatchTableEntry != &Providers) + { + DispatchTable = CONTAIN_RECORD(DispatchTableEntry, KD_DISPATCH_TABLE, ListEntry); + + RTL::WideString::FormatWideString(&DispatchTable->PrintContext, (PWCHAR)Format, Arguments); + + DispatchTableEntry = DispatchTableEntry->Flink; + } + + /* Clean up the va_list */ + VA_END(Arguments); +} + +/** + * Detects and enables the kernel's debug ports based on the 'DEBUG' parameter passed to the kernel. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KD::DebugIo::DetectDebugPorts(VOID) +{ + PCWSTR DebugOption; + XTSTATUS Status; + + /* Get debug parameter */ + Status = KE::BootInformation::GetKernelParameter(L"DEBUG", &DebugOption); + if(Status != STATUS_SUCCESS) + { + /* Debug parameter not found, disable debugging */ + DebugMode.Enabled = FALSE; + return Status; + } + + /* Skip parameter name and check if it is set */ + DebugOption += 5; + if(*DebugOption != L'=') + { + /* Debug parameter not set, disable debugging */ + DebugMode.Enabled = FALSE; + return STATUS_INVALID_PARAMETER; + } + + /* Skip '=' symbol */ + DebugOption++; + + /* Iterate over all debug ports */ + while(*DebugOption != L'\0' && *DebugOption != L' ') + { + /* Check what port is set for debugging */ + if(RTL::WideString::CompareWideStringInsensitive(DebugOption, L"COM", 3) == 0) + { + /* Enable serial port debugging mode */ + DebugMode.Mode |= DEBUG_PROVIDER_COMPORT; + + /* Read COM port number */ + DebugOption += 3; + while(*DebugOption >= '0' && *DebugOption <= '9') + { + /* Get port number */ + DebugMode.ComPortNumber *= 10; + DebugMode.ComPortNumber += *DebugOption - '0'; + DebugOption++; + } + + /* Check if custom COM port address supplied */ + if(DebugMode.ComPortNumber == 0 && RTL::WideString::CompareWideStringInsensitive(DebugOption, L":0x", 3) == 0) + { + /* COM port address provided */ + DebugOption += 3; + while((*DebugOption >= '0' && *DebugOption <= '9') || + (*DebugOption >= 'A' && *DebugOption <= 'F') || + (*DebugOption >= 'a' && *DebugOption <= 'f')) + { + /* Get port address */ + DebugMode.ComPortAddress *= 16; + if(*DebugOption >= '0' && *DebugOption <= '9') + { + DebugMode.ComPortAddress += *DebugOption - '0'; + } + else if(*DebugOption >= 'A' && *DebugOption <= 'F') + { + DebugMode.ComPortAddress += *DebugOption - 'A' + 10; + } + else if(*DebugOption >= 'a' && *DebugOption <= 'f') + { + DebugMode.ComPortAddress += *DebugOption - 'a' + 10; + } + DebugOption++; + } + } + + /* Look for additional COM port parameters */ + if(*DebugOption == ',') + { + /* Baud rate provided */ + DebugOption++; + while(*DebugOption >= '0' && *DebugOption <= '9') + { + /* Get baud rate */ + DebugMode.ComPortBaudRate *= 10; + DebugMode.ComPortBaudRate += *DebugOption - '0'; + DebugOption++; + } + } + } + else if(RTL::WideString::CompareWideStringInsensitive(DebugOption, L"SCREEN", 6) == 0) + { + /* Enable framebuffer debugging mode */ + DebugMode.Mode |= DEBUG_PROVIDER_FRAMEBUFFER; + DebugOption += 6; + } + else if(*DebugOption == L';') + { + /* Skip separator */ + DebugOption++; + } + else + { + /* Invalid debug option, skip it */ + while(*DebugOption != L'\0' && *DebugOption != L' ' && *DebugOption != L';') + { + /* Advance debug option */ + DebugOption++; + } + + } + } + + /* Ensure at least one debug port is enabled */ + if(DebugMode.Mode != 0) + { + /* Enable debugging */ + DebugMode.Enabled = TRUE; + } + + /* Return success */ + return STATUS_SUCCESS; +} + +/** + * Initializes the kernel's debugger I/O providers. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KD::DebugIo::InitializeDebugIoProviders(VOID) +{ + ULONG Index; + XTSTATUS ProviderStatus, Status; + + /* Initialize debug providers list */ + RTL::LinkedList::InitializeListHead(&Providers); + + RTL::Memory::ZeroMemory(&DebugMode, sizeof(KD_DEBUG_MODE)); + DetectDebugPorts(); + + /* Iterate over providers initialization routines */ + for(Index = 0; Index < KDBG_PROVIDERS_COUNT; Index++) + { + /* Initialize provider */ + ProviderStatus = IoProvidersInitRoutines[Index](); + Status = (Status || ProviderStatus); + } + + /* Initialize debug print routine */ + SetPrintRoutine((PKD_PRINT_ROUTINE)DbgPrint); + + /* Return status code */ + return Status; +} + +/** + * Initializes the framebuffer device provider for the kernel debugger. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KD::DebugIo::InitializeFrameBufferProvider(VOID) +{ + STATIC KD_DISPATCH_TABLE DispatchTable; + ULONG Height, Width; + + /* Check if framebuffer provider is enabled */ + if(DebugMode.Enabled && (DebugMode.Mode & DEBUG_PROVIDER_FRAMEBUFFER) == 0) + { + /* Screen is not enabled, no need to initialize provider */ + return STATUS_PORT_DISCONNECTED; + } + + /* Ensure frame buffer is initialized and get FB resolution */ + HL::FrameBuffer::InitializeFrameBuffer(); + HL::FrameBuffer::GetFrameBufferResolution(&Width, &Height); + + /* Print debug message */ + DebugPrint(L"Initializing debug console at framebuffer device (%lu x %lu)\n", Width, Height); + + /* Initialize scroll region to full screen and white font color */ + HL::FrameBuffer::InitializeScrollRegion(0, 0, Width - 1, Height - 1, 0xFFFFFFFF); + + /* Initialize screen dispatch table */ + DispatchTable.PrintContext.WriteWideCharacter = HL::FrameBuffer::DisplayCharacter; + RTL::LinkedList::InsertHeadList(&Providers, &DispatchTable.ListEntry); + + /* Return success */ + return STATUS_SUCCESS; +} + +/** + * Initializes the serial port device provider for the kernel debugger. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTAPI +XTSTATUS +KD::DebugIo::InitializeSerialPortProvider(VOID) +{ + STATIC KD_DISPATCH_TABLE DispatchTable; + XTSTATUS Status; + + /* Check if serial port provider is enabled */ + if(DebugMode.Enabled && (DebugMode.Mode & DEBUG_PROVIDER_COMPORT) == 0) + { + /* Serial port is not enabled, no need to initialize provider */ + return STATUS_PORT_DISCONNECTED; + } + + /* Check if custom COM port address supplied */ + if(!DebugMode.ComPortAddress) + { + /* We support only a pre-defined number of ports */ + if(DebugMode.ComPortNumber > COMPORT_COUNT) + { + /* Fail if wrong/unsupported port used */ + return STATUS_INVALID_PARAMETER; + } + + /* Check if serial port is set */ + if(DebugMode.ComPortNumber == 0) + { + /* Use COM1 by default */ + DebugMode.ComPortNumber = 1; + } + + /* Set custom port address based on the port number and print debug message */ + DebugMode.ComPortAddress = SerialPortList[DebugMode.ComPortNumber - 1]; + DebugPrint(L"Initializing debug console at serial port (COM%lu, BaudRate: %lu)\n", + DebugMode.ComPortNumber, DebugMode.ComPortBaudRate); + } + else + { + /* Custom port address supplied, print debug message */ + DebugPrint(L"Initializing debug console at serial port (0x%lX, BaudRate: %lu)\n", + DebugMode.ComPortAddress, DebugMode.ComPortBaudRate); + } + + /* Initialize COM port */ + Status = HL::ComPort::InitializeComPort(&SerialPort, (PUCHAR)UlongToPtr(DebugMode.ComPortAddress), DebugMode.ComPortBaudRate); + if(Status != STATUS_SUCCESS) + { + /* Serial port initialization failed */ + return Status; + } + + /* Initialize serial port dispatch table */ + DispatchTable.PrintContext.WriteWideCharacter = SerialWriteCharacter; + RTL::LinkedList::InsertHeadList(&Providers, &DispatchTable.ListEntry); + + /* Return success */ + return STATUS_SUCCESS; +} + +/** + * Configures the kernel's debug print routine by setting a new output handler. + * + * @param DebugPrintRoutine + * Supplies a pointer to the new debug print routine. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +KD::DebugIo::SetPrintRoutine(PKD_PRINT_ROUTINE DebugPrintRoutine) +{ + /* Set debug print routine */ + KdPrint = DebugPrintRoutine; +} + + +/** + * Writes a character to the serial console. + * + * @param Character + * The integer promotion of the character to be written. + * + * @return This routine returns a status code. + * + * @since XT 1.0 + */ +XTCDECL +XTSTATUS +KD::DebugIo::SerialWriteCharacter(WCHAR Character) +{ + WCHAR Buffer[2]; + + /* Write character to the serial console */ + Buffer[0] = Character; + Buffer[1] = 0; + return HL::ComPort::WriteComPort(&SerialPort, Buffer[0]); +} diff --git a/xtoskrnl/kd/globals.c b/xtoskrnl/kd/globals.c deleted file mode 100644 index cbc86aa..0000000 --- a/xtoskrnl/kd/globals.c +++ /dev/null @@ -1,31 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtoskrnl/kd/globals.c - * DESCRIPTION: Architecture independent global variables related to KD subsystem - * DEVELOPERS: Aiken Harris - */ - -#include - - -/* Pointer to DbgPrint() routine */ -PKD_PRINT_ROUTINE KdPrint = NULL; - -/* Kernel Debugger mode */ -KD_DEBUG_MODE KdpDebugMode; - -/* Debugger I/O providers initialization routines */ -PKD_INIT_ROUTINE KdpIoProvidersInitRoutines[KDBG_PROVIDERS_COUNT] = { - KdpInitializeFrameBufferProvider, - KdpInitializeSerialPortProvider -}; - -/* List of active I/O providers */ -LIST_ENTRY KdpProviders; - -/* Debugger's serial port handle */ -CPPORT KdpSerialPort; - -/* Pre-defined serial port addresses */ -ULONG KdpSerialPortList[COMPORT_COUNT] = COMPORT_ADDRESS; diff --git a/xtoskrnl/ke/bootinfo.cc b/xtoskrnl/ke/bootinfo.cc index 5fde8ff..7b4ed93 100644 --- a/xtoskrnl/ke/bootinfo.cc +++ b/xtoskrnl/ke/bootinfo.cc @@ -10,10 +10,10 @@ XTAPI -PVOID +PKD_PRINT_ROUTINE KE::BootInformation::GetDebugPrint(VOID) { - return InitializationBlock->LoaderInformation.DbgPrint; + return (PKD_PRINT_ROUTINE)InitializationBlock->LoaderInformation.DbgPrint; } /** diff --git a/xtoskrnl/ke/krnlinit.cc b/xtoskrnl/ke/krnlinit.cc index 3b7a1e2..c6e3aeb 100644 --- a/xtoskrnl/ke/krnlinit.cc +++ b/xtoskrnl/ke/krnlinit.cc @@ -42,7 +42,7 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters) if(DEBUG && BootInformation::GetDebugPrint()) { /* Use loader's provided DbgPrint() routine for early printing to serial console */ - KdSetPrintRoutine(BootInformation::GetDebugPrint()); + KD::DebugIo::SetPrintRoutine(BootInformation::GetDebugPrint()); DebugPrint(L"Initializing ExectOS v%d.%d for %s\n", XTOS_VERSION_MAJOR, XTOS_VERSION_MINOR, _ARCH_NAME); } @@ -56,7 +56,7 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters) if(DEBUG) { /* Initialize debug I/O */ - KdInitializeDebugIoProviders(); + KD::DebugIo::InitializeDebugIoProviders(); } /* Announce kernel startup */