/** Wrap the call to PI's EFI_PEI_LOAD_FILE_PPI. @param This A pointer to EFI_PEI_FV_FILE_LOADER_PPI. @param FfsHeader The pointer to the file header to be loaded by the Pe/Coff loader. @param ImageAddress The loaded address of the Image. @param ImageSize Pointer to the size of the loaded image. @param EntryPoint Pointer to the entry point of the image. @retval EFI_SUCCESS The image was loaded successfully. @retval EFI_OUT_OF_RESOURCE There was not enought memory. @retval EFI_INVALID_PARAMETER The contents of the FFS file did not contain a valid PE/COFF image that could be loaded. **/ EFI_STATUS EFIAPI FrameworkLoadFile ( IN EFI_PEI_FV_FILE_LOADER_PPI *This, IN EFI_FFS_FILE_HEADER *FfsHeader, OUT EFI_PHYSICAL_ADDRESS *ImageAddress, OUT UINT64 *ImageSize, OUT EFI_PHYSICAL_ADDRESS *EntryPoint ) { EFI_STATUS Status; EFI_PEI_LOAD_FILE_PPI *PiLoadFile; UINT32 AuthenticationState; Status = PeiServicesLocatePpi ( &gEfiPeiLoadFilePpiGuid, 0, NULL, (VOID **) &PiLoadFile ); ASSERT_EFI_ERROR (Status); return PiLoadFile->LoadFile ( PiLoadFile, (EFI_PEI_FILE_HANDLE) FfsHeader, ImageAddress, ImageSize, EntryPoint, &AuthenticationState ); }
/** Main entry point to last PEIM. This function finds DXE Core in the firmware volume and transfer the control to DXE core. @param This Entry point for DXE IPL PPI. @param PeiServices General purpose services available to every PEIM. @param HobList Address to the Pei HOB list. @return EFI_SUCCESS DXE core was successfully loaded. @return EFI_OUT_OF_RESOURCES There are not enough resources to load DXE core. **/ EFI_STATUS EFIAPI DxeLoadCore ( IN CONST EFI_DXE_IPL_PPI *This, IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_HOB_POINTERS HobList ) { EFI_STATUS Status; EFI_FV_FILE_INFO DxeCoreFileInfo; EFI_PHYSICAL_ADDRESS DxeCoreAddress; UINT64 DxeCoreSize; EFI_PHYSICAL_ADDRESS DxeCoreEntryPoint; EFI_BOOT_MODE BootMode; EFI_PEI_FILE_HANDLE FileHandle; EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable; EFI_PEI_LOAD_FILE_PPI *LoadFile; UINTN Instance; UINT32 AuthenticationState; UINTN DataSize; EFI_PEI_S3_RESUME2_PPI *S3Resume; EFI_PEI_RECOVERY_MODULE_PPI *PeiRecovery; EFI_MEMORY_TYPE_INFORMATION MemoryData[EfiMaxMemoryType + 1]; // // if in S3 Resume, restore configure // BootMode = GetBootModeHob (); if (BootMode == BOOT_ON_S3_RESUME) { Status = PeiServicesLocatePpi ( &gEfiPeiS3Resume2PpiGuid, 0, NULL, (VOID **) &S3Resume ); if (EFI_ERROR (Status)) { // // Report Status code that S3Resume PPI can not be found // REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MAJOR, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_S3_RESUME_PPI_NOT_FOUND) ); } ASSERT_EFI_ERROR (Status); Status = S3Resume->S3RestoreConfig2 (S3Resume); ASSERT_EFI_ERROR (Status); } else if (BootMode == BOOT_IN_RECOVERY_MODE) { REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_RECOVERY_BEGIN)); Status = PeiServicesLocatePpi ( &gEfiPeiRecoveryModulePpiGuid, 0, NULL, (VOID **) &PeiRecovery ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Locate Recovery PPI Failed.(Status = %r)\n", Status)); // // Report Status code the failure of locating Recovery PPI // REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MAJOR, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_RECOVERY_PPI_NOT_FOUND) ); CpuDeadLoop (); } REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_LOAD)); Status = PeiRecovery->LoadRecoveryCapsule (PeiServices, PeiRecovery); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Load Recovery Capsule Failed.(Status = %r)\n", Status)); // // Report Status code that recovery image can not be found // REPORT_STATUS_CODE ( EFI_ERROR_CODE | EFI_ERROR_MAJOR, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_EC_NO_RECOVERY_CAPSULE) ); CpuDeadLoop (); } REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_CAPSULE_START)); // // Now should have a HOB with the DXE core // } if (GetFirstGuidHob ((CONST EFI_GUID *)&gEfiMemoryTypeInformationGuid) == NULL) { // // Don't build GuidHob if GuidHob has been installed. // Status = PeiServicesLocatePpi ( &gEfiPeiReadOnlyVariable2PpiGuid, 0, NULL, (VOID **)&Variable ); if (!EFI_ERROR (Status)) { DataSize = sizeof (MemoryData); Status = Variable->GetVariable ( Variable, EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, &gEfiMemoryTypeInformationGuid, NULL, &DataSize, &MemoryData ); if (!EFI_ERROR (Status) && ValidateMemoryTypeInfoVariable(MemoryData, DataSize)) { // // Build the GUID'd HOB for DXE // BuildGuidDataHob ( &gEfiMemoryTypeInformationGuid, MemoryData, DataSize ); } } } // // Look in all the FVs present in PEI and find the DXE Core FileHandle // FileHandle = DxeIplFindDxeCore (); // // Load the DXE Core from a Firmware Volume. // Instance = 0; do { Status = PeiServicesLocatePpi (&gEfiPeiLoadFilePpiGuid, Instance++, NULL, (VOID **) &LoadFile); // // These must exist an instance of EFI_PEI_LOAD_FILE_PPI to support to load DxeCore file handle successfully. // ASSERT_EFI_ERROR (Status); Status = LoadFile->LoadFile ( LoadFile, FileHandle, &DxeCoreAddress, &DxeCoreSize, &DxeCoreEntryPoint, &AuthenticationState ); } while (EFI_ERROR (Status)); // // Get the DxeCore File Info from the FileHandle for the DxeCore GUID file name. // Status = PeiServicesFfsGetFileInfo (FileHandle, &DxeCoreFileInfo); ASSERT_EFI_ERROR (Status); // // Add HOB for the DXE Core // BuildModuleHob ( &DxeCoreFileInfo.FileName, DxeCoreAddress, ALIGN_VALUE (DxeCoreSize, EFI_PAGE_SIZE), DxeCoreEntryPoint ); // // Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT // REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_PEI_CORE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT)); DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DXE CORE at 0x%11p EntryPoint=0x%11p\n", (VOID *)(UINTN)DxeCoreAddress, FUNCTION_ENTRY_POINT (DxeCoreEntryPoint))); // // Transfer control to the DXE Core // The hand off state is simply a pointer to the HOB list // HandOffToDxeCore (DxeCoreEntryPoint, HobList); // // If we get here, then the DXE Core returned. This is an error // DxeCore should not return. // ASSERT (FALSE); CpuDeadLoop (); return EFI_OUT_OF_RESOURCES; }
/** Routine to load image file for subsequent execution by LoadFile Ppi. If any LoadFile Ppi is not found, the build-in support function for the PE32+/TE XIP image format is used. @param PeiServices - An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation @param FileHandle - Pointer to the FFS file header of the image. @param PeimState - The dispatch state of the input PEIM handle. @param EntryPoint - Pointer to entry point of specified image file for output. @param AuthenticationState - Pointer to attestation authentication state of image. @retval EFI_SUCCESS - Image is successfully loaded. @retval EFI_NOT_FOUND - Fail to locate necessary PPI @retval Others - Fail to load file. **/ EFI_STATUS PeiLoadImage ( IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_FILE_HANDLE FileHandle, IN UINT8 PeimState, OUT EFI_PHYSICAL_ADDRESS *EntryPoint, OUT UINT32 *AuthenticationState ) { EFI_STATUS PpiStatus; EFI_STATUS Status; UINTN Index; EFI_PEI_LOAD_FILE_PPI *LoadFile; EFI_PHYSICAL_ADDRESS ImageAddress; UINT64 ImageSize; BOOLEAN IsStrip; IsStrip = FALSE; // // If any instances of PEI_LOAD_FILE_PPI are installed, they are called. // one at a time, until one reports EFI_SUCCESS. // Index = 0; do { PpiStatus = PeiServicesLocatePpi ( &gEfiPeiLoadFilePpiGuid, Index, NULL, (VOID **)&LoadFile ); if (!EFI_ERROR (PpiStatus)) { Status = LoadFile->LoadFile ( LoadFile, FileHandle, &ImageAddress, &ImageSize, EntryPoint, AuthenticationState ); if (!EFI_ERROR (Status) || Status == EFI_WARN_BUFFER_TOO_SMALL) { // // The shadowed PEIM must be relocatable. // if (PeimState == PEIM_STATE_REGISITER_FOR_SHADOW) { IsStrip = RelocationIsStrip ((VOID *) (UINTN) ImageAddress); ASSERT (!IsStrip); if (IsStrip) { return EFI_UNSUPPORTED; } } // // The image to be started must have the machine type supported by PeiCore. // ASSERT (EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress))); if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeCoffLoaderGetMachineType ((VOID *) (UINTN) ImageAddress))) { return EFI_UNSUPPORTED; } return EFI_SUCCESS; } } Index++; } while (!EFI_ERROR (PpiStatus)); return PpiStatus; }