2 Status code driver for IA32/X64/EBC architecture.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
9 #include "StatusCodeRuntimeDxe.h"
11 EFI_EVENT mVirtualAddressChangeEvent
= NULL
;
12 EFI_HANDLE mHandle
= NULL
;
15 // Declaration of status code protocol.
17 EFI_STATUS_CODE_PROTOCOL mEfiStatusCodeProtocol
= {
22 // Report operation nest status.
23 // If it is set, then the report operation has nested.
25 UINT32 mStatusCodeNestStatus
= 0;
28 Entry point of DXE Status Code Driver.
30 This function is the entry point of this DXE Status Code Driver.
31 It installs Status Code Runtime Protocol, and registers event for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
33 @param ImageHandle The firmware allocated handle for the EFI image.
34 @param SystemTable A pointer to the EFI System Table.
36 @retval EFI_SUCCESS The entry point is executed successfully.
41 StatusCodeRuntimeDxeEntry (
42 IN EFI_HANDLE ImageHandle
,
43 IN EFI_SYSTEM_TABLE
*SystemTable
49 // Dispatch initialization request to supported devices
51 InitializationDispatcherWorker ();
54 // Install Status Code Runtime Protocol implementation as defined in PI Specification.
56 Status
= gBS
->InstallMultipleProtocolInterfaces (
58 &gEfiStatusCodeRuntimeProtocolGuid
,
59 &mEfiStatusCodeProtocol
,
62 ASSERT_EFI_ERROR (Status
);
64 Status
= gBS
->CreateEventEx (
67 VirtualAddressChangeCallBack
,
69 &gEfiEventVirtualAddressChangeGuid
,
70 &mVirtualAddressChangeEvent
72 ASSERT_EFI_ERROR (Status
);
78 Report status code to all supported device.
80 This function implements EFI_STATUS_CODE_PROTOCOL.ReportStatusCode().
81 It calls into the workers which dispatches the platform specific listeners.
83 @param CodeType Indicates the type of status code being reported.
84 @param Value Describes the current status of a hardware or software entity.
85 This included information about the class and subclass that is used to
86 classify the entity as well as an operation.
87 @param Instance The enumeration of a hardware or software entity within
88 the system. Valid instance numbers start with 1.
89 @param CallerId This optional parameter may be used to identify the caller.
90 This parameter allows the status code driver to apply different rules to
92 @param Data This optional parameter may be used to pass additional data.
94 @retval EFI_SUCCESS The function completed successfully
95 @retval EFI_DEVICE_ERROR The function should not be completed due to a device error.
101 IN EFI_STATUS_CODE_TYPE CodeType
,
102 IN EFI_STATUS_CODE_VALUE Value
,
104 IN EFI_GUID
*CallerId OPTIONAL
,
105 IN EFI_STATUS_CODE_DATA
*Data OPTIONAL
109 // Use atom operation to avoid the reentant of report.
110 // If current status is not zero, then the function is reentrancy.
112 if (InterlockedCompareExchange32 (&mStatusCodeNestStatus
, 0, 1) == 1) {
113 return EFI_DEVICE_ERROR
;
116 if (FeaturePcdGet (PcdStatusCodeUseSerial
)) {
117 SerialStatusCodeReportWorker (
125 if (FeaturePcdGet (PcdStatusCodeUseMemory
)) {
126 RtMemoryStatusCodeReportWorker (
132 if (FeaturePcdGet (PcdStatusCodeUseDataHub
)) {
133 DataHubStatusCodeReportWorker (
141 if (FeaturePcdGet (PcdStatusCodeUseOEM
)) {
143 // Call OEM hook status code library API to report status code to OEM device
145 OemHookStatusCodeReport (
155 // Restore the nest status of report
157 InterlockedCompareExchange32 (&mStatusCodeNestStatus
, 1, 0);
164 Virtual address change notification call back. It converts global pointer
167 @param Event Event whose notification function is being invoked.
168 @param Context Pointer to the notification function's context, which is
169 always zero in current implementation.
174 VirtualAddressChangeCallBack (
180 // Convert memory status code table to virtual address;
184 (VOID
**) &mRtMemoryStatusCodeTable
189 Dispatch initialization request to sub status code devices based on
190 customized feature flags.
194 InitializationDispatcherWorker (
198 EFI_PEI_HOB_POINTERS Hob
;
200 MEMORY_STATUSCODE_PACKET_HEADER
*PacketHeader
;
201 MEMORY_STATUSCODE_RECORD
*Record
;
203 UINTN MaxRecordNumber
;
206 // If enable UseSerial, then initialize serial port.
207 // if enable UseRuntimeMemory, then initialize runtime memory status code worker.
208 // if enable UseDataHub, then initialize data hub status code worker.
210 if (FeaturePcdGet (PcdStatusCodeUseSerial
)) {
212 // Call Serial Port Lib API to initialize serial port.
214 Status
= SerialPortInitialize ();
215 ASSERT_EFI_ERROR (Status
);
217 if (FeaturePcdGet (PcdStatusCodeUseMemory
)) {
218 Status
= RtMemoryStatusCodeInitializeWorker ();
219 ASSERT_EFI_ERROR (Status
);
221 if (FeaturePcdGet (PcdStatusCodeUseDataHub
)) {
222 DataHubStatusCodeInitializeWorker ();
224 if (FeaturePcdGet (PcdStatusCodeUseOEM
)) {
226 // Call OEM hook status code library API to initialize OEM device for status code.
228 Status
= OemHookStatusCodeInitialize ();
229 ASSERT_EFI_ERROR (Status
);
233 // Replay Status code which saved in GUID'ed HOB to all supported devices.
235 if (FeaturePcdGet (PcdStatusCodeReplayIn
)) {
237 // Journal GUID'ed HOBs to find all record entry, if found,
238 // then output record to support replay device.
240 Hob
.Raw
= GetFirstGuidHob (&gMemoryStatusCodeRecordGuid
);
241 if (Hob
.Raw
!= NULL
) {
242 PacketHeader
= (MEMORY_STATUSCODE_PACKET_HEADER
*) GET_GUID_HOB_DATA (Hob
.Guid
);
243 Record
= (MEMORY_STATUSCODE_RECORD
*) (PacketHeader
+ 1);
244 MaxRecordNumber
= (UINTN
) PacketHeader
->RecordIndex
;
245 if (PacketHeader
->PacketIndex
> 0) {
247 // Record has been wrapped around. So, record number has arrived at max number.
249 MaxRecordNumber
= (UINTN
) PacketHeader
->MaxRecordsNumber
;
251 for (Index
= 0; Index
< MaxRecordNumber
; Index
++) {
253 // Dispatch records to devices based on feature flag.
255 if (FeaturePcdGet (PcdStatusCodeUseSerial
)) {
256 SerialStatusCodeReportWorker (
257 Record
[Index
].CodeType
,
259 Record
[Index
].Instance
,
264 if (FeaturePcdGet (PcdStatusCodeUseMemory
)) {
265 RtMemoryStatusCodeReportWorker (
266 Record
[Index
].CodeType
,
268 Record
[Index
].Instance
271 if (FeaturePcdGet (PcdStatusCodeUseDataHub
)) {
272 DataHubStatusCodeReportWorker (
273 Record
[Index
].CodeType
,
275 Record
[Index
].Instance
,
280 if (FeaturePcdGet (PcdStatusCodeUseOEM
)) {
282 // Call OEM hook status code library API to report status code to OEM device
284 OemHookStatusCodeReport (
285 Record
[Index
].CodeType
,
287 Record
[Index
].Instance
,