]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/RuntimeDxeReportStatusCodeLib/ReportStatusCodeLib.c
MdeModulePkg/FPDT: Lock boot performance table address variable at EndOfDxe
[mirror_edk2.git] / MdeModulePkg / Library / RuntimeDxeReportStatusCodeLib / ReportStatusCodeLib.c
index f6d77815450e4b7d45ad6ce7fe2cd923ef158381..dc7fcf7a2d7879557b3456817eb56ba4abc822fe 100644 (file)
@@ -1,14 +1,8 @@
 /** @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
@@ -46,11 +48,11 @@ InternalGetReportStatusCode (
   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
@@ -82,6 +84,28 @@ ReportStatusCodeLibVirtualAddressChange (
   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
@@ -90,7 +114,7 @@ ReportStatusCodeLibVirtualAddressChange (
 \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
@@ -105,12 +129,12 @@ ReportStatusCodeLibConstructor (
 \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
@@ -121,18 +145,31 @@ ReportStatusCodeLibConstructor (
                   );\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
@@ -149,6 +186,9 @@ ReportStatusCodeLibDestructor (
   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
@@ -200,7 +240,7 @@ InternalReportStatusCode (
     //\r
     return mReportStatusCodeLibStatusCodeProtocol->ReportStatusCode (Type, Value, Instance, (EFI_GUID *)CallerId, Data);\r
   }\r
-  \r
+\r
   return EFI_UNSUPPORTED;\r
 }\r
 \r
@@ -581,21 +621,25 @@ ReportStatusCodeEx (
 {\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
@@ -609,8 +653,8 @@ ReportStatusCodeEx (
   //\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
@@ -634,7 +678,7 @@ ReportStatusCodeEx (
   //\r
   // Free the allocated buffer\r
   //\r
-  if (!EfiAtRuntime()) {\r
+  if (StatusCodeData != (EFI_STATUS_CODE_DATA *) StatusCodeBuffer) {\r
     gBS->FreePool (StatusCodeData);\r
   }\r
 \r