[PATCH] hw/riscv: boot: Support 64bit fdt address.

Dylan Jhong posted 1 patch 2 years ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20220419115945.37945-1-dylan@andestech.com
Maintainers: Palmer Dabbelt <palmer@dabbelt.com>, Alistair Francis <alistair.francis@wdc.com>, Bin Meng <bin.meng@windriver.com>
hw/riscv/boot.c         | 12 +++++++-----
include/hw/riscv/boot.h |  4 ++--
2 files changed, 9 insertions(+), 7 deletions(-)
[PATCH] hw/riscv: boot: Support 64bit fdt address.
Posted by Dylan Jhong 2 years ago
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(-)

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
Re: [PATCH] hw/riscv: boot: Support 64bit fdt address.
Posted by Alistair Francis 2 years ago
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
>
>
Re: [PATCH] hw/riscv: boot: Support 64bit fdt address.
Posted by Alistair Francis 2 years ago
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
>
>