[PATCH] qfw: Allocate ACPI memory using efi logic

Alexander Graf agraf at csgraf.de
Sun Feb 27 15:23:17 CET 2022


When we allocate ACPI tables dynamically as part of the qfw ACPI loading
code and then later want to boot a UEFI target using them, we need to make
sure that the UEFI logic is aware that these memory regions are ACPI, so
that the loading kernel can mark them as reserved.

Since we'll never see alignment requirements more than a page, let's just
use efi_allocate_pages when we see high memory allocation requests in a
UEFI enabled environment. Even if we then boot using the native zImage
later, the memory allocation will still be valid.

Without this patch, Linux will refuse to consume the DSDT when passed from
qfw's ACPI framework. With this patch, it happily uses it.

Signed-off-by: Alexander Graf <agraf at csgraf.de>
---
 drivers/misc/qfw.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
index 754bc6a603..7c6ed41f48 100644
--- a/drivers/misc/qfw.c
+++ b/drivers/misc/qfw.c
@@ -18,6 +18,9 @@
 #if defined(CONFIG_GENERATE_ACPI_TABLE) && !defined(CONFIG_ARM)
 #include <asm/tables.h>
 #endif
+#ifdef CONFIG_EFI_LOADER
+#include <efi_loader.h>
+#endif
 
 #if defined(CONFIG_GENERATE_ACPI_TABLE) && !defined(CONFIG_SANDBOX)
 /*
@@ -35,7 +38,7 @@ static int bios_linker_allocate(struct udevice *dev,
 {
 	uint32_t size, align;
 	struct fw_file *file;
-	unsigned long aligned_addr;
+	unsigned long aligned_addr = 0;
 
 	align = le32_to_cpu(entry->alloc.align);
 	/* align must be power of 2 */
@@ -59,7 +62,19 @@ static int bios_linker_allocate(struct udevice *dev,
 	 * in which is low memory
 	 */
 	if (entry->alloc.zone == BIOS_LINKER_LOADER_ALLOC_ZONE_HIGH) {
+#ifdef CONFIG_EFI_LOADER
+		efi_status_t ret;
+		u64 efi_addr = 1ULL << 32;
+
+		ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
+					 EFI_ACPI_RECLAIM_MEMORY,
+					 efi_size_in_pages(size),
+					 &efi_addr);
+		if (ret == EFI_SUCCESS)
+			aligned_addr = efi_addr;
+#else
 		aligned_addr = (unsigned long)memalign(align, size);
+#endif
 		if (!aligned_addr) {
 			printf("error: allocating resource\n");
 			return -ENOMEM;
-- 
2.32.0



More information about the U-Boot mailing list