2024-07-22 13:49:00 +03:00

205 lines
5.4 KiB
C

/** @file
Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include <PrePi.h>
//
// Hack to work in NT32
//
EFI_STATUS
EFIAPI
SecWinNtPeiLoadFile (
IN VOID *Pe32Data,
IN EFI_PHYSICAL_ADDRESS *ImageAddress,
IN UINT64 *ImageSize,
IN EFI_PHYSICAL_ADDRESS *EntryPoint
);
EFI_STATUS
EFIAPI
LoadUefiImage (
IN VOID *UefiImage,
IN UINT32 UefiImageSize,
OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
OUT UINT32 *DestinationSize,
OUT EFI_PHYSICAL_ADDRESS *EntryPoint
)
{
RETURN_STATUS Status;
UEFI_IMAGE_LOADER_IMAGE_CONTEXT ImageContext;
UINT32 ImageSize;
VOID *Buffer;
UINT32 BufferSize;
UINT32 BufferPages;
UINT32 BufferAlignment;
Status = UefiImageInitializeContext (
&ImageContext,
UefiImage,
UefiImageSize,
UEFI_IMAGE_SOURCE_FV,
UefiImageOriginFv
);
ASSERT_EFI_ERROR (Status);
ImageSize = UefiImageGetImageSize (&ImageContext);
BufferPages = EFI_SIZE_TO_PAGES (ImageSize);
BufferSize = EFI_PAGES_TO_SIZE (BufferPages);
BufferAlignment = UefiImageGetSegmentAlignment (&ImageContext);
//
// Allocate Memory for the image
//
Buffer = AllocateAlignedCodePages (BufferPages, BufferAlignment);
ASSERT (Buffer != 0);
//
// Load and relocate the image to our new buffer
//
Status = UefiImageLoadImageForExecution (&ImageContext, Buffer, BufferSize, NULL, 0);
ASSERT_EFI_ERROR (Status);
*ImageAddress = (UINTN) Buffer;
*DestinationSize = BufferSize;
*EntryPoint = (UINTN) UefiImageLoaderGetImageEntryPoint (&ImageContext);
return Status;
}
typedef
VOID
(EFIAPI *DXE_CORE_ENTRY_POINT)(
IN VOID *HobStart
);
EFI_STATUS
EFIAPI
LoadDxeCoreFromFfsFile (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN UINTN StackSize
)
{
EFI_STATUS Status;
VOID *UefiImage;
UINT32 UefiImageSize;
EFI_PHYSICAL_ADDRESS ImageAddress;
UINT32 DestinationSize;
EFI_PHYSICAL_ADDRESS EntryPoint;
VOID *BaseOfStack;
VOID *TopOfStack;
VOID *Hob;
EFI_FV_FILE_INFO FvFileInfo;
Status = FfsFindSectionDataWithHook (EFI_SECTION_PE32, NULL, FileHandle, &UefiImage, &UefiImageSize);
if (EFI_ERROR (Status)) {
return Status;
}
Status = LoadUefiImage (UefiImage, UefiImageSize, &ImageAddress, &DestinationSize, &EntryPoint);
// For NT32 Debug Status = SecWinNtPeiLoadFile (UefiImage, &ImageAddress, &ImageSize, &EntryPoint);
ASSERT_EFI_ERROR (Status);
//
// Extract the DxeCore GUID file name.
//
Status = FfsGetFileInfo (FileHandle, &FvFileInfo);
ASSERT_EFI_ERROR (Status);
BuildModuleHob (&FvFileInfo.FileName, (EFI_PHYSICAL_ADDRESS)(UINTN)ImageAddress, DestinationSize, EntryPoint);
DEBUG ((DEBUG_INFO | DEBUG_LOAD, "Loading DxeCore at 0x%10p EntryPoint=0x%10p\n", (VOID *)(UINTN)ImageAddress, (VOID *)(UINTN)EntryPoint));
Hob = GetHobList ();
if (StackSize == 0) {
// User the current stack
((DXE_CORE_ENTRY_POINT)(UINTN)EntryPoint)(Hob);
} else {
//
// Allocate 128KB for the Stack
//
BaseOfStack = AllocatePages (EFI_SIZE_TO_PAGES (StackSize));
ASSERT (BaseOfStack != NULL);
//
// Compute the top of the stack we were allocated. Pre-allocate a UINTN
// for safety.
//
TopOfStack = (VOID *)((UINTN)BaseOfStack + EFI_SIZE_TO_PAGES (StackSize) * EFI_PAGE_SIZE - CPU_STACK_ALIGNMENT);
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
//
// Update the contents of BSP stack HOB to reflect the real stack info passed to DxeCore.
//
UpdateStackHob ((EFI_PHYSICAL_ADDRESS)(UINTN)BaseOfStack, StackSize);
SwitchStack (
(SWITCH_STACK_ENTRY_POINT)(UINTN)EntryPoint,
Hob,
NULL,
TopOfStack
);
}
// Should never get here as DXE Core does not return
DEBUG ((DEBUG_ERROR, "DxeCore returned\n"));
ASSERT (FALSE);
return EFI_DEVICE_ERROR;
}
EFI_STATUS
EFIAPI
LoadDxeCoreFromFv (
IN UINTN *FvInstance OPTIONAL,
IN UINTN StackSize
)
{
EFI_STATUS Status;
EFI_PEI_FV_HANDLE VolumeHandle;
EFI_PEI_FILE_HANDLE FileHandle = NULL;
if (FvInstance != NULL) {
//
// Caller passed in a specific FV to try, so only try that one
//
Status = FfsFindNextVolume (*FvInstance, &VolumeHandle);
if (!EFI_ERROR (Status)) {
Status = FfsFindNextFile (EFI_FV_FILETYPE_DXE_CORE, VolumeHandle, &FileHandle);
}
} else {
Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_DXE_CORE, &VolumeHandle, &FileHandle);
}
if (!EFI_ERROR (Status)) {
return LoadDxeCoreFromFfsFile (FileHandle, StackSize);
}
return Status;
}
EFI_STATUS
EFIAPI
DecompressFirstFv (
VOID
)
{
EFI_STATUS Status;
EFI_PEI_FV_HANDLE VolumeHandle;
EFI_PEI_FILE_HANDLE FileHandle;
Status = FfsAnyFvFindFirstFile (EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, &VolumeHandle, &FileHandle);
if (!EFI_ERROR (Status)) {
Status = FfsProcessFvFile (FileHandle);
}
return Status;
}