2 Library that helps implement monolithic PEI
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 #include <Library/ReportStatusCodeLib.h>
18 #include <Library/SerialPortLib.h>
19 #include <Library/PrintLib.h>
21 #include <Protocol/StatusCode.h>
22 #include <Guid/StatusCodeDataTypeId.h>
23 #include <Guid/StatusCodeDataTypeDebug.h>
24 #include <FrameworkPei.h>
28 SerialReportStatusCode (
29 IN EFI_STATUS_CODE_TYPE CodeType
,
30 IN EFI_STATUS_CODE_VALUE Value
,
32 IN CONST EFI_GUID
*CallerId
,
33 IN CONST EFI_STATUS_CODE_DATA
*Data OPTIONAL
37 EFI_STATUS_CODE_PROTOCOL gStatusCode
= {
38 (EFI_REPORT_STATUS_CODE
)SerialReportStatusCode
42 Extracts ASSERT() information from a status code structure.
44 Converts the status code specified by CodeType, Value, and Data to the ASSERT()
45 arguments specified by Filename, Description, and LineNumber. If CodeType is
46 an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and
47 Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract
48 Filename, Description, and LineNumber from the optional data area of the
49 status code buffer specified by Data. The optional data area of Data contains
50 a Null-terminated ASCII string for the FileName, followed by a Null-terminated
51 ASCII string for the Description, followed by a 32-bit LineNumber. If the
52 ASSERT() information could be extracted from Data, then return TRUE.
53 Otherwise, FALSE is returned.
55 If Data is NULL, then ASSERT().
56 If Filename is NULL, then ASSERT().
57 If Description is NULL, then ASSERT().
58 If LineNumber is NULL, then ASSERT().
60 @param CodeType The type of status code being converted.
61 @param Value The status code value being converted.
62 @param Data Pointer to status code data buffer.
63 @param Filename Pointer to the source file name that generated the ASSERT().
64 @param Description Pointer to the description of the ASSERT().
65 @param LineNumber Pointer to source line number that generated the ASSERT().
67 @retval TRUE The status code specified by CodeType, Value, and Data was
68 converted ASSERT() arguments specified by Filename, Description,
70 @retval FALSE The status code specified by CodeType, Value, and Data could
71 not be converted to ASSERT() arguments.
76 ReportStatusCodeExtractAssertInfo (
77 IN EFI_STATUS_CODE_TYPE CodeType
,
78 IN EFI_STATUS_CODE_VALUE Value
,
79 IN CONST EFI_STATUS_CODE_DATA
*Data
,
81 OUT CHAR8
**Description
,
82 OUT UINT32
*LineNumber
85 EFI_DEBUG_ASSERT_DATA
*AssertData
;
87 ASSERT (Data
!= NULL
);
88 ASSERT (Filename
!= NULL
);
89 ASSERT (Description
!= NULL
);
90 ASSERT (LineNumber
!= NULL
);
92 if (((CodeType
& EFI_STATUS_CODE_TYPE_MASK
) == EFI_ERROR_CODE
) &&
93 ((CodeType
& EFI_STATUS_CODE_SEVERITY_MASK
) == EFI_ERROR_UNRECOVERED
) &&
94 ((Value
& EFI_STATUS_CODE_OPERATION_MASK
) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE
)) {
95 AssertData
= (EFI_DEBUG_ASSERT_DATA
*)(Data
+ 1);
96 *Filename
= (CHAR8
*)(AssertData
+ 1);
97 *Description
= *Filename
+ AsciiStrLen (*Filename
) + 1;
98 *LineNumber
= AssertData
->LineNumber
;
106 Extracts DEBUG() information from a status code structure.
108 Converts the status code specified by Data to the DEBUG() arguments specified
109 by ErrorLevel, Marker, and Format. If type GUID in Data is
110 EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and
111 Format from the optional data area of the status code buffer specified by Data.
112 The optional data area of Data contains a 32-bit ErrorLevel followed by Marker
113 which is 12 UINTN parameters, followed by a Null-terminated ASCII string for
114 the Format. If the DEBUG() information could be extracted from Data, then
115 return TRUE. Otherwise, FALSE is returned.
117 If Data is NULL, then ASSERT().
118 If ErrorLevel is NULL, then ASSERT().
119 If Marker is NULL, then ASSERT().
120 If Format is NULL, then ASSERT().
122 @param Data Pointer to status code data buffer.
123 @param ErrorLevel Pointer to error level mask for a debug message.
124 @param Marker Pointer to the variable argument list associated with Format.
125 @param Format Pointer to a Null-terminated ASCII format string of a
128 @retval TRUE The status code specified by Data was converted DEBUG() arguments
129 specified by ErrorLevel, Marker, and Format.
130 @retval FALSE The status code specified by Data could not be converted to
136 ReportStatusCodeExtractDebugInfo (
137 IN CONST EFI_STATUS_CODE_DATA
*Data
,
138 OUT UINT32
*ErrorLevel
,
139 OUT BASE_LIST
*Marker
,
143 EFI_DEBUG_INFO
*DebugInfo
;
145 ASSERT (Data
!= NULL
);
146 ASSERT (ErrorLevel
!= NULL
);
147 ASSERT (Marker
!= NULL
);
148 ASSERT (Format
!= NULL
);
151 // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE
153 if (!CompareGuid (&Data
->Type
, &gEfiStatusCodeDataTypeDebugGuid
)) {
158 // Retrieve the debug information from the status code record
160 DebugInfo
= (EFI_DEBUG_INFO
*)(Data
+ 1);
162 *ErrorLevel
= DebugInfo
->ErrorLevel
;
165 // The first 12 * UINTN bytes of the string are really an
166 // argument stack to support varargs on the Format string.
168 *Marker
= (BASE_LIST
) (DebugInfo
+ 1);
169 *Format
= (CHAR8
*)(((UINT64
*)*Marker
) + 12);
179 SerialReportStatusCode (
180 IN EFI_STATUS_CODE_TYPE CodeType
,
181 IN EFI_STATUS_CODE_VALUE Value
,
183 IN CONST EFI_GUID
*CallerId
,
184 IN CONST EFI_STATUS_CODE_DATA
*Data OPTIONAL
190 CHAR8 Buffer
[EFI_STATUS_CODE_DATA_MAX_SIZE
];
195 EFI_DEBUG_INFO
*DebugInfo
;
201 ReportStatusCodeExtractAssertInfo (CodeType
, Value
, Data
, &Filename
, &Description
, &LineNumber
)) {
204 // Print ASSERT() information into output buffer.
206 CharCount
= AsciiSPrint (
208 EFI_STATUS_CODE_DATA_MAX_SIZE
,
209 "\n\rASSERT!: %a (%d): %a\n\r",
217 // Callout to standard output.
219 SerialPortWrite ((UINT8
*)Buffer
, CharCount
);
222 } else if (Data
!= NULL
&&
223 ReportStatusCodeExtractDebugInfo (Data
, &ErrorLevel
, &Marker
, &Format
)) {
226 // Print DEBUG() information into output buffer.
228 CharCount
= AsciiBSPrint (
230 EFI_STATUS_CODE_DATA_MAX_SIZE
,
235 } else if (Data
!= NULL
&&
236 CompareGuid (&Data
->Type
, &gEfiStatusCodeSpecificDataGuid
) &&
237 (CodeType
& EFI_STATUS_CODE_TYPE_MASK
) == EFI_DEBUG_CODE
) {
240 // Print specific data into output buffer.
242 DebugInfo
= (EFI_DEBUG_INFO
*) (Data
+ 1);
243 Marker
= (BASE_LIST
) (DebugInfo
+ 1);
244 Format
= (CHAR8
*) (((UINT64
*) (DebugInfo
+ 1)) + 12);
246 CharCount
= AsciiBSPrint (Buffer
, EFI_STATUS_CODE_DATA_MAX_SIZE
, Format
, Marker
);
248 } else if ((CodeType
& EFI_STATUS_CODE_TYPE_MASK
) == EFI_ERROR_CODE
) {
250 // Print ERROR information into output buffer.
253 CharCount
= AsciiSPrint (
255 EFI_STATUS_CODE_DATA_MAX_SIZE
,
256 "ERROR: C%x:V%x I%x",
263 // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.
265 if (CallerId
!= NULL
) {
266 CharCount
+= AsciiSPrint (
267 &Buffer
[CharCount
- 1],
268 (EFI_STATUS_CODE_DATA_MAX_SIZE
- (sizeof (Buffer
[0]) * CharCount
)),
275 CharCount
+= AsciiSPrint (
276 &Buffer
[CharCount
- 1],
277 (EFI_STATUS_CODE_DATA_MAX_SIZE
- (sizeof (Buffer
[0]) * CharCount
)),
285 CharCount
+= AsciiSPrint (
286 &Buffer
[CharCount
- 1],
287 (EFI_STATUS_CODE_DATA_MAX_SIZE
- (sizeof (Buffer
[0]) * CharCount
)),
291 } else if ((CodeType
& EFI_STATUS_CODE_TYPE_MASK
) == EFI_PROGRESS_CODE
) {
292 CharCount
= AsciiSPrint (
294 EFI_STATUS_CODE_DATA_MAX_SIZE
,
295 "PROGRESS CODE: V%x I%x\n\r",
300 CharCount
= AsciiSPrint (
302 EFI_STATUS_CODE_DATA_MAX_SIZE
,
303 "Undefined: C%x:V%x I%x\n\r",
311 SerialPortWrite ((UINT8
*)Buffer
, CharCount
);
319 AddDxeCoreReportStatusCodeCallback (
323 BuildGuidDataHob (&gEfiStatusCodeRuntimeProtocolGuid
, &gStatusCode
, sizeof(VOID
*));