[PATCH 03/16] arm: save_prev_bl_data: ARM32 support

Sam Day me at samcday.com
Mon Jun 1 10:03:55 CEST 2026


The main change here is to make is_addr_accessible() portable, by using
gd->bd->bi_ram rather than the ARMv8 memory map. AFAICT, at the point
that this is running, these two things are 1:1 anyway (see
qcom_configure_bi_dram).

Once that's out of the way, we add ARM32 support by looking at r2 rather
than r0 and using portable pointer types.

Signed-off-by: Sam Day <me at samcday.com>
---
 arch/arm/lib/save_prev_bl_data.c | 49 ++++++++++++++++++++++++----------------
 1 file changed, 29 insertions(+), 20 deletions(-)

diff --git a/arch/arm/lib/save_prev_bl_data.c b/arch/arm/lib/save_prev_bl_data.c
index 4357acaef6c..83670541c50 100644
--- a/arch/arm/lib/save_prev_bl_data.c
+++ b/arch/arm/lib/save_prev_bl_data.c
@@ -12,33 +12,41 @@
 #include <fdt.h>
 #include <linux/errno.h>
 #include <asm/system.h>
-#include <asm/armv8/mmu.h>
 
-static ulong reg0 __section(".data");
+#include <asm/global_data.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static phys_addr_t prev_bl_fdt_addr __section(".data");
 
 /**
- * Save x0 register value, assuming previous bootloader set it to
- * point on loaded fdt or (for older linux kernels)atags.
+ * Save the register value used by Linux boot ABI to pass the FDT or ATAGS.
  */
-void save_boot_params(ulong r0)
+void save_boot_params(ulong r0, ulong __always_unused r1, ulong r2)
 {
-	reg0 = r0;
+	if (IS_ENABLED(CONFIG_ARM64))
+		prev_bl_fdt_addr = r0;
+	else
+		prev_bl_fdt_addr = r2;
+
 	save_boot_params_ret();
 }
 
 bool is_addr_accessible(phys_addr_t addr)
 {
-	struct mm_region *mem = mem_map;
 	phys_addr_t bank_start;
 	phys_addr_t bank_end;
 
-	while (mem->size) {
-		bank_start = mem->phys;
-		bank_end = bank_start + mem->size;
-		debug("check if block %pap - %pap includes %pap\n", &bank_start, &bank_end, &addr);
-		if (addr > bank_start && addr < bank_end)
+	for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
+		if (!gd->bd->bi_dram[i].size)
+			continue;
+
+		bank_start = gd->bd->bi_dram[i].start;
+		bank_end = bank_start + gd->bd->bi_dram[i].size;
+		debug("check if block %pap - %pap includes %pap\n",
+		      &bank_start, &bank_end, &addr);
+		if (addr >= bank_start && addr < bank_end)
 			return true;
-		mem++;
 	}
 
 	return false;
@@ -46,33 +54,34 @@ bool is_addr_accessible(phys_addr_t addr)
 
 phys_addr_t get_prev_bl_fdt_addr(void)
 {
-	return reg0;
+	return prev_bl_fdt_addr;
 }
 
 int save_prev_bl_data(void)
 {
 	struct fdt_header *fdt_blob;
 	int node;
-	u64 initrd_start_prop;
+	phys_addr_t initrd_start_prop;
 
-	if (!is_addr_accessible((phys_addr_t)reg0))
+	if (!is_addr_accessible(prev_bl_fdt_addr))
 		return -ENODATA;
 
-	fdt_blob = (struct fdt_header *)reg0;
+	fdt_blob = (struct fdt_header *)prev_bl_fdt_addr;
 	if (!fdt_valid(&fdt_blob)) {
-		pr_warn("%s: address 0x%lx is not a valid fdt\n", __func__, reg0);
+		pr_warn("%s: address 0x%lx is not a valid fdt\n",
+			__func__, prev_bl_fdt_addr);
 		return -ENODATA;
 	}
 
 	if (IS_ENABLED(CONFIG_SAVE_PREV_BL_FDT_ADDR))
-		env_set_addr("prevbl_fdt_addr", (void *)reg0);
+		env_set_addr("prevbl_fdt_addr", (const void *)prev_bl_fdt_addr);
 	if (!IS_ENABLED(CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR))
 		return 0;
 
 	node = fdt_path_offset(fdt_blob, "/chosen");
 	if (!node) {
 		pr_warn("%s: chosen node not found in device tree at addr: 0x%lx\n",
-					__func__, reg0);
+					__func__, prev_bl_fdt_addr);
 		return -ENODATA;
 	}
 	/*

-- 
2.54.0




More information about the U-Boot mailing list