summaryrefslogtreecommitdiffstats
path: root/UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c')
-rw-r--r--UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c b/UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c
new file mode 100644
index 0000000000..9d1d8a4f61
--- /dev/null
+++ b/UefiPayloadPkg/PayloadLoaderPeim/FitLib/FitLib.c
@@ -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;
+}