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
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
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
- ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME))) {\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
+ 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 = 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_PORT_IO;\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 (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) {\r
+ if (MergeGcdMapEntry.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
+ } 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
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