2 Report Status Code Library for DXE Phase.
4 Copyright (c) 2006 - 2007, 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
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.
15 #include "ReportStatusCodeLibInternal.h"
18 // Resources need by SMM runtime instance
20 #include <Library/OemHookStatusCodeLib.h>
21 #include <Protocol/SmmBase.h>
24 EFI_EVENT mVirtualAddressChangeEvent
;
27 EFI_EVENT mExitBootServicesEvent
;
30 EFI_STATUS_CODE_DATA
*mStatusCodeData
;
35 EFI_SMM_BASE_PROTOCOL
*mSmmBase
;
38 EFI_RUNTIME_SERVICES
*mRT
;
41 EFI_BOOT_SERVICES
*mBS
;
44 BOOLEAN mHaveExitedBootServices
= FALSE
;
47 Locate he report status code service.
49 @return EFI_REPORT_STATUS_CODE function point to
52 EFI_REPORT_STATUS_CODE
53 InternalGetReportStatusCode (
57 EFI_STATUS_CODE_PROTOCOL
*StatusCodeProtocol
;
61 return (EFI_REPORT_STATUS_CODE
) OemHookStatusCodeReport
;
62 } else if (mRT
->Hdr
.Revision
< 0x20000) {
63 return ((FRAMEWORK_EFI_RUNTIME_SERVICES
*)mRT
)->ReportStatusCode
;
64 } else if (!mHaveExitedBootServices
) {
65 Status
= mBS
->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid
, NULL
, (VOID
**)&StatusCodeProtocol
);
66 if (!EFI_ERROR (Status
) && StatusCodeProtocol
!= NULL
) {
67 return StatusCodeProtocol
->ReportStatusCode
;
76 Fixup internal report status code protocol interface.
78 @param[in] Event The Event that is being processed
79 @param[in] Context Event Context
84 ReportStatusCodeLibVirtualAddressChange (
89 if (NULL
!= mReportStatusCode
) {
90 mRT
->ConvertPointer (0, (VOID
**) &mReportStatusCode
);
92 mRT
->ConvertPointer (0, (VOID
**) &mStatusCodeData
);
93 mRT
->ConvertPointer (0, (VOID
**) &mRT
);
97 Update the In Runtime Indicator.
99 @param[in] Event The Event that is being processed
100 @param[in] Context Event Context
105 ReportStatusCodeLibExitBootServices (
110 mHaveExitedBootServices
= TRUE
;
114 Intialize Report Status Code Lib.
116 @param[in] ImageHandle The firmware allocated handle for the EFI image.
117 @param[in] SystemTable A pointer to the EFI System Table.
119 @return EFI_STATUS always returns EFI_SUCCESS.
123 ReportStatusCodeLibConstruct (
124 IN EFI_HANDLE ImageHandle
,
125 IN EFI_SYSTEM_TABLE
*SystemTable
130 mBS
= SystemTable
->BootServices
;
133 // SMM driver depends on the SMM BASE protocol.
134 // the SMM driver must be success to locate protocol.
136 ASSERT (mBS
!= NULL
);
137 Status
= mBS
->LocateProtocol (&gEfiSmmBaseProtocolGuid
, NULL
, (VOID
**) &mSmmBase
);
138 if (!EFI_ERROR (Status
)) {
139 mSmmBase
->InSmm (mSmmBase
, &mInSmm
);
141 Status
= mSmmBase
->SmmAllocatePool (
143 EfiRuntimeServicesData
,
144 sizeof (EFI_STATUS_CODE_DATA
) + EFI_STATUS_CODE_DATA_MAX_SIZE
,
145 (VOID
**) &mStatusCodeData
147 ASSERT_EFI_ERROR (Status
);
148 OemHookStatusCodeInitialize ();
154 // Library should not use the gRT directly, since it
155 // may be converted by other library instance.
160 mBS
->AllocatePool (EfiRuntimeServicesData
, sizeof (EFI_STATUS_CODE_DATA
) + EFI_STATUS_CODE_DATA_MAX_SIZE
, (VOID
**)&mStatusCodeData
);
161 ASSERT (NULL
!= mStatusCodeData
);
163 // Cache the report status code service
165 mReportStatusCode
= InternalGetReportStatusCode ();
168 // Register the call back of virtual address change
170 Status
= mBS
->CreateEvent (
171 EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
173 ReportStatusCodeLibVirtualAddressChange
,
175 &mVirtualAddressChangeEvent
177 ASSERT_EFI_ERROR (Status
);
181 // Register the call back of virtual address change
183 Status
= mBS
->CreateEvent (
184 EVT_SIGNAL_EXIT_BOOT_SERVICES
,
186 ReportStatusCodeLibExitBootServices
,
188 &mExitBootServicesEvent
190 ASSERT_EFI_ERROR (Status
);
196 Desctructor of library will close events.
198 @param ImageHandle callder module's image handle
199 @param SystemTable pointer to EFI system table.
200 @return the status of close event.
204 ReportStatusCodeLibDestruct (
205 IN EFI_HANDLE ImageHandle
,
206 IN EFI_SYSTEM_TABLE
*SystemTable
213 // Close SetVirtualAddressMap () notify function
215 ASSERT (mBS
!= NULL
);
216 Status
= mBS
->CloseEvent (mVirtualAddressChangeEvent
);
217 ASSERT_EFI_ERROR (Status
);
218 Status
= mBS
->CloseEvent (mExitBootServicesEvent
);
219 ASSERT_EFI_ERROR (Status
);
221 mBS
->FreePool (mStatusCodeData
);
223 mSmmBase
->SmmFreePool (mSmmBase
, mStatusCodeData
);
230 Reports a status code with full parameters.
232 The function reports a status code. If ExtendedData is NULL and ExtendedDataSize
233 is 0, then an extended data buffer is not reported. If ExtendedData is not
234 NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.
235 ExtendedData is assumed not have the standard status code header, so this function
236 is responsible for allocating a buffer large enough for the standard header and
237 the extended data passed into this function. The standard header is filled in
238 with a GUID specified by ExtendedDataGuid. If ExtendedDataGuid is NULL, then a
239 GUID of gEfiStatusCodeSpecificDatauid is used. The status code is reported with
240 an instance specified by Instance and a caller ID specified by CallerId. If
241 CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.
243 ReportStatusCodeEx()must actively prevent recursion. If ReportStatusCodeEx()
244 is called while processing another any other Report Status Code Library function,
245 then ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.
247 If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().
248 If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().
250 @param Type Status code type.
251 @param Value Status code value.
252 @param Instance Status code instance number.
253 @param CallerId Pointer to a GUID that identifies the caller of this
254 function. If this parameter is NULL, then a caller
255 ID of gEfiCallerIdGuid is used.
256 @param ExtendedDataGuid Pointer to the GUID for the extended data buffer.
257 If this parameter is NULL, then a the status code
258 standard header is filled in with
259 gEfiStatusCodeSpecificDataGuid.
260 @param ExtendedData Pointer to the extended data buffer. This is an
261 optional parameter that may be NULL.
262 @param ExtendedDataSize The size, in bytes, of the extended data buffer.
264 @retval EFI_SUCCESS The status code was reported.
265 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate
266 the extended data section if it was specified.
267 @retval EFI_UNSUPPORTED Report status code is not supported
272 InternalReportStatusCodeEx (
273 IN EFI_STATUS_CODE_TYPE Type
,
274 IN EFI_STATUS_CODE_VALUE Value
,
276 IN CONST EFI_GUID
*CallerId OPTIONAL
,
277 IN CONST EFI_GUID
*ExtendedDataGuid OPTIONAL
,
278 IN CONST VOID
*ExtendedData OPTIONAL
,
279 IN UINTN ExtendedDataSize
282 ASSERT (!((ExtendedData
== NULL
) && (ExtendedDataSize
!= 0)));
283 ASSERT (!((ExtendedData
!= NULL
) && (ExtendedDataSize
== 0)));
285 if (ExtendedDataSize
> EFI_STATUS_CODE_DATA_MAX_SIZE
) {
286 return EFI_OUT_OF_RESOURCES
;
290 // Fill in the extended data header
292 mStatusCodeData
->HeaderSize
= sizeof (EFI_STATUS_CODE_DATA
);
293 mStatusCodeData
->Size
= (UINT16
)ExtendedDataSize
;
294 if (ExtendedDataGuid
== NULL
) {
295 ExtendedDataGuid
= &gEfiStatusCodeSpecificDataGuid
;
297 CopyGuid (&mStatusCodeData
->Type
, ExtendedDataGuid
);
300 // Fill in the extended data buffer
302 CopyMem (mStatusCodeData
+ 1, ExtendedData
, ExtendedDataSize
);
305 // Report the status code
307 if (CallerId
== NULL
) {
308 CallerId
= &gEfiCallerIdGuid
;
310 return InternalReportStatusCode (Type
, Value
, Instance
, CallerId
, mStatusCodeData
);