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