From 5de4d7a7f500177fe4538c6d123af52957317a5f Mon Sep 17 00:00:00 2001 From: Rafal Kupiec Date: Thu, 15 Feb 2024 23:32:23 +0100 Subject: [PATCH] Use new string formatting mechanism in the boot loader --- xtldr/CMakeLists.txt | 1 - xtldr/console.c | 23 ++- xtldr/debug.c | 17 +- xtldr/includes/xtldr.h | 45 +---- xtldr/string.c | 444 ----------------------------------------- 5 files changed, 33 insertions(+), 497 deletions(-) delete mode 100644 xtldr/string.c diff --git a/xtldr/CMakeLists.txt b/xtldr/CMakeLists.txt index 3a59a5e..d6437e0 100644 --- a/xtldr/CMakeLists.txt +++ b/xtldr/CMakeLists.txt @@ -25,7 +25,6 @@ list(APPEND XTLDR_SOURCE ${XTLDR_SOURCE_DIR}/memory.c ${XTLDR_SOURCE_DIR}/protocol.c ${XTLDR_SOURCE_DIR}/shell.c - ${XTLDR_SOURCE_DIR}/string.c ${XTLDR_SOURCE_DIR}/textui.c ${XTLDR_SOURCE_DIR}/volume.c ${XTLDR_SOURCE_DIR}/xtldr.c) diff --git a/xtldr/console.c b/xtldr/console.c index 9620297..3578602 100644 --- a/xtldr/console.c +++ b/xtldr/console.c @@ -98,13 +98,18 @@ VOID BlConsolePrint(IN PUSHORT Format, IN ...) { + RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; VA_LIST Arguments; + /* Initialise the print contexts */ + ConsolePrintContext.WriteWideCharacter = BlpConsolePrintChar; + SerialPrintContext.WriteWideCharacter = BlpDebugPutChar; + /* Initialise the va_list */ VA_START(Arguments, Format); /* Format and print the string to the stdout */ - BlpStringPrint(BlpConsolePrintChar, Format, Arguments); + RtlFormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments); /* Print to serial console only if not running under OVMF */ if(RtlCompareWideString(EfiSystemTable->FirmwareVendor, L"EDK II", 6) != 0) @@ -113,7 +118,7 @@ BlConsolePrint(IN PUSHORT Format, if(DEBUG && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT)) { /* Format and print the string to the serial console */ - BlpStringPrint(BlpDebugPutChar, Format, Arguments); + RtlFormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments); } } @@ -281,18 +286,28 @@ BlSetCursorPosition(IN ULONGLONG PosX, * @param Character * The integer promotion of the character to be written. * - * @return This routine does not return any value. + * @return This routine returns a status code. * * @since XT 1.0 */ XTCDECL -VOID +XTSTATUS BlpConsolePrintChar(IN USHORT Character) { USHORT Buffer[2]; + /* Check if character is a newline ('\n') */ + if(Character == L'\n') + { + /* Print carriage return ('\r') as well */ + BlpConsolePrintChar(L'\r'); + } + /* Write character to the screen console */ Buffer[0] = Character; Buffer[1] = 0; EfiSystemTable->ConOut->OutputString(EfiSystemTable->ConOut, Buffer); + + /* Return success */ + return STATUS_SUCCESS; } diff --git a/xtldr/debug.c b/xtldr/debug.c index 343be67..fabd117 100644 --- a/xtldr/debug.c +++ b/xtldr/debug.c @@ -27,11 +27,16 @@ VOID BlDebugPrint(IN PUSHORT Format, IN ...) { + RTL_PRINT_CONTEXT ConsolePrintContext, SerialPrintContext; VA_LIST Arguments; /* Check if debugging enabled and if EFI serial port is fully initialized */ if(DEBUG) { + /* Initialize the print contexts */ + ConsolePrintContext.WriteWideCharacter = BlpConsolePrintChar; + SerialPrintContext.WriteWideCharacter = BlpDebugPutChar; + /* Initialise the va_list */ VA_START(Arguments, Format); @@ -39,14 +44,14 @@ BlDebugPrint(IN PUSHORT Format, if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SERIAL) && (BlpStatus.SerialPort.Flags & COMPORT_FLAG_INIT)) { /* Format and print the string to the serial console */ - BlpStringPrint(BlpDebugPutChar, Format, Arguments); + RtlFormatWideString(&SerialPrintContext, (PWCHAR)Format, Arguments); } /* Check if screen debug port is enabled and Boot Services are still available */ if((BlpStatus.DebugPort & XTBL_DEBUGPORT_SCREEN) && (BlpStatus.BootServices == TRUE)) { /* Format and print the string to the screen */ - BlpStringPrint(BlpConsolePrintChar, Format, Arguments); + RtlFormatWideString(&ConsolePrintContext, (PWCHAR)Format, Arguments); } /* Clean up the va_list */ @@ -245,12 +250,12 @@ BlpInitializeSerialPort(IN ULONG PortNumber, * @param Character * The integer promotion of the character to be written. * - * @return This routine does not return any value. + * @return This routine returns a status code. * * @since XT 1.0 */ XTCDECL -VOID +XTSTATUS BlpDebugPutChar(IN USHORT Character) { USHORT Buffer[2]; @@ -258,6 +263,8 @@ BlpDebugPutChar(IN USHORT Character) /* Write character to the serial console */ Buffer[0] = Character; Buffer[1] = 0; - HlComPortPutByte(&BlpStatus.SerialPort, Buffer[0]); + + /* Return success */ + return STATUS_EFI_SUCCESS; } diff --git a/xtldr/includes/xtldr.h b/xtldr/includes/xtldr.h index 84ab048..348603c 100644 --- a/xtldr/includes/xtldr.h +++ b/xtldr/includes/xtldr.h @@ -15,9 +15,6 @@ #include -/* XTLDR routine callbacks */ -typedef VOID (BLPRINTCHAR)(IN USHORT Character); - /* XTLDR routines forward references */ XTCDECL EFI_STATUS @@ -359,11 +356,11 @@ EFI_STATUS BlpActivateSerialIOController(); XTCDECL -VOID +XTSTATUS BlpConsolePrintChar(IN USHORT Character); XTCDECL -VOID +XTSTATUS BlpDebugPutChar(IN USHORT Character); XTCDECL @@ -483,44 +480,6 @@ BlpReadConfigFile(IN CONST PWCHAR ConfigDirectory, IN CONST PWCHAR ConfigFile, OUT PCHAR *ConfigData); -XTCDECL -VOID -BlpStringFormat(IN BLPRINTCHAR PrintCharRoutine, - IN PUSHORT Format, - IN ...); - -XTCDECL -VOID -BlpStringPrint(IN IN BLPRINTCHAR PrintCharRoutine, - IN PUSHORT Format, - IN VA_LIST Arguments); - -XTCDECL -VOID -BlpStringPrintSigned32(IN BLPRINTCHAR PrintCharRoutine, - IN INT Number, - IN UINT Base); - -XTCDECL -VOID -BlpStringPrintSigned64(IN BLPRINTCHAR PrintCharRoutine, - IN INT_PTR Number, - IN UINT_PTR Base); - -XTCDECL -VOID -BlpStringPrintUnsigned32(IN BLPRINTCHAR PrintCharRoutine, - IN UINT Number, - IN UINT Base, - IN UINT Padding); - -XTCDECL -VOID -BlpStringPrintUnsigned64(IN BLPRINTCHAR PrintCharRoutine, - IN UINT_PTR Number, - IN UINT_PTR Base, - IN UINT_PTR Padding); - XTCDECL ULONGLONG BlpStringReadPadding(IN PUSHORT *Format); diff --git a/xtldr/string.c b/xtldr/string.c deleted file mode 100644 index b968511..0000000 --- a/xtldr/string.c +++ /dev/null @@ -1,444 +0,0 @@ -/** - * PROJECT: ExectOS - * COPYRIGHT: See COPYING.md in the top level directory - * FILE: xtldr/string.c - * DESCRIPTION: EFI string manipulation support - * DEVELOPERS: Rafal Kupiec - */ - -#include - - -/** - * This routine formats the input string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Format - * The formatted string that is to be written to the specified device. - * - * @param Arguments - * A value identifying a variable arguments list initialized with VA_START. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpStringPrint(IN IN BLPRINTCHAR PrintCharRoutine, - IN PUSHORT Format, - IN VA_LIST Arguments) -{ - PEFI_GUID Guid; - PUCHAR String; - PWCHAR WideString; - ULONG PaddingCount; - - /* Read the variable arguments */ - for(; *Format; ++Format) - { - switch(*Format) - { - case L'%': - switch(*++Format) - { - case L'b': - /* Boolean */ - BlpStringFormat(PrintCharRoutine, L"%s", VA_ARG(Arguments, INT) ? "TRUE" : "FALSE"); - break; - case L'c': - /* Character */ - PrintCharRoutine(VA_ARG(Arguments, INT)); - break; - case L'd': - /* Signed 32-bit integer */ - BlpStringPrintSigned32(PrintCharRoutine, VA_ARG(Arguments, INT), 10); - break; - case L'g': - /* EFI GUID */ - Guid = VA_ARG(Arguments, PEFI_GUID); - BlpStringFormat(PrintCharRoutine, L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Guid->Data1, - Guid->Data2, Guid->Data3, Guid->Data4[0], Guid->Data4[1], Guid->Data4[2], - Guid->Data4[3], Guid->Data4[4], Guid->Data4[5], Guid->Data4[6], Guid->Data4[7]); - break; - case L'l': - /* 64-bit numbers */ - switch(*++Format) - { - case L'd': - /* Signed 64-bit integer */ - BlpStringPrintSigned64(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); - break; - case L'u': - /* Unsigned 64-bit integer */ - BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, 0); - break; - case L'x': - /* Unsigned 64-bit hexadecimal integer */ - BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); - break; - default: - /* Unknown by default */ - PrintCharRoutine(L'?'); - break; - } - break; - case L'p': - /* Pointer address */ - BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, 0); - break; - case L's': - /* String of characters */ - String = VA_ARG(Arguments, PUCHAR); - while(*String) - { - PrintCharRoutine(*String++); - } - break; - case L'S': - WideString = VA_ARG(Arguments, PWCHAR); - while(*WideString) - { - PrintCharRoutine((UCHAR)*WideString++); - } - break; - case L'u': - /* Unsigned 32-bit integer */ - BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT), 10, 0); - break; - case L'x': - /* Unsigned 32-bit hexadecimal integer */ - BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT), 16, 0); - break; - case L'0': - /* Zero padded numbers */ - ++Format; - PaddingCount = BlpStringReadPadding(&Format); - switch(*Format) - { - case L'd': - /* Zero-padded, signed 32-bit integer */ - BlpStringPrintSigned32(PrintCharRoutine, VA_ARG(Arguments, INT), 10); - break; - case L'l': - /* 64-bit numbers */ - switch(*++Format) - { - case L'd': - /* Zero-padded, signed 64-bit integer */ - BlpStringPrintSigned64(PrintCharRoutine, VA_ARG(Arguments, INT_PTR), 10); - break; - case L'u': - /* Zero-padded, unsigned 64-bit integer */ - BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 10, PaddingCount); - break; - case L'x': - /* Zero-padded, unsigned 64-bit hexadecimal integer */ - BlpStringPrintUnsigned64(PrintCharRoutine, VA_ARG(Arguments, UINT_PTR), 16, PaddingCount); - break; - default: - /* Unknown by default */ - PrintCharRoutine(L'?'); - break; - } - break; - case L'u': - /* Zero-padded, unsigned 32-bit integer */ - BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT), 10, PaddingCount); - break; - case L'x': - /* Zero-padded, unsigned 32-bit hexadecimal integer */ - BlpStringPrintUnsigned32(PrintCharRoutine, VA_ARG(Arguments, UINT), 16, PaddingCount); - break; - default: - /* Unknown by default */ - PrintCharRoutine(L'?'); - break; - } - break; - case L'%': - /* Percent character */ - PrintCharRoutine(L'%'); - break; - default: - /* Unknown by default */ - PrintCharRoutine(L'?'); - break; - } - break; - case L'\r': - /* Carriage return is ignored */ - break; - case L'\n': - /* New line together with carriage return */ - PrintCharRoutine(L'\r'); - PrintCharRoutine(L'\n'); - break; - default: - /* Put character by default */ - PrintCharRoutine(*Format); - break; - } - } -} - -/** - * This routine formats the input string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Format - * The formatted string that is to be written to the specified device. - * - * @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 -BlpStringFormat(IN BLPRINTCHAR PrintCharRoutine, - IN PUSHORT Format, - IN ...) -{ - VA_LIST Arguments; - - /* Initialise the va_list */ - VA_START(Arguments, Format); - - /* Format and print the string to the desired output */ - BlpStringPrint(PrintCharRoutine, Format, Arguments); - - /* Clean up the va_list */ - VA_END(Arguments); -} - -/** - * This routine converts 32-bit integer as string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Number - * 32-bit integer value. - * - * @param Base - * Specifies the number base system representation. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpStringPrintSigned32(IN BLPRINTCHAR PrintCharRoutine, - IN INT Number, - IN UINT Base) -{ - /* Print - (minus) if this is negative value */ - if(Number < 0) - { - PrintCharRoutine(L'-'); - Number *= -1; - } - - /* Print the integer value */ - BlpStringPrintUnsigned32(PrintCharRoutine, Number, Base, 0); -} - -/** - * This routine converts 64-bit integer as string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Number - * 64-bit integer value. - * - * @param Base - * Specifies the number base system representation. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpStringPrintSigned64(IN BLPRINTCHAR PrintCharRoutine, - IN INT_PTR Number, - IN UINT_PTR Base) -{ - /* Print - (minus) if this is negative value */ - if(Number < 0) - { - PrintCharRoutine(L'-'); - Number *= -1; - } - - /* Print the integer value */ - BlpStringPrintUnsigned64(PrintCharRoutine, Number, Base, 0); -} - -/** - * This routine converts 32-bit unsigned integer as string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Number - * 32-bit integer value. - * - * @param Base - * Specifies the number base system representation. - * - * @param Padding - * Specifies the number of leading zeros to complete the field width. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpStringPrintUnsigned32(IN BLPRINTCHAR PrintCharRoutine, - IN UINT Number, - IN UINT Base, - IN UINT Padding) -{ - UINT Buffer[20]; - UINT NumberLength; - PUINT Pointer; - - /* Set pointer to the end of buffer */ - Pointer = Buffer + ARRAY_SIZE(Buffer); - - /* Convert value to specified base system */ - *--Pointer = 0; - do - { - *--Pointer = BlpHexTable[Number % Base]; - } while(Pointer >= Buffer && (Number /= Base)); - - /* Calculate number length */ - NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1; - - /* Check if leading zeros are needed */ - if(NumberLength < Padding) - { - Padding -= NumberLength; - while(Padding--) - { - /* Write leading zeroes */ - PrintCharRoutine(L'0'); - } - } - - /* Print value to the console */ - for(; *Pointer; ++Pointer) - { - PrintCharRoutine(*Pointer); - } -} - -/** - * This routine converts 64-bit unsigned integer as string and prints it using specified routine. - * - * @param PrintCharRoutine - * Pointer to the routine that writes an input data to specific device. - * - * @param Number - * 64-bit integer value. - * - * @param Base - * Specifies the number base system representation. - * - * @param Padding - * Specifies the number of leading zeros to complete the field width. - * - * @return This routine does not return any value. - * - * @since XT 1.0 - */ -XTCDECL -VOID -BlpStringPrintUnsigned64(IN BLPRINTCHAR PrintCharRoutine, - IN UINT_PTR Number, - IN UINT_PTR Base, - IN UINT_PTR Padding) -{ - USHORT Buffer[20]; - UINT_PTR NumberLength; - PUSHORT Pointer; - - /* Set pointer to the end of buffer */ - Pointer = Buffer + ARRAY_SIZE(Buffer); - - /* Convert value to specified base system */ - *--Pointer = 0; - do - { - *--Pointer = BlpHexTable[Number % Base]; - } while(Pointer >= Buffer && (Number /= Base)); - - /* Calculate number length */ - NumberLength = ARRAY_SIZE(Buffer) - (Pointer - Buffer) - 1; - - /* Check if leading zeros are needed */ - if(NumberLength < Padding) - { - Padding -= NumberLength; - while(Padding--) - { - /* Write leading zeroes */ - PrintCharRoutine(L'0'); - } - } - - /* Print value to the console */ - for(; *Pointer; ++Pointer) - { - PrintCharRoutine(*Pointer); - } -} - -/** - * Reads the number of padding characters from the format string. - * - * @param Format - * The format string. - * - * @return Number of padding characters. - * - * @since XT 1.0 - */ -XTCDECL -ULONGLONG -BlpStringReadPadding(IN PUSHORT *Format) -{ - ULONG Count = 0; - PUSHORT Fmt = *Format; - - /* Read the padding */ - for(;; ++Fmt) - { - switch(*Fmt) - { - case L'0' ... L'9': - /* Check the number of leading zeroes */ - Count = Count * 10 + *Fmt - L'0'; - break; - default: - /* No padding by default */ - *Format = Fmt; - return Count; - } - } - - /* No padding by default */ - return 0; -}