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
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
// 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
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
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
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
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
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
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
//\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