diff options
Diffstat (limited to 'Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c')
-rw-r--r-- | Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c | 405 |
1 files changed, 405 insertions, 0 deletions
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c new file mode 100644 index 0000000..bfcdbe4 --- /dev/null +++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c @@ -0,0 +1,405 @@ +/*++ + +Copyright (c) 2004 - 2005, 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_PPI_DEFINITION (FindFv) +#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 *****// + +static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gPeiMemoryDiscoveredPpiGuid, + NULL +}; + +// +// Pei Core Module Variables +// +// +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, + + PeiFvFindNextVolume, + PeiFfsFindNextFile, + PeiFfsFindSectionData, + + PeiInstallPeiMemory, + PeiAllocatePages, + PeiAllocatePool, + PeiCoreCopyMem, + PeiCoreSetMem, + + PeiReportStatusCode, + +//*** AMI PORTING BEGIN ***// +// This is a bug fix. +// In accordance with PEI CIS 0.91 +// this structure has been extended with two more pointers. +// PeiCoreResetSystem + PeiCoreResetSystem, + NULL, + NULL +//*** AMI PORTING END *****// +}; + +VOID +EFIAPI +AsmWriteMm7 ( + IN UINT64 Value + ); + +EFI_STATUS +EFIAPI +PeiCore ( + IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor, + IN PEI_CORE_INSTANCE *OldCoreData + ); + +// +// Main entry point to the PEI Core +// +EFI_PEI_CORE_ENTRY_POINT (PeiMain) + +EFI_STATUS +EFIAPI +PeiMain ( + IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor + ) +/*++ + +Routine Description: + + Main entry point to Pei Core. + +Arguments: + + PeiStartupDescriptor - Information and services provided by SEC phase. + +Returns: + + This function never returns + +--*/ +{ + return PeiCore (PeiStartupDescriptor, NULL); +} + +EFI_STATUS +EFIAPI +PeiCore ( + IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor, + 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: + + PeiStartupDescriptor - Information and services 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_STATUS Status; + PEI_CORE_TEMP_POINTERS TempPtr; + PEI_CORE_DISPATCH_DATA *DispatchData; + + +#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) { + PeiCoreCopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE)); + } else { + PeiCoreSetMem (&PrivateData, sizeof (PEI_CORE_INSTANCE), 0); + } + + PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE; + PrivateData.PS = &mPS; + + // + // Mm7 stored PeiServicesTablePointer in EdkII Glue Library + // Update Mm7 now + // +//*** AMI PORTING BEGIN ***// +//#if (defined(EFI32)) || (defined(EFIX64)) +#ifndef EFI64 +//*** AMI PORTING END *****// + AsmWriteMm7 ((UINT64)(UINTN)(&PrivateData.PS)); +#endif + + InitializeMemoryServices (&PrivateData.PS, PeiStartupDescriptor, OldCoreData); + + InitializePpiServices (&PrivateData.PS, OldCoreData); + + InitializeSecurityServices (&PrivateData.PS, OldCoreData); + + InitializeDispatcherData (&PrivateData.PS, OldCoreData, PeiStartupDescriptor); + + 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->MaxTopOfCarHeap; + ((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->TopOfCarHeap - (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 (PeiStartupDescriptor->DispatchTable != NULL) { + Status = PeiInstallPpi (&PrivateData.PS, PeiStartupDescriptor->DispatchTable); + + 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 *****// + } + + DispatchData = &PrivateData.DispatchData; + + // + // Call PEIM dispatcher + // +//*** AMI PORTING BEGIN ***// + if (OldCoreData != NULL) { + AmiInitParts(&PrivateData.PS, InitPartsMem); + ProcessLoadHob(&PrivateData.PS); + } else { + AmiInitParts(&PrivateData.PS, InitParts); + } +//*** AMI PORTING END *****// + PeiDispatcher (PeiStartupDescriptor, &PrivateData, DispatchData); + + // + // 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); + + Status = PeiLocatePpi ( + &PrivateData.PS, + &gEfiDxeIplPpiGuid, + 0, + NULL, + &TempPtr.DxeIpl + ); +//*** AMI PORTING BEGIN ***// + //report DXEIPL_NOT_FOUND error + if (EFI_ERROR(Status)) + PEI_ERROR_CODE(&PrivateData.PS, PEI_DXEIPL_NOT_FOUND, EFI_ERROR_MAJOR); +// ASSERT_PEI_ERROR (&PrivateData.PS, Status); +//*** AMI PORTING END *****// + + PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "DXE IPL Entry(%X)\n",TempPtr.DxeIpl->Entry)); + Status = TempPtr.DxeIpl->Entry ( + TempPtr.DxeIpl, + &PrivateData.PS, +//*** AMI PORTING BEGIN ***// +// PEI CIS defines parameter as EFI_PEI_HOB_POINTERS, but +// EFI_PEI_HOB_POINTERS is not defined in PEI CIS. +// Until this is fixed PEI.h defines this parameter as VOID* +// PrivateData.HobList + 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 + DispatchData->PreviousPeimBitMap = 0; + // dispatch + PeiDispatcher (PeiStartupDescriptor, &PrivateData, DispatchData); + // DXE IPL + Status = TempPtr.DxeIpl->Entry ( + TempPtr.DxeIpl, + &PrivateData.PS, + PrivateData.HobList.Raw + ); +//*** AMI PORTING END *****// + ASSERT_PEI_ERROR (&PrivateData.PS, Status); + 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 *****//
\ No newline at end of file |