]> git.proxmox.com Git - mirror_edk2.git/blob - IntelFrameworkModulePkg/Library/SmmRuntimeDxeReportStatusCodeLibFramework/ReportStatusCodeLib.c
OvmfPkg/Csm/LegacyBiosDxe: Fix Legacy16GetTableAddress call for E820 data
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / SmmRuntimeDxeReportStatusCodeLibFramework / ReportStatusCodeLib.c
1 /** @file
2 API implementation for instance of Report Status Code Library.
3
4 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include "ReportStatusCodeLibInternal.h"
10
11 /**
12 Converts a status code to an 8-bit POST code value.
13
14 Converts the status code specified by CodeType and Value to an 8-bit POST code
15 and returns the 8-bit POST code in PostCode. If CodeType is an
16 EFI_PROGRESS_CODE or CodeType is an EFI_ERROR_CODE, then bits 0..4 of PostCode
17 are set to bits 16..20 of Value, and bits 5..7 of PostCode are set to bits
18 24..26 of Value., and TRUE is returned. Otherwise, FALSE is returned.
19
20 If PostCode is NULL, then ASSERT().
21
22 @param CodeType The type of status code being converted.
23 @param Value The status code value being converted.
24 @param PostCode A pointer to the 8-bit POST code value to return.
25
26 @retval TRUE The status code specified by CodeType and Value was converted
27 to an 8-bit POST code and returned in PostCode.
28 @retval FALSE The status code specified by CodeType and Value could not be
29 converted to an 8-bit POST code value.
30
31 **/
32 BOOLEAN
33 EFIAPI
34 CodeTypeToPostCode (
35 IN EFI_STATUS_CODE_TYPE CodeType,
36 IN EFI_STATUS_CODE_VALUE Value,
37 OUT UINT8 *PostCode
38 )
39 {
40 //
41 // If PostCode is NULL, then ASSERT()
42 //
43 ASSERT (PostCode != NULL);
44
45 //
46 // Convert Value to an 8 bit post code
47 //
48 if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ||
49 ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) ) {
50 *PostCode = (UINT8) ((((Value & EFI_STATUS_CODE_CLASS_MASK) >> 24) << 5) |
51 (((Value & EFI_STATUS_CODE_SUBCLASS_MASK) >> 16) & 0x1f));
52 return TRUE;
53 }
54 return FALSE;
55 }
56
57
58 /**
59 Extracts ASSERT() information from a status code structure.
60
61 Converts the status code specified by CodeType, Value, and Data to the ASSERT()
62 arguments specified by Filename, Description, and LineNumber. If CodeType is
63 an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and
64 Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract
65 Filename, Description, and LineNumber from the optional data area of the
66 status code buffer specified by Data. The optional data area of Data contains
67 a Null-terminated ASCII string for the FileName, followed by a Null-terminated
68 ASCII string for the Description, followed by a 32-bit LineNumber. If the
69 ASSERT() information could be extracted from Data, then return TRUE.
70 Otherwise, FALSE is returned.
71
72 If Data is NULL, then ASSERT().
73 If Filename is NULL, then ASSERT().
74 If Description is NULL, then ASSERT().
75 If LineNumber is NULL, then ASSERT().
76
77 @param CodeType The type of status code being converted.
78 @param Value The status code value being converted.
79 @param Data Pointer to status code data buffer.
80 @param Filename Pointer to the source file name that generated the ASSERT().
81 @param Description Pointer to the description of the ASSERT().
82 @param LineNumber Pointer to source line number that generated the ASSERT().
83
84 @retval TRUE The status code specified by CodeType, Value, and Data was
85 converted ASSERT() arguments specified by Filename, Description,
86 and LineNumber.
87 @retval FALSE The status code specified by CodeType, Value, and Data could
88 not be converted to ASSERT() arguments.
89
90 **/
91 BOOLEAN
92 EFIAPI
93 ReportStatusCodeExtractAssertInfo (
94 IN EFI_STATUS_CODE_TYPE CodeType,
95 IN EFI_STATUS_CODE_VALUE Value,
96 IN CONST EFI_STATUS_CODE_DATA *Data,
97 OUT CHAR8 **Filename,
98 OUT CHAR8 **Description,
99 OUT UINT32 *LineNumber
100 )
101 {
102 EFI_DEBUG_ASSERT_DATA *AssertData;
103
104 ASSERT (Data != NULL);
105 ASSERT (Filename != NULL);
106 ASSERT (Description != NULL);
107 ASSERT (LineNumber != NULL);
108
109 if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
110 ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) &&
111 ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)) {
112 AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
113 *Filename = (CHAR8 *)(AssertData + 1);
114 *Description = *Filename + AsciiStrLen (*Filename) + 1;
115 *LineNumber = AssertData->LineNumber;
116 return TRUE;
117 }
118 return FALSE;
119 }
120
121
122 /**
123 Extracts DEBUG() information from a status code structure.
124
125 Converts the status code specified by Data to the DEBUG() arguments specified
126 by ErrorLevel, Marker, and Format. If type GUID in Data is
127 EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and
128 Format from the optional data area of the status code buffer specified by Data.
129 The optional data area of Data contains a 32-bit ErrorLevel followed by Marker
130 which is 12 UINTN parameters, followed by a Null-terminated ASCII string for
131 the Format. If the DEBUG() information could be extracted from Data, then
132 return TRUE. Otherwise, FALSE is returned.
133
134 If Data is NULL, then ASSERT().
135 If ErrorLevel is NULL, then ASSERT().
136 If Marker is NULL, then ASSERT().
137 If Format is NULL, then ASSERT().
138
139 @param Data Pointer to status code data buffer.
140 @param ErrorLevel Pointer to error level mask for a debug message.
141 @param Marker Pointer to the variable argument list associated with Format.
142 @param Format Pointer to a Null-terminated ASCII format string of a
143 debug message.
144
145 @retval TRUE The status code specified by Data was converted DEBUG() arguments
146 specified by ErrorLevel, Marker, and Format.
147 @retval FALSE The status code specified by Data could not be converted to
148 DEBUG() arguments.
149
150 **/
151 BOOLEAN
152 EFIAPI
153 ReportStatusCodeExtractDebugInfo (
154 IN CONST EFI_STATUS_CODE_DATA *Data,
155 OUT UINT32 *ErrorLevel,
156 OUT BASE_LIST *Marker,
157 OUT CHAR8 **Format
158 )
159 {
160 EFI_DEBUG_INFO *DebugInfo;
161
162 ASSERT (Data != NULL);
163 ASSERT (ErrorLevel != NULL);
164 ASSERT (Marker != NULL);
165 ASSERT (Format != NULL);
166
167 //
168 // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE
169 //
170 if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {
171 return FALSE;
172 }
173
174 //
175 // Retrieve the debug information from the status code record
176 //
177 DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);
178
179 *ErrorLevel = DebugInfo->ErrorLevel;
180
181 //
182 // The first 12 * sizeof (UINT64) bytes following EFI_DEBUG_INFO are for variable arguments
183 // of format in DEBUG string. Its address is returned in Marker and has to be 64-bit aligned.
184 // It must be noticed that EFI_DEBUG_INFO follows EFI_STATUS_CODE_DATA, whose size is
185 // 20 bytes. The size of EFI_DEBUG_INFO is 4 bytes, so we can ensure that Marker
186 // returned is 64-bit aligned.
187 // 64-bit aligned is a must, otherwise retrieving 64-bit parameter from BASE_LIST will
188 // cause unalignment exception.
189 //
190 *Marker = (BASE_LIST) (DebugInfo + 1);
191 *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);
192
193 return TRUE;
194 }
195
196
197 /**
198 Reports a status code.
199
200 Reports the status code specified by the parameters Type and Value. Status
201 code also require an instance, caller ID, and extended data. This function
202 passed in a zero instance, NULL extended data, and a caller ID of
203 gEfiCallerIdGuid, which is the GUID for the module.
204
205 ReportStatusCode()must actively prevent recusrsion. If ReportStatusCode()
206 is called while processing another any other Report Status Code Library function,
207 then ReportStatusCode() must return immediately.
208
209 @param Type Status code type.
210 @param Value Status code value.
211
212 @retval EFI_SUCCESS The status code was reported.
213 @retval EFI_DEVICE_ERROR There status code could not be reported due to a
214 device error.
215 @retval EFI_UNSUPPORTED Report status code is not supported
216
217 **/
218 EFI_STATUS
219 EFIAPI
220 ReportStatusCode (
221 IN EFI_STATUS_CODE_TYPE Type,
222 IN EFI_STATUS_CODE_VALUE Value
223 )
224 {
225 return InternalReportStatusCode (Type, Value, 0, &gEfiCallerIdGuid, NULL);
226 }
227
228
229 /**
230 Reports a status code with a Device Path Protocol as the extended data.
231
232 Allocates and fills in the extended data section of a status code with the
233 Device Path Protocol specified by DevicePath. This function is responsible
234 for allocating a buffer large enough for the standard header and the device
235 path. The standard header is filled in with a GUID of
236 gEfiStatusCodeSpecificDataGuid. The status code is reported with a zero
237 instance and a caller ID of gEfiCallerIdGuid.
238
239 ReportStatusCodeWithDevicePath()must actively prevent recursion. If
240 ReportStatusCodeWithDevicePath() is called while processing another any other
241 Report Status Code Library function, then ReportStatusCodeWithDevicePath()
242 must return EFI_DEVICE_ERROR immediately.
243
244 If DevicePath is NULL, then ASSERT().
245
246 @param Type Status code type.
247 @param Value Status code value.
248 @param DevicePath Pointer to the Device Path Protocol to be reported.
249
250 @retval EFI_SUCCESS The status code was reported with the extended
251 data specified by DevicePath.
252 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the
253 extended data section.
254 @retval EFI_UNSUPPORTED Report status code is not supported
255
256 **/
257 EFI_STATUS
258 EFIAPI
259 ReportStatusCodeWithDevicePath (
260 IN EFI_STATUS_CODE_TYPE Type,
261 IN EFI_STATUS_CODE_VALUE Value,
262 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
263 )
264 {
265 ASSERT (DevicePath != NULL);
266 return ReportStatusCodeWithExtendedData (
267 Type,
268 Value,
269 (VOID *)DevicePath,
270 GetDevicePathSize (DevicePath)
271 );
272 }
273
274
275 /**
276 Reports a status code with an extended data buffer.
277
278 Allocates and fills in the extended data section of a status code with the
279 extended data specified by ExtendedData and ExtendedDataSize. ExtendedData
280 is assumed to be one of the data structures specified in Related Definitions.
281 These data structure do not have the standard header, so this function is
282 responsible for allocating a buffer large enough for the standard header and
283 the extended data passed into this function. The standard header is filled
284 in with a GUID of gEfiStatusCodeSpecificDataGuid. The status code is reported
285 with a zero instance and a caller ID of gEfiCallerIdGuid.
286
287 ReportStatusCodeWithExtendedData()must actively prevent recursion. If
288 ReportStatusCodeWithExtendedData() is called while processing another any other
289 Report Status Code Library function, then ReportStatusCodeWithExtendedData()
290 must return EFI_DEVICE_ERROR immediately.
291
292 If ExtendedData is NULL, then ASSERT().
293 If ExtendedDataSize is 0, then ASSERT().
294
295 @param Type Status code type.
296 @param Value Status code value.
297 @param ExtendedData Pointer to the extended data buffer to be reported.
298 @param ExtendedDataSize The size, in bytes, of the extended data buffer to
299 be reported.
300
301 @retval EFI_SUCCESS The status code was reported with the extended
302 data specified by ExtendedData and ExtendedDataSize.
303 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the
304 extended data section.
305 @retval EFI_UNSUPPORTED Report status code is not supported
306
307 **/
308 EFI_STATUS
309 EFIAPI
310 ReportStatusCodeWithExtendedData (
311 IN EFI_STATUS_CODE_TYPE Type,
312 IN EFI_STATUS_CODE_VALUE Value,
313 IN CONST VOID *ExtendedData,
314 IN UINTN ExtendedDataSize
315 )
316 {
317 ASSERT (ExtendedData != NULL);
318 ASSERT (ExtendedDataSize != 0);
319 return ReportStatusCodeEx (
320 Type,
321 Value,
322 0,
323 NULL,
324 NULL,
325 ExtendedData,
326 ExtendedDataSize
327 );
328 }
329
330
331 /**
332 Reports a status code with full parameters.
333
334 The function reports a status code. If ExtendedData is NULL and ExtendedDataSize
335 is 0, then an extended data buffer is not reported. If ExtendedData is not
336 NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.
337 ExtendedData is assumed not have the standard status code header, so this function
338 is responsible for allocating a buffer large enough for the standard header and
339 the extended data passed into this function. The standard header is filled in
340 with a GUID specified by ExtendedDataGuid. If ExtendedDataGuid is NULL, then a
341 GUID of gEfiStatusCodeSpecificDataGuid is used. The status code is reported with
342 an instance specified by Instance and a caller ID specified by CallerId. If
343 CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.
344
345 ReportStatusCodeEx()must actively prevent recursion. If
346 ReportStatusCodeEx() is called while processing another any
347 other Report Status Code Library function, then
348 ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.
349
350 If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().
351 If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().
352
353 @param Type Status code type.
354 @param Value Status code value.
355 @param Instance Status code instance number.
356 @param CallerId Pointer to a GUID that identifies the caller of this
357 function. If this parameter is NULL, then a caller
358 ID of gEfiCallerIdGuid is used.
359 @param ExtendedDataGuid Pointer to the GUID for the extended data buffer.
360 If this parameter is NULL, then a the status code
361 standard header is filled in with
362 gEfiStatusCodeSpecificDataGuid.
363 @param ExtendedData Pointer to the extended data buffer. This is an
364 optional parameter that may be NULL.
365 @param ExtendedDataSize The size, in bytes, of the extended data buffer.
366
367 @retval EFI_SUCCESS The status code was reported.
368 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate
369 the extended data section if it was specified.
370 @retval EFI_UNSUPPORTED Report status code is not supported
371
372 **/
373 EFI_STATUS
374 EFIAPI
375 ReportStatusCodeEx (
376 IN EFI_STATUS_CODE_TYPE Type,
377 IN EFI_STATUS_CODE_VALUE Value,
378 IN UINT32 Instance,
379 IN CONST EFI_GUID *CallerId OPTIONAL,
380 IN CONST EFI_GUID *ExtendedDataGuid OPTIONAL,
381 IN CONST VOID *ExtendedData OPTIONAL,
382 IN UINTN ExtendedDataSize
383 )
384 {
385 EFI_STATUS Status;
386
387 ASSERT (!((ExtendedData == NULL) && (ExtendedDataSize != 0)));
388 ASSERT (!((ExtendedData != NULL) && (ExtendedDataSize == 0)));
389
390 if (ExtendedDataSize > EFI_STATUS_CODE_DATA_MAX_SIZE) {
391 DEBUG ((EFI_D_ERROR, "Status code extended data is too large to be reported!\n"));
392 return EFI_OUT_OF_RESOURCES;
393 }
394
395 //
396 // Fill in the extended data header
397 //
398 mStatusCodeData->HeaderSize = (UINT16) sizeof (EFI_STATUS_CODE_DATA);
399 mStatusCodeData->Size = (UINT16)ExtendedDataSize;
400 if (ExtendedDataGuid == NULL) {
401 ExtendedDataGuid = &gEfiStatusCodeSpecificDataGuid;
402 }
403 CopyGuid (&mStatusCodeData->Type, ExtendedDataGuid);
404
405 //
406 // Fill in the extended data buffer
407 //
408 if (ExtendedData != NULL) {
409 CopyMem (mStatusCodeData + 1, ExtendedData, ExtendedDataSize);
410 }
411
412 //
413 // Report the status code
414 //
415 if (CallerId == NULL) {
416 CallerId = &gEfiCallerIdGuid;
417 }
418 Status = InternalReportStatusCode (Type, Value, Instance, CallerId, mStatusCodeData);
419
420 return Status;
421 }
422
423
424 /**
425 Returns TRUE if status codes of type EFI_PROGRESS_CODE are enabled
426
427 This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED
428 bit of PcdReportStatusCodeProperyMask is set. Otherwise FALSE is returned.
429
430 @retval TRUE The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of
431 PcdReportStatusCodeProperyMask is set.
432 @retval FALSE The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of
433 PcdReportStatusCodeProperyMask is clear.
434
435 **/
436 BOOLEAN
437 EFIAPI
438 ReportProgressCodeEnabled (
439 VOID
440 )
441 {
442 return (BOOLEAN) ((PcdGet8 (PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED) != 0);
443 }
444
445
446 /**
447 Returns TRUE if status codes of type EFI_ERROR_CODE are enabled
448
449 This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED
450 bit of PcdReportStatusCodeProperyMask is set. Otherwise FALSE is returned.
451
452 @retval TRUE The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of
453 PcdReportStatusCodeProperyMask is set.
454 @retval FALSE The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of
455 PcdReportStatusCodeProperyMask is clear.
456
457 **/
458 BOOLEAN
459 EFIAPI
460 ReportErrorCodeEnabled (
461 VOID
462 )
463 {
464 return (BOOLEAN) ((PcdGet8 (PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED) != 0);
465 }
466
467
468 /**
469 Returns TRUE if status codes of type EFI_DEBUG_CODE are enabled
470
471 This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED
472 bit of PcdReportStatusCodeProperyMask is set. Otherwise FALSE is returned.
473
474 @retval TRUE The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of
475 PcdReportStatusCodeProperyMask is set.
476 @retval FALSE The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of
477 PcdReportStatusCodeProperyMask is clear.
478
479 **/
480 BOOLEAN
481 EFIAPI
482 ReportDebugCodeEnabled (
483 VOID
484 )
485 {
486 return (BOOLEAN) ((PcdGet8 (PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED) != 0);
487 }