MdeModulePkg/Universal/StatusCodeHandler: Fix a bug about log lost

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3126

1. If use PeiDxeDebugLibReportStatusCode as DebugLib, then some logs
after ExitBootService() will be lost.
2. The root cause:
2.1 The original code will register an unregister function
of gEfiEventExitBootServicesGuid, this unregister function will call
EFI_RSC_HANDLER_PROTOCOL->Unregister and does not support log through
serial port.
2.2 And some other drivers also register call back funtions of
gEfiEventExitBootServicesGuid.
2.3 Then after the unregister function is called, other call back
functions can't out log if them use RSC as DebugLib.
3. The DxeMain will report status code EFI_SW_BS_PC_EXIT_BOOT_SERVICES
after notify all the call back functions of
gEfiEventExitBootServicesGuid.
4. Solution: the StatusCodeHandlerRuntimeDxe.c will not register an
unregister function of gEfiEventExitBootServicesGuid, but unregister it
after receive the status code of EFI_SW_BS_PC_EXIT_BOOT_SERVICES.

Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Signed-off-by: Ming Tan <ming.tan@intel.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
Reviewed-by: Dandan Bi <dandan.bi@intel.com>
This commit is contained in:
Tan, Ming 2020-12-18 12:50:46 +08:00 committed by mergify[bot]
parent d77f9b1eff
commit d4945b1027
3 changed files with 23 additions and 17 deletions

View File

@ -151,6 +151,16 @@ SerialStatusCodeReportWorker (
//
SerialPortWrite ((UINT8 *) Buffer, CharCount);
//
// If register an unregister function of gEfiEventExitBootServicesGuid,
// then some log called in ExitBootServices() will be lost,
// so unregister the handler after receive the value of exit boot service.
//
if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE &&
Value == (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)) {
UnregisterSerialBootTimeHandlers();
}
return EFI_SUCCESS;
}

View File

@ -10,23 +10,17 @@
#include "StatusCodeHandlerRuntimeDxe.h"
EFI_EVENT mVirtualAddressChangeEvent = NULL;
static EFI_EVENT mExitBootServicesEvent = NULL;
EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
/**
Unregister status code callback functions only available at boot time from
report status code router when exiting boot services.
@param Event Event whose notification function is being invoked.
@param Context Pointer to the notification function's context, which is
always zero in current implementation.
**/
VOID
EFIAPI
UnregisterBootTimeHandlers (
IN EFI_EVENT Event,
IN VOID *Context
UnregisterSerialBootTimeHandlers (
VOID
)
{
if (PcdGetBool (PcdStatusCodeUseSerial)) {
@ -178,15 +172,6 @@ StatusCodeHandlerRuntimeDxeEntry (
mRscHandlerProtocol->Register (RtMemoryStatusCodeReportWorker, TPL_HIGH_LEVEL);
}
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
UnregisterBootTimeHandlers,
NULL,
&gEfiEventExitBootServicesGuid,
&mExitBootServicesEvent
);
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,

View File

@ -118,4 +118,15 @@ RtMemoryStatusCodeReportWorker (
IN EFI_STATUS_CODE_DATA *Data OPTIONAL
);
/**
Unregister status code callback functions only available at boot time from
report status code router when exiting boot services.
**/
VOID
EFIAPI
UnregisterSerialBootTimeHandlers (
VOID
);
#endif