]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Acpi/FirmwarePerformanceDataTableSmm/FirmwarePerformanceSmm.c
MdeModulePkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / MdeModulePkg / Universal / Acpi / FirmwarePerformanceDataTableSmm / FirmwarePerformanceSmm.c
index 54a2275d4ed908bcd0e480242d4de82885d6bd15..d6c6e7693e4d0df91c62ea03c56d57fd40c578ee 100644 (file)
 \r
   FpdtSmiHandler() will receive untrusted input and do basic validation.\r
 \r
-  Copyright (c) 2011 - 2012, 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) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
 #include <PiSmm.h>\r
 \r
 #include <Protocol/SmmReportStatusCodeHandler.h>\r
-#include <Protocol/SmmAccess2.h>\r
 \r
 #include <Guid/FirmwarePerformance.h>\r
 \r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 #include <Library/SynchronizationLib.h>\r
+#include <Library/SmmMemLib.h>\r
 \r
-#define EXTENSION_RECORD_SIZE     0x1000\r
+SMM_BOOT_PERFORMANCE_TABLE    *mSmmBootPerformanceTable = NULL;\r
 \r
 EFI_SMM_RSC_HANDLER_PROTOCOL  *mRscHandlerProtocol    = NULL;\r
 UINT64                        mSuspendStartTime       = 0;\r
 BOOLEAN                       mS3SuspendLockBoxSaved  = FALSE;\r
 UINT32                        mBootRecordSize = 0;\r
-UINT32                        mBootRecordMaxSize = 0;\r
 UINT8                         *mBootRecordBuffer = NULL;\r
 \r
-EFI_SMRAM_DESCRIPTOR          *mSmramRanges;\r
-UINTN                         mSmramRangeCount;\r
 SPIN_LOCK                     mSmmFpdtLock;\r
 BOOLEAN                       mSmramIsOutOfResource = FALSE;\r
 \r
@@ -86,7 +77,6 @@ FpdtStatusCodeListenerSmm (
   EFI_STATUS                           Status;\r
   UINT64                               CurrentTime;\r
   EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD  S3SuspendRecord;\r
-  UINT8                                *NewRecordBuffer;\r
 \r
   //\r
   // Check whether status code is what we are interested in.\r
@@ -94,40 +84,27 @@ FpdtStatusCodeListenerSmm (
   if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) != EFI_PROGRESS_CODE) {\r
     return EFI_UNSUPPORTED;\r
   }\r
-  \r
+\r
   //\r
   // Collect one or more Boot records in boot time\r
   //\r
-  if (Data != NULL && CompareGuid (&Data->Type, &gEfiFirmwarePerformanceGuid)) {\r
+  if (Data != NULL && CompareGuid (&Data->Type, &gEdkiiFpdtExtendedFirmwarePerformanceGuid)) {\r
     AcquireSpinLock (&mSmmFpdtLock);\r
-    \r
-    if (mBootRecordSize + Data->Size > mBootRecordMaxSize) {\r
-      //\r
-      // Try to allocate big SMRAM data to store Boot record. \r
-      //\r
-      if (mSmramIsOutOfResource) {\r
-        ReleaseSpinLock (&mSmmFpdtLock);\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-      NewRecordBuffer = ReallocatePool (mBootRecordSize, mBootRecordSize + Data->Size + EXTENSION_RECORD_SIZE, mBootRecordBuffer); \r
-      if (NewRecordBuffer == NULL) {\r
-        ReleaseSpinLock (&mSmmFpdtLock);\r
-        mSmramIsOutOfResource = TRUE;\r
-        return EFI_OUT_OF_RESOURCES;\r
-      }\r
-      mBootRecordBuffer  = NewRecordBuffer;\r
-      mBootRecordMaxSize = mBootRecordSize + Data->Size + EXTENSION_RECORD_SIZE;\r
-    }\r
     //\r
-    // Save boot record into the temp memory space.\r
+    // Get the boot performance data.\r
     //\r
-    CopyMem (mBootRecordBuffer + mBootRecordSize, Data + 1, Data->Size);\r
-    mBootRecordSize += Data->Size;\r
-    \r
+    CopyMem (&mSmmBootPerformanceTable, Data + 1, Data->Size);\r
+    mBootRecordBuffer = ((UINT8 *) (mSmmBootPerformanceTable)) + sizeof (SMM_BOOT_PERFORMANCE_TABLE);\r
+\r
     ReleaseSpinLock (&mSmmFpdtLock);\r
     return EFI_SUCCESS;\r
   }\r
 \r
+  if (Data != NULL && CompareGuid (&Data->Type, &gEfiFirmwarePerformanceGuid)) {\r
+    DEBUG ((DEBUG_ERROR, "FpdtStatusCodeListenerSmm: Performance data reported through gEfiFirmwarePerformanceGuid will not be collected by FirmwarePerformanceDataTableSmm\n"));\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
   if ((Value != PcdGet32 (PcdProgressCodeS3SuspendStart)) &&\r
       (Value != PcdGet32 (PcdProgressCodeS3SuspendEnd))) {\r
     return EFI_UNSUPPORTED;\r
@@ -177,37 +154,10 @@ FpdtStatusCodeListenerSmm (
   return EFI_SUCCESS;\r
 }\r
 \r
-/**\r
-  This function check if the address is in SMRAM.\r
-\r
-  @param Buffer  the buffer address to be checked.\r
-  @param Length  the buffer length to be checked.\r
-\r
-  @retval TRUE  this address is in SMRAM.\r
-  @retval FALSE this address is NOT in SMRAM.\r
-**/\r
-BOOLEAN\r
-InternalIsAddressInSmram (\r
-  IN EFI_PHYSICAL_ADDRESS  Buffer,\r
-  IN UINT64                Length\r
-  )\r
-{\r
-  UINTN  Index;\r
-\r
-  for (Index = 0; Index < mSmramRangeCount; Index ++) {\r
-    if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer < mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) ||\r
-        ((mSmramRanges[Index].CpuStart >= Buffer) && (mSmramRanges[Index].CpuStart < Buffer + Length))) {\r
-      return TRUE;\r
-    }\r
-  }\r
-\r
-  return FALSE;\r
-}\r
-\r
 /**\r
   Communication service SMI Handler entry.\r
 \r
-  This SMI handler provides services for report SMM boot records. \r
+  This SMI handler provides services for report SMM boot records.\r
 \r
   Caution: This function may receive untrusted input.\r
   Communicate buffer and buffer size are external input, so this function will do basic validation.\r
@@ -219,11 +169,11 @@ InternalIsAddressInSmram (
                                  be conveyed from a non-SMM environment into an SMM environment.\r
   @param[in, out] CommBufferSize The size of the CommBuffer.\r
 \r
-  @retval EFI_SUCCESS                         The interrupt was handled and quiesced. No other handlers \r
+  @retval EFI_SUCCESS                         The interrupt was handled and quiesced. No other handlers\r
                                               should still be called.\r
-  @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED  The interrupt has been quiesced but other handlers should \r
+  @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED  The interrupt has been quiesced but other handlers should\r
                                               still be called.\r
-  @retval EFI_WARN_INTERRUPT_SOURCE_PENDING   The interrupt is still pending and other handlers should still \r
+  @retval EFI_WARN_INTERRUPT_SOURCE_PENDING   The interrupt is still pending and other handlers should still\r
                                               be called.\r
   @retval EFI_INTERRUPT_PENDING               The interrupt could not be quiesced.\r
 \r
@@ -239,6 +189,10 @@ FpdtSmiHandler (
 {\r
   EFI_STATUS                   Status;\r
   SMM_BOOT_RECORD_COMMUNICATE  *SmmCommData;\r
+  UINTN                        BootRecordOffset;\r
+  UINTN                        BootRecordSize;\r
+  VOID                         *BootRecordData;\r
+  UINTN                        TempCommBufferSize;\r
 \r
   //\r
   // If input is invalid, stop processing this SMI\r
@@ -247,12 +201,14 @@ FpdtSmiHandler (
     return EFI_SUCCESS;\r
   }\r
 \r
-  if(*CommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {\r
+  TempCommBufferSize = *CommBufferSize;\r
+\r
+  if(TempCommBufferSize < sizeof (SMM_BOOT_RECORD_COMMUNICATE)) {\r
     return EFI_SUCCESS;\r
   }\r
-  \r
-  if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)CommBuffer, *CommBufferSize)) {\r
-    DEBUG ((EFI_D_ERROR, "SMM communication data buffer is in SMRAM!\n"));\r
+\r
+  if (!SmmIsBufferOutsideSmmValid ((UINTN)CommBuffer, TempCommBufferSize)) {\r
+    DEBUG ((EFI_D_ERROR, "FpdtSmiHandler: SMM communication data buffer in SMRAM or overflow!\n"));\r
     return EFI_SUCCESS;\r
   }\r
 \r
@@ -262,38 +218,51 @@ FpdtSmiHandler (
 \r
   switch (SmmCommData->Function) {\r
     case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_SIZE :\r
-       SmmCommData->BootRecordSize = mBootRecordSize;\r
-       break;\r
+      if (mSmmBootPerformanceTable != NULL) {\r
+        mBootRecordSize = mSmmBootPerformanceTable->Header.Length - sizeof (SMM_BOOT_PERFORMANCE_TABLE);\r
+      }\r
+      SmmCommData->BootRecordSize = mBootRecordSize;\r
+      break;\r
 \r
     case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA :\r
-       if (SmmCommData->BootRecordData == NULL || SmmCommData->BootRecordSize < mBootRecordSize) {\r
-         Status = EFI_INVALID_PARAMETER;\r
-         break;\r
-       } \r
-\r
-       //\r
-       // Sanity check\r
-       //\r
-       SmmCommData->BootRecordSize = mBootRecordSize;\r
-       if (InternalIsAddressInSmram ((EFI_PHYSICAL_ADDRESS)(UINTN)SmmCommData->BootRecordData, mBootRecordSize)) {\r
-         DEBUG ((EFI_D_ERROR, "SMM Data buffer is in SMRAM!\n"));\r
-         Status = EFI_ACCESS_DENIED;\r
-         break;\r
-       }\r
-\r
-       CopyMem (\r
-         (UINT8*)SmmCommData->BootRecordData, \r
-         mBootRecordBuffer, \r
-         mBootRecordSize\r
-         );\r
-       break;\r
+      Status = EFI_UNSUPPORTED;\r
+      break;\r
+\r
+    case SMM_FPDT_FUNCTION_GET_BOOT_RECORD_DATA_BY_OFFSET :\r
+      BootRecordOffset = SmmCommData->BootRecordOffset;\r
+      BootRecordData   = SmmCommData->BootRecordData;\r
+      BootRecordSize   = SmmCommData->BootRecordSize;\r
+      if (BootRecordData == NULL || BootRecordOffset >= mBootRecordSize) {\r
+        Status = EFI_INVALID_PARAMETER;\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Sanity check\r
+      //\r
+      if (BootRecordSize > mBootRecordSize - BootRecordOffset) {\r
+        BootRecordSize = mBootRecordSize - BootRecordOffset;\r
+      }\r
+      SmmCommData->BootRecordSize = BootRecordSize;\r
+      if (!SmmIsBufferOutsideSmmValid ((UINTN)BootRecordData, BootRecordSize)) {\r
+        DEBUG ((EFI_D_ERROR, "FpdtSmiHandler: SMM Data buffer in SMRAM or overflow!\n"));\r
+        Status = EFI_ACCESS_DENIED;\r
+        break;\r
+      }\r
+\r
+      CopyMem (\r
+       (UINT8*)BootRecordData,\r
+       mBootRecordBuffer + BootRecordOffset,\r
+       BootRecordSize\r
+       );\r
+      break;\r
 \r
     default:\r
-       Status = EFI_UNSUPPORTED;\r
+      Status = EFI_UNSUPPORTED;\r
   }\r
 \r
   SmmCommData->ReturnStatus = Status;\r
-  \r
+\r
   return EFI_SUCCESS;\r
 }\r
 \r
@@ -316,14 +285,12 @@ FirmwarePerformanceSmmEntryPoint (
 {\r
   EFI_STATUS                Status;\r
   EFI_HANDLE                Handle;\r
-  EFI_SMM_ACCESS2_PROTOCOL  *SmmAccess;\r
-  UINTN                     Size;\r
 \r
   //\r
   // Initialize spin lock\r
   //\r
-  InitializeSpinLock (&mSmmFpdtLock); \r
-   \r
+  InitializeSpinLock (&mSmmFpdtLock);\r
+\r
   //\r
   // Get SMM Report Status Code Handler Protocol.\r
   //\r
@@ -340,28 +307,6 @@ FirmwarePerformanceSmmEntryPoint (
   Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerSmm);\r
   ASSERT_EFI_ERROR (Status);\r
 \r
-  //\r
-  // Get SMRAM information\r
-  //\r
-  Status = gBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Size = 0;\r
-  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);\r
-  ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
-\r
-  Status = gSmst->SmmAllocatePool (\r
-                    EfiRuntimeServicesData,\r
-                    Size,\r
-                    (VOID **)&mSmramRanges\r
-                    );\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);\r
-  ASSERT_EFI_ERROR (Status);\r
-\r
-  mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);\r
-\r
   //\r
   // Register SMI handler.\r
   //\r