diff options
author | Atish Patra <atish.patra@wdc.com> | 2020-07-01 11:39:47 -0700 |
---|---|---|
committer | Alistair Francis <alistair.francis@wdc.com> | 2020-07-13 17:25:37 -0700 |
commit | 66b1205bc5ab8bb3f5e12fa4155bbeb56e6724e9 (patch) | |
tree | ae9c0df216dda16062dfd1a7b598fc7d02d4d803 /hw/riscv/sifive_u.c | |
parent | 43cf723adca9a5e188c664c3b606a585192a599c (diff) |
RISC-V: Copy the fdt in dram instead of ROM
Currently, the fdt is copied to the ROM after the reset vector. The firmware
has to copy it to DRAM. Instead of this, directly copy the device tree to a
pre-computed dram address. The device tree load address should be as far as
possible from kernel and initrd images. That's why it is kept at the end of
the DRAM or 4GB whichever is lesser.
Signed-off-by: Atish Patra <atish.patra@wdc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Bin Meng <bin.meng@windriver.com>
Tested-by: Bin Meng <bin.meng@windriver.com>
Message-Id: <20200701183949.398134-3-atish.patra@wdc.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Diffstat (limited to 'hw/riscv/sifive_u.c')
-rw-r--r-- | hw/riscv/sifive_u.c | 28 |
1 files changed, 13 insertions, 15 deletions
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 0695c93d2c..39923209f4 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -379,6 +379,7 @@ static void sifive_u_machine_init(MachineState *machine) MemoryRegion *flash0 = g_new(MemoryRegion, 1); target_ulong start_addr = memmap[SIFIVE_U_DRAM].base; int i; + uint32_t fdt_load_addr; /* Initialize SoC */ object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_RISCV_U_SOC); @@ -450,40 +451,37 @@ static void sifive_u_machine_init(MachineState *machine) } } + /* Compute the fdt load address in dram */ + fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DRAM].base, + machine->ram_size, s->fdt); + /* reset vector */ - uint32_t reset_vec[8] = { + uint32_t reset_vec[11] = { s->msel, /* MSEL pin state */ 0x00000297, /* 1: auipc t0, %pcrel_hi(dtb) */ - 0x01c28593, /* addi a1, t0, %pcrel_lo(1b) */ 0xf1402573, /* csrr a0, mhartid */ #if defined(TARGET_RISCV32) + 0x0202a583, /* lw a1, 32(t0) */ 0x0182a283, /* lw t0, 24(t0) */ #elif defined(TARGET_RISCV64) - 0x0182e283, /* lwu t0, 24(t0) */ + 0x0202b583, /* ld a1, 32(t0) */ + 0x0182b283, /* ld t0, 24(t0) */ #endif 0x00028067, /* jr t0 */ 0x00000000, start_addr, /* start: .dword */ + 0x00000000, + fdt_load_addr, /* fdt_laddr: .dword */ + 0x00000000, /* dtb: */ }; /* copy in the reset vector in little_endian byte order */ - for (i = 0; i < sizeof(reset_vec) >> 2; i++) { + for (i = 0; i < ARRAY_SIZE(reset_vec); i++) { reset_vec[i] = cpu_to_le32(reset_vec[i]); } rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), memmap[SIFIVE_U_MROM].base, &address_space_memory); - - /* copy in the device tree */ - if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > - memmap[SIFIVE_U_MROM].size - sizeof(reset_vec)) { - error_report("not enough space to store device-tree"); - exit(1); - } - qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); - rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), - memmap[SIFIVE_U_MROM].base + sizeof(reset_vec), - &address_space_memory); } static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp) |