\r
\r
/**\r
- Internal function. Converts a memory range to the specified type.\r
- The range must exist in the memory map.\r
+ Internal function. Converts a memory range to the specified type or attributes.\r
+ The range must exist in the memory map. Either ChangingType or\r
+ ChangingAttributes must be set, but not both.\r
\r
@param Start The first address of the range Must be page\r
aligned\r
@param NumberOfPages The number of pages to convert\r
+ @param ChangingType Boolean indicating that type value should be changed\r
@param NewType The new type for the memory range\r
+ @param ChangingAttributes Boolean indicating that attributes value should be changed\r
+ @param NewAttributes The new attributes for the memory range\r
\r
@retval EFI_INVALID_PARAMETER Invalid parameter\r
@retval EFI_NOT_FOUND Could not find a descriptor cover the specified\r
\r
**/\r
EFI_STATUS\r
-CoreConvertPages (\r
+CoreConvertPagesEx (\r
IN UINT64 Start,\r
IN UINT64 NumberOfPages,\r
- IN EFI_MEMORY_TYPE NewType\r
+ IN BOOLEAN ChangingType,\r
+ IN EFI_MEMORY_TYPE NewType,\r
+ IN BOOLEAN ChangingAttributes,\r
+ IN UINT64 NewAttributes\r
)\r
{\r
\r
UINT64 End;\r
UINT64 RangeEnd;\r
UINT64 Attribute;\r
+ EFI_MEMORY_TYPE MemType;\r
LIST_ENTRY *Link;\r
MEMORY_MAP *Entry;\r
\r
ASSERT ((Start & EFI_PAGE_MASK) == 0);\r
ASSERT (End > Start) ;\r
ASSERT_LOCKED (&gMemoryLock);\r
+ ASSERT ( (ChangingType == FALSE) || (ChangingAttributes == FALSE) );\r
\r
if (NumberOfPages == 0 || ((Start & EFI_PAGE_MASK) != 0) || (Start > (Start + NumberOfBytes))) {\r
return EFI_INVALID_PARAMETER;\r
RangeEnd = Entry->End;\r
}\r
\r
- DEBUG ((DEBUG_PAGE, "ConvertRange: %lx-%lx to %d\n", Start, RangeEnd, NewType));\r
-\r
- //\r
- // Debug code - verify conversion is allowed\r
- //\r
- if (!(NewType == EfiConventionalMemory ? 1 : 0) ^ (Entry->Type == EfiConventionalMemory ? 1 : 0)) {\r
- DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "ConvertPages: Incompatible memory types\n"));\r
- return EFI_NOT_FOUND;\r
+ if (ChangingType) {\r
+ DEBUG ((DEBUG_PAGE, "ConvertRange: %lx-%lx to type %d\n", Start, RangeEnd, NewType));\r
+ }\r
+ if (ChangingAttributes) {\r
+ DEBUG ((DEBUG_PAGE, "ConvertRange: %lx-%lx to attr %lx\n", Start, RangeEnd, NewAttributes));\r
}\r
\r
- //\r
- // Update counters for the number of pages allocated to each memory type\r
- //\r
- if ((UINT32)Entry->Type < EfiMaxMemoryType) {\r
- if ((Start >= mMemoryTypeStatistics[Entry->Type].BaseAddress && Start <= mMemoryTypeStatistics[Entry->Type].MaximumAddress) ||\r
- (Start >= mDefaultBaseAddress && Start <= mDefaultMaximumAddress) ) {\r
- if (NumberOfPages > mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages) {\r
- mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages = 0;\r
- } else {\r
- mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages -= NumberOfPages;\r
+ if (ChangingType) {\r
+ //\r
+ // Debug code - verify conversion is allowed\r
+ //\r
+ if (!(NewType == EfiConventionalMemory ? 1 : 0) ^ (Entry->Type == EfiConventionalMemory ? 1 : 0)) {\r
+ DEBUG ((DEBUG_ERROR | DEBUG_PAGE, "ConvertPages: Incompatible memory types\n"));\r
+ return EFI_NOT_FOUND;\r
+ }\r
+\r
+ //\r
+ // Update counters for the number of pages allocated to each memory type\r
+ //\r
+ if ((UINT32)Entry->Type < EfiMaxMemoryType) {\r
+ if ((Start >= mMemoryTypeStatistics[Entry->Type].BaseAddress && Start <= mMemoryTypeStatistics[Entry->Type].MaximumAddress) ||\r
+ (Start >= mDefaultBaseAddress && Start <= mDefaultMaximumAddress) ) {\r
+ if (NumberOfPages > mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages) {\r
+ mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages = 0;\r
+ } else {\r
+ mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages -= NumberOfPages;\r
+ }\r
}\r
}\r
- }\r
\r
- if ((UINT32)NewType < EfiMaxMemoryType) {\r
- if ((Start >= mMemoryTypeStatistics[NewType].BaseAddress && Start <= mMemoryTypeStatistics[NewType].MaximumAddress) ||\r
- (Start >= mDefaultBaseAddress && Start <= mDefaultMaximumAddress) ) {\r
- mMemoryTypeStatistics[NewType].CurrentNumberOfPages += NumberOfPages;\r
- if (mMemoryTypeStatistics[NewType].CurrentNumberOfPages > gMemoryTypeInformation[mMemoryTypeStatistics[NewType].InformationIndex].NumberOfPages) {\r
- gMemoryTypeInformation[mMemoryTypeStatistics[NewType].InformationIndex].NumberOfPages = (UINT32)mMemoryTypeStatistics[NewType].CurrentNumberOfPages;\r
+ if ((UINT32)NewType < EfiMaxMemoryType) {\r
+ if ((Start >= mMemoryTypeStatistics[NewType].BaseAddress && Start <= mMemoryTypeStatistics[NewType].MaximumAddress) ||\r
+ (Start >= mDefaultBaseAddress && Start <= mDefaultMaximumAddress) ) {\r
+ mMemoryTypeStatistics[NewType].CurrentNumberOfPages += NumberOfPages;\r
+ if (mMemoryTypeStatistics[NewType].CurrentNumberOfPages > gMemoryTypeInformation[mMemoryTypeStatistics[NewType].InformationIndex].NumberOfPages) {\r
+ gMemoryTypeInformation[mMemoryTypeStatistics[NewType].InformationIndex].NumberOfPages = (UINT32)mMemoryTypeStatistics[NewType].CurrentNumberOfPages;\r
+ }\r
}\r
}\r
}\r
\r
//\r
// The new range inherits the same Attribute as the Entry\r
- //it is being cut out of\r
+ // it is being cut out of unless attributes are being changed\r
//\r
- Attribute = Entry->Attribute;\r
+ if (ChangingType) {\r
+ Attribute = Entry->Attribute;\r
+ MemType = NewType;\r
+ } else {\r
+ Attribute = NewAttributes;\r
+ MemType = Entry->Type;\r
+ }\r
\r
//\r
// If the descriptor is empty, then remove it from the map\r
//\r
// Add our new range in\r
//\r
- CoreAddRange (NewType, Start, RangeEnd, Attribute);\r
- if (NewType == EfiConventionalMemory) {\r
+ CoreAddRange (MemType, Start, RangeEnd, Attribute);\r
+ if (ChangingType && (MemType == EfiConventionalMemory)) {\r
//\r
// Avoid calling DEBUG_CLEAR_MEMORY() for an address of 0 because this\r
// macro will ASSERT() if address is 0. Instead, CoreAddRange() guarantees\r
}\r
\r
\r
+/**\r
+ Internal function. Converts a memory range to the specified type.\r
+ The range must exist in the memory map.\r
+\r
+ @param Start The first address of the range Must be page\r
+ aligned\r
+ @param NumberOfPages The number of pages to convert\r
+ @param NewType The new type for the memory range\r
+\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_NOT_FOUND Could not find a descriptor cover the specified\r
+ range or convertion not allowed.\r
+ @retval EFI_SUCCESS Successfully converts the memory range to the\r
+ specified type.\r
+\r
+**/\r
+EFI_STATUS\r
+CoreConvertPages (\r
+ IN UINT64 Start,\r
+ IN UINT64 NumberOfPages,\r
+ IN EFI_MEMORY_TYPE NewType\r
+ )\r
+{\r
+ return CoreConvertPagesEx(Start, NumberOfPages, TRUE, NewType, FALSE, 0);\r
+}\r
+\r
+\r
+/**\r
+ Internal function. Converts a memory range to use new attributes.\r
+\r
+ @param Start The first address of the range Must be page\r
+ aligned\r
+ @param NumberOfPages The number of pages to convert\r
+ @param NewAttributes The new attributes value for the range.\r
+\r
+ @retval EFI_INVALID_PARAMETER Invalid parameter\r
+ @retval EFI_NOT_FOUND Could not find a descriptor cover the specified\r
+ range or convertion not allowed.\r
+ @retval EFI_SUCCESS Successfully converts the memory range to the\r
+ specified attributes.\r
+\r
+**/\r
+VOID\r
+CoreUpdateMemoryAttributes (\r
+ IN EFI_PHYSICAL_ADDRESS Start,\r
+ IN UINT64 NumberOfPages,\r
+ IN UINT64 NewAttributes\r
+ )\r
+{\r
+ CoreAcquireMemoryLock ();\r
+\r
+ //\r
+ // Update the attributes to the new value\r
+ //\r
+ CoreConvertPagesEx(Start, NumberOfPages, FALSE, (EFI_MEMORY_TYPE)0, TRUE, NewAttributes);\r
+\r
+ CoreReleaseMemoryLock ();\r
+}\r
+\r
\r
/**\r
Internal function. Finds a consecutive free page range below\r