Message ID | 20220419115945.37945-1-dylan@andestech.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | hw/riscv: boot: Support 64bit fdt address. | expand |
On Tue, Apr 19, 2022 at 10:03 PM Dylan Jhong <dylan@andestech.com> wrote: > > The current riscv_load_fdt() forces fdt_load_addr to be placed at a dram address within 3GB, > but not all platforms have dram_base within 3GB. > > This patch adds an exception for dram base not within 3GB, > which will place fdt at dram_end align 16MB. > > riscv_setup_rom_reset_vec() also needs to be modified > > Signed-off-by: Dylan Jhong <dylan@andestech.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > hw/riscv/boot.c | 12 +++++++----- > include/hw/riscv/boot.h | 4 ++-- > 2 files changed, 9 insertions(+), 7 deletions(-) > > diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c > index 519fa455a1..852aa92bbe 100644 > --- a/hw/riscv/boot.c > +++ b/hw/riscv/boot.c > @@ -203,9 +203,9 @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, > return *start + size; > } > > -uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) > +uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) > { > - uint32_t temp, fdt_addr; > + uint64_t temp, fdt_addr; > hwaddr dram_end = dram_base + mem_size; > int ret, fdtsize = fdt_totalsize(fdt); > > @@ -220,7 +220,7 @@ uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) > * Thus, put it at an 16MB aligned address that less than fdt size from the > * end of dram or 3GB whichever is lesser. > */ > - temp = MIN(dram_end, 3072 * MiB); > + temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end; > fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 16 * MiB); > > ret = fdt_pack(fdt); > @@ -276,13 +276,15 @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts > hwaddr start_addr, > hwaddr rom_base, hwaddr rom_size, > uint64_t kernel_entry, > - uint32_t fdt_load_addr, void *fdt) > + uint64_t fdt_load_addr, void *fdt) > { > int i; > uint32_t start_addr_hi32 = 0x00000000; > + uint32_t fdt_load_addr_hi32 = 0x00000000; > > if (!riscv_is_32bit(harts)) { > start_addr_hi32 = start_addr >> 32; > + fdt_load_addr_hi32 = fdt_load_addr >> 32; > } > /* reset vector */ > uint32_t reset_vec[10] = { > @@ -295,7 +297,7 @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts > start_addr, /* start: .dword */ > start_addr_hi32, > fdt_load_addr, /* fdt_laddr: .dword */ > - 0x00000000, > + fdt_load_addr_hi32, > /* fw_dyn: */ > }; > if (riscv_is_32bit(harts)) { > diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h > index baff11dd8a..346441e369 100644 > --- a/include/hw/riscv/boot.h > +++ b/include/hw/riscv/boot.h > @@ -48,12 +48,12 @@ target_ulong riscv_load_kernel(const char *kernel_filename, > symbol_fn_t sym_cb); > hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, > uint64_t kernel_entry, hwaddr *start); > -uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); > +uint64_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); > void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts, > hwaddr saddr, > hwaddr rom_base, hwaddr rom_size, > uint64_t kernel_entry, > - uint32_t fdt_load_addr, void *fdt); > + uint64_t fdt_load_addr, void *fdt); > void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base, > hwaddr rom_size, > uint32_t reset_vec_size, > -- > 2.34.1 > >
On Tue, Apr 19, 2022 at 10:03 PM Dylan Jhong <dylan@andestech.com> wrote: > > The current riscv_load_fdt() forces fdt_load_addr to be placed at a dram address within 3GB, > but not all platforms have dram_base within 3GB. > > This patch adds an exception for dram base not within 3GB, > which will place fdt at dram_end align 16MB. > > riscv_setup_rom_reset_vec() also needs to be modified > > Signed-off-by: Dylan Jhong <dylan@andestech.com> Thanks! Applied to riscv-to-apply.next Alistair > --- > hw/riscv/boot.c | 12 +++++++----- > include/hw/riscv/boot.h | 4 ++-- > 2 files changed, 9 insertions(+), 7 deletions(-) > > diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c > index 519fa455a1..852aa92bbe 100644 > --- a/hw/riscv/boot.c > +++ b/hw/riscv/boot.c > @@ -203,9 +203,9 @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, > return *start + size; > } > > -uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) > +uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) > { > - uint32_t temp, fdt_addr; > + uint64_t temp, fdt_addr; > hwaddr dram_end = dram_base + mem_size; > int ret, fdtsize = fdt_totalsize(fdt); > > @@ -220,7 +220,7 @@ uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) > * Thus, put it at an 16MB aligned address that less than fdt size from the > * end of dram or 3GB whichever is lesser. > */ > - temp = MIN(dram_end, 3072 * MiB); > + temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end; > fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 16 * MiB); > > ret = fdt_pack(fdt); > @@ -276,13 +276,15 @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts > hwaddr start_addr, > hwaddr rom_base, hwaddr rom_size, > uint64_t kernel_entry, > - uint32_t fdt_load_addr, void *fdt) > + uint64_t fdt_load_addr, void *fdt) > { > int i; > uint32_t start_addr_hi32 = 0x00000000; > + uint32_t fdt_load_addr_hi32 = 0x00000000; > > if (!riscv_is_32bit(harts)) { > start_addr_hi32 = start_addr >> 32; > + fdt_load_addr_hi32 = fdt_load_addr >> 32; > } > /* reset vector */ > uint32_t reset_vec[10] = { > @@ -295,7 +297,7 @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts > start_addr, /* start: .dword */ > start_addr_hi32, > fdt_load_addr, /* fdt_laddr: .dword */ > - 0x00000000, > + fdt_load_addr_hi32, > /* fw_dyn: */ > }; > if (riscv_is_32bit(harts)) { > diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h > index baff11dd8a..346441e369 100644 > --- a/include/hw/riscv/boot.h > +++ b/include/hw/riscv/boot.h > @@ -48,12 +48,12 @@ target_ulong riscv_load_kernel(const char *kernel_filename, > symbol_fn_t sym_cb); > hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, > uint64_t kernel_entry, hwaddr *start); > -uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); > +uint64_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); > void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts, > hwaddr saddr, > hwaddr rom_base, hwaddr rom_size, > uint64_t kernel_entry, > - uint32_t fdt_load_addr, void *fdt); > + uint64_t fdt_load_addr, void *fdt); > void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base, > hwaddr rom_size, > uint32_t reset_vec_size, > -- > 2.34.1 > >
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index 519fa455a1..852aa92bbe 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -203,9 +203,9 @@ hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, return *start + size; } -uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) +uint64_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) { - uint32_t temp, fdt_addr; + uint64_t temp, fdt_addr; hwaddr dram_end = dram_base + mem_size; int ret, fdtsize = fdt_totalsize(fdt); @@ -220,7 +220,7 @@ uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt) * Thus, put it at an 16MB aligned address that less than fdt size from the * end of dram or 3GB whichever is lesser. */ - temp = MIN(dram_end, 3072 * MiB); + temp = (dram_base < 3072 * MiB) ? MIN(dram_end, 3072 * MiB) : dram_end; fdt_addr = QEMU_ALIGN_DOWN(temp - fdtsize, 16 * MiB); ret = fdt_pack(fdt); @@ -276,13 +276,15 @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts hwaddr start_addr, hwaddr rom_base, hwaddr rom_size, uint64_t kernel_entry, - uint32_t fdt_load_addr, void *fdt) + uint64_t fdt_load_addr, void *fdt) { int i; uint32_t start_addr_hi32 = 0x00000000; + uint32_t fdt_load_addr_hi32 = 0x00000000; if (!riscv_is_32bit(harts)) { start_addr_hi32 = start_addr >> 32; + fdt_load_addr_hi32 = fdt_load_addr >> 32; } /* reset vector */ uint32_t reset_vec[10] = { @@ -295,7 +297,7 @@ void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts start_addr, /* start: .dword */ start_addr_hi32, fdt_load_addr, /* fdt_laddr: .dword */ - 0x00000000, + fdt_load_addr_hi32, /* fw_dyn: */ }; if (riscv_is_32bit(harts)) { diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index baff11dd8a..346441e369 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -48,12 +48,12 @@ target_ulong riscv_load_kernel(const char *kernel_filename, symbol_fn_t sym_cb); hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, uint64_t kernel_entry, hwaddr *start); -uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); +uint64_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt); void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState *harts, hwaddr saddr, hwaddr rom_base, hwaddr rom_size, uint64_t kernel_entry, - uint32_t fdt_load_addr, void *fdt); + uint64_t fdt_load_addr, void *fdt); void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base, hwaddr rom_size, uint32_t reset_vec_size,
The current riscv_load_fdt() forces fdt_load_addr to be placed at a dram address within 3GB, but not all platforms have dram_base within 3GB. This patch adds an exception for dram base not within 3GB, which will place fdt at dram_end align 16MB. riscv_setup_rom_reset_vec() also needs to be modified Signed-off-by: Dylan Jhong <dylan@andestech.com> --- hw/riscv/boot.c | 12 +++++++----- include/hw/riscv/boot.h | 4 ++-- 2 files changed, 9 insertions(+), 7 deletions(-)