On Thu, Nov 21, 2024 at 12:42 AM Jim Shu <jim....@sifive.com> wrote: > > DTB is placed to the end of memory, so we will check if the start > address of DTB overlaps to the address of kernel/initrd. > > Signed-off-by: Jim Shu <jim....@sifive.com>
Reviewed-by: Alistair Francis <alistair.fran...@wdc.com> Alistair > --- > hw/riscv/boot.c | 25 ++++++++++++++++++++++++- > include/hw/riscv/boot.h | 3 +++ > 2 files changed, 27 insertions(+), 1 deletion(-) > > diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c > index 81d27f935e..bc8074fec8 100644 > --- a/hw/riscv/boot.c > +++ b/hw/riscv/boot.c > @@ -70,6 +70,7 @@ char *riscv_plic_hart_config_string(int hart_count) > void riscv_boot_info_init(RISCVBootInfo *info, RISCVHartArrayState *harts) > { > info->kernel_size = 0; > + info->initrd_size = 0; > info->is_32bit = riscv_is_32bit(harts); > } > > @@ -213,6 +214,9 @@ static void riscv_load_initrd(MachineState *machine, > RISCVBootInfo *info) > } > } > > + info->initrd_start = start; > + info->initrd_size = size; > + > /* Some RISC-V machines (e.g. opentitan) don't have a fdt. */ > if (fdt) { > end = start + size; > @@ -309,6 +313,7 @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr > dram_size, > int ret = fdt_pack(ms->fdt); > hwaddr dram_end, temp; > int fdtsize; > + uint64_t dtb_start, dtb_start_limit; > > /* Should only fail if we've built a corrupted tree */ > g_assert(ret == 0); > @@ -319,6 +324,17 @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr > dram_size, > exit(1); > } > > + if (info->initrd_size) { > + /* If initrd is successfully loaded, place DTB after it. */ > + dtb_start_limit = info->initrd_start + info->initrd_size; > + } else if (info->kernel_size) { > + /* If only kernel is successfully loaded, place DTB after it. */ > + dtb_start_limit = info->image_high_addr; > + } else { > + /* Otherwise, do not check DTB overlapping */ > + dtb_start_limit = 0; > + } > + > /* > * A dram_size == 0, usually from a MemMapEntry[].size element, > * means that the DRAM block goes all the way to ms->ram_size. > @@ -338,7 +354,14 @@ uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr > dram_size, > temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : > dram_end; > } > > - return QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); > + dtb_start = QEMU_ALIGN_DOWN(temp - fdtsize, 2 * MiB); > + > + if (dtb_start_limit && (dtb_start < dtb_start_limit)) { > + error_report("No enough memory to place DTB after kernel/initrd"); > + exit(1); > + } > + > + return dtb_start; > } > > /* > diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h > index 06b51ed086..7d59b2e6c6 100644 > --- a/include/hw/riscv/boot.h > +++ b/include/hw/riscv/boot.h > @@ -32,6 +32,9 @@ typedef struct RISCVBootInfo { > hwaddr image_low_addr; > hwaddr image_high_addr; > > + hwaddr initrd_start; > + ssize_t initrd_size; > + > bool is_32bit; > } RISCVBootInfo; > > -- > 2.17.1 > >