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