summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2015-03-06 02:54:05 +0000
committerlgao4 <lgao4@Edk2>2015-03-06 02:54:05 +0000
commit7970100ccbd48e6f931b078cb8e615eabee26141 (patch)
tree577ee21d8770d5cd6e28934a689bdec795dec65e
parent09f08c92b2c413b7c369daf65a70e739939fe87b (diff)
downloadedk2-platforms-7970100ccbd48e6f931b078cb8e615eabee26141.tar.xz
MdeModulePkg: use correct granularity when allocating pool pages
After fixing the sanity check on the alignment of the runtime regions in SVN revision #16630 ("MdeModulePkg/DxeMain: Fix wrong sanity check in CoreTerminateMemoryMap()"), it is no longer possible to define a runtime allocation alignment that is different from the boot time allocation alignment. For instance, #defining the following in MdeModulePkg/Core/Dxe/Mem/Imem.h will hit the ASSERT () in MdeModulePkg/Core/Dxe/Mem/Page.c:1798 #define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (SIZE_64KB) #define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE) (which is needed for 64-bit ARM to adhere to the Server Base Boot Requirements [SBBR], which stipulates that all runtime memory regions should be naturally aligned multiples of 64 KB) This patch fixes this use case by ensuring that the backing for the memory pools is allocated in appropriate chunks for the memory type. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Reviewed-by: Liming Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17011 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--MdeModulePkg/Core/Dxe/Mem/Pool.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/MdeModulePkg/Core/Dxe/Mem/Pool.c b/MdeModulePkg/Core/Dxe/Mem/Pool.c
index a40ddd51bd..f99293da5c 100644
--- a/MdeModulePkg/Core/Dxe/Mem/Pool.c
+++ b/MdeModulePkg/Core/Dxe/Mem/Pool.c
@@ -274,9 +274,20 @@ CoreAllocatePoolI (
UINTN FSize;
UINTN Offset;
UINTN NoPages;
+ UINTN Granularity;
ASSERT_LOCKED (&gMemoryLock);
+ if (PoolType == EfiACPIReclaimMemory ||
+ PoolType == EfiACPIMemoryNVS ||
+ PoolType == EfiRuntimeServicesCode ||
+ PoolType == EfiRuntimeServicesData) {
+
+ Granularity = EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT;
+ } else {
+ Granularity = DEFAULT_PAGE_ALLOCATION;
+ }
+
//
// Adjust the size by the pool header & tail overhead
//
@@ -301,9 +312,9 @@ CoreAllocatePoolI (
// (slow)
//
if (Index >= MAX_POOL_LIST) {
- NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;
- NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);
- Head = CoreAllocatePoolPages (PoolType, NoPages, DEFAULT_PAGE_ALLOCATION);
+ NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (Granularity) - 1;
+ NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1);
+ Head = CoreAllocatePoolPages (PoolType, NoPages, Granularity);
goto Done;
}
@@ -315,7 +326,7 @@ CoreAllocatePoolI (
//
// Get another page
//
- NewPage = CoreAllocatePoolPages(PoolType, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION), DEFAULT_PAGE_ALLOCATION);
+ NewPage = CoreAllocatePoolPages(PoolType, EFI_SIZE_TO_PAGES (Granularity), Granularity);
if (NewPage == NULL) {
goto Done;
}
@@ -324,11 +335,11 @@ CoreAllocatePoolI (
// Carve up new page into free pool blocks
//
Offset = 0;
- while (Offset < DEFAULT_PAGE_ALLOCATION) {
+ while (Offset < Granularity) {
ASSERT (Index < MAX_POOL_LIST);
FSize = LIST_TO_SIZE(Index);
- while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
+ while (Offset + FSize <= Granularity) {
Free = (POOL_FREE *) &NewPage[Offset];
Free->Signature = POOL_FREE_SIGNATURE;
Free->Index = (UINT32)Index;
@@ -339,7 +350,7 @@ CoreAllocatePoolI (
Index -= 1;
}
- ASSERT (Offset == DEFAULT_PAGE_ALLOCATION);
+ ASSERT (Offset == Granularity);
Index = SIZE_TO_LIST(Size);
}
@@ -467,6 +478,7 @@ CoreFreePoolI (
UINTN FSize;
UINTN Offset;
BOOLEAN AllFree;
+ UINTN Granularity;
ASSERT(Buffer != NULL);
//
@@ -508,6 +520,16 @@ CoreFreePoolI (
Pool->Used -= Size;
DEBUG ((DEBUG_POOL, "FreePool: %p (len %lx) %,ld\n", Head->Data, (UINT64)(Head->Size - POOL_OVERHEAD), (UINT64) Pool->Used));
+ if (Head->Type == EfiACPIReclaimMemory ||
+ Head->Type == EfiACPIMemoryNVS ||
+ Head->Type == EfiRuntimeServicesCode ||
+ Head->Type == EfiRuntimeServicesData) {
+
+ Granularity = EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT;
+ } else {
+ Granularity = DEFAULT_PAGE_ALLOCATION;
+ }
+
//
// Determine the pool list
//
@@ -522,8 +544,8 @@ CoreFreePoolI (
//
// Return the memory pages back to free memory
//
- NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;
- NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);
+ NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (Granularity) - 1;
+ NoPages &= ~(UINTN)(EFI_SIZE_TO_PAGES (Granularity) - 1);
CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages);
} else {
@@ -541,7 +563,7 @@ CoreFreePoolI (
// See if all the pool entries in the same page as Free are freed pool
// entries
//
- NewPage = (CHAR8 *)((UINTN)Free & ~((DEFAULT_PAGE_ALLOCATION) -1));
+ NewPage = (CHAR8 *)((UINTN)Free & ~(Granularity - 1));
Free = (POOL_FREE *) &NewPage[0];
ASSERT(Free != NULL);
@@ -552,9 +574,9 @@ CoreFreePoolI (
AllFree = TRUE;
Offset = 0;
- while ((Offset < DEFAULT_PAGE_ALLOCATION) && (AllFree)) {
+ while ((Offset < Granularity) && (AllFree)) {
FSize = LIST_TO_SIZE(Index);
- while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
+ while (Offset + FSize <= Granularity) {
Free = (POOL_FREE *) &NewPage[Offset];
ASSERT(Free != NULL);
if (Free->Signature != POOL_FREE_SIGNATURE) {
@@ -577,9 +599,9 @@ CoreFreePoolI (
Index = Free->Index;
Offset = 0;
- while (Offset < DEFAULT_PAGE_ALLOCATION) {
+ while (Offset < Granularity) {
FSize = LIST_TO_SIZE(Index);
- while (Offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
+ while (Offset + FSize <= Granularity) {
Free = (POOL_FREE *) &NewPage[Offset];
ASSERT(Free != NULL);
RemoveEntryList (&Free->Link);
@@ -591,7 +613,7 @@ CoreFreePoolI (
//
// Free the page
//
- CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION));
+ CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, EFI_SIZE_TO_PAGES (Granularity));
}
}
}