]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/SmmRuntimeDxeReportStatusCodeLibFramework/SmmRuntimeDxeSupport.c
Reviewed the code comments in the Include/Protocol directory for typos, grammar issue...
[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
6a27a4eb 161 Status = gBS->CreateEventEx (\r
162 EVT_NOTIFY_SIGNAL,\r
e5516b49 163 TPL_NOTIFY,\r
164 ReportStatusCodeLibVirtualAddressChange,\r
165 NULL,\r
6a27a4eb 166 &gEfiEventVirtualAddressChangeGuid,\r
e5516b49 167 &mVirtualAddressChangeEvent\r
168 );\r
169 ASSERT_EFI_ERROR (Status);\r
170\r
171\r
172 //\r
173 // Register the call back of virtual address change\r
174 // \r
6a27a4eb 175 Status = gBS->CreateEventEx (\r
176 EVT_NOTIFY_SIGNAL,\r
e5516b49 177 TPL_NOTIFY,\r
178 ReportStatusCodeLibExitBootServices,\r
179 NULL,\r
6a27a4eb 180 &gEfiEventExitBootServicesGuid,\r
e5516b49 181 &mExitBootServicesEvent\r
182 );\r
183 ASSERT_EFI_ERROR (Status);\r
184\r
185 return Status;\r
186}\r
187\r
ed7752ec 188/**\r
189 Desctructor of library will close events.\r
190 \r
191 @param ImageHandle callder module's image handle\r
192 @param SystemTable pointer to EFI system table.\r
193 @return the status of close event.\r
194**/\r
e5516b49 195EFI_STATUS\r
196EFIAPI\r
197ReportStatusCodeLibDestruct (\r
198 IN EFI_HANDLE ImageHandle,\r
199 IN EFI_SYSTEM_TABLE *SystemTable\r
200 )\r
201{\r
202 EFI_STATUS Status;\r
203\r
c0522bd7 204 if (!mInSmm) {\r
205 //\r
206 // Close SetVirtualAddressMap () notify function\r
207 //\r
9556741c 208 ASSERT (gBS != NULL);\r
209 Status = gBS->CloseEvent (mVirtualAddressChangeEvent);\r
c0522bd7 210 ASSERT_EFI_ERROR (Status);\r
9556741c 211 Status = gBS->CloseEvent (mExitBootServicesEvent);\r
c0522bd7 212 ASSERT_EFI_ERROR (Status);\r
213\r
9556741c 214 gBS->FreePool (mStatusCodeData);\r
c0522bd7 215 } else {\r
216 mSmmBase->SmmFreePool (mSmmBase, mStatusCodeData);\r
217 }\r
e5516b49 218\r
c0522bd7 219 return EFI_SUCCESS;\r
e5516b49 220}\r
221\r
e5516b49 222/**\r
223 Reports a status code with full parameters.\r
224\r
225 The function reports a status code. If ExtendedData is NULL and ExtendedDataSize\r
226 is 0, then an extended data buffer is not reported. If ExtendedData is not\r
227 NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.\r
228 ExtendedData is assumed not have the standard status code header, so this function\r
229 is responsible for allocating a buffer large enough for the standard header and\r
230 the extended data passed into this function. The standard header is filled in\r
231 with a GUID specified by ExtendedDataGuid. If ExtendedDataGuid is NULL, then a\r
232 GUID of gEfiStatusCodeSpecificDatauid is used. The status code is reported with\r
233 an instance specified by Instance and a caller ID specified by CallerId. If\r
234 CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.\r
235\r
236 ReportStatusCodeEx()must actively prevent recursion. If ReportStatusCodeEx()\r
237 is called while processing another any other Report Status Code Library function,\r
238 then ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.\r
239\r
240 If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().\r
241 If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().\r
242\r
243 @param Type Status code type.\r
244 @param Value Status code value.\r
245 @param Instance Status code instance number.\r
246 @param CallerId Pointer to a GUID that identifies the caller of this\r
247 function. If this parameter is NULL, then a caller\r
248 ID of gEfiCallerIdGuid is used.\r
249 @param ExtendedDataGuid Pointer to the GUID for the extended data buffer.\r
250 If this parameter is NULL, then a the status code\r
251 standard header is filled in with\r
252 gEfiStatusCodeSpecificDataGuid.\r
253 @param ExtendedData Pointer to the extended data buffer. This is an\r
254 optional parameter that may be NULL.\r
255 @param ExtendedDataSize The size, in bytes, of the extended data buffer.\r
256\r
257 @retval EFI_SUCCESS The status code was reported.\r
258 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate\r
259 the extended data section if it was specified.\r
260 @retval EFI_UNSUPPORTED Report status code is not supported\r
261\r
262**/\r
263EFI_STATUS\r
264EFIAPI\r
265InternalReportStatusCodeEx (\r
266 IN EFI_STATUS_CODE_TYPE Type,\r
267 IN EFI_STATUS_CODE_VALUE Value,\r
268 IN UINT32 Instance,\r
269 IN CONST EFI_GUID *CallerId OPTIONAL,\r
270 IN CONST EFI_GUID *ExtendedDataGuid OPTIONAL,\r
271 IN CONST VOID *ExtendedData OPTIONAL,\r
272 IN UINTN ExtendedDataSize\r
273 )\r
274{\r
275 ASSERT (!((ExtendedData == NULL) && (ExtendedDataSize != 0)));\r
276 ASSERT (!((ExtendedData != NULL) && (ExtendedDataSize == 0)));\r
277\r
278 if (ExtendedDataSize > EFI_STATUS_CODE_DATA_MAX_SIZE) {\r
279 return EFI_OUT_OF_RESOURCES;\r
280 }\r
281\r
282 //\r
283 // Fill in the extended data header\r
284 //\r
285 mStatusCodeData->HeaderSize = sizeof (EFI_STATUS_CODE_DATA);\r
286 mStatusCodeData->Size = (UINT16)ExtendedDataSize;\r
287 if (ExtendedDataGuid == NULL) {\r
288 ExtendedDataGuid = &gEfiStatusCodeSpecificDataGuid;\r
289 }\r
290 CopyGuid (&mStatusCodeData->Type, ExtendedDataGuid);\r
291\r
292 //\r
293 // Fill in the extended data buffer\r
294 //\r
261136bc 295 if (ExtendedData != NULL) {\r
296 CopyMem (mStatusCodeData + 1, ExtendedData, ExtendedDataSize);\r
297 }\r
e5516b49 298\r
299 //\r
300 // Report the status code\r
301 //\r
302 if (CallerId == NULL) {\r
303 CallerId = &gEfiCallerIdGuid;\r
304 }\r
305 return InternalReportStatusCode (Type, Value, Instance, CallerId, mStatusCodeData);\r
306}\r
ed7752ec 307\r