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