1) Improve the EFI Memory Map stability to improve ACPI S4 support

2) Update DXE IPL to always publish the MemoryTypeInformation HOB



git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4327 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
mdkinney 2007-11-27 02:47:37 +00:00
parent 7a5064ce42
commit b74350e956
4 changed files with 80 additions and 26 deletions

View File

@ -33,7 +33,10 @@ typedef struct {
EFI_PHYSICAL_ADDRESS BaseAddress; EFI_PHYSICAL_ADDRESS BaseAddress;
EFI_PHYSICAL_ADDRESS MaximumAddress; EFI_PHYSICAL_ADDRESS MaximumAddress;
UINT64 CurrentNumberOfPages; UINT64 CurrentNumberOfPages;
UINT64 NumberOfPages;
UINTN InformationIndex; UINTN InformationIndex;
BOOLEAN Special;
BOOLEAN Runtime;
} EFI_MEMORY_TYPE_STAISTICS; } EFI_MEMORY_TYPE_STAISTICS;
// //
@ -57,21 +60,21 @@ LIST_ENTRY mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemo
BOOLEAN mMemoryTypeInformationInitialized = FALSE; BOOLEAN mMemoryTypeInformationInitialized = FALSE;
EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = { EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = {
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiReservedMemoryType { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiReservedMemoryType
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiLoaderCode { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiLoaderCode
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiLoaderData { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiLoaderData
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiBootServicesCode { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiBootServicesCode
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiBootServicesData { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiBootServicesData
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiRuntimeServicesCode { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiRuntimeServicesCode
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiRuntimeServicesData { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiRuntimeServicesData
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiConventionalMemory { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiConventionalMemory
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiUnusableMemory { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiUnusableMemory
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiACPIReclaimMemory { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiACPIReclaimMemory
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiACPIMemoryNVS { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiACPIMemoryNVS
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiMemoryMappedIO { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiMemoryMappedIO
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiMemoryMappedIOPortSpace { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiMemoryMappedIOPortSpace
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiPalCode { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiPalCode
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType } // EfiMaxMemoryType { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE } // EfiMaxMemoryType
}; };
EFI_PHYSICAL_ADDRESS mDefaultMaximumAddress = EFI_MAX_ADDRESS; EFI_PHYSICAL_ADDRESS mDefaultMaximumAddress = EFI_MAX_ADDRESS;
@ -397,6 +400,7 @@ Returns:
mMemoryTypeStatistics[Type].BaseAddress, mMemoryTypeStatistics[Type].BaseAddress,
gMemoryTypeInformation[Index].NumberOfPages gMemoryTypeInformation[Index].NumberOfPages
); );
mMemoryTypeStatistics[Type].NumberOfPages = gMemoryTypeInformation[Index].NumberOfPages;
gMemoryTypeInformation[Index].NumberOfPages = 0; gMemoryTypeInformation[Index].NumberOfPages = 0;
} }
} }
@ -1363,6 +1367,7 @@ Returns:
LIST_ENTRY *Link; LIST_ENTRY *Link;
MEMORY_MAP *Entry; MEMORY_MAP *Entry;
EFI_GCD_MAP_ENTRY *GcdMapEntry; EFI_GCD_MAP_ENTRY *GcdMapEntry;
EFI_MEMORY_TYPE Type;
// //
// Make sure the parameters are valid // Make sure the parameters are valid
@ -1432,21 +1437,33 @@ Returns:
Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
ASSERT (Entry->VirtualStart == 0); ASSERT (Entry->VirtualStart == 0);
//
// Convert internal map into an EFI_MEMORY_DESCRIPTOR
//
MemoryMap->Type = Entry->Type; MemoryMap->Type = Entry->Type;
MemoryMap->PhysicalStart = Entry->Start; MemoryMap->PhysicalStart = Entry->Start;
MemoryMap->VirtualStart = Entry->VirtualStart; MemoryMap->VirtualStart = Entry->VirtualStart;
MemoryMap->NumberOfPages = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT); MemoryMap->NumberOfPages = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT);
//
switch (Entry->Type) { // If the memory type is EfiConventionalMemory, then determine if the range is part of a
case EfiRuntimeServicesCode: // memory type bin and needs to be converted to the same memory type as the rest of the
case EfiRuntimeServicesData: // memory type bin in order to minimize EFI Memory Map changes across reboots. This
case EfiPalCode: // improves the chances for a successful S4 resume in the presence of minor page allocation
MemoryMap->Attribute = Entry->Attribute | EFI_MEMORY_RUNTIME; // differences across reboots.
break; //
if (MemoryMap->Type == EfiConventionalMemory) {
default: for (Type = (EFI_MEMORY_TYPE) 0; Type < EfiMaxMemoryType; Type++) {
MemoryMap->Attribute = Entry->Attribute; if (mMemoryTypeStatistics[Type].Special &&
break; mMemoryTypeStatistics[Type].NumberOfPages > 0 &&
Entry->Start >= mMemoryTypeStatistics[Type].BaseAddress &&
Entry->End <= mMemoryTypeStatistics[Type].MaximumAddress ) {
MemoryMap->Type = Type;
}
}
}
MemoryMap->Attribute = Entry->Attribute;
if (mMemoryTypeStatistics[MemoryMap->Type].Runtime) {
MemoryMap->Attribute |= EFI_MEMORY_RUNTIME;
} }
MemoryMap = NextMemoryDescriptor (MemoryMap, Size); MemoryMap = NextMemoryDescriptor (MemoryMap, Size);

View File

@ -30,6 +30,8 @@ Abstract:
#include <Ppi/SectionExtraction.h> #include <Ppi/SectionExtraction.h>
#include <Ppi/FvLoadFile.h> #include <Ppi/FvLoadFile.h>
#include <Ppi/MemoryDiscovered.h> #include <Ppi/MemoryDiscovered.h>
#include <Ppi/ReadOnlyVariable2.h>
#include <Guid/MemoryTypeInformation.h>
#include <Ppi/Decompress.h> #include <Ppi/Decompress.h>
#include <Ppi/FirmwareVolumeInfo.h> #include <Ppi/FirmwareVolumeInfo.h>

View File

@ -93,6 +93,10 @@
gEfiDxeIplPpiGuid # PPI SOMETIMES_PRODUCED gEfiDxeIplPpiGuid # PPI SOMETIMES_PRODUCED
gEfiPeiDecompressPpiGuid gEfiPeiDecompressPpiGuid
gEfiPeiFirmwareVolumeInfoPpiGuid gEfiPeiFirmwareVolumeInfoPpiGuid
gEfiPeiReadOnlyVariable2PpiGuid
[Guids]
gEfiMemoryTypeInformationGuid
[FeaturePcd.common] [FeaturePcd.common]
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportCustomDecompress gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportCustomDecompress

View File

@ -170,6 +170,9 @@ DxeLoadCore (
EFI_PEI_FV_HANDLE VolumeHandle; EFI_PEI_FV_HANDLE VolumeHandle;
EFI_PEI_FILE_HANDLE FileHandle; EFI_PEI_FILE_HANDLE FileHandle;
UINTN Instance; UINTN Instance;
EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
UINTN DataSize;
EFI_MEMORY_TYPE_INFORMATION MemoryData [EfiMaxMemoryType + 1];
// //
// if in S3 Resume, restore configure // if in S3 Resume, restore configure
@ -192,6 +195,34 @@ DxeLoadCore (
// //
} }
Status = PeiServicesLocatePpi (
&gEfiPeiReadOnlyVariable2PpiGuid,
0,
NULL,
(VOID **)&Variable
);
ASSERT_EFI_ERROR (Status);
DataSize = sizeof (MemoryData);
Status = Variable->GetVariable (
Variable,
EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
&gEfiMemoryTypeInformationGuid,
NULL,
&DataSize,
&MemoryData
);
if (!EFI_ERROR (Status)) {
//
// Build the GUID'd HOB for DXE
//
BuildGuidDataHob (
&gEfiMemoryTypeInformationGuid,
MemoryData,
DataSize
);
}
// //
// If any FV contains an encapsulated FV extract that FV // If any FV contains an encapsulated FV extract that FV
// //