diff options
-rw-r--r-- | hw/riscv/boot.c | 35 | ||||
-rw-r--r-- | hw/riscv/microchip_pfsoc.c | 3 | ||||
-rw-r--r-- | hw/riscv/sifive_u.c | 3 | ||||
-rw-r--r-- | hw/riscv/spike.c | 3 | ||||
-rw-r--r-- | hw/riscv/virt.c | 3 | ||||
-rw-r--r-- | include/hw/riscv/boot.h | 2 |
6 files changed, 32 insertions, 17 deletions
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 2e53494b08..c7e0e50bd8 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -250,34 +250,45 @@ void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry) } /* - * The FDT should be put at the farthest point possible to - * avoid overwriting it with the kernel/initrd. + * This function makes an assumption that the DRAM interval + * 'dram_base' + 'dram_size' is contiguous. * - * This function makes an assumption that the DRAM is - * contiguous. It also cares about 32-bit systems and - * will limit fdt_addr to be addressable by them even for - * 64-bit CPUs. + * Considering that 'dram_end' is the lowest value between + * the end of the DRAM block and MachineState->ram_size, the + * FDT location will vary according to 'dram_base': + * + * - if 'dram_base' is less that 3072 MiB, the FDT will be + * put at the lowest value between 3072 MiB and 'dram_end'; + * + * - if 'dram_base' is higher than 3072 MiB, the FDT will be + * put at 'dram_end'. * * The FDT is fdt_packed() during the calculation. */ -uint64_t riscv_compute_fdt_addr(hwaddr dram_base, uint64_t mem_size, - void *fdt) +uint64_t riscv_compute_fdt_addr(hwaddr dram_base, hwaddr dram_size, + MachineState *ms) { - uint64_t temp; - hwaddr dram_end = dram_base + mem_size; - int ret = fdt_pack(fdt); + int ret = fdt_pack(ms->fdt); + hwaddr dram_end, temp; int fdtsize; /* Should only fail if we've built a corrupted tree */ g_assert(ret == 0); - fdtsize = fdt_totalsize(fdt); + fdtsize = fdt_totalsize(ms->fdt); if (fdtsize <= 0) { error_report("invalid device-tree"); exit(1); } /* + * A dram_size == 0, usually from a MemMapEntry[].size element, + * means that the DRAM block goes all the way to ms->ram_size. + */ + dram_end = dram_base; + dram_end += dram_size ? MIN(ms->ram_size, dram_size) : ms->ram_size; + + /* * We should put fdt as far as possible to avoid kernel/initrd overwriting * its content. But it should be addressable by 32 bit system as well. * Thus, put it at an 2MB aligned address that less than fdt size from the diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c index 17499d4152..2b91e49561 100644 --- a/hw/riscv/microchip_pfsoc.c +++ b/hw/riscv/microchip_pfsoc.c @@ -642,7 +642,8 @@ static void microchip_icicle_kit_machine_init(MachineState *machine) /* Compute the fdt load address in dram */ fdt_load_addr = riscv_compute_fdt_addr(memmap[MICROCHIP_PFSOC_DRAM_LO].base, - machine->ram_size, machine->fdt); + memmap[MICROCHIP_PFSOC_DRAM_LO].size, + machine); riscv_load_fdt(fdt_load_addr, machine->fdt); /* Load the reset vector */ diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 626d4dc2f3..d3ab7a9cda 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -617,7 +617,8 @@ static void sifive_u_machine_init(MachineState *machine) } fdt_load_addr = riscv_compute_fdt_addr(memmap[SIFIVE_U_DEV_DRAM].base, - machine->ram_size, machine->fdt); + memmap[SIFIVE_U_DEV_DRAM].size, + machine); riscv_load_fdt(fdt_load_addr, machine->fdt); if (!riscv_is_32bit(&s->soc.u_cpus)) { diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index f1114f2c71..cc3f6dac17 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -325,7 +325,8 @@ static void spike_board_init(MachineState *machine) } fdt_load_addr = riscv_compute_fdt_addr(memmap[SPIKE_DRAM].base, - machine->ram_size, machine->fdt); + memmap[SPIKE_DRAM].size, + machine); riscv_load_fdt(fdt_load_addr, machine->fdt); /* load the reset vector */ diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 2e0a0cdb17..a061151a6f 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -1304,7 +1304,8 @@ static void virt_machine_done(Notifier *notifier, void *data) } fdt_load_addr = riscv_compute_fdt_addr(memmap[VIRT_DRAM].base, - machine->ram_size, machine->fdt); + memmap[VIRT_DRAM].size, + machine); riscv_load_fdt(fdt_load_addr, machine->fdt); /* load the reset vector */ diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index 46de4ec46b..511390f60e 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -48,7 +48,7 @@ target_ulong riscv_load_kernel(MachineState *machine, symbol_fn_t sym_cb); void riscv_load_initrd(MachineState *machine, uint64_t kernel_entry); uint64_t riscv_compute_fdt_addr(hwaddr dram_start, uint64_t dram_size, - void *fdt); + MachineState *ms); void riscv_load_fdt(hwaddr fdt_addr, void *fdt); void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts, hwaddr saddr, |