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

Reply via email to