]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/AcpiTableDxe: use pool allocations when possible
authorArd Biesheuvel <ard.biesheuvel@arm.com>
Fri, 16 Oct 2020 14:36:08 +0000 (16:36 +0200)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Fri, 30 Oct 2020 14:50:33 +0000 (14:50 +0000)
On AArch64 systems, page based allocations for memory types that are
relevant to the OS are rounded up to 64 KB multiples. This wastes
some space in the ACPI table memory allocator, since it uses page
based allocations in order to be able to place the ACPI tables low
in memory.

Since the latter requirement does not exist on AArch64, switch to pool
allocations for all ACPI tables except the root tables if the active
allocation policy permits them to be anywhere in memory. The root
tables will be handled in a subsequent patch.

Signed-off-by: Ard Biesheuvel <ard.biesheuvel@arm.com>
Reviewed-by: Liming Gao <gaoliming@byosoft.com.cn>
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiSdt.c
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTable.h
MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableProtocol.c

index b1cba20c8ed794cc7b496e11bb35aa429241fb0f..14ced68e645f54c4836fc24253bb4b0d0d2b8e34 100644 (file)
@@ -68,8 +68,8 @@ FindTableByBuffer (
 \r
   while (CurrentLink != StartLink) {\r
     CurrentTableList = EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink);\r
-    if (((UINTN)CurrentTableList->PageAddress <= (UINTN)Buffer) &&\r
-        ((UINTN)CurrentTableList->PageAddress + EFI_PAGES_TO_SIZE(CurrentTableList->NumberOfPages) > (UINTN)Buffer)) {\r
+    if (((UINTN)CurrentTableList->Table <= (UINTN)Buffer) &&\r
+        ((UINTN)CurrentTableList->Table + CurrentTableList->TableSize > (UINTN)Buffer)) {\r
       //\r
       // Good! Found Table.\r
       //\r
index 425a462fd92bf1b6e96ab2b4b3cef3e57e25eac0..9d7cf7ccfc76537f4c2b1ddaf2f856d11fb23a84 100644 (file)
 //  Link is the linked list data.\r
 //  Version is the versions of the ACPI tables that this table belongs in.\r
 //  Table is a pointer to the table.\r
-//  PageAddress is the address of the pages allocated for the table.\r
-//  NumberOfPages is the number of pages allocated at PageAddress.\r
+//  TableSize is the size of the table\r
 //  Handle is used to identify a particular table.\r
+//  PoolAllocation carries the allocation type:\r
+//    FALSE: Table points to EFI_SIZE_TO_PAGES(TableSize) pages allocated using\r
+//           gBS->AllocatePages ()\r
+//    TRUE:  Table points to TableSize bytes allocated using gBS->AllocatePool ()\r
 //\r
 typedef struct {\r
   UINT32                  Signature;\r
   LIST_ENTRY              Link;\r
   EFI_ACPI_TABLE_VERSION  Version;\r
   EFI_ACPI_COMMON_HEADER  *Table;\r
-  EFI_PHYSICAL_ADDRESS    PageAddress;\r
-  UINTN                   NumberOfPages;\r
+  UINTN                   TableSize;\r
   UINTN                   Handle;\r
+  BOOLEAN                 PoolAllocation;\r
 } EFI_ACPI_TABLE_LIST;\r
 \r
 //\r
index ad7baf8205b4826cc31a21f2972e2ae96ca5aef7..eb79dbadbfc517cf205f8975ac0e4f0d0e748cf1 100644 (file)
@@ -428,6 +428,26 @@ ReallocateAcpiTableBuffer (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Free the memory associated with the provided EFI_ACPI_TABLE_LIST instance.\r
+\r
+  @param  TableEntry                EFI_ACPI_TABLE_LIST instance pointer\r
+\r
+**/\r
+STATIC\r
+VOID\r
+FreeTableMemory (\r
+  EFI_ACPI_TABLE_LIST   *TableEntry\r
+  )\r
+{\r
+  if (TableEntry->PoolAllocation) {\r
+    gBS->FreePool (TableEntry->Table);\r
+  } else {\r
+    gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)TableEntry->Table,\r
+           EFI_SIZE_TO_PAGES (TableEntry->TableSize));\r
+  }\r
+}\r
+\r
 /**\r
   This function adds an ACPI table to the table list.  It will detect FACS and\r
   allocate the correct type of memory and properly align the table.\r
@@ -454,14 +474,15 @@ AddTableToList (
   OUT UINTN                               *Handle\r
   )\r
 {\r
-  EFI_STATUS          Status;\r
-  EFI_ACPI_TABLE_LIST *CurrentTableList;\r
-  UINT32              CurrentTableSignature;\r
-  UINT32              CurrentTableSize;\r
-  UINT32              *CurrentRsdtEntry;\r
-  VOID                *CurrentXsdtEntry;\r
-  UINT64              Buffer64;\r
-  BOOLEAN             AddToRsdt;\r
+  EFI_STATUS            Status;\r
+  EFI_ACPI_TABLE_LIST   *CurrentTableList;\r
+  UINT32                CurrentTableSignature;\r
+  UINT32                CurrentTableSize;\r
+  UINT32                *CurrentRsdtEntry;\r
+  VOID                  *CurrentXsdtEntry;\r
+  EFI_PHYSICAL_ADDRESS  AllocPhysAddress;\r
+  UINT64                Buffer64;\r
+  BOOLEAN               AddToRsdt;\r
 \r
   //\r
   // Check for invalid input parameters\r
@@ -496,8 +517,9 @@ AddTableToList (
   // There is no architectural reason these should be below 4GB, it is purely\r
   // for convenience of implementation that we force memory below 4GB.\r
   //\r
-  CurrentTableList->PageAddress   = 0xFFFFFFFF;\r
-  CurrentTableList->NumberOfPages = EFI_SIZE_TO_PAGES (CurrentTableSize);\r
+  AllocPhysAddress                  = 0xFFFFFFFF;\r
+  CurrentTableList->TableSize       = CurrentTableSize;\r
+  CurrentTableList->PoolAllocation  = FALSE;\r
 \r
   //\r
   // Allocation memory type depends on the type of the table\r
@@ -518,9 +540,21 @@ AddTableToList (
     Status = gBS->AllocatePages (\r
                     AllocateMaxAddress,\r
                     EfiACPIMemoryNVS,\r
-                    CurrentTableList->NumberOfPages,\r
-                    &CurrentTableList->PageAddress\r
+                    EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),\r
+                    &AllocPhysAddress\r
+                    );\r
+  } else if (mAcpiTableAllocType == AllocateAnyPages) {\r
+    //\r
+    // If there is no allocation limit, there is also no need to use page\r
+    // based allocations for ACPI tables, which may be wasteful on platforms\r
+    // such as AArch64 that allocate multiples of 64 KB\r
+    //\r
+    Status = gBS->AllocatePool (\r
+                    EfiACPIReclaimMemory,\r
+                    CurrentTableList->TableSize,\r
+                    (VOID **)&CurrentTableList->Table\r
                     );\r
+    CurrentTableList->PoolAllocation = TRUE;\r
   } else {\r
     //\r
     // All other tables are ACPI reclaim memory, no alignment requirements.\r
@@ -528,9 +562,10 @@ AddTableToList (
     Status = gBS->AllocatePages (\r
                     mAcpiTableAllocType,\r
                     EfiACPIReclaimMemory,\r
-                    CurrentTableList->NumberOfPages,\r
-                    &CurrentTableList->PageAddress\r
+                    EFI_SIZE_TO_PAGES (CurrentTableList->TableSize),\r
+                    &AllocPhysAddress\r
                     );\r
+    CurrentTableList->Table = (EFI_ACPI_COMMON_HEADER *)(UINTN)AllocPhysAddress;\r
   }\r
   //\r
   // Check return value from memory alloc.\r
@@ -539,10 +574,10 @@ AddTableToList (
     gBS->FreePool (CurrentTableList);\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
-  //\r
-  // Update the table pointer with the allocated memory start\r
-  //\r
-  CurrentTableList->Table = (EFI_ACPI_COMMON_HEADER *) (UINTN) CurrentTableList->PageAddress;\r
+\r
+  if (!CurrentTableList->PoolAllocation) {\r
+    CurrentTableList->Table = (EFI_ACPI_COMMON_HEADER *)(UINTN)AllocPhysAddress;\r
+  }\r
 \r
   //\r
   // Initialize the table contents\r
@@ -575,7 +610,7 @@ AddTableToList (
     if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Fadt1 != NULL) ||\r
         ((Version & ACPI_TABLE_VERSION_GTE_2_0)  != 0 && AcpiTableInstance->Fadt3 != NULL)\r
         ) {\r
-      gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
+      FreeTableMemory (CurrentTableList);\r
       gBS->FreePool (CurrentTableList);\r
       return EFI_ACCESS_DENIED;\r
     }\r
@@ -729,7 +764,7 @@ AddTableToList (
     if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Facs1 != NULL) ||\r
         ((Version & ACPI_TABLE_VERSION_GTE_2_0)  != 0 && AcpiTableInstance->Facs3 != NULL)\r
         ) {\r
-      gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
+      FreeTableMemory (CurrentTableList);\r
       gBS->FreePool (CurrentTableList);\r
       return EFI_ACCESS_DENIED;\r
     }\r
@@ -813,7 +848,7 @@ AddTableToList (
     if (((Version & EFI_ACPI_TABLE_VERSION_1_0B) != 0 && AcpiTableInstance->Dsdt1 != NULL) ||\r
         ((Version & ACPI_TABLE_VERSION_GTE_2_0)  != 0 && AcpiTableInstance->Dsdt3 != NULL)\r
         ) {\r
-      gBS->FreePages (CurrentTableList->PageAddress, CurrentTableList->NumberOfPages);\r
+      FreeTableMemory (CurrentTableList);\r
       gBS->FreePool (CurrentTableList);\r
       return EFI_ACCESS_DENIED;\r
     }\r
@@ -1449,7 +1484,7 @@ DeleteTable (
     //\r
     // Free the Table\r
     //\r
-    gBS->FreePages (Table->PageAddress, Table->NumberOfPages);\r
+    FreeTableMemory (Table);\r
     RemoveEntryList (&(Table->Link));\r
     gBS->FreePool (Table);\r
   }\r