#include <FrameworkPei.h>\r
#include <FrameworkModuleBase.h>\r
#include <Guid/StatusCodeDataTypeId.h>\r
+#include <Guid/StatusCodeDataTypeDebug.h>\r
\r
#include <Library/DebugLib.h>\r
#include <Library/BaseLib.h>\r
#include <Library/ReportStatusCodeLib.h>\r
#include <Library/PcdLib.h>\r
\r
-#include <DebugInfo.h>\r
-\r
/**\r
\r
Prints a debug message to the debug output device if the specified error level is enabled.\r
...\r
)\r
{\r
- UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof (UINT64)];\r
+ UINT64 Buffer[(EFI_STATUS_CODE_DATA_MAX_SIZE / sizeof (UINT64)) + 1];\r
EFI_DEBUG_INFO *DebugInfo;\r
UINTN TotalSize;\r
- UINTN Index;\r
- VA_LIST Marker;\r
- UINT64 *ArgumentPointer;\r
+ VA_LIST VaListMarker;\r
+ BASE_LIST BaseListMarker;\r
+ CHAR8 *FormatString;\r
+ BOOLEAN Long;\r
+ BOOLEAN Done;\r
\r
//\r
// If Format is NULL, then ASSERT().\r
return;\r
}\r
\r
+ //\r
+ // Compute the total size of the record\r
+ //\r
TotalSize = sizeof (EFI_DEBUG_INFO) + 12 * sizeof (UINT64) + AsciiStrLen (Format) + 1;\r
- if (TotalSize > EFI_STATUS_CODE_DATA_MAX_SIZE) {\r
+\r
+ //\r
+ // If the TotalSize is larger than the maximum record size, then return\r
+ //\r
+ if (TotalSize > sizeof (Buffer)) {\r
return;\r
}\r
\r
//\r
- // Then EFI_DEBUG_INFO\r
+ // Fill in EFI_DEBUG_INFO\r
//\r
- DebugInfo = (EFI_DEBUG_INFO *)Buffer;\r
+ DebugInfo = (EFI_DEBUG_INFO *)(Buffer) + 1;\r
DebugInfo->ErrorLevel = (UINT32)ErrorLevel;\r
+ BaseListMarker = (BASE_LIST)(DebugInfo + 1);\r
+ FormatString = (CHAR8 *)((UINT64 *)(DebugInfo + 1) + 12);\r
+\r
+ //\r
+ // Copy the Format string into the record\r
+ //\r
+ AsciiStrCpy (FormatString, Format);\r
\r
//\r
// 256 byte mini Var Arg stack. That is followed by the format string.\r
//\r
- VA_START (Marker, Format);\r
- for (Index = 0, ArgumentPointer = (UINT64 *)(DebugInfo + 1); Index < 12; Index++, ArgumentPointer++) {\r
- WriteUnaligned64(ArgumentPointer, VA_ARG (Marker, UINT64));\r
+ VA_START (VaListMarker, Format);\r
+ for (; *Format != '\0'; Format++) {\r
+ if (*Format != '%') {\r
+ continue;\r
+ }\r
+ Long = FALSE;\r
+ //\r
+ // Parse Flags and Width\r
+ //\r
+ for (Done = FALSE; !Done; ) {\r
+ Format++;\r
+ switch (*Format) {\r
+ case '.': \r
+ case '-': \r
+ case '+': \r
+ case ' ': \r
+ case ',': \r
+ case '0':\r
+ case '1':\r
+ case '2':\r
+ case '3':\r
+ case '4':\r
+ case '5':\r
+ case '6':\r
+ case '7':\r
+ case '8':\r
+ case '9':\r
+ break;\r
+ case 'L':\r
+ case 'l': \r
+ Long = TRUE;\r
+ break;\r
+ case '*':\r
+ BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);\r
+ break;\r
+ case '\0':\r
+ //\r
+ // Make no output if Format string terminates unexpectedly when\r
+ // looking up for flag, width, precision and type. \r
+ //\r
+ Format--;\r
+ //\r
+ // break skipped on purpose.\r
+ //\r
+ default:\r
+ Done = TRUE;\r
+ break;\r
+ }\r
+ } \r
+ \r
+ //\r
+ // Handle each argument type\r
+ //\r
+ switch (*Format) {\r
+ case 'p':\r
+ if (sizeof (VOID *) > 4) {\r
+ Long = TRUE;\r
+ }\r
+ case 'X':\r
+ case 'x':\r
+ case 'd':\r
+ if (Long) {\r
+ BASE_ARG (BaseListMarker, INT64) = VA_ARG (VaListMarker, INT64);\r
+ } else {\r
+ BASE_ARG (BaseListMarker, int) = VA_ARG (VaListMarker, int);\r
+ }\r
+ break;\r
+ case 's':\r
+ case 'S':\r
+ case 'a':\r
+ case 'g':\r
+ case 't':\r
+ BASE_ARG (BaseListMarker, VOID *) = VA_ARG (VaListMarker, VOID *);\r
+ break;\r
+ case 'c':\r
+ BASE_ARG (BaseListMarker, UINTN) = VA_ARG (VaListMarker, UINTN);\r
+ break;\r
+ case 'r':\r
+ BASE_ARG (BaseListMarker, RETURN_STATUS) = VA_ARG (VaListMarker, RETURN_STATUS);\r
+ break;\r
+ }\r
+\r
+ //\r
+ // If the converted BASE_LIST is larger than the 12 * sizeof (UINT64) allocated bytes, then ASSERT()\r
+ // This indicates that the DEBUG() macro is passing in more argument than can be handled by \r
+ // the EFI_DEBUG_INFO record\r
+ //\r
+ ASSERT ((CHAR8 *)BaseListMarker <= FormatString);\r
+\r
+ //\r
+ // If the converted BASE_LIST is larger than the 12 * sizeof (UINT64) allocated bytes, then return\r
+ //\r
+ if ((CHAR8 *)BaseListMarker > FormatString) {\r
+ return;\r
+ }\r
}\r
- VA_END (Marker);\r
- AsciiStrCpy ((CHAR8 *)ArgumentPointer, Format);\r
+ VA_END (VaListMarker);\r
\r
+ //\r
+ // Send the DebugInfo record\r
+ //\r
REPORT_STATUS_CODE_EX (\r
EFI_DEBUG_CODE,\r
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED),\r
);\r
}\r
\r
-\r
/**\r
\r
Prints an assert message containing a filename, line number, and description.\r
FileNameLength = AsciiStrLen (FileName);\r
DescriptionLength = AsciiStrLen (Description);\r
TotalSize = sizeof (EFI_DEBUG_ASSERT_DATA) + FileNameLength + 1 + DescriptionLength + 1;\r
- if (TotalSize <= EFI_STATUS_CODE_DATA_MAX_SIZE) {\r
+ if (TotalSize <= sizeof (Buffer)) {\r
//\r
// Fill in EFI_DEBUG_ASSERT_DATA\r
//\r
(EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE),\r
0,\r
NULL,\r
- &gEfiStatusCodeDataTypeAssertGuid,\r
+ NULL,\r
AssertData,\r
TotalSize\r
);\r