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