]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Library/DxeReportStatusCodeLib/ReportStatusCodeLib.c
Roll back the change which doesn't call LocateProtocol when TPL is TPL_NOTIFY because...
[mirror_edk2.git] / MdeModulePkg / Library / DxeReportStatusCodeLib / ReportStatusCodeLib.c
index f32e167d94a112a2090f54e4f26e352909e2ef66..ce843cc47f46129d2d897577db8810dd5309ea75 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
   Report Status Code Library for DXE Phase.\r
 \r
-  Copyright (c) 2006 - 2009, Intel Corporation<BR>\r
-  All rights reserved. This program and the accompanying materials\r
+  Copyright (c) 2006 - 2010, 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
 \r
 #include <Library/ReportStatusCodeLib.h>\r
+#include <Library/BaseLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/BaseLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
 #include <Library/PcdLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
 #include <Library/DevicePathLib.h>\r
 \r
+#include <Protocol/StatusCode.h>\r
+\r
 #include <Guid/StatusCodeDataTypeId.h>\r
 #include <Guid/StatusCodeDataTypeDebug.h>\r
-#include <Protocol/StatusCode.h>\r
 \r
-EFI_REPORT_STATUS_CODE  mReportStatusCode = NULL;\r
+//\r
+// Define the maximum extended data size that is supported when a status code is\r
+// reported at TPL_HIGH_LEVEL.\r
+//\r
+#define MAX_EXTENDED_DATA_SIZE  0x200\r
+\r
+EFI_STATUS_CODE_PROTOCOL  *mReportStatusCodeLibStatusCodeProtocol = NULL;\r
 \r
 /**\r
   Locate the report status code service.\r
 \r
-  @return   Function pointer to the report status code service.\r
-            NULL is returned if no status code service is available.\r
+  Retrieve ReportStatusCode() API of Report Status Code Protocol.\r
 \r
 **/\r
-EFI_REPORT_STATUS_CODE\r
+VOID\r
 InternalGetReportStatusCode (\r
   VOID\r
   )\r
 {\r
-  EFI_STATUS_CODE_PROTOCOL  *StatusCodeProtocol;\r
-  EFI_STATUS                Status;\r
+  EFI_STATUS  Status;\r
 \r
+  if (mReportStatusCodeLibStatusCodeProtocol != NULL) {\r
+    return;\r
+  }\r
+\r
+  //\r
+  // Check gBS just in case ReportStatusCode is called before gBS is initialized.\r
+  //\r
   if (gBS != NULL && gBS->LocateProtocol != NULL) {\r
-    Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID**)&StatusCodeProtocol);\r
-    if (!EFI_ERROR (Status) && StatusCodeProtocol != NULL) {\r
-      return StatusCodeProtocol->ReportStatusCode;\r
+    Status = gBS->LocateProtocol (&gEfiStatusCodeRuntimeProtocolGuid, NULL, (VOID**) &mReportStatusCodeLibStatusCodeProtocol);\r
+    if (EFI_ERROR (Status)) {\r
+      mReportStatusCodeLibStatusCodeProtocol = NULL;\r
     }\r
   }\r
-\r
-  return NULL;\r
 }\r
 \r
 /**\r
-  Internal worker function that reports a status code through the status code service.\r
+  Internal worker function that reports a status code through the Report Status Code Protocol.\r
 \r
-  If status code service is not cached, then this function checks if status code service is\r
-  available in system.  If status code service is not available, then EFI_UNSUPPORTED is\r
-  returned.  If status code service is present, then it is cached in mReportStatusCode.\r
-  Finally this function reports status code through the status code service.\r
+  If status code service is not cached, then this function checks if Report Status Code\r
+  Protocol is available in system.  If Report Status Code Protocol is not available, then\r
+  EFI_UNSUPPORTED is returned.  If Report Status Code Protocol is present, then it is\r
+  cached in mReportStatusCodeLibStatusCodeProtocol. Finally this function reports status\r
+  code through the Report Status Code Protocol.\r
 \r
   @param  Type              Status code type.\r
   @param  Value             Status code value.\r
@@ -71,7 +80,7 @@ InternalGetReportStatusCode (
                             optional parameter that may be NULL.\r
 \r
   @retval EFI_SUCCESS       The status code was reported.\r
-  @retval EFI_UNSUPPORTED   Status code service is not available.\r
+  @retval EFI_UNSUPPORTED   Report Status Code Protocol is not available.\r
   @retval EFI_UNSUPPORTED   Status code type is not supported.\r
 \r
 **/\r
@@ -88,19 +97,17 @@ InternalReportStatusCode (
       (ReportErrorCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) ||\r
       (ReportDebugCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE)) {\r
     //\r
-    // If mReportStatusCode is NULL, then check if status code service is available in system.\r
+    // If mReportStatusCodeLibStatusCodeProtocol is NULL, then check if Report Status Code Protocol is available in system.\r
     //\r
-    if (mReportStatusCode == NULL) {\r
-      mReportStatusCode = InternalGetReportStatusCode ();\r
-      if (mReportStatusCode == NULL) {\r
-        return EFI_UNSUPPORTED;\r
-      }\r
+    InternalGetReportStatusCode ();\r
+    if (mReportStatusCodeLibStatusCodeProtocol == NULL) {\r
+      return EFI_UNSUPPORTED;\r
     }\r
-  \r
+\r
     //\r
-    // A status code service is present in system, so pass in all the parameters to the service.\r
+    // A Report Status Code Protocol is present in system, so pass in all the parameters to the service.\r
     //\r
-    return (*mReportStatusCode) (Type, Value, Instance, (EFI_GUID *)CallerId, Data);\r
+    return mReportStatusCodeLibStatusCodeProtocol->ReportStatusCode (Type, Value, Instance, (EFI_GUID *)CallerId, Data);\r
   }\r
   \r
   return EFI_UNSUPPORTED;\r
@@ -483,6 +490,8 @@ ReportStatusCodeEx (
 {\r
   EFI_STATUS            Status;\r
   EFI_STATUS_CODE_DATA  *StatusCodeData;\r
+  EFI_TPL               Tpl;\r
+  UINT64                Buffer[(MAX_EXTENDED_DATA_SIZE / sizeof (UINT64)) + 1];\r
 \r
   ASSERT (!((ExtendedData == NULL) && (ExtendedDataSize != 0)));\r
   ASSERT (!((ExtendedData != NULL) && (ExtendedDataSize == 0)));\r
@@ -492,19 +501,39 @@ ReportStatusCodeEx (
   }\r
 \r
   //\r
-  // Allocate space for the Status Code Header and its buffer\r
+  // Retrieve the current TPL\r
   //\r
+  Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+  gBS->RestoreTPL (Tpl);\r
+  \r
   StatusCodeData = NULL;\r
-  gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_STATUS_CODE_DATA) + ExtendedDataSize, (VOID **)&StatusCodeData);\r
+  if (Tpl <= TPL_NOTIFY) {\r
+    //\r
+    // Allocate space for the Status Code Header and its buffer\r
+    //\r
+    gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_STATUS_CODE_DATA) + ExtendedDataSize, (VOID **)&StatusCodeData);\r
+  }\r
+\r
   if (StatusCodeData == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
+    //\r
+    // If a buffer could not be allocated, then see if the local variable Buffer can be used\r
+    //\r
+    if (ExtendedDataSize > (MAX_EXTENDED_DATA_SIZE - sizeof (EFI_STATUS_CODE_DATA))) {\r
+      //\r
+      // The local variable Buffer not large enough to hold the extended data associated\r
+      // with the status code being reported.\r
+      //\r
+      DEBUG ((EFI_D_ERROR, "Status code extended data is too large to be reported!\n"));\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    StatusCodeData = (EFI_STATUS_CODE_DATA  *)Buffer;\r
   }\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
@@ -528,7 +557,9 @@ ReportStatusCodeEx (
   //\r
   // Free the allocated buffer\r
   //\r
-  gBS->FreePool (StatusCodeData);\r
+  if (StatusCodeData != (EFI_STATUS_CODE_DATA  *)Buffer) {\r
+    gBS->FreePool (StatusCodeData);\r
+  }\r
 \r
   return Status;\r
 }\r