Add Wrapper to indicate it for FspWrapper only. Add FSP2.0 EnumInitPhaseEndOfFirmware support.
Cc: Giri P Mudusuru <giri.p.mudus...@intel.com> Cc: Maurice Ma <maurice...@intel.com> Cc: Ravi P Rangarajan <ravi.p.rangara...@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Jiewen Yao <jiewen....@intel.com> Reviewed-by: Giri P Mudusuru <giri.p.mudus...@intel.com> Reviewed-by: Maurice Ma <maurice...@intel.com> Reviewed-by: Ravi P Rangarajan <ravi.p.rangara...@intel.com> --- IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.c | 176 -------------- IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf | 60 ----- IntelFspWrapperPkg/FspNotifyDxe/LoadBelow4G.c | 152 ------------ IntelFspWrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c | 250 ++++++++++++++++++++ IntelFspWrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf | 66 ++++++ IntelFspWrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c | 152 ++++++++++++ 6 files changed, 468 insertions(+), 388 deletions(-) diff --git a/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.c b/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.c deleted file mode 100644 index 1a1e4e6..0000000 --- a/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.c +++ /dev/null @@ -1,176 +0,0 @@ -/** @file - This driver will register two callbacks to call fsp's notifies. - - Copyright (c) 2014 - 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 <PiDxe.h> - -#include <Protocol/PciEnumerationComplete.h> - -#include <Library/UefiDriverEntryPoint.h> -#include <Library/UefiBootServicesTableLib.h> -#include <Library/DebugLib.h> -#include <Library/BaseMemoryLib.h> -#include <Library/UefiLib.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; - -/** - PciEnumerationComplete Protocol notification event handler. - - @param[in] Event Event whose notification function is being invoked. - @param[in] Context Pointer to the notification function's context. -**/ -VOID -EFIAPI -OnPciEnumerationComplete ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - NOTIFY_PHASE_PARAMS NotifyPhaseParams; - EFI_STATUS Status; - VOID *Interface; - - // - // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration. - // Just return if it is not found. - // - Status = gBS->LocateProtocol ( - &gEfiPciEnumerationCompleteProtocolGuid, - NULL, - &Interface - ); - if (EFI_ERROR (Status)) { - return ; - } - - NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; - Status = CallFspNotifyPhase (mFspHeader, &NotifyPhaseParams); - if (Status != EFI_SUCCESS) { - DEBUG((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status)); - } else { - DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n")); - } -} - -/** - Notification function of EVT_GROUP_READY_TO_BOOT event group. - - This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group. - When the Boot Manager is about to load and execute a boot option, it reclaims variable - storage if free size is below the threshold. - - @param[in] Event Event whose notification function is being invoked. - @param[in] Context Pointer to the notification function's context. - -**/ -VOID -EFIAPI -OnReadyToBoot ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - NOTIFY_PHASE_PARAMS NotifyPhaseParams; - EFI_STATUS Status; - - gBS->CloseEvent (Event); - - NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; - Status = CallFspNotifyPhase (mFspHeader, &NotifyPhaseParams); - if (Status != EFI_SUCCESS) { - DEBUG((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status)); - } else { - DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n")); - } -} - -/** - Main entry for the FSP DXE module. - - This routine registers two callbacks to call fsp's notifies. - - @param[in] ImageHandle The firmware allocated handle for the EFI image. - @param[in] SystemTable A pointer to the EFI System Table. - - @retval EFI_SUCCESS The entry point is executed successfully. - @retval other Some error occurs when executing this entry point. - -**/ -EFI_STATUS -EFIAPI -FspDxeEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_EVENT ReadyToBootEvent; - VOID *Registration; - 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) { - mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvFspBase)); - } else { - mFspHeader = FspFindFspHeader (PcdGet32 (PcdFlashFvSecondFspBase)); - } - DEBUG ((DEBUG_INFO, "FspHeader - 0x%x\n", mFspHeader)); - if (mFspHeader == NULL) { - return EFI_DEVICE_ERROR; - } - - ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent ( - &gEfiPciEnumerationCompleteProtocolGuid, - TPL_CALLBACK, - OnPciEnumerationComplete, - NULL, - &Registration - ); - ASSERT (ProtocolNotifyEvent != NULL); - - Status = EfiCreateEventReadyToBootEx ( - TPL_CALLBACK, - OnReadyToBoot, - NULL, - &ReadyToBootEvent - ); - ASSERT_EFI_ERROR (Status); - - return EFI_SUCCESS; -} - diff --git a/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf b/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf deleted file mode 100644 index 66970cc..0000000 --- a/IntelFspWrapperPkg/FspNotifyDxe/FspNotifyDxe.inf +++ /dev/null @@ -1,60 +0,0 @@ -## @file -# FSP DXE Module -# -# This driver will register two callbacks to call fsp's notifies. -# -# Copyright (c) 2014 - 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. -# -## - -[Defines] - INF_VERSION = 0x00010005 - BASE_NAME = FspNotifyDxe - FILE_GUID = 8714C537-6D4B-4247-AA6C-29E8495F9100 - MODULE_TYPE = DXE_DRIVER - VERSION_STRING = 1.0 - ENTRY_POINT = FspDxeEntryPoint - -# -# The following information is for reference only and not required by the build tools. -# -# VALID_ARCHITECTURES = IA32 X64 -# - -[Sources] - FspNotifyDxe.c - LoadBelow4G.c - -[Packages] - MdePkg/MdePkg.dec - IntelFspPkg/IntelFspPkg.dec - IntelFspWrapperPkg/IntelFspWrapperPkg.dec - -[LibraryClasses] - UefiDriverEntryPoint - UefiBootServicesTableLib - DebugLib - BaseMemoryLib - UefiLib - FspApiLib - PeCoffLib - CacheMaintenanceLib - DxeServicesLib - -[Protocols] - gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES - -[Pcd] - gFspWrapperTokenSpaceGuid.PcdFlashFvFspBase ## CONSUMES - gFspWrapperTokenSpaceGuid.PcdFlashFvSecondFspBase ## CONSUMES - gFspWrapperTokenSpaceGuid.PcdFlashFvFspSize ## CONSUMES - -[Depex] - TRUE diff --git a/IntelFspWrapperPkg/FspNotifyDxe/LoadBelow4G.c b/IntelFspWrapperPkg/FspNotifyDxe/LoadBelow4G.c deleted file mode 100644 index d39164e..0000000 --- a/IntelFspWrapperPkg/FspNotifyDxe/LoadBelow4G.c +++ /dev/null @@ -1,152 +0,0 @@ -/** @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; -} diff --git a/IntelFspWrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c b/IntelFspWrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c new file mode 100644 index 0000000..30c06b8 --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.c @@ -0,0 +1,250 @@ +/** @file + This driver will register two callbacks to call fsp's notifies. + + Copyright (c) 2014 - 2016, 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 <PiDxe.h> + +#include <Protocol/PciEnumerationComplete.h> + +#include <Library/UefiDriverEntryPoint.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/DebugLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/UefiLib.h> +#include <Library/FspWrapperApiLib.h> +#include <Library/PerformanceLib.h> +#include <Library/HobLib.h> + +typedef +EFI_STATUS +(EFIAPI * ADD_PERFORMANCE_RECORDS)( + IN CONST VOID *HobStart + ); + +struct _ADD_PERFORMANCE_RECORD_PROTOCOL { + ADD_PERFORMANCE_RECORDS AddPerformanceRecords; +}; + +typedef struct _ADD_PERFORMANCE_RECORD_PROTOCOL ADD_PERFORMANCE_RECORD_PROTOCOL; + +extern EFI_GUID gAddPerfRecordProtocolGuid; +extern EFI_GUID gFspHobGuid; +extern EFI_GUID gFspApiPerformanceGuid; + +EFI_EVENT mExitBootServicesEvent = NULL; + +/** + 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 + ); + +/** + PciEnumerationComplete Protocol notification event handler. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. +**/ +VOID +EFIAPI +OnPciEnumerationComplete ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + VOID *Interface; + + // + // Try to locate it because gEfiPciEnumerationCompleteProtocolGuid will trigger it once when registration. + // Just return if it is not found. + // + Status = gBS->LocateProtocol ( + &gEfiPciEnumerationCompleteProtocolGuid, + NULL, + &Interface + ); + if (EFI_ERROR (Status)) { + return ; + } + + NotifyPhaseParams.Phase = EnumInitPhaseAfterPciEnumeration; + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x6000); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x607F); + if (Status != EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase AfterPciEnumeration failed, status: 0x%x\n", Status)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase AfterPciEnumeration Success.\n")); + } +} + +/** + Notification function of EVT_GROUP_READY_TO_BOOT event group. + + This is a notification function registered on EVT_GROUP_READY_TO_BOOT event group. + When the Boot Manager is about to load and execute a boot option, it reclaims variable + storage if free size is below the threshold. + + @param[in] Event Event whose notification function is being invoked. + @param[in] Context Pointer to the notification function's context. + +**/ +VOID +EFIAPI +OnReadyToBoot ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + ADD_PERFORMANCE_RECORD_PROTOCOL *AddPerfRecordInterface; + EFI_PEI_HOB_POINTERS Hob; + VOID **FspHobListPtr; + + gBS->CloseEvent (Event); + + NotifyPhaseParams.Phase = EnumInitPhaseReadyToBoot; + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x4000); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x407F); + if (Status != EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase ReadyToBoot failed, status: 0x%x\n", Status)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase ReadyToBoot Success.\n")); + } + + Status = gBS->LocateProtocol ( + &gAddPerfRecordProtocolGuid, + NULL, + (VOID**) &AddPerfRecordInterface + ); + if (EFI_ERROR (Status)) { + DEBUG((DEBUG_INFO, "gAddPerfRecordProtocolGuid - Locate protocol failed\n")); + return; + } else { + Hob.Raw = GetHobList (); + if (Hob.Raw != NULL) { + Hob.Raw = GetNextGuidHob (&gFspHobGuid, Hob.Raw); + FspHobListPtr = GET_GUID_HOB_DATA(Hob.Raw); + AddPerfRecordInterface->AddPerformanceRecords((VOID *)(UINTN)(((UINT32)(UINTN)*FspHobListPtr) & 0xFFFFFFFF)); + } + } +} + +/** + This stage is notified just before the firmware/Preboot environment transfers + management of all system resources to the OS or next level execution environment. + + @param Event Event whose notification function is being invoked. + @param Context Pointer to the notification function's context, which is + always zero in current implementation. + +**/ +VOID +EFIAPI +OnEndOfFirmware ( + IN EFI_EVENT Event, + IN VOID *Context + ) +{ + NOTIFY_PHASE_PARAMS NotifyPhaseParams; + EFI_STATUS Status; + + gBS->CloseEvent (Event); + + NotifyPhaseParams.Phase = EnumInitPhaseEndOfFirmware; + PERF_START_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x2000); + Status = CallFspNotifyPhase (&NotifyPhaseParams); + PERF_END_EX(&gFspApiPerformanceGuid, "EventRec", NULL, 0, 0x207F); + if (Status != EFI_SUCCESS) { + DEBUG((DEBUG_ERROR, "FSP NotifyPhase EndOfFirmware failed, status: 0x%x\n", Status)); + } else { + DEBUG((DEBUG_INFO, "FSP NotifyPhase EndOfFirmware Success.\n")); + } +} + +/** + Main entry for the FSP DXE module. + + This routine registers two callbacks to call fsp's notifies. + + @param[in] ImageHandle The firmware allocated handle for the EFI image. + @param[in] SystemTable A pointer to the EFI System Table. + + @retval EFI_SUCCESS The entry point is executed successfully. + @retval other Some error occurs when executing this entry point. + +**/ +EFI_STATUS +EFIAPI +FspWrapperNotifyDxeEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_EVENT ReadyToBootEvent; + VOID *Registration; + EFI_EVENT ProtocolNotifyEvent; + + // + // Load this driver's image to memory + // + Status = RelocateImageUnder4GIfNeeded (ImageHandle, SystemTable); + if (EFI_ERROR (Status)) { + return EFI_SUCCESS; + } + + ProtocolNotifyEvent = EfiCreateProtocolNotifyEvent ( + &gEfiPciEnumerationCompleteProtocolGuid, + TPL_CALLBACK, + OnPciEnumerationComplete, + NULL, + &Registration + ); + ASSERT (ProtocolNotifyEvent != NULL); + + Status = EfiCreateEventReadyToBootEx ( + TPL_CALLBACK, + OnReadyToBoot, + NULL, + &ReadyToBootEvent + ); + ASSERT_EFI_ERROR (Status); + + Status = gBS->CreateEventEx ( + EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + OnEndOfFirmware, + NULL, + &gEfiEventExitBootServicesGuid, + &mExitBootServicesEvent + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} + diff --git a/IntelFspWrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf b/IntelFspWrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf new file mode 100644 index 0000000..7587df5 --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperNotifyDxe/FspWrapperNotifyDxe.inf @@ -0,0 +1,66 @@ +## @file +# FSP DXE Module +# +# This driver will register two callbacks to call fsp's notifies. +# +# Copyright (c) 2014 - 2016, 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. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FspWrapperNotifyDxe + FILE_GUID = 8714C537-6D4B-4247-AA6C-29E8495F9100 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = FspWrapperNotifyDxeEntryPoint + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + FspWrapperNotifyDxe.c + LoadBelow4G.c + +[Packages] + MdePkg/MdePkg.dec + IntelFspPkg/IntelFspPkg.dec + IntelFspWrapperPkg/IntelFspWrapperPkg.dec + +[LibraryClasses] + UefiDriverEntryPoint + UefiBootServicesTableLib + DebugLib + BaseMemoryLib + UefiLib + FspWrapperApiLib + PeCoffLib + CacheMaintenanceLib + DxeServicesLib + PerformanceLib + HobLib + +[Protocols] + gEfiPciEnumerationCompleteProtocolGuid ## CONSUMES + gAddPerfRecordProtocolGuid ## CONSUMES + +[Guids] + gFspApiPerformanceGuid ## CONSUMES ## GUID + gEfiEventExitBootServicesGuid ## CONSUMES ## Event + gFspHobGuid ## CONSUMES ## HOB + +[Pcd] + gFspWrapperTokenSpaceGuid.PcdFspsBaseAddress ## CONSUMES + +[Depex] + TRUE diff --git a/IntelFspWrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c b/IntelFspWrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c new file mode 100644 index 0000000..c073703 --- /dev/null +++ b/IntelFspWrapperPkg/FspWrapperNotifyDxe/LoadBelow4G.c @@ -0,0 +1,152 @@ +/** @file + +Copyright (c) 2015 - 2016, 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 ((DEBUG_INFO, "FspNotifyDxe - 2nd entry\n")); + return EFI_SUCCESS; + } + + DEBUG ((DEBUG_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 ((DEBUG_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 ((DEBUG_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; +} -- 2.7.4.windows.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel