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]
-=-=-=-=-=-=-=-=-=-=-=-
prev 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