From b74350e9562f0ad4400afdbc2a157d66f55fb113 Mon Sep 17 00:00:00 2001 From: mdkinney Date: Tue, 27 Nov 2007 02:47:37 +0000 Subject: [PATCH] 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 --- MdeModulePkg/Core/Dxe/Mem/Page.c | 69 +++++++++++++++---------- MdeModulePkg/Core/DxeIplPeim/DxeIpl.h | 2 + MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf | 4 ++ MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 31 +++++++++++ 4 files changed, 80 insertions(+), 26 deletions(-) diff --git a/MdeModulePkg/Core/Dxe/Mem/Page.c b/MdeModulePkg/Core/Dxe/Mem/Page.c index c4f3274906..0ac2aa5c91 100644 --- a/MdeModulePkg/Core/Dxe/Mem/Page.c +++ b/MdeModulePkg/Core/Dxe/Mem/Page.c @@ -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); diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h index dab6839ef3..e82cf38db2 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h @@ -30,6 +30,8 @@ Abstract: #include #include #include +#include +#include #include #include diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf index c28525acaf..898e67ed5a 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf @@ -93,6 +93,10 @@ gEfiDxeIplPpiGuid # PPI SOMETIMES_PRODUCED gEfiPeiDecompressPpiGuid gEfiPeiFirmwareVolumeInfoPpiGuid + gEfiPeiReadOnlyVariable2PpiGuid + +[Guids] + gEfiMemoryTypeInformationGuid [FeaturePcd.common] gEfiMdeModulePkgTokenSpaceGuid.PcdDxeIplSupportCustomDecompress diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c index d593e30c74..b7cadedd89 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c +++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c @@ -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 // -- 2.39.2