Merge patch series "sandbox: align LMB memory"

Heinrich Schuchardt <heinrich.schuchardt@canonical.com> says:

To implement the EFI_SYSTEM_TABLE_POINTER we need 4 MiB aligned
memory.

On the sandbox LMB uses addresses relative to the start of a page aligned
RAM buffer allocated with mmap(). This leads to a mismatch of alignment
between EFI which uses pointers and LMB which uses phys_addr_t.

Ensure that the RAM buffer used for LMB is 4 MiB aligned.

Provide a unit test for efi_alloc_aligned_pages() verifying this alignment.

Do not overwrite RAM size in dram_init().

Link: https://lore.kernel.org/r/20250608075428.32631-1-heinrich.schuchardt@canonical.com
diff --git a/arch/sandbox/cpu/state.c b/arch/sandbox/cpu/state.c
index 49236db..6a15c8b 100644
--- a/arch/sandbox/cpu/state.c
+++ b/arch/sandbox/cpu/state.c
@@ -480,7 +480,9 @@
 	state = &main_state;
 
 	state->ram_size = CFG_SYS_SDRAM_SIZE;
-	state->ram_buf = os_malloc(state->ram_size);
+	state->mmap_addr = os_malloc(state->ram_size + SB_SDRAM_ALIGN);
+	state->ram_buf = (uint8_t *)ALIGN((uintptr_t)state->mmap_addr,
+					  SB_SDRAM_ALIGN);
 	if (!state->ram_buf) {
 		printf("Out of memory\n");
 		os_exit(1);
@@ -533,7 +535,7 @@
 		trace_set_enabled(0);
 
 	os_free(state->state_fdt);
-	os_free(state->ram_buf);
+	os_free(state->mmap_addr);
 	memset(state, '\0', sizeof(*state));
 
 	return 0;
diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h
index dc21a62..9dea098 100644
--- a/arch/sandbox/include/asm/state.h
+++ b/arch/sandbox/include/asm/state.h
@@ -75,6 +75,7 @@
 	char **argv;			/* Command line arguments */
 	const char *jumped_fname;	/* Jumped from previous U-Boot */
 	const char *prog_fname;		/* U-Boot executable filename */
+	uint8_t *mmap_addr;		/* Memory allocated via mmap */
 	uint8_t *ram_buf;		/* Emulated RAM buffer */
 	unsigned long ram_size;		/* Size of RAM buffer */
 	const char *ram_buf_fname;	/* Filename to use for RAM buffer */
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index d97945e..43f4edc 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -101,7 +101,6 @@
 
 int dram_init(void)
 {
-	gd->ram_size = CFG_SYS_SDRAM_SIZE;
 	return 0;
 }
 
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index db2ac7f..44d4960 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -14,6 +14,8 @@
 #define CFG_SYS_SDRAM_BASE		0
 #define CFG_SYS_SDRAM_SIZE \
 		(SB_TO_UL(CONFIG_SANDBOX_RAM_SIZE_MB) << 20)
+/** define SB_SDRAM_ALIGN - Alignment of emulated RAM */
+#define SB_SDRAM_ALIGN			0x400000
 
 #define CFG_SYS_BAUDRATE_TABLE	{4800, 9600, 19200, 38400, 57600,\
 					115200}
diff --git a/test/lib/Makefile b/test/lib/Makefile
index ff4ff63..35b40b5 100644
--- a/test/lib/Makefile
+++ b/test/lib/Makefile
@@ -8,7 +8,7 @@
 ifeq ($(CONFIG_XPL_BUILD),)
 obj-y += abuf.o
 obj-y += alist.o
-obj-$(CONFIG_EFI_LOADER) += efi_device_path.o
+obj-$(CONFIG_EFI_LOADER) += efi_device_path.o efi_memory.o
 obj-$(CONFIG_EFI_SECURE_BOOT) += efi_image_region.o
 obj-y += hexdump.o
 obj-$(CONFIG_SANDBOX) += kconfig.o
diff --git a/test/lib/efi_memory.c b/test/lib/efi_memory.c
new file mode 100644
index 0000000..d2e1ab6
--- /dev/null
+++ b/test/lib/efi_memory.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Test memory functions
+ *
+ * Copyright (c) 2025 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ */
+
+#include <efi_loader.h>
+#include <test/lib.h>
+#include <test/test.h>
+#include <test/ut.h>
+
+static int lib_test_efi_alloc_aligned_pages(struct unit_test_state *uts)
+{
+	efi_status_t ret;
+
+	void *addr;
+	unsigned long align = 0x400000;
+
+	addr = efi_alloc_aligned_pages(4096, EFI_PERSISTENT_MEMORY_TYPE,
+				       EFI_PAGE_SIZE);
+	ut_asserteq_ptr(NULL, addr);
+
+	addr = efi_alloc_aligned_pages(4096, 0x6FFFFFFF, EFI_PAGE_SIZE);
+	ut_asserteq_ptr(NULL, addr);
+
+	align = 0x200;
+	addr = efi_alloc_aligned_pages(4096, EFI_ACPI_RECLAIM_MEMORY, align);
+	ut_assertnonnull(addr);
+	ut_asserteq_64(0, (uintptr_t)addr & (align - 1));
+
+	ret = efi_free_pages((uintptr_t) addr, 1);
+	ut_asserteq_64(ret, EFI_SUCCESS);
+
+	align = 0x400000;
+	addr = efi_alloc_aligned_pages(4096, EFI_ACPI_RECLAIM_MEMORY, align);
+	ut_assertnonnull(addr);
+	ut_asserteq_64(0, (uintptr_t)addr & (align - 1));
+
+	ret = efi_free_pages((uintptr_t) addr, 1);
+	ut_asserteq_64(ret, EFI_SUCCESS);
+
+	return 0;
+}
+LIB_TEST(lib_test_efi_alloc_aligned_pages, 0);
+
+static int lib_test_efi_allocate_pages(struct unit_test_state *uts)
+{
+	efi_status_t ret;
+	u64 memory;
+
+	ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+				 EFI_ACPI_RECLAIM_MEMORY,
+				 1, &memory);
+	ut_asserteq_64(ret, EFI_SUCCESS);
+	ut_asserteq_64(0, memory & EFI_PAGE_MASK);
+
+	ret = efi_free_pages(memory, 1);
+	ut_asserteq_64(ret, EFI_SUCCESS);
+
+	return 0;
+}
+LIB_TEST(lib_test_efi_allocate_pages, 0);