3 Copyright (c) 2004 - 2011, Intel Corporation. All rights reserved.<BR>
4 This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 SmmRuntimeDxeSupport.c
19 Report Status Code Library for DXE Phase.
23 #include "ReportStatusCodeLibInternal.h"
24 #include EFI_PROTOCOL_DEFINITION (SmmStatusCode)
26 EFI_EVENT mVirtualAddressChangeEvent
;
28 EFI_EVENT mExitBootServicesEvent
;
30 EFI_STATUS_CODE_DATA
*mStatusCodeData
;
34 EFI_SMM_BASE_PROTOCOL
*mSmmBase
;
36 EFI_RUNTIME_SERVICES
*mRTSmmRuntimeDxeReportStatusCodeLib
;
38 BOOLEAN mHaveExitedBootServices
= FALSE
;
40 EFI_SMM_STATUS_CODE_PROTOCOL
*mSmmStatusCode
;
43 SmmStatusCodeInitialize (
49 Status
= gBS
->LocateProtocol (&gEfiSmmStatusCodeProtocolGuid
, NULL
, (VOID
**) &mSmmStatusCode
);
50 if (EFI_ERROR (Status
)) {
51 mSmmStatusCode
= NULL
;
57 IN EFI_STATUS_CODE_TYPE Type
,
58 IN EFI_STATUS_CODE_VALUE Value
,
60 IN EFI_GUID
*CallerId OPTIONAL
,
61 IN EFI_STATUS_CODE_DATA
*Data OPTIONAL
64 if (mSmmStatusCode
!= NULL
) {
65 (mSmmStatusCode
->ReportStatusCode
) (mSmmStatusCode
, Type
, Value
, Instance
, CallerId
, Data
);
71 Locate he report status code service.
73 @return EFI_REPORT_STATUS_CODE function point to
76 EFI_REPORT_STATUS_CODE
77 InternalGetReportStatusCode (
81 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
82 EFI_STATUS_CODE_PROTOCOL
*StatusCodeProtocol
;
87 return (EFI_REPORT_STATUS_CODE
) SmmStatusCodeReport
;
88 #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
89 } else if (!mHaveExitedBootServices
) {
91 // Check gBS just in case. ReportStatusCode is called before gBS is initialized.
94 Status
= gBS
->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid
, NULL
, (VOID
**)&StatusCodeProtocol
);
95 if (!EFI_ERROR (Status
) && StatusCodeProtocol
!= NULL
) {
96 return StatusCodeProtocol
->ReportStatusCode
;
100 #elif (TIANO_RELEASE_VERSION != 0)
101 } else if (mRTSmmRuntimeDxeReportStatusCodeLib
!= NULL
) {
102 return mRTSmmRuntimeDxeReportStatusCodeLib
->ReportStatusCode
;
111 Fixup internal report status code protocol interface.
113 @param[in] Event The Event that is being processed
114 @param[in] Context Event Context
118 ReportStatusCodeLibVirtualAddressChange (
123 if (NULL
!= mReportStatusCode
) {
124 mRTSmmRuntimeDxeReportStatusCodeLib
->ConvertPointer (0, (VOID
**) &mReportStatusCode
);
126 mRTSmmRuntimeDxeReportStatusCodeLib
->ConvertPointer (0, (VOID
**) &mStatusCodeData
);
127 mRTSmmRuntimeDxeReportStatusCodeLib
->ConvertPointer (0, (VOID
**) &mRTSmmRuntimeDxeReportStatusCodeLib
);
131 Update the In Runtime Indicator.
133 @param[in] Event The Event that is being processed
134 @param[in] Context Event Context
138 ReportStatusCodeLibExitBootServices (
144 // If mReportStatusCode is NULL, then see if a Status Code Protocol instance is present
145 // in the handle database.
147 if (mReportStatusCode
== NULL
) {
148 mReportStatusCode
= InternalGetReportStatusCode ();
151 mHaveExitedBootServices
= TRUE
;
155 Intialize Report Status Code Lib.
157 @param[in] ImageHandle The firmware allocated handle for the EFI image.
158 @param[in] SystemTable A pointer to the EFI System Table.
160 @return EFI_STATUS always returns EFI_SUCCESS.
164 ReportStatusCodeLibConstruct (
165 IN EFI_HANDLE ImageHandle
,
166 IN EFI_SYSTEM_TABLE
*SystemTable
172 // SMM driver depends on the SMM BASE protocol.
173 // the SMM driver must be success to locate protocol.
175 Status
= gBS
->LocateProtocol (&gEfiSmmBaseProtocolGuid
, NULL
, (VOID
**) &mSmmBase
);
176 if (!EFI_ERROR (Status
)) {
177 mSmmBase
->InSmm (mSmmBase
, &mInSmm
);
179 Status
= mSmmBase
->SmmAllocatePool (
181 EfiRuntimeServicesData
,
182 sizeof (EFI_STATUS_CODE_DATA
) + EFI_STATUS_CODE_DATA_MAX_SIZE
,
183 (VOID
**) &mStatusCodeData
185 ASSERT_EFI_ERROR (Status
);
186 SmmStatusCodeInitialize ();
192 // Library should not use the gRT directly, since it
193 // may be converted by other library instance.
195 mRTSmmRuntimeDxeReportStatusCodeLib
= gRT
;
198 (gBS
->AllocatePool
) (EfiRuntimeServicesData
, sizeof (EFI_STATUS_CODE_DATA
) + EFI_STATUS_CODE_DATA_MAX_SIZE
, (VOID
**)&mStatusCodeData
);
199 ASSERT (NULL
!= mStatusCodeData
);
201 // Cache the report status code service
203 mReportStatusCode
= InternalGetReportStatusCode ();
206 // Register the call back of virtual address change
208 Status
= gBS
->CreateEvent (
209 EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
,
211 ReportStatusCodeLibVirtualAddressChange
,
213 &mVirtualAddressChangeEvent
215 ASSERT_EFI_ERROR (Status
);
219 // Register the call back of exit boot services
221 Status
= gBS
->CreateEvent (
222 EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES
,
224 ReportStatusCodeLibExitBootServices
,
226 &mExitBootServicesEvent
228 ASSERT_EFI_ERROR (Status
);
234 Desctructor of library will close events.
236 @param ImageHandle callder module's image handle
237 @param SystemTable pointer to EFI system table.
238 @return the status of close event.
242 ReportStatusCodeLibDestruct (
243 IN EFI_HANDLE ImageHandle
,
244 IN EFI_SYSTEM_TABLE
*SystemTable
251 // Close SetVirtualAddressMap () notify function
253 ASSERT (gBS
!= NULL
);
254 Status
= gBS
->CloseEvent (mVirtualAddressChangeEvent
);
255 ASSERT_EFI_ERROR (Status
);
256 Status
= gBS
->CloseEvent (mExitBootServicesEvent
);
257 ASSERT_EFI_ERROR (Status
);
259 (gBS
->FreePool
) (mStatusCodeData
);
261 mSmmBase
->SmmFreePool (mSmmBase
, mStatusCodeData
);
268 Reports a status code with full parameters.
270 The function reports a status code. If ExtendedData is NULL and ExtendedDataSize
271 is 0, then an extended data buffer is not reported. If ExtendedData is not
272 NULL and ExtendedDataSize is not 0, then an extended data buffer is allocated.
273 ExtendedData is assumed not have the standard status code header, so this function
274 is responsible for allocating a buffer large enough for the standard header and
275 the extended data passed into this function. The standard header is filled in
276 with a GUID specified by ExtendedDataGuid. If ExtendedDataGuid is NULL, then a
277 GUID of gEfiStatusCodeSpecificDatauid is used. The status code is reported with
278 an instance specified by Instance and a caller ID specified by CallerId. If
279 CallerId is NULL, then a caller ID of gEfiCallerIdGuid is used.
281 ReportStatusCodeEx()must actively prevent recursion. If ReportStatusCodeEx()
282 is called while processing another any other Report Status Code Library function,
283 then ReportStatusCodeEx() must return EFI_DEVICE_ERROR immediately.
285 If ExtendedData is NULL and ExtendedDataSize is not zero, then ASSERT().
286 If ExtendedData is not NULL and ExtendedDataSize is zero, then ASSERT().
288 @param Type Status code type.
289 @param Value Status code value.
290 @param Instance Status code instance number.
291 @param CallerId Pointer to a GUID that identifies the caller of this
292 function. If this parameter is NULL, then a caller
293 ID of gEfiCallerIdGuid is used.
294 @param ExtendedDataGuid Pointer to the GUID for the extended data buffer.
295 If this parameter is NULL, then a the status code
296 standard header is filled in with
297 gEfiStatusCodeSpecificDataGuid.
298 @param ExtendedData Pointer to the extended data buffer. This is an
299 optional parameter that may be NULL.
300 @param ExtendedDataSize The size, in bytes, of the extended data buffer.
302 @retval EFI_SUCCESS The status code was reported.
303 @retval EFI_OUT_OF_RESOURCES There were not enough resources to allocate
304 the extended data section if it was specified.
305 @retval EFI_UNSUPPORTED Report status code is not supported
310 InternalReportStatusCodeEx (
311 IN EFI_STATUS_CODE_TYPE Type
,
312 IN EFI_STATUS_CODE_VALUE Value
,
314 IN CONST EFI_GUID
*CallerId OPTIONAL
,
315 IN CONST EFI_GUID
*ExtendedDataGuid OPTIONAL
,
316 IN CONST VOID
*ExtendedData OPTIONAL
,
317 IN UINTN ExtendedDataSize
320 ASSERT (!((ExtendedData
== NULL
) && (ExtendedDataSize
!= 0)));
321 ASSERT (!((ExtendedData
!= NULL
) && (ExtendedDataSize
== 0)));
323 if (ExtendedDataSize
> EFI_STATUS_CODE_DATA_MAX_SIZE
) {
324 return EFI_OUT_OF_RESOURCES
;
328 // Fill in the extended data header
330 mStatusCodeData
->HeaderSize
= (UINT16
) sizeof (EFI_STATUS_CODE_DATA
);
331 mStatusCodeData
->Size
= (UINT16
)ExtendedDataSize
;
332 if (ExtendedDataGuid
== NULL
) {
333 ExtendedDataGuid
= &gEfiStatusCodeSpecificDataGuid
;
335 CopyGuid (&mStatusCodeData
->Type
, ExtendedDataGuid
);
338 // Fill in the extended data buffer
340 CopyMem (mStatusCodeData
+ 1, ExtendedData
, ExtendedDataSize
);
343 // Report the status code
345 if (CallerId
== NULL
) {
346 CallerId
= &gEfiCallerIdGuid
;
348 return InternalReportStatusCode (Type
, Value
, Instance
, CallerId
, mStatusCodeData
);