//\r
// Update the GCD map\r
//\r
- Entry->GcdMemoryType = EfiGcdMemoryTypeSystemMemory;\r
+ if ((Entry->Capabilities & EFI_MEMORY_MORE_RELIABLE) == EFI_MEMORY_MORE_RELIABLE) {\r
+ Entry->GcdMemoryType = EfiGcdMemoryTypeMoreReliable;\r
+ } else {\r
+ Entry->GcdMemoryType = EfiGcdMemoryTypeSystemMemory;\r
+ }\r
Entry->Capabilities |= EFI_MEMORY_TESTED;\r
Entry->ImageHandle = gDxeCoreImageHandle;\r
Entry->DeviceHandle = NULL;\r
return;\r
}\r
\r
- if (Type >= EfiMaxMemoryType && Type <= 0x7fffffff) {\r
+ if (Type >= EfiMaxMemoryType && Type < MEMORY_TYPE_OEM_RESERVED_MIN) {\r
return;\r
}\r
CoreAcquireMemoryLock ();\r
\r
DescEnd = ((DescEnd + 1) & (~(Alignment - 1))) - 1;\r
\r
+ // Skip if DescEnd is less than DescStart after alignment clipping\r
+ if (DescEnd < DescStart) {\r
+ continue;\r
+ }\r
+\r
//\r
// Compute the number of bytes we can used from this\r
// descriptor, and see it's enough to satisfy the request\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if ((MemoryType >= EfiMaxMemoryType && MemoryType <= 0x7fffffff) ||\r
+ if ((MemoryType >= EfiMaxMemoryType && MemoryType < MEMORY_TYPE_OEM_RESERVED_MIN) ||\r
(MemoryType == EfiConventionalMemory) || (MemoryType == EfiPersistentMemory)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
EFI_STATUS Status;\r
UINTN Size;\r
UINTN BufferSize;\r
- UINTN NumberOfRuntimePersistentEntries;\r
+ UINTN NumberOfEntries;\r
LIST_ENTRY *Link;\r
MEMORY_MAP *Entry;\r
EFI_GCD_MAP_ENTRY *GcdMapEntry;\r
+ EFI_GCD_MAP_ENTRY MergeGcdMapEntry;\r
EFI_MEMORY_TYPE Type;\r
EFI_MEMORY_DESCRIPTOR *MemoryMapStart;\r
\r
CoreAcquireGcdMemoryLock ();\r
\r
//\r
- // Count the number of Reserved and MMIO entries that are marked for runtime use\r
+ // Count the number of Reserved and runtime MMIO entries\r
// And, count the number of Persistent entries.\r
//\r
- NumberOfRuntimePersistentEntries = 0;\r
+ NumberOfEntries = 0;\r
for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) {\r
GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
- if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||\r
- (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {\r
- if ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {\r
- NumberOfRuntimePersistentEntries ++;\r
- }\r
- }\r
- \r
- if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypePersistentMemory) {\r
- NumberOfRuntimePersistentEntries ++;\r
+ if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypePersistentMemory) || \r
+ (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||\r
+ ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&\r
+ ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) {\r
+ NumberOfEntries ++;\r
}\r
}\r
\r
//\r
// Compute the buffer size needed to fit the entire map\r
//\r
- BufferSize = Size * NumberOfRuntimePersistentEntries;\r
+ BufferSize = Size * NumberOfEntries;\r
for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {\r
BufferSize += Size;\r
}\r
MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
}\r
\r
- for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) {\r
- GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
- if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||\r
- (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {\r
- if ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {\r
- // \r
- // Create EFI_MEMORY_DESCRIPTOR for every Reserved and MMIO GCD entries\r
- // that are marked for runtime use\r
- //\r
- MemoryMap->PhysicalStart = GcdMapEntry->BaseAddress;\r
- MemoryMap->VirtualStart = 0;\r
- MemoryMap->NumberOfPages = RShiftU64 ((GcdMapEntry->EndAddress - GcdMapEntry->BaseAddress + 1), EFI_PAGE_SHIFT);\r
- MemoryMap->Attribute = GcdMapEntry->Attributes & ~EFI_MEMORY_PORT_IO;\r
-\r
- if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) {\r
- MemoryMap->Type = EfiReservedMemoryType;\r
- } else if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {\r
- if ((GcdMapEntry->Attributes & EFI_MEMORY_PORT_IO) == EFI_MEMORY_PORT_IO) {\r
- MemoryMap->Type = EfiMemoryMappedIOPortSpace;\r
- } else {\r
- MemoryMap->Type = EfiMemoryMappedIO;\r
- }\r
- }\r
+ \r
+ ZeroMem (&MergeGcdMapEntry, sizeof (MergeGcdMapEntry));\r
+ GcdMapEntry = NULL;\r
+ for (Link = mGcdMemorySpaceMap.ForwardLink; ; Link = Link->ForwardLink) {\r
+ if (Link != &mGcdMemorySpaceMap) {\r
+ //\r
+ // Merge adjacent same type and attribute GCD memory range\r
+ //\r
+ GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);\r
+ \r
+ if ((MergeGcdMapEntry.Capabilities == GcdMapEntry->Capabilities) && \r
+ (MergeGcdMapEntry.Attributes == GcdMapEntry->Attributes) &&\r
+ (MergeGcdMapEntry.GcdMemoryType == GcdMapEntry->GcdMemoryType) &&\r
+ (MergeGcdMapEntry.GcdIoType == GcdMapEntry->GcdIoType)) {\r
+ MergeGcdMapEntry.EndAddress = GcdMapEntry->EndAddress;\r
+ continue;\r
+ }\r
+ }\r
\r
- //\r
- // Check to see if the new Memory Map Descriptor can be merged with an \r
- // existing descriptor if they are adjacent and have the same attributes\r
- //\r
- MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
+ if ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeReserved) ||\r
+ ((MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) &&\r
+ ((MergeGcdMapEntry.Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) {\r
+ //\r
+ // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR, \r
+ // it will be recorded as page PhysicalStart and NumberOfPages. \r
+ //\r
+ ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);\r
+ ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);\r
+ \r
+ // \r
+ // Create EFI_MEMORY_DESCRIPTOR for every Reserved and runtime MMIO GCD entries\r
+ //\r
+ MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;\r
+ MemoryMap->VirtualStart = 0;\r
+ MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);\r
+ MemoryMap->Attribute = (MergeGcdMapEntry.Attributes & ~EFI_MEMORY_PORT_IO) | \r
+ (MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |\r
+ EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB));\r
+\r
+ if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeReserved) {\r
+ MemoryMap->Type = EfiReservedMemoryType;\r
+ } else if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {\r
+ if ((MergeGcdMapEntry.Attributes & EFI_MEMORY_PORT_IO) == EFI_MEMORY_PORT_IO) {\r
+ MemoryMap->Type = EfiMemoryMappedIOPortSpace;\r
+ } else {\r
+ MemoryMap->Type = EfiMemoryMappedIO;\r
+ }\r
}\r
+\r
+ //\r
+ // Check to see if the new Memory Map Descriptor can be merged with an \r
+ // existing descriptor if they are adjacent and have the same attributes\r
+ //\r
+ MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
}\r
\r
- if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypePersistentMemory) {\r
+ if (MergeGcdMapEntry.GcdMemoryType == EfiGcdMemoryTypePersistentMemory) {\r
+ //\r
+ // Page Align GCD range is required. When it is converted to EFI_MEMORY_DESCRIPTOR, \r
+ // it will be recorded as page PhysicalStart and NumberOfPages. \r
+ //\r
+ ASSERT ((MergeGcdMapEntry.BaseAddress & EFI_PAGE_MASK) == 0);\r
+ ASSERT (((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1) & EFI_PAGE_MASK) == 0);\r
+\r
// \r
// Create EFI_MEMORY_DESCRIPTOR for every Persistent GCD entries\r
//\r
- MemoryMap->PhysicalStart = GcdMapEntry->BaseAddress;\r
+ MemoryMap->PhysicalStart = MergeGcdMapEntry.BaseAddress;\r
MemoryMap->VirtualStart = 0;\r
- MemoryMap->NumberOfPages = RShiftU64 ((GcdMapEntry->EndAddress - GcdMapEntry->BaseAddress + 1), EFI_PAGE_SHIFT);\r
- MemoryMap->Attribute = GcdMapEntry->Attributes | EFI_MEMORY_NV;\r
+ MemoryMap->NumberOfPages = RShiftU64 ((MergeGcdMapEntry.EndAddress - MergeGcdMapEntry.BaseAddress + 1), EFI_PAGE_SHIFT);\r
+ MemoryMap->Attribute = MergeGcdMapEntry.Attributes | EFI_MEMORY_NV | \r
+ (MergeGcdMapEntry.Capabilities & (EFI_MEMORY_RP | EFI_MEMORY_WP | EFI_MEMORY_XP | EFI_MEMORY_RO |\r
+ EFI_MEMORY_UC | EFI_MEMORY_UCE | EFI_MEMORY_WC | EFI_MEMORY_WT | EFI_MEMORY_WB));\r
MemoryMap->Type = EfiPersistentMemory;\r
\r
//\r
//\r
MemoryMap = MergeMemoryMapDescriptor (MemoryMapStart, MemoryMap, Size);\r
}\r
+ if (Link == &mGcdMemorySpaceMap) {\r
+ //\r
+ // break loop when arrive at head.\r
+ //\r
+ break;\r
+ }\r
+ if (GcdMapEntry != NULL) {\r
+ //\r
+ // Copy new GCD map entry for the following GCD range merge\r
+ //\r
+ CopyMem (&MergeGcdMapEntry, GcdMapEntry, sizeof (MergeGcdMapEntry));\r
+ }\r
}\r
\r
//\r