FspNotifyDxe need handle >4G memory.

The FSP API is always 32bit, but FspNotifyDxe might load to >4G memory. In order to make thunk work, we need reload FspNotifyDxe to <4G memory.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: "Yao, Jiewen" <Jiewen.Yao@intel.com>
Reviewed-by: "Mudusuru, Giri P" <giri.p.mudusuru@intel.com>


git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@18094 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Yao, Jiewen 2015-07-28 07:26:57 +00:00 committed by jyao1
parent 71a6022f69
commit 00899456b8
4 changed files with 182 additions and 0 deletions

View File

@ -23,6 +23,22 @@
#include <Library/UefiLib.h> #include <Library/UefiLib.h>
#include <Library/FspApiLib.h> #include <Library/FspApiLib.h>
/**
Relocate this image under 4G memory.
@param ImageHandle Handle of driver image.
@param SystemTable Pointer to system table.
@retval EFI_SUCCESS Image successfully relocated.
@retval EFI_ABORTED Failed to relocate image.
**/
EFI_STATUS
RelocateImageUnder4GIfNeeded (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
);
FSP_INFO_HEADER *mFspHeader = NULL; FSP_INFO_HEADER *mFspHeader = NULL;
/** /**
@ -120,6 +136,14 @@ FspDxeEntryPoint (
VOID *Registration; VOID *Registration;
EFI_EVENT ProtocolNotifyEvent; EFI_EVENT ProtocolNotifyEvent;
//
// Load this driver's image to memory
//
Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable);
if (EFI_ERROR (Status)) {
return EFI_SUCCESS;
}
if (PcdGet32 (PcdFlashFvSecondFspBase) == 0) { if (PcdGet32 (PcdFlashFvSecondFspBase) == 0) {
mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase));
} else { } else {

View File

@ -30,6 +30,7 @@
[Sources] [Sources]
FspNotifyDxe.c FspNotifyDxe.c
LoadBelow4G.c
[Packages] [Packages]
MdePkg/MdePkg.dec MdePkg/MdePkg.dec
@ -43,6 +44,9 @@
BaseMemoryLib BaseMemoryLib
UefiLib UefiLib
FspApiLib FspApiLib
PeCoffLib
CacheMaintenanceLib
DxeServicesLib
[Protocols] [Protocols]
gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES

View File

@ -0,0 +1,152 @@
/** @file
Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions
of the BSD License which accompanies this distribution. The
full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/PeCoffLib.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/CacheMaintenanceLib.h>
#include <Library/UefiLib.h>
/**
Relocate this image under 4G memory.
@param ImageHandle Handle of driver image.
@param SystemTable Pointer to system table.
@retval EFI_SUCCESS Image successfully relocated.
@retval EFI_ABORTED Failed to relocate image.
**/
EFI_STATUS
RelocateImageUnder4GIfNeeded (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status;
UINT8 *Buffer;
UINTN BufferSize;
EFI_HANDLE NewImageHandle;
UINTN Pages;
EFI_PHYSICAL_ADDRESS FfsBuffer;
PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
VOID *Interface;
//
// If it is already <4G, no need do relocate
//
if ((UINTN)RelocateImageUnder4GIfNeeded < 0xFFFFFFFF) {
return EFI_SUCCESS;
}
//
// If locate gEfiCallerIdGuid success, it means 2nd entry.
//
Status = gBS->LocateProtocol (&gEfiCallerIdGuid, NULL, &Interface);
if (!EFI_ERROR (Status)) {
DEBUG ((EFI_D_INFO, "FspNotifyDxe - 2nd entry\n"));
return EFI_SUCCESS;
}
DEBUG ((EFI_D_INFO, "FspNotifyDxe - 1st entry\n"));
//
// Here we install a dummy handle
//
NewImageHandle = NULL;
Status = gBS->InstallProtocolInterface (
&NewImageHandle,
&gEfiCallerIdGuid,
EFI_NATIVE_INTERFACE,
NULL
);
ASSERT_EFI_ERROR (Status);
//
// Reload image itself to <4G mem
//
Status = GetSectionFromAnyFv (
&gEfiCallerIdGuid,
EFI_SECTION_PE32,
0,
(VOID **) &Buffer,
&BufferSize
);
ASSERT_EFI_ERROR (Status);
ImageContext.Handle = Buffer;
ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
//
// Get information about the image being loaded
//
Status = PeCoffLoaderGetImageInfo (&ImageContext);
ASSERT_EFI_ERROR (Status);
if (ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
Pages = EFI_SIZE_TO_PAGES ((UINTN) (ImageContext.ImageSize + ImageContext.SectionAlignment));
} else {
Pages = EFI_SIZE_TO_PAGES ((UINTN) ImageContext.ImageSize);
}
FfsBuffer = 0xFFFFFFFF;
Status = gBS->AllocatePages (
AllocateMaxAddress,
EfiBootServicesCode,
Pages,
&FfsBuffer
);
ASSERT_EFI_ERROR (Status);
ImageContext.ImageAddress = (PHYSICAL_ADDRESS)(UINTN)FfsBuffer;
//
// Align buffer on section boundry
//
ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)(ImageContext.SectionAlignment - 1));
//
// Load the image to our new buffer
//
Status = PeCoffLoaderLoadImage (&ImageContext);
ASSERT_EFI_ERROR (Status);
//
// Relocate the image in our new buffer
//
Status = PeCoffLoaderRelocateImage (&ImageContext);
ASSERT_EFI_ERROR (Status);
//
// Free the buffer allocated by ReadSection since the image has been relocated in the new buffer
//
gBS->FreePool (Buffer);
//
// Flush the instruction cache so the image data is written before we execute it
//
InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
DEBUG ((EFI_D_INFO, "Loading driver at 0x%08x EntryPoint=0x%08x\n", (UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.EntryPoint));
Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)(ImageContext.EntryPoint)) (NewImageHandle, gST);
if (EFI_ERROR (Status)) {
DEBUG ((EFI_D_ERROR, "Error: Image at 0x%08x start failed: %r\n", ImageContext.ImageAddress, Status));
gBS->FreePages (FfsBuffer, Pages);
}
//
// return error to unload >4G copy, if we already relocate itself to <4G.
//
return EFI_ALREADY_STARTED;
}

View File

@ -34,6 +34,7 @@
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
# Dummy - test build only # Dummy - test build only
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
@ -66,6 +67,7 @@
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf DevicePathLib|MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf