From: "Ni, Ray" <ray.ni@intel.com>
To: "Chaganty, Rangasai V" <rangasai.v.chaganty@intel.com>,
"Chen, Marc W" <marc.w.chen@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Subject: Re: [edk2-platforms:PATCH] Intel/IntelSiliconPkg Implement SmmAccess in IntelSiliconPkg
Date: Fri, 23 Aug 2019 21:02:44 +0000 [thread overview]
Message-ID: <734D49CCEBEEF84792F5B80ED585239D5C296BCB@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <BCAAFC0A0683754C9A88D2C4E3F3A9C7ECEF3C44@fmsmsx104.amr.corp.intel.com>
It's not recommended to make IntelSiliconPkg depend on MdeModulePkg.
> -----Original Message-----
> From: Chaganty, Rangasai V
> Sent: Friday, August 23, 2019 11:34 AM
> To: Chen, Marc W <marc.w.chen@intel.com>; devel@edk2.groups.io
> Cc: Ni, Ray <ray.ni@intel.com>
> Subject: RE: [edk2-platforms:PATCH] Intel/IntelSiliconPkg Implement SmmAccess in IntelSiliconPkg
>
> May I know the reason to implement the SmmAccessLib instance under \Feature folder?
> Can we move it under IntelSiliconPkg\Library (We need to create a library folder in the root) and keep just the module in the
> \Feature folder?
>
> I've noticed there is a dependency on MdeModulePkg with this change.
> Could you provide the reason to have such dependency as part of this change?
>
> Thanks,
> Sai
>
> -----Original Message-----
> From: Chen, Marc W
> Sent: Friday, August 23, 2019 3:28 AM
> 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-platforms:PATCH] Intel/IntelSiliconPkg Implement SmmAccess in IntelSiliconPkg
>
> 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 | 42 +++
> .../Feature/SmmAccess/SmmAccessDxe/SmmAccess.inf | 47 +++
> .../SmmAccess/SmmAccessDxe/SmmAccessDriver.c | 267 ++++++++++++++++
> .../SmmAccess/SmmAccessDxe/SmmAccessDriver.h | 160 ++++++++++
> .../IntelSiliconPkg/Include/Library/SmmAccessLib.h | 32 ++
> 6 files changed, 891 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..88eb217d2a
> --- /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/SmmAccess.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;
> + PEI_SMM_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 PEI_SMM_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 PEI_SMM_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 PEI_SMM_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 PEI_SMM_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 _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
> + )
> +{
> + 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 = &gPeiSmmAccessPpiGuid;
> + 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..0c6f5f65d8
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/Library/PeiSmmAcce
> +++ ssLib/PeiSmmAccessLib.inf
> @@ -0,0 +1,42 @@
> +## @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
> +MdeModulePkg/MdeModulePkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +
> +[Sources]
> +PeiSmmAccessLib.c
> +
> +
> +[Ppis]
> +gPeiSmmAccessPpiGuid ## 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..b1c988844f
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Feature/SmmAccess/SmmAccessDxe/SmmAc
> +++ cess.inf
> @@ -0,0 +1,47 @@
> +## @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
> +MdeModulePkg/MdeModulePkg.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/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/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/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
next prev parent reply other threads:[~2019-08-23 21:02 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-23 10:27 [edk2-platforms:PATCH] Intel/IntelSiliconPkg Implement SmmAccess in IntelSiliconPkg Marc W Chen
2019-08-23 18:33 ` Chaganty, Rangasai V
2019-08-23 21:02 ` Ni, Ray [this message]
2019-08-24 6:25 ` Marc W Chen
2019-08-25 23:15 ` Ni, Ray
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=734D49CCEBEEF84792F5B80ED585239D5C296BCB@SHSMSX104.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox