Refactor part 5; Implement debugging ports
All checks were successful
Builds / ExectOS (amd64) (push) Successful in 25s
Builds / ExectOS (i686) (push) Successful in 24s

This commit is contained in:
Rafal Kupiec 2023-12-03 23:18:49 +01:00
parent 6a03db6fcd
commit 5131a682b8
Signed by: belliash
GPG Key ID: 4E829243E0CFE6B4
7 changed files with 381 additions and 41 deletions

View File

@ -10,6 +10,8 @@ include_directories(
list(APPEND XTLDR_SOURCE
${XTLDR_SOURCE_DIR}/config.c
${XTLDR_SOURCE_DIR}/console.c
${XTLDR_SOURCE_DIR}/debug.c
${XTLDR_SOURCE_DIR}/efiutils.c
${XTLDR_SOURCE_DIR}/globals.c
${XTLDR_SOURCE_DIR}/hardware.c
${XTLDR_SOURCE_DIR}/memory.c

View File

@ -52,27 +52,6 @@ BlConsoleEnableCursor()
EfiSystemTable->ConOut->EnableCursor(EfiSystemTable->ConOut, TRUE);
}
/**
* This routine initializes the EFI console.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlConsoleInitialize()
{
/* Clear console buffers */
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE);
EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE);
EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE);
/* Clear screen and enable cursor */
BlConsoleClearScreen();
BlConsoleEnableCursor();
}
/**
* This routine formats the input string and prints it out to the stdout and serial console.
*
@ -99,10 +78,42 @@ BlConsolePrint(IN PUINT16 Format,
/* Format and print the string to the stdout */
BlpStringPrint(BlpConsolePrintChar, Format, Arguments);
/* Print to serial console only if not running under OVMF */
if(RtlWideStringCompare(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0)
{
/* Check if debugging enabled and if EFI serial port is fully initialized */
if(DEBUG && (BlpSerialPort.Flags & COMPORT_FLAG_INIT))
{
/* Format and print the string to the serial console */
BlpStringPrint(BlpDebugPutChar, Format, Arguments);
}
}
/* Clean up the va_list */
VA_END(Arguments);
}
/**
* This routine initializes the EFI console.
*
* @return This routine returns status code.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlpConsoleInitialize()
{
/* Clear console buffers */
EfiSystemTable->ConIn->Reset(EfiSystemTable->ConIn, TRUE);
EfiSystemTable->ConOut->Reset(EfiSystemTable->ConOut, TRUE);
EfiSystemTable->StdErr->Reset(EfiSystemTable->StdErr, TRUE);
/* Clear screen and enable cursor */
BlConsoleClearScreen();
BlConsoleEnableCursor();
}
/**
* Writes a character to the default EFI console.
*

260
xtldr2/debug.c Normal file
View File

@ -0,0 +1,260 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/debug.c
* DESCRIPTION: XT Boot Loader debugging support
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtldr.h>
/**
* This routine formats the input string and prints it out to the debug ports.
*
* @param Format
* The formatted string that is to be written to the output.
*
* @param ...
* Depending on the format string, this routine might expect a sequence of additional arguments.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlDebugPrint(IN PUINT16 Format,
IN ...)
{
VA_LIST Arguments;
/* Check if debugging enabled and if EFI serial port is fully initialized */
if(DEBUG)
{
/* Initialise the va_list */
VA_START(Arguments, Format);
/* Check if serial debug port is enabled */
if((BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpSerialPort.Flags & COMPORT_FLAG_INIT))
{
/* Format and print the string to the serial console */
BlpStringPrint(BlpDebugPutChar, Format, Arguments);
}
/* Check if screen debug port is enabled and Boot Services are still available */
if((BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SCREEN) && (EfiSystemTable->BootServices != 0))
{
/* Format and print the string to the screen */
BlpStringPrint(BlpConsolePrintChar, Format, Arguments);
}
/* Clean up the va_list */
VA_END(Arguments);
}
}
/**
* This routine initializes the serial debug console.
*
* @param PortNumber
* Supplies a port number.
*
* @param PortAddress
* Supplies an address of the COM port.
*
* @param BaudRate
* Supplies an optional port baud rate.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlpDebugInitializeComPort(IN ULONG PortNumber,
IN ULONG PortAddress,
IN ULONG BaudRate)
{
EFI_STATUS EfiStatus;
XTSTATUS Status;
/* Print debug message depending on port settings */
if(PortAddress)
{
BlConsolePrint(L"Initializing serial console at COM port address: 0x%lx\n", PortAddress);
}
else
{
BlConsolePrint(L"Initializing serial console at port COM%d\n", PortNumber);
}
/* Initialize COM port */
Status = HlInitializeComPort(&BlpSerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate);
/* Port not found under supplied address */
if(Status == STATUS_NOT_FOUND && PortAddress)
{
/* This might be PCI(E) serial controller, try to activate I/O space access first */
EfiStatus = BlpActivateSerialIOController();
if(EfiStatus == STATUS_EFI_SUCCESS)
{
/* Try to reinitialize COM port */
BlConsolePrint(L"Enabled I/O space access for all PCI(E) serial controllers found\n");
Status = HlInitializeComPort(&BlpSerialPort, PortNumber, UlongToPtr(PortAddress), BaudRate);
}
}
/* Check COM port initialization status code */
if(Status != STATUS_SUCCESS)
{
/* Serial port initialization failed, mark as not ready */
return STATUS_EFI_NOT_READY;
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* This routine initializes the XTLDR debug console.
*
* @return This routine returns a status code.
*
* @since XT 1.0
*/
XTCDECL
EFI_STATUS
BlpDebugInitializeConsole()
{
ULONG PortAddress, PortNumber, BaudRate;
PWCHAR DebugPort, LastPort;
EFI_STATUS Status;
/* Set default serial port options */
PortAddress = 0;
PortNumber = 0;
BaudRate = 0;
/* Make sure any debug options are provided */
if(BlpConfiguration.Debug)
{
/* Find all debug ports */
DebugPort = RtlWideStringTokenize(BlpConfiguration.Debug, L";", &LastPort);
/* Iterate over all debug ports */
while(DebugPort != NULL)
{
/* Check what port is set for debugging */
if(RtlWideStringCompare(DebugPort, L"COM", 3) == 0)
{
/* Read COM port number */
DebugPort += 3;
while(*DebugPort >= '0' && *DebugPort <= '9')
{
/* Get port number */
PortNumber *= 10;
PortNumber += *DebugPort - '0';
DebugPort++;
}
/* Check if custom COM port address supplied */
if(PortNumber == 0 && RtlWideStringCompare(DebugPort, L":0x", 3) == 0)
{
/* COM port address provided */
DebugPort += 3;
while((*DebugPort >= '0' && *DebugPort <= '9') ||
(*DebugPort >= 'A' && *DebugPort <= 'F') ||
(*DebugPort >= 'a' && *DebugPort <= 'f'))
{
/* Get port address */
PortAddress *= 16;
if(*DebugPort >= '0' && *DebugPort <= '9')
{
PortAddress += *DebugPort - '0';
}
else if(*DebugPort >= 'A' && *DebugPort <= 'F')
{
PortAddress += *DebugPort - 'A' + 10;
}
else if(*DebugPort >= 'a' && *DebugPort <= 'f')
{
PortAddress += *DebugPort - 'a' + 10;
}
DebugPort++;
}
}
/* Look for additional COM port parameters */
if(*DebugPort == ',')
{
/* Baud rate provided */
DebugPort++;
while(*DebugPort >= '0' && *DebugPort <= '9')
{
/* Get baud rate */
BaudRate *= 10;
BaudRate += *DebugPort - '0';
DebugPort++;
}
}
/* Enable debug port */
BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SERIAL;
}
else if(RtlWideStringCompare(DebugPort, L"SCREEN", 5) == 0)
{
/* Enable debug port */
BlpConfiguration.DebugPort |= XTBL_DEBUGPORT_SCREEN;
}
else
{
/* Unsupported debug port specified */
BlConsolePrint(L"ERROR: Unsupported debug port ('%S') specified\n", DebugPort);
BlSleepExecution(3000);
}
/* Take next debug port */
DebugPort = RtlWideStringTokenize(NULL, L";", &LastPort);
}
}
/* Check if serial debug port is enabled */
if(BlpConfiguration.DebugPort & XTBL_DEBUGPORT_SERIAL)
{
/* Try to initialize COM port */
Status = BlpDebugInitializeComPort(PortNumber, PortAddress, BaudRate);
if(Status != STATUS_EFI_SUCCESS)
{
/* Remove serial debug port, as COM port initialization failed and return */
BlpConfiguration.DebugPort &= ~XTBL_DEBUGPORT_SERIAL;
return Status;
}
}
/* Return success */
return STATUS_EFI_SUCCESS;
}
/**
* Writes a character to the serial console.
*
* @param Character
* The integer promotion of the character to be written.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlpDebugPutChar(IN USHORT Character)
{
USHORT Buffer[2];
/* Write character to the serial console */
Buffer[0] = Character;
Buffer[1] = 0;
HlComPortPutByte(&BlpSerialPort, Buffer[0]);
}

27
xtldr2/efiutils.c Normal file
View File

@ -0,0 +1,27 @@
/**
* PROJECT: ExectOS
* COPYRIGHT: See COPYING.md in the top level directory
* FILE: xtldr/efiutils.c
* DESCRIPTION: EFI related routines for XT Boot Loader
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
*/
#include <xtldr.h>
/**
* Puts the system to sleep for the specified number of milliseconds.
*
* @param Milliseconds
* Supplies the number of milliseconds to sleep.
*
* @return This routine does not return any value.
*
* @since XT 1.0
*/
XTCDECL
VOID
BlSleepExecution(IN ULONG_PTR Milliseconds)
{
EfiSystemTable->BootServices->Stall(Milliseconds * 1000);
}

View File

@ -18,7 +18,7 @@
*/
XTCDECL
EFI_STATUS
BlpHwActivateSerialIOController()
BlpActivateSerialIOController()
{
EFI_GUID PciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
PEFI_PCI_ROOT_BRIDGE_IO_PROTOCOL PciDev;

View File

@ -15,17 +15,17 @@
/* XTLDR routine callbacks */
typedef VOID (BMPRINTCHAR)(IN USHORT Character);
/* XTLDR routines forward references */
XTCDECL
EFI_STATUS
BlMemoryAllocatePages(IN UINT64 Pages,
OUT PEFI_PHYSICAL_ADDRESS Memory);
OUT PEFI_PHYSICAL_ADDRESS Memory);
XTCDECL
EFI_STATUS
BlMemoryAllocatePool(IN UINT_PTR Size,
OUT PVOID *Memory);
OUT PVOID *Memory);
/* XTLDR routines forward references */
XTCDECL
VOID
BlConsoleClearScreen();
@ -38,40 +38,67 @@ XTCDECL
VOID
BlConsoleEnableCursor();
XTCDECL
VOID
BlConsolePrint(IN PUINT16 Format,
IN ...);
XTCDECL
VOID
BlDebugPrint(IN PUINT16 Format,
IN ...);
XTCDECL
EFI_STATUS
BlMemoreFreePages(IN UINT64 Pages,
IN EFI_PHYSICAL_ADDRESS Memory);
IN EFI_PHYSICAL_ADDRESS Memory);
XTCDECL
EFI_STATUS
BlMemoryFreePool(IN PVOID Memory);
XTCDECL
VOID
BlSleepExecution(IN ULONG_PTR Milliseconds);
XTCDECL
EFI_STATUS
BlStartXtLoader(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
XTCDECL
EFI_STATUS
BlpActivateSerialIOController();
XTCDECL
VOID
BlConsoleInitialize();
BlpConfigParseCommandLine(VOID);
XTCDECL
VOID
BlConsolePrint(IN PUINT16 Format,
IN ...);
BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options);
XTCDECL
VOID
BlpConsoleInitialize();
XTCDECL
VOID
BlpConsolePrintChar(IN USHORT Character);
XTCDECL
VOID
BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine,
IN PUINT16 Format,
IN VA_LIST Arguments);
EFI_STATUS
BlpDebugInitializeComPort(IN ULONG PortNumber,
IN ULONG PortAddress,
IN ULONG BaudRate);
XTCDECL
EFI_STATUS
BmStartXtLoader(IN EFI_HANDLE ImageHandle,
IN PEFI_SYSTEM_TABLE SystemTable);
BlpDebugInitializeConsole();
XTCDECL
VOID
BlpDebugPutChar(IN USHORT Character);
XTCDECL
VOID
@ -81,7 +108,9 @@ BlpStringFormat(IN BMPRINTCHAR PrintCharRoutine,
XTCDECL
VOID
BlpConfigParseCommandLine(VOID);
BlpStringPrint(IN IN BMPRINTCHAR PrintCharRoutine,
IN PUINT16 Format,
IN VA_LIST Arguments);
XTCDECL
VOID
@ -113,8 +142,4 @@ XTCDECL
UINT64
BlpStringReadPadding(IN PUINT16 *Format);
XTCDECL
VOID
BlpConfigUpdateGlobalConfiguration(IN PWCHAR Options);
#endif /* __XTLDR_BOOTMAN_H */

View File

@ -34,9 +34,24 @@ BlStartXtLoader(IN EFI_HANDLE ImageHandle,
EfiSystemTable = SystemTable;
/* Initialize UEFI console and early print XTLDR version */
BlConsoleInitialize();
BlpConsoleInitialize();
BlConsolePrint(L"XTLDR boot loader v%s\n", XTOS_VERSION);
/* Parse configuration options passed from UEFI shell */
BlpConfigParseCommandLine();
/* Attempt to early initialize debug console */
if(DEBUG)
{
Status = BlpDebugInitializeConsole();
if(Status != STATUS_EFI_SUCCESS)
{
/* Initialization failed, notify user on stdout */
BlConsolePrint(L"ERROR: Failed to initialize debug console\n");
BlSleepExecution(3000);
}
}
/* Temporary infinite loop */
for(;;);