/** @file\r
API implementation for instance of Report Status Code Library.\r
\r
- Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include <Guid/StatusCodeDataTypeDebug.h>\r
#include <Guid/EventGroup.h>\r
\r
+\r
+//\r
+// Define the maximum extended data size that is supported when a status code is reported.\r
+//\r
+#define MAX_EXTENDED_DATA_SIZE 0x200\r
+\r
EFI_STATUS_CODE_PROTOCOL *mReportStatusCodeLibStatusCodeProtocol = NULL;\r
EFI_EVENT mReportStatusCodeLibVirtualAddressChangeEvent;\r
+EFI_EVENT mReportStatusCodeLibExitBootServicesEvent;\r
+BOOLEAN mHaveExitedBootServices = FALSE;\r
\r
/**\r
Locate the report status code service.\r
if (mReportStatusCodeLibStatusCodeProtocol != NULL) {\r
return;\r
}\r
- \r
- if (EfiAtRuntime ()) {\r
+\r
+ if (mHaveExitedBootServices) {\r
return;\r
}\r
- \r
+\r
//\r
// Check gBS just in case ReportStatusCode is called before gBS is initialized.\r
//\r
EfiConvertPointer (0, (VOID **) &mReportStatusCodeLibStatusCodeProtocol);\r
}\r
\r
+/**\r
+ Notification function of EVT_SIGNAL_EXIT_BOOT_SERVICES.\r
+\r
+ @param Event Event whose notification function is being invoked.\r
+ @param Context Pointer to the notification function's context\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+ReportStatusCodeLibExitBootServices (\r
+ IN EFI_EVENT Event,\r
+ IN VOID *Context\r
+ )\r
+{\r
+ //\r
+ // Locate the report status code service before enter runtime.\r
+ //\r
+ InternalGetReportStatusCode ();\r
+\r
+ mHaveExitedBootServices = TRUE;\r
+}\r
+\r
/**\r
The constructor function of Runtime DXE Report Status Code Lib.\r
\r
\r
@param ImageHandle The firmware allocated handle for the EFI image.\r
@param SystemTable A pointer to the EFI System Table.\r
- \r
+\r
@retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
\r
**/\r
\r
//\r
// Cache the report status code service\r
- // \r
+ //\r
InternalGetReportStatusCode ();\r
\r
//\r
// Register notify function for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE\r
- // \r
+ //\r
Status = gBS->CreateEventEx (\r
EVT_NOTIFY_SIGNAL,\r
TPL_NOTIFY,\r
);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ //\r
+ // Register notify function for EVT_SIGNAL_EXIT_BOOT_SERVICES\r
+ //\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ ReportStatusCodeLibExitBootServices,\r
+ NULL,\r
+ &gEfiEventExitBootServicesGuid,\r
+ &mReportStatusCodeLibExitBootServicesEvent\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
return EFI_SUCCESS;\r
}\r
\r
/**\r
The destructor function of Runtime DXE Report Status Code Lib.\r
- \r
+\r
The destructor function frees memory allocated by constructor, and closes related events.\r
- It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS. \r
+ It will ASSERT() if that related operation fails and it will always return EFI_SUCCESS.\r
\r
@param ImageHandle The firmware allocated handle for the EFI image.\r
@param SystemTable A pointer to the EFI System Table.\r
- \r
+\r
@retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.\r
\r
**/\r
Status = gBS->CloseEvent (mReportStatusCodeLibVirtualAddressChangeEvent);\r
ASSERT_EFI_ERROR (Status);\r
\r
+ Status = gBS->CloseEvent (mReportStatusCodeLibExitBootServicesEvent);\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
return EFI_SUCCESS;\r
}\r
\r
//\r
return mReportStatusCodeLibStatusCodeProtocol->ReportStatusCode (Type, Value, Instance, (EFI_GUID *)CallerId, Data);\r
}\r
- \r
+\r
return EFI_UNSUPPORTED;\r
}\r
\r
{\r
EFI_STATUS Status;\r
EFI_STATUS_CODE_DATA *StatusCodeData;\r
- UINT8 StatusCodeBuffer[EFI_STATUS_CODE_DATA_MAX_SIZE];\r
+ UINT64 StatusCodeBuffer[(MAX_EXTENDED_DATA_SIZE / sizeof (UINT64)) + 1];\r
\r
ASSERT (!((ExtendedData == NULL) && (ExtendedDataSize != 0)));\r
ASSERT (!((ExtendedData != NULL) && (ExtendedDataSize == 0)));\r
\r
- if (EfiAtRuntime ()) {\r
- if (sizeof (EFI_STATUS_CODE_DATA) + ExtendedDataSize > EFI_STATUS_CODE_DATA_MAX_SIZE) {\r
+ if (ExtendedDataSize <= (MAX_EXTENDED_DATA_SIZE - sizeof (EFI_STATUS_CODE_DATA))) {\r
+ //\r
+ // Use Buffer instead of allocating if possible.\r
+ //\r
+ StatusCodeData = (EFI_STATUS_CODE_DATA *) StatusCodeBuffer;\r
+ } else {\r
+ if (mHaveExitedBootServices) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
- StatusCodeData = (EFI_STATUS_CODE_DATA *)StatusCodeBuffer;\r
- } else {\r
+\r
if (gBS == NULL || gBS->AllocatePool == NULL || gBS->FreePool == NULL) {\r
return EFI_UNSUPPORTED;\r
}\r
- \r
+\r
//\r
// Allocate space for the Status Code Header and its buffer\r
//\r
//\r
// Fill in the extended data header\r
//\r
- StatusCodeData->HeaderSize = sizeof (EFI_STATUS_CODE_DATA);\r
- StatusCodeData->Size = (UINT16)ExtendedDataSize;\r
+ StatusCodeData->HeaderSize = (UINT16) sizeof (EFI_STATUS_CODE_DATA);\r
+ StatusCodeData->Size = (UINT16) ExtendedDataSize;\r
if (ExtendedDataGuid == NULL) {\r
ExtendedDataGuid = &gEfiStatusCodeSpecificDataGuid;\r
}\r
//\r
// Free the allocated buffer\r
//\r
- if (!EfiAtRuntime()) {\r
+ if (StatusCodeData != (EFI_STATUS_CODE_DATA *) StatusCodeBuffer) {\r
gBS->FreePool (StatusCodeData);\r
}\r
\r