summaryrefslogtreecommitdiff
path: root/Core/CORE_PEI/DxeIpl.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/CORE_PEI/DxeIpl.c')
-rw-r--r--Core/CORE_PEI/DxeIpl.c838
1 files changed, 838 insertions, 0 deletions
diff --git a/Core/CORE_PEI/DxeIpl.c b/Core/CORE_PEI/DxeIpl.c
new file mode 100644
index 0000000..8a1a129
--- /dev/null
+++ b/Core/CORE_PEI/DxeIpl.c
@@ -0,0 +1,838 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_PEI/DxeIpl.c 4 10/25/12 8:50a Wesleychen $
+//
+// $Revision: 4 $
+//
+// $Date: 10/25/12 8:50a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_PEI/DxeIpl.c $
+//
+// 4 10/25/12 8:50a Wesleychen
+// - Update Core to 4.6.5.4.
+// - Fixed system hang at CKP 0x4F during S3 resume if HT is disabled.
+//
+// 45 5/21/12 10:42a Artems
+// [TAG] EIP87678
+// [Category] Improvement
+// [Description] Select ROM image to use on BOOT_ON_FLASH_UPDATE path
+// We have two images - one already in flash (old) and one in reflash
+// capsule
+// We can use either one to boot
+// [Files] DxeIpl.c
+//
+// 44 4/20/12 2:23p Artems
+// [TAG] EIP87678
+// [Category] New Feature
+// [Description] Select image to boot from on flash update boot path -
+// either old one (currently in flash) or new one (in recovery capsule)
+// [Files] Recovery.c DxeIpl.c Core.sdl Tokens.c
+//
+// 43 11/01/11 1:57p Felixp
+// [TAG] EIP 69841 and 71719
+// [Category] Improvement
+// [Description] The AMI customizations are removed from the DXE memory
+// manager.
+// They are replaced with the Memory Type Information HOB used in Tiano
+// projects.
+// This is done to reduces number of descriptors in the memory map
+// and to workaround Windows bug (Windows can't handle memory allocations
+// that happen after the start of the OS loader).
+// [Files] CORE_DXE.sdl, Page.c, BDS.c, DxeIpl.c
+//
+// 42 7/19/11 11:29a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 41 6/02/11 4:49p Artems
+//
+// 40 5/13/11 5:12p Artems
+// Preserved boot mode when recovery/flash update failed for error
+// reporting
+//
+// 39 5/05/11 3:44p Artems
+// Bugfix: different FV count for PI 0.9 and PI 1.0 specification
+//
+// 38 2/15/11 12:35p Artems
+// Added workaround so in recovery DXE_CORE ffs will be picked from right
+// FV
+//
+// 37 2/05/11 3:48p Artems
+// Added new ROM layout infrastructure support
+// Replaced call to FFS PPI with library function to work both in PI 0.91
+// and 1.0 modes
+//
+// 36 10/01/10 4:33p Felixp
+// Debug message with DXE Core addres is moved to after the instalaltion
+// of the END of PEI PPI
+//
+// 35 11/13/09 4:32p Felixp
+// Buffer overflow protection is added (calls to Sprintf replaced with
+// Sprintf_s).
+//
+// 34 7/10/09 4:32p Artems
+// Added function headers
+//
+// 33 5/21/09 5:19p Felixp
+// RomLayout support. Call to ReportFvDxeIpl is added.
+//
+// 32 5/07/08 12:23p Felixp
+// Converted to use new Performance API
+//
+// 31 4/18/08 6:27p Felixp
+// DXE_CORE_STARTED reported at the very end of PEI phase
+//
+// 30 4/20/07 5:10p Felixp
+// Status codes added
+//
+// 29 4/19/07 1:03p Felixp
+//
+// 27 4/17/07 9:07a Felixp
+// S3 & Recovery Status Codes removed. They are reported by the S3 &
+// Recovery PEIM
+//
+// 26 3/13/07 1:46a Felixp
+// Error reporting updated to use new PEI_ERROR_CODE macro
+//
+// 25 3/12/07 10:26a Felixp
+// LoadedImage PPI support added (defined in PI 1.0; used by AmiDebugger)
+//
+// 23 11/02/06 10:25p Felixp
+// Install EFI_PEI_END_OF_PEI_PHASE_PPI_GUID right before launching DXE
+// Core
+//
+// 22 8/25/06 10:58a Felixp
+//
+// 21 8/24/06 9:43a Felixp
+// Preliminary x64 support (work in progress)
+// DXE Core interfaces are no longer passed from PEI Core.
+// They are linked directly with DXE Core
+//
+// 20 6/04/06 10:50p Ambikas
+//
+// 19 5/22/06 12:14a Felixp
+// More status/error codes added
+//
+// 18 3/13/06 9:51a Felixp
+//
+// 17 12/01/05 9:52a Felixp
+// Recovery Logic changed: RecoveryModule PPI is used. Capsule processing
+// is moved to Recovery.c
+//
+// 16 10/09/05 11:25a Felixp
+// Performance measurements added.
+//
+// 15 6/16/05 10:56a Felixp
+// 1. Once memory is available, PEI Core PEIMs that created PEIM_LOAD_HOB
+// are reallocated to memory.
+// 2. ImagePei.c removed
+// 3. FileLoader moved from DxeIpl to PEI Core
+//
+// 14 6/06/05 1:25p Felixp
+// Type parameter removed from AllocatePages to match PEI CIS 0.91
+//
+// 13 3/25/05 5:47p Felixp
+// 1. S3 boot path: call of S3RestoreConfig added
+// 3. Recovery boot path: trace messages added
+//
+// 12 3/24/05 6:48p Felixp
+//
+// 11 3/22/05 10:03p Felixp
+// Recovery Support
+//
+// 10 3/17/05 1:54p Felixp
+// implementation of S3Resume boot path started
+//
+// 9 3/17/05 1:45p Felixp
+// Bug fix in memory installed callback (status was not checked)
+//
+// 8 3/04/05 9:39a Mandal
+//
+// 7 1/25/05 3:37p Felixp
+//
+// 6 1/25/05 3:26p Felixp
+// Once memory is available DxeIpl realocates itself to memory and
+// installs
+// LoadFile PPI
+//
+// 5 1/22/05 12:29p Felixp
+// Bug fix:
+// Last parameter to AllocatePages was VOID* instead of
+// EFI_PHYSICAL_ADDRESS, which
+// resulted in a stack corruption.
+//
+// 4 1/22/05 11:29a Felixp
+//
+// 2 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/23/04 9:42a Felixp
+//
+// 19 12/20/04 5:10p Felixp
+//
+// 18 12/20/04 4:54p Felixp
+//
+// 17 12/17/04 6:59p Felixp
+// PEI_DEBUG_MSG renamed to PEI_TRACE
+//
+// 16 11/24/04 9:38a Felixp
+// format of debug message changed
+//
+// 15 11/19/04 1:23a Felixp
+//
+// 14 11/10/04 5:18p Felixp
+// Debug message added
+//
+// 13 10/21/04 2:47p Felixp
+// Support for DXE Core compression added
+//
+// 12 7/13/04 10:42a Felixp
+//
+// 11 4/11/04 2:49p Felixp
+//
+// 10 4/07/04 12:46a Felixp
+// REAL PLATFORM DEBUGGING (lots of bug fixes)
+//
+// 9 3/29/04 6:06p Felixp
+//
+// 8 3/29/04 5:40p Felixp
+//
+// 7 3/28/04 2:11p Felixp
+// 1. PE Loader and some other commonly used code moved to the Library
+// 2. Warnings fixed (from now on warning will be treated as error)
+//
+// 6 3/20/04 12:03p Felixp
+//
+// 5 2/19/04 10:08a Felixp
+// Debugging code removed.
+//
+// 4 2/11/04 12:29a Felixp
+//
+// 3 2/10/04 4:02p Felixp
+//
+// 2 2/04/04 2:04a Felixp
+// work in progress...
+//
+// 1 1/28/04 3:23a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DxeIpl.c
+//
+// Description: DXE Core Loader
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//-----------------------------------------------------------------------------
+
+#include <PEI.h>
+#include <HOB.h>
+#include <AmiHobs.h>
+#include <AmiPeiLib.h>
+#include <PPI/RecoveryModule.h>
+#include <PPI/S3Resume2.h>
+#include <PPI/S3Resume.h>
+#include <PPI/LoadedImagePpi.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <token.h>
+#include <AmiHobs.h>
+#include "Core/CPU/CPU.h"
+#include "Core/CPU/CpuCspLib.h"
+
+#define SMM_ASM_FIXUP_SMM_BASE 0x38002
+#define SMM_ASM_FIXUP_IED_ZERO_MEM 0x38029
+#define SMM_ASM_BASE_CHANGE_FLAG 0x3808f
+#define APIC_SMI (2 << 8)
+#define APIC_LEVEL_ASSERT (1 << 14)
+#define APIC_NO_SHORT_HAND (0 << 18)
+
+//-----------------------------------------------------------------------------
+
+//****************************************************************************/
+// TYPE DECLARATIONS
+//****************************************************************************/
+typedef VOID (EFIAPI *DXE_ENTRY_POINT)(
+ IN VOID *HobStart
+);
+
+//****************************************************************************/
+// FUNCTION DECLARATIONS
+//****************************************************************************/
+EFI_STATUS EFIAPI Entry(
+ IN EFI_DXE_IPL_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *HobList
+);
+
+#ifdef x64_BUILD_SUPPORT
+VOID InitLongMode(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1
+);
+#endif
+
+//****************************************************************************/
+// VARIABLE DECLARATIONS
+//****************************************************************************/
+// PPIs
+EFI_DXE_IPL_PPI DxeIplPpi = { Entry };
+EFI_GUID guidDxeIpl = EFI_DXE_IPL_PPI_GUID;
+EFI_GUID guidEndOfPei = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+
+// PPI to be installed
+static EFI_PEI_PPI_DESCRIPTOR PpiList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidDxeIpl, &DxeIplPpi
+ }
+};
+
+static EFI_PEI_PPI_DESCRIPTOR EndOfPpiList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidEndOfPei, NULL
+ }
+};
+
+EFI_PEI_LOADED_IMAGE_PPI LoadedImagePpi;
+EFI_GUID guidLoadedImage = EFI_PEI_LOADED_IMAGE_PPI_GUID;
+static EFI_PEI_PPI_DESCRIPTOR LoadedImagePpiDesc[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidLoadedImage, &LoadedImagePpi
+ }
+};
+
+// The order of elements in this array is important.
+// It defines the order of memory types in the DXE memory map.
+// The first array element corresponds to the type with the largest address.
+// Keeping boot time memory types at the bottom of the list improves
+// stability of the runtime portions of the memory map
+// which is important during S4 resume.
+CONST EFI_MEMORY_TYPE_INFORMATION DefaultMemoryTypeInformation[] = {
+ { EfiRuntimeServicesCode, 0x30 },
+ { EfiRuntimeServicesData, 0x20 },
+ { EfiACPIMemoryNVS, 0x60 },
+ { EfiACPIReclaimMemory, 0x10 },
+ { EfiReservedMemoryType, 0x30 },
+ { EfiBootServicesCode, 0x600 },
+ { EfiBootServicesData, 0x1500 },
+ { EfiMaxMemoryType, 0 } // indicates the end of the table
+};
+
+//****************************************************************************/
+// IMPLEMENTATION
+//****************************************************************************/
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: LoadDxeCore
+//
+// Description:
+// Loads DXE core file into memory
+//
+// Input:
+// IN EFI_PEI_SERVICES **ppPS - pointer to PEI services structure
+// IN EFI_FIRMWARE_VOLUME_HEADER *pFV - pointer to firmware volume header
+// OUT EFI_FFS_FILE_HEADER **ppFile - pointer to returned FFS file header
+// OUT EFI_PHYSICAL_ADDRESS *pAddress - pointer to returned address where file loaded
+// OUT UINT64 *pSize - pointer to returned file size
+// OUT EFI_PHYSICAL_ADDRESS *pEntry - pointer to returned address of entry point
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - DXE core loaded successfully
+// EFI_ERROR - DXE core file not found or cannot be loaded
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS LoadDxeCore(
+ IN EFI_PEI_SERVICES **ppPS,
+ IN EFI_FIRMWARE_VOLUME_HEADER *pFV,
+ OUT EFI_FFS_FILE_HEADER **ppFile,
+ OUT EFI_PHYSICAL_ADDRESS *pAddress,
+ OUT UINT64 *pSize,
+ OUT EFI_PHYSICAL_ADDRESS *pEntry
+)
+{
+ EFI_STATUS Status;
+ *ppFile = NULL;
+ // loop via all files
+ while(TRUE)
+ {
+ Status = (*ppPS)->FfsFindNextFile(ppPS, EFI_FV_FILETYPE_DXE_CORE, pFV, ppFile);
+ if( EFI_ERROR(Status) ) return Status;
+ Status = PeiLoadFile(ppPS,*ppFile,pAddress,pSize,pEntry);
+ if( !EFI_ERROR(Status) ) return Status;
+ }
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: S3Resume
+//
+// Description:
+// Implementation of S3 wake boot path
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - S3 resume boot path is failed or cannot be found
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS S3Resume(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_PEI_S3_RESUME2_PPI *pS32;
+ EFI_PEI_S3_RESUME_PPI *pS3;
+ EFI_PEI_PPI_DESCRIPTOR *pDummy;
+ EFI_STATUS Status;
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "S3Resume\n"));
+ Status = (*PeiServices)->LocatePpi(PeiServices,&gEfiPeiS3Resume2PpiGuid,0,&pDummy,&pS32);
+ if (EFI_ERROR(Status))
+ {
+ Status = (*PeiServices)->LocatePpi(PeiServices,&gPeiS3ResumePpiGuid,0,&pDummy,&pS3);
+ if (EFI_ERROR(Status))
+ {
+ PEI_ERROR_CODE(PeiServices,PEI_S3_RESUME_PPI_NOT_FOUND,EFI_ERROR_MAJOR);
+ return Status;
+ }
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "Calling S3RestoreConfig\n"));
+ return pS3->S3RestoreConfig(PeiServices);
+ }
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "Calling S3RestoreConfig2\n"));
+ return pS32->S3RestoreConfig2(pS32);
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: Recovery
+//
+// Description:
+// Implementation of recovery boot path
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - recovery capsule not found
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS Recovery(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ static EFI_GUID guidRecoveryModule = EFI_PEI_RECOVERY_MODULE_PPI_GUID;
+ EFI_PEI_RECOVERY_MODULE_PPI *pRecovery;
+ EFI_PEI_PPI_DESCRIPTOR *pDummy;
+ EFI_STATUS Status = (*PeiServices)->LocatePpi(PeiServices,&guidRecoveryModule,0,&pDummy,&pRecovery);
+ if (EFI_ERROR(Status)){
+ PEI_ERROR_CODE(PeiServices,PEI_RECOVERY_PPI_NOT_FOUND,EFI_ERROR_MAJOR);
+ return Status;
+ }
+ return pRecovery->LoadRecoveryCapsule(PeiServices,pRecovery);
+}
+
+//defined in ReportFv2.c
+EFI_STATUS ReportFV2Dxe(
+ IN VOID* RecoveryCapsule OPTIONAL,
+ IN EFI_PEI_SERVICES **PeiServices
+);
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: FindRecoveryBuffer
+//
+// Description:
+// Searches for recovery capsule address in HOB
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+// OUT VOID **Buffer - pointer where to store found address
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - recovery capsule not found
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindRecoveryBuffer(
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT VOID **Buffer
+)
+{
+ EFI_STATUS Status;
+ RECOVERY_IMAGE_HOB *RecoveryHob;
+ static EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+
+ Status = (*PeiServices)->GetHobList(PeiServices, &RecoveryHob);
+ if(EFI_ERROR(Status))
+ return Status; //we are not on recovery boot path
+
+ Status = FindNextHobByGuid(&RecoveryHobGuid, &RecoveryHob);
+ if(EFI_ERROR(Status))
+ return Status; //we are not on recovery boot path
+
+ if(RecoveryHob->Status == EFI_SUCCESS && RecoveryHob->Address != NULL) {
+ *Buffer = (VOID *)(UINTN)RecoveryHob->Address;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+extern const BOOLEAN UseNewImage;
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: PublishDxeFv
+//
+// Description:
+// Publishes Firmware volumes required for DXE phase
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+// IN EFI_BOOT_MODE BootMode - current boot mode
+//
+// Output:
+// UINTN - Number of next firmware volume to start search for DXE_CORE from
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN PublishDxeFv(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+)
+{
+ EFI_STATUS Status;
+ UINTN FvNum = 0;
+ VOID *RecoveryBuffer = NULL;
+ EFI_FIRMWARE_VOLUME_HEADER* pFV;
+
+/* first check for recovery/flashupdate capsule
+BOOT_IN_RECOVERY_MODE - actual recovery or flash update via recovery capsule on disk (in latter case
+boot mode will be changed to BOOT_ON_FLASH_UPDATE after call to Recovery() function)
+BOOT_ON_FLASH_UPDATE - flash update via recovery capsule in memory
+*/
+ if (BootMode == BOOT_IN_RECOVERY_MODE || BootMode == BOOT_ON_FLASH_UPDATE) {
+ Status = Recovery(PeiServices);
+ if (!EFI_ERROR(Status)) {
+ Status = FindRecoveryBuffer(PeiServices, &RecoveryBuffer);
+ (*PeiServices)->GetBootMode(PeiServices, &BootMode); //check if boot mode changed
+ }
+
+ if(EFI_ERROR(Status)) {
+ /* we can't find recovery capsule, report error */
+ PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_FAILED, EFI_ERROR_MAJOR);
+ }
+ }
+
+ if(RecoveryBuffer != NULL) {
+ if(BootMode == BOOT_IN_RECOVERY_MODE || UseNewImage) {
+#if PI_SPECIFICATION_VERSION >= 0x00010000
+ /* when we're in recovery we publish DXE Fv from recovery buffer, instead of flash */
+ while( !EFI_ERROR((*PeiServices)->FfsFindNextVolume(PeiServices, FvNum, &pFV)))
+ FvNum++; //determine how many FVs published already
+#endif
+ Status = ReportFV2Dxe(RecoveryBuffer, PeiServices);
+ if(!EFI_ERROR(Status)) {
+ return FvNum;
+ } else {
+ /* we can't publish recovery capsule, report error */
+ PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_FAILED, EFI_ERROR_MAJOR);
+ }
+ }
+ }
+
+ Status = ReportFV2Dxe(NULL, PeiServices);
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: Entry
+//
+// Description:
+// Implementation of EFI_DXE_IPL_PPI Entry function
+//
+// Input:
+// IN EFI_DXE_IPL_PPI *This - pointer to PPI instance
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+// IN EFI_HOB_HANDOFF_INFO_TABLE *HobList - pointer to HOB list
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - Boot failed
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI Entry(
+ IN EFI_DXE_IPL_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *HobList
+)
+{
+ EFI_FIRMWARE_VOLUME_HEADER* pFV;
+ UINTN FvNum;
+ EFI_PHYSICAL_ADDRESS DxeCoreAddress, DxeCoreEntry;
+ UINT64 DxeCoreSize;
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER* pFile;
+ EFI_BOOT_MODE BootMode=(EFI_BOOT_MODE)-1; //set it to invalid value
+ EFI_PEI_LOADED_IMAGE_PPI *OldLoadedImagePpi;
+ EFI_PEI_PPI_DESCRIPTOR *OldLoadedImageDesc;
+#ifdef EFI_DEBUG
+ CHAR8 sName[0x100];
+#endif
+ EFI_MEMORY_TYPE_INFORMATION MemoryInformationBuffer[EfiMaxMemoryType + 1];
+ EFI_MEMORY_TYPE_INFORMATION *MemoryInformationPtr = NULL;
+ UINTN MemoryInformationSize;
+ EFI_HOB_GUID_TYPE *MemoryInformationHob;
+
+ PEI_PERF_START(PeiServices,DXEIPL_TOK, NULL,0);
+ PEI_PROGRESS_CODE(PeiServices,PEI_DXE_IPL_STARTED);
+
+ (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ if (BootMode == BOOT_ON_S3_RESUME) {
+#ifndef AMI_CPU_S3_PEI_SUPPORT
+#define AMI_CPU_S3_PEI_SUPPORT 0
+#endif
+#if AMI_CPU_S3_PEI_SUPPORT == 0
+ {
+ VOID *FirstHob;
+ SMM_HOB *SmmHob;
+ EFI_GUID gSmmHobGuid = SMM_HOB_GUID;
+ VOID *SaveBuffer;
+ UINT8 ApicId;
+ UINT8 i,j;
+
+ (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ SmmHob = (SMM_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &SmmHob)))
+ {
+ if (guidcmp(&SmmHob->EfiHobGuidType.Name, &gSmmHobGuid) == 0)
+ break;
+ }
+ if (!EFI_ERROR(Status))
+ {
+ //Allocate memory for temporarly perserve the 3000:8000 data.
+ Status = (*PeiServices)->AllocatePool(
+ PeiServices,
+ SmmGetBaseSaveBufferSize(),
+ &SaveBuffer
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ SmmSetupDefaultHandler(SaveBuffer, SmmHob);
+
+ for (i = 0, j = 0; i < SmmHob->NumCpus; ++i)
+ {
+ *(UINT32*)SMM_ASM_FIXUP_SMM_BASE = (UINT32)SmmHob->SmmBase[i];
+ *(UINT8*)SMM_ASM_BASE_CHANGE_FLAG = 0; //Initialize Flag
+
+ ApicId = j;
+ MemReadWrite32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_HIGH_REGISTER), ApicId << 24, 0x00ffffff);
+ MemReadWrite32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_LOW_REGISTER), APIC_NO_SHORT_HAND + APIC_LEVEL_ASSERT + APIC_SMI, 0);
+
+ while (!(*(volatile UINT8*)SMM_ASM_BASE_CHANGE_FLAG))
+ {
+ CPULib_Pause(); //Wait on Flag
+ }
+ ++*(UINT16*)SMM_ASM_FIXUP_IED_ZERO_MEM; //Only 0, for first thread to clear IED memory.
+
+ if (IsHtEnabled())
+ {
+ j++;
+ }
+ else
+ {
+ j += 2;
+ }
+ }
+
+ SmmRemoveDefaultHandler(SaveBuffer);
+ }
+ }
+#endif
+ PEI_PERF_END(PeiServices, DXEIPL_TOK, NULL, 0);
+ S3Resume(PeiServices);
+ //if S3 Resume failed, report error and reset system
+ PEI_ERROR_CODE(PeiServices, PEI_S3_RESUME_FAILED, EFI_ERROR_MAJOR);
+ (*PeiServices)->ResetSystem(PeiServices);
+ } else {
+ FvNum = PublishDxeFv(PeiServices, BootMode);
+ }
+
+ while( !EFI_ERROR ((*PeiServices)->FfsFindNextVolume (PeiServices, FvNum++, &pFV) )
+ && EFI_ERROR(Status=LoadDxeCore(PeiServices,pFV,&pFile,&DxeCoreAddress,&DxeCoreSize,&DxeCoreEntry))
+ );
+ if (EFI_ERROR(Status))
+ {
+ PEI_ERROR_CODE(PeiServices,PEI_DXE_CORE_NOT_FOUND,EFI_ERROR_MAJOR);
+ PEI_PERF_END(PeiServices,DXEIPL_TOK, NULL,0);
+ return Status;
+ }
+ //Create module allocation HOB for DXE Core
+ CreateHobMemoryAllocationModule(
+ PeiServices, DxeCoreAddress, DxeCoreSize,
+ EfiBootServicesCode, &pFile->Name,
+ DxeCoreEntry
+ );
+
+ // Create a MemoryTypeInformation HOB (used by DXE memory manager)
+
+ // There can only be a single memory type information HOB.
+ // Invalidate other HOB instances (if any).
+ Status = (*PeiServices)->GetHobList(PeiServices, &MemoryInformationHob);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ while (!EFI_ERROR(
+ FindNextHobByGuid(&gEfiMemoryTypeInformationGuid, &MemoryInformationHob)
+ )) MemoryInformationHob->Header.HobType = EFI_HOB_TYPE_UNUSED;
+
+ MemoryInformationSize = sizeof(MemoryInformationBuffer);
+
+ // In case of S4 resume, use memory type information
+ // from the last full boot (S5 resume).
+ // This preserves the memory map across sessions.
+ Status = PeiGetVariable (
+ PeiServices,
+ (BootMode == BOOT_ON_S4_RESUME)
+ ? L"PreviousMemoryTypeInformation"
+ : EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+ &gEfiMemoryTypeInformationGuid,
+ NULL, &MemoryInformationSize, MemoryInformationBuffer
+ );
+ if (EFI_ERROR(Status)){
+ MemoryInformationPtr = (EFI_MEMORY_TYPE_INFORMATION*)DefaultMemoryTypeInformation;
+ MemoryInformationSize = sizeof(DefaultMemoryTypeInformation);
+ }else{
+ MemoryInformationPtr=MemoryInformationBuffer;
+ }
+ Status = (*PeiServices)->CreateHob (
+ PeiServices, EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(EFI_HOB_GUID_TYPE) + MemoryInformationSize,
+ &MemoryInformationHob
+ );
+ if (!EFI_ERROR(Status)) {
+ MemoryInformationHob->Name = gEfiMemoryTypeInformationGuid;
+ MemCpy( MemoryInformationHob+1, MemoryInformationPtr, MemoryInformationSize);
+ }
+
+
+ //Update LoadedImage PPI information
+ LoadedImagePpi.ImageAddress = DxeCoreAddress;
+ LoadedImagePpi.ImageSize = DxeCoreSize;
+ LoadedImagePpi.FileHandle = pFile;
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices, &guidLoadedImage,
+ 0, &OldLoadedImageDesc, &OldLoadedImagePpi
+ );
+ if (!(EFI_ERROR(Status))) { // if Loaded Image PPI was located
+ Status = (*PeiServices)->ReInstallPpi (
+ PeiServices, OldLoadedImageDesc, LoadedImagePpiDesc
+ );
+ } else {
+ // Loaded Image PPI not found, try installing it again.
+ Status = (*PeiServices)->InstallPpi(
+ PeiServices,LoadedImagePpiDesc
+ );
+ }
+ PEI_PERF_END(PeiServices,DXEIPL_TOK, NULL,0);
+ (*PeiServices)->InstallPpi(PeiServices,EndOfPpiList);
+#ifdef EFI_DEBUG
+ if (!GetName((VOID*)DxeCoreAddress,sName)) Sprintf_s(sName,sizeof(sName),"DXE-Core");
+ PeiTrace(TRACE_DXEIPL, PeiServices, "%s.Entry(%X)\n", sName, DxeCoreEntry);
+#endif
+ PEI_PROGRESS_CODE(PeiServices,DXE_CORE_STARTED);
+#ifdef x64_BUILD_SUPPORT
+ InitLongMode(
+ PeiServices, (VOID*)(UINTN)DxeCoreEntry, HobList
+ );
+#else
+ ((DXE_ENTRY_POINT )DxeCoreEntry)(HobList);
+#endif
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: PeiInitDxeIpl
+//
+// Description:
+// DXE loader entry point
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader - pointer to FFS file header
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - EFI_DXE_IPL_PPI installed successfully
+// EFI_ERROR - error occured during execution
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiInitDxeIpl (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ return (*PeiServices)->InstallPpi(PeiServices,PpiList);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************