]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Library/SmmRuntimeDxeReportStatusCodeLibFramework/SmmRuntimeDxeSupport.c
Add the missing header file.
[mirror_edk2.git] / IntelFrameworkModulePkg / Library / SmmRuntimeDxeReportStatusCodeLibFramework / SmmRuntimeDxeSupport.c
CommitLineData
e5516b49 1/** @file\r
29f766e4 2 Library constructor & destructor, event handlers, and other internal worker functions.\r
e5516b49 3\r
29f766e4 4 Copyright (c) 2006 - 2009, Intel Corporation<BR>\r
e5516b49 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
29f766e4 17EFI_EVENT mVirtualAddressChangeEvent;\r
18EFI_EVENT mExitBootServicesEvent;\r
19EFI_STATUS_CODE_DATA *mStatusCodeData;\r
20BOOLEAN mInSmm;\r
21EFI_SMM_BASE_PROTOCOL *mSmmBase;\r
22EFI_RUNTIME_SERVICES *mInternalRT;\r
23BOOLEAN mHaveExitedBootServices = FALSE;\r
24EFI_REPORT_STATUS_CODE mReportStatusCode = NULL;\r
e5516b49 25\r
29f766e4 26/**\r
27 Locate the report status code service.\r
b13b4473 28\r
29f766e4 29 In SMM, it retrieves OemHookStatusCodeReport() from customized OEM Hook Status Code Lib.\r
30 Otherwise, it first tries to retrieve ReportStatusCode() in Runtime Services Table.\r
31 If not found, it then tries to retrieve ReportStatusCode() API of Report Status Code Protocol.\r
e5516b49 32\r
29f766e4 33 @return Function pointer to the report status code service.\r
34 NULL is returned if no status code service is available.\r
e5516b49 35\r
e5516b49 36**/\r
37EFI_REPORT_STATUS_CODE\r
38InternalGetReportStatusCode (\r
39 VOID\r
40 )\r
41{\r
42 EFI_STATUS_CODE_PROTOCOL *StatusCodeProtocol;\r
e5516b49 43 EFI_STATUS Status;\r
44\r
404d4e5c 45 if (mInSmm) {\r
46 return (EFI_REPORT_STATUS_CODE) OemHookStatusCodeReport;\r
29f766e4 47 } else if (mInternalRT != NULL && mInternalRT->Hdr.Revision < 0x20000) {\r
48 return ((FRAMEWORK_EFI_RUNTIME_SERVICES*)mInternalRT)->ReportStatusCode;\r
e5516b49 49 } else if (!mHaveExitedBootServices) {\r
9556741c 50 //\r
51 // Check gBS just in case. ReportStatusCode is called before gBS is initialized.\r
52 //\r
53 if (gBS != NULL) {\r
54 Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID**)&StatusCodeProtocol);\r
55 if (!EFI_ERROR (Status) && StatusCodeProtocol != NULL) {\r
56 return StatusCodeProtocol->ReportStatusCode;\r
57 }\r
e5516b49 58 }\r
59 }\r
60\r
61 return NULL;\r
62}\r
63\r
29f766e4 64/**\r
65 Internal worker function that reports a status code through the status code service.\r
66\r
67 If status code service is not cached, then this function checks if status code service is\r
68 available in system. If status code service is not available, then EFI_UNSUPPORTED is\r
69 returned. If status code service is present, then it is cached in mReportStatusCode.\r
70 Finally this function reports status code through the status code service.\r
71\r
72 @param Type Status code type.\r
73 @param Value Status code value.\r
74 @param Instance Status code instance number.\r
75 @param CallerId Pointer to a GUID that identifies the caller of this\r
76 function. This is an optional parameter that may be\r
77 NULL.\r
78 @param Data Pointer to the extended data buffer. This is an\r
79 optional parameter that may be NULL.\r
80\r
81 @retval EFI_SUCCESS The status code was reported.\r
82 @retval EFI_UNSUPPORTED Status code service is not available.\r
83 @retval EFI_UNSUPPORTED Status code type is not supported.\r
84\r
85**/\r
86EFI_STATUS\r
87InternalReportStatusCode (\r
88 IN EFI_STATUS_CODE_TYPE Type,\r
89 IN EFI_STATUS_CODE_VALUE Value,\r
90 IN UINT32 Instance,\r
91 IN CONST EFI_GUID *CallerId OPTIONAL,\r
92 IN EFI_STATUS_CODE_DATA *Data OPTIONAL\r
93 )\r
94{\r
95 if ((ReportProgressCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ||\r
96 (ReportErrorCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) ||\r
97 (ReportDebugCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE)) {\r
98 //\r
99 // If mReportStatusCode is NULL, then check if status code service is available in system.\r
100 //\r
101 if (mReportStatusCode == NULL) {\r
102 mReportStatusCode = InternalGetReportStatusCode ();\r
103 if (mReportStatusCode == NULL) {\r
104 return EFI_UNSUPPORTED;\r
105 }\r
106 }\r
107 \r
108 //\r
109 // A status code service is present in system, so pass in all the parameters to the service.\r
110 //\r
111 return (*mReportStatusCode) (Type, Value, Instance, (EFI_GUID *)CallerId, Data);\r
112 }\r
113 \r
114 return EFI_UNSUPPORTED;\r
115}\r
e5516b49 116\r
117/**\r
29f766e4 118 Notification function of EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.\r
119\r
120 @param Event Event whose notification function is being invoked.\r
121 @param Context Pointer to the notification function's context\r
e5516b49 122\r
e5516b49 123**/\r
e5516b49 124VOID\r
125EFIAPI\r
126ReportStatusCodeLibVirtualAddressChange (\r
127 IN EFI_EVENT Event,\r
128 IN VOID *Context\r
129 )\r
130{\r
29f766e4 131 if (mReportStatusCode != NULL) {\r
132 mInternalRT->ConvertPointer (0, (VOID **) &mReportStatusCode);\r
e5516b49 133 }\r
29f766e4 134 mInternalRT->ConvertPointer (0, (VOID **) &mStatusCodeData);\r
135 mInternalRT->ConvertPointer (0, (VOID **) &mInternalRT);\r
e5516b49 136}\r
137\r
138/**\r
29f766e4 139 Notification function of EVT_SIGNAL_EXIT_BOOT_SERVICES.\r
140\r
141 @param Event Event whose notification function is being invoked.\r
142 @param Context Pointer to the notification function's context\r
e5516b49 143\r
e5516b49 144**/\r
e5516b49 145VOID\r
146EFIAPI\r
147ReportStatusCodeLibExitBootServices (\r
148 IN EFI_EVENT Event,\r
149 IN VOID *Context\r
150 )\r
151{\r
152 mHaveExitedBootServices = TRUE;\r
153}\r
154\r
155/**\r
29f766e4 156 The constructor function of SMM Runtime DXE Report Status Code Lib.\r
e5516b49 157\r
29f766e4 158 This function allocates memory for extended status code data, caches\r
159 the report status code service, and registers events.\r
160\r
161 @param ImageHandle The firmware allocated handle for the EFI image.\r
162 @param SystemTable A pointer to the EFI System Table.\r
163 \r
164 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
e5516b49 165\r
e5516b49 166**/\r
167EFI_STATUS\r
168EFIAPI\r
169ReportStatusCodeLibConstruct (\r
170 IN EFI_HANDLE ImageHandle,\r
171 IN EFI_SYSTEM_TABLE *SystemTable\r
172 )\r
173{\r
29f766e4 174 EFI_STATUS Status;\r
e5516b49 175\r
176 //\r
29f766e4 177 // If in SMM mode, then allocates memory from SMRAM for extended status code data.\r
178 //\r
9556741c 179 Status = gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, (VOID **) &mSmmBase);\r
e5516b49 180 if (!EFI_ERROR (Status)) {\r
c0522bd7 181 mSmmBase->InSmm (mSmmBase, &mInSmm);\r
404d4e5c 182 if (mInSmm) {\r
c0522bd7 183 Status = mSmmBase->SmmAllocatePool (\r
184 mSmmBase,\r
e5516b49 185 EfiRuntimeServicesData, \r
186 sizeof (EFI_STATUS_CODE_DATA) + EFI_STATUS_CODE_DATA_MAX_SIZE, \r
187 (VOID **) &mStatusCodeData\r
188 );\r
189 ASSERT_EFI_ERROR (Status);\r
190 OemHookStatusCodeInitialize ();\r
191 return EFI_SUCCESS;\r
192 }\r
193 }\r
194\r
29f766e4 195\r
b13b4473 196 //\r
29f766e4 197 // If not in SMM mode, then allocate runtime memory for extended status code data.\r
198 //\r
199 // Library should not use the gRT directly, for it may be converted by other library instance.\r
b13b4473 200 // \r
29f766e4 201 mInternalRT = gRT;\r
202 mInSmm = FALSE;\r
b13b4473 203\r
29f766e4 204 mStatusCodeData = AllocateRuntimePool (sizeof (EFI_STATUS_CODE_DATA) + EFI_STATUS_CODE_DATA_MAX_SIZE);\r
205 ASSERT (mStatusCodeData != NULL);\r
e5516b49 206 //\r
207 // Cache the report status code service\r
208 // \r
209 mReportStatusCode = InternalGetReportStatusCode ();\r
210\r
211 //\r
29f766e4 212 // Register notify function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE\r
e5516b49 213 // \r
6a27a4eb 214 Status = gBS->CreateEventEx (\r
215 EVT_NOTIFY_SIGNAL,\r
e5516b49 216 TPL_NOTIFY,\r
217 ReportStatusCodeLibVirtualAddressChange,\r
218 NULL,\r
6a27a4eb 219 &gEfiEventVirtualAddressChangeGuid,\r
e5516b49 220 &mVirtualAddressChangeEvent\r
221 );\r
222 ASSERT_EFI_ERROR (Status);\r
223\r
e5516b49 224 //\r
29f766e4 225 // Register notify function for EVT_SIGNAL_EXIT_BOOT_SERVICES\r
e5516b49 226 // \r
6a27a4eb 227 Status = gBS->CreateEventEx (\r
228 EVT_NOTIFY_SIGNAL,\r
e5516b49 229 TPL_NOTIFY,\r
230 ReportStatusCodeLibExitBootServices,\r
231 NULL,\r
6a27a4eb 232 &gEfiEventExitBootServicesGuid,\r
e5516b49 233 &mExitBootServicesEvent\r
234 );\r
235 ASSERT_EFI_ERROR (Status);\r
236\r
29f766e4 237 return EFI_SUCCESS;\r
e5516b49 238}\r
239\r
ed7752ec 240/**\r
29f766e4 241 The destructor function of SMM Runtime DXE Report Status Code Lib.\r
242 \r
243 The destructor function frees memory allocated by constructor, and closes related events.\r
244 It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS. \r
245\r
246 @param ImageHandle The firmware allocated handle for the EFI image.\r
247 @param SystemTable A pointer to the EFI System Table.\r
ed7752ec 248 \r
29f766e4 249 @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
250\r
ed7752ec 251**/\r
e5516b49 252EFI_STATUS\r
253EFIAPI\r
254ReportStatusCodeLibDestruct (\r
255 IN EFI_HANDLE ImageHandle,\r
256 IN EFI_SYSTEM_TABLE *SystemTable\r
257 )\r
258{\r
259 EFI_STATUS Status;\r
260\r
c0522bd7 261 if (!mInSmm) {\r
9556741c 262 ASSERT (gBS != NULL);\r
263 Status = gBS->CloseEvent (mVirtualAddressChangeEvent);\r
c0522bd7 264 ASSERT_EFI_ERROR (Status);\r
9556741c 265 Status = gBS->CloseEvent (mExitBootServicesEvent);\r
c0522bd7 266 ASSERT_EFI_ERROR (Status);\r
267\r
29f766e4 268 FreePool (mStatusCodeData);\r
c0522bd7 269 } else {\r
270 mSmmBase->SmmFreePool (mSmmBase, mStatusCodeData);\r
271 }\r
e5516b49 272\r
c0522bd7 273 return EFI_SUCCESS;\r
e5516b49 274}\r
275\r