summaryrefslogtreecommitdiff
path: root/Platform/BroxtonPlatformPkg/Common/SampleCode/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
diff options
context:
space:
mode:
Diffstat (limited to 'Platform/BroxtonPlatformPkg/Common/SampleCode/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c')
-rw-r--r--Platform/BroxtonPlatformPkg/Common/SampleCode/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c1304
1 files changed, 0 insertions, 1304 deletions
diff --git a/Platform/BroxtonPlatformPkg/Common/SampleCode/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/Platform/BroxtonPlatformPkg/Common/SampleCode/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
deleted file mode 100644
index 7b2de6aad2..0000000000
--- a/Platform/BroxtonPlatformPkg/Common/SampleCode/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ /dev/null
@@ -1,1304 +0,0 @@
-/** @file
- EFI PEI Core dispatch services.
-
- Copyright (c) 2006 - 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 "PeiMain.h"
-
-///
-/// temporary memory is filled with this initial value during SEC phase
-///
-#define INIT_CAR_VALUE 0x5AA55AA5
-
-typedef struct {
- EFI_STATUS_CODE_DATA DataHeader;
- EFI_HANDLE Handle;
-} PEIM_FILE_HANDLE_EXTENDED_DATA;
-
-/**
- Discover all Peims and optional Apriori file in one FV. There is at most one
- Apriori file in one FV.
-
- @param[in] Private Pointer to the private data passed in from caller
- @param[in] CoreFileHandle The instance of PEI_CORE_FV_HANDLE.
-
-**/
-VOID
-DiscoverPeimsAndOrderWithApriori (
- IN PEI_CORE_INSTANCE *Private,
- IN PEI_CORE_FV_HANDLE *CoreFileHandle
- )
-{
- EFI_STATUS Status;
- EFI_PEI_FILE_HANDLE FileHandle;
- EFI_PEI_FILE_HANDLE AprioriFileHandle;
- EFI_GUID *Apriori;
- UINTN Index;
- UINTN Index2;
- UINTN PeimIndex;
- UINTN PeimCount;
- EFI_GUID *Guid;
- EFI_PEI_FILE_HANDLE *TempFileHandles;
- EFI_GUID *FileGuid;
- EFI_PEI_FIRMWARE_VOLUME_PPI *FvPpi;
- EFI_FV_FILE_INFO FileInfo;
-
- FvPpi = CoreFileHandle->FvPpi;
-
- //
- // Walk the FV and find all the PEIMs and the Apriori file.
- //
- AprioriFileHandle = NULL;
- Private->CurrentFvFileHandles[0] = NULL;
- Guid = NULL;
- FileHandle = NULL;
- TempFileHandles = Private->FileHandles;
- FileGuid = Private->FileGuid;
-
- //
- // If the current Fv has been scanned, directly get its cachable record.
- //
- if (Private->Fv[Private->CurrentPeimFvCount].ScanFv) {
- CopyMem (Private->CurrentFvFileHandles, Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv));
- return;
- }
-
- //
- // Go ahead to scan this Fv, and cache FileHandles within it.
- //
- Status = EFI_NOT_FOUND;
- for (PeimCount = 0; PeimCount <= PcdGet32 (PcdPeiCoreMaxPeimPerFv); PeimCount++) {
- Status = FvPpi->FindFileByType (FvPpi, PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE, CoreFileHandle->FvHandle, &FileHandle);
- if (Status != EFI_SUCCESS || PeimCount == PcdGet32 (PcdPeiCoreMaxPeimPerFv)) {
- break;
- }
-
- Private->CurrentFvFileHandles[PeimCount] = FileHandle;
- }
-
- //
- // Check whether the count of files exceeds the max support files in a FV image
- // If more files are required in a FV image, PcdPeiCoreMaxPeimPerFv can be set to a larger value in DSC file.
- //
- ASSERT ((Status != EFI_SUCCESS) || (PeimCount < PcdGet32 (PcdPeiCoreMaxPeimPerFv)));
-
- //
- // Get Apriori File handle
- //
- Private->AprioriCount = 0;
- Status = FvPpi->FindFileByName (FvPpi, &gPeiAprioriFileNameGuid, &CoreFileHandle->FvHandle, &AprioriFileHandle);
- if (!EFI_ERROR(Status) && AprioriFileHandle != NULL) {
- //
- // Read the Apriori file
- //
- Status = FvPpi->FindSectionByType (FvPpi, EFI_SECTION_RAW, AprioriFileHandle, (VOID **) &Apriori);
- if (!EFI_ERROR (Status)) {
- //
- // Calculate the number of PEIMs in the A Priori list
- //
- Status = FvPpi->GetFileInfo (FvPpi, AprioriFileHandle, &FileInfo);
- ASSERT_EFI_ERROR (Status);
- Private->AprioriCount = FileInfo.BufferSize;
- if (IS_SECTION2 (FileInfo.Buffer)) {
- Private->AprioriCount -= sizeof (EFI_COMMON_SECTION_HEADER2);
- } else {
- Private->AprioriCount -= sizeof (EFI_COMMON_SECTION_HEADER);
- }
- Private->AprioriCount /= sizeof (EFI_GUID);
-
- for (Index = 0; Index < PeimCount; Index++) {
- //
- // Make an array of file name guids that matches the FileHandle array so we can convert
- // quickly from file name to file handle
- //
- Status = FvPpi->GetFileInfo (FvPpi, Private->CurrentFvFileHandles[Index], &FileInfo);
- CopyMem (&FileGuid[Index], &FileInfo.FileName, sizeof(EFI_GUID));
- }
-
- //
- // Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file.
- // Add available PEIMs in Apriori file into TempFileHandles array at first.
- //
- Index2 = 0;
- for (Index = 0; Index2 < Private->AprioriCount; Index++) {
- while (Index2 < Private->AprioriCount) {
- Guid = ScanGuid (FileGuid, PeimCount * sizeof (EFI_GUID), &Apriori[Index2++]);
- if (Guid != NULL) {
- break;
- }
- }
- if (Guid == NULL) {
- break;
- }
- PeimIndex = ((UINTN)Guid - (UINTN)&FileGuid[0])/sizeof (EFI_GUID);
- TempFileHandles[Index] = Private->CurrentFvFileHandles[PeimIndex];
-
- //
- // Since we have copied the file handle we can remove it from this list.
- //
- Private->CurrentFvFileHandles[PeimIndex] = NULL;
- }
-
- //
- // Update valid Aprioricount
- //
- Private->AprioriCount = Index;
-
- //
- // Add in any PEIMs not in the Apriori file
- //
- for (;Index < PeimCount; Index++) {
- for (Index2 = 0; Index2 < PeimCount; Index2++) {
- if (Private->CurrentFvFileHandles[Index2] != NULL) {
- TempFileHandles[Index] = Private->CurrentFvFileHandles[Index2];
- Private->CurrentFvFileHandles[Index2] = NULL;
- break;
- }
- }
- }
- //
- //Index the end of array contains re-range Pei moudle.
- //
- TempFileHandles[Index] = NULL;
-
- //
- // Private->CurrentFvFileHandles is currently in PEIM in the FV order.
- // We need to update it to start with files in the A Priori list and
- // then the remaining files in PEIM order.
- //
- CopyMem (Private->CurrentFvFileHandles, TempFileHandles, sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv));
- }
- }
- //
- // Cache the current Fv File Handle. So that we don't have to scan the Fv again.
- // Instead, we can retrieve the file handles within this Fv from cachable data.
- //
- Private->Fv[Private->CurrentPeimFvCount].ScanFv = TRUE;
- CopyMem (Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, Private->CurrentFvFileHandles, sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv));
-
-}
-
-//
-// This is the minimum memory required by DxeCore initialization. When LMFA feature enabled,
-// This part of memory still need reserved on the very top of memory so that the DXE Core could
-// use these memory for data initialization. This macro should be sync with the same marco
-// defined in DXE Core.
-//
-#define MINIMUM_INITIAL_MEMORY_SIZE 0x10000
-/**
- This function is to test if the memory range described in resource HOB is available or not.
-
- This function should only be invoked when Loading Module at Fixed Address(LMFA) feature is enabled. Some platform may allocate the
- memory before PeiLoadFixAddressHook in invoked. so this function is to test if the memory range described by the input resource HOB is
- available or not.
-
- @param[in] PrivateData Pointer to the private data passed in from caller
- @param[in] ResourceHob Pointer to a resource HOB which described the memory range described by the input resource HOB
-
-**/
-BOOLEAN
-PeiLoadFixAddressIsMemoryRangeAvailable (
- IN PEI_CORE_INSTANCE *PrivateData,
- IN EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob
- )
-{
- EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
- BOOLEAN IsAvailable;
- EFI_PEI_HOB_POINTERS Hob;
-
- IsAvailable = TRUE;
- if (PrivateData == NULL || ResourceHob == NULL) {
- return FALSE;
- }
- //
- // test if the memory range describe in the HOB is already allocated.
- //
- for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
- //
- // See if this is a memory allocation HOB
- //
- if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
- MemoryHob = Hob.MemoryAllocation;
- if(MemoryHob->AllocDescriptor.MemoryBaseAddress == ResourceHob->PhysicalStart &&
- MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength == ResourceHob->PhysicalStart + ResourceHob->ResourceLength) {
- IsAvailable = FALSE;
- break;
- }
- }
- }
-
- return IsAvailable;
-}
-
-/**
- Hook function for Loading Module at Fixed Address feature
-
- This function should only be invoked when Loading Module at Fixed Address(LMFA) feature is enabled. When feature is
- configured as Load Modules at Fix Absolute Address, this function is to validate the top address assigned by user. When
- feature is configured as Load Modules at Fixed Offset, the functino is to find the top address which is TOLM-TSEG in general.
- And also the function will re-install PEI memory.
-
- @param[in] PrivateData Pointer to the private data passed in from caller
-
-**/
-VOID
-PeiLoadFixAddressHook(
- IN PEI_CORE_INSTANCE *PrivateData
- )
-{
- EFI_PHYSICAL_ADDRESS TopLoadingAddress;
- UINT64 PeiMemorySize;
- UINT64 TotalReservedMemorySize;
- UINT64 MemoryRangeEnd;
- EFI_PHYSICAL_ADDRESS HighAddress;
- EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
- EFI_HOB_RESOURCE_DESCRIPTOR *NextResourceHob;
- EFI_HOB_RESOURCE_DESCRIPTOR *CurrentResourceHob;
- EFI_PEI_HOB_POINTERS CurrentHob;
- EFI_PEI_HOB_POINTERS Hob;
- EFI_PEI_HOB_POINTERS NextHob;
- EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
-
- //
- // Initialize Local Variables
- //
- CurrentResourceHob = NULL;
- ResourceHob = NULL;
- NextResourceHob = NULL;
- HighAddress = 0;
- TopLoadingAddress = 0;
- MemoryRangeEnd = 0;
- CurrentHob.Raw = PrivateData->HobList.Raw;
- PeiMemorySize = PrivateData->PhysicalMemoryLength;
-
- //
- // The top reserved memory include 3 parts: the topest range is for DXE core initialization with the size MINIMUM_INITIAL_MEMORY_SIZE
- // then RuntimeCodePage range and Boot time code range.
- //
- TotalReservedMemorySize = MINIMUM_INITIAL_MEMORY_SIZE + EFI_PAGES_TO_SIZE (PcdGet32 (PcdLoadFixAddressRuntimeCodePageNumber));
- TotalReservedMemorySize+= EFI_PAGES_TO_SIZE (PcdGet32 (PcdLoadFixAddressBootTimeCodePageNumber));
-
- //
- // PEI memory range lies below the top reserved memory
- //
- TotalReservedMemorySize += PeiMemorySize;
-
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressRuntimeCodePageNumber= 0x%x.\n", PcdGet32 (PcdLoadFixAddressRuntimeCodePageNumber)));
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressBootTimeCodePageNumber= 0x%x.\n", PcdGet32 (PcdLoadFixAddressBootTimeCodePageNumber)));
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressPeiCodePageNumber= 0x%x.\n", PcdGet32 (PcdLoadFixAddressPeiCodePageNumber)));
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: Total Reserved Memory Size = 0x%lx.\n", TotalReservedMemorySize));
-
- //
- // Loop through the system memory typed hob to merge the adjacent memory range
- //
- for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
- //
- // See if this is a resource descriptor HOB
- //
- if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
-
- ResourceHob = Hob.ResourceDescriptor;
- //
- // If range described in this hob is not system memory or heigher than MAX_ADDRESS, ignored.
- //
- if (ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY ||
- ResourceHob->PhysicalStart + ResourceHob->ResourceLength > MAX_ADDRESS) {
- continue;
- }
-
- for (NextHob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(NextHob); NextHob.Raw = GET_NEXT_HOB(NextHob)) {
- if (NextHob.Raw == Hob.Raw){
- continue;
- }
- //
- // See if this is a resource descriptor HOB
- //
- if (GET_HOB_TYPE (NextHob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
-
- NextResourceHob = NextHob.ResourceDescriptor;
- //
- // test if range described in this NextResourceHob is system memory and have the same attribute.
- // Note: Here is a assumption that system memory should always be healthy even without test.
- //
- if (NextResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
- (((NextResourceHob->ResourceAttribute^ResourceHob->ResourceAttribute)&(~EFI_RESOURCE_ATTRIBUTE_TESTED)) == 0)){
-
- //
- // See if the memory range described in ResourceHob and NextResourceHob is adjacent
- //
- if ((ResourceHob->PhysicalStart <= NextResourceHob->PhysicalStart &&
- ResourceHob->PhysicalStart + ResourceHob->ResourceLength >= NextResourceHob->PhysicalStart)||
- (ResourceHob->PhysicalStart >= NextResourceHob->PhysicalStart&&
- ResourceHob->PhysicalStart <= NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength)) {
-
- MemoryRangeEnd = ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength)>(NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength)) ?
- (ResourceHob->PhysicalStart + ResourceHob->ResourceLength):(NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength);
-
- ResourceHob->PhysicalStart = (ResourceHob->PhysicalStart < NextResourceHob->PhysicalStart) ?
- ResourceHob->PhysicalStart : NextResourceHob->PhysicalStart;
-
-
- ResourceHob->ResourceLength = (MemoryRangeEnd - ResourceHob->PhysicalStart);
-
- ResourceHob->ResourceAttribute = ResourceHob->ResourceAttribute & (~EFI_RESOURCE_ATTRIBUTE_TESTED);
- //
- // Delete the NextResourceHob by marking it as unused.
- //
- GET_HOB_TYPE (NextHob) = EFI_HOB_TYPE_UNUSED;
-
- }
- }
- }
- }
- }
- }
- //
- // Some platform is already allocated pages before the HOB re-org. Here to build dedicated resource HOB to describe
- // the allocated memory range
- //
- for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
- //
- // See if this is a memory allocation HOB
- //
- if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
- MemoryHob = Hob.MemoryAllocation;
- for (NextHob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(NextHob); NextHob.Raw = GET_NEXT_HOB(NextHob)) {
- //
- // See if this is a resource descriptor HOB
- //
- if (GET_HOB_TYPE (NextHob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
- NextResourceHob = NextHob.ResourceDescriptor;
- //
- // If range described in this hob is not system memory or heigher than MAX_ADDRESS, ignored.
- //
- if (NextResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY || NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength > MAX_ADDRESS) {
- continue;
- }
- //
- // If the range describe in memory allocation HOB belongs to the memroy range described by the resource hob
- //
- if (MemoryHob->AllocDescriptor.MemoryBaseAddress >= NextResourceHob->PhysicalStart &&
- MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength <= NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength) {
- //
- // Build seperate resource hob for this allocated range
- //
- if (MemoryHob->AllocDescriptor.MemoryBaseAddress > NextResourceHob->PhysicalStart) {
- BuildResourceDescriptorHob (
- EFI_RESOURCE_SYSTEM_MEMORY,
- NextResourceHob->ResourceAttribute,
- NextResourceHob->PhysicalStart,
- (MemoryHob->AllocDescriptor.MemoryBaseAddress - NextResourceHob->PhysicalStart)
- );
- }
- if (MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength < NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength) {
- BuildResourceDescriptorHob (
- EFI_RESOURCE_SYSTEM_MEMORY,
- NextResourceHob->ResourceAttribute,
- MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength,
- (NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength -(MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength))
- );
- }
- NextResourceHob->PhysicalStart = MemoryHob->AllocDescriptor.MemoryBaseAddress;
- NextResourceHob->ResourceLength = MemoryHob->AllocDescriptor.MemoryLength;
- break;
- }
- }
- }
- }
- }
-
- //
- // Try to find and validate the TOP address.
- //
- if ((INT64)PcdGet64(PcdLoadModuleAtFixAddressEnable) > 0 ) {
- //
- // The LMFA feature is enabled as load module at fixed absolute address.
- //
- TopLoadingAddress = (EFI_PHYSICAL_ADDRESS)PcdGet64(PcdLoadModuleAtFixAddressEnable);
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: Loading module at fixed absolute address.\n"));
- //
- // validate the Address. Loop the resource descriptor HOB to make sure the address is in valid memory range
- //
- if ((TopLoadingAddress & EFI_PAGE_MASK) != 0) {
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:Top Address 0x%lx is invalid since top address should be page align. \n", TopLoadingAddress));
- ASSERT (FALSE);
- }
- //
- // Search for a memory region that is below MAX_ADDRESS and in which TopLoadingAddress lies
- //
- for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
- //
- // See if this is a resource descriptor HOB
- //
- if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
-
- ResourceHob = Hob.ResourceDescriptor;
- //
- // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS
- //
- if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
- ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS) {
- //
- // See if Top address specified by user is valid.
- //
- if (ResourceHob->PhysicalStart + TotalReservedMemorySize < TopLoadingAddress &&
- (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MINIMUM_INITIAL_MEMORY_SIZE) >= TopLoadingAddress &&
- PeiLoadFixAddressIsMemoryRangeAvailable(PrivateData, ResourceHob)) {
- CurrentResourceHob = ResourceHob;
- CurrentHob = Hob;
- break;
- }
- }
- }
- }
- if (CurrentResourceHob != NULL) {
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO:Top Address 0x%lx is valid \n", TopLoadingAddress));
- TopLoadingAddress += MINIMUM_INITIAL_MEMORY_SIZE;
- } else {
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:Top Address 0x%lx is invalid \n", TopLoadingAddress));
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:The recommended Top Address for the platform is: \n"));
- //
- // Print the recomended Top address range.
- //
- for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
- //
- // See if this is a resource descriptor HOB
- //
- if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
-
- ResourceHob = Hob.ResourceDescriptor;
- //
- // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS
- //
- if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
- ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS) {
- //
- // See if Top address specified by user is valid.
- //
- if (ResourceHob->ResourceLength > TotalReservedMemorySize && PeiLoadFixAddressIsMemoryRangeAvailable(PrivateData, ResourceHob)) {
- DEBUG ((EFI_D_INFO, "(0x%lx, 0x%lx)\n",
- (ResourceHob->PhysicalStart + TotalReservedMemorySize -MINIMUM_INITIAL_MEMORY_SIZE),
- (ResourceHob->PhysicalStart + ResourceHob->ResourceLength -MINIMUM_INITIAL_MEMORY_SIZE)
- ));
- }
- }
- }
- }
- //
- // Assert here
- //
- ASSERT (FALSE);
- return;
- }
- } else {
- //
- // The LMFA feature is enabled as load module at fixed offset relative to TOLM
- // Parse the Hob list to find the topest available memory. Generally it is (TOLM - TSEG)
- //
- //
- // Search for a tested memory region that is below MAX_ADDRESS
- //
- for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
- //
- // See if this is a resource descriptor HOB
- //
- if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
-
- ResourceHob = Hob.ResourceDescriptor;
- //
- // See if this resource descrior HOB describes tested system memory below MAX_ADDRESS
- //
- if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
- ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS &&
- ResourceHob->ResourceLength > TotalReservedMemorySize && PeiLoadFixAddressIsMemoryRangeAvailable(PrivateData, ResourceHob)) {
- //
- // See if this is the highest largest system memory region below MaxAddress
- //
- if (ResourceHob->PhysicalStart > HighAddress) {
- CurrentResourceHob = ResourceHob;
- CurrentHob = Hob;
- HighAddress = CurrentResourceHob->PhysicalStart;
- }
- }
- }
- }
- if (CurrentResourceHob == NULL) {
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED ERROR:The System Memory is too small\n"));
- //
- // Assert here
- //
- ASSERT (FALSE);
- return;
- } else {
- TopLoadingAddress = CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength ;
- }
- }
-
- if (CurrentResourceHob != NULL) {
- //
- // rebuild resource HOB for PEI memmory and reserved memory
- //
- BuildResourceDescriptorHob (
- EFI_RESOURCE_SYSTEM_MEMORY,
- (
- EFI_RESOURCE_ATTRIBUTE_PRESENT |
- EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
- EFI_RESOURCE_ATTRIBUTE_TESTED |
- EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
- ),
- (TopLoadingAddress - TotalReservedMemorySize),
- TotalReservedMemorySize
- );
- //
- // rebuild resource for the remain memory if necessary
- //
- if (CurrentResourceHob->PhysicalStart < TopLoadingAddress - TotalReservedMemorySize) {
- BuildResourceDescriptorHob (
- EFI_RESOURCE_SYSTEM_MEMORY,
- (
- EFI_RESOURCE_ATTRIBUTE_PRESENT |
- EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
- EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
- ),
- CurrentResourceHob->PhysicalStart,
- (TopLoadingAddress - TotalReservedMemorySize - CurrentResourceHob->PhysicalStart)
- );
- }
- if (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength > TopLoadingAddress ) {
- BuildResourceDescriptorHob (
- EFI_RESOURCE_SYSTEM_MEMORY,
- (
- EFI_RESOURCE_ATTRIBUTE_PRESENT |
- EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
- EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
- EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
- ),
- TopLoadingAddress,
- (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength - TopLoadingAddress)
- );
- }
- //
- // Delete CurrentHob by marking it as unused since the the memory range described by is rebuilt.
- //
- GET_HOB_TYPE (CurrentHob) = EFI_HOB_TYPE_UNUSED;
- }
-
- //
- // Cache the top address for Loading Module at Fixed Address feature
- //
- PrivateData->LoadModuleAtFixAddressTopAddress = TopLoadingAddress - MINIMUM_INITIAL_MEMORY_SIZE;
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: Top address = 0x%lx\n", PrivateData->LoadModuleAtFixAddressTopAddress));
- //
- // reinstall the PEI memory relative to TopLoadingAddress
- //
- PrivateData->PhysicalMemoryBegin = TopLoadingAddress - TotalReservedMemorySize;
- PrivateData->FreePhysicalMemoryTop = PrivateData->PhysicalMemoryBegin + PeiMemorySize;
-}
-
-/**
- This routine is invoked in switch stack as PeiCore Entry.
-
- @param[in] SecCoreData Points to a data structure containing information about the PEI core's operating
- environment, such as the size and location of temporary RAM, the stack location and
- the BFV location.
- @param[in] Private Pointer to old core data that is used to initialize the
- core's data areas.
-
-**/
-VOID
-EFIAPI
-PeiCoreEntry (
- IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
- IN PEI_CORE_INSTANCE *Private
- )
-{
- //
- // Entry PEI Phase 2
- //
- PeiCore (SecCoreData, NULL, Private);
-}
-
-/**
- Conduct PEIM dispatch.
-
- @param[in] SecCoreData Points to a data structure containing information about the PEI core's operating
- environment, such as the size and location of temporary RAM, the stack location and
- the BFV location.
- @param[in] Private Pointer to the private data passed in from caller
-
-**/
-VOID
-PeiDispatcher (
- IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
- IN PEI_CORE_INSTANCE *Private
- )
-{
- EFI_STATUS Status;
- UINT32 Index1;
- UINT32 Index2;
- CONST EFI_PEI_SERVICES **PeiServices;
- EFI_PEI_FILE_HANDLE PeimFileHandle;
- UINTN FvCount;
- UINTN PeimCount;
- UINT32 AuthenticationState;
- EFI_PHYSICAL_ADDRESS EntryPoint;
- EFI_PEIM_ENTRY_POINT2 PeimEntryPoint;
- UINTN SaveCurrentPeimCount;
- UINTN SaveCurrentFvCount;
- EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;
- PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData;
- EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;
- UINT64 NewStackSize;
- UINTN HeapTemporaryRamSize;
- EFI_PHYSICAL_ADDRESS BaseOfNewHeap;
- EFI_PHYSICAL_ADDRESS TopOfNewStack;
- EFI_PHYSICAL_ADDRESS TopOfOldStack;
- EFI_PHYSICAL_ADDRESS TemporaryRamBase;
- UINTN TemporaryRamSize;
- UINTN TemporaryStackSize;
- VOID *TemporaryStackBase;
- UINTN PeiTemporaryRamSize;
- VOID *PeiTemporaryRamBase;
- UINTN StackOffset;
- BOOLEAN StackOffsetPositive;
- EFI_PHYSICAL_ADDRESS HoleMemBase;
- UINTN HoleMemSize;
- EFI_FV_FILE_INFO FvFileInfo;
- PEI_CORE_FV_HANDLE *CoreFvHandle;
- VOID *LoadFixPeiCodeBegin;
- EFI_PHYSICAL_ADDRESS TempBase1;
- UINTN TempSize1;
- EFI_PHYSICAL_ADDRESS TempBase2;
- UINTN TempSize2;
- UINTN Index;
-
- PeiServices = (CONST EFI_PEI_SERVICES **) &Private->Ps;
- PeimEntryPoint = NULL;
- PeimFileHandle = NULL;
- EntryPoint = 0;
-
- if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {
- //
- // Once real memory is available, shadow the RegisterForShadow modules. And meanwhile
- // update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.
- //
- SaveCurrentPeimCount = Private->CurrentPeimCount;
- SaveCurrentFvCount = Private->CurrentPeimFvCount;
- SaveCurrentFileHandle = Private->CurrentFileHandle;
-
- for (Index1 = 0; Index1 <= SaveCurrentFvCount; Index1++) {
- for (Index2 = 0; (Index2 < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {
- if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) {
- PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];
- Status = PeiLoadImage (
- (CONST EFI_PEI_SERVICES **) &Private->Ps,
- PeimFileHandle,
- PEIM_STATE_REGISITER_FOR_SHADOW,
- &EntryPoint,
- &AuthenticationState
- );
- if (Status == EFI_SUCCESS) {
- //
- // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
- //
- Private->Fv[Index1].PeimState[Index2]++;
- Private->CurrentFileHandle = PeimFileHandle;
- Private->CurrentPeimFvCount = Index1;
- Private->CurrentPeimCount = Index2;
- //
- // Call the PEIM entry point
- //
- PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
-
- PERF_START (PeimFileHandle, "PEIM", NULL, 0);
- PeimEntryPoint(PeimFileHandle, (const EFI_PEI_SERVICES **) &Private->Ps);
- PERF_END (PeimFileHandle, "PEIM", NULL, 0);
- }
-
- //
- // Process the Notify list and dispatch any notifies for
- // newly installed PPIs.
- //
- ProcessNotifyList (Private);
- }
- }
- }
- Private->CurrentFileHandle = SaveCurrentFileHandle;
- Private->CurrentPeimFvCount = SaveCurrentFvCount;
- Private->CurrentPeimCount = SaveCurrentPeimCount;
- }
-
- //
- // This is the main dispatch loop. It will search known FVs for PEIMs and
- // attempt to dispatch them. If any PEIM gets dispatched through a single
- // pass of the dispatcher, it will start over from the Bfv again to see
- // if any new PEIMs dependencies got satisfied. With a well ordered
- // FV where PEIMs are found in the order their dependencies are also
- // satisfied, this dipatcher should run only once.
- //
- do {
- //
- // In case that reenter PeiCore happens, the last pass record is still available.
- //
- if (!Private->PeimDispatcherReenter) {
- Private->PeimNeedingDispatch = FALSE;
- Private->PeimDispatchOnThisPass = FALSE;
- } else {
- Private->PeimDispatcherReenter = FALSE;
- }
-
- for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) {
- CoreFvHandle = FindNextCoreFvHandle (Private, FvCount);
- ASSERT (CoreFvHandle != NULL);
-
- //
- // If the FV has corresponding EFI_PEI_FIRMWARE_VOLUME_PPI instance, then dispatch it.
- //
- if (CoreFvHandle->FvPpi == NULL) {
- continue;
- }
-
- Private->CurrentPeimFvCount = FvCount;
-
- if (Private->CurrentPeimCount == 0) {
- //
- // When going through each FV, at first, search Apriori file to
- // reorder all PEIMs to ensure the PEIMs in Apriori file to get
- // dispatch at first.
- //
- DiscoverPeimsAndOrderWithApriori (Private, CoreFvHandle);
- }
-
- //
- // Start to dispatch all modules within the current Fv.
- //
- for (PeimCount = Private->CurrentPeimCount;
- (PeimCount < PcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->CurrentFvFileHandles[PeimCount] != NULL);
- PeimCount++) {
- Private->CurrentPeimCount = PeimCount;
- PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount];
-
- if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) {
- if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {
- Private->PeimNeedingDispatch = TRUE;
- } else {
- Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeimFileHandle, &FvFileInfo);
- ASSERT_EFI_ERROR (Status);
- if (FvFileInfo.FileType == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
- //
- // For Fv type file, Produce new FV PPI and FV hob
- //
- Status = ProcessFvFile (Private, &Private->Fv[FvCount], PeimFileHandle);
- if (Status == EFI_SUCCESS) {
- //
- // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
- //
- Private->Fv[FvCount].PeimState[PeimCount]++;
- Private->PeimDispatchOnThisPass = TRUE;
- }
- } else {
- //
- // For PEIM driver, Load its entry point
- //
- Status = PeiLoadImage (
- PeiServices,
- PeimFileHandle,
- PEIM_STATE_NOT_DISPATCHED,
- &EntryPoint,
- &AuthenticationState
- );
- if (Status == EFI_SUCCESS) {
- //
- // The PEIM has its dependencies satisfied, and its entry point
- // has been found, so invoke it.
- //
- PERF_START (PeimFileHandle, "PEIM", NULL, 0);
-
- ExtendedData.Handle = (EFI_HANDLE) PeimFileHandle;
-
- REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
- EFI_PROGRESS_CODE,
- (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN),
- (VOID *) (&ExtendedData),
- sizeof (ExtendedData)
- );
-
- Status = VerifyPeim (Private, CoreFvHandle->FvHandle, PeimFileHandle, AuthenticationState);
- if (Status != EFI_SECURITY_VIOLATION) {
- //
- // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
- //
- Private->Fv[FvCount].PeimState[PeimCount]++;
- //
- // Call the PEIM entry point for PEIM driver
- //
- PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2) (UINTN) EntryPoint;
- PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);
- Private->PeimDispatchOnThisPass = TRUE;
- }
-
- REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
- EFI_PROGRESS_CODE,
- (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END),
- (VOID *) (&ExtendedData),
- sizeof (ExtendedData)
- );
- PERF_END (PeimFileHandle, "PEIM", NULL, 0);
-
- }
- }
-
- if (Private->SwitchStackSignal) {
- //
- // Before switch stack from temporary memory to permenent memory, caculate the heap and stack
- // usage in temporary memory for debuging.
- //
- DEBUG_CODE_BEGIN ();
- UINT32 *StackPointer;
- for (StackPointer = (UINT32 *) SecCoreData->StackBase;
- (StackPointer < (UINT32 *) ((UINTN) SecCoreData->StackBase + SecCoreData->StackSize)) \
- && (*StackPointer == INIT_CAR_VALUE);
- StackPointer ++);
-
- DEBUG ((EFI_D_INFO, "Temp Stack : BaseAddress=0x%p Length=0x%X\n", SecCoreData->StackBase, (UINT32) SecCoreData->StackSize));
- DEBUG ((EFI_D_INFO, "Temp Heap : BaseAddress=0x%p Length=0x%X\n", Private->HobList.Raw, (UINT32) ((UINTN) Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN) Private->HobList.Raw)));
- DEBUG ((EFI_D_INFO, "Total temporary memory: %d bytes.\n", (UINT32) SecCoreData->TemporaryRamSize));
- DEBUG ((EFI_D_INFO, " temporary memory stack ever used: %d bytes.\n",
- (UINT32) (SecCoreData->StackSize - ((UINTN) StackPointer - (UINTN) SecCoreData->StackBase))
- ));
- DEBUG ((EFI_D_INFO, " temporary memory heap used: %d bytes.\n",
- (UINT32) ((UINTN) Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN)Private->HobList.Raw)
- ));
- DEBUG_CODE_END ();
-
- if (PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0 && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
- //
- // Loading Module at Fixed Address is enabled
- //
- PeiLoadFixAddressHook (Private);
-
- //
- // If Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range.
- //
- LoadFixPeiCodeBegin = AllocatePages ((UINTN) PcdGet32 (PcdLoadFixAddressPeiCodePageNumber));
- DEBUG ((EFI_D_INFO, "LOADING MODULE FIXED INFO: PeiCodeBegin = 0x%lX, PeiCodeTop= 0x%lX\n", (UINT64) (UINTN) LoadFixPeiCodeBegin, (UINT64) ((UINTN) LoadFixPeiCodeBegin + PcdGet32 (PcdLoadFixAddressPeiCodePageNumber) * EFI_PAGE_SIZE)));
- }
-
- //
- // Reserve the size of new stack at bottom of physical memory
- //
- // The size of new stack in permenent memory must be the same size
- // or larger than the size of old stack in temporary memory.
- // But if new stack is smaller than the size of old stack, we also reserve
- // the size of old stack at bottom of permenent memory.
- //
- NewStackSize = RShiftU64 (Private->PhysicalMemoryLength, 1);
- NewStackSize = ALIGN_VALUE (NewStackSize, EFI_PAGE_SIZE);
- NewStackSize = MIN (PcdGet32 (PcdPeiCoreMaxPeiStackSize), NewStackSize);
- DEBUG ((EFI_D_INFO, "Old Stack size %d, New stack size %d\n", (UINT32) SecCoreData->StackSize, (UINT32) NewStackSize));
- ASSERT (NewStackSize >= SecCoreData->StackSize);
-
- //
- // Caculate stack offset and heap offset between temporary memory and new permement
- // memory seperately.
- //
- TopOfOldStack = (UINTN) SecCoreData->StackBase + SecCoreData->StackSize;
- TopOfNewStack = Private->PhysicalMemoryBegin + NewStackSize;
- if (TopOfNewStack >= TopOfOldStack) {
- StackOffsetPositive = TRUE;
- StackOffset = (UINTN) (TopOfNewStack - TopOfOldStack);
- } else {
- StackOffsetPositive = FALSE;
- StackOffset = (UINTN) (TopOfOldStack - TopOfNewStack);
- }
- Private->StackOffsetPositive = StackOffsetPositive;
- Private->StackOffset = StackOffset;
-
- //
- // Build Stack HOB that describes the permanent memory stack
- //
- DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%lX Length=0x%lX\n", TopOfNewStack - NewStackSize, NewStackSize));
- BuildStackHob (TopOfNewStack - NewStackSize, NewStackSize);
-
- //
- // Cache information from SecCoreData into locals before SecCoreData is converted to a permanent memory address
- //
- TemporaryRamBase = (EFI_PHYSICAL_ADDRESS) (UINTN) SecCoreData->TemporaryRamBase;
- TemporaryRamSize = SecCoreData->TemporaryRamSize;
- TemporaryStackSize = SecCoreData->StackSize;
- TemporaryStackBase = SecCoreData->StackBase;
- PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize;
- PeiTemporaryRamBase = SecCoreData->PeiTemporaryRamBase;
-
- //
- // TemporaryRamSupportPpi is produced by platform's SEC
- //
- Status = PeiServicesLocatePpi (
- &gEfiTemporaryRamSupportPpiGuid,
- 0,
- NULL,
- (VOID**) &TemporaryRamSupportPpi
- );
- if (!EFI_ERROR (Status)) {
- //
- // Heap Offset
- //
- BaseOfNewHeap = TopOfNewStack;
- if (BaseOfNewHeap >= (UINTN) SecCoreData->PeiTemporaryRamBase) {
- Private->HeapOffsetPositive = TRUE;
- Private->HeapOffset = (UINTN) (BaseOfNewHeap - (UINTN) SecCoreData->PeiTemporaryRamBase);
- } else {
- Private->HeapOffsetPositive = FALSE;
- Private->HeapOffset = (UINTN) ((UINTN) SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap);
- }
-
- DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64) Private->HeapOffset, (UINT64) Private->StackOffset));
-
- //
- // Caculate new HandOffTable and PrivateData address in permanent memory's stack
- //
- if (StackOffsetPositive) {
- SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *) ((UINTN) (VOID *) SecCoreData + StackOffset);
- Private = (PEI_CORE_INSTANCE *) ((UINTN) (VOID *) Private + StackOffset);
- } else {
- SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *) ((UINTN) (VOID *) SecCoreData - StackOffset);
- Private = (PEI_CORE_INSTANCE *) ((UINTN) (VOID *) Private - StackOffset);
- }
-
- //
- // Temporary Ram Support PPI is provided by platform, it will copy
- // temporary memory to permenent memory and do stack switching.
- // After invoking Temporary Ram Support PPI, the following code's
- // stack is in permanent memory.
- //
- TemporaryRamSupportPpi->TemporaryRamMigration (
- PeiServices,
- TemporaryRamBase,
- (EFI_PHYSICAL_ADDRESS) (UINTN) (TopOfNewStack - TemporaryStackSize),
- TemporaryRamSize
- );
- //
- // Entry PEI Phase 2
- //
- PeiCore (SecCoreData, NULL, Private);
- } else {
- //
- // Migrate the PEI Services Table pointer from temporary RAM to permanent RAM.
- //
- MigratePeiServicesTablePointer ();
-
- //
- // Heap Offset
- //
- BaseOfNewHeap = TopOfNewStack;
- HoleMemBase = TopOfNewStack;
- HoleMemSize = TemporaryRamSize - PeiTemporaryRamSize - TemporaryStackSize;
- if (HoleMemSize != 0) {
- //
- // Make sure HOB List start address is 8 byte alignment.
- //
- BaseOfNewHeap = ALIGN_VALUE (BaseOfNewHeap + HoleMemSize, 8);
- }
- if (BaseOfNewHeap >= (UINTN) SecCoreData->PeiTemporaryRamBase) {
- Private->HeapOffsetPositive = TRUE;
- Private->HeapOffset = (UINTN) (BaseOfNewHeap - (UINTN) SecCoreData->PeiTemporaryRamBase);
- } else {
- Private->HeapOffsetPositive = FALSE;
- Private->HeapOffset = (UINTN) ((UINTN) SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap);
- }
-
- DEBUG ((EFI_D_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64) Private->HeapOffset, (UINT64) Private->StackOffset));
-
- //
- // Migrate Heap
- //
- HeapTemporaryRamSize = (UINTN) (Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - Private->HobList.HandoffInformationTable->EfiMemoryBottom);
- ASSERT (BaseOfNewHeap + HeapTemporaryRamSize <= Private->FreePhysicalMemoryTop);
- CopyMem ((UINT8 *) (UINTN) BaseOfNewHeap, (UINT8 *) PeiTemporaryRamBase, HeapTemporaryRamSize);
-
- //
- // Migrate Stack
- //
- CopyMem ((UINT8 *) (UINTN) (TopOfNewStack - TemporaryStackSize), TemporaryStackBase, TemporaryStackSize);
-
- //
- // Copy Hole Range Data
- // Convert PPI from Hole.
- //
- if (HoleMemSize != 0) {
- //
- // Prepare Hole
- //
- if (PeiTemporaryRamBase < TemporaryStackBase) {
- TempBase1 = (EFI_PHYSICAL_ADDRESS) (UINTN) PeiTemporaryRamBase;
- TempSize1 = PeiTemporaryRamSize;
- TempBase2 = (EFI_PHYSICAL_ADDRESS) (UINTN) TemporaryStackBase;
- TempSize2 = TemporaryStackSize;
- } else {
- TempBase1 = (EFI_PHYSICAL_ADDRESS) (UINTN) TemporaryStackBase;
- TempSize1 = TemporaryStackSize;
- TempBase2 =(EFI_PHYSICAL_ADDRESS) (UINTN) PeiTemporaryRamBase;
- TempSize2 = PeiTemporaryRamSize;
- }
- if (TemporaryRamBase < TempBase1) {
- Private->HoleData[0].Base = TemporaryRamBase;
- Private->HoleData[0].Size = (UINTN) (TempBase1 - TemporaryRamBase);
- }
- if (TempBase1 + TempSize1 < TempBase2) {
- Private->HoleData[1].Base = TempBase1 + TempSize1;
- Private->HoleData[1].Size = (UINTN) (TempBase2 - TempBase1 - TempSize1);
- }
- if (TempBase2 + TempSize2 < TemporaryRamBase + TemporaryRamSize) {
- Private->HoleData[2].Base = TempBase2 + TempSize2;
- Private->HoleData[2].Size = (UINTN) (TemporaryRamBase + TemporaryRamSize - TempBase2 - TempSize2);
- }
-
- //
- // Copy Hole Range data.
- //
- for (Index = 0; Index < HOLE_MAX_NUMBER; Index ++) {
- if (Private->HoleData[Index].Size > 0) {
- if (HoleMemBase > Private->HoleData[Index].Base) {
- Private->HoleData[Index].OffsetPositive = TRUE;
- Private->HoleData[Index].Offset = (UINTN) (HoleMemBase - Private->HoleData[Index].Base);
- } else {
- Private->HoleData[Index].OffsetPositive = FALSE;
- Private->HoleData[Index].Offset = (UINTN) (Private->HoleData[Index].Base - HoleMemBase);
- }
- CopyMem ((VOID *) (UINTN) HoleMemBase, (VOID *) (UINTN) Private->HoleData[Index].Base, Private->HoleData[Index].Size);
- HoleMemBase = HoleMemBase + Private->HoleData[Index].Size;
- }
- }
- }
-
- //
- // Switch new stack
- //
- SwitchStack (
- (SWITCH_STACK_ENTRY_POINT)(UINTN)PeiCoreEntry,
- (VOID *) SecCoreData,
- (VOID *) Private,
- (VOID *) (UINTN) TopOfNewStack
- );
- }
-
- //
- // Code should not come here
- //
- ASSERT (FALSE);
- }
-
- //
- // Process the Notify list and dispatch any notifies for
- // newly installed PPIs.
- //
- ProcessNotifyList (Private);
-
- if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \
- (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || PcdGetBool (PcdShadowPeimOnS3Boot))) {
- //
- // If memory is availble we shadow images by default for performance reasons.
- // We call the entry point a 2nd time so the module knows it's shadowed.
- //
- //PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
- ASSERT (PeimEntryPoint != NULL);
- PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);
- //PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
-
- //
- // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
- //
- Private->Fv[FvCount].PeimState[PeimCount]++;
-
- //
- // Process the Notify list and dispatch any notifies for
- // newly installed PPIs.
- //
- ProcessNotifyList (Private);
- }
- }
- }
- }
-
- //
- // We set to NULL here to optimize the 2nd entry to this routine after
- // memory is found. This reprevents rescanning of the FV. We set to
- // NULL here so we start at the begining of the next FV
- //
- Private->CurrentFileHandle = NULL;
- Private->CurrentPeimCount = 0;
- //
- // Before walking through the next FV,Private->CurrentFvFileHandles[]should set to NULL
- //
- SetMem (Private->CurrentFvFileHandles, sizeof (EFI_PEI_FILE_HANDLE) * PcdGet32 (PcdPeiCoreMaxPeimPerFv), 0);
- }
-
- //
- // Before making another pass, we should set Private->CurrentPeimFvCount =0 to go
- // through all the FV.
- //
- Private->CurrentPeimFvCount = 0;
-
- //
- // PeimNeedingDispatch being TRUE means we found a PEIM that did not get
- // dispatched. So we need to make another pass
- //
- // PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this
- // pass. If we did not dispatch a PEIM there is no point in trying again
- // as it will fail the next time too (nothing has changed).
- //
- } while (Private->PeimNeedingDispatch && Private->PeimDispatchOnThisPass);
-
-}
-
-/**
- Initialize the Dispatcher's data members
-
- @param[in] PrivateData PeiCore's private data structure
- @param[in] OldCoreData Old data from SecCore
- NULL if being run in non-permament memory mode.
- @param[in] SecCoreData Points to a data structure containing information about the PEI core's operating
- environment, such as the size and location of temporary RAM, the stack location and
- the BFV location.
-
- @return None.
-
-**/
-VOID
-InitializeDispatcherData (
- IN PEI_CORE_INSTANCE *PrivateData,
- IN PEI_CORE_INSTANCE *OldCoreData,
- IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
- )
-{
- if (OldCoreData == NULL) {
- PrivateData->PeimDispatcherReenter = FALSE;
- PeiInitializeFv (PrivateData, SecCoreData);
- } else {
- PeiReinitializeFv (PrivateData);
- }
-
- return;
-}
-
-/**
- This routine parses the Dependency Expression, if available, and
- decides if the module can be executed.
-
- @param[in] Private PeiCore's private data structure
- @param[in] FileHandle PEIM's file handle
- @param[in] PeimCount Peim count in all dispatched PEIMs.
-
- @retval TRUE Can be dispatched
- @retval FALSE Cannot be dispatched
-
-**/
-BOOLEAN
-DepexSatisfied (
- IN PEI_CORE_INSTANCE *Private,
- IN EFI_PEI_FILE_HANDLE FileHandle,
- IN UINTN PeimCount
- )
-{
- EFI_STATUS Status;
- VOID *DepexData;
- EFI_FV_FILE_INFO FileInfo;
-
- Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);
- if (EFI_ERROR (Status)) {
- DEBUG ((DEBUG_DISPATCH, "Evaluate PEI DEPEX for FFS(Unknown)\n"));
- } else {
- DEBUG ((DEBUG_DISPATCH, "Evaluate PEI DEPEX for FFS(%g)\n", &FileInfo.FileName));
- }
-
- if (PeimCount < Private->AprioriCount) {
- //
- // If its in the A priori file then we set Depex to TRUE
- //
- DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (Apriori)\n"));
- return TRUE;
- }
-
- //
- // Depex section not in the encapsulated section.
- //
- Status = PeiServicesFfsFindSectionData (
- EFI_SECTION_PEI_DEPEX,
- FileHandle,
- (VOID **) &DepexData
- );
-
- if (EFI_ERROR (Status)) {
- //
- // If there is no DEPEX, assume the module can be executed
- //
- DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (No DEPEX)\n"));
- return TRUE;
- }
-
- //
- // Evaluate a given DEPEX
- //
- return PeimDispatchReadiness (&Private->Ps, DepexData);
-}
-
-/**
- This routine enable a PEIM to register itself to shadow when PEI Foundation
- discovery permanent memory.
-
- @param[in] FileHandle File handle of a PEIM.
-
- @retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself.
- @retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself.
- @retval EFI_SUCCESS Successfully to register itself.
-
-**/
-EFI_STATUS
-EFIAPI
-PeiRegisterForShadow (
- IN EFI_PEI_FILE_HANDLE FileHandle
- )
-{
- PEI_CORE_INSTANCE *Private;
-
- Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
-
- if (Private->CurrentFileHandle != FileHandle) {
- //
- // The FileHandle must be for the current PEIM
- //
- return EFI_NOT_FOUND;
- }
-
- if (Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] >= PEIM_STATE_REGISITER_FOR_SHADOW) {
- //
- // If the PEIM has already entered the PEIM_STATE_REGISTER_FOR_SHADOW or PEIM_STATE_DONE then it's already been started
- //
- return EFI_ALREADY_STARTED;
- }
-
- Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] = PEIM_STATE_REGISITER_FOR_SHADOW;
-
- return EFI_SUCCESS;
-}
-
-
-