* [edk2-platforms:PATCH v4] IntelSiliconPkg/Feature Implement SmmAccess
@ 2019-08-27 8:54 Marc W Chen
0 siblings, 0 replies; only message in thread
From: Marc W Chen @ 2019-08-27 8:54 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 | 339 +++++++++++++++++++++
.../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 | 28 ++
6 files changed, 881 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..da141cfa0e
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAccessLib/PeiSmmAccessLib.c
@@ -0,0 +1,339 @@
+/** @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.
+
+ - @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..f658bac68c
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/SmmAccessLib.h
@@ -0,0 +1,28 @@
+/** @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_LIB_H_
+#define _SMM_ACCESS_LIB_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.
+
+ - @result
+ Publish _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
+ );
+#endif
--
2.16.2.windows.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2019-08-27 8:54 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-08-27 8:54 [edk2-platforms:PATCH v4] IntelSiliconPkg/Feature Implement SmmAccess 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