+++ /dev/null
-/** @file\r
- Library that helps implement monolithic PEI\r
-\r
- Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include <PrePi.h>\r
-#include <Library/ReportStatusCodeLib.h>\r
-#include <Library/SerialPortLib.h>\r
-#include <Library/PrintLib.h>\r
-\r
-#include <Protocol/StatusCode.h>\r
-#include <Guid/StatusCodeDataTypeId.h>\r
-#include <Guid/StatusCodeDataTypeDebug.h>\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SerialReportStatusCode (\r
- IN EFI_STATUS_CODE_TYPE CodeType,\r
- IN EFI_STATUS_CODE_VALUE Value,\r
- IN UINT32 Instance,\r
- IN CONST EFI_GUID *CallerId,\r
- IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL\r
- );\r
-\r
-\r
-EFI_STATUS_CODE_PROTOCOL gStatusCode = {\r
- (EFI_REPORT_STATUS_CODE)SerialReportStatusCode\r
-};\r
-\r
-/**\r
- Extracts ASSERT() information from a status code structure.\r
-\r
- Converts the status code specified by CodeType, Value, and Data to the ASSERT()\r
- arguments specified by Filename, Description, and LineNumber. If CodeType is\r
- an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and\r
- Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract\r
- Filename, Description, and LineNumber from the optional data area of the\r
- status code buffer specified by Data. The optional data area of Data contains\r
- a Null-terminated ASCII string for the FileName, followed by a Null-terminated\r
- ASCII string for the Description, followed by a 32-bit LineNumber. If the\r
- ASSERT() information could be extracted from Data, then return TRUE.\r
- Otherwise, FALSE is returned.\r
-\r
- If Data is NULL, then ASSERT().\r
- If Filename is NULL, then ASSERT().\r
- If Description is NULL, then ASSERT().\r
- If LineNumber is NULL, then ASSERT().\r
-\r
- @param CodeType The type of status code being converted.\r
- @param Value The status code value being converted.\r
- @param Data Pointer to status code data buffer.\r
- @param Filename Pointer to the source file name that generated the ASSERT().\r
- @param Description Pointer to the description of the ASSERT().\r
- @param LineNumber Pointer to source line number that generated the ASSERT().\r
-\r
- @retval TRUE The status code specified by CodeType, Value, and Data was\r
- converted ASSERT() arguments specified by Filename, Description,\r
- and LineNumber.\r
- @retval FALSE The status code specified by CodeType, Value, and Data could\r
- not be converted to ASSERT() arguments.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-ReportStatusCodeExtractAssertInfo (\r
- IN EFI_STATUS_CODE_TYPE CodeType,\r
- IN EFI_STATUS_CODE_VALUE Value,\r
- IN CONST EFI_STATUS_CODE_DATA *Data,\r
- OUT CHAR8 **Filename,\r
- OUT CHAR8 **Description,\r
- OUT UINT32 *LineNumber\r
- )\r
-{\r
- EFI_DEBUG_ASSERT_DATA *AssertData;\r
-\r
- ASSERT (Data != NULL);\r
- ASSERT (Filename != NULL);\r
- ASSERT (Description != NULL);\r
- ASSERT (LineNumber != NULL);\r
-\r
- if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&\r
- ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) &&\r
- ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {\r
- AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);\r
- *Filename = (CHAR8 *)(AssertData + 1);\r
- *Description = *Filename + AsciiStrLen (*Filename) + 1;\r
- *LineNumber = AssertData->LineNumber;\r
- return TRUE;\r
- }\r
- return FALSE;\r
-}\r
-\r
-\r
-/**\r
- Extracts DEBUG() information from a status code structure.\r
-\r
- Converts the status code specified by Data to the DEBUG() arguments specified\r
- by ErrorLevel, Marker, and Format. If type GUID in Data is\r
- EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and\r
- Format from the optional data area of the status code buffer specified by Data.\r
- The optional data area of Data contains a 32-bit ErrorLevel followed by Marker\r
- which is 12 UINTN parameters, followed by a Null-terminated ASCII string for\r
- the Format. If the DEBUG() information could be extracted from Data, then\r
- return TRUE. Otherwise, FALSE is returned.\r
-\r
- If Data is NULL, then ASSERT().\r
- If ErrorLevel is NULL, then ASSERT().\r
- If Marker is NULL, then ASSERT().\r
- If Format is NULL, then ASSERT().\r
-\r
- @param Data Pointer to status code data buffer.\r
- @param ErrorLevel Pointer to error level mask for a debug message.\r
- @param Marker Pointer to the variable argument list associated with Format.\r
- @param Format Pointer to a Null-terminated ASCII format string of a\r
- debug message.\r
-\r
- @retval TRUE The status code specified by Data was converted DEBUG() arguments\r
- specified by ErrorLevel, Marker, and Format.\r
- @retval FALSE The status code specified by Data could not be converted to\r
- DEBUG() arguments.\r
-\r
-**/\r
-BOOLEAN\r
-EFIAPI\r
-ReportStatusCodeExtractDebugInfo (\r
- IN CONST EFI_STATUS_CODE_DATA *Data,\r
- OUT UINT32 *ErrorLevel,\r
- OUT BASE_LIST *Marker,\r
- OUT CHAR8 **Format\r
- )\r
-{\r
- EFI_DEBUG_INFO *DebugInfo;\r
-\r
- ASSERT (Data != NULL);\r
- ASSERT (ErrorLevel != NULL);\r
- ASSERT (Marker != NULL);\r
- ASSERT (Format != NULL);\r
-\r
- //\r
- // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE\r
- //\r
- if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {\r
- return FALSE;\r
- }\r
-\r
- //\r
- // Retrieve the debug information from the status code record\r
- //\r
- DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);\r
-\r
- *ErrorLevel = DebugInfo->ErrorLevel;\r
-\r
- //\r
- // The first 12 * UINTN bytes of the string are really an\r
- // argument stack to support varargs on the Format string.\r
- //\r
- *Marker = (BASE_LIST) (DebugInfo + 1);\r
- *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);\r
-\r
- return TRUE;\r
-}\r
-\r
-\r
-\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-SerialReportStatusCode (\r
- IN EFI_STATUS_CODE_TYPE CodeType,\r
- IN EFI_STATUS_CODE_VALUE Value,\r
- IN UINT32 Instance,\r
- IN CONST EFI_GUID *CallerId,\r
- IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL\r
- )\r
-{\r
- CHAR8 *Filename;\r
- CHAR8 *Description;\r
- CHAR8 *Format;\r
- CHAR8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];\r
- UINT32 ErrorLevel;\r
- UINT32 LineNumber;\r
- UINTN CharCount;\r
- BASE_LIST Marker;\r
- EFI_DEBUG_INFO *DebugInfo;\r
-\r
- Buffer[0] = '\0';\r
-\r
-\r
- if (Data != NULL &&\r
- ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {\r
-\r
- //\r
- // Print ASSERT() information into output buffer.\r
- //\r
- CharCount = AsciiSPrint (\r
- Buffer,\r
- EFI_STATUS_CODE_DATA_MAX_SIZE,\r
- "\n\rASSERT!: %a (%d): %a\n\r",\r
- Filename,\r
- LineNumber,\r
- Description\r
- );\r
-\r
-\r
- //\r
- // Callout to standard output.\r
- //\r
- SerialPortWrite ((UINT8 *)Buffer, CharCount);\r
- return EFI_SUCCESS;\r
-\r
- } else if (Data != NULL &&\r
- ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {\r
-\r
- //\r
- // Print DEBUG() information into output buffer.\r
- //\r
- CharCount = AsciiBSPrint (\r
- Buffer,\r
- EFI_STATUS_CODE_DATA_MAX_SIZE,\r
- Format,\r
- Marker\r
- );\r
-\r
- } else if (Data != NULL &&\r
- CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) &&\r
- (CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {\r
-\r
- //\r
- // Print specific data into output buffer.\r
- //\r
- DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);\r
- Marker = (BASE_LIST) (DebugInfo + 1);\r
- Format = (CHAR8 *) (((UINT64 *) (DebugInfo + 1)) + 12);\r
-\r
- CharCount = AsciiBSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);\r
-\r
- } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {\r
- //\r
- // Print ERROR information into output buffer.\r
- //\r
-\r
- CharCount = AsciiSPrint (\r
- Buffer,\r
- EFI_STATUS_CODE_DATA_MAX_SIZE,\r
- "ERROR: C%x:V%x I%x",\r
- CodeType,\r
- Value,\r
- Instance\r
- );\r
-\r
- //\r
- // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.\r
- //\r
- if (CallerId != NULL) {\r
- CharCount += AsciiSPrint (\r
- &Buffer[CharCount - 1],\r
- (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),\r
- " %g",\r
- CallerId\r
- );\r
- }\r
-\r
- if (Data != NULL) {\r
- CharCount += AsciiSPrint (\r
- &Buffer[CharCount - 1],\r
- (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),\r
- " %x",\r
- Data\r
- );\r
-\r
- }\r
-\r
-\r
- CharCount += AsciiSPrint (\r
- &Buffer[CharCount - 1],\r
- (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),\r
- "\n\r"\r
- );\r
-\r
- } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {\r
- CharCount = AsciiSPrint (\r
- Buffer,\r
- EFI_STATUS_CODE_DATA_MAX_SIZE,\r
- "PROGRESS CODE: V%x I%x\n\r",\r
- Value,\r
- Instance\r
- );\r
- } else {\r
- CharCount = AsciiSPrint (\r
- Buffer,\r
- EFI_STATUS_CODE_DATA_MAX_SIZE,\r
- "Undefined: C%x:V%x I%x\n\r",\r
- CodeType,\r
- Value,\r
- Instance\r
- );\r
-\r
- }\r
-\r
- SerialPortWrite ((UINT8 *)Buffer, CharCount);\r
- return EFI_SUCCESS;\r
-\r
-}\r
-\r
-\r
-VOID\r
-EFIAPI\r
-AddDxeCoreReportStatusCodeCallback (\r
- VOID\r
- )\r
-{\r
- BuildGuidDataHob (&gEfiStatusCodeRuntimeProtocolGuid, &gStatusCode, sizeof(VOID *));\r
-}\r
-\r