]> git.proxmox.com Git - mirror_edk2.git/commitdiff
UefiPayloadPkg: Add a common SmmAccessDxe module
authorGuo Dong <guo.dong@intel.com>
Wed, 22 Sep 2021 21:16:41 +0000 (14:16 -0700)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Mon, 25 Oct 2021 17:28:21 +0000 (17:28 +0000)
SmmAccessDxe module would consume EFI_SMRAM_HOB_DESCRIPTOR_BLOCK HOB to
produce SMM access protocol gEfiSmmAccess2ProtocolGuid (open, close, lock,
and GetCapabilities.)

Signed-off-by: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Reviewed-by: Benjamin You <benjamin.you@intel.com>
UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c [new file with mode: 0644]
UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h [new file with mode: 0644]
UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf [new file with mode: 0644]

diff --git a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c
new file mode 100644 (file)
index 0000000..ce7026d
--- /dev/null
@@ -0,0 +1,254 @@
+/** @file\r
+  This driver publishes the SMM Access 2 Protocol.\r
+\r
+  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
+  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#include "SmmAccessDxe.h"\r
+\r
+SMM_ACCESS_PRIVATE_DATA         mSmmAccess;\r
+\r
+/**\r
+   Update region state from SMRAM description\r
+\r
+   @param[in] OrLogic     Indicate to use OR if true or AND if false.\r
+   @param[in] Value       The value to set to region state based on OrLogic.\r
+\r
+**/\r
+VOID\r
+SyncRegionState2SmramDesc(\r
+  IN BOOLEAN                OrLogic,\r
+  IN UINT64                 Value\r
+  )\r
+{\r
+  UINT32                    Index;\r
+\r
+  for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {\r
+    if (OrLogic) {\r
+      mSmmAccess.SmramDesc[Index].RegionState |= Value;\r
+    } else {\r
+      mSmmAccess.SmramDesc[Index].RegionState &= Value;\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+   This routine accepts a request to "open" a region of SMRAM.  The\r
+   region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.\r
+   The use of "open" means that the memory is visible from all boot-service\r
+   and SMM agents.\r
+\r
+   @param This                    Pointer to the SMM Access Interface.\r
+\r
+   @retval EFI_SUCCESS            The region was successfully opened.\r
+   @retval EFI_DEVICE_ERROR       The region could not be opened because locked by chipset.\r
+   @retval EFI_INVALID_PARAMETER  The descriptor index was out of bounds.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Open (\r
+  IN EFI_SMM_ACCESS2_PROTOCOL          *This\r
+  )\r
+{\r
+  if ((mSmmAccess.SmmRegionState & EFI_SMRAM_LOCKED) != 0) {\r
+    //\r
+    // Cannot open a "locked" region\r
+    //\r
+    DEBUG ((DEBUG_INFO, "Cannot open the locked SMRAM Region\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  mSmmAccess.SmmRegionState &= ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);\r
+  SyncRegionState2SmramDesc(FALSE, (UINT64)(UINTN)(~(EFI_SMRAM_CLOSED | EFI_ALLOCATED)));\r
+\r
+  mSmmAccess.SmmRegionState |= EFI_SMRAM_OPEN;\r
+  SyncRegionState2SmramDesc(TRUE, EFI_SMRAM_OPEN);\r
+  mSmmAccess.SmmAccess.OpenState = TRUE;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+   This routine accepts a request to "close" a region of SMRAM. The region\r
+   could be legacy AB or TSEG near top of physical memory.\r
+   The use of "close" means that the memory is only visible from SMM agents,\r
+   not from BS or RT code.\r
+\r
+   @param This                      Pointer to the SMM Access Interface.\r
+\r
+   @retval EFI_SUCCESS              The region was successfully closed.\r
+   @retval EFI_DEVICE_ERROR         The region could not be closed because locked by\r
+                                    chipset.\r
+   @retval EFI_INVALID_PARAMETER    The descriptor index was out of bounds.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Close (\r
+  IN EFI_SMM_ACCESS2_PROTOCOL    *This\r
+  )\r
+{\r
+  if ((mSmmAccess.SmmRegionState & EFI_SMRAM_LOCKED) != 0) {\r
+    //\r
+    // Cannot close a "locked" region\r
+    //\r
+    DEBUG ((DEBUG_INFO, "Cannot close the locked SMRAM Region\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  if ((mSmmAccess.SmmRegionState & EFI_SMRAM_CLOSED) != 0) {\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  mSmmAccess.SmmRegionState &= ~EFI_SMRAM_OPEN;\r
+  SyncRegionState2SmramDesc(FALSE, (UINT64)(UINTN)(~EFI_SMRAM_OPEN));\r
+\r
+  mSmmAccess.SmmRegionState |= (EFI_SMRAM_CLOSED | EFI_ALLOCATED);\r
+  SyncRegionState2SmramDesc(TRUE, EFI_SMRAM_CLOSED | EFI_ALLOCATED);\r
+\r
+  mSmmAccess.SmmAccess.OpenState = FALSE;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+   This routine accepts a request to "lock" SMRAM.  The\r
+   region could be legacy AB or TSEG near top of physical memory.\r
+   The use of "lock" means that the memory can no longer be opened\r
+   to BS state.\r
+\r
+   @param This                     Pointer to the SMM Access Interface.\r
+\r
+   @retval EFI_SUCCESS             The region was successfully locked.\r
+   @retval EFI_DEVICE_ERROR        The region could not be locked because at least\r
+                                   one range is still open.\r
+   @retval EFI_INVALID_PARAMETER   The descriptor index was out of bounds.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+Lock (\r
+  IN EFI_SMM_ACCESS2_PROTOCOL    *This\r
+  )\r
+{\r
+  if (mSmmAccess.SmmAccess.OpenState) {\r
+    DEBUG ((DEBUG_INFO, "Cannot lock SMRAM when it is still open\n"));\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  mSmmAccess.SmmRegionState |= EFI_SMRAM_LOCKED;\r
+  SyncRegionState2SmramDesc(TRUE, EFI_SMRAM_LOCKED);\r
+  mSmmAccess.SmmAccess.LockState = TRUE;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+   This routine services a user request to discover the SMRAM\r
+   capabilities of this platform.  This will report the possible\r
+   ranges that are possible for SMRAM access, based upon the\r
+   memory controller capabilities.\r
+\r
+   @param This            Pointer to the SMRAM Access Interface.\r
+   @param SmramMapSize    Pointer to the variable containing size of the\r
+                          buffer to contain the description information.\r
+   @param SmramMap        Buffer containing the data describing the Smram\r
+                          region descriptors.\r
+\r
+   @retval EFI_BUFFER_TOO_SMALL  The user did not provide a sufficient buffer.\r
+   @retval EFI_SUCCESS           The user provided a sufficiently-sized buffer.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+GetCapabilities (\r
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL     *This,\r
+  IN OUT   UINTN                        *SmramMapSize,\r
+  IN OUT   EFI_SMRAM_DESCRIPTOR         *SmramMap\r
+  )\r
+{\r
+  EFI_STATUS                            Status;\r
+  UINTN                                 NecessaryBufferSize;\r
+\r
+  NecessaryBufferSize = mSmmAccess.NumberRegions * sizeof(EFI_SMRAM_DESCRIPTOR);\r
+  if (*SmramMapSize < NecessaryBufferSize) {\r
+    Status = EFI_BUFFER_TOO_SMALL;\r
+  } else {\r
+    CopyMem(SmramMap, mSmmAccess.SmramDesc, NecessaryBufferSize);\r
+    Status = EFI_SUCCESS;\r
+  }\r
+\r
+  *SmramMapSize = NecessaryBufferSize;\r
+  return Status;\r
+}\r
+\r
+/**\r
+  This function installs EFI_SMM_ACCESS_PROTOCOL.\r
+\r
+  @param  ImageHandle Handle for the image of this driver\r
+  @param  SystemTable Pointer to the EFI System Table\r
+\r
+  @retval EFI_UNSUPPORTED There's no Intel ICH on this platform\r
+  @return The status returned from InstallProtocolInterface().\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmAccessEntryPoint (\r
+  IN EFI_HANDLE                   ImageHandle,\r
+  IN EFI_SYSTEM_TABLE             *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_HOB_GUID_TYPE               *GuidHob;\r
+  UINT32                          SmmRegionNum;\r
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *SmramHob;\r
+  UINT32                          Index;\r
+\r
+  //\r
+  // Get SMRAM info HOB\r
+  //\r
+  GuidHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);\r
+  if (GuidHob == NULL) {\r
+    DEBUG ((DEBUG_INFO, "SMRAM HOB NOT found\n"));\r
+    return EFI_NOT_FOUND;\r
+  }\r
+  SmramHob     = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) GET_GUID_HOB_DATA(GuidHob);\r
+  SmmRegionNum = SmramHob->NumberOfSmmReservedRegions;\r
+  mSmmAccess.SmramDesc = AllocateZeroPool (sizeof (EFI_SMRAM_DESCRIPTOR) * SmmRegionNum);\r
+  if (mSmmAccess.SmramDesc == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+  CopyMem (mSmmAccess.SmramDesc, &SmramHob->Descriptor, sizeof (EFI_SMRAM_DESCRIPTOR) * SmmRegionNum);\r
+\r
+  DEBUG ((DEBUG_INFO, "NumberOfSmmReservedRegions = 0x%x\n", SmmRegionNum));\r
+  for (Index = 0; Index < SmmRegionNum; Index++) {\r
+    DEBUG ((DEBUG_INFO, "%d: base=0x%x, size = 0x%x, State=0x%x\n",Index,\r
+       SmramHob->Descriptor[Index].PhysicalStart,\r
+       SmramHob->Descriptor[Index].PhysicalSize,\r
+       SmramHob->Descriptor[Index].RegionState));\r
+     mSmmAccess.SmramDesc[Index].RegionState &= EFI_ALLOCATED;\r
+     mSmmAccess.SmramDesc[Index].RegionState |= EFI_SMRAM_CLOSED | EFI_CACHEABLE;\r
+  }\r
+\r
+  mSmmAccess.Signature                    = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;\r
+  mSmmAccess.NumberRegions                = SmmRegionNum;\r
+  mSmmAccess.SmmAccess.Open               = Open;\r
+  mSmmAccess.SmmAccess.Close              = Close;\r
+  mSmmAccess.SmmAccess.Lock               = Lock;\r
+  mSmmAccess.SmmAccess.GetCapabilities    = GetCapabilities;\r
+  mSmmAccess.SmmAccess.LockState          = FALSE;\r
+  mSmmAccess.SmmAccess.OpenState          = FALSE;\r
+  mSmmAccess.SmmRegionState               = EFI_SMRAM_CLOSED;\r
+\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &mSmmAccess.Handle,\r
+                  &gEfiSmmAccess2ProtocolGuid,\r
+                  &mSmmAccess.SmmAccess,\r
+                  NULL\r
+                  );\r
+\r
+  return Status;\r
+}\r
diff --git a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h
new file mode 100644 (file)
index 0000000..b6d76da
--- /dev/null
@@ -0,0 +1,37 @@
+/** @file\r
+  The header file of SMM access DXE.\r
+\r
+Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+\r
+#ifndef SMM_ACCESS_DRIVER_H_\r
+#define SMM_ACCESS_DRIVER_H_\r
+\r
+#include <PiDxe.h>\r
+#include <Protocol/SmmAccess2.h>\r
+#include <Library/HobLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Guid/SmramMemoryReserve.h>\r
+\r
+\r
+#define  SMM_ACCESS_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('S', 'M', 'M', 'A')\r
+\r
+typedef struct {\r
+  UINTN                           Signature;\r
+  EFI_HANDLE                      Handle;\r
+  EFI_SMM_ACCESS2_PROTOCOL        SmmAccess;\r
+  //\r
+  // Local Data for SMM Access interface goes here\r
+  //\r
+  UINT32                          SmmRegionState;\r
+  UINT32                          NumberRegions;\r
+  EFI_SMRAM_DESCRIPTOR            *SmramDesc;\r
+} SMM_ACCESS_PRIVATE_DATA;\r
+\r
+#endif\r
diff --git a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf
new file mode 100644 (file)
index 0000000..aac5ee8
--- /dev/null
@@ -0,0 +1,51 @@
+## @file\r
+# SMM Access 2 Protocol Dxe Driver\r
+#\r
+# This module produces the SMM Access 2 Protocol.\r
+#\r
+#  Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  SPDX-License-Identifier: BSD-2-Clause-Patent\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SmmAccessDxe\r
+  FILE_GUID                      = 47579CF5-1E4F-4b41-99BB-A5C334846D3B\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = SmmAccessEntryPoint\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64\r
+#\r
+\r
+[Sources]\r
+  SmmAccessDxe.c\r
+  SmmAccessDxe.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  UefiPayloadPkg/UefiPayloadPkg.dec\r
+\r
+[LibraryClasses]\r
+  UefiDriverEntryPoint\r
+  UefiBootServicesTableLib\r
+  DebugLib\r
+  BaseLib\r
+  BaseMemoryLib\r
+  MemoryAllocationLib\r
+  HobLib\r
+\r
+[Guids]\r
+  gEfiSmmSmramMemoryGuid\r
+\r
+[Protocols]\r
+  gEfiSmmAccess2ProtocolGuid                    ## PRODUCES\r
+\r
+[Depex]\r
+  TRUE\r