/** @file\r
UEFI Debug Library that sends messages to EFI_DEBUGPORT_PROTOCOL.Write.\r
\r
- Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php.\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <Uefi.h>\r
\r
#include <Library/DebugLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
#include <Library/PrintLib.h>\r
#include <Library/PcdLib.h>\r
#include <Library/BaseLib.h>\r
//\r
// Define the timeout for EFI_DEBUGPORT_PROTOCOL.Write\r
//\r
-#define WRITE_TIMEOUT 1000\r
+#define WRITE_TIMEOUT 1000\r
+\r
+EFI_DEBUGPORT_PROTOCOL *mDebugPort = NULL;\r
\r
+//\r
+// VA_LIST can not initialize to NULL for all compiler, so we use this to\r
+// indicate a null VA_LIST\r
+//\r
+VA_LIST mVaListNull;\r
\r
-EFI_DEBUGPORT_PROTOCOL *mDebugPort = NULL;\r
+extern BOOLEAN mPostEBS;\r
+extern EFI_BOOT_SERVICES *mDebugBS;\r
\r
/**\r
Send message to DebugPort Protocol.\r
IN UINTN BufferLength\r
)\r
{\r
- UINTN Length;\r
- EFI_STATUS Status;\r
-\r
- //\r
- // If mDebugPort is NULL, initialize first.\r
- //\r
- if (mDebugPort == NULL) {\r
- Status = gBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **)&mDebugPort);\r
+ UINTN Length;\r
+ EFI_STATUS Status;\r
+\r
+ if (!mPostEBS) {\r
+ //\r
+ // If mDebugPort is NULL, initialize first.\r
+ //\r
+ if (mDebugPort == NULL) {\r
+ Status = mDebugBS->LocateProtocol (&gEfiDebugPortProtocolGuid, NULL, (VOID **)&mDebugPort);\r
if (EFI_ERROR (Status)) {\r
- return;\r
+ return;\r
}\r
\r
mDebugPort->Reset (mDebugPort);\r
- }\r
+ }\r
\r
- //\r
- // EFI_DEBUGPORT_PROTOCOL.Write is called until all message is sent.\r
- //\r
- while (BufferLength > 0) {\r
- Length = BufferLength;\r
+ //\r
+ // EFI_DEBUGPORT_PROTOCOL.Write is called until all message is sent.\r
+ //\r
+ while (BufferLength > 0) {\r
+ Length = BufferLength;\r
\r
- Status = mDebugPort->Write (mDebugPort, WRITE_TIMEOUT, &Length, (VOID *) Buffer);\r
- if (EFI_ERROR (Status) || BufferLength < Length) {\r
- break;\r
- }\r
+ Status = mDebugPort->Write (mDebugPort, WRITE_TIMEOUT, &Length, (VOID *)Buffer);\r
+ if (EFI_ERROR (Status) || (BufferLength < Length)) {\r
+ break;\r
+ }\r
\r
- Buffer += Length;\r
- BufferLength -= Length;\r
+ Buffer += Length;\r
+ BufferLength -= Length;\r
+ }\r
}\r
}\r
\r
...\r
)\r
{\r
- CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];\r
- VA_LIST Marker;\r
+ VA_LIST Marker;\r
\r
- //\r
- // If Format is NULL, then ASSERT().\r
- //\r
- ASSERT (Format != NULL);\r
+ VA_START (Marker, Format);\r
+ DebugVPrint (ErrorLevel, Format, Marker);\r
+ VA_END (Marker);\r
+}\r
\r
- //\r
- // Check driver debug mask value and global mask\r
- //\r
- if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {\r
- return;\r
+/**\r
+ Prints a debug message to the debug output device if the specified\r
+ error level is enabled base on Null-terminated format string and a\r
+ VA_LIST argument list or a BASE_LIST argument list.\r
+\r
+ If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function\r
+ GetDebugPrintErrorLevel (), then print the message specified by Format and\r
+ the associated variable argument list to the debug output device.\r
+\r
+ If Format is NULL, then ASSERT().\r
+\r
+ @param ErrorLevel The error level of the debug message.\r
+ @param Format Format string for the debug message to print.\r
+ @param VaListMarker VA_LIST marker for the variable argument list.\r
+ @param BaseListMarker BASE_LIST marker for the variable argument list.\r
+\r
+**/\r
+VOID\r
+DebugPrintMarker (\r
+ IN UINTN ErrorLevel,\r
+ IN CONST CHAR8 *Format,\r
+ IN VA_LIST VaListMarker,\r
+ IN BASE_LIST BaseListMarker\r
+ )\r
+{\r
+ CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];\r
+\r
+ if (!mPostEBS) {\r
+ //\r
+ // If Format is NULL, then ASSERT().\r
+ //\r
+ ASSERT (Format != NULL);\r
+\r
+ //\r
+ // Check driver debug mask value and global mask\r
+ //\r
+ if ((ErrorLevel & GetDebugPrintErrorLevel ()) == 0) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Convert the DEBUG() message to an ASCII String\r
+ //\r
+ if (BaseListMarker == NULL) {\r
+ AsciiVSPrint (Buffer, sizeof (Buffer), Format, VaListMarker);\r
+ } else {\r
+ AsciiBSPrint (Buffer, sizeof (Buffer), Format, BaseListMarker);\r
+ }\r
+\r
+ //\r
+ // Send the print string to EFI_DEBUGPORT_PROTOCOL.Write.\r
+ //\r
+ UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer));\r
}\r
+}\r
\r
- //\r
- // Convert the DEBUG() message to an ASCII String\r
- //\r
- VA_START (Marker, Format);\r
- AsciiVSPrint (Buffer, sizeof (Buffer), Format, Marker);\r
- VA_END (Marker);\r
+/**\r
+ Prints a debug message to the debug output device if the specified\r
+ error level is enabled.\r
\r
- //\r
- // Send the print string to EFI_DEBUGPORT_PROTOCOL.Write.\r
- //\r
- UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer));\r
+ If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function\r
+ GetDebugPrintErrorLevel (), then print the message specified by Format and\r
+ the associated variable argument list to the debug output device.\r
+\r
+ If Format is NULL, then ASSERT().\r
+\r
+ @param ErrorLevel The error level of the debug message.\r
+ @param Format Format string for the debug message to print.\r
+ @param VaListMarker VA_LIST marker for the variable argument list.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DebugVPrint (\r
+ IN UINTN ErrorLevel,\r
+ IN CONST CHAR8 *Format,\r
+ IN VA_LIST VaListMarker\r
+ )\r
+{\r
+ DebugPrintMarker (ErrorLevel, Format, VaListMarker, NULL);\r
}\r
\r
+/**\r
+ Prints a debug message to the debug output device if the specified\r
+ error level is enabled.\r
+ This function use BASE_LIST which would provide a more compatible\r
+ service than VA_LIST.\r
+\r
+ If any bit in ErrorLevel is also set in DebugPrintErrorLevelLib function\r
+ GetDebugPrintErrorLevel (), then print the message specified by Format and\r
+ the associated variable argument list to the debug output device.\r
+\r
+ If Format is NULL, then ASSERT().\r
+\r
+ @param ErrorLevel The error level of the debug message.\r
+ @param Format Format string for the debug message to print.\r
+ @param BaseListMarker BASE_LIST marker for the variable argument list.\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+DebugBPrint (\r
+ IN UINTN ErrorLevel,\r
+ IN CONST CHAR8 *Format,\r
+ IN BASE_LIST BaseListMarker\r
+ )\r
+{\r
+ DebugPrintMarker (ErrorLevel, Format, mVaListNull, BaseListMarker);\r
+}\r
\r
/**\r
Prints an assert message containing a filename, line number, and description.\r
{\r
CHAR8 Buffer[MAX_DEBUG_MESSAGE_LENGTH];\r
\r
- //\r
- // Generate the ASSERT() message in ASCII format\r
- //\r
- AsciiSPrint (\r
- Buffer,\r
- sizeof (Buffer),\r
- "ASSERT [%a] %a(%d): %a\n",\r
- gEfiCallerBaseName,\r
- FileName,\r
- LineNumber,\r
- Description\r
- );\r
-\r
- //\r
- // Send the print string to EFI_DEBUGPORT_PROTOCOL.Write.\r
- //\r
- UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer));\r
-\r
- //\r
- // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings\r
- //\r
- if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {\r
- CpuBreakpoint ();\r
- } else if ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {\r
- CpuDeadLoop ();\r
+ if (!mPostEBS) {\r
+ //\r
+ // Generate the ASSERT() message in ASCII format\r
+ //\r
+ AsciiSPrint (\r
+ Buffer,\r
+ sizeof (Buffer),\r
+ "ASSERT [%a] %a(%d): %a\n",\r
+ gEfiCallerBaseName,\r
+ FileName,\r
+ LineNumber,\r
+ Description\r
+ );\r
+\r
+ //\r
+ // Send the print string to EFI_DEBUGPORT_PROTOCOL.Write.\r
+ //\r
+ UefiDebugLibDebugPortProtocolWrite (Buffer, AsciiStrLen (Buffer));\r
+\r
+ //\r
+ // Generate a Breakpoint, DeadLoop, or NOP based on PCD settings\r
+ //\r
+ if ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_BREAKPOINT_ENABLED) != 0) {\r
+ CpuBreakpoint ();\r
+ } else if ((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_ASSERT_DEADLOOP_ENABLED) != 0) {\r
+ CpuDeadLoop ();\r
+ }\r
}\r
}\r
\r
-\r
/**\r
Fills a target buffer with PcdDebugClearMemoryValue, and returns the target buffer.\r
\r
//\r
// SetMem() checks for the the ASSERT() condition on Length and returns Buffer\r
//\r
- return SetMem (Buffer, Length, PcdGet8(PcdDebugClearMemoryValue));\r
+ return SetMem (Buffer, Length, PcdGet8 (PcdDebugClearMemoryValue));\r
}\r
\r
-\r
/**\r
Returns TRUE if ASSERT() macros are enabled.\r
\r
VOID\r
)\r
{\r
- return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);\r
+ return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_ASSERT_ENABLED) != 0);\r
}\r
\r
-\r
/**\r
Returns TRUE if DEBUG() macros are enabled.\r
\r
VOID\r
)\r
{\r
- return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);\r
+ return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_PRINT_ENABLED) != 0);\r
}\r
\r
-\r
/**\r
Returns TRUE if DEBUG_CODE() macros are enabled.\r
\r
VOID\r
)\r
{\r
- return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);\r
+ return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_DEBUG_CODE_ENABLED) != 0);\r
}\r
\r
-\r
/**\r
Returns TRUE if DEBUG_CLEAR_MEMORY() macro is enabled.\r
\r
VOID\r
)\r
{\r
- return (BOOLEAN) ((PcdGet8(PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);\r
+ return (BOOLEAN)((PcdGet8 (PcdDebugPropertyMask) & DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED) != 0);\r
}\r
\r
/**\r
BOOLEAN\r
EFIAPI\r
DebugPrintLevelEnabled (\r
- IN CONST UINTN ErrorLevel\r
+ IN CONST UINTN ErrorLevel\r
)\r
{\r
- return (BOOLEAN) ((ErrorLevel & PcdGet32(PcdFixedDebugPrintErrorLevel)) != 0);\r
+ return (BOOLEAN)((ErrorLevel & PcdGet32 (PcdFixedDebugPrintErrorLevel)) != 0);\r
}\r
-\r