audk/UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c

128 lines
4.2 KiB
C

/** @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;
}