Extend the functionality of DxeRuntimeDebugLibSerialPort by invoking any available RuntimeDebugOutputProtocol to emit debug output at runtime rather than staying silent.
Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <[email protected]> --- MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c | 155 +++++++++++++++++--- MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf | 5 + 2 files changed, 143 insertions(+), 17 deletions(-) diff --git a/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c b/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c index e1266f77fa41..b5460f10ebb6 100644 --- a/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c +++ b/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DebugLib.c @@ -25,10 +25,16 @@ #include <Library/PcdLib.h> #include <Library/BaseMemoryLib.h> #include <Library/SerialPortLib.h> +#include <Protocol/RuntimeDebugOutput.h> STATIC EFI_EVENT mEfiExitBootServicesEvent; +STATIC EFI_EVENT mEfiVirtualAddressChangeEvent; +STATIC EFI_EVENT mRegisterRuntimeDebugOutputProtocolEvent; +STATIC VOID *mRegisterProtocolRegistration; STATIC BOOLEAN mEfiAtRuntime = FALSE; +STATIC EDK2_RUNTIME_DEBUG_OUTPUT_PROTOCOL *mRuntimeOutput = NULL; + // // Define the maximum debug and assert message length that this library supports // @@ -53,6 +59,58 @@ ExitBootServicesEvent ( } /** + Attach to the RuntimeDebugOutputProtocol as soon as it gets registered + + @param[in] Event The Event that is being processed. + @param[in] Context The Event Context. + +**/ +STATIC +VOID +EFIAPI +RegisterRuntimeDebugOutputProtocolEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_STATUS Status; + EFI_BOOT_SERVICES *BS; + + BS = Context; + + Status = BS->LocateProtocol (&gEdkiiRuntimeDebugOutputProtocolGuid, + mRegisterProtocolRegistration, + (VOID **)&mRuntimeOutput); + if (EFI_ERROR (Status)) { + return; + } + + BS->CloseEvent (Event); +} + +/** + Fix up virtual address of the runtime debug output protocol + + @param[in] Event The Event that is being processed. + @param[in] Context The Event Context. + +**/ +STATIC +VOID +EFIAPI +VirtualAddressChangeEvent ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + EFI_RUNTIME_SERVICES *RT; + + RT = Context; + + RT->ConvertPointer (0x0, (VOID **)&mRuntimeOutput); +} + +/** The constructor function to initialize the Serial Port library and register a callback for the ExitBootServices event. @@ -70,17 +128,64 @@ DxeRuntimeDebugLibSerialPortConstructor ( IN EFI_SYSTEM_TABLE *SystemTable ) { - EFI_STATUS Status; + EFI_STATUS Status; + EFI_BOOT_SERVICES *BS; Status = SerialPortInitialize (); if (EFI_ERROR (Status)) { return Status; } - return SystemTable->BootServices->CreateEventEx (EVT_NOTIFY_SIGNAL, - TPL_NOTIFY, ExitBootServicesEvent, NULL, - &gEfiEventExitBootServicesGuid, - &mEfiExitBootServicesEvent); + BS = SystemTable->BootServices; + + Status = BS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, + RegisterRuntimeDebugOutputProtocolEvent, BS, + &mRegisterRuntimeDebugOutputProtocolEvent); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Register for protocol notifications on this event + // + Status = BS->RegisterProtocolNotify (&gEdkiiRuntimeDebugOutputProtocolGuid, + mRegisterRuntimeDebugOutputProtocolEvent, + &mRegisterProtocolRegistration); + if (EFI_ERROR (Status)) { + goto CloseProtocolEvent; + } + + // + // Kick the event so we will perform an initial pass of + // current installed drivers + // + BS->SignalEvent (mRegisterRuntimeDebugOutputProtocolEvent); + + Status = BS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, + ExitBootServicesEvent, NULL, + &gEfiEventExitBootServicesGuid, + &mEfiExitBootServicesEvent); + if (EFI_ERROR (Status)) { + goto CloseProtocolEvent; + } + + Status = BS->CreateEventEx (EVT_NOTIFY_SIGNAL, TPL_NOTIFY, + VirtualAddressChangeEvent, SystemTable->RuntimeServices, + &gEfiEventVirtualAddressChangeGuid, + &mEfiVirtualAddressChangeEvent); + if (EFI_ERROR (Status)) { + goto CloseExitBootServicesEvent; + } + + return EFI_SUCCESS; + +CloseExitBootServicesEvent: + BS->CloseEvent (mEfiExitBootServicesEvent); + +CloseProtocolEvent: + BS->CloseEvent (mRegisterRuntimeDebugOutputProtocolEvent); + + return Status; } /** @@ -100,7 +205,29 @@ DxeRuntimeDebugLibSerialPortDestructor ( IN EFI_SYSTEM_TABLE *SystemTable ) { - return SystemTable->BootServices->CloseEvent (mEfiExitBootServicesEvent); + EFI_BOOT_SERVICES *BS; + + BS = SystemTable->BootServices; + + BS->CloseEvent (mRegisterRuntimeDebugOutputProtocolEvent); + BS->CloseEvent (mEfiExitBootServicesEvent); + + return EFI_SUCCESS; +} + +STATIC +UINTN +DebugWriteOutput ( + IN UINT8 *Buffer, + IN UINTN NumberOfBytes + ) +{ + if (!mEfiAtRuntime) { + return SerialPortWrite (Buffer, NumberOfBytes); + } else if (mRuntimeOutput != NULL) { + return mRuntimeOutput->Write (mRuntimeOutput, Buffer, NumberOfBytes); + } + return 0; } /** @@ -129,10 +256,6 @@ DebugPrint ( CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH]; VA_LIST Marker; - if (mEfiAtRuntime) { - return; - } - // // If Format is NULL, then ASSERT(). // @@ -155,7 +278,7 @@ DebugPrint ( // // Send the print string to a Serial Port // - SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer)); + DebugWriteOutput ((UINT8 *)Buffer, AsciiStrLen (Buffer)); } @@ -196,12 +319,10 @@ DebugAssert ( AsciiSPrint (Buffer, sizeof (Buffer), "ASSERT [%a] %a(%d): %a\n", gEfiCallerBaseName, FileName, LineNumber, Description); - if (!mEfiAtRuntime) { - // - // Send the print string to the Console Output device - // - SerialPortWrite ((UINT8 *)Buffer, AsciiStrLen (Buffer)); - } + // + // Send the print string to the Console Output device + // + DebugWriteOutput ((UINT8 *)Buffer, AsciiStrLen (Buffer)); // // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings diff --git a/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf b/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf index 813358096982..d2fbdde25f1d 100644 --- a/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf +++ b/MdeModulePkg/Library/DxeRuntimeDebugLibSerialPort/DxeRuntimeDebugLibSerialPort.inf @@ -36,6 +36,7 @@ [Sources] DebugLib.c [Packages] + MdeModulePkg/MdeModulePkg.dec MdePkg/MdePkg.dec [LibraryClasses] @@ -48,6 +49,10 @@ [LibraryClasses] [Guids] gEfiEventExitBootServicesGuid ## CONSUMES ## Event + gEfiEventVirtualAddressChangeGuid ## CONSUMES ## Event + +[Protocols] + gEdkiiRuntimeDebugOutputProtocolGuid ## SOMETIMES_CONSUMES [Pcd] gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue ## SOMETIMES_CONSUMES -- 2.11.0 _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

