-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Provide Fit format for UniversalPayload, developer can use argument "--Fit" to build UniversalPayload.fit Cc: Guo Dong <[email protected]> Cc: Sean Rhodes <[email protected]> Cc: James Lu <[email protected]> Cc: Gua Guo <[email protected]> Reviewed-by: Gua Guo <[email protected]> Signed-off-by: BruceX Wang <[email protected]>
- Loading branch information
1 parent
d6b0537
commit 39f3c26
Showing
14 changed files
with
1,899 additions
and
103 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** @file | ||
Universal Payload general definitions. | ||
Copyright (c) 2023, Intel Corporation. All rights reserved.<BR> | ||
SPDX-License-Identifier: BSD-2-Clause-Patent | ||
**/ | ||
|
||
#ifndef UNIVERSAL_PAYLOAD_BASE_H_ | ||
#define UNIVERSAL_PAYLOAD_BASE_H_ | ||
|
||
extern GUID gUniversalPayloadBaseGuid; | ||
|
||
typedef struct { | ||
UNIVERSAL_PAYLOAD_GENERIC_HEADER Header; | ||
EFI_PHYSICAL_ADDRESS Entry; | ||
} UNIVERSAL_PAYLOAD_BASE; | ||
|
||
#endif // UNIVERSAL_PAYLOAD_BASE_H_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 changes: 150 additions & 0 deletions
150
UefiPayloadPkg/PayloadLoaderPeim/FitPayloadLoaderPeim.c
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
} |
Oops, something went wrong.