public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Benjamin Doron" <benjamin.doron00@gmail.com>
To: devel@edk2.groups.io
Cc: Guo Dong <guo.dong@intel.com>, Ray Ni <ray.ni@intel.com>,
	Sean Rhodes <sean@starlabs.systems>,
	James Lu <james.lu@intel.com>, Gua Guo <gua.guo@intel.com>
Subject: [edk2-devel] [PATCH v2 4/4] [WIP] UefiPayloadPkg: Support SMRAMC register
Date: Mon, 11 Dec 2023 17:39:12 -0500	[thread overview]
Message-ID: <20231211223919.1225565-4-benjamin.doron00@gmail.com> (raw)
In-Reply-To: <20231211223919.1225565-1-benjamin.doron00@gmail.com>

From: Benjamin Doron <benjamin.doron@9elements.com>

Former Intel platforms controlled SMRAM protection using a dedicated
register.

SlimBootloader-supported platforms have converged on the SMRR, but for
coreboot to support prior platforms too, lock-down is advised.

Requires testing.

TODO: It is more correct to install a handler in SMM to set SPI to
write-protected again, though it's at least assumed secure at present:
as the SMI will not be acknowledged, platform will re-enter SMM.

Cc: Guo Dong <guo.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Sean Rhodes <sean@starlabs.systems>
Cc: James Lu <james.lu@intel.com>
Cc: Gua Guo <gua.guo@intel.com>
Signed-off-by: Benjamin Doron <benjamin.doron@9elements.com>
---
 UefiPayloadPkg/BlSupportSmm/BlSupportSmm.c        |  29 ++++++
 UefiPayloadPkg/BlSupportSmm/BlSupportSmm.inf      |   1 +
 UefiPayloadPkg/Include/Guid/SmmRegisterInfoGuid.h |   1 +
 UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c        | 103 +++++++++++++++++++-
 UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h        |   1 +
 UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf      |   2 +
 6 files changed, 136 insertions(+), 1 deletion(-)

diff --git a/UefiPayloadPkg/BlSupportSmm/BlSupportSmm.c b/UefiPayloadPkg/BlSupportSmm/BlSupportSmm.c
index 0d16aec8ef70..48e7ff9ad044 100644
--- a/UefiPayloadPkg/BlSupportSmm/BlSupportSmm.c
+++ b/UefiPayloadPkg/BlSupportSmm/BlSupportSmm.c
@@ -6,6 +6,8 @@
   writting 0xB2 port with given value from SMM communication area.
   The paylaod SMM handler got chance to restore regs in S3 path.
 
+  Global TODO: Install SMI handler to handle SPI write-protect.
+
   Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
@@ -13,9 +15,14 @@
 
 #include <BlSupportSmm.h>
 
+#define B_SA_SMRAMC_D_LCK_MASK     (0x10)
+#define B_SA_SMRAMC_D_CLS_MASK     (0x20)
+#define B_SA_SMRAMC_D_OPEN_MASK    (0x40)
+
 PLD_S3_COMMUNICATION            mPldS3Hob;
 EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *mSmramHob         = NULL;
 PLD_SMM_REGISTERS               *mSmmRegisterHob   = NULL;
+UINT32                          mSmramcAddress = 0xFFFFFFFF;
 UINT64                          mSmmFeatureControl = 0;
 
 /**
@@ -185,6 +192,20 @@ SmmFeatureLockOnS3 (
   mSmmFeatureControl = AsmReadMsr64 (MSR_SMM_FEATURE_CONTROL);
 }
 
+/**
+  Set SMRAMC, if supported, on S3 path.
+
+**/
+VOID
+SetSmramcOnS3 (
+  VOID
+  )
+{
+  if (mSmramcAddress != 0xFFFFFFFF) {
+    PciOr8 (mSmramcAddress, B_SA_SMRAMC_D_LCK_MASK);
+  }
+}
+
 /**
   Function to program SMRR base and mask.
 
@@ -299,6 +320,7 @@ BlSwSmiHandler (
   )
 {
   SetSmrrOnS3 ();
+  SetSmramcOnS3 ();
   SmmFeatureLockOnS3 ();
   LockSmiGlobalEn ();
 
@@ -353,6 +375,7 @@ BlSupportSmm (
   EFI_HANDLE                     SwHandle;
   EFI_HOB_GUID_TYPE              *GuidHob;
   VOID                           *SmmHob;
+  PLD_GENERIC_REGISTER           *SmramcReg;
   VOID                           *Registration;
 
   //
@@ -399,6 +422,12 @@ BlSupportSmm (
     }
 
     CopyMem (mSmmRegisterHob, SmmHob, GET_GUID_HOB_DATA_SIZE (GuidHob));
+
+    SmramcReg = GetRegisterById (REGISTER_ID_SMRAMC);
+    if (SmramcReg != NULL) {
+      DEBUG ((DEBUG_INFO, "SMRAMC reg found.\n"));
+      mSmramcAddress = SmramcReg->Address.Address;
+    }
   } else {
     return EFI_NOT_FOUND;
   }
diff --git a/UefiPayloadPkg/BlSupportSmm/BlSupportSmm.inf b/UefiPayloadPkg/BlSupportSmm/BlSupportSmm.inf
index 75d4777971fc..a92a971f7c49 100644
--- a/UefiPayloadPkg/BlSupportSmm/BlSupportSmm.inf
+++ b/UefiPayloadPkg/BlSupportSmm/BlSupportSmm.inf
@@ -33,6 +33,7 @@
   MemoryAllocationLib
   BaseLib
   IoLib
+  PciLib
   HobLib
 
 [Guids]
diff --git a/UefiPayloadPkg/Include/Guid/SmmRegisterInfoGuid.h b/UefiPayloadPkg/Include/Guid/SmmRegisterInfoGuid.h
index 665eaa7e7729..feeb984b9f9b 100644
--- a/UefiPayloadPkg/Include/Guid/SmmRegisterInfoGuid.h
+++ b/UefiPayloadPkg/Include/Guid/SmmRegisterInfoGuid.h
@@ -27,6 +27,7 @@ typedef EFI_ACPI_3_0_GENERIC_ADDRESS_STRUCTURE PLD_GENERIC_ADDRESS;
 #define REGISTER_ID_SMI_EOS          3
 #define REGISTER_ID_SMI_APM_EN       4
 #define REGISTER_ID_SMI_APM_STS      5
+#define REGISTER_ID_SMRAMC           6
 
 #pragma pack(1)
 typedef struct {
diff --git a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c
index acb07192f714..919a47bdde7e 100644
--- a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c
+++ b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.c
@@ -7,8 +7,14 @@
 **/
 
 #include "SmmAccessDxe.h"
+#include <Library/PciLib.h>
+
+#define B_SA_SMRAMC_D_LCK_MASK     (0x10)
+#define B_SA_SMRAMC_D_CLS_MASK     (0x20)
+#define B_SA_SMRAMC_D_OPEN_MASK    (0x40)
 
 SMM_ACCESS_PRIVATE_DATA  mSmmAccess;
+UINT32  mSmramcAddress = 0xFFFFFFFF;
 
 /**
    Update region state from SMRAM description
@@ -53,6 +59,8 @@ Open (
   IN EFI_SMM_ACCESS2_PROTOCOL  *This
   )
 {
+  UINT8  SmramControl;
+
   if ((mSmmAccess.SmmRegionState & EFI_SMRAM_LOCKED) != 0) {
     //
     // Cannot open a "locked" region
@@ -61,13 +69,33 @@ Open (
     return EFI_DEVICE_ERROR;
   }
 
+  //
+  // Chipset code
+  //
+  if (mSmramcAddress != 0xFFFFFFFF) {
+    SmramControl = PciRead8 (mSmramcAddress);
+
+    // Cannot open locked region
+    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
+      mSmmAccess.SmmRegionState |= EFI_SMRAM_LOCKED;
+      SyncRegionState2SmramDesc (TRUE, EFI_SMRAM_LOCKED);
+
+      DEBUG ((DEBUG_WARN, "Cannot open a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+
+    SmramControl |= B_SA_SMRAMC_D_OPEN_MASK;
+    SmramControl &= ~(B_SA_SMRAMC_D_CLS_MASK);
+    PciWrite8 (mSmramcAddress, SmramControl);
+  }
+
   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;
 }
 
@@ -91,6 +119,8 @@ Close (
   IN EFI_SMM_ACCESS2_PROTOCOL  *This
   )
 {
+  UINT8  SmramControl;
+
   if ((mSmmAccess.SmmRegionState & EFI_SMRAM_LOCKED) != 0) {
     //
     // Cannot close a "locked" region
@@ -103,6 +133,25 @@ Close (
     return EFI_DEVICE_ERROR;
   }
 
+  //
+  // Chipset code
+  //
+  if (mSmramcAddress != 0xFFFFFFFF) {
+    SmramControl = PciRead8 (mSmramcAddress);
+
+    // Cannot open locked region
+    if ((SmramControl & B_SA_SMRAMC_D_LCK_MASK) != 0) {
+      mSmmAccess.SmmRegionState |= EFI_SMRAM_LOCKED;
+      SyncRegionState2SmramDesc (TRUE, EFI_SMRAM_LOCKED);
+
+      DEBUG ((DEBUG_WARN, "Cannot close a locked SMRAM region\n"));
+      return EFI_DEVICE_ERROR;
+    }
+
+    SmramControl &= ~(B_SA_SMRAMC_D_OPEN_MASK);
+    PciWrite8 (mSmramcAddress, SmramControl);
+  }
+
   mSmmAccess.SmmRegionState &= ~EFI_SMRAM_OPEN;
   SyncRegionState2SmramDesc (FALSE, (UINT64)(UINTN)(~EFI_SMRAM_OPEN));
 
@@ -142,6 +191,14 @@ Lock (
   mSmmAccess.SmmRegionState |= EFI_SMRAM_LOCKED;
   SyncRegionState2SmramDesc (TRUE, EFI_SMRAM_LOCKED);
   mSmmAccess.SmmAccess.LockState = TRUE;
+
+  //
+  // Chipset code
+  //
+  if (mSmramcAddress != 0xFFFFFFFF) {
+    PciOr8 (mSmramcAddress, B_SA_SMRAMC_D_LCK_MASK);
+  }
+
   return EFI_SUCCESS;
 }
 
@@ -184,6 +241,33 @@ GetCapabilities (
   return Status;
 }
 
+/**
+  Get specified SMI register based on given register ID
+
+  @param[in]  SmmRegister  SMI related register array from bootloader
+  @param[in]  Id           The register ID to get.
+
+  @retval NULL             The register is not found
+  @return smi register
+
+**/
+PLD_GENERIC_REGISTER *
+GetRegisterById (
+  PLD_SMM_REGISTERS  *SmmRegisters,
+  UINT64             Id
+  )
+{
+  UINT32  Index;
+
+  for (Index = 0; Index < SmmRegisters->Count; Index++) {
+    if (SmmRegisters->Registers[Index].Id == Id) {
+      return &SmmRegisters->Registers[Index];
+    }
+  }
+
+  return NULL;
+}
+
 /**
   This function installs EFI_SMM_ACCESS_PROTOCOL.
 
@@ -206,6 +290,8 @@ SmmAccessEntryPoint (
   UINT32                          SmmRegionNum;
   EFI_SMRAM_HOB_DESCRIPTOR_BLOCK  *SmramHob;
   UINT32                          Index;
+  PLD_SMM_REGISTERS               *SmmRegisters;
+  PLD_GENERIC_REGISTER            *SmramcReg;
 
   //
   // Get SMRAM info HOB
@@ -239,6 +325,21 @@ SmmAccessEntryPoint (
     mSmmAccess.SmramDesc[Index].RegionState |= EFI_SMRAM_CLOSED | EFI_CACHEABLE;
   }
 
+  //
+  // Some platforms require to open/close SMRAMC register
+  // Supports PCH, not ICH (QEMU)
+  //
+  GuidHob = GetFirstGuidHob (&gSmmRegisterInfoGuid);
+  if (GuidHob != NULL) {
+    SmmRegisters = GET_GUID_HOB_DATA (GuidHob);
+
+    SmramcReg = GetRegisterById (SmmRegisters, REGISTER_ID_SMRAMC);
+    if (SmramcReg != NULL) {
+      DEBUG ((DEBUG_INFO, "SMRAMC reg found.\n"));
+      mSmramcAddress = SmramcReg->Address.Address;
+    }
+  }
+
   mSmmAccess.Signature                 = SMM_ACCESS_PRIVATE_DATA_SIGNATURE;
   mSmmAccess.NumberRegions             = SmmRegionNum;
   mSmmAccess.SmmAccess.Open            = Open;
diff --git a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h
index 51a3cac8c51b..73c50a2f861e 100644
--- a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h
+++ b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.h
@@ -18,6 +18,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
 #include <Library/MemoryAllocationLib.h>
 #include <Library/BaseMemoryLib.h>
 #include <Guid/SmramMemoryReserve.h>
+#include <Guid/SmmRegisterInfoGuid.h>
 
 #define  SMM_ACCESS_PRIVATE_DATA_SIGNATURE  SIGNATURE_32 ('S', 'M', 'M', 'A')
 
diff --git a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf
index aac5ee8f28dc..bff15bc0989a 100644
--- a/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf
+++ b/UefiPayloadPkg/SmmAccessDxe/SmmAccessDxe.inf
@@ -40,9 +40,11 @@
   BaseMemoryLib
   MemoryAllocationLib
   HobLib
+  PciLib
 
 [Guids]
   gEfiSmmSmramMemoryGuid
+  gSmmRegisterInfoGuid
 
 [Protocols]
   gEfiSmmAccess2ProtocolGuid                    ## PRODUCES
-- 
2.43.0



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#112339): https://edk2.groups.io/g/devel/message/112339
Mute This Topic: https://groups.io/mt/103119572/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



      parent reply	other threads:[~2023-12-11 22:39 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-12-11 22:39 [edk2-devel] [PATCH v2 1/4] UefiPayloadPkg/SblParseLib: Build SMM feature GUID HOBs from bootloader Benjamin Doron
2023-12-11 22:39 ` [edk2-devel] [PATCH v2 2/4] UefiPayloadPkg: Introduce coreboot FMAP parser library Benjamin Doron
2023-12-11 22:39 ` [edk2-devel] [PATCH v2 3/4] [WIP] UefiPayloadPkg/CbParseLib: Initial coreboot support for SMM payload Benjamin Doron
2023-12-11 22:39 ` Benjamin Doron [this message]

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=20231211223919.1225565-4-benjamin.doron00@gmail.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