]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/SmmRuntimeDxeReportStatusCodeLibFramework/SmmRuntimeDxeSupport.c
Add missing DevicePathLib in INF file.
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / SmmRuntimeDxeReportStatusCodeLibFramework / SmmRuntimeDxeSupport.c
CommitLineData
e5516b49 1/** @file\r
2 Report Status Code Library for DXE Phase.\r
3\r
4 Copyright (c) 2006 - 2007, Intel Corporation<BR>\r
5 All rights reserved. This program and the accompanying materials\r
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
12\r
13**/\r
14\r
15#include "ReportStatusCodeLibInternal.h"\r
16\r
17//\r
18// Resources need by SMM runtime instance\r
19// \r
20#include <Library/OemHookStatusCodeLib.h>\r
21#include <Protocol/SmmBase.h>\r
22\r
e5516b49 23EFI_EVENT mVirtualAddressChangeEvent;\r
24\r
e5516b49 25EFI_EVENT mExitBootServicesEvent;\r
26\r
e5516b49 27EFI_STATUS_CODE_DATA *mStatusCodeData;\r
28\r
404d4e5c 29BOOLEAN mInSmm;\r
e5516b49 30\r
c0522bd7 31EFI_SMM_BASE_PROTOCOL *mSmmBase;\r
32\r
b13b4473 33EFI_RUNTIME_SERVICES *mRT;\r
34\r
e5516b49 35BOOLEAN mHaveExitedBootServices = FALSE;\r
36\r
37/**\r
ed7752ec 38 Locate he report status code service.\r
e5516b49 39\r
40 @return EFI_REPORT_STATUS_CODE function point to\r
41 ReportStatusCode.\r
42**/\r
43EFI_REPORT_STATUS_CODE\r
44InternalGetReportStatusCode (\r
45 VOID\r
46 )\r
47{\r
48 EFI_STATUS_CODE_PROTOCOL *StatusCodeProtocol;\r
e5516b49 49 EFI_STATUS Status;\r
50\r
404d4e5c 51 if (mInSmm) {\r
52 return (EFI_REPORT_STATUS_CODE) OemHookStatusCodeReport;\r
9556741c 53 } else if (mRT != NULL && mRT->Hdr.Revision < 0x20000) {\r
b13b4473 54 return ((FRAMEWORK_EFI_RUNTIME_SERVICES*)mRT)->ReportStatusCode;\r
e5516b49 55 } else if (!mHaveExitedBootServices) {\r
9556741c 56 //\r
57 // Check gBS just in case. ReportStatusCode is called before gBS is initialized.\r
58 //\r
59 if (gBS != NULL) {\r
60 Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID**)&StatusCodeProtocol);\r
61 if (!EFI_ERROR (Status) && StatusCodeProtocol != NULL) {\r
62 return StatusCodeProtocol->ReportStatusCode;\r
63 }\r
e5516b49 64 }\r
65 }\r
66\r
67 return NULL;\r
68}\r
69\r
70\r
71/**\r
72 Fixup internal report status code protocol interface.\r
73\r
74 @param[in] Event The Event that is being processed\r
75 @param[in] Context Event Context\r
76**/\r
e5516b49 77VOID\r
78EFIAPI\r
79ReportStatusCodeLibVirtualAddressChange (\r
80 IN EFI_EVENT Event,\r
81 IN VOID *Context\r
82 )\r
83{\r
84 if (NULL != mReportStatusCode) {\r
b13b4473 85 mRT->ConvertPointer (0, (VOID **) &mReportStatusCode);\r
e5516b49 86 }\r
b13b4473 87 mRT->ConvertPointer (0, (VOID **) &mStatusCodeData);\r
88 mRT->ConvertPointer (0, (VOID **) &mRT);\r
e5516b49 89}\r
90\r
91/**\r
ed7752ec 92 Update the In Runtime Indicator.\r
e5516b49 93\r
94 @param[in] Event The Event that is being processed\r
95 @param[in] Context Event Context\r
96**/\r
e5516b49 97VOID\r
98EFIAPI\r
99ReportStatusCodeLibExitBootServices (\r
100 IN EFI_EVENT Event,\r
101 IN VOID *Context\r
102 )\r
103{\r
104 mHaveExitedBootServices = TRUE;\r
105}\r
106\r
107/**\r
108 Intialize Report Status Code Lib.\r
109\r
110 @param[in] ImageHandle The firmware allocated handle for the EFI image.\r
111 @param[in] SystemTable A pointer to the EFI System Table.\r
112\r
113 @return EFI_STATUS always returns EFI_SUCCESS.\r
114**/\r
115EFI_STATUS\r
116EFIAPI\r
117ReportStatusCodeLibConstruct (\r
118 IN EFI_HANDLE ImageHandle,\r
119 IN EFI_SYSTEM_TABLE *SystemTable\r
120 )\r
121{\r
404d4e5c 122 EFI_STATUS Status;\r
e5516b49 123\r
124 //\r
125 // SMM driver depends on the SMM BASE protocol.\r
126 // the SMM driver must be success to locate protocol.\r
127 // \r
9556741c 128 Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &mSmmBase);\r
e5516b49 129 if (!EFI_ERROR (Status)) {\r
c0522bd7 130 mSmmBase->InSmm (mSmmBase, &mInSmm);\r
404d4e5c 131 if (mInSmm) {\r
c0522bd7 132 Status = mSmmBase->SmmAllocatePool (\r
133 mSmmBase,\r
e5516b49 134 EfiRuntimeServicesData, \r
135 sizeof (EFI_STATUS_CODE_DATA) + EFI_STATUS_CODE_DATA_MAX_SIZE, \r
136 (VOID **) &mStatusCodeData\r
137 );\r
138 ASSERT_EFI_ERROR (Status);\r
139 OemHookStatusCodeInitialize ();\r
140 return EFI_SUCCESS;\r
141 }\r
142 }\r
143\r
b13b4473 144 //\r
145 // Library should not use the gRT directly, since it\r
146 // may be converted by other library instance.\r
147 // \r
404d4e5c 148 mRT = gRT;\r
149 mInSmm = FALSE;\r
b13b4473 150\r
9556741c 151 gBS->AllocatePool (EfiRuntimeServicesData, sizeof (EFI_STATUS_CODE_DATA) + EFI_STATUS_CODE_DATA_MAX_SIZE, (VOID **)&mStatusCodeData);\r
e5516b49 152 ASSERT (NULL != mStatusCodeData);\r
153 //\r
154 // Cache the report status code service\r
155 // \r
156 mReportStatusCode = InternalGetReportStatusCode ();\r
157\r
158 //\r
159 // Register the call back of virtual address change\r
160 // \r
9556741c 161 Status = gBS->CreateEvent (\r
e5516b49 162 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,\r
163 TPL_NOTIFY,\r
164 ReportStatusCodeLibVirtualAddressChange,\r
165 NULL,\r
166 &mVirtualAddressChangeEvent\r
167 );\r
168 ASSERT_EFI_ERROR (Status);\r
169\r
170\r
171 //\r
172 // Register the call back of virtual address change\r
173 // \r
9556741c 174 Status = gBS->CreateEvent (\r
e5516b49 175 EVT_SIGNAL_EXIT_BOOT_SERVICES,\r
176 TPL_NOTIFY,\r
177 ReportStatusCodeLibExitBootServices,\r
178 NULL,\r
179 &mExitBootServicesEvent\r
180 );\r
181 ASSERT_EFI_ERROR (Status);\r
182\r
183 return Status;\r
184}\r
185\r
ed7752ec 186/**\r
187 Desctructor of library will close events.\r
188 \r
189 @param ImageHandle callder module's image handle\r
190 @param SystemTable pointer to EFI system table.\r
191 @return the status of close event.\r
192**/\r
e5516b49 193EFI_STATUS\r
194EFIAPI\r
195ReportStatusCodeLibDestruct (\r
196 IN EFI_HANDLE ImageHandle,\r
197 IN EFI_SYSTEM_TABLE *SystemTable\r
198 )\r
199{\r
200 EFI_STATUS Status;\r
201\r
c0522bd7 202 if (!mInSmm) {\r
203 //\r
204 // Close SetVirtualAddressMap () notify function\r
205 //\r
9556741c 206 ASSERT (gBS != NULL);\r
207 Status = gBS->CloseEvent (mVirtualAddressChangeEvent);\r
c0522bd7 208 ASSERT_EFI_ERROR (Status);\r
9556741c 209 Status = gBS->CloseEvent (mExitBootServicesEvent);\r
c0522bd7 210 ASSERT_EFI_ERROR (Status);\r
211\r
9556741c 212 gBS->FreePool (mStatusCodeData);\r
c0522bd7 213 } else {\r
214 mSmmBase->SmmFreePool (mSmmBase, mStatusCodeData);\r
215 }\r
e5516b49 216\r
c0522bd7 217 return EFI_SUCCESS;\r
e5516b49 218}\r
219\r
e5516b49 220/**\r
221 Reports a status code with full parameters.\r
222\r
223 The function reports a status code. If ExtendedData is NULL and ExtendedDataSize\r
224 is 0, then an extended data buffer is not reported. If ExtendedData is not\r
225 NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.\r
226 ExtendedData is assumed not have the standard status code header, so this function\r
227 is responsible for allocating a buffer large enough for the standard header and\r
228 the extended data passed into this function. The standard header is filled in\r
229 with a GUID specified by ExtendedDataGuid. If ExtendedDataGuid is NULL, then a\r
230 GUID of gEfiStatusCodeSpecificDatauid is used. The status code is reported with\r
231 an instance specified by Instance and a caller ID specified by CallerId. If\r
232 CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.\r
233\r
234 ReportStatusCodeEx()must actively prevent recursion. If ReportStatusCodeEx()\r
235 is called while processing another any other Report Status Code Library function,\r
236 then ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.\r
237\r
238 If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().\r
239 If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().\r
240\r
241 @param Type Status code type.\r
242 @param Value Status code value.\r
243 @param Instance Status code instance number.\r
244 @param CallerId Pointer to a GUID that identifies the caller of this\r
245 function. If this parameter is NULL, then a caller\r
246 ID of gEfiCallerIdGuid is used.\r
247 @param ExtendedDataGuid Pointer to the GUID for the extended data buffer.\r
248 If this parameter is NULL, then a the status code\r
249 standard header is filled in with\r
250 gEfiStatusCodeSpecificDataGuid.\r
251 @param ExtendedData Pointer to the extended data buffer. This is an\r
252 optional parameter that may be NULL.\r
253 @param ExtendedDataSize The size, in bytes, of the extended data buffer.\r
254\r
255 @retval EFI_SUCCESS The status code was reported.\r
256 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate\r
257 the extended data section if it was specified.\r
258 @retval EFI_UNSUPPORTED Report status code is not supported\r
259\r
260**/\r
261EFI_STATUS\r
262EFIAPI\r
263InternalReportStatusCodeEx (\r
264 IN EFI_STATUS_CODE_TYPE Type,\r
265 IN EFI_STATUS_CODE_VALUE Value,\r
266 IN UINT32 Instance,\r
267 IN CONST EFI_GUID *CallerId OPTIONAL,\r
268 IN CONST EFI_GUID *ExtendedDataGuid OPTIONAL,\r
269 IN CONST VOID *ExtendedData OPTIONAL,\r
270 IN UINTN ExtendedDataSize\r
271 )\r
272{\r
273 ASSERT (!((ExtendedData == NULL) && (ExtendedDataSize != 0)));\r
274 ASSERT (!((ExtendedData != NULL) && (ExtendedDataSize == 0)));\r
275\r
276 if (ExtendedDataSize > EFI_STATUS_CODE_DATA_MAX_SIZE) {\r
277 return EFI_OUT_OF_RESOURCES;\r
278 }\r
279\r
280 //\r
281 // Fill in the extended data header\r
282 //\r
283 mStatusCodeData->HeaderSize = sizeof (EFI_STATUS_CODE_DATA);\r
284 mStatusCodeData->Size = (UINT16)ExtendedDataSize;\r
285 if (ExtendedDataGuid == NULL) {\r
286 ExtendedDataGuid = &gEfiStatusCodeSpecificDataGuid;\r
287 }\r
288 CopyGuid (&mStatusCodeData->Type, ExtendedDataGuid);\r
289\r
290 //\r
291 // Fill in the extended data buffer\r
292 //\r
293 CopyMem (mStatusCodeData + 1, ExtendedData, ExtendedDataSize);\r
294\r
295 //\r
296 // Report the status code\r
297 //\r
298 if (CallerId == NULL) {\r
299 CallerId = &gEfiCallerIdGuid;\r
300 }\r
301 return InternalReportStatusCode (Type, Value, Instance, CallerId, mStatusCodeData);\r
302}\r
ed7752ec 303\r