ArmPkg/ArmTransferListLib: Add utility functions
Added functionality TransferList Library TransferListVerifyChecksum - Verify TransferList CheckSum TransferListCheckHeader - Check if TransferList header is valid, return suitable opcodes validating the header TransferListFindEntry - Find a specific entry on the TransferList using the TagId TransferListDump - Dump the contents of the TransferList header and the entry headers Signed-off-by: Prachotan Reddy Bathi <Prachotan.Bathi@arm.com>
This commit is contained in:
committed by
mergify[bot]
parent
5fc1ba3f25
commit
e841099600
@@ -2,7 +2,7 @@
|
||||
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>
|
||||
Copyright (c) 2025, Arm Limited. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Reference(s):
|
||||
@@ -73,6 +73,16 @@
|
||||
*/
|
||||
#define TRANSFER_LIST_FL_HAS_CHECKSUM BIT0
|
||||
|
||||
/*
|
||||
* Operation codes indicating the validity of the Transfer List.
|
||||
*/
|
||||
typedef enum {
|
||||
TRANSFER_LIST_OPS_INVALID, /* invalid for any operation */
|
||||
TRANSFER_LIST_OPS_ALL, /* valid for all operations */
|
||||
TRANSFER_LIST_OPS_RO, /* valid for read only */
|
||||
TRANSFER_LIST_OPS_CUSTOM, /* abort or switch to special code to interpret */
|
||||
} TRANSFER_LIST_OPS;
|
||||
|
||||
/*
|
||||
* Transfer list starts with the following header.
|
||||
* Transfer entries followed after the following header.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
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>
|
||||
Copyright (c) 2022 - 2025, Arm Limited. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Reference(s):
|
||||
@@ -21,7 +21,7 @@
|
||||
/**
|
||||
Return the first Transfer Entry Node in the Transfer List.
|
||||
|
||||
@param [in] TransferListHeader TransferListHeader
|
||||
@param [in] TransferListHeader Pointer to the Transfer List Header.
|
||||
|
||||
@return Pointer to the Transfer Entry Node if successful otherwise NULL
|
||||
|
||||
@@ -103,4 +103,58 @@ TransferListGetEntryData (
|
||||
IN TRANSFER_ENTRY_HEADER *TransferEntry
|
||||
);
|
||||
|
||||
/**
|
||||
Dump the transfer list to the debug output.
|
||||
|
||||
@param [in] TransferListHeader Pointer to the Transfer List Header
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
TransferListDump (
|
||||
IN TRANSFER_LIST_HEADER *TransferListHeader
|
||||
);
|
||||
|
||||
/**
|
||||
Verify the checksum of the transfer list.
|
||||
|
||||
@param [in] TransferListHeader Pointer to the Transfer List Header
|
||||
|
||||
@retval FALSE Invalid Checksum
|
||||
@retval TRUE Valid Checksum
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
TransferListVerifyChecksum (
|
||||
IN TRANSFER_LIST_HEADER *TransferListHeader
|
||||
);
|
||||
|
||||
/**
|
||||
Check the header of the Transfer List.
|
||||
|
||||
@param [in] TransferListHeader Pointer to the Transfer List Header
|
||||
|
||||
@return TRANSFER_LIST_OPS code indicating the validity of the Transfer List
|
||||
**/
|
||||
TRANSFER_LIST_OPS
|
||||
EFIAPI
|
||||
TransferListCheckHeader (
|
||||
IN TRANSFER_LIST_HEADER *TransferListHeader
|
||||
);
|
||||
|
||||
/**
|
||||
Find a Transfer Entry Node in the Transfer List matched with the given tag-id.
|
||||
|
||||
@param [in] TransferListHeader Pointer to the Transfer List Header
|
||||
@param [in] TagId Tag id
|
||||
|
||||
@return Pointer to the Transfer Entry Node if successful otherwise NULL
|
||||
**/
|
||||
TRANSFER_ENTRY_HEADER *
|
||||
EFIAPI
|
||||
TransferListFindEntry (
|
||||
IN TRANSFER_LIST_HEADER *TransferListHeader,
|
||||
IN UINT16 TagId
|
||||
);
|
||||
|
||||
#endif // ARM_TRANSFER_LIST_LIB_
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
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>
|
||||
Copyright (c) 2022 - 2025, Arm Limited. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
|
||||
@par Reference(s):
|
||||
@@ -14,6 +14,90 @@
|
||||
#include <Library/BaseLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
|
||||
/**
|
||||
This function verifies the checksum of the Transfer List.
|
||||
|
||||
@param [in] TransferListHeader Pointer to the Transfer List Header
|
||||
|
||||
@retval FALSE Invalid Checksum
|
||||
@retval TRUE Valid Checksum
|
||||
|
||||
**/
|
||||
BOOLEAN
|
||||
EFIAPI
|
||||
TransferListVerifyChecksum (
|
||||
IN TRANSFER_LIST_HEADER *TransferListHeader
|
||||
)
|
||||
{
|
||||
if (TransferListHeader == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ((TransferListHeader->Flags & TRANSFER_LIST_FL_HAS_CHECKSUM) == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return (CalculateSum8 ((UINT8 *)TransferListHeader, TransferListHeader->UsedSize) == 0);
|
||||
}
|
||||
|
||||
/**
|
||||
This function checks the header of the Transfer List.
|
||||
|
||||
@param [in] TransferListHeader Pointer to the Transfer List Header
|
||||
|
||||
@return TRANSFER_LIST_OPS code indicating the validity of the Transfer List
|
||||
|
||||
**/
|
||||
TRANSFER_LIST_OPS
|
||||
EFIAPI
|
||||
TransferListCheckHeader (
|
||||
IN TRANSFER_LIST_HEADER *TransferListHeader
|
||||
)
|
||||
{
|
||||
if (TransferListHeader == NULL) {
|
||||
return TRANSFER_LIST_OPS_INVALID;
|
||||
}
|
||||
|
||||
if (TransferListHeader->Signature != TRANSFER_LIST_SIGNATURE_64) {
|
||||
DEBUG ((DEBUG_ERROR, "Bad transfer list signature 0x%x\n", TransferListHeader->Signature));
|
||||
return TRANSFER_LIST_OPS_INVALID;
|
||||
}
|
||||
|
||||
if (TransferListHeader->TotalSize == 0) {
|
||||
DEBUG ((DEBUG_ERROR, "Bad transfer list total size 0x%x\n", TransferListHeader->TotalSize));
|
||||
return TRANSFER_LIST_OPS_INVALID;
|
||||
}
|
||||
|
||||
if (TransferListHeader->UsedSize > TransferListHeader->TotalSize) {
|
||||
DEBUG ((DEBUG_ERROR, "Bad transfer list used size 0x%x\n", TransferListHeader->UsedSize));
|
||||
return TRANSFER_LIST_OPS_INVALID;
|
||||
}
|
||||
|
||||
if (TransferListHeader->HeaderSize != sizeof (TRANSFER_LIST_HEADER)) {
|
||||
DEBUG ((DEBUG_ERROR, "Bad transfer list header size 0x%x\n", TransferListHeader->HeaderSize));
|
||||
return TRANSFER_LIST_OPS_INVALID;
|
||||
}
|
||||
|
||||
if (TransferListVerifyChecksum (TransferListHeader) == FALSE) {
|
||||
DEBUG ((DEBUG_ERROR, "Bad transfer list checksum 0x%x\n", TransferListHeader->Checksum));
|
||||
return TRANSFER_LIST_OPS_INVALID;
|
||||
}
|
||||
|
||||
if (TransferListHeader->Version == 0) {
|
||||
DEBUG ((DEBUG_ERROR, "Transfer list version is invalid\n"));
|
||||
return TRANSFER_LIST_OPS_INVALID;
|
||||
} else if (TransferListHeader->Version == ARM_FW_HANDOFF_PROTOCOL_VERSION) {
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Transfer list version is valid for all operations\n"));
|
||||
return TRANSFER_LIST_OPS_ALL;
|
||||
} else if (TransferListHeader->Version > ARM_FW_HANDOFF_PROTOCOL_VERSION) {
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Transfer list version is valid for read-only\n"));
|
||||
return TRANSFER_LIST_OPS_RO;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Old or custom transfer list version is detected\n"));
|
||||
return TRANSFER_LIST_OPS_CUSTOM;
|
||||
}
|
||||
|
||||
/**
|
||||
Return the first Transfer Entry Node in the Transfer List.
|
||||
|
||||
@@ -165,3 +249,73 @@ TransferListGetEntryData (
|
||||
|
||||
return (VOID *)((UINTN)TransferEntry + TransferEntry->HeaderSize);
|
||||
}
|
||||
|
||||
/**
|
||||
Find a Transfer Entry Node in the Transfer List matched with the given tag-id.
|
||||
|
||||
@param [in] TransferListHeader Pointer to the Transfer List Header
|
||||
@param [in] TagId Tag id
|
||||
|
||||
@return Pointer to the Transfer Entry Node if successful otherwise NULL
|
||||
**/
|
||||
TRANSFER_ENTRY_HEADER *
|
||||
EFIAPI
|
||||
TransferListFindEntry (
|
||||
IN TRANSFER_LIST_HEADER *TransferListHeader,
|
||||
IN UINT16 TagId
|
||||
)
|
||||
{
|
||||
TRANSFER_ENTRY_HEADER *Entry = NULL;
|
||||
|
||||
do {
|
||||
Entry = TransferListGetNextEntry (TransferListHeader, Entry);
|
||||
} while ((Entry != NULL) && (Entry->TagId != TagId));
|
||||
|
||||
return Entry;
|
||||
}
|
||||
|
||||
/**
|
||||
Dump the transfer list to the debug output.
|
||||
|
||||
@param [in] TransferListHeader Pointer to the Transfer List Header
|
||||
|
||||
**/
|
||||
VOID
|
||||
EFIAPI
|
||||
TransferListDump (
|
||||
IN TRANSFER_LIST_HEADER *TransferListHeader
|
||||
)
|
||||
{
|
||||
TRANSFER_ENTRY_HEADER *Entry;
|
||||
UINTN Idx;
|
||||
|
||||
Entry = NULL;
|
||||
Idx = 0;
|
||||
|
||||
if (TransferListHeader == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Dump transfer list:\n"));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "signature 0x%x\n", TransferListHeader->Signature));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "checksum 0x%x\n", TransferListHeader->Checksum));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "version 0x%x\n", TransferListHeader->Version));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "hdr_size 0x%x\n", TransferListHeader->HeaderSize));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "alignment 0x%x\n", TransferListHeader->Alignment));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "used_size 0x%x\n", TransferListHeader->UsedSize));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "total_size 0x%x\n", TransferListHeader->TotalSize));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "flags 0x%x\n", TransferListHeader->Flags));
|
||||
|
||||
while (TRUE) {
|
||||
Entry = TransferListGetNextEntry (TransferListHeader, Entry);
|
||||
if (Entry == NULL) {
|
||||
break;
|
||||
}
|
||||
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Entry %d:\n", Idx++));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "tag_id 0x%x\n", Entry->TagId));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "hdr_size 0x%x\n", Entry->HeaderSize));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "data_size 0x%x\n", Entry->DataSize));
|
||||
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "data_addr 0x%lx\n", (UINTN)TransferListGetEntryData (Entry)));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user