1 // SPDX-License-Identifier: GPL-2.0+
3 * save_prev_bl_data - saving previous bootloader data
4 * to environment variables.
11 #include <fdt_support.h>
14 #include <linux/errno.h>
15 #include <asm/system.h>
16 #include <asm/armv8/mmu.h>
18 static ulong reg0 __section(".data");
21 * Save x0 register value, assuming previous bootloader set it to
22 * point on loaded fdt or (for older linux kernels)atags.
24 void save_boot_params(ulong r0)
27 save_boot_params_ret();
30 bool is_addr_accessible(phys_addr_t addr)
32 struct mm_region *mem = mem_map;
33 phys_addr_t bank_start;
37 bank_start = mem->phys;
38 bank_end = bank_start + mem->size;
39 debug("check if block %pap - %pap includes %pap\n", &bank_start, &bank_end, &addr);
40 if (addr > bank_start && addr < bank_end)
48 phys_addr_t get_prev_bl_fdt_addr(void)
53 int save_prev_bl_data(void)
55 struct fdt_header *fdt_blob;
57 u64 initrd_start_prop;
59 if (!is_addr_accessible((phys_addr_t)reg0))
62 fdt_blob = (struct fdt_header *)reg0;
63 if (!fdt_valid(&fdt_blob)) {
64 pr_warn("%s: address 0x%lx is not a valid fdt\n", __func__, reg0);
68 if (IS_ENABLED(CONFIG_SAVE_PREV_BL_FDT_ADDR))
69 env_set_addr("prevbl_fdt_addr", (void *)reg0);
70 if (!IS_ENABLED(CONFIG_SAVE_PREV_BL_INITRAMFS_START_ADDR))
73 node = fdt_path_offset(fdt_blob, "/chosen");
75 pr_warn("%s: chosen node not found in device tree at addr: 0x%lx\n",
80 * linux,initrd-start property might be either 64 or 32 bit,
81 * depending on primary bootloader implementation.
83 initrd_start_prop = fdtdec_get_uint64(fdt_blob, node, "linux,initrd-start", 0);
84 if (!initrd_start_prop) {
85 debug("%s: attempt to get uint64 linux,initrd-start property failed, trying uint\n",
87 initrd_start_prop = fdtdec_get_uint(fdt_blob, node, "linux,initrd-start", 0);
88 if (!initrd_start_prop) {
89 debug("%s: attempt to get uint failed, too\n", __func__);
93 env_set_addr("prevbl_initrd_start_addr", (void *)initrd_start_prop);