]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/ReportStatusCodeLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / MdeModulePkg / Library / RuntimeDxeReportStatusCodeLib / ReportStatusCodeLib.c
1 /** @file
2 API implementation for instance of Report Status Code Library.
3
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
6
7 **/
8
9 #include <Library/ReportStatusCodeLib.h>
10 #include <Library/BaseLib.h>
11 #include <Library/DebugLib.h>
12 #include <Library/UefiBootServicesTableLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/PcdLib.h>
15 #include <Library/DevicePathLib.h>
16 #include <Library/UefiRuntimeLib.h>
17
18 #include <Protocol/StatusCode.h>
19
20 #include <Guid/StatusCodeDataTypeId.h>
21 #include <Guid/StatusCodeDataTypeDebug.h>
22 #include <Guid/EventGroup.h>
23
24 EFI_STATUS_CODE_PROTOCOL *mReportStatusCodeLibStatusCodeProtocol = NULL;
25 EFI_EVENT mReportStatusCodeLibVirtualAddressChangeEvent;
26 EFI_EVENT mReportStatusCodeLibExitBootServicesEvent;
27 BOOLEAN mHaveExitedBootServices = FALSE;
28
29 /**
30 Locate the report status code service.
31
32 Retrieve ReportStatusCode() API of Report Status Code Protocol.
33
34 **/
35 VOID
36 InternalGetReportStatusCode (
37 VOID
38 )
39 {
40 EFI_STATUS Status;
41
42 if (mReportStatusCodeLibStatusCodeProtocol != NULL) {
43 return;
44 }
45
46 if (mHaveExitedBootServices) {
47 return;
48 }
49
50 //
51 // Check gBS just in case ReportStatusCode is called before gBS is initialized.
52 //
53 if ((gBS != NULL) && (gBS->LocateProtocol != NULL)) {
54 Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID **)&mReportStatusCodeLibStatusCodeProtocol);
55 if (EFI_ERROR (Status)) {
56 mReportStatusCodeLibStatusCodeProtocol = NULL;
57 }
58 }
59 }
60
61 /**
62 Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
63
64 @param Event Event whose notification function is being invoked.
65 @param Context Pointer to the notification function's context
66
67 **/
68 VOID
69 EFIAPI
70 ReportStatusCodeLibVirtualAddressChange (
71 IN EFI_EVENT Event,
72 IN VOID *Context
73 )
74 {
75 if (mReportStatusCodeLibStatusCodeProtocol == NULL) {
76 return;
77 }
78
79 EfiConvertPointer (0, (VOID **)&mReportStatusCodeLibStatusCodeProtocol);
80 }
81
82 /**
83 Notification function of EVT_SIGNAL_EXIT_BOOT_SERVICES.
84
85 @param Event Event whose notification function is being invoked.
86 @param Context Pointer to the notification function's context
87
88 **/
89 VOID
90 EFIAPI
91 ReportStatusCodeLibExitBootServices (
92 IN EFI_EVENT Event,
93 IN VOID *Context
94 )
95 {
96 //
97 // Locate the report status code service before enter runtime.
98 //
99 InternalGetReportStatusCode ();
100
101 mHaveExitedBootServices = TRUE;
102 }
103
104 /**
105 The constructor function of Runtime DXE Report Status Code Lib.
106
107 This function allocates memory for extended status code data, caches
108 the report status code service, and registers events.
109
110 @param ImageHandle The firmware allocated handle for the EFI image.
111 @param SystemTable A pointer to the EFI System Table.
112
113 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
114
115 **/
116 EFI_STATUS
117 EFIAPI
118 ReportStatusCodeLibConstructor (
119 IN EFI_HANDLE ImageHandle,
120 IN EFI_SYSTEM_TABLE *SystemTable
121 )
122 {
123 EFI_STATUS Status;
124
125 //
126 // Cache the report status code service
127 //
128 InternalGetReportStatusCode ();
129
130 //
131 // Register notify function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
132 //
133 Status = gBS->CreateEventEx (
134 EVT_NOTIFY_SIGNAL,
135 TPL_NOTIFY,
136 ReportStatusCodeLibVirtualAddressChange,
137 NULL,
138 &gEfiEventVirtualAddressChangeGuid,
139 &mReportStatusCodeLibVirtualAddressChangeEvent
140 );
141 ASSERT_EFI_ERROR (Status);
142
143 //
144 // Register notify function for EVT_SIGNAL_EXIT_BOOT_SERVICES
145 //
146 Status = gBS->CreateEventEx (
147 EVT_NOTIFY_SIGNAL,
148 TPL_NOTIFY,
149 ReportStatusCodeLibExitBootServices,
150 NULL,
151 &gEfiEventExitBootServicesGuid,
152 &mReportStatusCodeLibExitBootServicesEvent
153 );
154 ASSERT_EFI_ERROR (Status);
155
156 return EFI_SUCCESS;
157 }
158
159 /**
160 The destructor function of Runtime DXE Report Status Code Lib.
161
162 The destructor function frees memory allocated by constructor, and closes related events.
163 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS.
164
165 @param ImageHandle The firmware allocated handle for the EFI image.
166 @param SystemTable A pointer to the EFI System Table.
167
168 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
169
170 **/
171 EFI_STATUS
172 EFIAPI
173 ReportStatusCodeLibDestructor (
174 IN EFI_HANDLE ImageHandle,
175 IN EFI_SYSTEM_TABLE *SystemTable
176 )
177 {
178 EFI_STATUS Status;
179
180 ASSERT (gBS != NULL);
181 Status = gBS->CloseEvent (mReportStatusCodeLibVirtualAddressChangeEvent);
182 ASSERT_EFI_ERROR (Status);
183
184 Status = gBS->CloseEvent (mReportStatusCodeLibExitBootServicesEvent);
185 ASSERT_EFI_ERROR (Status);
186
187 return EFI_SUCCESS;
188 }
189
190 /**
191 Internal worker function that reports a status code through the Report Status Code Protocol.
192
193 If status code service is not cached, then this function checks if Report Status Code
194 Protocol is available in system. If Report Status Code Protocol is not available, then
195 EFI_UNSUPPORTED is returned. If Report Status Code Protocol is present, then it is
196 cached in mReportStatusCodeLibStatusCodeProtocol. Finally this function reports status
197 code through the Report Status Code Protocol.
198
199 @param Type Status code type.
200 @param Value Status code value.
201 @param Instance Status code instance number.
202 @param CallerId Pointer to a GUID that identifies the caller of this
203 function. This is an optional parameter that may be
204 NULL.
205 @param Data Pointer to the extended data buffer. This is an
206 optional parameter that may be NULL.
207
208 @retval EFI_SUCCESS The status code was reported.
209 @retval EFI_UNSUPPORTED Report Status Code Protocol is not available.
210 @retval EFI_UNSUPPORTED Status code type is not supported.
211
212 **/
213 EFI_STATUS
214 InternalReportStatusCode (
215 IN EFI_STATUS_CODE_TYPE Type,
216 IN EFI_STATUS_CODE_VALUE Value,
217 IN UINT32 Instance,
218 IN CONST EFI_GUID *CallerId OPTIONAL,
219 IN EFI_STATUS_CODE_DATA *Data OPTIONAL
220 )
221 {
222 if ((ReportProgressCodeEnabled () && (((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE)) ||
223 (ReportErrorCodeEnabled () && (((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)) ||
224 (ReportDebugCodeEnabled () && (((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE)))
225 {
226 //
227 // If mReportStatusCodeLibStatusCodeProtocol is NULL, then check if Report Status Code Protocol is available in system.
228 //
229 InternalGetReportStatusCode ();
230 if (mReportStatusCodeLibStatusCodeProtocol == NULL) {
231 return EFI_UNSUPPORTED;
232 }
233
234 //
235 // A Report Status Code Protocol is present in system, so pass in all the parameters to the service.
236 //
237 return mReportStatusCodeLibStatusCodeProtocol->ReportStatusCode (Type, Value, Instance, (EFI_GUID *)CallerId, Data);
238 }
239
240 return EFI_UNSUPPORTED;
241 }
242
243 /**
244 Converts a status code to an 8-bit POST code value.
245
246 Converts the status code specified by CodeType and Value to an 8-bit POST code
247 and returns the 8-bit POST code in PostCode. If CodeType is an
248 EFI_PROGRESS_CODE or CodeType is an EFI_ERROR_CODE, then bits 0..4 of PostCode
249 are set to bits 16..20 of Value, and bits 5..7 of PostCode are set to bits
250 24..26 of Value., and TRUE is returned. Otherwise, FALSE is returned.
251
252 If PostCode is NULL, then ASSERT().
253
254 @param CodeType The type of status code being converted.
255 @param Value The status code value being converted.
256 @param PostCode A pointer to the 8-bit POST code value to return.
257
258 @retval TRUE The status code specified by CodeType and Value was converted
259 to an 8-bit POST code and returned in PostCode.
260 @retval FALSE The status code specified by CodeType and Value could not be
261 converted to an 8-bit POST code value.
262
263 **/
264 BOOLEAN
265 EFIAPI
266 CodeTypeToPostCode (
267 IN EFI_STATUS_CODE_TYPE CodeType,
268 IN EFI_STATUS_CODE_VALUE Value,
269 OUT UINT8 *PostCode
270 )
271 {
272 //
273 // If PostCode is NULL, then ASSERT()
274 //
275 ASSERT (PostCode != NULL);
276
277 //
278 // Convert Value to an 8 bit post code
279 //
280 if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ||
281 ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE))
282 {
283 *PostCode = (UINT8)((((Value & EFI_STATUS_CODE_CLASS_MASK) >> 24) << 5) |
284 (((Value & EFI_STATUS_CODE_SUBCLASS_MASK) >> 16) & 0x1f));
285 return TRUE;
286 }
287
288 return FALSE;
289 }
290
291 /**
292 Extracts ASSERT() information from a status code structure.
293
294 Converts the status code specified by CodeType, Value, and Data to the ASSERT()
295 arguments specified by Filename, Description, and LineNumber. If CodeType is
296 an EFI_ERROR_CODE, and CodeType has a severity of EFI_ERROR_UNRECOVERED, and
297 Value has an operation mask of EFI_SW_EC_ILLEGAL_SOFTWARE_STATE, extract
298 Filename, Description, and LineNumber from the optional data area of the
299 status code buffer specified by Data. The optional data area of Data contains
300 a Null-terminated ASCII string for the FileName, followed by a Null-terminated
301 ASCII string for the Description, followed by a 32-bit LineNumber. If the
302 ASSERT() information could be extracted from Data, then return TRUE.
303 Otherwise, FALSE is returned.
304
305 If Data is NULL, then ASSERT().
306 If Filename is NULL, then ASSERT().
307 If Description is NULL, then ASSERT().
308 If LineNumber is NULL, then ASSERT().
309
310 @param CodeType The type of status code being converted.
311 @param Value The status code value being converted.
312 @param Data Pointer to status code data buffer.
313 @param Filename Pointer to the source file name that generated the ASSERT().
314 @param Description Pointer to the description of the ASSERT().
315 @param LineNumber Pointer to source line number that generated the ASSERT().
316
317 @retval TRUE The status code specified by CodeType, Value, and Data was
318 converted ASSERT() arguments specified by Filename, Description,
319 and LineNumber.
320 @retval FALSE The status code specified by CodeType, Value, and Data could
321 not be converted to ASSERT() arguments.
322
323 **/
324 BOOLEAN
325 EFIAPI
326 ReportStatusCodeExtractAssertInfo (
327 IN EFI_STATUS_CODE_TYPE CodeType,
328 IN EFI_STATUS_CODE_VALUE Value,
329 IN CONST EFI_STATUS_CODE_DATA *Data,
330 OUT CHAR8 **Filename,
331 OUT CHAR8 **Description,
332 OUT UINT32 *LineNumber
333 )
334 {
335 EFI_DEBUG_ASSERT_DATA *AssertData;
336
337 ASSERT (Data != NULL);
338 ASSERT (Filename != NULL);
339 ASSERT (Description != NULL);
340 ASSERT (LineNumber != NULL);
341
342 if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
343 ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) &&
344 ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE))
345 {
346 AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
347 *Filename = (CHAR8 *)(AssertData + 1);
348 *Description = *Filename + AsciiStrLen (*Filename) + 1;
349 *LineNumber = AssertData->LineNumber;
350 return TRUE;
351 }
352
353 return FALSE;
354 }
355
356 /**
357 Extracts DEBUG() information from a status code structure.
358
359 Converts the status code specified by Data to the DEBUG() arguments specified
360 by ErrorLevel, Marker, and Format. If type GUID in Data is
361 EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID, then extract ErrorLevel, Marker, and
362 Format from the optional data area of the status code buffer specified by Data.
363 The optional data area of Data contains a 32-bit ErrorLevel followed by Marker
364 which is 12 UINTN parameters, followed by a Null-terminated ASCII string for
365 the Format. If the DEBUG() information could be extracted from Data, then
366 return TRUE. Otherwise, FALSE is returned.
367
368 If Data is NULL, then ASSERT().
369 If ErrorLevel is NULL, then ASSERT().
370 If Marker is NULL, then ASSERT().
371 If Format is NULL, then ASSERT().
372
373 @param Data Pointer to status code data buffer.
374 @param ErrorLevel Pointer to error level mask for a debug message.
375 @param Marker Pointer to the variable argument list associated with Format.
376 @param Format Pointer to a Null-terminated ASCII format string of a
377 debug message.
378
379 @retval TRUE The status code specified by Data was converted DEBUG() arguments
380 specified by ErrorLevel, Marker, and Format.
381 @retval FALSE The status code specified by Data could not be converted to
382 DEBUG() arguments.
383
384 **/
385 BOOLEAN
386 EFIAPI
387 ReportStatusCodeExtractDebugInfo (
388 IN CONST EFI_STATUS_CODE_DATA *Data,
389 OUT UINT32 *ErrorLevel,
390 OUT BASE_LIST *Marker,
391 OUT CHAR8 **Format
392 )
393 {
394 EFI_DEBUG_INFO *DebugInfo;
395
396 ASSERT (Data != NULL);
397 ASSERT (ErrorLevel != NULL);
398 ASSERT (Marker != NULL);
399 ASSERT (Format != NULL);
400
401 //
402 // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE
403 //
404 if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {
405 return FALSE;
406 }
407
408 //
409 // Retrieve the debug information from the status code record
410 //
411 DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);
412
413 *ErrorLevel = DebugInfo->ErrorLevel;
414
415 //
416 // The first 12 * sizeof (UINT64) bytes following EFI_DEBUG_INFO are for variable arguments
417 // of format in DEBUG string. Its address is returned in Marker and has to be 64-bit aligned.
418 // It must be noticed that EFI_DEBUG_INFO follows EFI_STATUS_CODE_DATA, whose size is
419 // 20 bytes. The size of EFI_DEBUG_INFO is 4 bytes, so we can ensure that Marker
420 // returned is 64-bit aligned.
421 // 64-bit aligned is a must, otherwise retrieving 64-bit parameter from BASE_LIST will
422 // cause unalignment exception.
423 //
424 *Marker = (BASE_LIST)(DebugInfo + 1);
425 *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);
426
427 return TRUE;
428 }
429
430 /**
431 Reports a status code.
432
433 Reports the status code specified by the parameters Type and Value. Status
434 code also require an instance, caller ID, and extended data. This function
435 passed in a zero instance, NULL extended data, and a caller ID of
436 gEfiCallerIdGuid, which is the GUID for the module.
437
438 ReportStatusCode()must actively prevent recusrsion. If ReportStatusCode()
439 is called while processing another any other Report Status Code Library function,
440 then ReportStatusCode() must return immediately.
441
442 @param Type Status code type.
443 @param Value Status code value.
444
445 @retval EFI_SUCCESS The status code was reported.
446 @retval EFI_DEVICE_ERROR There status code could not be reported due to a
447 device error.
448 @retval EFI_UNSUPPORTED Report status code is not supported
449
450 **/
451 EFI_STATUS
452 EFIAPI
453 ReportStatusCode (
454 IN EFI_STATUS_CODE_TYPE Type,
455 IN EFI_STATUS_CODE_VALUE Value
456 )
457 {
458 return InternalReportStatusCode (Type, Value, 0, &gEfiCallerIdGuid, NULL);
459 }
460
461 /**
462 Reports a status code with a Device Path Protocol as the extended data.
463
464 Allocates and fills in the extended data section of a status code with the
465 Device Path Protocol specified by DevicePath. This function is responsible
466 for allocating a buffer large enough for the standard header and the device
467 path. The standard header is filled in with a GUID of
468 gEfiStatusCodeSpecificDataGuid. The status code is reported with a zero
469 instance and a caller ID of gEfiCallerIdGuid.
470
471 ReportStatusCodeWithDevicePath()must actively prevent recursion. If
472 ReportStatusCodeWithDevicePath() is called while processing another any other
473 Report Status Code Library function, then ReportStatusCodeWithDevicePath()
474 must return EFI_DEVICE_ERROR immediately.
475
476 If DevicePath is NULL, then ASSERT().
477
478 @param Type Status code type.
479 @param Value Status code value.
480 @param DevicePath Pointer to the Device Path Protocol to be reported.
481
482 @retval EFI_SUCCESS The status code was reported with the extended
483 data specified by DevicePath.
484 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the
485 extended data section.
486 @retval EFI_UNSUPPORTED Report status code is not supported
487
488 **/
489 EFI_STATUS
490 EFIAPI
491 ReportStatusCodeWithDevicePath (
492 IN EFI_STATUS_CODE_TYPE Type,
493 IN EFI_STATUS_CODE_VALUE Value,
494 IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
495 )
496 {
497 ASSERT (DevicePath != NULL);
498 return ReportStatusCodeWithExtendedData (
499 Type,
500 Value,
501 (VOID *)DevicePath,
502 GetDevicePathSize (DevicePath)
503 );
504 }
505
506 /**
507 Reports a status code with an extended data buffer.
508
509 Allocates and fills in the extended data section of a status code with the
510 extended data specified by ExtendedData and ExtendedDataSize. ExtendedData
511 is assumed to be one of the data structures specified in Related Definitions.
512 These data structure do not have the standard header, so this function is
513 responsible for allocating a buffer large enough for the standard header and
514 the extended data passed into this function. The standard header is filled
515 in with a GUID of gEfiStatusCodeSpecificDataGuid. The status code is reported
516 with a zero instance and a caller ID of gEfiCallerIdGuid.
517
518 ReportStatusCodeWithExtendedData()must actively prevent recursion. If
519 ReportStatusCodeWithExtendedData() is called while processing another any other
520 Report Status Code Library function, then ReportStatusCodeWithExtendedData()
521 must return EFI_DEVICE_ERROR immediately.
522
523 If ExtendedData is NULL, then ASSERT().
524 If ExtendedDataSize is 0, then ASSERT().
525
526 @param Type Status code type.
527 @param Value Status code value.
528 @param ExtendedData Pointer to the extended data buffer to be reported.
529 @param ExtendedDataSize The size, in bytes, of the extended data buffer to
530 be reported.
531
532 @retval EFI_SUCCESS The status code was reported with the extended
533 data specified by ExtendedData and ExtendedDataSize.
534 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate the
535 extended data section.
536 @retval EFI_UNSUPPORTED Report status code is not supported
537
538 **/
539 EFI_STATUS
540 EFIAPI
541 ReportStatusCodeWithExtendedData (
542 IN EFI_STATUS_CODE_TYPE Type,
543 IN EFI_STATUS_CODE_VALUE Value,
544 IN CONST VOID *ExtendedData,
545 IN UINTN ExtendedDataSize
546 )
547 {
548 ASSERT (ExtendedData != NULL);
549 ASSERT (ExtendedDataSize != 0);
550 return ReportStatusCodeEx (
551 Type,
552 Value,
553 0,
554 NULL,
555 NULL,
556 ExtendedData,
557 ExtendedDataSize
558 );
559 }
560
561 /**
562 Reports a status code with full parameters.
563
564 The function reports a status code. If ExtendedData is NULL and ExtendedDataSize
565 is 0, then an extended data buffer is not reported. If ExtendedData is not
566 NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.
567 ExtendedData is assumed not have the standard status code header, so this function
568 is responsible for allocating a buffer large enough for the standard header and
569 the extended data passed into this function. The standard header is filled in
570 with a GUID specified by ExtendedDataGuid. If ExtendedDataGuid is NULL, then a
571 GUID of gEfiStatusCodeSpecificDataGuid is used. The status code is reported with
572 an instance specified by Instance and a caller ID specified by CallerId. If
573 CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.
574
575 ReportStatusCodeEx()must actively prevent recursion. If
576 ReportStatusCodeEx() is called while processing another any
577 other Report Status Code Library function, then
578 ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.
579
580 If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().
581 If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().
582
583 @param Type Status code type.
584 @param Value Status code value.
585 @param Instance Status code instance number.
586 @param CallerId Pointer to a GUID that identifies the caller of this
587 function. If this parameter is NULL, then a caller
588 ID of gEfiCallerIdGuid is used.
589 @param ExtendedDataGuid Pointer to the GUID for the extended data buffer.
590 If this parameter is NULL, then a the status code
591 standard header is filled in with
592 gEfiStatusCodeSpecificDataGuid.
593 @param ExtendedData Pointer to the extended data buffer. This is an
594 optional parameter that may be NULL.
595 @param ExtendedDataSize The size, in bytes, of the extended data buffer.
596
597 @retval EFI_SUCCESS The status code was reported.
598 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate
599 the extended data section if it was specified.
600 @retval EFI_UNSUPPORTED Report status code is not supported
601
602 **/
603 EFI_STATUS
604 EFIAPI
605 ReportStatusCodeEx (
606 IN EFI_STATUS_CODE_TYPE Type,
607 IN EFI_STATUS_CODE_VALUE Value,
608 IN UINT32 Instance,
609 IN CONST EFI_GUID *CallerId OPTIONAL,
610 IN CONST EFI_GUID *ExtendedDataGuid OPTIONAL,
611 IN CONST VOID *ExtendedData OPTIONAL,
612 IN UINTN ExtendedDataSize
613 )
614 {
615 EFI_STATUS Status;
616 EFI_STATUS_CODE_DATA *StatusCodeData;
617 UINT64 StatusCodeBuffer[(MAX_EXTENDED_DATA_SIZE / sizeof (UINT64)) + 1];
618
619 ASSERT (!((ExtendedData == NULL) && (ExtendedDataSize != 0)));
620 ASSERT (!((ExtendedData != NULL) && (ExtendedDataSize == 0)));
621
622 if (ExtendedDataSize <= (MAX_EXTENDED_DATA_SIZE - sizeof (EFI_STATUS_CODE_DATA))) {
623 //
624 // Use Buffer instead of allocating if possible.
625 //
626 StatusCodeData = (EFI_STATUS_CODE_DATA *)StatusCodeBuffer;
627 } else {
628 if (mHaveExitedBootServices) {
629 return EFI_OUT_OF_RESOURCES;
630 }
631
632 if ((gBS == NULL) || (gBS->AllocatePool == NULL) || (gBS->FreePool == NULL)) {
633 return EFI_UNSUPPORTED;
634 }
635
636 //
637 // Allocate space for the Status Code Header and its buffer
638 //
639 StatusCodeData = NULL;
640 gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_STATUS_CODE_DATA) + ExtendedDataSize, (VOID **)&StatusCodeData);
641 if (StatusCodeData == NULL) {
642 return EFI_OUT_OF_RESOURCES;
643 }
644 }
645
646 //
647 // Fill in the extended data header
648 //
649 StatusCodeData->HeaderSize = (UINT16)sizeof (EFI_STATUS_CODE_DATA);
650 StatusCodeData->Size = (UINT16)ExtendedDataSize;
651 if (ExtendedDataGuid == NULL) {
652 ExtendedDataGuid = &gEfiStatusCodeSpecificDataGuid;
653 }
654
655 CopyGuid (&StatusCodeData->Type, ExtendedDataGuid);
656
657 //
658 // Fill in the extended data buffer
659 //
660 if (ExtendedData != NULL) {
661 CopyMem (StatusCodeData + 1, ExtendedData, ExtendedDataSize);
662 }
663
664 //
665 // Report the status code
666 //
667 if (CallerId == NULL) {
668 CallerId = &gEfiCallerIdGuid;
669 }
670
671 Status = InternalReportStatusCode (Type, Value, Instance, CallerId, StatusCodeData);
672
673 //
674 // Free the allocated buffer
675 //
676 if (StatusCodeData != (EFI_STATUS_CODE_DATA *)StatusCodeBuffer) {
677 gBS->FreePool (StatusCodeData);
678 }
679
680 return Status;
681 }
682
683 /**
684 Returns TRUE if status codes of type EFI_PROGRESS_CODE are enabled
685
686 This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED
687 bit of PcdReportStatusCodeProperyMask is set. Otherwise FALSE is returned.
688
689 @retval TRUE The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of
690 PcdReportStatusCodeProperyMask is set.
691 @retval FALSE The REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED bit of
692 PcdReportStatusCodeProperyMask is clear.
693
694 **/
695 BOOLEAN
696 EFIAPI
697 ReportProgressCodeEnabled (
698 VOID
699 )
700 {
701 return (BOOLEAN)((PcdGet8 (PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED) != 0);
702 }
703
704 /**
705 Returns TRUE if status codes of type EFI_ERROR_CODE are enabled
706
707 This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED
708 bit of PcdReportStatusCodeProperyMask is set. Otherwise FALSE is returned.
709
710 @retval TRUE The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of
711 PcdReportStatusCodeProperyMask is set.
712 @retval FALSE The REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED bit of
713 PcdReportStatusCodeProperyMask is clear.
714
715 **/
716 BOOLEAN
717 EFIAPI
718 ReportErrorCodeEnabled (
719 VOID
720 )
721 {
722 return (BOOLEAN)((PcdGet8 (PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED) != 0);
723 }
724
725 /**
726 Returns TRUE if status codes of type EFI_DEBUG_CODE are enabled
727
728 This function returns TRUE if the REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED
729 bit of PcdReportStatusCodeProperyMask is set. Otherwise FALSE is returned.
730
731 @retval TRUE The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of
732 PcdReportStatusCodeProperyMask is set.
733 @retval FALSE The REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED bit of
734 PcdReportStatusCodeProperyMask is clear.
735
736 **/
737 BOOLEAN
738 EFIAPI
739 ReportDebugCodeEnabled (
740 VOID
741 )
742 {
743 return (BOOLEAN)((PcdGet8 (PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED) != 0);
744 }