]>
Commit | Line | Data |
---|---|---|
c8126ad9 | 1 | /** @file\r |
2 | Status code driver for IA32/X64/EBC architecture.\r | |
3 | \r | |
0a6f4824 | 4 | Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r |
c0a00b14 | 5 | SPDX-License-Identifier: BSD-2-Clause-Patent\r |
c8126ad9 | 6 | \r |
c8126ad9 | 7 | **/\r |
8 | \r | |
20e7a774 | 9 | #include "StatusCodeRuntimeDxe.h"\r |
c8126ad9 | 10 | \r |
a8cbf345 | 11 | EFI_EVENT mVirtualAddressChangeEvent = NULL;\r |
12 | EFI_HANDLE mHandle = NULL;\r | |
c8126ad9 | 13 | \r |
14 | //\r | |
15 | // Declaration of status code protocol.\r | |
16 | //\r | |
c8126ad9 | 17 | EFI_STATUS_CODE_PROTOCOL mEfiStatusCodeProtocol = {\r |
18 | ReportDispatcher\r | |
19 | };\r | |
20 | \r | |
21 | //\r | |
a8cbf345 | 22 | // Report operation nest status.\r |
23 | // If it is set, then the report operation has nested.\r | |
c8126ad9 | 24 | //\r |
a8cbf345 | 25 | UINT32 mStatusCodeNestStatus = 0;\r |
c8126ad9 | 26 | \r |
27 | /**\r | |
a8cbf345 | 28 | Entry point of DXE Status Code Driver.\r |
c8126ad9 | 29 | \r |
a8cbf345 | 30 | This function is the entry point of this DXE Status Code Driver.\r |
31 | It installs Status Code Runtime Protocol, and registers event for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.\r | |
ececc2eb | 32 | \r |
a8cbf345 | 33 | @param ImageHandle The firmware allocated handle for the EFI image.\r |
34 | @param SystemTable A pointer to the EFI System Table.\r | |
0a6f4824 | 35 | \r |
a8cbf345 | 36 | @retval EFI_SUCCESS The entry point is executed successfully.\r |
c8126ad9 | 37 | \r |
38 | **/\r | |
39 | EFI_STATUS\r | |
6ba0bc7c | 40 | EFIAPI\r |
20e7a774 | 41 | StatusCodeRuntimeDxeEntry (\r |
c8126ad9 | 42 | IN EFI_HANDLE ImageHandle,\r |
43 | IN EFI_SYSTEM_TABLE *SystemTable\r | |
44 | )\r | |
45 | {\r | |
c8126ad9 | 46 | EFI_STATUS Status;\r |
47 | \r | |
48 | //\r | |
49 | // Dispatch initialization request to supported devices\r | |
50 | //\r | |
51 | InitializationDispatcherWorker ();\r | |
52 | \r | |
53 | //\r | |
a8cbf345 | 54 | // Install Status Code Runtime Protocol implementation as defined in PI Specification.\r |
c8126ad9 | 55 | //\r |
56 | Status = gBS->InstallMultipleProtocolInterfaces (\r | |
a8cbf345 | 57 | &mHandle,\r |
c8126ad9 | 58 | &gEfiStatusCodeRuntimeProtocolGuid,\r |
59 | &mEfiStatusCodeProtocol,\r | |
60 | NULL\r | |
61 | );\r | |
62 | ASSERT_EFI_ERROR (Status);\r | |
63 | \r | |
6a27a4eb | 64 | Status = gBS->CreateEventEx (\r |
65 | EVT_NOTIFY_SIGNAL,\r | |
ececc2eb | 66 | TPL_NOTIFY,\r |
67 | VirtualAddressChangeCallBack,\r | |
68 | NULL,\r | |
a8cbf345 | 69 | &gEfiEventVirtualAddressChangeGuid,\r |
70 | &mVirtualAddressChangeEvent\r | |
ececc2eb | 71 | );\r |
72 | ASSERT_EFI_ERROR (Status);\r | |
73 | \r | |
a8cbf345 | 74 | return EFI_SUCCESS;\r |
c8126ad9 | 75 | }\r |
76 | \r | |
77 | /**\r | |
ececc2eb | 78 | Report status code to all supported device.\r |
a8cbf345 | 79 | \r |
80 | This function implements EFI_STATUS_CODE_PROTOCOL.ReportStatusCode().\r | |
81 | It calls into the workers which dispatches the platform specific listeners.\r | |
82 | \r | |
9484bb62 | 83 | @param CodeType Indicates the type of status code being reported.\r |
a8cbf345 | 84 | @param Value Describes the current status of a hardware or software entity.\r |
85 | This included information about the class and subclass that is used to\r | |
86 | classify the entity as well as an operation.\r | |
87 | @param Instance The enumeration of a hardware or software entity within\r | |
88 | the system. Valid instance numbers start with 1.\r | |
89 | @param CallerId This optional parameter may be used to identify the caller.\r | |
90 | This parameter allows the status code driver to apply different rules to\r | |
91 | different callers.\r | |
92 | @param Data This optional parameter may be used to pass additional data.\r | |
93 | \r | |
94 | @retval EFI_SUCCESS The function completed successfully\r | |
95 | @retval EFI_DEVICE_ERROR The function should not be completed due to a device error.\r | |
c8126ad9 | 96 | \r |
97 | **/\r | |
ececc2eb | 98 | EFI_STATUS\r |
c8126ad9 | 99 | EFIAPI\r |
100 | ReportDispatcher (\r | |
101 | IN EFI_STATUS_CODE_TYPE CodeType,\r | |
102 | IN EFI_STATUS_CODE_VALUE Value,\r | |
103 | IN UINT32 Instance,\r | |
104 | IN EFI_GUID *CallerId OPTIONAL,\r | |
105 | IN EFI_STATUS_CODE_DATA *Data OPTIONAL\r | |
106 | )\r | |
107 | {\r | |
108 | //\r | |
109 | // Use atom operation to avoid the reentant of report.\r | |
110 | // If current status is not zero, then the function is reentrancy.\r | |
111 | //\r | |
a8cbf345 | 112 | if (InterlockedCompareExchange32 (&mStatusCodeNestStatus, 0, 1) == 1) {\r |
c8126ad9 | 113 | return EFI_DEVICE_ERROR;\r |
114 | }\r | |
115 | \r | |
d2c315e6 | 116 | if (FeaturePcdGet (PcdStatusCodeUseSerial)) {\r |
c8126ad9 | 117 | SerialStatusCodeReportWorker (\r |
118 | CodeType,\r | |
119 | Value,\r | |
120 | Instance,\r | |
121 | CallerId,\r | |
122 | Data\r | |
123 | );\r | |
124 | }\r | |
d2c315e6 | 125 | if (FeaturePcdGet (PcdStatusCodeUseMemory)) {\r |
c8126ad9 | 126 | RtMemoryStatusCodeReportWorker (\r |
c8126ad9 | 127 | CodeType,\r |
128 | Value,\r | |
129 | Instance\r | |
130 | );\r | |
131 | }\r | |
132 | if (FeaturePcdGet (PcdStatusCodeUseDataHub)) {\r | |
133 | DataHubStatusCodeReportWorker (\r | |
134 | CodeType,\r | |
135 | Value,\r | |
136 | Instance,\r | |
137 | CallerId,\r | |
138 | Data\r | |
139 | );\r | |
140 | }\r | |
141 | if (FeaturePcdGet (PcdStatusCodeUseOEM)) {\r | |
a8cbf345 | 142 | //\r |
143 | // Call OEM hook status code library API to report status code to OEM device\r | |
144 | //\r | |
c8126ad9 | 145 | OemHookStatusCodeReport (\r |
146 | CodeType,\r | |
147 | Value,\r | |
148 | Instance,\r | |
149 | CallerId,\r | |
150 | Data\r | |
151 | );\r | |
152 | }\r | |
153 | \r | |
154 | //\r | |
155 | // Restore the nest status of report\r | |
156 | //\r | |
a8cbf345 | 157 | InterlockedCompareExchange32 (&mStatusCodeNestStatus, 1, 0);\r |
c8126ad9 | 158 | \r |
159 | return EFI_SUCCESS;\r | |
160 | }\r | |
161 | \r | |
162 | \r | |
163 | /**\r | |
ececc2eb | 164 | Virtual address change notification call back. It converts global pointer\r |
c8126ad9 | 165 | to virtual address.\r |
166 | \r | |
167 | @param Event Event whose notification function is being invoked.\r | |
168 | @param Context Pointer to the notification function's context, which is\r | |
169 | always zero in current implementation.\r | |
170 | \r | |
171 | **/\r | |
172 | VOID\r | |
173 | EFIAPI\r | |
174 | VirtualAddressChangeCallBack (\r | |
175 | IN EFI_EVENT Event,\r | |
176 | IN VOID *Context\r | |
177 | )\r | |
178 | {\r | |
179 | //\r | |
180 | // Convert memory status code table to virtual address;\r | |
181 | //\r | |
182 | EfiConvertPointer (\r | |
ececc2eb | 183 | 0,\r |
a8cbf345 | 184 | (VOID **) &mRtMemoryStatusCodeTable\r |
c8126ad9 | 185 | );\r |
186 | }\r | |
187 | \r | |
20e7a774 | 188 | /**\r |
0a6f4824 | 189 | Dispatch initialization request to sub status code devices based on\r |
20e7a774 | 190 | customized feature flags.\r |
0a6f4824 | 191 | \r |
20e7a774 | 192 | **/\r |
193 | VOID\r | |
194 | InitializationDispatcherWorker (\r | |
195 | VOID\r | |
196 | )\r | |
197 | {\r | |
198 | EFI_PEI_HOB_POINTERS Hob;\r | |
199 | EFI_STATUS Status;\r | |
200 | MEMORY_STATUSCODE_PACKET_HEADER *PacketHeader;\r | |
201 | MEMORY_STATUSCODE_RECORD *Record;\r | |
20e7a774 | 202 | UINTN Index;\r |
c945216e | 203 | UINTN MaxRecordNumber;\r |
20e7a774 | 204 | \r |
205 | //\r | |
206 | // If enable UseSerial, then initialize serial port.\r | |
207 | // if enable UseRuntimeMemory, then initialize runtime memory status code worker.\r | |
208 | // if enable UseDataHub, then initialize data hub status code worker.\r | |
209 | //\r | |
d2c315e6 | 210 | if (FeaturePcdGet (PcdStatusCodeUseSerial)) {\r |
20e7a774 | 211 | //\r |
212 | // Call Serial Port Lib API to initialize serial port.\r | |
213 | //\r | |
214 | Status = SerialPortInitialize ();\r | |
215 | ASSERT_EFI_ERROR (Status);\r | |
216 | }\r | |
d2c315e6 | 217 | if (FeaturePcdGet (PcdStatusCodeUseMemory)) {\r |
20e7a774 | 218 | Status = RtMemoryStatusCodeInitializeWorker ();\r |
219 | ASSERT_EFI_ERROR (Status);\r | |
220 | }\r | |
221 | if (FeaturePcdGet (PcdStatusCodeUseDataHub)) {\r | |
c945216e | 222 | DataHubStatusCodeInitializeWorker ();\r |
20e7a774 | 223 | }\r |
224 | if (FeaturePcdGet (PcdStatusCodeUseOEM)) {\r | |
225 | //\r | |
226 | // Call OEM hook status code library API to initialize OEM device for status code.\r | |
227 | //\r | |
228 | Status = OemHookStatusCodeInitialize ();\r | |
229 | ASSERT_EFI_ERROR (Status);\r | |
230 | }\r | |
231 | \r | |
232 | //\r | |
0a6f4824 | 233 | // Replay Status code which saved in GUID'ed HOB to all supported devices.\r |
20e7a774 | 234 | //\r |
d2c315e6 | 235 | if (FeaturePcdGet (PcdStatusCodeReplayIn)) {\r |
0a6f4824 LG |
236 | //\r |
237 | // Journal GUID'ed HOBs to find all record entry, if found,\r | |
d2c315e6 LG |
238 | // then output record to support replay device.\r |
239 | //\r | |
d2c315e6 | 240 | Hob.Raw = GetFirstGuidHob (&gMemoryStatusCodeRecordGuid);\r |
c945216e | 241 | if (Hob.Raw != NULL) {\r |
d2c315e6 | 242 | PacketHeader = (MEMORY_STATUSCODE_PACKET_HEADER *) GET_GUID_HOB_DATA (Hob.Guid);\r |
c945216e LG |
243 | Record = (MEMORY_STATUSCODE_RECORD *) (PacketHeader + 1);\r |
244 | MaxRecordNumber = (UINTN) PacketHeader->RecordIndex;\r | |
245 | if (PacketHeader->PacketIndex > 0) {\r | |
d2c315e6 | 246 | //\r |
c945216e | 247 | // Record has been wrapped around. So, record number has arrived at max number.\r |
d2c315e6 | 248 | //\r |
c945216e LG |
249 | MaxRecordNumber = (UINTN) PacketHeader->MaxRecordsNumber;\r |
250 | }\r | |
251 | for (Index = 0; Index < MaxRecordNumber; Index++) {\r | |
d2c315e6 | 252 | //\r |
c945216e | 253 | // Dispatch records to devices based on feature flag.\r |
d2c315e6 | 254 | //\r |
c945216e LG |
255 | if (FeaturePcdGet (PcdStatusCodeUseSerial)) {\r |
256 | SerialStatusCodeReportWorker (\r | |
257 | Record[Index].CodeType,\r | |
258 | Record[Index].Value,\r | |
259 | Record[Index].Instance,\r | |
260 | NULL,\r | |
261 | NULL\r | |
262 | );\r | |
263 | }\r | |
264 | if (FeaturePcdGet (PcdStatusCodeUseMemory)) {\r | |
265 | RtMemoryStatusCodeReportWorker (\r | |
266 | Record[Index].CodeType,\r | |
267 | Record[Index].Value,\r | |
268 | Record[Index].Instance\r | |
269 | );\r | |
270 | }\r | |
271 | if (FeaturePcdGet (PcdStatusCodeUseDataHub)) {\r | |
272 | DataHubStatusCodeReportWorker (\r | |
273 | Record[Index].CodeType,\r | |
274 | Record[Index].Value,\r | |
275 | Record[Index].Instance,\r | |
276 | NULL,\r | |
277 | NULL\r | |
278 | );\r | |
279 | }\r | |
280 | if (FeaturePcdGet (PcdStatusCodeUseOEM)) {\r | |
281 | //\r | |
282 | // Call OEM hook status code library API to report status code to OEM device\r | |
283 | //\r | |
284 | OemHookStatusCodeReport (\r | |
285 | Record[Index].CodeType,\r | |
286 | Record[Index].Value,\r | |
287 | Record[Index].Instance,\r | |
288 | NULL,\r | |
289 | NULL\r | |
290 | );\r | |
291 | }\r | |
20e7a774 | 292 | }\r |
20e7a774 | 293 | }\r |
20e7a774 | 294 | }\r |
295 | }\r |