public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v2] IntelSiliconPkg/Feature Implement SmmAccess
@ 2019-08-26  6:13 Marc W Chen
  2019-08-26 16:52 ` Ni, Ray
  2019-08-27  6:21 ` [edk2-devel] " Zeng, Star
  0 siblings, 2 replies; 4+ messages in thread
From: Marc W Chen @ 2019-08-26  6:13 UTC (permalink / raw)
  To: devel; +Cc: Marc Chen, Ray Ni, Rangasai V Chaganty

REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2121

Implement SmmAccess for PEI and DXE phase in IntelSiliconPkg

Signed-off-by: Marc Chen <marc.w.chen@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
---
 .../Library/PeiSmmAccessLib/PeiSmmAccessLib.c      | 343 +++++++++++++++++++++
 .../Library/PeiSmmAccessLib/PeiSmmAccessLib.inf    |  41 +++
 .../Feature/SmmAccess/SmmAccessDxe/SmmAccess.inf   |  46 +++
 .../SmmAccess/SmmAccessDxe/SmmAccessDriver.c       | 267 ++++++++++++++++
 .../SmmAccess/SmmAccessDxe/SmmAccessDriver.h       | 160 ++++++++++
 .../IntelSiliconPkg/Include/Library/SmmAccessLib.h |  32 ++
 6 files changed, 889 insertions(+)
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.c
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.inf
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess.inf
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccessDriver.c
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccessDriver.h
 create mode 100644 Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h

diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.c b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.c
new file mode 100644
index 0000000000..cc5bf745d2
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.c
@@ -0,0 +1,343 @@
+/** @file
+  This is to publish the SMM Access Ppi instance.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PciSegmentLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/HobLib.h>
+#include <Uefi/UefiBaseType.h>
+#include <Guid/SmramMemoryReserve.h>
+
+#include <Ppi/MmAccess.h>
+#include <IndustryStandard/Pci22.h>
+
+#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's', 'a')
+
+///
+/// Private data
+///
+typedef struct {
+  UINTN                 Signature;
+  EFI_HANDLE            Handle;
+  EFI_PEI_MM_ACCESS_PPI SmmAccess;
+  //
+  // Local Data for SMM Access interface goes here
+  //
+  UINTN                 NumberRegions;
+  EFI_SMRAM_DESCRIPTOR  *SmramDesc;
+} SMM_ACCESS_PRIVATE_DATA;
+
+#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
+        CR (a, \
+          SMM_ACCESS_PRIVATE_DATA, \
+          SmmAccess, \
+          SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
+      )
+
+/**
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all PEIM
+  and SMM agents.
+
+  @param[in] This             -  Pointer to the SMM Access Interface.
+  @param[in] DescriptorIndex  -  Region of SMRAM to Open.
+  @param[in] PeiServices      -  General purpose services available to every PEIM.
+
+  @retval EFI_SUCCESS            -  The region was successfully opened.
+  @retval EFI_DEVICE_ERROR       -  The region could not be opened because locked by
+                                    chipset.
+  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_PEI_SERVICES           **PeiServices,
+  IN EFI_PEI_MM_ACCESS_PPI      *This,
+  IN UINTN                      DescriptorIndex
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+  if (DescriptorIndex >= SmmAccess->NumberRegions) {
+    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
+
+    return EFI_INVALID_PARAMETER;
+  } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+    //
+    // Cannot open a "locked" region
+    //
+    DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+
+    return EFI_DEVICE_ERROR;
+  }
+
+  SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) EFI_SMRAM_OPEN;
+  SmmAccess->SmmAccess.OpenState = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "close" a region of SMRAM.  This is valid for
+  compatible SMRAM region.
+
+  @param[in] PeiServices      -  General purpose services available to every PEIM.
+  @param[in] This             -  Pointer to the SMM Access Interface.
+  @param[in] DescriptorIndex  -  Region of SMRAM to Close.
+
+  @retval EFI_SUCCESS            -  The region was successfully closed.
+  @retval EFI_DEVICE_ERROR       -  The region could not be closed because locked by
+                                    chipset.
+  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_PEI_SERVICES        **PeiServices,
+  IN EFI_PEI_MM_ACCESS_PPI   *This,
+  IN UINTN                   DescriptorIndex
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  BOOLEAN                 OpenState;
+  UINT8                   Index;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+  if (DescriptorIndex >= SmmAccess->NumberRegions) {
+    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
+
+    return EFI_INVALID_PARAMETER;
+  } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+    //
+    // Cannot close a "locked" region
+    //
+    DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_CLOSED) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~EFI_SMRAM_OPEN;
+  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+
+  //
+  // Find out if any regions are still open
+  //
+  OpenState = FALSE;
+  for (Index = 0; Index < SmmAccess->NumberRegions; Index++) {
+    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) == EFI_SMRAM_OPEN) {
+      OpenState = TRUE;
+    }
+  }
+
+  SmmAccess->SmmAccess.OpenState = OpenState;
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to PEIM.
+
+  @param[in] PeiServices      - General purpose services available to every PEIM.
+  @param[in] This             -  Pointer to the SMM Access Interface.
+  @param[in] DescriptorIndex  -  Region of SMRAM to Lock.
+
+  @retval EFI_SUCCESS            -  The region was successfully locked.
+  @retval EFI_DEVICE_ERROR       -  The region could not be locked because at least
+                                    one range is still open.
+  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_PEI_SERVICES          **PeiServices,
+  IN EFI_PEI_MM_ACCESS_PPI     *This,
+  IN UINTN                     DescriptorIndex
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+  if (DescriptorIndex >= SmmAccess->NumberRegions) {
+    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
+
+    return EFI_INVALID_PARAMETER;
+  } else if (SmmAccess->SmmAccess.OpenState) {
+    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are still open\n"));
+
+    return EFI_DEVICE_ERROR;
+  }
+
+  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) EFI_SMRAM_LOCKED;
+  SmmAccess->SmmAccess.LockState = TRUE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+  @param[in] PeiServices   - General purpose services available to every PEIM.
+  @param[in] This          -  Pointer to the SMRAM Access Interface.
+  @param[in] SmramMapSize  -  Pointer to the variable containing size of the
+                              buffer to contain the description information.
+  @param[in] SmramMap      -  Buffer containing the data describing the Smram
+                              region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  -  The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           -  The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN EFI_PEI_SERVICES                **PeiServices,
+  IN EFI_PEI_MM_ACCESS_PPI           *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+{
+  EFI_STATUS              Status;
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINTN                   NecessaryBufferSize;
+
+  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR);
+  if (*SmramMapSize < NecessaryBufferSize) {
+    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
+
+    Status = EFI_BUFFER_TOO_SMALL;
+  } else {
+    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
+    Status = EFI_SUCCESS;
+  }
+
+  *SmramMapSize = NecessaryBufferSize;
+  return Status;
+}
+
+/**
+  This function is to install an SMM Access PPI
+  - <b>Introduction</b> \n
+    A module to install a PPI for controlling SMM mode memory access basically for S3 resume usage.
+
+  - @pre
+    - _PEI_MASTER_BOOT_MODE_PEIM_PPI: A PPI published by foundation to get bootmode executed earlier.
+    - _PEI_PERMANENT_MEMORY_INSTALLED_PPI: a PPI that will be installed after memory controller initialization completed to indicate that physical memory is usable after this point.
+
+  - @result
+    Publish _EFI_PEI_MM_ACCESS_PPI.
+
+    @retval EFI_SUCCESS           - Ppi successfully started and installed.
+    @retval EFI_NOT_FOUND         - Ppi can't be found.
+    @retval EFI_OUT_OF_RESOURCES  - Ppi does not have enough resources to initialize the driver.
+**/
+EFI_STATUS
+EFIAPI
+PeiInstallSmmAccessPpi (
+  VOID
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           Index;
+  EFI_PEI_PPI_DESCRIPTOR          *PpiList;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
+  SMM_ACCESS_PRIVATE_DATA         *SmmAccessPrivate;
+  VOID                            *HobList;
+  EFI_BOOT_MODE                   BootMode;
+
+  Status = PeiServicesGetBootMode (&BootMode);
+  if (EFI_ERROR (Status)) {
+    //
+    // If not in S3 boot path. do nothing
+    //
+    return EFI_SUCCESS;
+  }
+
+  if (BootMode != BOOT_ON_S3_RESUME) {
+    return EFI_SUCCESS;
+  }
+  //
+  // Initialize private data
+  //
+  SmmAccessPrivate  = AllocateZeroPool (sizeof (*SmmAccessPrivate));
+  ASSERT (SmmAccessPrivate != NULL);
+  if (SmmAccessPrivate == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+  PpiList           = AllocateZeroPool (sizeof (*PpiList));
+  ASSERT (PpiList != NULL);
+  if (PpiList == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  SmmAccessPrivate->Signature = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
+  SmmAccessPrivate->Handle    = NULL;
+
+  //
+  // Get Hob list
+  //
+  HobList = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);
+  if (HobList == NULL) {
+    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  DescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) ((UINT8 *) HobList + sizeof (EFI_HOB_GUID_TYPE));
+
+  //
+  // Alloc space for SmmAccessPrivate->SmramDesc
+  //
+  SmmAccessPrivate->SmramDesc = AllocateZeroPool ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof (EFI_SMRAM_DESCRIPTOR));
+  if (SmmAccessPrivate->SmramDesc == NULL) {
+    DEBUG ((DEBUG_WARN, "Alloc SmmAccessPrivate->SmramDesc fail.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DEBUG ((DEBUG_INFO, "Alloc SmmAccessPrivate->SmramDesc success.\n"));
+
+  //
+  // use the hob to publish SMRAM capabilities
+  //
+  for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+    SmmAccessPrivate->SmramDesc[Index].PhysicalStart  = DescriptorBlock->Descriptor[Index].PhysicalStart;
+    SmmAccessPrivate->SmramDesc[Index].CpuStart       = DescriptorBlock->Descriptor[Index].CpuStart;
+    SmmAccessPrivate->SmramDesc[Index].PhysicalSize   = DescriptorBlock->Descriptor[Index].PhysicalSize;
+    SmmAccessPrivate->SmramDesc[Index].RegionState    = DescriptorBlock->Descriptor[Index].RegionState;
+  }
+
+  SmmAccessPrivate->NumberRegions             = Index;
+  SmmAccessPrivate->SmmAccess.Open            = Open;
+  SmmAccessPrivate->SmmAccess.Close           = Close;
+  SmmAccessPrivate->SmmAccess.Lock            = Lock;
+  SmmAccessPrivate->SmmAccess.GetCapabilities = GetCapabilities;
+  SmmAccessPrivate->SmmAccess.LockState       = FALSE;
+  SmmAccessPrivate->SmmAccess.OpenState       = FALSE;
+
+  //
+  // Install PPI
+  //
+  PpiList->Flags  = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+  PpiList->Guid   = &gEfiPeiMmAccessPpiGuid;
+  PpiList->Ppi    = &SmmAccessPrivate->SmmAccess;
+
+  Status          = PeiServicesInstallPpi (PpiList);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.inf b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.inf
new file mode 100644
index 0000000000..f04d071318
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.inf
@@ -0,0 +1,41 @@
+## @file
+# Library description file for the SmmAccess module
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = PeiSmmAccessLib
+FILE_GUID = 54020881-B594-442A-8377-A57AFF98C7CF
+VERSION_STRING = 1.0
+MODULE_TYPE = PEIM
+LIBRARY_CLASS = SmmAccessLib
+
+
+[LibraryClasses]
+BaseLib
+BaseMemoryLib
+HobLib
+PciSegmentLib
+PeiServicesLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+
+
+[Sources]
+PeiSmmAccessLib.c
+
+
+[Ppis]
+gEfiPeiMmAccessPpiGuid ## PRODUCES
+
+
+[Guids]
+gEfiSmmSmramMemoryGuid
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess.inf b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess.inf
new file mode 100644
index 0000000000..34dc65d7a3
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess.inf
@@ -0,0 +1,46 @@
+## @file
+# Component description file for the SmmAccess module
+#
+# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = SmmAccess
+FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+ENTRY_POINT = SmmAccessDriverEntryPoint
+
+
+[LibraryClasses]
+UefiDriverEntryPoint
+BaseLib
+BaseMemoryLib
+DebugLib
+HobLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+
+
+[Sources]
+SmmAccessDriver.h
+SmmAccessDriver.c
+
+
+[Protocols]
+gEfiSmmAccess2ProtocolGuid       ## PRODUCES
+
+
+[Guids]
+gEfiSmmSmramMemoryGuid
+
+
+[Depex]
+TRUE
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccessDriver.c b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccessDriver.c
new file mode 100644
index 0000000000..3d3c4ab206
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccessDriver.c
@@ -0,0 +1,267 @@
+/** @file
+  This is the driver that publishes the SMM Access Protocol
+  instance for System Agent.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include "SmmAccessDriver.h"
+
+static SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
+
+/**
+  This is the standard EFI driver point that
+  installs an SMM Access Protocol
+
+  @param[in] ImageHandle     - Handle for the image of this driver
+  @param[in] SystemTable     - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS           - Protocol was installed successfully
+  @exception EFI_UNSUPPORTED    - Protocol was not installed
+  @retval EFI_NOT_FOUND         - Protocol can't be found.
+  @retval EFI_OUT_OF_RESOURCES  - Protocol does not have enough resources to initialize the driver.
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS                      Status;
+  UINTN                           Index;
+  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
+  EFI_PEI_HOB_POINTERS            *Hob;
+
+  //
+  // Initialize Global variables
+  //
+  ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
+
+  mSmmAccess.Signature        = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
+  mSmmAccess.Handle           = NULL;
+
+  //
+  // Get Hob list
+  //
+  Hob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);
+  if (Hob == NULL) {
+    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
+    return EFI_NOT_FOUND;
+  }
+
+  DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof (EFI_HOB_GUID_TYPE));
+
+  //
+  // Alloc space for mSmmAccess.SmramDesc
+  //
+  mSmmAccess.SmramDesc = AllocateZeroPool ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof (EFI_SMRAM_DESCRIPTOR));
+  if (mSmmAccess.SmramDesc == NULL) {
+    DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
+
+  //
+  // Use the HOB to publish SMRAM capabilities
+  //
+  for (Index = 0; Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
+    mSmmAccess.SmramDesc[Index].PhysicalStart = DescriptorBlock->Descriptor[Index].PhysicalStart;
+    mSmmAccess.SmramDesc[Index].CpuStart      = DescriptorBlock->Descriptor[Index].CpuStart;
+    mSmmAccess.SmramDesc[Index].PhysicalSize  = DescriptorBlock->Descriptor[Index].PhysicalSize;
+    mSmmAccess.SmramDesc[Index].RegionState   = DescriptorBlock->Descriptor[Index].RegionState;
+  }
+
+  mSmmAccess.NumberRegions              = Index;
+  mSmmAccess.SmmAccess.Open             = Open;
+  mSmmAccess.SmmAccess.Close            = Close;
+  mSmmAccess.SmmAccess.Lock             = Lock;
+  mSmmAccess.SmmAccess.GetCapabilities  = GetCapabilities;
+  mSmmAccess.SmmAccess.LockState        = FALSE;
+  mSmmAccess.SmmAccess.OpenState        = FALSE;
+
+  //
+  // Install our protocol interfaces on the device's handle
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &mSmmAccess.Handle,
+                  &gEfiSmmAccess2ProtocolGuid,
+                  &mSmmAccess.SmmAccess,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces returned %r\n", Status));
+    return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully opened.
+  @retval EFI_DEVICE_ERROR      - The region could not be opened because locked by
+                          chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+  }
+
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) EFI_SMRAM_OPEN;
+  }
+  SmmAccess->SmmAccess.OpenState = TRUE;
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "close" a region of SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "close" means that the memory is only visible from SMM agents,
+  not from BS or RT code.
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully closed.
+  @retval EFI_DEVICE_ERROR      - The region could not be closed because locked by chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  BOOLEAN                 OpenState;
+  UINT8                   Index;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState & EFI_SMRAM_LOCKED) {
+      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+      continue;
+    }
+
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64) ~EFI_SMRAM_OPEN;
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64) (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+  }
+
+  //
+  // Find out if any regions are still open
+  //
+  OpenState = FALSE;
+  for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
+    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) == EFI_SMRAM_OPEN) {
+      OpenState = TRUE;
+    }
+  }
+
+  SmmAccess->SmmAccess.OpenState = OpenState;
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state..
+
+  @param[in] This               - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully locked.
+  @retval EFI_DEVICE_ERROR      - The region could not be locked because at least
+                                  one range is still open.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  )
+{
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINTN                   DescriptorIndex;
+
+  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  if (SmmAccess->SmmAccess.OpenState) {
+    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are still open\n"));
+    return EFI_DEVICE_ERROR;
+  }
+  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions; DescriptorIndex++) {
+    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= EFI_SMRAM_LOCKED;
+  }
+  SmmAccess->SmmAccess.LockState = TRUE;
+
+  return EFI_SUCCESS;
+}
+
+/**
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+  @param[in] This                  - Pointer to the SMRAM Access Interface.
+  @param[in] SmramMapSize          - Pointer to the variable containing size of the
+                                     buffer to contain the description information.
+  @param[in] SmramMap              - Buffer containing the data describing the Smram
+                                     region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                       *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
+  )
+{
+  EFI_STATUS              Status;
+  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
+  UINTN                   NecessaryBufferSize;
+
+  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
+
+  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof (EFI_SMRAM_DESCRIPTOR);
+
+  if (*SmramMapSize < NecessaryBufferSize) {
+    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
+    Status = EFI_BUFFER_TOO_SMALL;
+  } else {
+    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
+    Status = EFI_SUCCESS;
+  }
+
+  *SmramMapSize = NecessaryBufferSize;
+
+  return Status;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccessDriver.h b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccessDriver.h
new file mode 100644
index 0000000000..c0ff3a250b
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccessDriver.h
@@ -0,0 +1,160 @@
+/** @file
+  Header file for SMM Access Driver.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _SMM_ACCESS_DRIVER_H_
+#define _SMM_ACCESS_DRIVER_H_
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+#include <Library/PciLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Uefi/UefiBaseType.h>
+
+#include <Guid/SmramMemoryReserve.h>
+#include <Protocol/SmmAccess2.h>
+#include <IndustryStandard/Pci22.h>
+
+#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's', 'a')
+
+///
+/// Private data
+///
+typedef struct {
+  UINTN                           Signature;
+  EFI_HANDLE                      Handle;
+  EFI_SMM_ACCESS2_PROTOCOL        SmmAccess;
+
+  ///
+  /// Local Data for SMM Access interface goes here
+  ///
+  UINTN                           NumberRegions;
+  EFI_SMRAM_DESCRIPTOR            *SmramDesc;
+} SMM_ACCESS_PRIVATE_DATA;
+
+#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
+  CR (a, \
+      SMM_ACCESS_PRIVATE_DATA, \
+      SmmAccess, \
+      SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
+      )
+
+//
+// Prototypes
+// Driver model protocol interface
+//
+/**
+  <b>SMM Access Driver Entry Point</b>
+  This driver installs an SMM Access Protocol
+  - <b>Introduction</b> \n
+    This module publishes the SMM access protocol.  The protocol is used by the SMM Base driver to access the SMRAM region when the processor is not in SMM.
+    The SMM Base driver uses the services provided by the SMM access protocol to open SMRAM during post and copy the SMM handler.
+    SMM access protocol is also used to close the SMRAM region once the copying is done.
+    Finally, the SMM access protocol provides services to "Lock" the SMRAM region.
+    Please refer the SMM Protocols section in the attached SMM CIS Specification version 0.9 for further details.
+    This driver is required if SMM is supported. Proper configuration of SMM registers is recommended even if SMM is not supported.
+
+  - @result
+    Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the System Management Mode Core Interface Specification, available at the URL: http://www.intel.com/technology/framework/spec.htm
+
+  - <b>Porting Recommendations</b> \n
+    No modification of this module is recommended.  Any modification should be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL protocol definition.
+
+  @param[in] ImageHandle     - Handle for the image of this driver
+  @param[in] SystemTable     - Pointer to the EFI System Table
+
+  @retval EFI_SUCCESS     - Protocol was installed successfully
+  @exception EFI_UNSUPPORTED - Protocol was not installed
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessDriverEntryPoint (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  );
+
+/**
+  This routine accepts a request to "open" a region of SMRAM.  The
+  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
+  The use of "open" means that the memory is visible from all boot-service
+  and SMM agents.
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully opened.
+  @retval EFI_DEVICE_ERROR      - The region could not be opened because locked by
+                          chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Open (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  );
+
+/**
+  This routine accepts a request to "close" a region of SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "close" means that the memory is only visible from SMM agents,
+  not from BS or RT code.
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully closed.
+  @retval EFI_DEVICE_ERROR      - The region could not be closed because locked by
+                            chipset.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+  IN EFI_SMM_ACCESS2_PROTOCOL  *This
+  );
+
+/**
+  This routine accepts a request to "lock" SMRAM.  The
+  region could be legacy AB or TSEG near top of physical memory.
+  The use of "lock" means that the memory can no longer be opened
+  to BS state..
+
+  @param[in] This                  - Pointer to the SMM Access Interface.
+
+  @retval EFI_SUCCESS           - The region was successfully locked.
+  @retval EFI_DEVICE_ERROR      - The region could not be locked because at least
+                          one range is still open.
+  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
+**/
+EFI_STATUS
+EFIAPI
+Lock (
+  IN EFI_SMM_ACCESS2_PROTOCOL *This
+  );
+
+/**
+  This routine services a user request to discover the SMRAM
+  capabilities of this platform.  This will report the possible
+  ranges that are possible for SMRAM access, based upon the
+  memory controller capabilities.
+
+  @param[in] This                  - Pointer to the SMRAM Access Interface.
+  @param[in] SmramMapSize          - Pointer to the variable containing size of the
+                            buffer to contain the description information.
+  @param[in] SmramMap              - Buffer containing the data describing the Smram
+                            region descriptors.
+
+  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient buffer.
+  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
+**/
+EFI_STATUS
+EFIAPI
+GetCapabilities (
+  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
+  IN OUT UINTN                   *SmramMapSize,
+  IN OUT EFI_SMRAM_DESCRIPTOR    *SmramMap
+  );
+#endif
diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h b/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
new file mode 100644
index 0000000000..b7cb88f6ca
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
@@ -0,0 +1,32 @@
+/** @file
+  Header file for SMM Access Driver.
+
+  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#ifndef _SMM_ACCESS_H_
+#define _SMM_ACCESS_H_
+
+/**
+  This function is to install an SMM Access PPI
+  - <b>Introduction</b> \n
+    A module to install a PPI for controlling SMM mode memory access basically for S3 resume usage.
+
+  - @pre
+    - _PEI_MASTER_BOOT_MODE_PEIM_PPI: A PPI published by foundation to get bootmode executed earlier.
+    - _PEI_PERMANENT_MEMORY_INSTALLED_PPI: a PPI that will be installed after memory controller initialization completed to indicate that physical memory is usable after this point.
+
+  - @result
+    Publish _PEI_SMM_ACCESS_PPI.
+
+    @retval EFI_SUCCESS           - Ppi successfully started and installed.
+    @retval EFI_NOT_FOUND         - Ppi can't be found.
+    @retval EFI_OUT_OF_RESOURCES  - Ppi does not have enough resources to initialize the driver.
+**/
+EFI_STATUS
+EFIAPI
+PeiInstallSmmAccessPpi (
+  VOID
+  );
+#endif
-- 
2.16.2.windows.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2] IntelSiliconPkg/Feature Implement SmmAccess
  2019-08-26  6:13 [PATCH v2] IntelSiliconPkg/Feature Implement SmmAccess Marc W Chen
@ 2019-08-26 16:52 ` Ni, Ray
  2019-08-27  6:21 ` [edk2-devel] " Zeng, Star
  1 sibling, 0 replies; 4+ messages in thread
From: Ni, Ray @ 2019-08-26 16:52 UTC (permalink / raw)
  To: Chen, Marc W, devel@edk2.groups.io; +Cc: Chaganty, Rangasai V

Marc,
Thanks for addressing the MdeModulePkg dependency in this patch.

Just one minor comment:
In SmmAccessLib.h, change
#ifndef _SMM_ACCESS_H_
To:
#ifndef _SMM_ACCESS_LIB_H_

This change avoids a potential macro conflict.

With that change, Reviewed-by: Ray Ni <ray.ni@intel.com>


> -----Original Message-----
> From: Chen, Marc W
> Sent: Monday, August 26, 2019 2:14 PM
> To: devel@edk2.groups.io
> Cc: Chen, Marc W <marc.w.chen@intel.com>; Ni, Ray <ray.ni@intel.com>;
> Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>
> Subject: [PATCH v2] IntelSiliconPkg/Feature Implement SmmAccess
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2121
> 
> Implement SmmAccess for PEI and DXE phase in IntelSiliconPkg
> 
> Signed-off-by: Marc Chen <marc.w.chen@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> ---
>  .../Library/PeiSmmAccessLib/PeiSmmAccessLib.c      | 343
> +++++++++++++++++++++
>  .../Library/PeiSmmAccessLib/PeiSmmAccessLib.inf    |  41 +++
>  .../Feature/SmmAccess/SmmAccessDxe/SmmAccess.inf   |  46 +++
>  .../SmmAccess/SmmAccessDxe/SmmAccessDriver.c       | 267
> ++++++++++++++++
>  .../SmmAccess/SmmAccessDxe/SmmAccessDriver.h       | 160 ++++++++++
>  .../IntelSiliconPkg/Include/Library/SmmAccessLib.h |  32 ++
>  6 files changed, 889 insertions(+)
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiS
> mmAccessLib.c
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiS
> mmAccessLib.inf
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess.in
> f
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccessDri
> ver.c
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccessDri
> ver.h
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/Pe
> iSmmAccessLib.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/Pe
> iSmmAccessLib.c
> new file mode 100644
> index 0000000000..cc5bf745d2
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAcce
> +++ ssLib/PeiSmmAccessLib.c
> @@ -0,0 +1,343 @@
> +/** @file
> +  This is to publish the SMM Access Ppi instance.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h> #include
> +<Library/PciSegmentLib.h> #include <Library/PeiServicesLib.h> #include
> +<Library/HobLib.h> #include <Uefi/UefiBaseType.h> #include
> +<Guid/SmramMemoryReserve.h>
> +
> +#include <Ppi/MmAccess.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's',
> +'a')
> +
> +///
> +/// Private data
> +///
> +typedef struct {
> +  UINTN                 Signature;
> +  EFI_HANDLE            Handle;
> +  EFI_PEI_MM_ACCESS_PPI SmmAccess;
> +  //
> +  // Local Data for SMM Access interface goes here
> +  //
> +  UINTN                 NumberRegions;
> +  EFI_SMRAM_DESCRIPTOR  *SmramDesc;
> +} SMM_ACCESS_PRIVATE_DATA;
> +
> +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
> +        CR (a, \
> +          SMM_ACCESS_PRIVATE_DATA, \
> +          SmmAccess, \
> +          SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
> +      )
> +
> +/**
> +  This routine accepts a request to "open" a region of SMRAM.  The
> +  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +  The use of "open" means that the memory is visible from all PEIM
> +  and SMM agents.
> +
> +  @param[in] This             -  Pointer to the SMM Access Interface.
> +  @param[in] DescriptorIndex  -  Region of SMRAM to Open.
> +  @param[in] PeiServices      -  General purpose services available to every PEIM.
> +
> +  @retval EFI_SUCCESS            -  The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR       -  The region could not be opened because
> locked by
> +                                    chipset.
> +  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_MM_ACCESS_PPI      *This,
> +  IN UINTN                      DescriptorIndex
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  if
> + (DescriptorIndex >= SmmAccess->NumberRegions) {
> +    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
> +
> +    return EFI_INVALID_PARAMETER;
> +  } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +    //
> +    // Cannot open a "locked" region
> +    //
> +    DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> +
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> +~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> +  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> +EFI_SMRAM_OPEN;
> +  SmmAccess->SmmAccess.OpenState = TRUE;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "close" a region of SMRAM.  This is
> +valid for
> +  compatible SMRAM region.
> +
> +  @param[in] PeiServices      -  General purpose services available to every PEIM.
> +  @param[in] This             -  Pointer to the SMM Access Interface.
> +  @param[in] DescriptorIndex  -  Region of SMRAM to Close.
> +
> +  @retval EFI_SUCCESS            -  The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR       -  The region could not be closed because
> locked by
> +                                    chipset.
> +  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> +  IN EFI_PEI_SERVICES        **PeiServices,
> +  IN EFI_PEI_MM_ACCESS_PPI   *This,
> +  IN UINTN                   DescriptorIndex
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  BOOLEAN                 OpenState;
> +  UINT8                   Index;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  if
> + (DescriptorIndex >= SmmAccess->NumberRegions) {
> +    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
> +
> +    return EFI_INVALID_PARAMETER;
> +  } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +    //
> +    // Cannot close a "locked" region
> +    //
> +    DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> +
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_CLOSED) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> + ~EFI_SMRAM_OPEN;  SmmAccess->SmramDesc[DescriptorIndex].RegionState
> |=
> + (UINT64) (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> +
> +  //
> +  // Find out if any regions are still open  //  OpenState = FALSE;
> + for (Index = 0; Index < SmmAccess->NumberRegions; Index++) {
> +    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) ==
> EFI_SMRAM_OPEN) {
> +      OpenState = TRUE;
> +    }
> +  }
> +
> +  SmmAccess->SmmAccess.OpenState = OpenState;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "lock" SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "lock" means that the memory can no longer be opened
> +  to PEIM.
> +
> +  @param[in] PeiServices      - General purpose services available to every PEIM.
> +  @param[in] This             -  Pointer to the SMM Access Interface.
> +  @param[in] DescriptorIndex  -  Region of SMRAM to Lock.
> +
> +  @retval EFI_SUCCESS            -  The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR       -  The region could not be locked because at
> least
> +                                    one range is still open.
> +  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> +  IN EFI_PEI_SERVICES          **PeiServices,
> +  IN EFI_PEI_MM_ACCESS_PPI     *This,
> +  IN UINTN                     DescriptorIndex
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  if
> + (DescriptorIndex >= SmmAccess->NumberRegions) {
> +    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
> +
> +    return EFI_INVALID_PARAMETER;
> +  } else if (SmmAccess->SmmAccess.OpenState) {
> +    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are still
> + open\n"));
> +
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> + EFI_SMRAM_LOCKED;  SmmAccess->SmmAccess.LockState = TRUE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine services a user request to discover the SMRAM
> +  capabilities of this platform.  This will report the possible
> +  ranges that are possible for SMRAM access, based upon the
> +  memory controller capabilities.
> +
> +  @param[in] PeiServices   - General purpose services available to every PEIM.
> +  @param[in] This          -  Pointer to the SMRAM Access Interface.
> +  @param[in] SmramMapSize  -  Pointer to the variable containing size of the
> +                              buffer to contain the description information.
> +  @param[in] SmramMap      -  Buffer containing the data describing the Smram
> +                              region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  -  The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           -  The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN EFI_PEI_MM_ACCESS_PPI           *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +{
> +  EFI_STATUS              Status;
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINTN                   NecessaryBufferSize;
> +
> +  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof
> + (EFI_SMRAM_DESCRIPTOR);  if (*SmramMapSize < NecessaryBufferSize) {
> +    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
> +
> +    Status = EFI_BUFFER_TOO_SMALL;
> +  } else {
> +    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  *SmramMapSize = NecessaryBufferSize;
> +  return Status;
> +}
> +
> +/**
> +  This function is to install an SMM Access PPI
> +  - <b>Introduction</b> \n
> +    A module to install a PPI for controlling SMM mode memory access basically
> for S3 resume usage.
> +
> +  - @pre
> +    - _PEI_MASTER_BOOT_MODE_PEIM_PPI: A PPI published by foundation to
> get bootmode executed earlier.
> +    - _PEI_PERMANENT_MEMORY_INSTALLED_PPI: a PPI that will be installed
> after memory controller initialization completed to indicate that physical
> memory is usable after this point.
> +
> +  - @result
> +    Publish _EFI_PEI_MM_ACCESS_PPI.
> +
> +    @retval EFI_SUCCESS           - Ppi successfully started and installed.
> +    @retval EFI_NOT_FOUND         - Ppi can't be found.
> +    @retval EFI_OUT_OF_RESOURCES  - Ppi does not have enough resources to
> initialize the driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiInstallSmmAccessPpi (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           Index;
> +  EFI_PEI_PPI_DESCRIPTOR          *PpiList;
> +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
> +  SMM_ACCESS_PRIVATE_DATA         *SmmAccessPrivate;
> +  VOID                            *HobList;
> +  EFI_BOOT_MODE                   BootMode;
> +
> +  Status = PeiServicesGetBootMode (&BootMode);  if (EFI_ERROR (Status))
> + {
> +    //
> +    // If not in S3 boot path. do nothing
> +    //
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (BootMode != BOOT_ON_S3_RESUME) {
> +    return EFI_SUCCESS;
> +  }
> +  //
> +  // Initialize private data
> +  //
> +  SmmAccessPrivate  = AllocateZeroPool (sizeof (*SmmAccessPrivate));
> + ASSERT (SmmAccessPrivate != NULL);  if (SmmAccessPrivate == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  PpiList           = AllocateZeroPool (sizeof (*PpiList));
> +  ASSERT (PpiList != NULL);
> +  if (PpiList == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  SmmAccessPrivate->Signature = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
> +  SmmAccessPrivate->Handle    = NULL;
> +
> +  //
> +  // Get Hob list
> +  //
> +  HobList = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);  if (HobList ==
> + NULL) {
> +    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) ((UINT8 *)
> + HobList + sizeof (EFI_HOB_GUID_TYPE));
> +
> +  //
> +  // Alloc space for SmmAccessPrivate->SmramDesc  //
> + SmmAccessPrivate->SmramDesc = AllocateZeroPool
> + ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof
> (EFI_SMRAM_DESCRIPTOR));  if (SmmAccessPrivate->SmramDesc == NULL) {
> +    DEBUG ((DEBUG_WARN, "Alloc SmmAccessPrivate->SmramDesc fail.\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "Alloc SmmAccessPrivate->SmramDesc success.\n"));
> +
> +  //
> +  // use the hob to publish SMRAM capabilities  //  for (Index = 0;
> + Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
> +    SmmAccessPrivate->SmramDesc[Index].PhysicalStart  = DescriptorBlock-
> >Descriptor[Index].PhysicalStart;
> +    SmmAccessPrivate->SmramDesc[Index].CpuStart       = DescriptorBlock-
> >Descriptor[Index].CpuStart;
> +    SmmAccessPrivate->SmramDesc[Index].PhysicalSize   = DescriptorBlock-
> >Descriptor[Index].PhysicalSize;
> +    SmmAccessPrivate->SmramDesc[Index].RegionState    = DescriptorBlock-
> >Descriptor[Index].RegionState;
> +  }
> +
> +  SmmAccessPrivate->NumberRegions             = Index;
> +  SmmAccessPrivate->SmmAccess.Open            = Open;
> +  SmmAccessPrivate->SmmAccess.Close           = Close;
> +  SmmAccessPrivate->SmmAccess.Lock            = Lock;
> +  SmmAccessPrivate->SmmAccess.GetCapabilities = GetCapabilities;
> +  SmmAccessPrivate->SmmAccess.LockState       = FALSE;
> +  SmmAccessPrivate->SmmAccess.OpenState       = FALSE;
> +
> +  //
> +  // Install PPI
> +  //
> +  PpiList->Flags  = (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
> +  PpiList->Guid   = &gEfiPeiMmAccessPpiGuid;
> +  PpiList->Ppi    = &SmmAccessPrivate->SmmAccess;
> +
> +  Status          = PeiServicesInstallPpi (PpiList);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/Pe
> iSmmAccessLib.inf
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/Pe
> iSmmAccessLib.inf
> new file mode 100644
> index 0000000000..f04d071318
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAcce
> +++ ssLib/PeiSmmAccessLib.inf
> @@ -0,0 +1,41 @@
> +## @file
> +# Library description file for the SmmAccess module # # Copyright (c)
> +2019, Intel Corporation. All rights reserved.<BR> #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiSmmAccessLib
> +FILE_GUID = 54020881-B594-442A-8377-A57AFF98C7CF
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = SmmAccessLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +BaseMemoryLib
> +HobLib
> +PciSegmentLib
> +PeiServicesLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +
> +[Sources]
> +PeiSmmAccessLib.c
> +
> +
> +[Ppis]
> +gEfiPeiMmAccessPpiGuid ## PRODUCES
> +
> +
> +[Guids]
> +gEfiSmmSmramMemoryGuid
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess.
> inf
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess.
> inf
> new file mode 100644
> index 0000000000..34dc65d7a3
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> +++ cess.inf
> @@ -0,0 +1,46 @@
> +## @file
> +# Component description file for the SmmAccess module # # Copyright (c)
> +2019, Intel Corporation. All rights reserved.<BR> #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = SmmAccess
> +FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_DRIVER
> +ENTRY_POINT = SmmAccessDriverEntryPoint
> +
> +
> +[LibraryClasses]
> +UefiDriverEntryPoint
> +BaseLib
> +BaseMemoryLib
> +DebugLib
> +HobLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +
> +[Sources]
> +SmmAccessDriver.h
> +SmmAccessDriver.c
> +
> +
> +[Protocols]
> +gEfiSmmAccess2ProtocolGuid       ## PRODUCES
> +
> +
> +[Guids]
> +gEfiSmmSmramMemoryGuid
> +
> +
> +[Depex]
> +TRUE
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess
> Driver.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess
> Driver.c
> new file mode 100644
> index 0000000000..3d3c4ab206
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> +++ cessDriver.c
> @@ -0,0 +1,267 @@
> +/** @file
> +  This is the driver that publishes the SMM Access Protocol
> +  instance for System Agent.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include "SmmAccessDriver.h"
> +
> +static SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
> +
> +/**
> +  This is the standard EFI driver point that
> +  installs an SMM Access Protocol
> +
> +  @param[in] ImageHandle     - Handle for the image of this driver
> +  @param[in] SystemTable     - Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS           - Protocol was installed successfully
> +  @exception EFI_UNSUPPORTED    - Protocol was not installed
> +  @retval EFI_NOT_FOUND         - Protocol can't be found.
> +  @retval EFI_OUT_OF_RESOURCES  - Protocol does not have enough
> resources to initialize the driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmAccessDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           Index;
> +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
> +  EFI_PEI_HOB_POINTERS            *Hob;
> +
> +  //
> +  // Initialize Global variables
> +  //
> +  ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
> +
> +  mSmmAccess.Signature        = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
> +  mSmmAccess.Handle           = NULL;
> +
> +  //
> +  // Get Hob list
> +  //
> +  Hob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);  if (Hob == NULL) {
> +    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof
> + (EFI_HOB_GUID_TYPE));
> +
> +  //
> +  // Alloc space for mSmmAccess.SmramDesc  //  mSmmAccess.SmramDesc =
> + AllocateZeroPool ((DescriptorBlock->NumberOfSmmReservedRegions) *
> + sizeof (EFI_SMRAM_DESCRIPTOR));  if (mSmmAccess.SmramDesc == NULL) {
> +    DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
> +
> +  //
> +  // Use the HOB to publish SMRAM capabilities  //  for (Index = 0;
> + Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
> +    mSmmAccess.SmramDesc[Index].PhysicalStart = DescriptorBlock-
> >Descriptor[Index].PhysicalStart;
> +    mSmmAccess.SmramDesc[Index].CpuStart      = DescriptorBlock-
> >Descriptor[Index].CpuStart;
> +    mSmmAccess.SmramDesc[Index].PhysicalSize  = DescriptorBlock-
> >Descriptor[Index].PhysicalSize;
> +    mSmmAccess.SmramDesc[Index].RegionState   = DescriptorBlock-
> >Descriptor[Index].RegionState;
> +  }
> +
> +  mSmmAccess.NumberRegions              = Index;
> +  mSmmAccess.SmmAccess.Open             = Open;
> +  mSmmAccess.SmmAccess.Close            = Close;
> +  mSmmAccess.SmmAccess.Lock             = Lock;
> +  mSmmAccess.SmmAccess.GetCapabilities  = GetCapabilities;
> +  mSmmAccess.SmmAccess.LockState        = FALSE;
> +  mSmmAccess.SmmAccess.OpenState        = FALSE;
> +
> +  //
> +  // Install our protocol interfaces on the device's handle  //  Status
> + = gBS->InstallMultipleProtocolInterfaces (
> +                  &mSmmAccess.Handle,
> +                  &gEfiSmmAccess2ProtocolGuid,
> +                  &mSmmAccess.SmmAccess,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces returned %r\n",
> Status));
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "open" a region of SMRAM.  The
> +  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +  The use of "open" means that the memory is visible from all
> +boot-service
> +  and SMM agents.
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR      - The region could not be opened because
> locked by
> +                          chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  for
> + (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> +      return EFI_DEVICE_ERROR;
> +    }
> +  }
> +
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> +EFI_SMRAM_OPEN;
> +  }
> +  SmmAccess->SmmAccess.OpenState = TRUE;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "close" a region of SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "close" means that the memory is only visible from SMM
> +agents,
> +  not from BS or RT code.
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR      - The region could not be closed because
> locked by chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  BOOLEAN                 OpenState;
> +  UINT8                   Index;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> +      continue;
> +    }
> +
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> ~EFI_SMRAM_OPEN;
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> + (EFI_SMRAM_CLOSED | EFI_ALLOCATED);  }
> +
> +  //
> +  // Find out if any regions are still open  //  OpenState = FALSE;
> + for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
> +    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN) ==
> EFI_SMRAM_OPEN) {
> +      OpenState = TRUE;
> +    }
> +  }
> +
> +  SmmAccess->SmmAccess.OpenState = OpenState;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "lock" SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "lock" means that the memory can no longer be opened
> +  to BS state..
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR      - The region could not be locked because at
> least
> +                                  one range is still open.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  if (SmmAccess->SmmAccess.OpenState) {
> +    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are still
> open\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> + EFI_SMRAM_LOCKED;  }  SmmAccess->SmmAccess.LockState = TRUE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine services a user request to discover the SMRAM
> +  capabilities of this platform.  This will report the possible
> +  ranges that are possible for SMRAM access, based upon the
> +  memory controller capabilities.
> +
> +  @param[in] This                  - Pointer to the SMRAM Access Interface.
> +  @param[in] SmramMapSize          - Pointer to the variable containing size of
> the
> +                                     buffer to contain the description information.
> +  @param[in] SmramMap              - Buffer containing the data describing the
> Smram
> +                                     region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +{
> +  EFI_STATUS              Status;
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINTN                   NecessaryBufferSize;
> +
> +  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof
> + (EFI_SMRAM_DESCRIPTOR);
> +
> +  if (*SmramMapSize < NecessaryBufferSize) {
> +    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
> +    Status = EFI_BUFFER_TOO_SMALL;
> +  } else {
> +    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  *SmramMapSize = NecessaryBufferSize;
> +
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess
> Driver.h
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAccess
> Driver.h
> new file mode 100644
> index 0000000000..c0ff3a250b
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> +++ cessDriver.h
> @@ -0,0 +1,160 @@
> +/** @file
> +  Header file for SMM Access Driver.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _SMM_ACCESS_DRIVER_H_
> +#define _SMM_ACCESS_DRIVER_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/MemoryAllocationLib.h> #include
> +<Library/UefiBootServicesTableLib.h>
> +#include <Uefi/UefiBaseType.h>
> +
> +#include <Guid/SmramMemoryReserve.h>
> +#include <Protocol/SmmAccess2.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5', 's',
> +'a')
> +
> +///
> +/// Private data
> +///
> +typedef struct {
> +  UINTN                           Signature;
> +  EFI_HANDLE                      Handle;
> +  EFI_SMM_ACCESS2_PROTOCOL        SmmAccess;
> +
> +  ///
> +  /// Local Data for SMM Access interface goes here
> +  ///
> +  UINTN                           NumberRegions;
> +  EFI_SMRAM_DESCRIPTOR            *SmramDesc;
> +} SMM_ACCESS_PRIVATE_DATA;
> +
> +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
> +  CR (a, \
> +      SMM_ACCESS_PRIVATE_DATA, \
> +      SmmAccess, \
> +      SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
> +      )
> +
> +//
> +// Prototypes
> +// Driver model protocol interface
> +//
> +/**
> +  <b>SMM Access Driver Entry Point</b>
> +  This driver installs an SMM Access Protocol
> +  - <b>Introduction</b> \n
> +    This module publishes the SMM access protocol.  The protocol is used by the
> SMM Base driver to access the SMRAM region when the processor is not in SMM.
> +    The SMM Base driver uses the services provided by the SMM access protocol
> to open SMRAM during post and copy the SMM handler.
> +    SMM access protocol is also used to close the SMRAM region once the
> copying is done.
> +    Finally, the SMM access protocol provides services to "Lock" the SMRAM
> region.
> +    Please refer the SMM Protocols section in the attached SMM CIS
> Specification version 0.9 for further details.
> +    This driver is required if SMM is supported. Proper configuration of SMM
> registers is recommended even if SMM is not supported.
> +
> +  - @result
> +    Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the System
> + Management Mode Core Interface Specification, available at the URL:
> + http://www.intel.com/technology/framework/spec.htm
> +
> +  - <b>Porting Recommendations</b> \n
> +    No modification of this module is recommended.  Any modification should
> be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL protocol
> definition.
> +
> +  @param[in] ImageHandle     - Handle for the image of this driver
> +  @param[in] SystemTable     - Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS     - Protocol was installed successfully
> +  @exception EFI_UNSUPPORTED - Protocol was not installed **/
> +EFI_STATUS EFIAPI SmmAccessDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  );
> +
> +/**
> +  This routine accepts a request to "open" a region of SMRAM.  The
> +  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +  The use of "open" means that the memory is visible from all
> +boot-service
> +  and SMM agents.
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR      - The region could not be opened because
> locked by
> +                          chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  );
> +
> +/**
> +  This routine accepts a request to "close" a region of SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "close" means that the memory is only visible from SMM
> +agents,
> +  not from BS or RT code.
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR      - The region could not be closed because
> locked by
> +                            chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  );
> +
> +/**
> +  This routine accepts a request to "lock" SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "lock" means that the memory can no longer be opened
> +  to BS state..
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR      - The region could not be locked because at
> least
> +                          one range is still open.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  );
> +
> +/**
> +  This routine services a user request to discover the SMRAM
> +  capabilities of this platform.  This will report the possible
> +  ranges that are possible for SMRAM access, based upon the
> +  memory controller capabilities.
> +
> +  @param[in] This                  - Pointer to the SMRAM Access Interface.
> +  @param[in] SmramMapSize          - Pointer to the variable containing size of
> the
> +                            buffer to contain the description information.
> +  @param[in] SmramMap              - Buffer containing the data describing the
> Smram
> +                            region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> +  IN OUT UINTN                   *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR    *SmramMap
> +  );
> +#endif
> diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> b/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> new file mode 100644
> index 0000000000..b7cb88f6ca
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> @@ -0,0 +1,32 @@
> +/** @file
> +  Header file for SMM Access Driver.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _SMM_ACCESS_H_
> +#define _SMM_ACCESS_H_
> +
> +/**
> +  This function is to install an SMM Access PPI
> +  - <b>Introduction</b> \n
> +    A module to install a PPI for controlling SMM mode memory access basically
> for S3 resume usage.
> +
> +  - @pre
> +    - _PEI_MASTER_BOOT_MODE_PEIM_PPI: A PPI published by foundation to
> get bootmode executed earlier.
> +    - _PEI_PERMANENT_MEMORY_INSTALLED_PPI: a PPI that will be installed
> after memory controller initialization completed to indicate that physical
> memory is usable after this point.
> +
> +  - @result
> +    Publish _PEI_SMM_ACCESS_PPI.
> +
> +    @retval EFI_SUCCESS           - Ppi successfully started and installed.
> +    @retval EFI_NOT_FOUND         - Ppi can't be found.
> +    @retval EFI_OUT_OF_RESOURCES  - Ppi does not have enough resources to
> initialize the driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiInstallSmmAccessPpi (
> +  VOID
> +  );
> +#endif
> --
> 2.16.2.windows.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [edk2-devel] [PATCH v2] IntelSiliconPkg/Feature Implement SmmAccess
  2019-08-26  6:13 [PATCH v2] IntelSiliconPkg/Feature Implement SmmAccess Marc W Chen
  2019-08-26 16:52 ` Ni, Ray
@ 2019-08-27  6:21 ` Zeng, Star
  2019-08-27  7:01   ` Marc W Chen
  1 sibling, 1 reply; 4+ messages in thread
From: Zeng, Star @ 2019-08-27  6:21 UTC (permalink / raw)
  To: devel@edk2.groups.io, Chen, Marc W
  Cc: Ni, Ray, Chaganty, Rangasai V, Zeng, Star

Include new library and driver to IntelSiliconPkg.dsc for building coverage?
In SmmAccessLib.h, it still refers the _PEI_SMM_ACCESS_PPI definition from MdeModulePkg? And need have _EFI prefix for _PEI_MASTER_BOOT_MODE_PEIM_PPI and _PEI_PERMANENT_MEMORY_INSTALLED_PPI?
In PeiSmmAccessLib.inf, the word 'module' in description " Library description file for the SmmAccess module " need to be updated?



Thanks,
Star

> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Marc W Chen
> Sent: Monday, August 26, 2019 2:14 PM
> To: devel@edk2.groups.io
> Cc: Chen, Marc W <marc.w.chen@intel.com>; Ni, Ray <ray.ni@intel.com>;
> Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>
> Subject: [edk2-devel] [PATCH v2] IntelSiliconPkg/Feature Implement
> SmmAccess
> 
> REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2121
> 
> Implement SmmAccess for PEI and DXE phase in IntelSiliconPkg
> 
> Signed-off-by: Marc Chen <marc.w.chen@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> ---
>  .../Library/PeiSmmAccessLib/PeiSmmAccessLib.c      | 343
> +++++++++++++++++++++
>  .../Library/PeiSmmAccessLib/PeiSmmAccessLib.inf    |  41 +++
>  .../Feature/SmmAccess/SmmAccessDxe/SmmAccess.inf   |  46 +++
>  .../SmmAccess/SmmAccessDxe/SmmAccessDriver.c       | 267
> ++++++++++++++++
>  .../SmmAccess/SmmAccessDxe/SmmAccessDriver.h       | 160 ++++++++++
>  .../IntelSiliconPkg/Include/Library/SmmAccessLib.h |  32 ++
>  6 files changed, 889 insertions(+)
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/
> PeiSmmAccessLib.c
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/
> PeiSmmAccessLib.inf
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAcce
> ss.inf
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAcce
> ssDriver.c
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAcce
> ssDriver.h
>  create mode 100644
> Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> 
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLi
> b/PeiSmmAccessLib.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLi
> b/PeiSmmAccessLib.c
> new file mode 100644
> index 0000000000..cc5bf745d2
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAcce
> +++ ssLib/PeiSmmAccessLib.c
> @@ -0,0 +1,343 @@
> +/** @file
> +  This is to publish the SMM Access Ppi instance.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/MemoryAllocationLib.h> #include
> +<Library/PciSegmentLib.h> #include <Library/PeiServicesLib.h> #include
> +<Library/HobLib.h> #include <Uefi/UefiBaseType.h> #include
> +<Guid/SmramMemoryReserve.h>
> +
> +#include <Ppi/MmAccess.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5',
> 's',
> +'a')
> +
> +///
> +/// Private data
> +///
> +typedef struct {
> +  UINTN                 Signature;
> +  EFI_HANDLE            Handle;
> +  EFI_PEI_MM_ACCESS_PPI SmmAccess;
> +  //
> +  // Local Data for SMM Access interface goes here
> +  //
> +  UINTN                 NumberRegions;
> +  EFI_SMRAM_DESCRIPTOR  *SmramDesc;
> +} SMM_ACCESS_PRIVATE_DATA;
> +
> +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
> +        CR (a, \
> +          SMM_ACCESS_PRIVATE_DATA, \
> +          SmmAccess, \
> +          SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
> +      )
> +
> +/**
> +  This routine accepts a request to "open" a region of SMRAM.  The
> +  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +  The use of "open" means that the memory is visible from all PEIM
> +  and SMM agents.
> +
> +  @param[in] This             -  Pointer to the SMM Access Interface.
> +  @param[in] DescriptorIndex  -  Region of SMRAM to Open.
> +  @param[in] PeiServices      -  General purpose services available to every
> PEIM.
> +
> +  @retval EFI_SUCCESS            -  The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR       -  The region could not be opened because
> locked by
> +                                    chipset.
> +  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of
> bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> +  IN EFI_PEI_SERVICES           **PeiServices,
> +  IN EFI_PEI_MM_ACCESS_PPI      *This,
> +  IN UINTN                      DescriptorIndex
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  if
> + (DescriptorIndex >= SmmAccess->NumberRegions) {
> +    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
> +
> +    return EFI_INVALID_PARAMETER;
> +  } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +    //
> +    // Cannot open a "locked" region
> +    //
> +    DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> +
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> +~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> +  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> +EFI_SMRAM_OPEN;
> +  SmmAccess->SmmAccess.OpenState = TRUE;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "close" a region of SMRAM.  This is
> +valid for
> +  compatible SMRAM region.
> +
> +  @param[in] PeiServices      -  General purpose services available to every
> PEIM.
> +  @param[in] This             -  Pointer to the SMM Access Interface.
> +  @param[in] DescriptorIndex  -  Region of SMRAM to Close.
> +
> +  @retval EFI_SUCCESS            -  The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR       -  The region could not be closed because
> locked by
> +                                    chipset.
> +  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of
> bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> +  IN EFI_PEI_SERVICES        **PeiServices,
> +  IN EFI_PEI_MM_ACCESS_PPI   *This,
> +  IN UINTN                   DescriptorIndex
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  BOOLEAN                 OpenState;
> +  UINT8                   Index;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  if
> + (DescriptorIndex >= SmmAccess->NumberRegions) {
> +    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
> +
> +    return EFI_INVALID_PARAMETER;
> +  } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +    //
> +    // Cannot close a "locked" region
> +    //
> +    DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> +
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_CLOSED) {
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> + ~EFI_SMRAM_OPEN;  SmmAccess-
> >SmramDesc[DescriptorIndex].RegionState |=
> + (UINT64) (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> +
> +  //
> +  // Find out if any regions are still open  //  OpenState = FALSE;
> + for (Index = 0; Index < SmmAccess->NumberRegions; Index++) {
> +    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN)
> == EFI_SMRAM_OPEN) {
> +      OpenState = TRUE;
> +    }
> +  }
> +
> +  SmmAccess->SmmAccess.OpenState = OpenState;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "lock" SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "lock" means that the memory can no longer be opened
> +  to PEIM.
> +
> +  @param[in] PeiServices      - General purpose services available to every
> PEIM.
> +  @param[in] This             -  Pointer to the SMM Access Interface.
> +  @param[in] DescriptorIndex  -  Region of SMRAM to Lock.
> +
> +  @retval EFI_SUCCESS            -  The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR       -  The region could not be locked because
> at least
> +                                    one range is still open.
> +  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of
> bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> +  IN EFI_PEI_SERVICES          **PeiServices,
> +  IN EFI_PEI_MM_ACCESS_PPI     *This,
> +  IN UINTN                     DescriptorIndex
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  if
> + (DescriptorIndex >= SmmAccess->NumberRegions) {
> +    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
> +
> +    return EFI_INVALID_PARAMETER;
> +  } else if (SmmAccess->SmmAccess.OpenState) {
> +    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are
> still
> + open\n"));
> +
> +    return EFI_DEVICE_ERROR;
> +  }
> +
> +  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> + EFI_SMRAM_LOCKED;  SmmAccess->SmmAccess.LockState = TRUE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine services a user request to discover the SMRAM
> +  capabilities of this platform.  This will report the possible
> +  ranges that are possible for SMRAM access, based upon the
> +  memory controller capabilities.
> +
> +  @param[in] PeiServices   - General purpose services available to every
> PEIM.
> +  @param[in] This          -  Pointer to the SMRAM Access Interface.
> +  @param[in] SmramMapSize  -  Pointer to the variable containing size of the
> +                              buffer to contain the description information.
> +  @param[in] SmramMap      -  Buffer containing the data describing the
> Smram
> +                              region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  -  The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           -  The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> +  IN EFI_PEI_SERVICES                **PeiServices,
> +  IN EFI_PEI_MM_ACCESS_PPI           *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +{
> +  EFI_STATUS              Status;
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINTN                   NecessaryBufferSize;
> +
> +  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof
> + (EFI_SMRAM_DESCRIPTOR);  if (*SmramMapSize < NecessaryBufferSize) {
> +    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
> +
> +    Status = EFI_BUFFER_TOO_SMALL;
> +  } else {
> +    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  *SmramMapSize = NecessaryBufferSize;
> +  return Status;
> +}
> +
> +/**
> +  This function is to install an SMM Access PPI
> +  - <b>Introduction</b> \n
> +    A module to install a PPI for controlling SMM mode memory access
> basically for S3 resume usage.
> +
> +  - @pre
> +    - _PEI_MASTER_BOOT_MODE_PEIM_PPI: A PPI published by foundation
> to get bootmode executed earlier.
> +    - _PEI_PERMANENT_MEMORY_INSTALLED_PPI: a PPI that will be installed
> after memory controller initialization completed to indicate that physical
> memory is usable after this point.
> +
> +  - @result
> +    Publish _EFI_PEI_MM_ACCESS_PPI.
> +
> +    @retval EFI_SUCCESS           - Ppi successfully started and installed.
> +    @retval EFI_NOT_FOUND         - Ppi can't be found.
> +    @retval EFI_OUT_OF_RESOURCES  - Ppi does not have enough resources
> to initialize the driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiInstallSmmAccessPpi (
> +  VOID
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           Index;
> +  EFI_PEI_PPI_DESCRIPTOR          *PpiList;
> +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
> +  SMM_ACCESS_PRIVATE_DATA         *SmmAccessPrivate;
> +  VOID                            *HobList;
> +  EFI_BOOT_MODE                   BootMode;
> +
> +  Status = PeiServicesGetBootMode (&BootMode);  if (EFI_ERROR (Status))
> + {
> +    //
> +    // If not in S3 boot path. do nothing
> +    //
> +    return EFI_SUCCESS;
> +  }
> +
> +  if (BootMode != BOOT_ON_S3_RESUME) {
> +    return EFI_SUCCESS;
> +  }
> +  //
> +  // Initialize private data
> +  //
> +  SmmAccessPrivate  = AllocateZeroPool (sizeof (*SmmAccessPrivate));
> + ASSERT (SmmAccessPrivate != NULL);  if (SmmAccessPrivate == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +  PpiList           = AllocateZeroPool (sizeof (*PpiList));
> +  ASSERT (PpiList != NULL);
> +  if (PpiList == NULL) {
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  SmmAccessPrivate->Signature =
> SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
> +  SmmAccessPrivate->Handle    = NULL;
> +
> +  //
> +  // Get Hob list
> +  //
> +  HobList = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);  if (HobList ==
> + NULL) {
> +    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) ((UINT8 *)
> + HobList + sizeof (EFI_HOB_GUID_TYPE));
> +
> +  //
> +  // Alloc space for SmmAccessPrivate->SmramDesc  //
> + SmmAccessPrivate->SmramDesc = AllocateZeroPool
> + ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof
> (EFI_SMRAM_DESCRIPTOR));  if (SmmAccessPrivate->SmramDesc == NULL) {
> +    DEBUG ((DEBUG_WARN, "Alloc SmmAccessPrivate->SmramDesc fail.\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "Alloc SmmAccessPrivate->SmramDesc
> success.\n"));
> +
> +  //
> +  // use the hob to publish SMRAM capabilities  //  for (Index = 0;
> + Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
> +    SmmAccessPrivate->SmramDesc[Index].PhysicalStart  = DescriptorBlock-
> >Descriptor[Index].PhysicalStart;
> +    SmmAccessPrivate->SmramDesc[Index].CpuStart       = DescriptorBlock-
> >Descriptor[Index].CpuStart;
> +    SmmAccessPrivate->SmramDesc[Index].PhysicalSize   = DescriptorBlock-
> >Descriptor[Index].PhysicalSize;
> +    SmmAccessPrivate->SmramDesc[Index].RegionState    = DescriptorBlock-
> >Descriptor[Index].RegionState;
> +  }
> +
> +  SmmAccessPrivate->NumberRegions             = Index;
> +  SmmAccessPrivate->SmmAccess.Open            = Open;
> +  SmmAccessPrivate->SmmAccess.Close           = Close;
> +  SmmAccessPrivate->SmmAccess.Lock            = Lock;
> +  SmmAccessPrivate->SmmAccess.GetCapabilities = GetCapabilities;
> +  SmmAccessPrivate->SmmAccess.LockState       = FALSE;
> +  SmmAccessPrivate->SmmAccess.OpenState       = FALSE;
> +
> +  //
> +  // Install PPI
> +  //
> +  PpiList->Flags  = (EFI_PEI_PPI_DESCRIPTOR_PPI |
> EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
> +  PpiList->Guid   = &gEfiPeiMmAccessPpiGuid;
> +  PpiList->Ppi    = &SmmAccessPrivate->SmmAccess;
> +
> +  Status          = PeiServicesInstallPpi (PpiList);
> +  ASSERT_EFI_ERROR (Status);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLi
> b/PeiSmmAccessLib.inf
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLi
> b/PeiSmmAccessLib.inf
> new file mode 100644
> index 0000000000..f04d071318
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAcce
> +++ ssLib/PeiSmmAccessLib.inf
> @@ -0,0 +1,41 @@
> +## @file
> +# Library description file for the SmmAccess module # # Copyright (c)
> +2019, Intel Corporation. All rights reserved.<BR> #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = PeiSmmAccessLib
> +FILE_GUID = 54020881-B594-442A-8377-A57AFF98C7CF
> +VERSION_STRING = 1.0
> +MODULE_TYPE = PEIM
> +LIBRARY_CLASS = SmmAccessLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +BaseMemoryLib
> +HobLib
> +PciSegmentLib
> +PeiServicesLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +
> +[Sources]
> +PeiSmmAccessLib.c
> +
> +
> +[Ppis]
> +gEfiPeiMmAccessPpiGuid ## PRODUCES
> +
> +
> +[Guids]
> +gEfiSmmSmramMemoryGuid
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> cess.inf
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> cess.inf
> new file mode 100644
> index 0000000000..34dc65d7a3
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> +++ cess.inf
> @@ -0,0 +1,46 @@
> +## @file
> +# Component description file for the SmmAccess module # # Copyright (c)
> +2019, Intel Corporation. All rights reserved.<BR> #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = SmmAccess
> +FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_DRIVER
> +ENTRY_POINT = SmmAccessDriverEntryPoint
> +
> +
> +[LibraryClasses]
> +UefiDriverEntryPoint
> +BaseLib
> +BaseMemoryLib
> +DebugLib
> +HobLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +
> +[Sources]
> +SmmAccessDriver.h
> +SmmAccessDriver.c
> +
> +
> +[Protocols]
> +gEfiSmmAccess2ProtocolGuid       ## PRODUCES
> +
> +
> +[Guids]
> +gEfiSmmSmramMemoryGuid
> +
> +
> +[Depex]
> +TRUE
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> cessDriver.c
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> cessDriver.c
> new file mode 100644
> index 0000000000..3d3c4ab206
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> +++ cessDriver.c
> @@ -0,0 +1,267 @@
> +/** @file
> +  This is the driver that publishes the SMM Access Protocol
> +  instance for System Agent.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#include "SmmAccessDriver.h"
> +
> +static SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
> +
> +/**
> +  This is the standard EFI driver point that
> +  installs an SMM Access Protocol
> +
> +  @param[in] ImageHandle     - Handle for the image of this driver
> +  @param[in] SystemTable     - Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS           - Protocol was installed successfully
> +  @exception EFI_UNSUPPORTED    - Protocol was not installed
> +  @retval EFI_NOT_FOUND         - Protocol can't be found.
> +  @retval EFI_OUT_OF_RESOURCES  - Protocol does not have enough
> resources to initialize the driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +SmmAccessDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  EFI_STATUS                      Status;
> +  UINTN                           Index;
> +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
> +  EFI_PEI_HOB_POINTERS            *Hob;
> +
> +  //
> +  // Initialize Global variables
> +  //
> +  ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
> +
> +  mSmmAccess.Signature        = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
> +  mSmmAccess.Handle           = NULL;
> +
> +  //
> +  // Get Hob list
> +  //
> +  Hob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);  if (Hob == NULL)
> {
> +    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
> +    return EFI_NOT_FOUND;
> +  }
> +
> +  DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof
> + (EFI_HOB_GUID_TYPE));
> +
> +  //
> +  // Alloc space for mSmmAccess.SmramDesc  //  mSmmAccess.SmramDesc
> =
> + AllocateZeroPool ((DescriptorBlock->NumberOfSmmReservedRegions) *
> + sizeof (EFI_SMRAM_DESCRIPTOR));  if (mSmmAccess.SmramDesc == NULL)
> {
> +    DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
> +    return EFI_OUT_OF_RESOURCES;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
> +
> +  //
> +  // Use the HOB to publish SMRAM capabilities  //  for (Index = 0;
> + Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
> +    mSmmAccess.SmramDesc[Index].PhysicalStart = DescriptorBlock-
> >Descriptor[Index].PhysicalStart;
> +    mSmmAccess.SmramDesc[Index].CpuStart      = DescriptorBlock-
> >Descriptor[Index].CpuStart;
> +    mSmmAccess.SmramDesc[Index].PhysicalSize  = DescriptorBlock-
> >Descriptor[Index].PhysicalSize;
> +    mSmmAccess.SmramDesc[Index].RegionState   = DescriptorBlock-
> >Descriptor[Index].RegionState;
> +  }
> +
> +  mSmmAccess.NumberRegions              = Index;
> +  mSmmAccess.SmmAccess.Open             = Open;
> +  mSmmAccess.SmmAccess.Close            = Close;
> +  mSmmAccess.SmmAccess.Lock             = Lock;
> +  mSmmAccess.SmmAccess.GetCapabilities  = GetCapabilities;
> +  mSmmAccess.SmmAccess.LockState        = FALSE;
> +  mSmmAccess.SmmAccess.OpenState        = FALSE;
> +
> +  //
> +  // Install our protocol interfaces on the device's handle  //  Status
> + = gBS->InstallMultipleProtocolInterfaces (
> +                  &mSmmAccess.Handle,
> +                  &gEfiSmmAccess2ProtocolGuid,
> +                  &mSmmAccess.SmmAccess,
> +                  NULL
> +                  );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces
> returned %r\n", Status));
> +    return EFI_UNSUPPORTED;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "open" a region of SMRAM.  The
> +  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +  The use of "open" means that the memory is visible from all
> +boot-service
> +  and SMM agents.
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR      - The region could not be opened because
> locked by
> +                          chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  for
> + (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> +      return EFI_DEVICE_ERROR;
> +    }
> +  }
> +
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> +EFI_SMRAM_OPEN;
> +  }
> +  SmmAccess->SmmAccess.OpenState = TRUE;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "close" a region of SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "close" means that the memory is only visible from SMM
> +agents,
> +  not from BS or RT code.
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR      - The region could not be closed because
> locked by chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  BOOLEAN                 OpenState;
> +  UINT8                   Index;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> EFI_SMRAM_LOCKED) {
> +      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> +      continue;
> +    }
> +
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> ~EFI_SMRAM_OPEN;
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> + (EFI_SMRAM_CLOSED | EFI_ALLOCATED);  }
> +
> +  //
> +  // Find out if any regions are still open  //  OpenState = FALSE;
> + for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
> +    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN)
> == EFI_SMRAM_OPEN) {
> +      OpenState = TRUE;
> +    }
> +  }
> +
> +  SmmAccess->SmmAccess.OpenState = OpenState;
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine accepts a request to "lock" SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "lock" means that the memory can no longer be opened
> +  to BS state..
> +
> +  @param[in] This               - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR      - The region could not be locked because at
> least
> +                                  one range is still open.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  )
> +{
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINTN                   DescriptorIndex;
> +
> +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  if (SmmAccess->SmmAccess.OpenState) {
> +    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions are
> still open\n"));
> +    return EFI_DEVICE_ERROR;
> +  }
> +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> DescriptorIndex++) {
> +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> + EFI_SMRAM_LOCKED;  }  SmmAccess->SmmAccess.LockState = TRUE;
> +
> +  return EFI_SUCCESS;
> +}
> +
> +/**
> +  This routine services a user request to discover the SMRAM
> +  capabilities of this platform.  This will report the possible
> +  ranges that are possible for SMRAM access, based upon the
> +  memory controller capabilities.
> +
> +  @param[in] This                  - Pointer to the SMRAM Access Interface.
> +  @param[in] SmramMapSize          - Pointer to the variable containing size of
> the
> +                                     buffer to contain the description information.
> +  @param[in] SmramMap              - Buffer containing the data describing the
> Smram
> +                                     region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> +  IN OUT UINTN                       *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> +  )
> +{
> +  EFI_STATUS              Status;
> +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> +  UINTN                   NecessaryBufferSize;
> +
> +  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> +
> +  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof
> + (EFI_SMRAM_DESCRIPTOR);
> +
> +  if (*SmramMapSize < NecessaryBufferSize) {
> +    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
> +    Status = EFI_BUFFER_TOO_SMALL;
> +  } else {
> +    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  *SmramMapSize = NecessaryBufferSize;
> +
> +  return Status;
> +}
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> cessDriver.h
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> cessDriver.h
> new file mode 100644
> index 0000000000..c0ff3a250b
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> +++ cessDriver.h
> @@ -0,0 +1,160 @@
> +/** @file
> +  Header file for SMM Access Driver.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _SMM_ACCESS_DRIVER_H_
> +#define _SMM_ACCESS_DRIVER_H_
> +
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/HobLib.h>
> +#include <Library/PciLib.h>
> +#include <Library/MemoryAllocationLib.h> #include
> +<Library/UefiBootServicesTableLib.h>
> +#include <Uefi/UefiBaseType.h>
> +
> +#include <Guid/SmramMemoryReserve.h>
> +#include <Protocol/SmmAccess2.h>
> +#include <IndustryStandard/Pci22.h>
> +
> +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5',
> 's',
> +'a')
> +
> +///
> +/// Private data
> +///
> +typedef struct {
> +  UINTN                           Signature;
> +  EFI_HANDLE                      Handle;
> +  EFI_SMM_ACCESS2_PROTOCOL        SmmAccess;
> +
> +  ///
> +  /// Local Data for SMM Access interface goes here
> +  ///
> +  UINTN                           NumberRegions;
> +  EFI_SMRAM_DESCRIPTOR            *SmramDesc;
> +} SMM_ACCESS_PRIVATE_DATA;
> +
> +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
> +  CR (a, \
> +      SMM_ACCESS_PRIVATE_DATA, \
> +      SmmAccess, \
> +      SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
> +      )
> +
> +//
> +// Prototypes
> +// Driver model protocol interface
> +//
> +/**
> +  <b>SMM Access Driver Entry Point</b>
> +  This driver installs an SMM Access Protocol
> +  - <b>Introduction</b> \n
> +    This module publishes the SMM access protocol.  The protocol is used by
> the SMM Base driver to access the SMRAM region when the processor is not
> in SMM.
> +    The SMM Base driver uses the services provided by the SMM access
> protocol to open SMRAM during post and copy the SMM handler.
> +    SMM access protocol is also used to close the SMRAM region once the
> copying is done.
> +    Finally, the SMM access protocol provides services to "Lock" the SMRAM
> region.
> +    Please refer the SMM Protocols section in the attached SMM CIS
> Specification version 0.9 for further details.
> +    This driver is required if SMM is supported. Proper configuration of SMM
> registers is recommended even if SMM is not supported.
> +
> +  - @result
> +    Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the
> System
> + Management Mode Core Interface Specification, available at the URL:
> + http://www.intel.com/technology/framework/spec.htm
> +
> +  - <b>Porting Recommendations</b> \n
> +    No modification of this module is recommended.  Any modification
> should be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL
> protocol definition.
> +
> +  @param[in] ImageHandle     - Handle for the image of this driver
> +  @param[in] SystemTable     - Pointer to the EFI System Table
> +
> +  @retval EFI_SUCCESS     - Protocol was installed successfully
> +  @exception EFI_UNSUPPORTED - Protocol was not installed **/
> +EFI_STATUS EFIAPI SmmAccessDriverEntryPoint (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  );
> +
> +/**
> +  This routine accepts a request to "open" a region of SMRAM.  The
> +  region could be legacy ABSEG, HSEG, or TSEG near top of physical memory.
> +  The use of "open" means that the memory is visible from all
> +boot-service
> +  and SMM agents.
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully opened.
> +  @retval EFI_DEVICE_ERROR      - The region could not be opened because
> locked by
> +                          chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Open (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  );
> +
> +/**
> +  This routine accepts a request to "close" a region of SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "close" means that the memory is only visible from SMM
> +agents,
> +  not from BS or RT code.
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully closed.
> +  @retval EFI_DEVICE_ERROR      - The region could not be closed because
> locked by
> +                            chipset.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Close (
> +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> +  );
> +
> +/**
> +  This routine accepts a request to "lock" SMRAM.  The
> +  region could be legacy AB or TSEG near top of physical memory.
> +  The use of "lock" means that the memory can no longer be opened
> +  to BS state..
> +
> +  @param[in] This                  - Pointer to the SMM Access Interface.
> +
> +  @retval EFI_SUCCESS           - The region was successfully locked.
> +  @retval EFI_DEVICE_ERROR      - The region could not be locked because at
> least
> +                          one range is still open.
> +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> bounds.
> +**/
> +EFI_STATUS
> +EFIAPI
> +Lock (
> +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> +  );
> +
> +/**
> +  This routine services a user request to discover the SMRAM
> +  capabilities of this platform.  This will report the possible
> +  ranges that are possible for SMRAM access, based upon the
> +  memory controller capabilities.
> +
> +  @param[in] This                  - Pointer to the SMRAM Access Interface.
> +  @param[in] SmramMapSize          - Pointer to the variable containing size of
> the
> +                            buffer to contain the description information.
> +  @param[in] SmramMap              - Buffer containing the data describing the
> Smram
> +                            region descriptors.
> +
> +  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient
> buffer.
> +  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> +**/
> +EFI_STATUS
> +EFIAPI
> +GetCapabilities (
> +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> +  IN OUT UINTN                   *SmramMapSize,
> +  IN OUT EFI_SMRAM_DESCRIPTOR    *SmramMap
> +  );
> +#endif
> diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> b/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> new file mode 100644
> index 0000000000..b7cb88f6ca
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> @@ -0,0 +1,32 @@
> +/** @file
> +  Header file for SMM Access Driver.
> +
> +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +  SPDX-License-Identifier: BSD-2-Clause-Patent
> +
> +**/
> +#ifndef _SMM_ACCESS_H_
> +#define _SMM_ACCESS_H_
> +
> +/**
> +  This function is to install an SMM Access PPI
> +  - <b>Introduction</b> \n
> +    A module to install a PPI for controlling SMM mode memory access
> basically for S3 resume usage.
> +
> +  - @pre
> +    - _PEI_MASTER_BOOT_MODE_PEIM_PPI: A PPI published by foundation
> to get bootmode executed earlier.
> +    - _PEI_PERMANENT_MEMORY_INSTALLED_PPI: a PPI that will be installed
> after memory controller initialization completed to indicate that physical
> memory is usable after this point.
> +
> +  - @result
> +    Publish _PEI_SMM_ACCESS_PPI.
> +
> +    @retval EFI_SUCCESS           - Ppi successfully started and installed.
> +    @retval EFI_NOT_FOUND         - Ppi can't be found.
> +    @retval EFI_OUT_OF_RESOURCES  - Ppi does not have enough resources
> to initialize the driver.
> +**/
> +EFI_STATUS
> +EFIAPI
> +PeiInstallSmmAccessPpi (
> +  VOID
> +  );
> +#endif
> --
> 2.16.2.windows.1
> 
> 
> 


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [edk2-devel] [PATCH v2] IntelSiliconPkg/Feature Implement SmmAccess
  2019-08-27  6:21 ` [edk2-devel] " Zeng, Star
@ 2019-08-27  7:01   ` Marc W Chen
  0 siblings, 0 replies; 4+ messages in thread
From: Marc W Chen @ 2019-08-27  7:01 UTC (permalink / raw)
  To: Zeng, Star, devel@edk2.groups.io; +Cc: Ni, Ray, Chaganty, Rangasai V

Thanks Star for reviewing, it is a typo, let me update it in next patch.

Thanks,
Marc

> -----Original Message-----
> From: Zeng, Star
> Sent: Tuesday, August 27, 2019 2:22 PM
> To: devel@edk2.groups.io; Chen, Marc W <marc.w.chen@intel.com>
> Cc: Ni, Ray <ray.ni@intel.com>; Chaganty, Rangasai V
> <rangasai.v.chaganty@intel.com>; Zeng, Star <star.zeng@intel.com>
> Subject: RE: [edk2-devel] [PATCH v2] IntelSiliconPkg/Feature Implement
> SmmAccess
> 
> Include new library and driver to IntelSiliconPkg.dsc for building coverage?
> In SmmAccessLib.h, it still refers the _PEI_SMM_ACCESS_PPI definition from
> MdeModulePkg? And need have _EFI prefix for
> _PEI_MASTER_BOOT_MODE_PEIM_PPI and
> _PEI_PERMANENT_MEMORY_INSTALLED_PPI?
> In PeiSmmAccessLib.inf, the word 'module' in description " Library
> description file for the SmmAccess module " need to be updated?
> 
> 
> 
> Thanks,
> Star
> 
> > -----Original Message-----
> > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> > Marc W Chen
> > Sent: Monday, August 26, 2019 2:14 PM
> > To: devel@edk2.groups.io
> > Cc: Chen, Marc W <marc.w.chen@intel.com>; Ni, Ray <ray.ni@intel.com>;
> > Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>
> > Subject: [edk2-devel] [PATCH v2] IntelSiliconPkg/Feature Implement
> > SmmAccess
> >
> > REF:https://bugzilla.tianocore.org/show_bug.cgi?id=2121
> >
> > Implement SmmAccess for PEI and DXE phase in IntelSiliconPkg
> >
> > Signed-off-by: Marc Chen <marc.w.chen@intel.com>
> > Cc: Ray Ni <ray.ni@intel.com>
> > Cc: Rangasai V Chaganty <rangasai.v.chaganty@intel.com>
> > ---
> >  .../Library/PeiSmmAccessLib/PeiSmmAccessLib.c      | 343
> > +++++++++++++++++++++
> >  .../Library/PeiSmmAccessLib/PeiSmmAccessLib.inf    |  41 +++
> >  .../Feature/SmmAccess/SmmAccessDxe/SmmAccess.inf   |  46 +++
> >  .../SmmAccess/SmmAccessDxe/SmmAccessDriver.c       | 267
> > ++++++++++++++++
> >  .../SmmAccess/SmmAccessDxe/SmmAccessDriver.h       | 160 ++++++++++
> >  .../IntelSiliconPkg/Include/Library/SmmAccessLib.h |  32 ++
> >  6 files changed, 889 insertions(+)
> >  create mode 100644
> >
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/
> > PeiSmmAccessLib.c
> >  create mode 100644
> >
> Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/
> > PeiSmmAccessLib.inf
> >  create mode 100644
> > Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAcce
> > ss.inf
> >  create mode 100644
> > Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAcce
> > ssDriver.c
> >  create mode 100644
> > Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAcce
> > ssDriver.h
> >  create mode 100644
> > Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> >
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLi
> > b/PeiSmmAccessLib.c
> >
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLi
> > b/PeiSmmAccessLib.c
> > new file mode 100644
> > index 0000000000..cc5bf745d2
> > --- /dev/null
> > +++
> > b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAcce
> > +++ ssLib/PeiSmmAccessLib.c
> > @@ -0,0 +1,343 @@
> > +/** @file
> > +  This is to publish the SMM Access Ppi instance.
> > +
> > +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/MemoryAllocationLib.h> #include
> > +<Library/PciSegmentLib.h> #include <Library/PeiServicesLib.h> #include
> > +<Library/HobLib.h> #include <Uefi/UefiBaseType.h> #include
> > +<Guid/SmramMemoryReserve.h>
> > +
> > +#include <Ppi/MmAccess.h>
> > +#include <IndustryStandard/Pci22.h>
> > +
> > +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5',
> > 's',
> > +'a')
> > +
> > +///
> > +/// Private data
> > +///
> > +typedef struct {
> > +  UINTN                 Signature;
> > +  EFI_HANDLE            Handle;
> > +  EFI_PEI_MM_ACCESS_PPI SmmAccess;
> > +  //
> > +  // Local Data for SMM Access interface goes here
> > +  //
> > +  UINTN                 NumberRegions;
> > +  EFI_SMRAM_DESCRIPTOR  *SmramDesc;
> > +} SMM_ACCESS_PRIVATE_DATA;
> > +
> > +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
> > +        CR (a, \
> > +          SMM_ACCESS_PRIVATE_DATA, \
> > +          SmmAccess, \
> > +          SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
> > +      )
> > +
> > +/**
> > +  This routine accepts a request to "open" a region of SMRAM.  The
> > +  region could be legacy ABSEG, HSEG, or TSEG near top of physical
> memory.
> > +  The use of "open" means that the memory is visible from all PEIM
> > +  and SMM agents.
> > +
> > +  @param[in] This             -  Pointer to the SMM Access Interface.
> > +  @param[in] DescriptorIndex  -  Region of SMRAM to Open.
> > +  @param[in] PeiServices      -  General purpose services available to every
> > PEIM.
> > +
> > +  @retval EFI_SUCCESS            -  The region was successfully opened.
> > +  @retval EFI_DEVICE_ERROR       -  The region could not be opened
> because
> > locked by
> > +                                    chipset.
> > +  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of
> > bounds.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Open (
> > +  IN EFI_PEI_SERVICES           **PeiServices,
> > +  IN EFI_PEI_MM_ACCESS_PPI      *This,
> > +  IN UINTN                      DescriptorIndex
> > +  )
> > +{
> > +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> > +
> > +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  if
> > + (DescriptorIndex >= SmmAccess->NumberRegions) {
> > +    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
> > +
> > +    return EFI_INVALID_PARAMETER;
> > +  } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> > EFI_SMRAM_LOCKED) {
> > +    //
> > +    // Cannot open a "locked" region
> > +    //
> > +    DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> > +
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> > +~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> > +  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> > +EFI_SMRAM_OPEN;
> > +  SmmAccess->SmmAccess.OpenState = TRUE;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  This routine accepts a request to "close" a region of SMRAM.  This is
> > +valid for
> > +  compatible SMRAM region.
> > +
> > +  @param[in] PeiServices      -  General purpose services available to every
> > PEIM.
> > +  @param[in] This             -  Pointer to the SMM Access Interface.
> > +  @param[in] DescriptorIndex  -  Region of SMRAM to Close.
> > +
> > +  @retval EFI_SUCCESS            -  The region was successfully closed.
> > +  @retval EFI_DEVICE_ERROR       -  The region could not be closed because
> > locked by
> > +                                    chipset.
> > +  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of
> > bounds.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Close (
> > +  IN EFI_PEI_SERVICES        **PeiServices,
> > +  IN EFI_PEI_MM_ACCESS_PPI   *This,
> > +  IN UINTN                   DescriptorIndex
> > +  )
> > +{
> > +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> > +  BOOLEAN                 OpenState;
> > +  UINT8                   Index;
> > +
> > +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  if
> > + (DescriptorIndex >= SmmAccess->NumberRegions) {
> > +    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
> > +
> > +    return EFI_INVALID_PARAMETER;
> > +  } else if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> > EFI_SMRAM_LOCKED) {
> > +    //
> > +    // Cannot close a "locked" region
> > +    //
> > +    DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> > +
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> > EFI_SMRAM_CLOSED) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> > + ~EFI_SMRAM_OPEN;  SmmAccess-
> > >SmramDesc[DescriptorIndex].RegionState |=
> > + (UINT64) (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> > +
> > +  //
> > +  // Find out if any regions are still open  //  OpenState = FALSE;
> > + for (Index = 0; Index < SmmAccess->NumberRegions; Index++) {
> > +    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN)
> > == EFI_SMRAM_OPEN) {
> > +      OpenState = TRUE;
> > +    }
> > +  }
> > +
> > +  SmmAccess->SmmAccess.OpenState = OpenState;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  This routine accepts a request to "lock" SMRAM.  The
> > +  region could be legacy AB or TSEG near top of physical memory.
> > +  The use of "lock" means that the memory can no longer be opened
> > +  to PEIM.
> > +
> > +  @param[in] PeiServices      - General purpose services available to every
> > PEIM.
> > +  @param[in] This             -  Pointer to the SMM Access Interface.
> > +  @param[in] DescriptorIndex  -  Region of SMRAM to Lock.
> > +
> > +  @retval EFI_SUCCESS            -  The region was successfully locked.
> > +  @retval EFI_DEVICE_ERROR       -  The region could not be locked because
> > at least
> > +                                    one range is still open.
> > +  @retval EFI_INVALID_PARAMETER  -  The descriptor index was out of
> > bounds.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Lock (
> > +  IN EFI_PEI_SERVICES          **PeiServices,
> > +  IN EFI_PEI_MM_ACCESS_PPI     *This,
> > +  IN UINTN                     DescriptorIndex
> > +  )
> > +{
> > +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> > +
> > +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  if
> > + (DescriptorIndex >= SmmAccess->NumberRegions) {
> > +    DEBUG ((DEBUG_WARN, "SMRAM region out of range\n"));
> > +
> > +    return EFI_INVALID_PARAMETER;
> > +  } else if (SmmAccess->SmmAccess.OpenState) {
> > +    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions
> are
> > still
> > + open\n"));
> > +
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> > + EFI_SMRAM_LOCKED;  SmmAccess->SmmAccess.LockState = TRUE;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  This routine services a user request to discover the SMRAM
> > +  capabilities of this platform.  This will report the possible
> > +  ranges that are possible for SMRAM access, based upon the
> > +  memory controller capabilities.
> > +
> > +  @param[in] PeiServices   - General purpose services available to every
> > PEIM.
> > +  @param[in] This          -  Pointer to the SMRAM Access Interface.
> > +  @param[in] SmramMapSize  -  Pointer to the variable containing size of
> the
> > +                              buffer to contain the description information.
> > +  @param[in] SmramMap      -  Buffer containing the data describing the
> > Smram
> > +                              region descriptors.
> > +
> > +  @retval EFI_BUFFER_TOO_SMALL  -  The user did not provide a sufficient
> > buffer.
> > +  @retval EFI_SUCCESS           -  The user provided a sufficiently-sized buffer.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetCapabilities (
> > +  IN EFI_PEI_SERVICES                **PeiServices,
> > +  IN EFI_PEI_MM_ACCESS_PPI           *This,
> > +  IN OUT UINTN                       *SmramMapSize,
> > +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> > +  )
> > +{
> > +  EFI_STATUS              Status;
> > +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> > +  UINTN                   NecessaryBufferSize;
> > +
> > +  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> > +  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof
> > + (EFI_SMRAM_DESCRIPTOR);  if (*SmramMapSize < NecessaryBufferSize) {
> > +    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
> > +
> > +    Status = EFI_BUFFER_TOO_SMALL;
> > +  } else {
> > +    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
> > +    Status = EFI_SUCCESS;
> > +  }
> > +
> > +  *SmramMapSize = NecessaryBufferSize;
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is to install an SMM Access PPI
> > +  - <b>Introduction</b> \n
> > +    A module to install a PPI for controlling SMM mode memory access
> > basically for S3 resume usage.
> > +
> > +  - @pre
> > +    - _PEI_MASTER_BOOT_MODE_PEIM_PPI: A PPI published by foundation
> > to get bootmode executed earlier.
> > +    - _PEI_PERMANENT_MEMORY_INSTALLED_PPI: a PPI that will be
> installed
> > after memory controller initialization completed to indicate that physical
> > memory is usable after this point.
> > +
> > +  - @result
> > +    Publish _EFI_PEI_MM_ACCESS_PPI.
> > +
> > +    @retval EFI_SUCCESS           - Ppi successfully started and installed.
> > +    @retval EFI_NOT_FOUND         - Ppi can't be found.
> > +    @retval EFI_OUT_OF_RESOURCES  - Ppi does not have enough
> resources
> > to initialize the driver.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +PeiInstallSmmAccessPpi (
> > +  VOID
> > +  )
> > +{
> > +  EFI_STATUS                      Status;
> > +  UINTN                           Index;
> > +  EFI_PEI_PPI_DESCRIPTOR          *PpiList;
> > +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
> > +  SMM_ACCESS_PRIVATE_DATA         *SmmAccessPrivate;
> > +  VOID                            *HobList;
> > +  EFI_BOOT_MODE                   BootMode;
> > +
> > +  Status = PeiServicesGetBootMode (&BootMode);  if (EFI_ERROR (Status))
> > + {
> > +    //
> > +    // If not in S3 boot path. do nothing
> > +    //
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  if (BootMode != BOOT_ON_S3_RESUME) {
> > +    return EFI_SUCCESS;
> > +  }
> > +  //
> > +  // Initialize private data
> > +  //
> > +  SmmAccessPrivate  = AllocateZeroPool (sizeof (*SmmAccessPrivate));
> > + ASSERT (SmmAccessPrivate != NULL);  if (SmmAccessPrivate == NULL) {
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +  PpiList           = AllocateZeroPool (sizeof (*PpiList));
> > +  ASSERT (PpiList != NULL);
> > +  if (PpiList == NULL) {
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  SmmAccessPrivate->Signature =
> > SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
> > +  SmmAccessPrivate->Handle    = NULL;
> > +
> > +  //
> > +  // Get Hob list
> > +  //
> > +  HobList = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);  if (HobList
> ==
> > + NULL) {
> > +    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
> > +    return EFI_NOT_FOUND;
> > +  }
> > +
> > +  DescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) ((UINT8 *)
> > + HobList + sizeof (EFI_HOB_GUID_TYPE));
> > +
> > +  //
> > +  // Alloc space for SmmAccessPrivate->SmramDesc  //
> > + SmmAccessPrivate->SmramDesc = AllocateZeroPool
> > + ((DescriptorBlock->NumberOfSmmReservedRegions) * sizeof
> > (EFI_SMRAM_DESCRIPTOR));  if (SmmAccessPrivate->SmramDesc == NULL) {
> > +    DEBUG ((DEBUG_WARN, "Alloc SmmAccessPrivate->SmramDesc
> fail.\n"));
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "Alloc SmmAccessPrivate->SmramDesc
> > success.\n"));
> > +
> > +  //
> > +  // use the hob to publish SMRAM capabilities  //  for (Index = 0;
> > + Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
> > +    SmmAccessPrivate->SmramDesc[Index].PhysicalStart  = DescriptorBlock-
> > >Descriptor[Index].PhysicalStart;
> > +    SmmAccessPrivate->SmramDesc[Index].CpuStart       = DescriptorBlock-
> > >Descriptor[Index].CpuStart;
> > +    SmmAccessPrivate->SmramDesc[Index].PhysicalSize   = DescriptorBlock-
> > >Descriptor[Index].PhysicalSize;
> > +    SmmAccessPrivate->SmramDesc[Index].RegionState    =
> DescriptorBlock-
> > >Descriptor[Index].RegionState;
> > +  }
> > +
> > +  SmmAccessPrivate->NumberRegions             = Index;
> > +  SmmAccessPrivate->SmmAccess.Open            = Open;
> > +  SmmAccessPrivate->SmmAccess.Close           = Close;
> > +  SmmAccessPrivate->SmmAccess.Lock            = Lock;
> > +  SmmAccessPrivate->SmmAccess.GetCapabilities = GetCapabilities;
> > +  SmmAccessPrivate->SmmAccess.LockState       = FALSE;
> > +  SmmAccessPrivate->SmmAccess.OpenState       = FALSE;
> > +
> > +  //
> > +  // Install PPI
> > +  //
> > +  PpiList->Flags  = (EFI_PEI_PPI_DESCRIPTOR_PPI |
> > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
> > +  PpiList->Guid   = &gEfiPeiMmAccessPpiGuid;
> > +  PpiList->Ppi    = &SmmAccessPrivate->SmmAccess;
> > +
> > +  Status          = PeiServicesInstallPpi (PpiList);
> > +  ASSERT_EFI_ERROR (Status);
> > +
> > +  return EFI_SUCCESS;
> > +}
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLi
> > b/PeiSmmAccessLib.inf
> >
> b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLi
> > b/PeiSmmAccessLib.inf
> > new file mode 100644
> > index 0000000000..f04d071318
> > --- /dev/null
> > +++
> > b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAcce
> > +++ ssLib/PeiSmmAccessLib.inf
> > @@ -0,0 +1,41 @@
> > +## @file
> > +# Library description file for the SmmAccess module # # Copyright (c)
> > +2019, Intel Corporation. All rights reserved.<BR> #
> > +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> > +
> > +
> > +[Defines]
> > +INF_VERSION = 0x00010017
> > +BASE_NAME = PeiSmmAccessLib
> > +FILE_GUID = 54020881-B594-442A-8377-A57AFF98C7CF
> > +VERSION_STRING = 1.0
> > +MODULE_TYPE = PEIM
> > +LIBRARY_CLASS = SmmAccessLib
> > +
> > +
> > +[LibraryClasses]
> > +BaseLib
> > +BaseMemoryLib
> > +HobLib
> > +PciSegmentLib
> > +PeiServicesLib
> > +
> > +
> > +[Packages]
> > +MdePkg/MdePkg.dec
> > +IntelSiliconPkg/IntelSiliconPkg.dec
> > +
> > +
> > +[Sources]
> > +PeiSmmAccessLib.c
> > +
> > +
> > +[Ppis]
> > +gEfiPeiMmAccessPpiGuid ## PRODUCES
> > +
> > +
> > +[Guids]
> > +gEfiSmmSmramMemoryGuid
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> > cess.inf
> > b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> > cess.inf
> > new file mode 100644
> > index 0000000000..34dc65d7a3
> > --- /dev/null
> > +++
> > b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> > +++ cess.inf
> > @@ -0,0 +1,46 @@
> > +## @file
> > +# Component description file for the SmmAccess module # # Copyright (c)
> > +2019, Intel Corporation. All rights reserved.<BR> #
> > +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> > +
> > +
> > +[Defines]
> > +INF_VERSION = 0x00010017
> > +BASE_NAME = SmmAccess
> > +FILE_GUID = 1323C7F8-DAD5-4126-A54B-7A05FBF41515
> > +VERSION_STRING = 1.0
> > +MODULE_TYPE = DXE_DRIVER
> > +ENTRY_POINT = SmmAccessDriverEntryPoint
> > +
> > +
> > +[LibraryClasses]
> > +UefiDriverEntryPoint
> > +BaseLib
> > +BaseMemoryLib
> > +DebugLib
> > +HobLib
> > +
> > +
> > +[Packages]
> > +MdePkg/MdePkg.dec
> > +IntelSiliconPkg/IntelSiliconPkg.dec
> > +
> > +
> > +[Sources]
> > +SmmAccessDriver.h
> > +SmmAccessDriver.c
> > +
> > +
> > +[Protocols]
> > +gEfiSmmAccess2ProtocolGuid       ## PRODUCES
> > +
> > +
> > +[Guids]
> > +gEfiSmmSmramMemoryGuid
> > +
> > +
> > +[Depex]
> > +TRUE
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> > cessDriver.c
> > b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> > cessDriver.c
> > new file mode 100644
> > index 0000000000..3d3c4ab206
> > --- /dev/null
> > +++
> > b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> > +++ cessDriver.c
> > @@ -0,0 +1,267 @@
> > +/** @file
> > +  This is the driver that publishes the SMM Access Protocol
> > +  instance for System Agent.
> > +
> > +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#include "SmmAccessDriver.h"
> > +
> > +static SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
> > +
> > +/**
> > +  This is the standard EFI driver point that
> > +  installs an SMM Access Protocol
> > +
> > +  @param[in] ImageHandle     - Handle for the image of this driver
> > +  @param[in] SystemTable     - Pointer to the EFI System Table
> > +
> > +  @retval EFI_SUCCESS           - Protocol was installed successfully
> > +  @exception EFI_UNSUPPORTED    - Protocol was not installed
> > +  @retval EFI_NOT_FOUND         - Protocol can't be found.
> > +  @retval EFI_OUT_OF_RESOURCES  - Protocol does not have enough
> > resources to initialize the driver.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SmmAccessDriverEntryPoint (
> > +  IN EFI_HANDLE         ImageHandle,
> > +  IN EFI_SYSTEM_TABLE   *SystemTable
> > +  )
> > +{
> > +  EFI_STATUS                      Status;
> > +  UINTN                           Index;
> > +  EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *DescriptorBlock;
> > +  EFI_PEI_HOB_POINTERS            *Hob;
> > +
> > +  //
> > +  // Initialize Global variables
> > +  //
> > +  ZeroMem (&mSmmAccess, sizeof (mSmmAccess));
> > +
> > +  mSmmAccess.Signature        = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
> > +  mSmmAccess.Handle           = NULL;
> > +
> > +  //
> > +  // Get Hob list
> > +  //
> > +  Hob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);  if (Hob == NULL)
> > {
> > +    DEBUG ((DEBUG_WARN, "SmramMemoryReserve HOB not found\n"));
> > +    return EFI_NOT_FOUND;
> > +  }
> > +
> > +  DescriptorBlock = (VOID *) ((UINT8 *) Hob + sizeof
> > + (EFI_HOB_GUID_TYPE));
> > +
> > +  //
> > +  // Alloc space for mSmmAccess.SmramDesc  //
> mSmmAccess.SmramDesc
> > =
> > + AllocateZeroPool ((DescriptorBlock->NumberOfSmmReservedRegions) *
> > + sizeof (EFI_SMRAM_DESCRIPTOR));  if (mSmmAccess.SmramDesc == NULL)
> > {
> > +    DEBUG ((DEBUG_WARN, "Alloc mSmmAccess.SmramDesc fail.\n"));
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "Alloc mSmmAccess.SmramDesc success.\n"));
> > +
> > +  //
> > +  // Use the HOB to publish SMRAM capabilities  //  for (Index = 0;
> > + Index < DescriptorBlock->NumberOfSmmReservedRegions; Index++) {
> > +    mSmmAccess.SmramDesc[Index].PhysicalStart = DescriptorBlock-
> > >Descriptor[Index].PhysicalStart;
> > +    mSmmAccess.SmramDesc[Index].CpuStart      = DescriptorBlock-
> > >Descriptor[Index].CpuStart;
> > +    mSmmAccess.SmramDesc[Index].PhysicalSize  = DescriptorBlock-
> > >Descriptor[Index].PhysicalSize;
> > +    mSmmAccess.SmramDesc[Index].RegionState   = DescriptorBlock-
> > >Descriptor[Index].RegionState;
> > +  }
> > +
> > +  mSmmAccess.NumberRegions              = Index;
> > +  mSmmAccess.SmmAccess.Open             = Open;
> > +  mSmmAccess.SmmAccess.Close            = Close;
> > +  mSmmAccess.SmmAccess.Lock             = Lock;
> > +  mSmmAccess.SmmAccess.GetCapabilities  = GetCapabilities;
> > +  mSmmAccess.SmmAccess.LockState        = FALSE;
> > +  mSmmAccess.SmmAccess.OpenState        = FALSE;
> > +
> > +  //
> > +  // Install our protocol interfaces on the device's handle  //  Status
> > + = gBS->InstallMultipleProtocolInterfaces (
> > +                  &mSmmAccess.Handle,
> > +                  &gEfiSmmAccess2ProtocolGuid,
> > +                  &mSmmAccess.SmmAccess,
> > +                  NULL
> > +                  );
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_WARN, "InstallMultipleProtocolInterfaces
> > returned %r\n", Status));
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  This routine accepts a request to "open" a region of SMRAM.  The
> > +  region could be legacy ABSEG, HSEG, or TSEG near top of physical
> memory.
> > +  The use of "open" means that the memory is visible from all
> > +boot-service
> > +  and SMM agents.
> > +
> > +  @param[in] This               - Pointer to the SMM Access Interface.
> > +
> > +  @retval EFI_SUCCESS           - The region was successfully opened.
> > +  @retval EFI_DEVICE_ERROR      - The region could not be opened because
> > locked by
> > +                          chipset.
> > +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> > bounds.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Open (
> > +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> > +  )
> > +{
> > +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> > +  UINTN                   DescriptorIndex;
> > +
> > +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);  for
> > + (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> > DescriptorIndex++) {
> > +    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> > EFI_SMRAM_LOCKED) {
> > +      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
> > +      return EFI_DEVICE_ERROR;
> > +    }
> > +  }
> > +
> > +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> > DescriptorIndex++) {
> > +    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> > ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
> > +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> > +EFI_SMRAM_OPEN;
> > +  }
> > +  SmmAccess->SmmAccess.OpenState = TRUE;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  This routine accepts a request to "close" a region of SMRAM.  The
> > +  region could be legacy AB or TSEG near top of physical memory.
> > +  The use of "close" means that the memory is only visible from SMM
> > +agents,
> > +  not from BS or RT code.
> > +
> > +  @param[in] This               - Pointer to the SMM Access Interface.
> > +
> > +  @retval EFI_SUCCESS           - The region was successfully closed.
> > +  @retval EFI_DEVICE_ERROR      - The region could not be closed because
> > locked by chipset.
> > +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> > bounds.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Close (
> > +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> > +  )
> > +{
> > +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> > +  BOOLEAN                 OpenState;
> > +  UINT8                   Index;
> > +  UINTN                   DescriptorIndex;
> > +
> > +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> > +
> > +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> > DescriptorIndex++) {
> > +    if (SmmAccess->SmramDesc[DescriptorIndex].RegionState &
> > EFI_SMRAM_LOCKED) {
> > +      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
> > +      continue;
> > +    }
> > +
> > +    SmmAccess->SmramDesc[DescriptorIndex].RegionState &= (UINT64)
> > ~EFI_SMRAM_OPEN;
> > +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |= (UINT64)
> > + (EFI_SMRAM_CLOSED | EFI_ALLOCATED);  }
> > +
> > +  //
> > +  // Find out if any regions are still open  //  OpenState = FALSE;
> > + for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
> > +    if ((SmmAccess->SmramDesc[Index].RegionState & EFI_SMRAM_OPEN)
> > == EFI_SMRAM_OPEN) {
> > +      OpenState = TRUE;
> > +    }
> > +  }
> > +
> > +  SmmAccess->SmmAccess.OpenState = OpenState;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  This routine accepts a request to "lock" SMRAM.  The
> > +  region could be legacy AB or TSEG near top of physical memory.
> > +  The use of "lock" means that the memory can no longer be opened
> > +  to BS state..
> > +
> > +  @param[in] This               - Pointer to the SMM Access Interface.
> > +
> > +  @retval EFI_SUCCESS           - The region was successfully locked.
> > +  @retval EFI_DEVICE_ERROR      - The region could not be locked because
> at
> > least
> > +                                  one range is still open.
> > +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> > bounds.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Lock (
> > +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> > +  )
> > +{
> > +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> > +  UINTN                   DescriptorIndex;
> > +
> > +  SmmAccess = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> > +
> > +  if (SmmAccess->SmmAccess.OpenState) {
> > +    DEBUG ((DEBUG_WARN, "Cannot lock SMRAM when SMRAM regions
> are
> > still open\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +  for (DescriptorIndex = 0; DescriptorIndex < SmmAccess->NumberRegions;
> > DescriptorIndex++) {
> > +    SmmAccess->SmramDesc[DescriptorIndex].RegionState |=
> > + EFI_SMRAM_LOCKED;  }  SmmAccess->SmmAccess.LockState = TRUE;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  This routine services a user request to discover the SMRAM
> > +  capabilities of this platform.  This will report the possible
> > +  ranges that are possible for SMRAM access, based upon the
> > +  memory controller capabilities.
> > +
> > +  @param[in] This                  - Pointer to the SMRAM Access Interface.
> > +  @param[in] SmramMapSize          - Pointer to the variable containing size
> of
> > the
> > +                                     buffer to contain the description information.
> > +  @param[in] SmramMap              - Buffer containing the data describing
> the
> > Smram
> > +                                     region descriptors.
> > +
> > +  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient
> > buffer.
> > +  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetCapabilities (
> > +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> > +  IN OUT UINTN                       *SmramMapSize,
> > +  IN OUT EFI_SMRAM_DESCRIPTOR        *SmramMap
> > +  )
> > +{
> > +  EFI_STATUS              Status;
> > +  SMM_ACCESS_PRIVATE_DATA *SmmAccess;
> > +  UINTN                   NecessaryBufferSize;
> > +
> > +  SmmAccess           = SMM_ACCESS_PRIVATE_DATA_FROM_THIS (This);
> > +
> > +  NecessaryBufferSize = SmmAccess->NumberRegions * sizeof
> > + (EFI_SMRAM_DESCRIPTOR);
> > +
> > +  if (*SmramMapSize < NecessaryBufferSize) {
> > +    DEBUG ((DEBUG_WARN, "SMRAM Map Buffer too small\n"));
> > +    Status = EFI_BUFFER_TOO_SMALL;
> > +  } else {
> > +    CopyMem (SmramMap, SmmAccess->SmramDesc, NecessaryBufferSize);
> > +    Status = EFI_SUCCESS;
> > +  }
> > +
> > +  *SmramMapSize = NecessaryBufferSize;
> > +
> > +  return Status;
> > +}
> > diff --git
> > a/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> > cessDriver.h
> > b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> > cessDriver.h
> > new file mode 100644
> > index 0000000000..c0ff3a250b
> > --- /dev/null
> > +++
> > b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> > +++ cessDriver.h
> > @@ -0,0 +1,160 @@
> > +/** @file
> > +  Header file for SMM Access Driver.
> > +
> > +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef _SMM_ACCESS_DRIVER_H_
> > +#define _SMM_ACCESS_DRIVER_H_
> > +
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/HobLib.h>
> > +#include <Library/PciLib.h>
> > +#include <Library/MemoryAllocationLib.h> #include
> > +<Library/UefiBootServicesTableLib.h>
> > +#include <Uefi/UefiBaseType.h>
> > +
> > +#include <Guid/SmramMemoryReserve.h>
> > +#include <Protocol/SmmAccess2.h>
> > +#include <IndustryStandard/Pci22.h>
> > +
> > +#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('4', '5',
> > 's',
> > +'a')
> > +
> > +///
> > +/// Private data
> > +///
> > +typedef struct {
> > +  UINTN                           Signature;
> > +  EFI_HANDLE                      Handle;
> > +  EFI_SMM_ACCESS2_PROTOCOL        SmmAccess;
> > +
> > +  ///
> > +  /// Local Data for SMM Access interface goes here
> > +  ///
> > +  UINTN                           NumberRegions;
> > +  EFI_SMRAM_DESCRIPTOR            *SmramDesc;
> > +} SMM_ACCESS_PRIVATE_DATA;
> > +
> > +#define SMM_ACCESS_PRIVATE_DATA_FROM_THIS(a) \
> > +  CR (a, \
> > +      SMM_ACCESS_PRIVATE_DATA, \
> > +      SmmAccess, \
> > +      SMM_ACCESS_PRIVATE_DATA_SIGNATURE \
> > +      )
> > +
> > +//
> > +// Prototypes
> > +// Driver model protocol interface
> > +//
> > +/**
> > +  <b>SMM Access Driver Entry Point</b>
> > +  This driver installs an SMM Access Protocol
> > +  - <b>Introduction</b> \n
> > +    This module publishes the SMM access protocol.  The protocol is used
> by
> > the SMM Base driver to access the SMRAM region when the processor is
> not
> > in SMM.
> > +    The SMM Base driver uses the services provided by the SMM access
> > protocol to open SMRAM during post and copy the SMM handler.
> > +    SMM access protocol is also used to close the SMRAM region once the
> > copying is done.
> > +    Finally, the SMM access protocol provides services to "Lock" the SMRAM
> > region.
> > +    Please refer the SMM Protocols section in the attached SMM CIS
> > Specification version 0.9 for further details.
> > +    This driver is required if SMM is supported. Proper configuration of
> SMM
> > registers is recommended even if SMM is not supported.
> > +
> > +  - @result
> > +    Publishes the _EFI_SMM_ACCESS_PROTOCOL: Documented in the
> > System
> > + Management Mode Core Interface Specification, available at the URL:
> > + http://www.intel.com/technology/framework/spec.htm
> > +
> > +  - <b>Porting Recommendations</b> \n
> > +    No modification of this module is recommended.  Any modification
> > should be done in compliance with the _EFI_SMM_ACCESS_PROTOCOL
> > protocol definition.
> > +
> > +  @param[in] ImageHandle     - Handle for the image of this driver
> > +  @param[in] SystemTable     - Pointer to the EFI System Table
> > +
> > +  @retval EFI_SUCCESS     - Protocol was installed successfully
> > +  @exception EFI_UNSUPPORTED - Protocol was not installed **/
> > +EFI_STATUS EFIAPI SmmAccessDriverEntryPoint (
> > +  IN EFI_HANDLE         ImageHandle,
> > +  IN EFI_SYSTEM_TABLE   *SystemTable
> > +  );
> > +
> > +/**
> > +  This routine accepts a request to "open" a region of SMRAM.  The
> > +  region could be legacy ABSEG, HSEG, or TSEG near top of physical
> memory.
> > +  The use of "open" means that the memory is visible from all
> > +boot-service
> > +  and SMM agents.
> > +
> > +  @param[in] This                  - Pointer to the SMM Access Interface.
> > +
> > +  @retval EFI_SUCCESS           - The region was successfully opened.
> > +  @retval EFI_DEVICE_ERROR      - The region could not be opened because
> > locked by
> > +                          chipset.
> > +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> > bounds.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Open (
> > +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> > +  );
> > +
> > +/**
> > +  This routine accepts a request to "close" a region of SMRAM.  The
> > +  region could be legacy AB or TSEG near top of physical memory.
> > +  The use of "close" means that the memory is only visible from SMM
> > +agents,
> > +  not from BS or RT code.
> > +
> > +  @param[in] This                  - Pointer to the SMM Access Interface.
> > +
> > +  @retval EFI_SUCCESS           - The region was successfully closed.
> > +  @retval EFI_DEVICE_ERROR      - The region could not be closed because
> > locked by
> > +                            chipset.
> > +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> > bounds.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Close (
> > +  IN EFI_SMM_ACCESS2_PROTOCOL  *This
> > +  );
> > +
> > +/**
> > +  This routine accepts a request to "lock" SMRAM.  The
> > +  region could be legacy AB or TSEG near top of physical memory.
> > +  The use of "lock" means that the memory can no longer be opened
> > +  to BS state..
> > +
> > +  @param[in] This                  - Pointer to the SMM Access Interface.
> > +
> > +  @retval EFI_SUCCESS           - The region was successfully locked.
> > +  @retval EFI_DEVICE_ERROR      - The region could not be locked because
> at
> > least
> > +                          one range is still open.
> > +  @retval EFI_INVALID_PARAMETER - The descriptor index was out of
> > bounds.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Lock (
> > +  IN EFI_SMM_ACCESS2_PROTOCOL *This
> > +  );
> > +
> > +/**
> > +  This routine services a user request to discover the SMRAM
> > +  capabilities of this platform.  This will report the possible
> > +  ranges that are possible for SMRAM access, based upon the
> > +  memory controller capabilities.
> > +
> > +  @param[in] This                  - Pointer to the SMRAM Access Interface.
> > +  @param[in] SmramMapSize          - Pointer to the variable containing size
> of
> > the
> > +                            buffer to contain the description information.
> > +  @param[in] SmramMap              - Buffer containing the data describing
> the
> > Smram
> > +                            region descriptors.
> > +
> > +  @retval EFI_BUFFER_TOO_SMALL  - The user did not provide a sufficient
> > buffer.
> > +  @retval EFI_SUCCESS           - The user provided a sufficiently-sized buffer.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetCapabilities (
> > +  IN CONST EFI_SMM_ACCESS2_PROTOCOL  *This,
> > +  IN OUT UINTN                   *SmramMapSize,
> > +  IN OUT EFI_SMRAM_DESCRIPTOR    *SmramMap
> > +  );
> > +#endif
> > diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> > b/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> > new file mode 100644
> > index 0000000000..b7cb88f6ca
> > --- /dev/null
> > +++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
> > @@ -0,0 +1,32 @@
> > +/** @file
> > +  Header file for SMM Access Driver.
> > +
> > +  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> > +  SPDX-License-Identifier: BSD-2-Clause-Patent
> > +
> > +**/
> > +#ifndef _SMM_ACCESS_H_
> > +#define _SMM_ACCESS_H_
> > +
> > +/**
> > +  This function is to install an SMM Access PPI
> > +  - <b>Introduction</b> \n
> > +    A module to install a PPI for controlling SMM mode memory access
> > basically for S3 resume usage.
> > +
> > +  - @pre
> > +    - _PEI_MASTER_BOOT_MODE_PEIM_PPI: A PPI published by foundation
> > to get bootmode executed earlier.
> > +    - _PEI_PERMANENT_MEMORY_INSTALLED_PPI: a PPI that will be
> installed
> > after memory controller initialization completed to indicate that physical
> > memory is usable after this point.
> > +
> > +  - @result
> > +    Publish _PEI_SMM_ACCESS_PPI.
> > +
> > +    @retval EFI_SUCCESS           - Ppi successfully started and installed.
> > +    @retval EFI_NOT_FOUND         - Ppi can't be found.
> > +    @retval EFI_OUT_OF_RESOURCES  - Ppi does not have enough
> resources
> > to initialize the driver.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +PeiInstallSmmAccessPpi (
> > +  VOID
> > +  );
> > +#endif
> > --
> > 2.16.2.windows.1
> >
> >
> > 


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-08-27  7:01 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-08-26  6:13 [PATCH v2] IntelSiliconPkg/Feature Implement SmmAccess Marc W Chen
2019-08-26 16:52 ` Ni, Ray
2019-08-27  6:21 ` [edk2-devel] " Zeng, Star
2019-08-27  7:01   ` Marc W Chen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox