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 2/4] UefiPayloadPkg: Introduce coreboot FMAP parser library
Date: Mon, 11 Dec 2023 17:39:10 -0500 [thread overview]
Message-ID: <20231211223919.1225565-2-benjamin.doron00@gmail.com> (raw)
In-Reply-To: <20231211223919.1225565-1-benjamin.doron00@gmail.com>
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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#112337): https://edk2.groups.io/g/devel/message/112337
Mute This Topic: https://groups.io/mt/103119570/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next 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 ` Benjamin Doron [this message]
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 ` [edk2-devel] [PATCH v2 4/4] [WIP] UefiPayloadPkg: Support SMRAMC register Benjamin Doron
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-2-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