MdePkg/UefiDebugLibDebugPortProtocol: Make it runtime safe

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

After ExitBootServices, some pointer would be invalid such as
the Protocol pointer and gBS. The function depend on those should
be prevent. So disable the related function while after
ExitBootServices.
Change the gBS to a internal one, because there will be a cycle
consume between UefiBootServicesTableLib and DebugLib due to the
library constructors.
Also remove the SMM support for this instance.

Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
Cc: Sean Brogan <sean.brogan@microsoft.com>
Cc: Michael Turner <Michael.Turner@microsoft.com>
Cc: Bret Barkelew <Bret.Barkelew@microsoft.com>
Signed-off-by: Zhichao Gao <zhichao.gao@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
This commit is contained in:
Aaron Antone
2019-04-08 10:48:00 +08:00
committed by Liming Gao
parent c0b2816d69
commit 2b5778c68b
3 changed files with 163 additions and 72 deletions

View File

@ -9,7 +9,6 @@
#include <Uefi.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/PrintLib.h>
#include <Library/PcdLib.h>
#include <Library/BaseLib.h>
@ -37,6 +36,9 @@ EFI_DEBUGPORT_PROTOCOL *mDebugPort = NULL;
//
VA_LIST mVaListNull;
extern BOOLEAN mPostEBS;
extern EFI_BOOT_SERVICES *mDebugBS;
/**
Send message to DebugPort Protocol.
@ -56,31 +58,33 @@ UefiDebugLibDebugPortProtocolWrite (
UINTN Length;
EFI_STATUS Status;
//
// If mDebugPort is NULL, initialize first.
//
if (mDebugPort == NULL) {
Status = gBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **)&mDebugPort);
if (EFI_ERROR (Status)) {
return;
}
if (!mPostEBS) {
//
// If mDebugPort is NULL, initialize first.
//
if (mDebugPort == NULL) {
Status = mDebugBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **)&mDebugPort);
if (EFI_ERROR (Status)) {
return;
}
mDebugPort->Reset (mDebugPort);
}
//
// EFI_DEBUGPORT_PROTOCOL.Write is called until all message is sent.
//
while (BufferLength > 0) {
Length = BufferLength;
Status = mDebugPort->Write (mDebugPort, WRITE_TIMEOUT, &Length, (VOID *) Buffer);
if (EFI_ERROR (Status) || BufferLength < Length) {
break;
mDebugPort->Reset (mDebugPort);
}
Buffer += Length;
BufferLength -= Length;
//
// EFI_DEBUGPORT_PROTOCOL.Write is called until all message is sent.
//
while (BufferLength > 0) {
Length = BufferLength;
Status = mDebugPort->Write (mDebugPort, WRITE_TIMEOUT, &Length, (VOID *) Buffer);
if (EFI_ERROR (Status) || BufferLength < Length) {
break;
}
Buffer += Length;
BufferLength -= Length;
}
}
}
@ -142,31 +146,33 @@ DebugPrintMarker (
{
CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
//
// If Format is NULL, then ASSERT().
//
ASSERT (Format != NULL);
if (!mPostEBS) {
//
// If Format is NULL, then ASSERT().
//
ASSERT (Format != NULL);
//
// Check driver debug mask value and global mask
//
if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
return;
//
// Check driver debug mask value and global mask
//
if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {
return;
}
//
// Convert the DEBUG() message to an ASCII String
//
if (BaseListMarker == NULL) {
AsciiVSPrint (Buffer, sizeof (Buffer), Format, VaListMarker);
} else {
AsciiBSPrint (Buffer, sizeof (Buffer), Format, BaseListMarker);
}
//
// Send the print string to EFI_DEBUGPORT_PROTOCOL.Write.
//
UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer));
}
//
// Convert the DEBUG() message to an ASCII String
//
if (BaseListMarker == NULL) {
AsciiVSPrint (Buffer, sizeof (Buffer), Format, VaListMarker);
} else {
AsciiBSPrint (Buffer, sizeof (Buffer), Format, BaseListMarker);
}
//
// Send the print string to EFI_DEBUGPORT_PROTOCOL.Write.
//
UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer));
}
@ -259,31 +265,33 @@ DebugAssert (
{
CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];
//
// Generate the ASSERT() message in ASCII format
//
AsciiSPrint (
Buffer,
sizeof (Buffer),
"ASSERT [%a] %a(%d): %a\n",
gEfiCallerBaseName,
FileName,
LineNumber,
Description
);
if (!mPostEBS) {
//
// Generate the ASSERT() message in ASCII format
//
AsciiSPrint (
Buffer,
sizeof (Buffer),
"ASSERT [%a] %a(%d): %a\n",
gEfiCallerBaseName,
FileName,
LineNumber,
Description
);
//
// Send the print string to EFI_DEBUGPORT_PROTOCOL.Write.
//
UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer));
//
// Send the print string to EFI_DEBUGPORT_PROTOCOL.Write.
//
UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer));
//
// Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
//
if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
CpuBreakpoint ();
} else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
CpuDeadLoop ();
//
// Generate a Breakpoint, DeadLoop, or NOP based on PCD settings
//
if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {
CpuBreakpoint ();
} else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {
CpuDeadLoop ();
}
}
}