Migrate KD subsystem to C++
This commit is contained in:
@@ -28,9 +28,8 @@ list(APPEND XTOSKRNL_SOURCE
|
|||||||
${XTOSKRNL_SOURCE_DIR}/hl/fbdev.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/fbdev.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/init.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/init.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/hl/ioreg.cc
|
${XTOSKRNL_SOURCE_DIR}/hl/ioreg.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/kd/dbginit.c
|
${XTOSKRNL_SOURCE_DIR}/kd/data.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.c
|
${XTOSKRNL_SOURCE_DIR}/kd/dbgio.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/kd/globals.c
|
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/irq.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/krnlinit.cc
|
||||||
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
|
${XTOSKRNL_SOURCE_DIR}/ke/${ARCH}/kthread.cc
|
||||||
|
16
xtoskrnl/includes/kd.hh
Normal file
16
xtoskrnl/includes/kd.hh
Normal file
@@ -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 <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTOSKRNL_KD_HH
|
||||||
|
#define __XTOSKRNL_KD_HH
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
#include <kd/dbgio.hh>
|
||||||
|
|
||||||
|
#endif /* __XTOSKRNL_KD_HH */
|
40
xtoskrnl/includes/kd/dbgio.hh
Normal file
40
xtoskrnl/includes/kd/dbgio.hh
Normal file
@@ -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 <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __XTOSKRNL_KD_DBGIO_HH
|
||||||
|
#define __XTOSKRNL_KD_DBGIO_HH
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/* 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 */
|
@@ -21,7 +21,7 @@ namespace KE
|
|||||||
STATIC PKERNEL_INITIALIZATION_BLOCK InitializationBlock;
|
STATIC PKERNEL_INITIALIZATION_BLOCK InitializationBlock;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
STATIC XTAPI PVOID GetDebugPrint(VOID);
|
STATIC XTAPI PKD_PRINT_ROUTINE GetDebugPrint(VOID);
|
||||||
STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID);
|
STATIC XTAPI SYSTEM_FIRMWARE_TYPE GetFirmwareType(VOID);
|
||||||
STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName,
|
STATIC XTAPI XTSTATUS GetKernelParameter(IN PCWSTR ParameterName,
|
||||||
OUT PCWSTR *Parameter);
|
OUT PCWSTR *Parameter);
|
||||||
|
@@ -29,6 +29,7 @@ extern "C" {
|
|||||||
#include <ar.hh>
|
#include <ar.hh>
|
||||||
#include <ex.hh>
|
#include <ex.hh>
|
||||||
#include <hl.hh>
|
#include <hl.hh>
|
||||||
|
#include <kd.hh>
|
||||||
#include <ke.hh>
|
#include <ke.hh>
|
||||||
#include <po.hh>
|
#include <po.hh>
|
||||||
#include <rtl.hh>
|
#include <rtl.hh>
|
||||||
|
31
xtoskrnl/kd/data.cc
Normal file
31
xtoskrnl/kd/data.cc
Normal file
@@ -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 <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/* 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;
|
@@ -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 <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
}
|
|
@@ -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 <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.h>
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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]);
|
|
||||||
}
|
|
358
xtoskrnl/kd/dbgio.cc
Normal file
358
xtoskrnl/kd/dbgio.cc
Normal file
@@ -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 <harraiken91@gmail.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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]);
|
||||||
|
}
|
@@ -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 <harraiken91@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <xtos.h>
|
|
||||||
|
|
||||||
|
|
||||||
/* 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;
|
|
@@ -10,10 +10,10 @@
|
|||||||
|
|
||||||
|
|
||||||
XTAPI
|
XTAPI
|
||||||
PVOID
|
PKD_PRINT_ROUTINE
|
||||||
KE::BootInformation::GetDebugPrint(VOID)
|
KE::BootInformation::GetDebugPrint(VOID)
|
||||||
{
|
{
|
||||||
return InitializationBlock->LoaderInformation.DbgPrint;
|
return (PKD_PRINT_ROUTINE)InitializationBlock->LoaderInformation.DbgPrint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -42,7 +42,7 @@ KeStartXtSystem(IN PKERNEL_INITIALIZATION_BLOCK Parameters)
|
|||||||
if(DEBUG && BootInformation::GetDebugPrint())
|
if(DEBUG && BootInformation::GetDebugPrint())
|
||||||
{
|
{
|
||||||
/* Use loader's provided DbgPrint() routine for early printing to serial console */
|
/* 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);
|
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)
|
if(DEBUG)
|
||||||
{
|
{
|
||||||
/* Initialize debug I/O */
|
/* Initialize debug I/O */
|
||||||
KdInitializeDebugIoProviders();
|
KD::DebugIo::InitializeDebugIoProviders();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Announce kernel startup */
|
/* Announce kernel startup */
|
||||||
|
Reference in New Issue
Block a user