* [edk2-devel] [PATCH v1 1/4] UefiPayloadPkg/SblParseLib: Build SMM feature GUID HOBs from bootloader
@ 2023-12-11 22:37 Benjamin Doron
2023-12-11 22:37 ` [edk2-devel] [PATCH v1 2/4] UefiPayloadPkg: Introduce coreboot FMAP parser library Benjamin Doron
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Benjamin Doron @ 2023-12-11 22:37 UTC (permalink / raw)
To: devel; +Cc: Guo Dong, Ray Ni, Sean Rhodes, James Lu, Gua Guo
From: Benjamin Doron <benjamin.doron@9elements.com>
UefiPayload does not install all SBL HOBs, EDK2-relevant ones must be
installed individually. This was omitted from the SMM feature pushes.
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/Library/SblParseLib/SblParseLib.c | 77 ++++++++++++++++++++
UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf | 5 ++
2 files changed, 82 insertions(+)
diff --git a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c
index d88238bfdccb..9775ad4ac2a6 100644
--- a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c
+++ b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.c
@@ -15,6 +15,11 @@
#include <Library/HobLib.h>
#include <Library/BlParseLib.h>
#include <IndustryStandard/Acpi.h>
+#include <Guid/SmmRegisterInfoGuid.h>
+#include <Guid/SmramMemoryReserve.h>
+#include <Guid/SpiFlashInfoGuid.h>
+#include <Guid/NvVariableInfoGuid.h>
+#include <Guid/SmmS3CommunicationInfoGuid.h>
#include <UniversalPayload/PciRootBridges.h>
/**
@@ -264,6 +269,17 @@ ParseMiscInfo (
RETURN_STATUS Status;
UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *BlRootBridgesHob;
UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PldRootBridgesHob;
+ // TODO: Drop half by ignoring return?
+ PLD_SMM_REGISTERS *BlSmmRegisters;
+ PLD_SMM_REGISTERS *PldSmmRegisters;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *BlSmramHob;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *PldSmramHob;
+ SPI_FLASH_INFO *BlSpiFlashInfo;
+ SPI_FLASH_INFO *PldSpiFlashInfo;
+ NV_VARIABLE_INFO *BlNvVariableInfo;
+ NV_VARIABLE_INFO *PldNvVariableInfo;
+ PLD_S3_COMMUNICATION *BlS3Communication;
+ PLD_S3_COMMUNICATION *PldS3Communication;
Status = RETURN_NOT_FOUND;
BlRootBridgesHob = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GetGuidHobDataFromSbl (
@@ -287,5 +303,66 @@ ParseMiscInfo (
}
}
+ // Perhaps payload does not perform SMM, do not override Status
+ BlSmmRegisters = GetGuidHobDataFromSbl (&gSmmRegisterInfoGuid);
+ if (BlSmmRegisters != NULL) {
+ PldSmmRegisters = BuildGuidDataHob (
+ &gSmmRegisterInfoGuid,
+ BlSmmRegisters,
+ sizeof (PLD_SMM_REGISTERS) + (BlSmmRegisters->Count * sizeof (PLD_GENERIC_REGISTER))
+ );
+ if (PldSmmRegisters != NULL) {
+ DEBUG ((DEBUG_INFO, "Create SMM register info guid hob\n"));
+ }
+ }
+
+ BlSmramHob = GetGuidHobDataFromSbl (&gEfiSmmSmramMemoryGuid);
+ if (BlSmramHob != NULL) {
+ PldSmramHob = BuildGuidDataHob (
+ &gEfiSmmSmramMemoryGuid,
+ BlSmramHob,
+ sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + ((BlSmramHob->number_of_smm_regions - 1) * sizeof (EFI_SMRAM_DESCRIPTOR))
+ );
+ if (PldSmramHob != NULL) {
+ DEBUG ((DEBUG_INFO, "Create SMM SMRAM memory info guid hob\n"));
+ }
+ }
+
+ BlSpiFlashInfo = GetGuidHobDataFromSbl (&gSpiFlashInfoGuid);
+ if (BlSpiFlashInfo != NULL) {
+ PldSpiFlashInfo = BuildGuidDataHob (
+ &gSpiFlashInfoGuid,
+ BlSpiFlashInfo,
+ sizeof (SPI_FLASH_INFO)
+ );
+ if (PldSpiFlashInfo != NULL) {
+ DEBUG ((DEBUG_INFO, "Create SPI flash info guid hob\n"));
+ }
+ }
+
+ BlNvVariableInfo = GetGuidHobDataFromSbl (&gNvVariableInfoGuid);
+ if (BlNvVariableInfo != NULL) {
+ PldNvVariableInfo = BuildGuidDataHob (
+ &gNvVariableInfoGuid,
+ BlNvVariableInfo,
+ sizeof (NV_VARIABLE_INFO)
+ );
+ if (PldNvVariableInfo != NULL) {
+ DEBUG ((DEBUG_INFO, "Create NV variable info guid hob\n"));
+ }
+ }
+
+ BlS3Communication = GetGuidHobDataFromSbl (&gS3CommunicationGuid);
+ if (BlS3Communication != NULL) {
+ PldS3Communication = BuildGuidDataHob (
+ &gS3CommunicationGuid,
+ BlS3Communication,
+ sizeof (PLD_S3_COMMUNICATION)
+ );
+ if (PldS3Communication != NULL) {
+ DEBUG ((DEBUG_INFO, "Create S3 communication guid hob\n"));
+ }
+ }
+
return Status;
}
diff --git a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf
index f83a10ccd826..1c77d86a8643 100644
--- a/UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf
+++ b/UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf
@@ -41,6 +41,11 @@
gEfiGraphicsInfoHobGuid
gEfiGraphicsDeviceInfoHobGuid
gUniversalPayloadPciRootBridgeInfoGuid
+ gSmmRegisterInfoGuid
+ gEfiSmmSmramMemoryGuid
+ gSpiFlashInfoGuid
+ gNvVariableInfoGuid
+ gS3CommunicationGuid
[Pcd]
gUefiPayloadPkgTokenSpaceGuid.PcdBootloaderParameter
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [edk2-devel] [PATCH v1 2/4] UefiPayloadPkg: Introduce coreboot FMAP parser library
2023-12-11 22:37 [edk2-devel] [PATCH v1 1/4] UefiPayloadPkg/SblParseLib: Build SMM feature GUID HOBs from bootloader Benjamin Doron
@ 2023-12-11 22:37 ` Benjamin Doron
2023-12-11 22:37 ` [edk2-devel] [PATCH v1 3/4] [WIP] UefiPayloadPkg/CbParseLib: Initial coreboot support for SMM payload Benjamin Doron
2023-12-11 22:37 ` [edk2-devel] [PATCH v1 4/4] [WIP] UefiPayloadPkg: Support SMRAMC register Benjamin Doron
2 siblings, 0 replies; 4+ messages in thread
From: Benjamin Doron @ 2023-12-11 22:37 UTC (permalink / raw)
To: devel; +Cc: Guo Dong, Ray Ni, Sean Rhodes, James Lu, Gua Guo
From: Benjamin Doron <benjamin.doron@9elements.com>
Parse coreboot FMAP structures to find the memory region in SPI flash
by the FMAP area name.
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/Include/Coreboot.h | 21 ++++
UefiPayloadPkg/Include/Library/FmapParserLib.h | 35 +++++++
UefiPayloadPkg/Library/CbFmapParserLib/CbFmapParserLib.c | 104 ++++++++++++++++++++
UefiPayloadPkg/Library/CbFmapParserLib/CbFmapParserLib.inf | 28 ++++++
UefiPayloadPkg/UefiPayloadPkg.dsc | 1 +
5 files changed, 189 insertions(+)
diff --git a/UefiPayloadPkg/Include/Coreboot.h b/UefiPayloadPkg/Include/Coreboot.h
index 2d454f7c893c..6c33dda9ef85 100644
--- a/UefiPayloadPkg/Include/Coreboot.h
+++ b/UefiPayloadPkg/Include/Coreboot.h
@@ -249,6 +249,27 @@ struct cb_cbmem_tab {
UINT64 cbmem_tab;
};
+#define CB_TAG_FMAP 0x0037
+#define FMAP_STRLEN 32 /* includes null-terminator */
+struct fmap_area {
+ UINT32 offset; /* offset relative to base */
+ UINT32 size; /* size in bytes */
+ UINT8 name[FMAP_STRLEN]; /* descriptive name */
+ UINT16 flags; /* flags for this area */
+} __attribute__ ((packed));
+
+struct fmap {
+ UINT8 signature[8]; /* "__FMAP__" (0x5F5F464D41505F5F) */
+ UINT8 ver_major; /* major version */
+ UINT8 ver_minor; /* minor version */
+ UINT64 base; /* address of the firmware binary */
+ UINT32 size; /* size of firmware binary in bytes */
+ UINT8 name[FMAP_STRLEN]; /* name of this firmware binary */
+ UINT16 nareas; /* number of areas described by
+ fmap_areas[] below */
+ struct fmap_area areas[];
+} __attribute__ ((packed));
+
/* Helpful macros */
#define MEM_RANGE_COUNT(_rec) \
diff --git a/UefiPayloadPkg/Include/Library/FmapParserLib.h b/UefiPayloadPkg/Include/Library/FmapParserLib.h
new file mode 100644
index 000000000000..f03b9b22a85b
--- /dev/null
+++ b/UefiPayloadPkg/Include/Library/FmapParserLib.h
@@ -0,0 +1,35 @@
+/** @file
+ Contains helper functions for parsing FMAP.
+
+ Copyright (c) 2023, 9elements GmbH.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiMultiPhase.h>
+#include <Pi/PiMultiPhase.h>
+
+#define FMAP_SIGNATURE "__FMAP__"
+#define FMAP_VER_MAJOR 1
+#define FMAP_VER_MINOR 1
+
+/**
+ Find a requested FMAP area's address and size.
+
+ @param[in] FmapAreaName Name string of FMAP area to find
+ @param[out] FmapAreaAddress Pointer to return of FMAP area memory address
+ @param[out] FmapAreaSize Pointer to return of FMAP area size
+
+ @retval EFI_SUCCESS Successfully found the FMAP area information.
+ @retval EFI_INVALID_PARAMETER Input arguments are invalid.
+ @retval EFI_NOT_FOUND Failed to find the FMAP area information.
+
+**/
+EFI_STATUS
+EFIAPI
+FmapLocateArea (
+ IN CHAR8 *FmapAreaName,
+ IN OUT EFI_PHYSICAL_ADDRESS *FmapAreaAddress,
+ IN OUT UINT32 *FmapAreaSize
+ );
diff --git a/UefiPayloadPkg/Library/CbFmapParserLib/CbFmapParserLib.c b/UefiPayloadPkg/Library/CbFmapParserLib/CbFmapParserLib.c
new file mode 100644
index 000000000000..1a181b7266f0
--- /dev/null
+++ b/UefiPayloadPkg/Library/CbFmapParserLib/CbFmapParserLib.c
@@ -0,0 +1,104 @@
+/** @file
+ Contains helper functions for parsing FMAP.
+
+ Copyright (c) 2023, 9elements GmbH.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/BlParseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/FmapParserLib.h>
+#include <Coreboot.h>
+
+/**
+ Find coreboot record with given Tag.
+ NOTE: This coreboot-specific function definition is absent
+ from the common BlParseLib header.
+
+ @param Tag The tag id to be found
+
+ @retval NULL The Tag is not found.
+ @retval Others The pointer to the record found.
+
+**/
+VOID *
+FindCbTag (
+ IN UINT32 Tag
+ );
+
+/**
+ Find a requested FMAP area's address and size.
+
+ @param[in] FmapAreaName Name string of FMAP area to find
+ @param[out] FmapAreaAddress Pointer to return of FMAP area memory address
+ @param[out] FmapAreaSize Pointer to return of FMAP area size
+
+ @retval EFI_SUCCESS Successfully found the FMAP area information.
+ @retval EFI_INVALID_PARAMETER Input arguments are invalid.
+ @retval EFI_NOT_FOUND Failed to find the FMAP area information.
+
+**/
+EFI_STATUS
+EFIAPI
+FmapLocateArea (
+ IN CHAR8 *FmapAreaName,
+ IN OUT EFI_PHYSICAL_ADDRESS *FmapAreaAddress,
+ IN OUT UINT32 *FmapAreaSize
+ )
+{
+ struct cb_cbmem_ref *CbMemRef;
+ struct fmap *Fmap;
+ UINTN Index;
+
+ //
+ // Perform basic validation
+ //
+ if ((FmapAreaName == NULL) || (FmapAreaAddress == NULL) || (FmapAreaSize == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // FMAP_STRLEN includes sizeof NULL-terminator, so this also too long
+ if (AsciiStrLen (FmapAreaName) >= FMAP_STRLEN) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // The coreboot table contains large structures as references
+ CbMemRef = FindCbTag (CB_TAG_FMAP);
+ if (CbMemRef == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ Fmap = (VOID *)(UINTN)CbMemRef->cbmem_addr; // Support PEI and DXE
+ if (Fmap == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Perform FMAP validation
+ //
+ if ((AsciiStrnCmp ((CHAR8 *)Fmap->signature, FMAP_SIGNATURE, 8) != 0)
+ || (Fmap->ver_major != FMAP_VER_MAJOR) || (Fmap->ver_minor != FMAP_VER_MINOR)) {
+ return EFI_NOT_FOUND;
+ }
+
+ for (Index = 0; Index < Fmap->nareas; Index++) {
+ if (AsciiStrCmp ((CHAR8 *)Fmap->areas[Index].name, FmapAreaName) == 0) {
+ DEBUG ((
+ DEBUG_INFO,
+ "FMAP: Found area \"%a\" at offset 0x%x (size 0x%0x)\n",
+ FmapAreaName,
+ Fmap->areas[Index].offset,
+ Fmap->areas[Index].size
+ ));
+
+ *FmapAreaAddress = Fmap->base + Fmap->areas[Index].offset;
+ *FmapAreaSize = Fmap->areas[Index].size;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
diff --git a/UefiPayloadPkg/Library/CbFmapParserLib/CbFmapParserLib.inf b/UefiPayloadPkg/Library/CbFmapParserLib/CbFmapParserLib.inf
new file mode 100644
index 000000000000..8e64a67614d9
--- /dev/null
+++ b/UefiPayloadPkg/Library/CbFmapParserLib/CbFmapParserLib.inf
@@ -0,0 +1,28 @@
+## @file
+# Contains helper functions for parsing FMAP.
+#
+# Copyright (c) 2023, 9elements GmbH.<BR>
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = CbFmapParserLib
+ FILE_GUID = 6B4EE7FA-413A-445A-91B2-E63F3106FDE3
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = FmapParserLib
+
+[Sources]
+ CbFmapParserLib.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ UefiPayloadPkg/UefiPayloadPkg.dec
+
+[LibraryClasses]
+ BaseLib
+ BlParseLib
+ DebugLib
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc
index 2dbd875f377a..35e2f85a2ba8 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dsc
+++ b/UefiPayloadPkg/UefiPayloadPkg.dsc
@@ -280,6 +280,7 @@
!if $(UNIVERSAL_PAYLOAD) == FALSE
!if $(BOOTLOADER) == "COREBOOT"
BlParseLib|UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf
+ FmapParserLib|UefiPayloadPkg/Library/CbFmapParserLib/CbFmapParserLib.inf
!else
BlParseLib|UefiPayloadPkg/Library/SblParseLib/SblParseLib.inf
!endif
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [edk2-devel] [PATCH v1 3/4] [WIP] UefiPayloadPkg/CbParseLib: Initial coreboot support for SMM payload
2023-12-11 22:37 [edk2-devel] [PATCH v1 1/4] UefiPayloadPkg/SblParseLib: Build SMM feature GUID HOBs from bootloader Benjamin Doron
2023-12-11 22:37 ` [edk2-devel] [PATCH v1 2/4] UefiPayloadPkg: Introduce coreboot FMAP parser library Benjamin Doron
@ 2023-12-11 22:37 ` Benjamin Doron
2023-12-11 22:37 ` [edk2-devel] [PATCH v1 4/4] [WIP] UefiPayloadPkg: Support SMRAMC register Benjamin Doron
2 siblings, 0 replies; 4+ messages in thread
From: Benjamin Doron @ 2023-12-11 22:37 UTC (permalink / raw)
To: devel; +Cc: Guo Dong, Ray Ni, Sean Rhodes, James Lu, Gua Guo
From: Benjamin Doron <benjamin.doron@9elements.com>
To be used with the https://review.coreboot.org/c/coreboot/+/70378
patch-series. Now feature complete, awaiting final upstream feedback
whether generating some data inside coreboot is okay.
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/Include/Coreboot.h | 50 ++++++++
UefiPayloadPkg/Library/CbParseLib/CbParseLib.c | 121 +++++++++++++++++++-
UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf | 9 ++
3 files changed, 179 insertions(+), 1 deletion(-)
diff --git a/UefiPayloadPkg/Include/Coreboot.h b/UefiPayloadPkg/Include/Coreboot.h
index 6c33dda9ef85..add64d9623d9 100644
--- a/UefiPayloadPkg/Include/Coreboot.h
+++ b/UefiPayloadPkg/Include/Coreboot.h
@@ -270,6 +270,56 @@ struct fmap {
struct fmap_area areas[];
} __attribute__ ((packed));
+#define CB_TAG_PLD_SMM_REGISTER_INFO 0x0050
+struct lb_pld_generic_register {
+ UINT8 register_id;
+ UINT8 address_space_id;
+ UINT8 register_bit_width;
+ UINT8 register_bit_offset;
+ UINT32 value;
+ struct cbuint64 address;
+};
+
+struct lb_pld_smm_registers {
+ UINT32 tag;
+ UINT32 size;
+ UINT32 revision;
+ UINT32 count;
+ struct lb_pld_generic_register registers[];
+};
+
+#define CB_TAG_PLD_SMM_SMRAM 0x0051
+struct lb_pld_smram_descriptor {
+ struct cbuint64 physical_start;
+ struct cbuint64 physical_size;
+ struct cbuint64 region_state;
+};
+
+struct lb_pld_smram_descriptor_block {
+ UINT32 tag;
+ UINT32 size;
+ UINT32 number_of_smm_regions;
+ struct lb_pld_smram_descriptor descriptor[1];
+};
+
+#define CB_TAG_PLD_SPI_FLASH_INFO 0x0052
+struct lb_pld_spi_flash_info {
+ UINT32 tag;
+ UINT32 size;
+ UINT16 revision;
+ UINT16 flags;
+ struct lb_pld_generic_register spi_address;
+};
+
+#define CB_TAG_PLD_S3_COMMUNICATION 0x0054
+struct lb_pld_s3_communication {
+ UINT32 tag;
+ UINT32 size;
+ struct lb_pld_smram_descriptor comm_buffer;
+ UINT8 pld_acpi_s3_enable;
+ UINT8 pad[3];
+};
+
/* Helpful macros */
#define MEM_RANGE_COUNT(_rec) \
diff --git a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c
index 8a353f77f635..46b164231fe5 100644
--- a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c
+++ b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.c
@@ -7,15 +7,22 @@
**/
-#include <Uefi/UefiBaseType.h>
+#include <PiPei.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PcdLib.h>
#include <Library/IoLib.h>
+#include <Library/HobLib.h>
#include <Library/BlParseLib.h>
+#include <Library/FmapParserLib.h>
#include <IndustryStandard/Acpi.h>
#include <Coreboot.h>
+#include <Guid/SmmRegisterInfoGuid.h>
+#include <Guid/SmramMemoryReserve.h>
+#include <Guid/SpiFlashInfoGuid.h>
+#include <Guid/NvVariableInfoGuid.h>
+#include <Guid/SmmS3CommunicationInfoGuid.h>
/**
Convert a packed value from cbuint64 to a UINT64 value.
@@ -602,5 +609,117 @@ ParseMiscInfo (
VOID
)
{
+ struct lb_pld_smm_registers *BlSmmRegisters;
+ PLD_SMM_REGISTERS *PldSmmRegisters;
+ UINTN Index;
+ struct lb_pld_smram_descriptor_block *BlSmramInfo;
+ EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *PldSmramHob;
+ struct lb_pld_spi_flash_info *BlSpiFlashInfo;
+ SPI_FLASH_INFO *PldSpiFlashInfo;
+ EFI_PHYSICAL_ADDRESS SmmStoreFmapRegionAddress;
+ UINT32 SmmStoreFmapRegionSize;
+ EFI_STATUS Status;
+ NV_VARIABLE_INFO *PldNvVariableInfo;
+ struct lb_pld_s3_communication *BlS3Communication;
+ PLD_S3_COMMUNICATION *PldS3Communication;
+
+ BlSmmRegisters = FindCbTag (CB_TAG_PLD_SMM_REGISTER_INFO);
+ if (BlSmmRegisters != NULL) {
+ PldSmmRegisters = BuildGuidHob (
+ &gSmmRegisterInfoGuid,
+ sizeof (PLD_SMM_REGISTERS) + (BlSmmRegisters->count * sizeof (PLD_GENERIC_REGISTER))
+ );
+ if (PldSmmRegisters != NULL) {
+ PldSmmRegisters->Revision = BlSmmRegisters->revision;
+
+ PldSmmRegisters->Count = BlSmmRegisters->count;
+ for (Index = 0; Index < BlSmmRegisters->count; Index++) {
+ PldSmmRegisters->Registers[Index].Id = BlSmmRegisters->registers[Index].register_id;
+ PldSmmRegisters->Registers[Index].Address.AddressSpaceId = BlSmmRegisters->registers[Index].address_space_id;
+ PldSmmRegisters->Registers[Index].Address.RegisterBitWidth = BlSmmRegisters->registers[Index].register_bit_width;
+ PldSmmRegisters->Registers[Index].Address.RegisterBitOffset = BlSmmRegisters->registers[Index].register_bit_offset;
+ PldSmmRegisters->Registers[Index].Value = BlSmmRegisters->registers[Index].value;
+ PldSmmRegisters->Registers[Index].Address.Address = cb_unpack64 (BlSmmRegisters->registers[Index].address);
+
+ // Required for UefiPayload implementation compatibility
+ PldSmmRegisters->Registers[Index].Address.AccessSize = EFI_ACPI_3_0_DWORD;
+ }
+
+ DEBUG ((DEBUG_INFO, "Create SMM register info guid hob\n"));
+ }
+ }
+
+ BlSmramInfo = FindCbTag (CB_TAG_PLD_SMM_SMRAM);
+ if (BlSmramInfo != NULL) {
+ PldSmramHob = BuildGuidHob (
+ &gEfiSmmSmramMemoryGuid,
+ sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + ((BlSmramInfo->number_of_smm_regions - 1) * sizeof (EFI_SMRAM_DESCRIPTOR))
+ );
+ if (PldSmramHob != NULL) {
+ PldSmramHob->NumberOfSmmReservedRegions = BlSmramInfo->number_of_smm_regions;
+ for (Index = 0; Index < BlSmramInfo->number_of_smm_regions; Index++) {
+ PldSmramHob->Descriptor[Index].PhysicalStart = cb_unpack64 (BlSmramInfo->descriptor[Index].physical_start);
+ PldSmramHob->Descriptor[Index].CpuStart = cb_unpack64 (BlSmramInfo->descriptor[Index].physical_start);
+ PldSmramHob->Descriptor[Index].PhysicalSize = cb_unpack64 (BlSmramInfo->descriptor[Index].physical_size);
+ PldSmramHob->Descriptor[Index].RegionState = cb_unpack64 (BlSmramInfo->descriptor[Index].region_state);
+ }
+
+ DEBUG ((DEBUG_INFO, "Create SMRAM memory info guid hob\n"));
+ }
+ }
+
+ BlSpiFlashInfo = FindCbTag (CB_TAG_PLD_SPI_FLASH_INFO);
+ if (BlSpiFlashInfo != NULL) {
+ PldSpiFlashInfo = BuildGuidHob (
+ &gSpiFlashInfoGuid,
+ sizeof (SPI_FLASH_INFO)
+ );
+ if (PldSpiFlashInfo != NULL) {
+ PldSpiFlashInfo->Revision = BlSpiFlashInfo->revision;
+ PldSpiFlashInfo->Flags = BlSpiFlashInfo->flags;
+
+ PldSpiFlashInfo->SpiAddress.AddressSpaceId = BlSpiFlashInfo->spi_address.address_space_id;
+ PldSpiFlashInfo->SpiAddress.RegisterBitWidth = BlSpiFlashInfo->spi_address.register_bit_width;
+ PldSpiFlashInfo->SpiAddress.RegisterBitOffset = BlSpiFlashInfo->spi_address.register_bit_offset;
+ PldSpiFlashInfo->SpiAddress.Address = cb_unpack64 (BlSpiFlashInfo->spi_address.address);
+
+ // Required for UefiPayload implementation compatibility
+ PldSpiFlashInfo->SpiAddress.AccessSize = EFI_ACPI_3_0_DWORD;
+
+ DEBUG ((DEBUG_INFO, "Create SPI flash info guid hob\n"));
+ }
+ }
+
+ Status = FmapLocateArea ("SMMSTORE", &SmmStoreFmapRegionAddress, &SmmStoreFmapRegionSize);
+ if (!EFI_ERROR (Status)) {
+ PldNvVariableInfo = BuildGuidHob (
+ &gNvVariableInfoGuid,
+ sizeof (NV_VARIABLE_INFO)
+ );
+ if (PldNvVariableInfo != NULL) {
+ PldNvVariableInfo->Revision = 0;
+ PldNvVariableInfo->VariableStoreBase = (UINT32)SmmStoreFmapRegionAddress;
+ PldNvVariableInfo->VariableStoreSize = SmmStoreFmapRegionSize;
+
+ DEBUG ((DEBUG_INFO, "Create NV variable info guid hob\n"));
+ }
+ }
+
+ BlS3Communication = FindCbTag (CB_TAG_PLD_S3_COMMUNICATION);
+ if (BlS3Communication != NULL) {
+ PldS3Communication = BuildGuidHob (
+ &gS3CommunicationGuid,
+ sizeof (PLD_S3_COMMUNICATION)
+ );
+ if (PldS3Communication != NULL) {
+ PldS3Communication->CommBuffer.PhysicalStart = cb_unpack64 (BlS3Communication->comm_buffer.physical_start);
+ PldS3Communication->CommBuffer.CpuStart = cb_unpack64 (BlS3Communication->comm_buffer.physical_start);
+ PldS3Communication->CommBuffer.PhysicalSize = cb_unpack64 (BlS3Communication->comm_buffer.physical_size);
+ PldS3Communication->PldAcpiS3Enable = BlS3Communication->pld_acpi_s3_enable;
+
+ DEBUG ((DEBUG_INFO, "Create S3 communication info guid hob\n"));
+ }
+ }
+
return RETURN_SUCCESS;
}
diff --git a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf
index cf81697703cc..306b7ae38fe8 100644
--- a/UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf
+++ b/UefiPayloadPkg/Library/CbParseLib/CbParseLib.inf
@@ -34,6 +34,15 @@
IoLib
DebugLib
PcdLib
+ HobLib
+ FmapParserLib
+
+[Guids]
+ gSmmRegisterInfoGuid
+ gEfiSmmSmramMemoryGuid
+ gSpiFlashInfoGuid
+ gNvVariableInfoGuid
+ gS3CommunicationGuid
[Pcd]
gUefiPayloadPkgTokenSpaceGuid.PcdBootloaderParameter
--
2.43.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [edk2-devel] [PATCH v1 4/4] [WIP] UefiPayloadPkg: Support SMRAMC register
2023-12-11 22:37 [edk2-devel] [PATCH v1 1/4] UefiPayloadPkg/SblParseLib: Build SMM feature GUID HOBs from bootloader Benjamin Doron
2023-12-11 22:37 ` [edk2-devel] [PATCH v1 2/4] UefiPayloadPkg: Introduce coreboot FMAP parser library Benjamin Doron
2023-12-11 22:37 ` [edk2-devel] [PATCH v1 3/4] [WIP] UefiPayloadPkg/CbParseLib: Initial coreboot support for SMM payload Benjamin Doron
@ 2023-12-11 22:37 ` Benjamin Doron
2 siblings, 0 replies; 4+ messages in thread
From: Benjamin Doron @ 2023-12-11 22:37 UTC (permalink / raw)
To: devel; +Cc: Guo Dong, Ray Ni, Sean Rhodes, James Lu, Gua Guo
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
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2023-12-11 22:37 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-12-11 22:37 [edk2-devel] [PATCH v1 1/4] UefiPayloadPkg/SblParseLib: Build SMM feature GUID HOBs from bootloader Benjamin Doron
2023-12-11 22:37 ` [edk2-devel] [PATCH v1 2/4] UefiPayloadPkg: Introduce coreboot FMAP parser library Benjamin Doron
2023-12-11 22:37 ` [edk2-devel] [PATCH v1 3/4] [WIP] UefiPayloadPkg/CbParseLib: Initial coreboot support for SMM payload Benjamin Doron
2023-12-11 22:37 ` [edk2-devel] [PATCH v1 4/4] [WIP] UefiPayloadPkg: Support SMRAMC register Benjamin Doron
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox