mirror of https://github.com/acidanthera/audk.git
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:
parent
7a5064ce42
commit
b74350e956
|
@ -33,7 +33,10 @@ typedef struct {
|
|||
EFI_PHYSICAL_ADDRESS BaseAddress;
|
||||
EFI_PHYSICAL_ADDRESS MaximumAddress;
|
||||
UINT64 CurrentNumberOfPages;
|
||||
UINT64 NumberOfPages;
|
||||
UINTN InformationIndex;
|
||||
BOOLEAN Special;
|
||||
BOOLEAN Runtime;
|
||||
} EFI_MEMORY_TYPE_STAISTICS;
|
||||
|
||||
//
|
||||
|
@ -57,21 +60,21 @@ LIST_ENTRY mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemo
|
|||
BOOLEAN mMemoryTypeInformationInitialized = FALSE;
|
||||
|
||||
EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = {
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiReservedMemoryType
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiLoaderCode
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiLoaderData
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiBootServicesCode
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiBootServicesData
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiRuntimeServicesCode
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiRuntimeServicesData
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiConventionalMemory
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiUnusableMemory
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiACPIReclaimMemory
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiACPIMemoryNVS
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiMemoryMappedIO
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiMemoryMappedIOPortSpace
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType }, // EfiPalCode
|
||||
{ 0, EFI_MAX_ADDRESS, 0, EfiMaxMemoryType } // EfiMaxMemoryType
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiReservedMemoryType
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiLoaderCode
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiLoaderData
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiBootServicesCode
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiBootServicesData
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiRuntimeServicesCode
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiRuntimeServicesData
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiConventionalMemory
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiUnusableMemory
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiACPIReclaimMemory
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiACPIMemoryNVS
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiMemoryMappedIO
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiMemoryMappedIOPortSpace
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiPalCode
|
||||
{ 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE } // EfiMaxMemoryType
|
||||
};
|
||||
|
||||
EFI_PHYSICAL_ADDRESS mDefaultMaximumAddress = EFI_MAX_ADDRESS;
|
||||
|
@ -397,6 +400,7 @@ Returns:
|
|||
mMemoryTypeStatistics[Type].BaseAddress,
|
||||
gMemoryTypeInformation[Index].NumberOfPages
|
||||
);
|
||||
mMemoryTypeStatistics[Type].NumberOfPages = gMemoryTypeInformation[Index].NumberOfPages;
|
||||
gMemoryTypeInformation[Index].NumberOfPages = 0;
|
||||
}
|
||||
}
|
||||
|
@ -1363,6 +1367,7 @@ Returns:
|
|||
LIST_ENTRY *Link;
|
||||
MEMORY_MAP *Entry;
|
||||
EFI_GCD_MAP_ENTRY *GcdMapEntry;
|
||||
EFI_MEMORY_TYPE Type;
|
||||
|
||||
//
|
||||
// Make sure the parameters are valid
|
||||
|
@ -1432,21 +1437,33 @@ Returns:
|
|||
Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
|
||||
ASSERT (Entry->VirtualStart == 0);
|
||||
|
||||
//
|
||||
// Convert internal map into an EFI_MEMORY_DESCRIPTOR
|
||||
//
|
||||
MemoryMap->Type = Entry->Type;
|
||||
MemoryMap->PhysicalStart = Entry->Start;
|
||||
MemoryMap->VirtualStart = Entry->VirtualStart;
|
||||
MemoryMap->NumberOfPages = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT);
|
||||
|
||||
switch (Entry->Type) {
|
||||
case EfiRuntimeServicesCode:
|
||||
case EfiRuntimeServicesData:
|
||||
case EfiPalCode:
|
||||
MemoryMap->Attribute = Entry->Attribute | EFI_MEMORY_RUNTIME;
|
||||
break;
|
||||
|
||||
default:
|
||||
MemoryMap->Attribute = Entry->Attribute;
|
||||
break;
|
||||
//
|
||||
// If the memory type is EfiConventionalMemory, then determine if the range is part of a
|
||||
// memory type bin and needs to be converted to the same memory type as the rest of the
|
||||
// memory type bin in order to minimize EFI Memory Map changes across reboots. This
|
||||
// improves the chances for a successful S4 resume in the presence of minor page allocation
|
||||
// differences across reboots.
|
||||
//
|
||||
if (MemoryMap->Type == EfiConventionalMemory) {
|
||||
for (Type = (EFI_MEMORY_TYPE) 0; Type < EfiMaxMemoryType; Type++) {
|
||||
if (mMemoryTypeStatistics[Type].Special &&
|
||||
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);
|
||||
|
|
|
@ -30,6 +30,8 @@ Abstract:
|
|||
#include <Ppi/SectionExtraction.h>
|
||||
#include <Ppi/FvLoadFile.h>
|
||||
#include <Ppi/MemoryDiscovered.h>
|
||||
#include <Ppi/ReadOnlyVariable2.h>
|
||||
#include <Guid/MemoryTypeInformation.h>
|
||||
#include <Ppi/Decompress.h>
|
||||
#include <Ppi/FirmwareVolumeInfo.h>
|
||||
|
||||
|
|
|
@ -93,6 +93,10 @@
|
|||
gEfiDxeIplPpiGuid # PPI SOMETIMES_PRODUCED
|
||||
gEfiPeiDecompressPpiGuid
|
||||
gEfiPeiFirmwareVolumeInfoPpiGuid
|
||||
gEfiPeiReadOnlyVariable2PpiGuid
|
||||
|
||||
[Guids]
|
||||
gEfiMemoryTypeInformationGuid
|
||||
|
||||
[FeaturePcd.common]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportCustomDecompress
|
||||
|
|
|
@ -170,6 +170,9 @@ DxeLoadCore (
|
|||
EFI_PEI_FV_HANDLE VolumeHandle;
|
||||
EFI_PEI_FILE_HANDLE FileHandle;
|
||||
UINTN Instance;
|
||||
EFI_PEI_READ_ONLY_VARIABLE2_PPI *Variable;
|
||||
UINTN DataSize;
|
||||
EFI_MEMORY_TYPE_INFORMATION MemoryData [EfiMaxMemoryType + 1];
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
|
|
Loading…
Reference in New Issue