diff mbox series

[v2,2/4] hw/riscv: Return the end address of the loaded firmware

Message ID 558cf67162342d65a23262248b040563716628b2.1602634524.git.alistair.francis@wdc.com
State Superseded
Headers show
Series Allow loading a no MMU kernel | expand

Commit Message

Alistair Francis Oct. 14, 2020, 12:17 a.m. UTC
Instead of returning the unused entry address from riscv_load_firmware()
instead return the end address. Also return the end address from
riscv_find_and_load_firmware().

This tells the caller if a firmware was loaded and how big it is. This
can be used to determine the load address of the next image (usually the
kernel).

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/riscv/boot.h |  8 ++++----
 hw/riscv/boot.c         | 28 +++++++++++++++++-----------
 2 files changed, 21 insertions(+), 15 deletions(-)

Comments

Palmer Dabbelt Oct. 19, 2020, 11:17 p.m. UTC | #1
On Tue, 13 Oct 2020 17:17:28 PDT (-0700), Alistair Francis wrote:
> Instead of returning the unused entry address from riscv_load_firmware()

> instead return the end address. Also return the end address from

> riscv_find_and_load_firmware().

>

> This tells the caller if a firmware was loaded and how big it is. This

> can be used to determine the load address of the next image (usually the

> kernel).

>

> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

> ---

>  include/hw/riscv/boot.h |  8 ++++----

>  hw/riscv/boot.c         | 28 +++++++++++++++++-----------

>  2 files changed, 21 insertions(+), 15 deletions(-)

>

> diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h

> index 451338780a..0acbd8aa6e 100644

> --- a/include/hw/riscv/boot.h

> +++ b/include/hw/riscv/boot.h

> @@ -23,10 +23,10 @@

>  #include "exec/cpu-defs.h"

>  #include "hw/loader.h"

>

> -void riscv_find_and_load_firmware(MachineState *machine,

> -                                  const char *default_machine_firmware,

> -                                  hwaddr firmware_load_addr,

> -                                  symbol_fn_t sym_cb);

> +target_ulong riscv_find_and_load_firmware(MachineState *machine,

> +                                          const char *default_machine_firmware,

> +                                          hwaddr firmware_load_addr,

> +                                          symbol_fn_t sym_cb);

>  char *riscv_find_firmware(const char *firmware_filename);

>  target_ulong riscv_load_firmware(const char *firmware_filename,

>                                   hwaddr firmware_load_addr,

> diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c

> index 21adaae56e..fa699308a0 100644

> --- a/hw/riscv/boot.c

> +++ b/hw/riscv/boot.c

> @@ -40,12 +40,13 @@

>  #define fw_dynamic_info_data(__val)     cpu_to_le64(__val)

>  #endif

>

> -void riscv_find_and_load_firmware(MachineState *machine,

> -                                  const char *default_machine_firmware,

> -                                  hwaddr firmware_load_addr,

> -                                  symbol_fn_t sym_cb)

> +target_ulong riscv_find_and_load_firmware(MachineState *machine,

> +                                          const char *default_machine_firmware,

> +                                          hwaddr firmware_load_addr,

> +                                          symbol_fn_t sym_cb)

>  {

>      char *firmware_filename = NULL;

> +    target_ulong firmware_end_addr = firmware_load_addr;

>

>      if ((!machine->firmware) || (!strcmp(machine->firmware, "default"))) {

>          /*

> @@ -60,9 +61,12 @@ void riscv_find_and_load_firmware(MachineState *machine,

>

>      if (firmware_filename) {

>          /* If not "none" load the firmware */

> -        riscv_load_firmware(firmware_filename, firmware_load_addr, sym_cb);

> +        firmware_end_addr = riscv_load_firmware(firmware_filename,

> +                                                firmware_load_addr, sym_cb);

>          g_free(firmware_filename);

>      }

> +

> +    return firmware_end_addr;

>  }

>

>  char *riscv_find_firmware(const char *firmware_filename)

> @@ -91,17 +95,19 @@ target_ulong riscv_load_firmware(const char *firmware_filename,

>                                   hwaddr firmware_load_addr,

>                                   symbol_fn_t sym_cb)

>  {

> -    uint64_t firmware_entry;

> +    uint64_t firmware_entry, firmware_size, firmware_end;

>

>      if (load_elf_ram_sym(firmware_filename, NULL, NULL, NULL,

> -                         &firmware_entry, NULL, NULL, NULL,

> +                         &firmware_entry, NULL, &firmware_end, NULL,

>                           0, EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {

> -        return firmware_entry;

> +        return firmware_end;

>      }

>

> -    if (load_image_targphys_as(firmware_filename, firmware_load_addr,

> -                               ram_size, NULL) > 0) {

> -        return firmware_load_addr;

> +    firmware_size = load_image_targphys_as(firmware_filename,

> +                                           firmware_load_addr, ram_size, NULL);

> +

> +    if (firmware_size > 0) {

> +        return firmware_load_addr + firmware_size;

>      }

>

>      error_report("could not load firmware '%s'", firmware_filename);


Reviewed-by: Palmer Dabbelt <palmerdabbelt@google.com>
Bin Meng Oct. 20, 2020, 3:17 a.m. UTC | #2
On Wed, Oct 14, 2020 at 8:28 AM Alistair Francis
<alistair.francis@wdc.com> wrote:
>

> Instead of returning the unused entry address from riscv_load_firmware()

> instead return the end address. Also return the end address from

> riscv_find_and_load_firmware().

>

> This tells the caller if a firmware was loaded and how big it is. This

> can be used to determine the load address of the next image (usually the

> kernel).

>

> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

> ---

>  include/hw/riscv/boot.h |  8 ++++----

>  hw/riscv/boot.c         | 28 +++++++++++++++++-----------

>  2 files changed, 21 insertions(+), 15 deletions(-)

>


Reviewed-by: Bin Meng <bin.meng@windriver.com>

Tested-by: Bin Meng <bin.meng@windriver.com>
diff mbox series

Patch

diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
index 451338780a..0acbd8aa6e 100644
--- a/include/hw/riscv/boot.h
+++ b/include/hw/riscv/boot.h
@@ -23,10 +23,10 @@ 
 #include "exec/cpu-defs.h"
 #include "hw/loader.h"
 
-void riscv_find_and_load_firmware(MachineState *machine,
-                                  const char *default_machine_firmware,
-                                  hwaddr firmware_load_addr,
-                                  symbol_fn_t sym_cb);
+target_ulong riscv_find_and_load_firmware(MachineState *machine,
+                                          const char *default_machine_firmware,
+                                          hwaddr firmware_load_addr,
+                                          symbol_fn_t sym_cb);
 char *riscv_find_firmware(const char *firmware_filename);
 target_ulong riscv_load_firmware(const char *firmware_filename,
                                  hwaddr firmware_load_addr,
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
index 21adaae56e..fa699308a0 100644
--- a/hw/riscv/boot.c
+++ b/hw/riscv/boot.c
@@ -40,12 +40,13 @@ 
 #define fw_dynamic_info_data(__val)     cpu_to_le64(__val)
 #endif
 
-void riscv_find_and_load_firmware(MachineState *machine,
-                                  const char *default_machine_firmware,
-                                  hwaddr firmware_load_addr,
-                                  symbol_fn_t sym_cb)
+target_ulong riscv_find_and_load_firmware(MachineState *machine,
+                                          const char *default_machine_firmware,
+                                          hwaddr firmware_load_addr,
+                                          symbol_fn_t sym_cb)
 {
     char *firmware_filename = NULL;
+    target_ulong firmware_end_addr = firmware_load_addr;
 
     if ((!machine->firmware) || (!strcmp(machine->firmware, "default"))) {
         /*
@@ -60,9 +61,12 @@  void riscv_find_and_load_firmware(MachineState *machine,
 
     if (firmware_filename) {
         /* If not "none" load the firmware */
-        riscv_load_firmware(firmware_filename, firmware_load_addr, sym_cb);
+        firmware_end_addr = riscv_load_firmware(firmware_filename,
+                                                firmware_load_addr, sym_cb);
         g_free(firmware_filename);
     }
+
+    return firmware_end_addr;
 }
 
 char *riscv_find_firmware(const char *firmware_filename)
@@ -91,17 +95,19 @@  target_ulong riscv_load_firmware(const char *firmware_filename,
                                  hwaddr firmware_load_addr,
                                  symbol_fn_t sym_cb)
 {
-    uint64_t firmware_entry;
+    uint64_t firmware_entry, firmware_size, firmware_end;
 
     if (load_elf_ram_sym(firmware_filename, NULL, NULL, NULL,
-                         &firmware_entry, NULL, NULL, NULL,
+                         &firmware_entry, NULL, &firmware_end, NULL,
                          0, EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) {
-        return firmware_entry;
+        return firmware_end;
     }
 
-    if (load_image_targphys_as(firmware_filename, firmware_load_addr,
-                               ram_size, NULL) > 0) {
-        return firmware_load_addr;
+    firmware_size = load_image_targphys_as(firmware_filename,
+                                           firmware_load_addr, ram_size, NULL);
+
+    if (firmware_size > 0) {
+        return firmware_load_addr + firmware_size;
     }
 
     error_report("could not load firmware '%s'", firmware_filename);