2 Status code driver for IA32/X64/EBC architecture.
4 Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "StatusCodeRuntimeDxe.h"
17 EFI_EVENT mVirtualAddressChangeEvent
= NULL
;
18 EFI_HANDLE mHandle
= NULL
;
21 // Declaration of status code protocol.
23 EFI_STATUS_CODE_PROTOCOL mEfiStatusCodeProtocol
= {
28 // Report operation nest status.
29 // If it is set, then the report operation has nested.
31 UINT32 mStatusCodeNestStatus
= 0;
34 Entry point of DXE Status Code Driver.
36 This function is the entry point of this DXE Status Code Driver.
37 It installs Status Code Runtime Protocol, and registers event for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
39 @param ImageHandle The firmware allocated handle for the EFI image.
40 @param SystemTable A pointer to the EFI System Table.
42 @retval EFI_SUCCESS The entry point is executed successfully.
47 StatusCodeRuntimeDxeEntry (
48 IN EFI_HANDLE ImageHandle
,
49 IN EFI_SYSTEM_TABLE
*SystemTable
55 // Dispatch initialization request to supported devices
57 InitializationDispatcherWorker ();
60 // Install Status Code Runtime Protocol implementation as defined in PI Specification.
62 Status
= gBS
->InstallMultipleProtocolInterfaces (
64 &gEfiStatusCodeRuntimeProtocolGuid
,
65 &mEfiStatusCodeProtocol
,
68 ASSERT_EFI_ERROR (Status
);
70 Status
= gBS
->CreateEventEx (
73 VirtualAddressChangeCallBack
,
75 &gEfiEventVirtualAddressChangeGuid
,
76 &mVirtualAddressChangeEvent
78 ASSERT_EFI_ERROR (Status
);
84 Report status code to all supported device.
86 This function implements EFI_STATUS_CODE_PROTOCOL.ReportStatusCode().
87 It calls into the workers which dispatches the platform specific listeners.
89 @param CodeType Indicates the type of status code being reported.
90 @param Value Describes the current status of a hardware or software entity.
91 This included information about the class and subclass that is used to
92 classify the entity as well as an operation.
93 @param Instance The enumeration of a hardware or software entity within
94 the system. Valid instance numbers start with 1.
95 @param CallerId This optional parameter may be used to identify the caller.
96 This parameter allows the status code driver to apply different rules to
98 @param Data This optional parameter may be used to pass additional data.
100 @retval EFI_SUCCESS The function completed successfully
101 @retval EFI_DEVICE_ERROR The function should not be completed due to a device error.
107 IN EFI_STATUS_CODE_TYPE CodeType
,
108 IN EFI_STATUS_CODE_VALUE Value
,
110 IN EFI_GUID
*CallerId OPTIONAL
,
111 IN EFI_STATUS_CODE_DATA
*Data OPTIONAL
115 // Use atom operation to avoid the reentant of report.
116 // If current status is not zero, then the function is reentrancy.
118 if (InterlockedCompareExchange32 (&mStatusCodeNestStatus
, 0, 1) == 1) {
119 return EFI_DEVICE_ERROR
;
122 if (FeaturePcdGet (PcdStatusCodeUseSerial
)) {
123 SerialStatusCodeReportWorker (
131 if (FeaturePcdGet (PcdStatusCodeUseMemory
)) {
132 RtMemoryStatusCodeReportWorker (
138 if (FeaturePcdGet (PcdStatusCodeUseDataHub
)) {
139 DataHubStatusCodeReportWorker (
147 if (FeaturePcdGet (PcdStatusCodeUseOEM
)) {
149 // Call OEM hook status code library API to report status code to OEM device
151 OemHookStatusCodeReport (
161 // Restore the nest status of report
163 InterlockedCompareExchange32 (&mStatusCodeNestStatus
, 1, 0);
170 Virtual address change notification call back. It converts global pointer
173 @param Event Event whose notification function is being invoked.
174 @param Context Pointer to the notification function's context, which is
175 always zero in current implementation.
180 VirtualAddressChangeCallBack (
186 // Convert memory status code table to virtual address;
190 (VOID
**) &mRtMemoryStatusCodeTable
195 Dispatch initialization request to sub status code devices based on
196 customized feature flags.
200 InitializationDispatcherWorker (
204 EFI_PEI_HOB_POINTERS Hob
;
206 MEMORY_STATUSCODE_PACKET_HEADER
*PacketHeader
;
207 MEMORY_STATUSCODE_RECORD
*Record
;
208 UINTN ExpectedPacketIndex
;
213 // If enable UseSerial, then initialize serial port.
214 // if enable UseRuntimeMemory, then initialize runtime memory status code worker.
215 // if enable UseDataHub, then initialize data hub status code worker.
217 if (FeaturePcdGet (PcdStatusCodeUseSerial
)) {
219 // Call Serial Port Lib API to initialize serial port.
221 Status
= SerialPortInitialize ();
222 ASSERT_EFI_ERROR (Status
);
224 if (FeaturePcdGet (PcdStatusCodeUseMemory
)) {
225 Status
= RtMemoryStatusCodeInitializeWorker ();
226 ASSERT_EFI_ERROR (Status
);
228 if (FeaturePcdGet (PcdStatusCodeUseDataHub
)) {
229 Status
= DataHubStatusCodeInitializeWorker ();
230 ASSERT_EFI_ERROR (Status
);
232 if (FeaturePcdGet (PcdStatusCodeUseOEM
)) {
234 // Call OEM hook status code library API to initialize OEM device for status code.
236 Status
= OemHookStatusCodeInitialize ();
237 ASSERT_EFI_ERROR (Status
);
241 // Replay Status code which saved in GUID'ed HOB to all supported devices.
243 if (FeaturePcdGet (PcdStatusCodeReplayIn
)) {
245 // Journal GUID'ed HOBs to find all record entry, if found,
246 // then output record to support replay device.
248 ExpectedPacketIndex
= 0;
249 Hob
.Raw
= GetFirstGuidHob (&gMemoryStatusCodeRecordGuid
);
251 while (Hob
.Raw
!= NULL
) {
252 PacketHeader
= (MEMORY_STATUSCODE_PACKET_HEADER
*) GET_GUID_HOB_DATA (Hob
.Guid
);
253 if (PacketHeader
->PacketIndex
== ExpectedPacketIndex
) {
254 Record
= (MEMORY_STATUSCODE_RECORD
*) (PacketHeader
+ 1);
255 for (Index
= 0; Index
< PacketHeader
->RecordIndex
; Index
++) {
257 // Dispatch records to devices based on feature flag.
259 if (FeaturePcdGet (PcdStatusCodeUseSerial
)) {
260 SerialStatusCodeReportWorker (
261 Record
[Index
].CodeType
,
263 Record
[Index
].Instance
,
268 if (FeaturePcdGet (PcdStatusCodeUseMemory
)) {
269 RtMemoryStatusCodeReportWorker (
270 Record
[Index
].CodeType
,
272 Record
[Index
].Instance
275 if (FeaturePcdGet (PcdStatusCodeUseDataHub
)) {
276 DataHubStatusCodeReportWorker (
277 Record
[Index
].CodeType
,
279 Record
[Index
].Instance
,
284 if (FeaturePcdGet (PcdStatusCodeUseOEM
)) {
286 // Call OEM hook status code library API to report status code to OEM device
288 OemHookStatusCodeReport (
289 Record
[Index
].CodeType
,
291 Record
[Index
].Instance
,
297 ExpectedPacketIndex
++;
300 // See whether there is gap of packet or not
302 if (HobStart
!= NULL
) {
307 } else if (HobStart
!= NULL
) {
309 // Cache the found packet for improve the performance
314 Hob
.Raw
= GetNextGuidHob (&gMemoryStatusCodeRecordGuid
, Hob
.Raw
);