From: "Guo Dong" <guo.dong@intel.com>
To: devel@edk2.groups.io
Cc: ray.ni@intel.com, maurice.ma@intel.com, benjamin.you@intel.com,
Guo Dong <guo.dong@intel.com>
Subject: [`edk2-devel][PATCH 1/8] UefiPayloadPkg: Add a common SmmAccessDxe module
Date: Sat, 25 Sep 2021 16:05:23 -0700 [thread overview]
Message-ID: <20210925230530.861-2-guo.dong@intel.com> (raw)
In-Reply-To: <20210925230530.861-1-guo.dong@intel.com>
From: Guo Dong <guo.dong@intel.com>
SmmAccessDxe module would consume EFI_SMRAM_HOB_DESCRIPTOR_BLOCK HOB to
produce SMM access protocol gEfiSmmAccess2ProtocolGuid (open, close, lock,
and GetCapabilities.)
Signed-off-by: Guo Dong <guo.dong@intel.com>
---
UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c | 254 +++++++++++++++++++
UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h | 38 +++
UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf | 51 ++++
3 files changed, 343 insertions(+)
create mode 100644 UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c
create mode 100644 UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h
create mode 100644 UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf
diff --git a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c
new file mode 100644
index 0000000000..ad75c6a2d9
--- /dev/null
+++ b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c
@@ -0,0 +1,254 @@
+/** @file
+ This driver publishes the SMM Access 2 Protocol.
+
+ Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "SmmAccessDxe.h"
+
+SMM_ACCESS_PRIVATE_DATA mSmmAccess;
+
+/**
+ Update region state from SMRAM description
+
+ @param[in] OrLogic Indicate to use OR if ture or AND if false.
+ @param[in] Value The value to set to region state based on OrLogic.
+
+**/
+VOID
+SyncRegionState2SmramDesc(
+ IN BOOLEAN OrLogic,
+ IN UINT64 Value
+ )
+{
+ UINT32 Index;
+
+ for (Index = 0; Index < mSmmAccess.NumberRegions; Index++) {
+ if (OrLogic) {
+ mSmmAccess.SmramDesc[Index].RegionState |= Value;
+ } else {
+ mSmmAccess.SmramDesc[Index].RegionState &= Value;
+ }
+ }
+}
+
+/**
+ 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 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
+ )
+{
+ if ((mSmmAccess.SmmRegionState & EFI_SMRAM_LOCKED) != 0) {
+ //
+ // Cannot open a "locked" region
+ //
+ DEBUG ((DEBUG_INFO, "Cannot open the locked SMRAM Region\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ mSmmAccess.SmmRegionState &= ~(EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+ SyncRegionState2SmramDesc(FALSE, (UINT64)(UINTN)(~(EFI_SMRAM_CLOSED | EFI_ALLOCATED)));
+
+ mSmmAccess.SmmRegionState |= EFI_SMRAM_OPEN;
+ SyncRegionState2SmramDesc(TRUE, EFI_SMRAM_OPEN);
+ mSmmAccess.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 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
+ )
+{
+ if ((mSmmAccess.SmmRegionState & EFI_SMRAM_LOCKED) != 0) {
+ //
+ // Cannot close a "locked" region
+ //
+ DEBUG ((DEBUG_INFO, "Cannot close the locked SMRAM Region\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ((mSmmAccess.SmmRegionState & EFI_SMRAM_CLOSED) != 0) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ mSmmAccess.SmmRegionState &= ~EFI_SMRAM_OPEN;
+ SyncRegionState2SmramDesc(FALSE, (UINT64)(UINTN)(~EFI_SMRAM_OPEN));
+
+ mSmmAccess.SmmRegionState |= (EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+ SyncRegionState2SmramDesc(TRUE, EFI_SMRAM_CLOSED | EFI_ALLOCATED);
+
+ mSmmAccess.SmmAccess.OpenState = FALSE;
+
+ 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 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
+ )
+{
+ if (mSmmAccess.SmmAccess.OpenState) {
+ DEBUG ((DEBUG_INFO, "Cannot lock SMRAM when it is still open\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ mSmmAccess.SmmRegionState |= EFI_SMRAM_LOCKED;
+ SyncRegionState2SmramDesc(TRUE, EFI_SMRAM_LOCKED);
+ mSmmAccess.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 This Pointer to the SMRAM Access Interface.
+ @param SmramMapSize Pointer to the variable containing size of the
+ buffer to contain the description information.
+ @param 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;
+ UINTN NecessaryBufferSize;
+
+ NecessaryBufferSize = mSmmAccess.NumberRegions * sizeof(EFI_SMRAM_DESCRIPTOR);
+ if (*SmramMapSize < NecessaryBufferSize) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ } else {
+ CopyMem(SmramMap, mSmmAccess.SmramDesc, NecessaryBufferSize);
+ Status = EFI_SUCCESS;
+ }
+
+ *SmramMapSize = NecessaryBufferSize;
+ return Status;
+}
+
+/**
+ This function installs EFI_SMM_ACCESS_PROTOCOL.
+
+ @param ImageHandle Handle for the image of this driver
+ @param SystemTable Pointer to the EFI System Table
+
+ @retval EFI_UNSUPPORTED There's no Intel ICH on this platform
+ @return The status returned from InstallProtocolInterface().
+
+**/
+EFI_STATUS
+EFIAPI
+SmmAccessEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ UINT32 SmmRegionNum;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *SmramHob;
+ UINT32 Index;
+
+ //
+ // Get SMRAM info HOB
+ //
+ GuidHob = GetFirstGuidHob (&gEfiSmmSmramMemoryGuid);
+ if (GuidHob == NULL) {
+ DEBUG ((DEBUG_INFO, "SMRAM HOB NOT found\n"));
+ return EFI_NOT_FOUND;
+ }
+ SmramHob = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *) GET_GUID_HOB_DATA(GuidHob);
+ SmmRegionNum = SmramHob->NumberOfSmmReservedRegions;
+ mSmmAccess.SmramDesc = AllocateZeroPool (sizeof (EFI_SMRAM_DESCRIPTOR) * SmmRegionNum);
+ if (mSmmAccess.SmramDesc == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ CopyMem (mSmmAccess.SmramDesc, &SmramHob->Descriptor, sizeof (EFI_SMRAM_DESCRIPTOR) * SmmRegionNum);
+
+ DEBUG ((DEBUG_INFO, "NumberOfSmmReservedRegions = 0x%x\n", SmmRegionNum));
+ for (Index = 0; Index < SmmRegionNum; Index++) {
+ DEBUG ((DEBUG_INFO, "%d: base=0x%x, size = 0x%x, State=0x%x\n",Index,
+ SmramHob->Descriptor[Index].PhysicalStart,
+ SmramHob->Descriptor[Index].PhysicalSize,
+ SmramHob->Descriptor[Index].RegionState));
+ mSmmAccess.SmramDesc[Index].RegionState &= EFI_ALLOCATED;
+ mSmmAccess.SmramDesc[Index].RegionState |= EFI_SMRAM_CLOSED | EFI_CACHEABLE;
+ }
+
+ mSmmAccess.Signature = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
+ mSmmAccess.NumberRegions = SmmRegionNum;
+ mSmmAccess.SmmAccess.Open = Open;
+ mSmmAccess.SmmAccess.Close = Close;
+ mSmmAccess.SmmAccess.Lock = Lock;
+ mSmmAccess.SmmAccess.GetCapabilities = GetCapabilities;
+ mSmmAccess.SmmAccess.LockState = FALSE;
+ mSmmAccess.SmmAccess.OpenState = FALSE;
+ mSmmAccess.SmmRegionState = EFI_SMRAM_CLOSED;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &mSmmAccess.Handle,
+ &gEfiSmmAccess2ProtocolGuid,
+ &mSmmAccess.SmmAccess,
+ NULL
+ );
+
+ return Status;
+}
diff --git a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h
new file mode 100644
index 0000000000..7b64c0afcb
--- /dev/null
+++ b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h
@@ -0,0 +1,38 @@
+/** @file
+ The header file of SMM access DXE.
+
+Copyright (c) 2014 - 2021, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _SMM_ACCESS_DRIVER_H
+#define _SMM_ACCESS_DRIVER_H
+
+#include <PiDxe.h>
+#include <Protocol/SmmAccess2.h>
+//#include <Protocol/SmmControl2.h>
+#include <Library/HobLib.h>
+#include <Library/BaseLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Guid/SmramMemoryReserve.h>
+
+
+#define SMM_ACCESS_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('S', 'M', 'M', 'A')
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_SMM_ACCESS2_PROTOCOL SmmAccess;
+ //
+ // Local Data for SMM Access interface goes here
+ //
+ UINT32 SmmRegionState;
+ UINT32 NumberRegions;
+ EFI_SMRAM_DESCRIPTOR *SmramDesc;
+} SMM_ACCESS_PRIVATE_DATA;
+
+#endif
diff --git a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf
new file mode 100644
index 0000000000..aac5ee8f28
--- /dev/null
+++ b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf
@@ -0,0 +1,51 @@
+## @file
+# SMM Access 2 Protocol Dxe Driver
+#
+# This module produces the SMM Access 2 Protocol.
+#
+# Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SmmAccessDxe
+ FILE_GUID = 47579CF5-1E4F-4b41-99BB-A5C334846D3B
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = SmmAccessEntryPoint
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ SmmAccessDxe.c
+ SmmAccessDxe.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ UefiBootServicesTableLib
+ DebugLib
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ HobLib
+
+[Guids]
+ gEfiSmmSmramMemoryGuid
+
+[Protocols]
+ gEfiSmmAccess2ProtocolGuid ## PRODUCES
+
+[Depex]
+ TRUE
--
2.32.0.windows.2
next prev parent reply other threads:[~2021-09-25 23:05 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-09-25 23:05 [`edk2-devel][PATCH 0/8] Add SMM variable support for UEFI payload Guo Dong
2021-09-25 23:05 ` Guo Dong [this message]
2021-09-25 23:05 ` [`edk2-devel][PATCH 2/8] UefiPayloadPkg: Add a common SMM control Runtime DXE module Guo Dong
2021-09-25 23:05 ` [`edk2-devel][PATCH 3/8] UefiPayloadPkg: Add bootloader SMM support module Guo Dong
2021-09-25 23:05 ` [`edk2-devel][PATCH 4/8] UefiPayloadPkg: Add SpiFlashLib Guo Dong
2021-09-25 23:05 ` [`edk2-devel][PATCH 5/8] UefiPayloadPkg: Add FlashDeviceLib Guo Dong
2021-09-25 23:05 ` [`edk2-devel][PATCH 6/8] UefiPayloadPkg: Add a common FVB SMM module Guo Dong
2021-09-25 23:05 ` [`edk2-devel][PATCH 7/8] UefiPayloadPkg: Add a SMM dispatch module Guo Dong
2021-09-25 23:05 ` [`edk2-devel][PATCH 8/8] UefiPayloadPkg: Add SMM support and SMM variable support Guo Dong
2021-09-30 0:11 ` [`edk2-devel][PATCH 0/8] Add SMM variable support for UEFI payload 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=20210925230530.861-2-guo.dong@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