\r
EFI_LOCK mPropertiesTableLock = EFI_INITIALIZE_LOCK_VARIABLE (TPL_NOTIFY);\r
\r
+//\r
+// Temporary save for original memory map.\r
+// This is for MemoryAttributesTable only.\r
+//\r
+extern BOOLEAN mIsConstructingMemoryAttributesTable;\r
+EFI_MEMORY_DESCRIPTOR *mMemoryMapOrg;\r
+UINTN mMemoryMapOrgSize;\r
+UINTN mDescriptorSize;\r
+\r
//\r
// Below functions are for MemoryMap\r
//\r
return ;\r
}\r
\r
+/**\r
+ Check if this memory entry spans across original memory map boundary.\r
+\r
+ @param PhysicalStart The PhysicalStart of memory\r
+ @param NumberOfPages The NumberOfPages of memory\r
+\r
+ @retval TRUE This memory entry spans across original memory map boundary.\r
+ @retval FALSE This memory entry does not span cross original memory map boundary.\r
+**/\r
+STATIC\r
+BOOLEAN\r
+DoesEntrySpanAcrossBoundary (\r
+ IN UINT64 PhysicalStart,\r
+ IN UINT64 NumberOfPages\r
+ )\r
+{\r
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEntry;\r
+ EFI_MEMORY_DESCRIPTOR *MemoryMapEnd;\r
+ UINT64 MemoryBlockLength;\r
+\r
+ MemoryMapEntry = mMemoryMapOrg;\r
+ MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *) ((UINT8 *) mMemoryMapOrg + mMemoryMapOrgSize);\r
+ while (MemoryMapEntry < MemoryMapEnd) {\r
+ MemoryBlockLength = (UINT64) (EfiPagesToSize (MemoryMapEntry->NumberOfPages));\r
+\r
+ if ((MemoryMapEntry->PhysicalStart <= PhysicalStart) &&\r
+ (MemoryMapEntry->PhysicalStart + MemoryBlockLength > PhysicalStart) &&\r
+ (MemoryMapEntry->PhysicalStart + MemoryBlockLength < PhysicalStart + EfiPagesToSize (NumberOfPages))) {\r
+ return TRUE;\r
+ }\r
+\r
+ MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, mDescriptorSize);\r
+ }\r
+ return FALSE;\r
+}\r
+\r
/**\r
Merge continous memory map entries whose have same attributes.\r
\r
CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof(EFI_MEMORY_DESCRIPTOR));\r
NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
\r
- MemoryBlockLength = (UINT64) (EfiPagesToSize (MemoryMapEntry->NumberOfPages));\r
- if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&\r
- (MemoryMapEntry->Type == NextMemoryMapEntry->Type) &&\r
- (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&\r
- ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) {\r
- NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
- MemoryMapEntry = NextMemoryMapEntry;\r
- }\r
+ do {\r
+ MemoryBlockLength = (UINT64) (EfiPagesToSize (MemoryMapEntry->NumberOfPages));\r
+ if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) &&\r
+ (MemoryMapEntry->Type == NextMemoryMapEntry->Type) &&\r
+ (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) &&\r
+ ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart) &&\r
+ (!DoesEntrySpanAcrossBoundary (MemoryMapEntry->PhysicalStart, MemoryMapEntry->NumberOfPages + NextMemoryMapEntry->NumberOfPages))) {\r
+ MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
+ if (NewMemoryMapEntry != MemoryMapEntry) {\r
+ NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages;\r
+ }\r
+\r
+ NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);\r
+ continue;\r
+ } else {\r
+ MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize);\r
+ break;\r
+ }\r
+ } while (TRUE);\r
\r
MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize);\r
NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize);\r
}\r
\r
/**\r
- This function for GetMemoryMap() with properties table.\r
+ This function for GetMemoryMap() with properties table capability.\r
\r
It calls original GetMemoryMap() to get the original memory map information. Then\r
plus the additional memory map entries for PE Code/Data seperation.\r
@retval EFI_INVALID_PARAMETER One of the parameters has an invalid value.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
CoreGetMemoryMapPropertiesTable (\r
//\r
Status = EFI_BUFFER_TOO_SMALL;\r
} else {\r
+ if (mIsConstructingMemoryAttributesTable) {\r
+ //\r
+ // If the memory map is constructed for memory attributes table,\r
+ // save original memory map, because they will be checked later\r
+ // to make sure the memory attributes table entry does not cross\r
+ // the original memory map entry boundary.\r
+ // This work must NOT be done in normal GetMemoryMap() because\r
+ // allocating memory is not allowed due to MapKey update.\r
+ //\r
+ mDescriptorSize = *DescriptorSize;\r
+ mMemoryMapOrgSize = *MemoryMapSize;\r
+ mMemoryMapOrg = AllocateCopyPool (*MemoryMapSize, MemoryMap);\r
+ if (mMemoryMapOrg == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto Exit;\r
+ }\r
+ }\r
+\r
//\r
// Split PE code/data\r
//\r
SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize);\r
+\r
+ if (mIsConstructingMemoryAttributesTable) {\r
+ FreePool (mMemoryMapOrg);\r
+ mMemoryMapOrg = NULL;\r
+ mMemoryMapOrgSize = 0;\r
+ }\r
}\r
}\r
\r
+Exit:\r
CoreReleasePropertiesTableLock ();\r
return Status;\r
}\r