summaryrefslogtreecommitdiff
path: root/Core/CORE_PEI/CORE_PEI_PI/PeiMain.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/CORE_PEI/CORE_PEI_PI/PeiMain.c')
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/PeiMain.c404
1 files changed, 404 insertions, 0 deletions
diff --git a/Core/CORE_PEI/CORE_PEI_PI/PeiMain.c b/Core/CORE_PEI/CORE_PEI_PI/PeiMain.c
new file mode 100644
index 0000000..31c5db1
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/PeiMain.c
@@ -0,0 +1,404 @@
+/*++
+
+Copyright (c) 2006 - 2007, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+ PeiMain.c
+
+Abstract:
+
+ Pei Core Main Entry Point
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_PPI_DEFINITION (MemoryDiscovered)
+#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+#include EFI_GUID_DEFINITION (StatusCode)
+
+//
+// CAR is filled with this initial value during SEC phase
+//
+#define INIT_CAR_VALUE 0x5AA55AA5
+
+#ifdef EFI_PEI_PERFORMANCE
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ );
+
+#endif
+
+//*** AMI PORTING BEGIN ***//
+VOID InitParts(VOID* p1, VOID*p2);
+VOID InitPartsMem(VOID* p1, VOID*p2);
+VOID ProcessLoadHob(EFI_PEI_SERVICES **PeiServices);
+VOID AmiInitParts(IN EFI_PEI_SERVICES **PeiServices, VOID* InitFunction);
+//*** AMI PORTING END *****//
+
+//
+// PPI that represents memory being discoverd in PEI.
+//
+static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiMemoryDiscoveredPpiGuid,
+ NULL
+};
+
+static EFI_PEI_SERVICES mPS = {
+ {
+ PEI_SERVICES_SIGNATURE,
+ PEI_SERVICES_REVISION,
+ sizeof (EFI_PEI_SERVICES),
+ 0,
+ 0
+ },
+ PeiInstallPpi,
+ PeiReInstallPpi,
+ PeiLocatePpi,
+ PeiNotifyPpi,
+
+ PeiGetBootMode,
+ PeiSetBootMode,
+
+ PeiGetHobList,
+ PeiCreateHob,
+
+ PeiFfsFindNextVolume,
+ PeiFfsFindNextFile,
+ PeiFfsFindSectionData,
+
+ PeiInstallPeiMemory,
+ PeiAllocatePages,
+ PeiAllocatePool,
+ PeiCoreCopyMem,
+ PeiCoreSetMem,
+
+ PeiReportStatusCode,
+ PeiResetSystem,
+
+ NULL,
+ NULL,
+
+ PeiFfsFindFileByName,
+ PeiFfsGetFileInfo,
+ PeiFfsGetVolumeInfo,
+ PeiRegisterForShadow
+};
+
+
+//
+// Main entry point to the PEI Core
+//
+EFI_PEI_CORE_ENTRY_POINT (PeiMain)
+
+EFI_STATUS
+EFIAPI
+PeiMain (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList
+ )
+/*++
+
+Routine Description:
+
+ Main entry point to Pei Core.
+
+Arguments:
+
+ SecCoreData - Information about the PEI core's operating environment.
+ PpList - Points to a list of one or more PPI descriptors to be
+ installed initially by the PEI core.
+
+Returns:
+
+ This function never returns
+
+--*/
+{
+ return PeiCore (SecCoreData,PpList, NULL);
+}
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ The entry routine to Pei Core, invoked by PeiMain during transition
+ from SEC to PEI. After switching stack in the PEI core, it will restart
+ with the old core data.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ PpList - Pointer to Ppi list provided by SEC phase.
+ OldCoreData - Pointer to old core data that is used to initialize the
+ core's data areas.
+
+Returns:
+
+ This function never returns
+ EFI_NOT_FOUND - Never reach
+
+--*/
+{
+ PEI_CORE_INSTANCE PrivateData;
+ EFI_PEI_SERVICES **PeiServices;
+ EFI_STATUS Status;
+ EFI_DXE_IPL_PPI *DxeIpl;
+ EFI_PEI_CPU_IO_PPI *CpuIo;
+ EFI_PEI_PCI_CFG2_PPI *PciCfg;
+
+#ifdef EFI_PEI_PERFORMANCE
+ UINT64 mTick;
+
+ mTick = 0;
+ if (OldCoreData == NULL) {
+ GetTimerValue (&mTick);
+ }
+#endif
+
+
+ //
+ // For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()
+ // the 63-bit of address is set to 1.
+ //
+ SWITCH_TO_CACHE_MODE (OldCoreData);
+
+ if (OldCoreData != NULL) {
+
+ //
+ // 2nd time through we are using System Memory and we restore a previous
+ // state by copying the OldCoreData into PrivateData. A lot of the
+ // init code will note initialize PrivateData on the 2nd pass.
+ //
+ PeiCoreCopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
+
+ //
+ // 2nd time through Pei Core has been shadowed. To Pei Services,
+ // CpuIo and PciCfg services may have been updated by some Pei Modules. So before
+ // update PrivateData.ServiceTableShadow with memory version, save the CpuIo
+ // PciCfg and restore them then.
+ //
+ CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;
+ PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;
+ PeiCoreCopyMem (&(PrivateData.ServiceTableShadow), &mPS, sizeof (EFI_PEI_SERVICES));
+ PrivateData.ServiceTableShadow.CpuIo = CpuIo;
+ PrivateData.ServiceTableShadow.PciCfg = PciCfg;
+ } else {
+
+ //
+ // 1st time through we are using Temp memory
+ //
+ PeiCoreSetMem (&PrivateData, sizeof (PEI_CORE_INSTANCE),0);
+ PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
+
+ //
+ // Copy PeiServices from ROM to Temp memory in PrivateData
+ //
+ PeiCoreCopyMem (&(PrivateData.ServiceTableShadow), &mPS, sizeof (EFI_PEI_SERVICES));
+ }
+
+ PrivateData.PS = &PrivateData.ServiceTableShadow;
+ PeiServices = &PrivateData.PS;
+
+ InitializeMemoryServices (&PrivateData, SecCoreData, OldCoreData);
+
+ InitializePpiServices (&PrivateData, OldCoreData);
+
+ //
+ // Save PeiServicePointer so that it can be retrieved anywhere.
+ //
+ SetPeiServicesTablePointer(PeiServices);
+
+ if (OldCoreData != NULL) {
+
+ PEI_PERF_END (&PrivateData.PS,L"PreMem", NULL, 0);
+ PEI_PERF_START (&PrivateData.PS,L"PostMem", NULL, 0);
+
+ //
+ // The following code dumps out interesting cache as RAM usage information
+ // so we can keep tabs on how the cache as RAM is being utilized. The
+ // PEI_DEBUG_CODE macro is used to prevent this code from being compiled
+ // on a debug build.
+ //
+ PEI_DEBUG_CODE (
+ {
+ UINTN *StackPointer;
+ UINTN StackValue;
+
+ StackValue = INIT_CAR_VALUE;
+ for (StackPointer = (UINTN *) OldCoreData->TopOfCarHeap;
+ ((UINTN) StackPointer < ((UINTN) OldCoreData->BottomOfCarHeap + OldCoreData->SizeOfCacheAsRam))
+ && StackValue == INIT_CAR_VALUE;
+ StackPointer++) {
+ StackValue = *StackPointer;
+ }
+
+ PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "Total Cache as RAM: %d bytes.\n", OldCoreData->SizeOfCacheAsRam));
+ PEI_DEBUG (
+ (
+ &PrivateData.PS, EFI_D_INFO, " CAR stack ever used: %d bytes.\n",
+ ((UINTN) OldCoreData->MaxTopOfCarHeap - (UINTN) StackPointer)
+ )
+ );
+ PEI_DEBUG (
+ (
+ &PrivateData.PS, EFI_D_INFO, " CAR heap used: %d bytes.\n",
+ ((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -
+ (UINTN) OldCoreData->HobList.Raw)
+ )
+ );
+ }
+ )
+
+//*** AMI PORTING BEGIN ***//
+ PrivateData.LoadedImage->Ppi = &PrivateData.LoadedImagePpi;
+//*** AMI PORTING END *****//
+
+ //
+ // Alert any listeners that there is permanent memory available
+ //
+ PEI_PERF_START (&PrivateData.PS,L"DisMem", NULL, 0);
+ Status = PeiInstallPpi (&PrivateData.PS, &mMemoryDiscoveredPpi);
+ PEI_PERF_END (&PrivateData.PS,L"DisMem", NULL, 0);
+
+ } else {
+
+ //
+ // Report Status Code EFI_SW_PC_INIT
+ //
+ PEI_REPORT_STATUS_CODE (
+ &(PrivateData.PS),
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT,
+ 0,
+ NULL,
+ NULL
+ );
+
+ //
+ // If first pass, start performance measurement.
+ //
+ PEI_PERF_START (&PrivateData.PS,L"PreMem", NULL, mTick);
+
+ //
+ // If SEC provided any PPI services to PEI, install them.
+ //
+ if (PpList != NULL) {
+ Status = PeiInstallPpi (&PrivateData.PS, PpList);
+ ASSERT_PEI_ERROR (&PrivateData.PS, Status);
+ }
+//*** AMI PORTING BEGIN ***//
+{
+ static EFI_GUID gEfiPeiLoadedImagePpiGuid = EFI_PEI_LOADED_IMAGE_PPI_GUID;
+ static EFI_PEI_PPI_DESCRIPTOR LoadedImagePpiDesc =
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiLoadedImagePpiGuid, NULL
+ };
+ PeiAllocatePool(&PrivateData.PS,sizeof(EFI_PEI_PPI_DESCRIPTOR),&PrivateData.LoadedImage);
+ *PrivateData.LoadedImage = LoadedImagePpiDesc;
+ PrivateData.LoadedImage->Ppi = &PrivateData.LoadedImagePpi;
+ PeiInstallPpi (&PrivateData.PS, PrivateData.LoadedImage);
+}
+//*** AMI PORTING END *****//
+ }
+
+ InitializeSecurityServices (&PrivateData, OldCoreData);
+
+ InitializeDispatcherData (&PrivateData, OldCoreData, SecCoreData);
+
+ //
+ // Install Pei Load File PPI.
+ //
+ InitializeImageServices (&PrivateData, OldCoreData);
+
+ //
+ // Call PEIM dispatcher
+ //
+//*** AMI PORTING BEGIN ***//
+ if (OldCoreData != NULL) {
+ AmiInitParts(PeiServices, InitPartsMem);
+ ProcessLoadHob(PeiServices);
+ } else {
+ AmiInitParts(PeiServices, InitParts);
+ }
+//*** AMI PORTING END *****//
+ PeiDispatcher (SecCoreData, &PrivateData);
+
+ //
+ // Check if InstallPeiMemory service was called.
+ //
+//*** AMI PORTING BEGIN ***//
+ //report MEMORY_NOT_INSTALLED error
+ if (!PrivateData.PeiMemoryInstalled)
+ PEI_ERROR_CODE(&PrivateData.PS, PEI_MEMORY_NOT_INSTALLED, EFI_ERROR_MAJOR);
+// PEI_ASSERT(&PrivateData.PS, PrivateData.PeiMemoryInstalled == TRUE);
+//*** AMI PORTING END *****//
+
+ PEI_PERF_END (&PrivateData.PS, L"PostMem", NULL, 0);
+
+ DxeIpl = PeiReturnPpi (&PrivateData.PS, &gEfiDxeIplPpiGuid);
+//*** AMI PORTING BEGIN ***//
+ //report DXEIPL_NOT_FOUND error
+ if (DxeIpl==NULL)
+ PEI_ERROR_CODE(&PrivateData.PS, PEI_DXEIPL_NOT_FOUND, EFI_ERROR_MAJOR);
+// PEI_ASSERT (&PrivateData.PS, DxeIpl != NULL);
+//*** AMI PORTING END *****//
+
+ PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "DXE IPL Entry\n"));
+
+//*** AMI PORTING BEGIN ***//
+ //DxeIpl->Entry (DxeIpl, &PrivateData.PS, PrivateData.HobList);
+ DxeIpl->Entry (DxeIpl, &PrivateData.PS, PrivateData.HobList.Raw);
+//*** AMI PORTING END *****//
+//*** AMI PORTING BEGIN ***//
+ // If DXE IPL returned control, let's call dispatcher again
+ // DXE IPL might have dicovered new FV or have changed a boot mode
+
+ // reset previous bitmap so that the dispatcher will attempt to execute any new PEIMs
+ // dispatch
+ PeiDispatcher (SecCoreData, &PrivateData);
+ // DXE IPL
+ DxeIpl->Entry (DxeIpl, &PrivateData.PS, PrivateData.HobList.Raw);
+//*** AMI PORTING END *****//
+ PEI_ASSERT (&PrivateData.PS,FALSE);
+ return EFI_NOT_FOUND;
+
+}
+
+//*** AMI PORTING BEGIN ***//
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+)
+{
+ PEI_CORE_INSTANCE *Private = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+ Private->LoadedImagePpi.ImageAddress = ImageAddress;
+ Private->LoadedImagePpi.ImageSize = ImageSize;
+ Private->LoadedImagePpi.FileHandle = FileHandle;
+ PeiReInstallPpi(PeiServices,Private->LoadedImage,Private->LoadedImage);
+}
+//*** AMI PORTING END *****//