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 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++) {
|
||||||
|
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;
|
MemoryMap->Attribute = Entry->Attribute;
|
||||||
break;
|
if (mMemoryTypeStatistics[MemoryMap->Type].Runtime) {
|
||||||
|
MemoryMap->Attribute |= EFI_MEMORY_RUNTIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryMap = NextMemoryDescriptor (MemoryMap, Size);
|
MemoryMap = NextMemoryDescriptor (MemoryMap, Size);
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
//
|
//
|
||||||
|
|
Loading…
Reference in New Issue