UefiPayloadPkg: Add FIT support
Provide Fit format for UniversalPayload, developer can use argument "--Fit" to build UniversalPayload.fit Cc: Guo Dong <guo.dong@intel.com> Cc: Sean Rhodes <sean@starlabs.systems> Cc: James Lu <james.lu@intel.com> Cc: Gua Guo <gua.guo@intel.com> Reviewed-by: Gua Guo <gua.guo@intel.com> Signed-off-by: BruceX Wang <brucex.wang@intel.com>
This commit is contained in:
committed by
mergify[bot]
parent
d6b05375b4
commit
39f3c26e8c
60
UefiPayloadPkg/PayloadLoaderPeim/FitLib.h
Normal file
60
UefiPayloadPkg/PayloadLoaderPeim/FitLib.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/** @file
|
||||
FIT Load Image Support
|
||||
Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#ifndef FIT_LIB_H_
|
||||
#define FIT_LIB_H_
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/FdtLib.h>
|
||||
|
||||
typedef struct {
|
||||
UINT64 RelocateType;
|
||||
UINT64 Offset;
|
||||
} FIT_RELOCATE_ITEM;
|
||||
|
||||
typedef struct {
|
||||
EFI_PHYSICAL_ADDRESS ImageBase;
|
||||
EFI_PHYSICAL_ADDRESS PayloadBaseAddress;
|
||||
UINT64 PayloadSize;
|
||||
UINTN PayloadEntryOffset;
|
||||
UINTN PayloadEntrySize;
|
||||
EFI_PHYSICAL_ADDRESS PayloadEntryPoint;
|
||||
UINTN RelocateTableOffset;
|
||||
UINTN RelocateTableCount;
|
||||
EFI_PHYSICAL_ADDRESS PayloadLoadAddress;
|
||||
} FIT_IMAGE_CONTEXT;
|
||||
|
||||
typedef struct {
|
||||
CHAR8 *Name;
|
||||
UINT32 Offset;
|
||||
} PROPERTY_DATA;
|
||||
|
||||
#define IMAGE_BASE_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, ImageBase)
|
||||
#define PAYLOAD_BASE_ADDR_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, PayloadBaseAddress)
|
||||
#define PAYLOAD_BASE_SIZE_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, PayloadSize)
|
||||
#define PAYLOAD_ENTRY_OFFSET_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, PayloadEntryOffset)
|
||||
#define PAYLOAD_ENTRY_SIZE_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, PayloadEntrySize)
|
||||
#define PAYLOAD_ENTRY_POINT_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, PayloadEntryPoint)
|
||||
#define RELOCATE_TABLE_OFFSET_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, RelocateTableOffset)
|
||||
#define RELOCATE_TABLE_COUNT_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, RelocateTableCount)
|
||||
#define PAYLOAD_LOAD_ADDR_OFFSET OFFSET_OF (FIT_IMAGE_CONTEXT, PayloadLoadAddress)
|
||||
|
||||
/**
|
||||
Parse the FIT image info.
|
||||
@param[in] ImageBase Memory address of an image.
|
||||
@param[out] Context The FIT image context pointer.
|
||||
@retval EFI_UNSUPPORTED Unsupported binary type.
|
||||
@retval EFI_SUCCESS FIT binary is loaded successfully.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ParseFitImage (
|
||||
IN VOID *ImageBase,
|
||||
OUT FIT_IMAGE_CONTEXT *Context
|
||||
);
|
||||
|
||||
#endif
|
127
UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c
Normal file
127
UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c
Normal file
@@ -0,0 +1,127 @@
|
||||
/** @file
|
||||
FIT Load Image Support
|
||||
Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include "FitLib.h"
|
||||
|
||||
PROPERTY_DATA PropertyData32List[] = {
|
||||
{ "data-offset", PAYLOAD_ENTRY_OFFSET_OFFSET },
|
||||
{ "data-size", PAYLOAD_ENTRY_SIZE_OFFSET },
|
||||
{ "reloc-start", RELOCATE_TABLE_OFFSET_OFFSET }
|
||||
};
|
||||
|
||||
PROPERTY_DATA PropertyData64List[] = {
|
||||
{ "entry-start", PAYLOAD_ENTRY_POINT_OFFSET },
|
||||
{ "load", PAYLOAD_LOAD_ADDR_OFFSET }
|
||||
};
|
||||
|
||||
/**
|
||||
Parse the target firmware image info in FIT.
|
||||
@param[in] Fdt Memory address of a fdt.
|
||||
@param[in] Firmware Target name of an image.
|
||||
@param[out] Context The FIT image context pointer.
|
||||
@retval EFI_NOT_FOUND FIT node dose not find.
|
||||
@retval EFI_SUCCESS FIT binary is loaded successfully.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
FitParseFirmwarePropertyData (
|
||||
IN VOID *Fdt,
|
||||
IN CHAR8 *Firmware,
|
||||
OUT FIT_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
CONST FDT_PROPERTY *PropertyPtr;
|
||||
INT32 ImageNode;
|
||||
INT32 TianoNode;
|
||||
INT32 TempLen;
|
||||
UINT32 *Data32;
|
||||
UINT64 *Data64;
|
||||
UINT32 *ContextOffset32;
|
||||
UINT64 *ContextOffset64;
|
||||
INT32 Index;
|
||||
|
||||
ImageNode = FdtSubnodeOffsetNameLen (Fdt, 0, "images", (INT32)AsciiStrLen ("images"));
|
||||
if (ImageNode <= 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
TianoNode = FdtSubnodeOffsetNameLen (Fdt, ImageNode, Firmware, (INT32)AsciiStrLen (Firmware));
|
||||
if (TianoNode <= 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
for (Index = 0; Index < sizeof (PropertyData32List) / sizeof (PROPERTY_DATA); Index++) {
|
||||
PropertyPtr = FdtGetProperty (Fdt, TianoNode, PropertyData32List[Index].Name, &TempLen);
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
ContextOffset32 = (UINT32 *)((UINTN)Context + PropertyData32List[Index].Offset);
|
||||
*ContextOffset32 = Fdt32ToCpu (*Data32);
|
||||
}
|
||||
|
||||
for (Index = 0; Index < sizeof (PropertyData64List)/sizeof (PROPERTY_DATA); Index++) {
|
||||
PropertyPtr = FdtGetProperty (Fdt, TianoNode, PropertyData64List[Index].Name, &TempLen);
|
||||
Data64 = (UINT64 *)(PropertyPtr->Data);
|
||||
ContextOffset64 = (UINT64 *)((UINTN)Context + PropertyData64List[Index].Offset);
|
||||
*ContextOffset64 = Fdt64ToCpu (*Data64);
|
||||
}
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
Parse the FIT image info.
|
||||
@param[in] ImageBase Memory address of an image.
|
||||
@param[out] Context The FIT image context pointer.
|
||||
@retval EFI_UNSUPPORTED Unsupported binary type.
|
||||
@retval EFI_SUCCESS FIT binary is loaded successfully.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
ParseFitImage (
|
||||
IN VOID *ImageBase,
|
||||
OUT FIT_IMAGE_CONTEXT *Context
|
||||
)
|
||||
{
|
||||
VOID *Fdt;
|
||||
INT32 ConfigNode;
|
||||
INT32 Config1Node;
|
||||
CONST FDT_PROPERTY *PropertyPtr;
|
||||
INT32 TempLen;
|
||||
UINT32 *Data32;
|
||||
UINT64 Value;
|
||||
EFI_STATUS Status;
|
||||
UINTN UplSize;
|
||||
CHAR8 *Firmware;
|
||||
|
||||
Status = FdtCheckHeader (ImageBase);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return EFI_UNSUPPORTED;
|
||||
}
|
||||
|
||||
Fdt = ImageBase;
|
||||
PropertyPtr = FdtGetProperty (Fdt, 0, "size", &TempLen);
|
||||
Data32 = (UINT32 *)(PropertyPtr->Data);
|
||||
UplSize = Value = Fdt32ToCpu (*Data32);
|
||||
ConfigNode = FdtSubnodeOffsetNameLen (Fdt, 0, "configurations", (INT32)AsciiStrLen ("configurations"));
|
||||
if (ConfigNode <= 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
Config1Node = FdtSubnodeOffsetNameLen (Fdt, ConfigNode, "conf-1", (INT32)AsciiStrLen ("conf-1"));
|
||||
if (Config1Node <= 0) {
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
|
||||
PropertyPtr = FdtGetProperty (Fdt, Config1Node, "firmware", &TempLen);
|
||||
Firmware = (CHAR8 *)(PropertyPtr->Data);
|
||||
|
||||
FitParseFirmwarePropertyData (Fdt, Firmware, Context);
|
||||
|
||||
Context->ImageBase = (EFI_PHYSICAL_ADDRESS)ImageBase;
|
||||
Context->PayloadSize = UplSize;
|
||||
Context->RelocateTableCount = (Context->PayloadEntrySize - (Context->RelocateTableOffset - Context->PayloadEntryOffset)) / sizeof (FIT_RELOCATE_ITEM);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
150
UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c
Normal file
150
UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c
Normal file
@@ -0,0 +1,150 @@
|
||||
/** @file
|
||||
FIT Load Image Support
|
||||
Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
|
||||
SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
**/
|
||||
|
||||
#include <PiPei.h>
|
||||
#include <UniversalPayload/UniversalPayload.h>
|
||||
#include <Guid/UniversalPayloadBase.h>
|
||||
#include <UniversalPayload/ExtraData.h>
|
||||
|
||||
#include <Ppi/LoadFile.h>
|
||||
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/HobLib.h>
|
||||
#include <Library/PeiServicesLib.h>
|
||||
#include <Library/MemoryAllocationLib.h>
|
||||
#include <Library/BaseMemoryLib.h>
|
||||
|
||||
#include "FitLib.h"
|
||||
|
||||
/**
|
||||
The wrapper function of PeiLoadImageLoadImage().
|
||||
@param This - Pointer to EFI_PEI_LOAD_FILE_PPI.
|
||||
@param FileHandle - Pointer to the FFS file header of the image.
|
||||
@param ImageAddressArg - Pointer to PE/TE image.
|
||||
@param ImageSizeArg - Size of PE/TE image.
|
||||
@param EntryPoint - Pointer to entry point of specified image file for output.
|
||||
@param AuthenticationState - Pointer to attestation authentication state of image.
|
||||
@return Status of PeiLoadImageLoadImage().
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiLoadFileLoadPayload (
|
||||
IN CONST EFI_PEI_LOAD_FILE_PPI *This,
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg OPTIONAL,
|
||||
OUT UINT64 *ImageSizeArg OPTIONAL,
|
||||
OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
|
||||
OUT UINT32 *AuthenticationState
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
FIT_IMAGE_CONTEXT Context;
|
||||
UINTN Instance;
|
||||
VOID *Binary;
|
||||
FIT_RELOCATE_ITEM *RelocateTable;
|
||||
UNIVERSAL_PAYLOAD_BASE *PayloadBase;
|
||||
UINTN Length;
|
||||
UINTN Delta;
|
||||
UINTN Index;
|
||||
|
||||
Instance = 0;
|
||||
do {
|
||||
Status = PeiServicesFfsFindSectionData3 (EFI_SECTION_RAW, Instance++, FileHandle, &Binary, AuthenticationState);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
ZeroMem (&Context, sizeof (Context));
|
||||
Status = ParseFitImage (Binary, &Context);
|
||||
} while (EFI_ERROR (Status));
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"Before Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint: 0x%08x\n",
|
||||
Context.PayloadBaseAddress,
|
||||
Context.PayloadSize,
|
||||
Context.PayloadEntryPoint
|
||||
));
|
||||
Context.PayloadBaseAddress = (EFI_PHYSICAL_ADDRESS)AllocatePages (EFI_SIZE_TO_PAGES (Context.PayloadSize));
|
||||
|
||||
RelocateTable = (FIT_RELOCATE_ITEM *)(UINTN)(Context.PayloadBaseAddress + Context.RelocateTableOffset);
|
||||
CopyMem ((VOID *)Context.PayloadBaseAddress, Binary, Context.PayloadSize);
|
||||
|
||||
if (Context.PayloadBaseAddress > Context.PayloadLoadAddress) {
|
||||
Delta = Context.PayloadBaseAddress - Context.PayloadLoadAddress;
|
||||
Context.PayloadEntryPoint += Delta;
|
||||
for (Index = 0; Index < Context.RelocateTableCount; Index++) {
|
||||
if ((RelocateTable[Index].RelocateType == 10) || (RelocateTable[Index].RelocateType == 3)) {
|
||||
*((UINT64 *)(Context.PayloadBaseAddress + RelocateTable[Index].Offset)) = *((UINT64 *)(Context.PayloadBaseAddress + RelocateTable[Index].Offset)) + Delta;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Delta = Context.PayloadLoadAddress - Context.PayloadBaseAddress;
|
||||
Context.PayloadEntryPoint -= Delta;
|
||||
for (Index = 0; Index < Context.RelocateTableCount; Index++) {
|
||||
if ((RelocateTable[Index].RelocateType == 10) || (RelocateTable[Index].RelocateType == 3)) {
|
||||
*((UINT64 *)(Context.PayloadBaseAddress + RelocateTable[Index].Offset)) = *((UINT64 *)(Context.PayloadBaseAddress + RelocateTable[Index].Offset)) - Delta;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG ((
|
||||
DEBUG_INFO,
|
||||
"After Rebase Payload File Base: 0x%08x, File Size: 0x%08X, EntryPoint: 0x%08x\n",
|
||||
Context.PayloadBaseAddress,
|
||||
Context.PayloadSize,
|
||||
Context.PayloadEntryPoint
|
||||
));
|
||||
|
||||
Length = sizeof (UNIVERSAL_PAYLOAD_BASE);
|
||||
PayloadBase = BuildGuidHob (
|
||||
&gUniversalPayloadBaseGuid,
|
||||
Length
|
||||
);
|
||||
PayloadBase->Entry = (EFI_PHYSICAL_ADDRESS)Context.ImageBase;
|
||||
|
||||
*ImageAddressArg = Context.PayloadBaseAddress;
|
||||
*ImageSizeArg = Context.PayloadSize;
|
||||
*EntryPoint = Context.PayloadEntryPoint;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
EFI_PEI_LOAD_FILE_PPI mPeiLoadFilePpi = {
|
||||
PeiLoadFileLoadPayload
|
||||
};
|
||||
|
||||
EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiPeiLoadFilePpiGuid,
|
||||
&mPeiLoadFilePpi
|
||||
};
|
||||
|
||||
/**
|
||||
Install Pei Load File PPI.
|
||||
@param FileHandle Handle of the file being invoked.
|
||||
@param PeiServices Describes the list of possible PEI Services.
|
||||
@retval EFI_SUCESS The entry point executes successfully.
|
||||
@retval Others Some error occurs during the execution of this function.
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
InitializeFitPayloadLoaderPeim (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
|
||||
Status = PeiServicesInstallPpi (&gPpiLoadFilePpiList);
|
||||
|
||||
return Status;
|
||||
}
|
59
UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf
Normal file
59
UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.inf
Normal file
@@ -0,0 +1,59 @@
|
||||
## @file
|
||||
# Produce LoadFile PPI for payload loading.
|
||||
#
|
||||
# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause-Patent
|
||||
#
|
||||
##
|
||||
|
||||
[Defines]
|
||||
INF_VERSION = 0x00010005
|
||||
BASE_NAME = FitPayloadLoaderPeim
|
||||
FILE_GUID = 55AC82C8-FC17-4C56-BCDA-990BB0A73E41
|
||||
MODULE_TYPE = PEIM
|
||||
VERSION_STRING = 1.0
|
||||
|
||||
ENTRY_POINT = InitializeFitPayloadLoaderPeim
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
# VALID_ARCHITECTURES = IA32 X64
|
||||
#
|
||||
|
||||
[Sources]
|
||||
FitPayloadLoaderPeim.c
|
||||
FitLib.h
|
||||
FitLib/FitLib.c
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
MdeModulePkg/MdeModulePkg.dec
|
||||
PcAtChipsetPkg/PcAtChipsetPkg.dec
|
||||
UefiPayloadPkg/UefiPayloadPkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
PcdLib
|
||||
MemoryAllocationLib
|
||||
BaseMemoryLib
|
||||
PeiServicesLib
|
||||
HobLib
|
||||
BaseLib
|
||||
PeimEntryPoint
|
||||
DebugLib
|
||||
FdtLib
|
||||
|
||||
[Ppis]
|
||||
gEfiPeiLoadFilePpiGuid ## PRODUCES
|
||||
|
||||
[Pcd]
|
||||
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcIndexRegister
|
||||
gPcAtChipsetPkgTokenSpaceGuid.PcdRtcTargetRegister
|
||||
|
||||
[Guids]
|
||||
gUniversalPayloadExtraDataGuid ## PRODUCES
|
||||
gUniversalPayloadBaseGuid ## PRODUCES
|
||||
|
||||
[Depex]
|
||||
TRUE
|
Reference in New Issue
Block a user