diff options
author | levi.yun <yeoreum.yun@arm.com> | 2024-02-21 16:09:38 +0000 |
---|---|---|
committer | mergify[bot] <37929162+mergify[bot]@users.noreply.github.com> | 2025-01-17 14:55:42 +0000 |
commit | fbeab84945b0100310713a584f8fecbf4621c11e (patch) | |
tree | 7622bf415f972e1b05ca8bd11b78b755288295da /ArmPkg | |
parent | 6087382c62686130a6cb8bd397afe23bad9c4e67 (diff) | |
download | edk2-fbeab84945b0100310713a584f8fecbf4621c11e.tar.gz |
ArmPkg/Library: Introduce ArmTransferListLib
ArmTransferList is used to pass boot information according to
firmware handoff protocol specification [0].
When initializing StandaloneMm, it gets boot information from
the PHIT HOB in the TransferList.
[0] https://github.com/FirmwareHandoff/firmware_handoff
Signed-off-by: Levi Yun <yeoreum.yun@arm.com>
Diffstat (limited to 'ArmPkg')
-rw-r--r-- | ArmPkg/ArmPkg.dec | 5 | ||||
-rw-r--r-- | ArmPkg/ArmPkg.dsc | 2 | ||||
-rw-r--r-- | ArmPkg/Include/IndustryStandard/ArmTransferList.h | 130 | ||||
-rw-r--r-- | ArmPkg/Include/Library/ArmTransferListLib.h | 109 | ||||
-rw-r--r-- | ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c | 170 | ||||
-rw-r--r-- | ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf | 27 |
6 files changed, 443 insertions, 0 deletions
diff --git a/ArmPkg/ArmPkg.dec b/ArmPkg/ArmPkg.dec index 49cbffa5fc..112187fc46 100644 --- a/ArmPkg/ArmPkg.dec +++ b/ArmPkg/ArmPkg.dec @@ -93,6 +93,11 @@ #
StandaloneMmMmuLib|Include/Library/StandaloneMmMmuLib.h
+ ## @libraryclass Provides an interface for a Arm Transfer List.
+ #
+ ArmTransferListLib|Include/Library/ArmTransferListLib.h
+
+
[Guids.common]
gArmTokenSpaceGuid = { 0xBB11ECFE, 0x820F, 0x4968, { 0xBB, 0xA6, 0xF7, 0x6A, 0xFE, 0x30, 0x25, 0x96 } }
diff --git a/ArmPkg/ArmPkg.dsc b/ArmPkg/ArmPkg.dsc index d5a29f31ea..85d3f49c18 100644 --- a/ArmPkg/ArmPkg.dsc +++ b/ArmPkg/ArmPkg.dsc @@ -86,6 +86,7 @@ ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+ ArmTransferListLib|ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf
ArmMtlLib|ArmPkg/Library/ArmMtlNullLib/ArmMtlNullLib.inf
@@ -129,6 +130,7 @@ ArmPkg/Library/ArmSmcLibNull/ArmSmcLibNull.inf
ArmPkg/Library/ArmSvcLib/ArmSvcLib.inf
ArmPkg/Library/OpteeLib/OpteeLib.inf
+ ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf
ArmPkg/Filesystem/SemihostFs/SemihostFs.inf
diff --git a/ArmPkg/Include/IndustryStandard/ArmTransferList.h b/ArmPkg/Include/IndustryStandard/ArmTransferList.h new file mode 100644 index 0000000000..455c7d809d --- /dev/null +++ b/ArmPkg/Include/IndustryStandard/ArmTransferList.h @@ -0,0 +1,130 @@ +/** @file
+ Header file defining a Transfer List and Transfer Entry as specified by the
+ A-profile Firmware Handoff Protocol specification.
+
+ Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - https://github.com/FirmwareHandoff/firmware_handoff
+
+ @par Glossary:
+ - TL - Transfer list
+ - TE - Transfer entry
+ - HOB - Hand off block.
+**/
+
+#ifndef ARM_TRANSFER_LIST_
+#define ARM_TRANSFER_LIST_
+
+#include <Base.h>
+#include <Uefi.h>
+
+#define ARM_FW_HANDOFF_PROTOCOL_VERSION 1
+
+#define TRANSFER_LIST_ALIGNMENT 8 // 8 byte alignment
+#define TRANSFER_LIST_SIGNATURE_64 (0x4a0fb10b)
+#define TRANSFER_LIST_SIGNATURE_32 (0xfb10b)
+
+/*
+ * For register convention, please see below:
+ * https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/register_conventions.rst
+ */
+#define REGISTER_CONVENTION_VERSION_SHIFT_64 (32)
+#define TRANSFER_LIST_SIGNATURE_MASK_64 \
+ ((1ULL << REGISTER_CONVENTION_VERSION_SHIFT_64) - 1)
+
+#define REGISTER_CONVENTION_VERSION_SHIFT_32 (24)
+#define TRANSFER_LIST_SIGNATURE_MASK_32 \
+ ((1UL << REGISTER_CONVENTION_VERSION_SHIFT_32) - 1)
+
+#define REGISTER_CONVENTION_VERSION_MASK (0xff)
+#define REGISTER_CONVENTION_VERSION (1)
+
+#define CREATE_TRANSFER_LIST_HANDOFF_X1_VALUE(version) \
+ ((TRANSFER_LIST_SIGNATURE & \
+ (REGISTER_CONVENTION_VERSION_SHIFT_64 - 1)) | \
+ ((version) << REGISTER_CONVENTION_VERSION_SHIFT_64))
+
+#define CREATE_TRANSFER_LIST_HANDOFF_R1_VALUE(version) \
+ ((TRANSFER_LIST_SIGNATURE & \
+ (REGISTER_CONVENTION_VERSION_SHIFT_32 - 1)) | \
+ ((version) << REGISTER_CONVENTION_VERSION_SHIFT_32))
+
+/*
+ * tag id identifies contents of transfer entry.
+ * below is the standard tag id used in transfer entry.
+ * please see:
+ * https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/transfer_list.rst
+ * "Standard transfer entries" Section.
+ */
+#define TRANSFER_ENTRY_TAG_ID_EMPTY 0
+#define TRANSFER_ENTRY_TAG_ID_FDT 1
+#define TRANSFER_ENTRY_TAG_ID_HOB 2
+#define TRANSFER_ENTRY_TAG_ID_HOB_LIST 3
+#define TRANSFER_ENTRY_TAG_ID_ACPI_TABLE_AGGREGATE 4
+#define TRANSFER_ENTRY_TAG_ID_TPM_EVENT_LOG 5
+#define TRANSFER_ENTRY_TAG_ID_TPM_CRB_BASE 6
+
+/*
+ * Flag value in TransferListHeader->Flags.
+ * please see:
+ * https://github.com/FirmwareHandoff/firmware_handoff/blob/main/source/transfer_list.rst
+ */
+#define TRANSFER_LIST_FL_HAS_CHECKSUM BIT0
+
+/*
+ * Transfer list starts with the following header.
+ * Transfer entries followed after the following header.
+ */
+typedef struct TransferListHeader {
+ /// Signature, must be TRANSFER_LIST_SIGNATURE
+ UINT32 Signature;
+
+ /// Checksum
+ UINT8 Checksum;
+
+ /// Version of the TL Header.
+ UINT8 Version;
+
+ /// The size of this TL header in bytes.
+ UINT8 HeaderSize;
+
+ /// The maximum alignment required by any transfer entry in the transfer list,
+ /// specified as a power of two.
+ UINT8 Alignment;
+
+ /// The number of bytes occupied by the TL. This field
+ /// accounts for the size of the TL header plus the size
+ /// of all the entries contained in the TL.
+ UINT32 UsedSize;
+
+ /// The number of bytes occupied by the entire TL,
+ /// including any spare space at the end after UsedSize.
+ UINT32 TotalSize;
+
+ /// Flags word.
+ UINT32 Flags;
+
+ /// Reserved.
+ UINT32 Reserved;
+} TRANSFER_LIST_HEADER;
+
+/*
+ * Transfer entry in transfer list starts with the following header.
+ */
+typedef struct TransferEntryHeader {
+ /// The entry type identifier.
+ UINT16 TagId;
+
+ /// Reserved.
+ UINT8 Reserved0;
+
+ /// The size of this entry header in bytes.
+ UINT8 HeaderSize;
+
+ /// The size of the data content in bytes.
+ UINT32 DataSize;
+} TRANSFER_ENTRY_HEADER;
+
+#endif // ARM_TRANSFER_LIST_
diff --git a/ArmPkg/Include/Library/ArmTransferListLib.h b/ArmPkg/Include/Library/ArmTransferListLib.h new file mode 100644 index 0000000000..033821a181 --- /dev/null +++ b/ArmPkg/Include/Library/ArmTransferListLib.h @@ -0,0 +1,109 @@ +/** @file
+ Library that implements the helper functions to parse and pack a Transfer
+ List as specified by the A-profile Firmware Handoff Specification.
+
+ Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - https://github.com/FirmwareHandoff/firmware_handoff
+
+ @par Glossary:
+ - TL - Transfer list
+ - TE - Transfer entry
+ - HOB - Hand off block.
+**/
+
+#ifndef ARM_TRANSFER_LIST_LIB_
+#define ARM_TRANSFER_LIST_LIB_
+
+#include <Base.h>
+#include <Uefi.h>
+#include <IndustryStandard/ArmTransferList.h>
+#include <Pi/PiBootMode.h>
+#include <Pi/PiHob.h>
+
+/**
+ Return the first Transfer Entry Node in the Transfer List.
+
+ @param [in] Tlh TransferListHeader
+
+ @return Pointer to the Transfer Entry Node if successful otherwise NULL
+
+**/
+TRANSFER_ENTRY_HEADER *
+EFIAPI
+TlGetFirstEntry (
+ IN TRANSFER_LIST_HEADER *Tlh
+ );
+
+/**
+ Return the next Transfer Entry Node in the Transfer List from
+ last Transfer Entry Node.
+
+ @param [in] Tlh TransferListHeader
+ @param [in] CurrentTe Pointer to the Current Transfer Entry.
+ If this is NULL, the first Transfer Entry is returned.
+
+ @return Pointer to the next Transfer Entry Node if successful otherwise NULL
+
+**/
+TRANSFER_ENTRY_HEADER *
+EFIAPI
+TlGetNextEntry (
+ IN TRANSFER_LIST_HEADER *Tlh,
+ IN TRANSFER_ENTRY_HEADER *CurrentTe
+ );
+
+/**
+ Return the first Transfer Entry Node in the Transfer List
+ matched with given tag-id.
+
+ @param [in] Tlh TransferListHeader
+ @param [in] TagId Tag id
+
+ @return Pointer to the Transfer Entry Node if successful otherwise NULL
+
+**/
+TRANSFER_ENTRY_HEADER *
+EFIAPI
+TlFindFirstEntry (
+ IN TRANSFER_LIST_HEADER *Tlh,
+ IN UINT16 TagId
+ );
+
+/**
+ Return the Next Transfer Entry Node in the Transfer List
+ matched with given tag-id from last Transfer Entry Node.
+
+ @param [in] Tlh TransferListHeader
+ @param [in] CurrentTe Pointer to the Current Transfer Entry.
+ If this is NULL, the first Transfer Entry is returned.
+ @param [in] TagId Tag id
+
+ @return Pointer to the Transfer Entry Node if successful otherwise NULL
+
+**/
+TRANSFER_ENTRY_HEADER *
+EFIAPI
+TlFindNextEntry (
+ IN TRANSFER_LIST_HEADER *Tlh,
+ IN TRANSFER_ENTRY_HEADER *CurrentTe,
+ IN UINT16 TagId
+ );
+
+/**
+ Return the data in Transfer Entry.
+
+ @param [in] Te TransferEntryHeader
+
+ @return Pointer to the Data of Transfer Entry Node if successful otherwise NULL
+
+**/
+VOID *
+EFIAPI
+TlGetEntryData (
+ IN TRANSFER_ENTRY_HEADER *Te
+ );
+
+#endif // ARM_TRANSFER_LIST_LIB_
diff --git a/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c new file mode 100644 index 0000000000..43fbf65090 --- /dev/null +++ b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.c @@ -0,0 +1,170 @@ +/** @file
+ Library that implements the helper functions to parse and pack a Transfer
+ List as specified by the A-profile Firmware Handoff Specification.
+
+ Copyright (c) 2022, Arm Limited. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Reference(s):
+ - https://github.com/FirmwareHandoff/firmware_handoff
+
+ @par Glossary:
+ - TL - Transfer list
+ - TE - Transfer entry
+ - Tlh - Transfer list header
+**/
+
+#include <Base.h>
+#include <Library/ArmTransferListLib.h>
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+
+/**
+ Return the first Transfer Entry Node in the Transfer List.
+
+ @param [in] Tlh TransferListHeader
+
+ @return Pointer to the Transfer Entry Node if successful otherwise NULL
+
+**/
+TRANSFER_ENTRY_HEADER *
+EFIAPI
+TlGetFirstEntry (
+ IN TRANSFER_LIST_HEADER *Tlh
+ )
+{
+ return TlGetNextEntry (Tlh, NULL);
+}
+
+/**
+ Return the next Transfer Entry Node in the Transfer List from
+ last Transfer Entry Node.
+
+ @param [in] Tlh TransferListHeader
+ @param [in] CurrentTe Pointer to the Current Transfer Entry.
+ If this is NULL, the first Transfer Entry is returned.
+
+ @return Pointer to the Transfer Entry Node if successful otherwise NULL
+
+**/
+TRANSFER_ENTRY_HEADER *
+EFIAPI
+TlGetNextEntry (
+ IN TRANSFER_LIST_HEADER *Tlh,
+ IN TRANSFER_ENTRY_HEADER *CurrentTe
+ )
+{
+ TRANSFER_ENTRY_HEADER *Te;
+ UINTN CurrentAddr;
+ UINTN EndAddr;
+
+ if (Tlh == NULL) {
+ return NULL;
+ }
+
+ EndAddr = (UINTN)Tlh + Tlh->UsedSize;
+
+ if (CurrentTe != NULL) {
+ CurrentAddr = (UINTN)CurrentTe + CurrentTe->HeaderSize + CurrentTe->DataSize;
+ } else {
+ CurrentAddr = (UINTN)Tlh + Tlh->HeaderSize;
+ }
+
+ CurrentAddr = ALIGN_VALUE (CurrentAddr, (1 << Tlh->Alignment));
+
+ Te = (TRANSFER_ENTRY_HEADER *)CurrentAddr;
+
+ if (((CurrentAddr + sizeof (TRANSFER_LIST_HEADER)) < CurrentAddr) ||
+ ((CurrentAddr + sizeof (TRANSFER_ENTRY_HEADER)) > EndAddr) ||
+ ((CurrentAddr + Te->HeaderSize + Te->DataSize) < CurrentAddr) ||
+ ((CurrentAddr + Te->HeaderSize + Te->DataSize) > EndAddr))
+ {
+ return NULL;
+ }
+
+ return Te;
+}
+
+/**
+ Return the first Transfer Entry Node in the Transfer List
+ matched with given tag-id.
+
+ @param [in] Tlh TransferListHeader
+ @param [in] TagId Tag id
+
+ @return Pointer to the Transfer Entry Node if successful otherwise NULL
+
+**/
+TRANSFER_ENTRY_HEADER *
+EFIAPI
+TlFindFirstEntry (
+ IN TRANSFER_LIST_HEADER *Tlh,
+ IN UINT16 TagId
+ )
+{
+ TRANSFER_ENTRY_HEADER *Te;
+
+ Te = TlGetFirstEntry (Tlh);
+
+ while ((Te != NULL) && ((Te->TagId != TagId) || Te->Reserved0 != 0)) {
+ Te = TlGetNextEntry (Tlh, Te);
+ }
+
+ return Te;
+}
+
+/**
+ Return the Next Transfer Entry Node in the Transfer List
+ matched with given tag-id from last Transfer Entry Node.
+
+ @param [in] Tlh TransferListHeader
+ @param [in] CurrentTe Pointer to the Current Transfer Entry.
+ If this is NULL, the first Transfer Entry is returned.
+ @param [in] TagId Tag id
+
+ @return Pointer to the Transfer Entry Node if successful otherwise NULL
+
+**/
+TRANSFER_ENTRY_HEADER *
+EFIAPI
+TlFindNextEntry (
+ IN TRANSFER_LIST_HEADER *Tlh,
+ IN TRANSFER_ENTRY_HEADER *CurrentTe,
+ IN UINT16 TagId
+ )
+{
+ TRANSFER_ENTRY_HEADER *Te;
+
+ if (CurrentTe == NULL) {
+ return TlFindFirstEntry (Tlh, TagId);
+ } else {
+ Te = TlGetNextEntry (Tlh, CurrentTe);
+ }
+
+ while ((Te != NULL) && ((Te->TagId != TagId) || Te->Reserved0 != 0)) {
+ Te = TlGetNextEntry (Tlh, Te);
+ }
+
+ return Te;
+}
+
+/**
+ Return the data in Transfer Entry.
+
+ @param [in] Te TransferEntryHeader
+
+ @return Pointer to the Data of Transfer Entry Node if successful otherwise NULL
+
+**/
+VOID *
+EFIAPI
+TlGetEntryData (
+ IN TRANSFER_ENTRY_HEADER *Te
+ )
+{
+ if ((Te == NULL) || (Te->DataSize == 0)) {
+ return NULL;
+ }
+
+ return (VOID *)((UINTN)Te + Te->HeaderSize);
+}
diff --git a/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf new file mode 100644 index 0000000000..b1eeb8a1f7 --- /dev/null +++ b/ArmPkg/Library/ArmTransferListLib/ArmTransferListLib.inf @@ -0,0 +1,27 @@ +## @file
+# Library that implements the helper functions to parse and pack a
+# Transfer List according to the A-profile Firmware Handoff Specification.
+#
+# Copyright (c) 2024, Arm Limited. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001C
+ BASE_NAME = ArmTransferListLib
+ FILE_GUID = 3BD1750F-FB52-4AA8-B91E-D00EFA5D7D29
+ MODULE_TYPE = BASE
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = ArmTransferListLib
+
+[Sources]
+ ArmTransferListLib.c
+
+[Packages]
+ ArmPkg/ArmPkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ BaseLib
|