/** @file FIT Load Image Support Copyright (c) 2023, Intel Corporation. All rights reserved.
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; }