]> git.proxmox.com Git - mirror_edk2.git/blame - EmbeddedPkg/Library/PrePiLib/ReportStatusCode.c
ARM Packages: Removed trailing spaces
[mirror_edk2.git] / EmbeddedPkg / Library / PrePiLib / ReportStatusCode.c
CommitLineData
1e57a462 1/** @file\r
2 Library that helps implement monolithic PEI\r
3\r
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
3402aac7 5\r
1e57a462 6 This program and the accompanying materials\r
7 are licensed and made available under the terms and conditions of the BSD License\r
8 which accompanies this distribution. The full text of the license may be found at\r
9 http://opensource.org/licenses/bsd-license.php\r
10\r
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13\r
14**/\r
15\r
16#include <PrePi.h>\r
17#include <Library/ReportStatusCodeLib.h>\r
18#include <Library/SerialPortLib.h>\r
19#include <Library/PrintLib.h>\r
20\r
21#include <Protocol/StatusCode.h>\r
22#include <Guid/StatusCodeDataTypeId.h>\r
23#include <Guid/StatusCodeDataTypeDebug.h>\r
24#include <FrameworkPei.h>\r
25\r
1e57a462 26EFI_STATUS\r
27EFIAPI\r
28SerialReportStatusCode (\r
29 IN EFI_STATUS_CODE_TYPE CodeType,\r
30 IN EFI_STATUS_CODE_VALUE Value,\r
31 IN UINT32 Instance,\r
32 IN CONST EFI_GUID *CallerId,\r
33 IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL\r
34 );\r
35\r
36\r
3402aac7
RC
37EFI_STATUS_CODE_PROTOCOL gStatusCode = {\r
38 (EFI_REPORT_STATUS_CODE)SerialReportStatusCode\r
1e57a462 39};\r
40\r
41/**\r
42 Extracts ASSERT() information from a status code structure.\r
43\r
44 Converts the status code specified by CodeType, Value, and Data to the ASSERT()\r
45 arguments specified by Filename, Description, and LineNumber. If CodeType is\r
46 an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and\r
47 Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract\r
48 Filename, Description, and LineNumber from the optional data area of the\r
49 status code buffer specified by Data. The optional data area of Data contains\r
50 a Null-terminated ASCII string for the FileName, followed by a Null-terminated\r
51 ASCII string for the Description, followed by a 32-bit LineNumber. If the\r
52 ASSERT() information could be extracted from Data, then return TRUE.\r
53 Otherwise, FALSE is returned.\r
54\r
55 If Data is NULL, then ASSERT().\r
56 If Filename is NULL, then ASSERT().\r
57 If Description is NULL, then ASSERT().\r
58 If LineNumber is NULL, then ASSERT().\r
59\r
60 @param CodeType The type of status code being converted.\r
61 @param Value The status code value being converted.\r
62 @param Data Pointer to status code data buffer.\r
63 @param Filename Pointer to the source file name that generated the ASSERT().\r
64 @param Description Pointer to the description of the ASSERT().\r
65 @param LineNumber Pointer to source line number that generated the ASSERT().\r
66\r
67 @retval TRUE The status code specified by CodeType, Value, and Data was\r
68 converted ASSERT() arguments specified by Filename, Description,\r
69 and LineNumber.\r
70 @retval FALSE The status code specified by CodeType, Value, and Data could\r
71 not be converted to ASSERT() arguments.\r
72\r
73**/\r
74BOOLEAN\r
75EFIAPI\r
76ReportStatusCodeExtractAssertInfo (\r
77 IN EFI_STATUS_CODE_TYPE CodeType,\r
78 IN EFI_STATUS_CODE_VALUE Value,\r
79 IN CONST EFI_STATUS_CODE_DATA *Data,\r
80 OUT CHAR8 **Filename,\r
81 OUT CHAR8 **Description,\r
82 OUT UINT32 *LineNumber\r
83 )\r
84{\r
85 EFI_DEBUG_ASSERT_DATA *AssertData;\r
86\r
87 ASSERT (Data != NULL);\r
88 ASSERT (Filename != NULL);\r
89 ASSERT (Description != NULL);\r
90 ASSERT (LineNumber != NULL);\r
91\r
92 if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&\r
93 ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) &&\r
94 ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {\r
95 AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);\r
96 *Filename = (CHAR8 *)(AssertData + 1);\r
97 *Description = *Filename + AsciiStrLen (*Filename) + 1;\r
98 *LineNumber = AssertData->LineNumber;\r
99 return TRUE;\r
100 }\r
101 return FALSE;\r
102}\r
103\r
104\r
105/**\r
106 Extracts DEBUG() information from a status code structure.\r
107\r
108 Converts the status code specified by Data to the DEBUG() arguments specified\r
109 by ErrorLevel, Marker, and Format. If type GUID in Data is\r
110 EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and\r
111 Format from the optional data area of the status code buffer specified by Data.\r
112 The optional data area of Data contains a 32-bit ErrorLevel followed by Marker\r
113 which is 12 UINTN parameters, followed by a Null-terminated ASCII string for\r
114 the Format. If the DEBUG() information could be extracted from Data, then\r
115 return TRUE. Otherwise, FALSE is returned.\r
116\r
117 If Data is NULL, then ASSERT().\r
118 If ErrorLevel is NULL, then ASSERT().\r
119 If Marker is NULL, then ASSERT().\r
120 If Format is NULL, then ASSERT().\r
121\r
122 @param Data Pointer to status code data buffer.\r
123 @param ErrorLevel Pointer to error level mask for a debug message.\r
124 @param Marker Pointer to the variable argument list associated with Format.\r
125 @param Format Pointer to a Null-terminated ASCII format string of a\r
126 debug message.\r
127\r
128 @retval TRUE The status code specified by Data was converted DEBUG() arguments\r
129 specified by ErrorLevel, Marker, and Format.\r
130 @retval FALSE The status code specified by Data could not be converted to\r
131 DEBUG() arguments.\r
132\r
133**/\r
134BOOLEAN\r
135EFIAPI\r
136ReportStatusCodeExtractDebugInfo (\r
137 IN CONST EFI_STATUS_CODE_DATA *Data,\r
138 OUT UINT32 *ErrorLevel,\r
139 OUT BASE_LIST *Marker,\r
140 OUT CHAR8 **Format\r
141 )\r
142{\r
143 EFI_DEBUG_INFO *DebugInfo;\r
144\r
145 ASSERT (Data != NULL);\r
146 ASSERT (ErrorLevel != NULL);\r
147 ASSERT (Marker != NULL);\r
148 ASSERT (Format != NULL);\r
149\r
150 //\r
151 // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE\r
152 //\r
153 if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {\r
154 return FALSE;\r
155 }\r
156\r
157 //\r
158 // Retrieve the debug information from the status code record\r
159 //\r
160 DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);\r
161\r
162 *ErrorLevel = DebugInfo->ErrorLevel;\r
163\r
164 //\r
165 // The first 12 * UINTN bytes of the string are really an\r
166 // argument stack to support varargs on the Format string.\r
167 //\r
168 *Marker = (BASE_LIST) (DebugInfo + 1);\r
169 *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);\r
170\r
171 return TRUE;\r
172}\r
173\r
174\r
175\r
176\r
177EFI_STATUS\r
178EFIAPI\r
179SerialReportStatusCode (\r
180 IN EFI_STATUS_CODE_TYPE CodeType,\r
181 IN EFI_STATUS_CODE_VALUE Value,\r
182 IN UINT32 Instance,\r
183 IN CONST EFI_GUID *CallerId,\r
184 IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL\r
185 )\r
186{\r
187 CHAR8 *Filename;\r
188 CHAR8 *Description;\r
189 CHAR8 *Format;\r
190 CHAR8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];\r
191 UINT32 ErrorLevel;\r
192 UINT32 LineNumber;\r
193 UINTN CharCount;\r
194 BASE_LIST Marker;\r
195 EFI_DEBUG_INFO *DebugInfo;\r
196\r
197 Buffer[0] = '\0';\r
198\r
199\r
200 if (Data != NULL &&\r
201 ReportStatusCodeExtractAssertInfo (CodeType, Value, Data, &Filename, &Description, &LineNumber)) {\r
202\r
203 //\r
204 // Print ASSERT() information into output buffer.\r
205 //\r
206 CharCount = AsciiSPrint (\r
207 Buffer,\r
208 EFI_STATUS_CODE_DATA_MAX_SIZE,\r
209 "\n\rASSERT!: %a (%d): %a\n\r",\r
210 Filename,\r
211 LineNumber,\r
212 Description\r
213 );\r
214\r
215\r
216 //\r
217 // Callout to standard output.\r
218 //\r
219 SerialPortWrite ((UINT8 *)Buffer, CharCount);\r
220 return EFI_SUCCESS;\r
221\r
222 } else if (Data != NULL &&\r
223 ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {\r
3402aac7 224\r
1e57a462 225 //\r
226 // Print DEBUG() information into output buffer.\r
227 //\r
228 CharCount = AsciiBSPrint (\r
229 Buffer,\r
230 EFI_STATUS_CODE_DATA_MAX_SIZE,\r
231 Format,\r
232 Marker\r
233 );\r
234\r
235 } else if (Data != NULL &&\r
236 CompareGuid (&Data->Type, &gEfiStatusCodeSpecificDataGuid) &&\r
237 (CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE) {\r
238\r
239 //\r
240 // Print specific data into output buffer.\r
241 //\r
242 DebugInfo = (EFI_DEBUG_INFO *) (Data + 1);\r
243 Marker = (BASE_LIST) (DebugInfo + 1);\r
244 Format = (CHAR8 *) (((UINT64 *) (DebugInfo + 1)) + 12);\r
245\r
246 CharCount = AsciiBSPrint (Buffer, EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker);\r
247\r
248 } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) {\r
249 //\r
250 // Print ERROR information into output buffer.\r
251 //\r
252\r
253 CharCount = AsciiSPrint (\r
254 Buffer,\r
255 EFI_STATUS_CODE_DATA_MAX_SIZE,\r
256 "ERROR: C%x:V%x I%x",\r
257 CodeType,\r
258 Value,\r
259 Instance\r
260 );\r
261\r
262 //\r
263 // Make sure we don't try to print values that weren't intended to be printed, especially NULL GUID pointers.\r
264 //\r
265 if (CallerId != NULL) {\r
266 CharCount += AsciiSPrint (\r
267 &Buffer[CharCount - 1],\r
268 (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),\r
269 " %g",\r
270 CallerId\r
271 );\r
272 }\r
273\r
274 if (Data != NULL) {\r
275 CharCount += AsciiSPrint (\r
276 &Buffer[CharCount - 1],\r
277 (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),\r
278 " %x",\r
279 Data\r
280 );\r
281\r
282 }\r
283\r
284\r
285 CharCount += AsciiSPrint (\r
286 &Buffer[CharCount - 1],\r
287 (EFI_STATUS_CODE_DATA_MAX_SIZE - (sizeof (Buffer[0]) * CharCount)),\r
288 "\n\r"\r
289 );\r
290\r
291 } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {\r
292 CharCount = AsciiSPrint (\r
293 Buffer,\r
294 EFI_STATUS_CODE_DATA_MAX_SIZE,\r
295 "PROGRESS CODE: V%x I%x\n\r",\r
296 Value,\r
297 Instance\r
298 );\r
299 } else {\r
300 CharCount = AsciiSPrint (\r
301 Buffer,\r
302 EFI_STATUS_CODE_DATA_MAX_SIZE,\r
303 "Undefined: C%x:V%x I%x\n\r",\r
304 CodeType,\r
305 Value,\r
306 Instance\r
307 );\r
308\r
309 }\r
310\r
311 SerialPortWrite ((UINT8 *)Buffer, CharCount);\r
312 return EFI_SUCCESS;\r
313\r
314}\r
315\r
316\r
317VOID\r
318EFIAPI\r
319AddDxeCoreReportStatusCodeCallback (\r
320 VOID\r
321 )\r
322{\r
323 BuildGuidDataHob (&gEfiStatusCodeRuntimeProtocolGuid, &gStatusCode, sizeof(VOID *));\r
324}\r
325\r