/** @file\r
SMM Memory page management functions.\r
\r
- Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2009 - 2018, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials are licensed and made available\r
under the terms and conditions of the BSD License which accompanies this\r
distribution. The full text of the license may be found at\r
@param[out] Memory A pointer to receive the base allocated memory\r
address.\r
@param[in] AddRegion If this memory is new added region.\r
- @param[in] NeedGuard Flag to indicate Guard page is needed
- or not
+ @param[in] NeedGuard Flag to indicate Guard page is needed\r
+ or not\r
\r
@retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec.\r
@retval EFI_NOT_FOUND Could not allocate pages match the requirement.\r
IN EFI_MEMORY_TYPE MemoryType,\r
IN UINTN NumberOfPages,\r
OUT EFI_PHYSICAL_ADDRESS *Memory,\r
- IN BOOLEAN AddRegion,
- IN BOOLEAN NeedGuard
+ IN BOOLEAN AddRegion,\r
+ IN BOOLEAN NeedGuard\r
);\r
\r
/**\r
EfiRuntimeServicesData,\r
EFI_SIZE_TO_PAGES (RUNTIME_PAGE_ALLOCATION_GRANULARITY),\r
&Mem,\r
- TRUE,
- FALSE
+ TRUE,\r
+ FALSE\r
);\r
ASSERT_EFI_ERROR (Status);\r
if(!EFI_ERROR (Status)) {\r
)\r
{\r
RemoveEntryList (&Entry->Link);\r
+ Entry->Link.ForwardLink = NULL;\r
+\r
if (!Entry->FromStack) {\r
InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link);\r
}\r
return Count;\r
}\r
\r
-/**\r
- Dump Smm memory map entry.\r
-**/\r
-VOID\r
-DumpSmmMemoryMapEntry (\r
- VOID\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- MEMORY_MAP *Entry;\r
- EFI_PHYSICAL_ADDRESS Last;\r
-\r
- Last = 0;\r
- DEBUG ((DEBUG_INFO, "DumpSmmMemoryMapEntry:\n"));\r
- Link = gMemoryMap.ForwardLink;\r
- while (Link != &gMemoryMap) {\r
- Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
- Link = Link->ForwardLink;\r
-\r
- if ((Last != 0) && (Last != (UINT64)-1)) {\r
- if (Last + 1 != Entry->Start) {\r
- Last = (UINT64)-1;\r
- } else {\r
- Last = Entry->End;\r
- }\r
- } else if (Last == 0) {\r
- Last = Entry->End;\r
- }\r
-\r
- DEBUG ((DEBUG_INFO, "Entry (Link - 0x%x)\n", &Entry->Link));\r
- DEBUG ((DEBUG_INFO, " Signature - 0x%x\n", Entry->Signature));\r
- DEBUG ((DEBUG_INFO, " Link.ForwardLink - 0x%x\n", Entry->Link.ForwardLink));\r
- DEBUG ((DEBUG_INFO, " Link.BackLink - 0x%x\n", Entry->Link.BackLink));\r
- DEBUG ((DEBUG_INFO, " Type - 0x%x\n", Entry->Type));\r
- DEBUG ((DEBUG_INFO, " Start - 0x%016lx\n", Entry->Start));\r
- DEBUG ((DEBUG_INFO, " End - 0x%016lx\n", Entry->End));\r
- }\r
-\r
- ASSERT (Last != (UINT64)-1);\r
-}\r
-\r
-/**\r
- Dump Smm memory map.\r
-**/\r
-VOID\r
-DumpSmmMemoryMap (\r
- VOID\r
- )\r
-{\r
- LIST_ENTRY *Node;\r
- FREE_PAGE_LIST *Pages;\r
-\r
- DEBUG ((DEBUG_INFO, "DumpSmmMemoryMap\n"));\r
\r
- Pages = NULL;\r
- Node = mSmmMemoryMap.ForwardLink;\r
- while (Node != &mSmmMemoryMap) {\r
- Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);\r
- DEBUG ((DEBUG_INFO, "Pages - 0x%x\n", Pages));\r
- DEBUG ((DEBUG_INFO, "Pages->NumberOfPages - 0x%x\n", Pages->NumberOfPages));\r
- Node = Node->ForwardLink;\r
- }\r
-}\r
-\r
-/**\r
- Check if a Smm base~length is in Smm memory map.\r
-\r
- @param[in] Base The base address of Smm memory to be checked.\r
- @param[in] Length THe length of Smm memory to be checked.\r
-\r
- @retval TRUE Smm base~length is in smm memory map.\r
- @retval FALSE Smm base~length is in smm memory map.\r
-**/\r
-BOOLEAN\r
-SmmMemoryMapConsistencyCheckRange (\r
- IN EFI_PHYSICAL_ADDRESS Base,\r
- IN UINTN Length\r
- )\r
-{\r
- LIST_ENTRY *Link;\r
- MEMORY_MAP *Entry;\r
- BOOLEAN Result;\r
-\r
- Result = FALSE;\r
- Link = gMemoryMap.ForwardLink;\r
- while (Link != &gMemoryMap) {\r
- Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
- Link = Link->ForwardLink;\r
-\r
- if (Entry->Type != EfiConventionalMemory) {\r
- continue;\r
- }\r
- if (Entry->Start == Base && Entry->End == Base + Length - 1) {\r
- Result = TRUE;\r
- break;\r
- }\r
- }\r
-\r
- return Result;\r
-}\r
-\r
-/**\r
- Check the consistency of Smm memory map.\r
-**/\r
-VOID\r
-SmmMemoryMapConsistencyCheck (\r
- VOID\r
- )\r
-{\r
- LIST_ENTRY *Node;\r
- FREE_PAGE_LIST *Pages;\r
- BOOLEAN Result;\r
-\r
- Pages = NULL;\r
- Node = mSmmMemoryMap.ForwardLink;\r
- while (Node != &mSmmMemoryMap) {\r
- Pages = BASE_CR (Node, FREE_PAGE_LIST, Link);\r
- Result = SmmMemoryMapConsistencyCheckRange ((EFI_PHYSICAL_ADDRESS)(UINTN)Pages, (UINTN)EFI_PAGES_TO_SIZE(Pages->NumberOfPages));\r
- ASSERT (Result);\r
- Node = Node->ForwardLink;\r
- }\r
-}\r
\r
/**\r
Internal Function. Allocate n pages from given free page node.\r
@param[out] Memory A pointer to receive the base allocated memory\r
address.\r
@param[in] AddRegion If this memory is new added region.\r
- @param[in] NeedGuard Flag to indicate Guard page is needed
- or not
+ @param[in] NeedGuard Flag to indicate Guard page is needed\r
+ or not\r
\r
@retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec.\r
@retval EFI_NOT_FOUND Could not allocate pages match the requirement.\r
IN EFI_MEMORY_TYPE MemoryType,\r
IN UINTN NumberOfPages,\r
OUT EFI_PHYSICAL_ADDRESS *Memory,\r
- IN BOOLEAN AddRegion,
- IN BOOLEAN NeedGuard
+ IN BOOLEAN AddRegion,\r
+ IN BOOLEAN NeedGuard\r
)\r
{\r
UINTN RequestedAddress;\r
case AllocateAnyPages:\r
RequestedAddress = (UINTN)(-1);\r
case AllocateMaxAddress:\r
- if (NeedGuard) {
- *Memory = InternalAllocMaxAddressWithGuard (
- &mSmmMemoryMap,
- NumberOfPages,
- RequestedAddress,
- MemoryType
- );
- if (*Memory == (UINTN)-1) {
- return EFI_OUT_OF_RESOURCES;
- } else {
- ASSERT (VerifyMemoryGuard (*Memory, NumberOfPages) == TRUE);
- return EFI_SUCCESS;
- }
- }
-
+ if (NeedGuard) {\r
+ *Memory = InternalAllocMaxAddressWithGuard (\r
+ &mSmmMemoryMap,\r
+ NumberOfPages,\r
+ RequestedAddress,\r
+ MemoryType\r
+ );\r
+ if (*Memory == (UINTN)-1) {\r
+ return EFI_OUT_OF_RESOURCES;\r
+ } else {\r
+ ASSERT (VerifyMemoryGuard (*Memory, NumberOfPages) == TRUE);\r
+ return EFI_SUCCESS;\r
+ }\r
+ }\r
+\r
*Memory = InternalAllocMaxAddress (\r
&mSmmMemoryMap,\r
NumberOfPages,\r
@param[in] NumberOfPages The number of pages to allocate.\r
@param[out] Memory A pointer to receive the base allocated memory\r
address.\r
- @param[in] NeedGuard Flag to indicate Guard page is needed
- or not
+ @param[in] NeedGuard Flag to indicate Guard page is needed\r
+ or not\r
\r
@retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec.\r
@retval EFI_NOT_FOUND Could not allocate pages match the requirement.\r
IN EFI_ALLOCATE_TYPE Type,\r
IN EFI_MEMORY_TYPE MemoryType,\r
IN UINTN NumberOfPages,\r
- OUT EFI_PHYSICAL_ADDRESS *Memory,
- IN BOOLEAN NeedGuard
+ OUT EFI_PHYSICAL_ADDRESS *Memory,\r
+ IN BOOLEAN NeedGuard\r
)\r
{\r
- return SmmInternalAllocatePagesEx (Type, MemoryType, NumberOfPages, Memory,
- FALSE, NeedGuard);
+ return SmmInternalAllocatePagesEx (Type, MemoryType, NumberOfPages, Memory,\r
+ FALSE, NeedGuard);\r
}\r
\r
/**\r
)\r
{\r
EFI_STATUS Status;\r
- BOOLEAN NeedGuard;
+ BOOLEAN NeedGuard;\r
\r
- NeedGuard = IsPageTypeToGuard (MemoryType, Type);
- Status = SmmInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory,
- NeedGuard);
+ NeedGuard = IsPageTypeToGuard (MemoryType, Type);\r
+ Status = SmmInternalAllocatePages (Type, MemoryType, NumberOfPages, Memory,\r
+ NeedGuard);\r
if (!EFI_ERROR (Status)) {\r
SmmCoreUpdateProfile (\r
(EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),\r
\r
@param[in] Memory Base address of memory being freed.\r
@param[in] NumberOfPages The number of pages to free.\r
- @param[in] IsGuarded Is the memory to free guarded or not.
+ @param[in] IsGuarded Is the memory to free guarded or not.\r
\r
@retval EFI_NOT_FOUND Could not find the entry that covers the range.\r
@retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero.\r
EFIAPI\r
SmmInternalFreePages (\r
IN EFI_PHYSICAL_ADDRESS Memory,\r
- IN UINTN NumberOfPages,
- IN BOOLEAN IsGuarded
+ IN UINTN NumberOfPages,\r
+ IN BOOLEAN IsGuarded\r
)\r
{\r
- if (IsGuarded) {
- return SmmInternalFreePagesExWithGuard (Memory, NumberOfPages, FALSE);
- }
+ if (IsGuarded) {\r
+ return SmmInternalFreePagesExWithGuard (Memory, NumberOfPages, FALSE);\r
+ }\r
return SmmInternalFreePagesEx (Memory, NumberOfPages, FALSE);\r
}\r
\r
+/**\r
+ Check whether the input range is in memory map.\r
+\r
+ @param Memory Base address of memory being inputed.\r
+ @param NumberOfPages The number of pages.\r
+\r
+ @retval TRUE In memory map.\r
+ @retval FALSE Not in memory map.\r
+\r
+**/\r
+BOOLEAN\r
+InMemMap (\r
+ IN EFI_PHYSICAL_ADDRESS Memory,\r
+ IN UINTN NumberOfPages\r
+ )\r
+{\r
+ LIST_ENTRY *Link;\r
+ MEMORY_MAP *Entry;\r
+ EFI_PHYSICAL_ADDRESS Last;\r
+\r
+ Last = Memory + EFI_PAGES_TO_SIZE (NumberOfPages) - 1;\r
+\r
+ Link = gMemoryMap.ForwardLink;\r
+ while (Link != &gMemoryMap) {\r
+ Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);\r
+ Link = Link->ForwardLink;\r
+\r
+ if ((Entry->Start <= Memory) && (Entry->End >= Last)) {\r
+ return TRUE;\r
+ }\r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
/**\r
Frees previous allocated pages.\r
\r
)\r
{\r
EFI_STATUS Status;\r
- BOOLEAN IsGuarded;
+ BOOLEAN IsGuarded;\r
+\r
+ if (!InMemMap(Memory, NumberOfPages)) {\r
+ return EFI_NOT_FOUND;\r
+ }\r
\r
- IsGuarded = IsHeapGuardEnabled () && IsMemoryGuarded (Memory);
- Status = SmmInternalFreePages (Memory, NumberOfPages, IsGuarded);
+ IsGuarded = IsHeapGuardEnabled () && IsMemoryGuarded (Memory);\r
+ Status = SmmInternalFreePages (Memory, NumberOfPages, IsGuarded);\r
if (!EFI_ERROR (Status)) {\r
SmmCoreUpdateProfile (\r
(EFI_PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS (0),\r