]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/StatusCode/RuntimeDxe/StatusCodeRuntimeDxe.c
IntelFrameworkModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / StatusCode / RuntimeDxe / StatusCodeRuntimeDxe.c
CommitLineData
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 11EFI_EVENT mVirtualAddressChangeEvent = NULL;\r
12EFI_HANDLE mHandle = NULL;\r
c8126ad9 13\r
14//\r
15// Declaration of status code protocol.\r
16//\r
c8126ad9 17EFI_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 25UINT32 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
39EFI_STATUS\r
6ba0bc7c 40EFIAPI\r
20e7a774 41StatusCodeRuntimeDxeEntry (\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 98EFI_STATUS\r
c8126ad9 99EFIAPI\r
100ReportDispatcher (\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
172VOID\r
173EFIAPI\r
174VirtualAddressChangeCallBack (\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
193VOID\r
194InitializationDispatcherWorker (\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