TianoCore EDK2 master
Loading...
Searching...
No Matches
ReportStatusCodeLib.c
Go to the documentation of this file.
1
11#include <Library/BaseLib.h>
12#include <Library/DebugLib.h>
15#include <Library/PcdLib.h>
17
18#include <Protocol/StatusCode.h>
19
22
23EFI_STATUS_CODE_PROTOCOL *mReportStatusCodeLibStatusCodeProtocol = NULL;
24EFI_EVENT mOnStatusCodeProtocolInstallEvent;
25
32VOID
34 VOID
35 )
36{
37 EFI_STATUS Status;
38
39 if (mReportStatusCodeLibStatusCodeProtocol != NULL) {
40 return;
41 }
42
43 //
44 // Check gBS just in case ReportStatusCode is called before gBS is initialized.
45 //
46 if ((gBS != NULL) && (gBS->LocateProtocol != NULL)) {
47 Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID **)&mReportStatusCodeLibStatusCodeProtocol);
48 if (EFI_ERROR (Status)) {
49 mReportStatusCodeLibStatusCodeProtocol = NULL;
50 }
51 }
52}
53
81 IN UINT32 Instance,
82 IN CONST EFI_GUID *CallerId OPTIONAL,
83 IN EFI_STATUS_CODE_DATA *Data OPTIONAL
84 )
85{
87 (ReportErrorCodeEnabled () && (((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)) ||
88 (ReportDebugCodeEnabled () && (((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE)))
89 {
90 //
91 // If mReportStatusCodeLibStatusCodeProtocol is NULL, the protocol has not yet been registered. Return immediately.
92 //
93 if (mReportStatusCodeLibStatusCodeProtocol == NULL) {
94 return EFI_UNSUPPORTED;
95 }
96
97 //
98 // A Report Status Code Protocol is present in system, so pass in all the parameters to the service.
99 //
100 return mReportStatusCodeLibStatusCodeProtocol->ReportStatusCode (Type, Value, Instance, (EFI_GUID *)CallerId, Data);
101 }
102
103 return EFI_UNSUPPORTED;
104}
105
127BOOLEAN
128EFIAPI
130 IN EFI_STATUS_CODE_TYPE CodeType,
132 OUT UINT8 *PostCode
133 )
134{
135 //
136 // If PostCode is NULL, then ASSERT()
137 //
138 ASSERT (PostCode != NULL);
139
140 //
141 // Convert Value to an 8 bit post code
142 //
143 if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ||
144 ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE))
145 {
146 *PostCode = (UINT8)((((Value & EFI_STATUS_CODE_CLASS_MASK) >> 24) << 5) |
147 (((Value & EFI_STATUS_CODE_SUBCLASS_MASK) >> 16) & 0x1f));
148 return TRUE;
149 }
150
151 return FALSE;
152}
153
187BOOLEAN
188EFIAPI
190 IN EFI_STATUS_CODE_TYPE CodeType,
193 OUT CHAR8 **Filename,
194 OUT CHAR8 **Description,
195 OUT UINT32 *LineNumber
196 )
197{
198 EFI_DEBUG_ASSERT_DATA *AssertData;
199
200 ASSERT (Data != NULL);
201 ASSERT (Filename != NULL);
202 ASSERT (Description != NULL);
203 ASSERT (LineNumber != NULL);
204
205 if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
206 ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED) &&
207 ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE))
208 {
209 AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
210 *Filename = (CHAR8 *)(AssertData + 1);
211 *Description = *Filename + AsciiStrLen (*Filename) + 1;
212 *LineNumber = AssertData->LineNumber;
213 return TRUE;
214 }
215
216 return FALSE;
217}
218
248BOOLEAN
249EFIAPI
252 OUT UINT32 *ErrorLevel,
253 OUT BASE_LIST *Marker,
254 OUT CHAR8 **Format
255 )
256{
257 EFI_DEBUG_INFO *DebugInfo;
258
259 ASSERT (Data != NULL);
260 ASSERT (ErrorLevel != NULL);
261 ASSERT (Marker != NULL);
262 ASSERT (Format != NULL);
263
264 //
265 // If the GUID type is not EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID then return FALSE
266 //
267 if (!CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid)) {
268 return FALSE;
269 }
270
271 //
272 // Retrieve the debug information from the status code record
273 //
274 DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);
275
276 *ErrorLevel = DebugInfo->ErrorLevel;
277
278 //
279 // The first 12 * sizeof (UINT64) bytes following EFI_DEBUG_INFO are for variable arguments
280 // of format in DEBUG string. Its address is returned in Marker and has to be 64-bit aligned.
281 // It must be noticed that EFI_DEBUG_INFO follows EFI_STATUS_CODE_DATA, whose size is
282 // 20 bytes. The size of EFI_DEBUG_INFO is 4 bytes, so we can ensure that Marker
283 // returned is 64-bit aligned.
284 // 64-bit aligned is a must, otherwise retrieving 64-bit parameter from BASE_LIST will
285 // cause unalignment exception.
286 //
287 *Marker = (BASE_LIST)(DebugInfo + 1);
288 *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);
289
290 return TRUE;
291}
292
315EFIAPI
319 )
320{
321 return InternalReportStatusCode (Type, Value, 0, &gEfiCallerIdGuid, NULL);
322}
323
353EFIAPI
358 )
359{
360 ASSERT (DevicePath != NULL);
362 Type,
363 Value,
364 (VOID *)DevicePath,
365 GetDevicePathSize (DevicePath)
366 );
367}
368
403EFIAPI
407 IN CONST VOID *ExtendedData,
408 IN UINTN ExtendedDataSize
409 )
410{
411 ASSERT (ExtendedData != NULL);
412 ASSERT (ExtendedDataSize != 0);
413 return ReportStatusCodeEx (
414 Type,
415 Value,
416 0,
417 NULL,
418 NULL,
419 ExtendedData,
420 ExtendedDataSize
421 );
422}
423
467EFIAPI
471 IN UINT32 Instance,
472 IN CONST EFI_GUID *CallerId OPTIONAL,
473 IN CONST EFI_GUID *ExtendedDataGuid OPTIONAL,
474 IN CONST VOID *ExtendedData OPTIONAL,
475 IN UINTN ExtendedDataSize
476 )
477{
478 EFI_STATUS Status;
479 EFI_STATUS_CODE_DATA *StatusCodeData;
480 EFI_TPL Tpl;
481 UINT64 Buffer[(MAX_EXTENDED_DATA_SIZE / sizeof (UINT64)) + 1];
482
483 ASSERT (!((ExtendedData == NULL) && (ExtendedDataSize != 0)));
484 ASSERT (!((ExtendedData != NULL) && (ExtendedDataSize == 0)));
485
486 if (ExtendedDataSize <= (MAX_EXTENDED_DATA_SIZE - sizeof (EFI_STATUS_CODE_DATA))) {
487 //
488 // Use Buffer instead of allocating if possible.
489 //
490 StatusCodeData = (EFI_STATUS_CODE_DATA *)Buffer;
491 } else {
492 if ((gBS == NULL) || (gBS->AllocatePool == NULL) || (gBS->FreePool == NULL)) {
493 return EFI_UNSUPPORTED;
494 }
495
496 //
497 // Retrieve the current TPL
498 //
499 Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
500 gBS->RestoreTPL (Tpl);
501
502 if (Tpl > TPL_NOTIFY) {
503 return EFI_OUT_OF_RESOURCES;
504 }
505
506 //
507 // Allocate space for the Status Code Header and its buffer
508 //
509 StatusCodeData = NULL;
510 gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_STATUS_CODE_DATA) + ExtendedDataSize, (VOID **)&StatusCodeData);
511 if (StatusCodeData == NULL) {
512 return EFI_OUT_OF_RESOURCES;
513 }
514 }
515
516 //
517 // Fill in the extended data header
518 //
519 StatusCodeData->HeaderSize = (UINT16)sizeof (EFI_STATUS_CODE_DATA);
520 StatusCodeData->Size = (UINT16)ExtendedDataSize;
521 if (ExtendedDataGuid == NULL) {
522 ExtendedDataGuid = &gEfiStatusCodeSpecificDataGuid;
523 }
524
525 CopyGuid (&StatusCodeData->Type, ExtendedDataGuid);
526
527 //
528 // Fill in the extended data buffer
529 //
530 if (ExtendedData != NULL) {
531 CopyMem (StatusCodeData + 1, ExtendedData, ExtendedDataSize);
532 }
533
534 //
535 // Report the status code
536 //
537 if (CallerId == NULL) {
538 CallerId = &gEfiCallerIdGuid;
539 }
540
541 Status = InternalReportStatusCode (Type, Value, Instance, CallerId, StatusCodeData);
542
543 //
544 // Free the allocated buffer
545 //
546 if (StatusCodeData != (EFI_STATUS_CODE_DATA *)Buffer) {
547 gBS->FreePool (StatusCodeData);
548 }
549
550 return Status;
551}
552
565BOOLEAN
566EFIAPI
568 VOID
569 )
570{
571 return (BOOLEAN)((PcdGet8 (PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_PROGRESS_CODE_ENABLED) != 0);
572}
573
586BOOLEAN
587EFIAPI
589 VOID
590 )
591{
592 return (BOOLEAN)((PcdGet8 (PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_ERROR_CODE_ENABLED) != 0);
593}
594
607BOOLEAN
608EFIAPI
610 VOID
611 )
612{
613 return (BOOLEAN)((PcdGet8 (PcdReportStatusCodePropertyMask) & REPORT_STATUS_CODE_PROPERTY_DEBUG_CODE_ENABLED) != 0);
614}
615
624VOID
625EFIAPI
627 IN EFI_EVENT Event,
628 IN VOID *Context
629 )
630{
632
633 if (mReportStatusCodeLibStatusCodeProtocol != NULL) {
634 gBS->CloseEvent (mOnStatusCodeProtocolInstallEvent);
635 }
636}
637
649EFIAPI
651 IN EFI_HANDLE ImageHandle,
652 IN EFI_SYSTEM_TABLE *SystemTable
653 )
654{
655 EFI_STATUS Status;
656 VOID *Registration;
657
659
660 //
661 // Register for protocol installation notification if the protocol is not found
662 //
663 if ((mReportStatusCodeLibStatusCodeProtocol == NULL) && (gBS != NULL)) {
664 //
665 // Create the event
666 //
667 Status = gBS->CreateEvent (
668 EVT_NOTIFY_SIGNAL,
669 TPL_CALLBACK,
671 NULL,
672 &mOnStatusCodeProtocolInstallEvent
673 );
674 ASSERT_EFI_ERROR (Status);
675
676 //
677 // Register for protocol notifications on this event
678 //
679 Status = gBS->RegisterProtocolNotify (
680 &gEfiStatusCodeRuntimeProtocolGuid,
681 mOnStatusCodeProtocolInstallEvent,
682 &Registration
683 );
684 ASSERT_EFI_ERROR (Status);
685 }
686
687 return EFI_SUCCESS;
688}
689
700EFIAPI
702 IN EFI_HANDLE ImageHandle,
703 IN EFI_SYSTEM_TABLE *SystemTable
704 )
705{
706 EFI_STATUS Status;
707
708 if (mReportStatusCodeLibStatusCodeProtocol == NULL) {
709 Status = gBS->CloseEvent (mOnStatusCodeProtocolInstallEvent);
710 ASSERT_EFI_ERROR (Status);
711 }
712
713 return EFI_SUCCESS;
714}
UINT64 UINTN
UINTN EFIAPI AsciiStrLen(IN CONST CHAR8 *String)
Definition: String.c:641
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
UINTN EFIAPI GetDevicePathSize(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_STATUS EFIAPI ReportStatusCodeLibConstructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
VOID InternalGetReportStatusCode(VOID)
BOOLEAN EFIAPI ReportErrorCodeEnabled(VOID)
VOID EFIAPI OnStatusCodeRuntimeProtocolInstalledNotification(IN EFI_EVENT Event, IN VOID *Context)
EFI_STATUS EFIAPI ReportStatusCodeWithExtendedData(IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value, IN CONST VOID *ExtendedData, IN UINTN ExtendedDataSize)
BOOLEAN EFIAPI ReportProgressCodeEnabled(VOID)
BOOLEAN EFIAPI CodeTypeToPostCode(IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, OUT UINT8 *PostCode)
EFI_STATUS EFIAPI ReportStatusCodeWithDevicePath(IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath)
EFI_STATUS EFIAPI ReportStatusCode(IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value)
EFI_STATUS EFIAPI ReportStatusCodeEx(IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value, IN UINT32 Instance, IN CONST EFI_GUID *CallerId OPTIONAL, IN CONST EFI_GUID *ExtendedDataGuid OPTIONAL, IN CONST VOID *ExtendedData OPTIONAL, IN UINTN ExtendedDataSize)
EFI_STATUS InternalReportStatusCode(IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value, IN UINT32 Instance, IN CONST EFI_GUID *CallerId OPTIONAL, IN EFI_STATUS_CODE_DATA *Data OPTIONAL)
BOOLEAN EFIAPI ReportDebugCodeEnabled(VOID)
BOOLEAN EFIAPI ReportStatusCodeExtractDebugInfo(IN CONST EFI_STATUS_CODE_DATA *Data, OUT UINT32 *ErrorLevel, OUT BASE_LIST *Marker, OUT CHAR8 **Format)
EFI_STATUS EFIAPI ReportStatusCodeLibDestructor(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
BOOLEAN EFIAPI ReportStatusCodeExtractAssertInfo(IN EFI_STATUS_CODE_TYPE CodeType, IN EFI_STATUS_CODE_VALUE Value, IN CONST EFI_STATUS_CODE_DATA *Data, OUT CHAR8 **Filename, OUT CHAR8 **Description, OUT UINT32 *LineNumber)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define VOID
Definition: Base.h:269
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
UINTN * BASE_LIST
Definition: Base.h:711
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:463
#define PcdGet8(TokenName)
Definition: PcdLib.h:336
UINT32 EFI_STATUS_CODE_VALUE
Definition: PiStatusCode.h:68
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:44
UINT32 EFI_STATUS_CODE_TYPE
Definition: PiStatusCode.h:25
#define EFI_STATUS_CODE_CLASS_MASK
Definition: PiStatusCode.h:75
#define EFI_STATUS_CODE_TYPE_MASK
Definition: PiStatusCode.h:33
UINT32 EFIAPI PostCode(IN UINT32 Value)
Definition: PostCode.c:35
#define MAX_EXTENDED_DATA_SIZE
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
UINTN EFI_TPL
Definition: UefiBaseType.h:41
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EfiBootServicesData
Definition: Base.h:213