Split the common RISC-V boot functions into a seperate file. This allows
us to share the common code.
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
hw/riscv/Makefile.objs | 1 +
hw/riscv/boot.c | 69 +++++++++++++++++++++++++++++++++++++++++
hw/riscv/sifive_e.c | 17 ++--------
hw/riscv/sifive_u.c | 17 ++--------
hw/riscv/spike.c | 21 +++----------
hw/riscv/virt.c | 51 +++---------------------------
include/hw/riscv/boot.h | 27 ++++++++++++++++
7 files changed, 110 insertions(+), 93 deletions(-)
create mode 100644 hw/riscv/boot.c
create mode 100644 include/hw/riscv/boot.h
diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
index a65027304a..eb9d4f9ffc 100644
--- a/hw/riscv/Makefile.objs
+++ b/hw/riscv/Makefile.objs
@@ -1,3 +1,4 @@
+obj-y += boot.o
obj-$(CONFIG_SPIKE) += riscv_htif.o
obj-$(CONFIG_HART) += riscv_hart.o
obj-$(CONFIG_SIFIVE_E) += sifive_e.o
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
new file mode 100644
index 0000000000..62f94aaf8a
--- /dev/null
+++ b/hw/riscv/boot.c
@@ -0,0 +1,69 @@
+/*
+ * QEMU RISC-V Boot Helper
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2019 Alistair Francis <alistair.francis@wdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "qemu/osdep.h"
+#include "qemu/units.h"
+#include "qemu/error-report.h"
+#include "exec/cpu-defs.h"
+#include "hw/loader.h"
+#include "hw/riscv/boot.h"
+#include "elf.h"
+
+target_ulong riscv_load_kernel(const char *kernel_filename)
+{
+ uint64_t kernel_entry, kernel_high;
+
+ if (load_elf(kernel_filename, NULL, NULL, NULL,
+ &kernel_entry, NULL, &kernel_high,
+ 0, EM_RISCV, 1, 0) < 0) {
+ error_report("could not load kernel '%s'", kernel_filename);
+ exit(1);
+ }
+
+ return kernel_entry;
+}
+
+hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
+ uint64_t kernel_entry, hwaddr *start)
+{
+ int size;
+
+ /* We want to put the initrd far enough into RAM that when the
+ * kernel is uncompressed it will not clobber the initrd. However
+ * on boards without much RAM we must ensure that we still leave
+ * enough room for a decent sized initrd, and on boards with large
+ * amounts of RAM we must avoid the initrd being so far up in RAM
+ * that it is outside lowmem and inaccessible to the kernel.
+ * So for boards with less than 256MB of RAM we put the initrd
+ * halfway into RAM, and for boards with 256MB of RAM or more we put
+ * the initrd at 128MB.
+ */
+ *start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
+
+ size = load_ramdisk(filename, *start, mem_size - *start);
+ if (size == -1) {
+ size = load_image_targphys(filename, *start, mem_size - *start);
+ if (size == -1) {
+ error_report("could not load ramdisk '%s'", filename);
+ exit(1);
+ }
+ }
+
+ return *start + size;
+}
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 80ac56fa7d..9d58ae362b 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -44,10 +44,10 @@
#include "hw/riscv/sifive_prci.h"
#include "hw/riscv/sifive_uart.h"
#include "hw/riscv/sifive_e.h"
+#include "hw/riscv/boot.h"
#include "chardev/char.h"
#include "sysemu/arch_init.h"
#include "exec/address-spaces.h"
-#include "elf.h"
static const struct MemmapEntry {
hwaddr base;
@@ -74,19 +74,6 @@ static const struct MemmapEntry {
[SIFIVE_E_DTIM] = { 0x80000000, 0x4000 }
};
-static target_ulong load_kernel(const char *kernel_filename)
-{
- uint64_t kernel_entry, kernel_high;
-
- if (load_elf(kernel_filename, NULL, NULL, NULL,
- &kernel_entry, NULL, &kernel_high,
- 0, EM_RISCV, 1, 0) < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- return kernel_entry;
-}
-
static void sifive_mmio_emulate(MemoryRegion *parent, const char *name,
uintptr_t offset, uintptr_t length)
{
@@ -131,7 +118,7 @@ static void riscv_sifive_e_init(MachineState *machine)
memmap[SIFIVE_E_MROM].base, &address_space_memory);
if (machine->kernel_filename) {
- load_kernel(machine->kernel_filename);
+ riscv_load_kernel(machine->kernel_filename);
}
}
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 5ecc47cea3..1b9281bd4a 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -41,11 +41,11 @@
#include "hw/riscv/sifive_uart.h"
#include "hw/riscv/sifive_prci.h"
#include "hw/riscv/sifive_u.h"
+#include "hw/riscv/boot.h"
#include "chardev/char.h"
#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "exec/address-spaces.h"
-#include "elf.h"
#include <libfdt.h>
@@ -65,19 +65,6 @@ static const struct MemmapEntry {
#define GEM_REVISION 0x10070109
-static target_ulong load_kernel(const char *kernel_filename)
-{
- uint64_t kernel_entry, kernel_high;
-
- if (load_elf(kernel_filename, NULL, NULL, NULL,
- &kernel_entry, NULL, &kernel_high,
- 0, EM_RISCV, 1, 0) < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- return kernel_entry;
-}
-
static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
uint64_t mem_size, const char *cmdline)
{
@@ -280,7 +267,7 @@ static void riscv_sifive_u_init(MachineState *machine)
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
if (machine->kernel_filename) {
- load_kernel(machine->kernel_filename);
+ riscv_load_kernel(machine->kernel_filename);
}
/* reset vector */
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index 5b33d4be3b..e68be00a5f 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -36,12 +36,12 @@
#include "hw/riscv/riscv_hart.h"
#include "hw/riscv/sifive_clint.h"
#include "hw/riscv/spike.h"
+#include "hw/riscv/boot.h"
#include "chardev/char.h"
#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "sysemu/qtest.h"
#include "exec/address-spaces.h"
-#include "elf.h"
#include <libfdt.h>
@@ -54,19 +54,6 @@ static const struct MemmapEntry {
[SPIKE_DRAM] = { 0x80000000, 0x0 },
};
-static target_ulong load_kernel(const char *kernel_filename)
-{
- uint64_t kernel_entry, kernel_high;
-
- if (load_elf_ram_sym(kernel_filename, NULL, NULL, NULL,
- &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0,
- NULL, true, htif_symbol_callback) < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- return kernel_entry;
-}
-
static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
uint64_t mem_size, const char *cmdline)
{
@@ -199,7 +186,7 @@ static void spike_board_init(MachineState *machine)
mask_rom);
if (machine->kernel_filename) {
- load_kernel(machine->kernel_filename);
+ riscv_load_kernel(machine->kernel_filename);
}
/* reset vector */
@@ -287,7 +274,7 @@ static void spike_v1_10_0_board_init(MachineState *machine)
mask_rom);
if (machine->kernel_filename) {
- load_kernel(machine->kernel_filename);
+ riscv_load_kernel(machine->kernel_filename);
}
/* reset vector */
@@ -372,7 +359,7 @@ static void spike_v1_09_1_board_init(MachineState *machine)
mask_rom);
if (machine->kernel_filename) {
- load_kernel(machine->kernel_filename);
+ riscv_load_kernel(machine->kernel_filename);
}
/* reset vector */
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 84d94d0c42..5f8c11471b 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -34,13 +34,13 @@
#include "hw/riscv/sifive_clint.h"
#include "hw/riscv/sifive_test.h"
#include "hw/riscv/virt.h"
+#include "hw/riscv/boot.h"
#include "chardev/char.h"
#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "exec/address-spaces.h"
#include "hw/pci/pci.h"
#include "hw/pci-host/gpex.h"
-#include "elf.h"
#include <libfdt.h>
@@ -61,47 +61,6 @@ static const struct MemmapEntry {
[VIRT_PCIE_ECAM] = { 0x30000000, 0x10000000 },
};
-static target_ulong load_kernel(const char *kernel_filename)
-{
- uint64_t kernel_entry, kernel_high;
-
- if (load_elf(kernel_filename, NULL, NULL, NULL,
- &kernel_entry, NULL, &kernel_high,
- 0, EM_RISCV, 1, 0) < 0) {
- error_report("could not load kernel '%s'", kernel_filename);
- exit(1);
- }
- return kernel_entry;
-}
-
-static hwaddr load_initrd(const char *filename, uint64_t mem_size,
- uint64_t kernel_entry, hwaddr *start)
-{
- int size;
-
- /* We want to put the initrd far enough into RAM that when the
- * kernel is uncompressed it will not clobber the initrd. However
- * on boards without much RAM we must ensure that we still leave
- * enough room for a decent sized initrd, and on boards with large
- * amounts of RAM we must avoid the initrd being so far up in RAM
- * that it is outside lowmem and inaccessible to the kernel.
- * So for boards with less than 256MB of RAM we put the initrd
- * halfway into RAM, and for boards with 256MB of RAM or more we put
- * the initrd at 128MB.
- */
- *start = kernel_entry + MIN(mem_size / 2, 128 * MiB);
-
- size = load_ramdisk(filename, *start, mem_size - *start);
- if (size == -1) {
- size = load_image_targphys(filename, *start, mem_size - *start);
- if (size == -1) {
- error_report("could not load ramdisk '%s'", filename);
- exit(1);
- }
- }
- return *start + size;
-}
-
static void create_pcie_irq_map(void *fdt, char *nodename,
uint32_t plic_phandle)
{
@@ -422,13 +381,13 @@ static void riscv_virt_board_init(MachineState *machine)
mask_rom);
if (machine->kernel_filename) {
- uint64_t kernel_entry = load_kernel(machine->kernel_filename);
+ uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename);
if (machine->initrd_filename) {
hwaddr start;
- hwaddr end = load_initrd(machine->initrd_filename,
- machine->ram_size, kernel_entry,
- &start);
+ hwaddr end = riscv_load_initrd(machine->initrd_filename,
+ machine->ram_size, kernel_entry,
+ &start);
qemu_fdt_setprop_cell(fdt, "/chosen",
"linux,initrd-start", start);
qemu_fdt_setprop_cell(fdt, "/chosen", "linux,initrd-end",
diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h
new file mode 100644
index 0000000000..f84fd6c2df
--- /dev/null
+++ b/include/hw/riscv/boot.h
@@ -0,0 +1,27 @@
+/*
+ * QEMU RISC-V Boot Helper
+ *
+ * Copyright (c) 2017 SiFive, Inc.
+ * Copyright (c) 2019 Alistair Francis <alistair.francis@wdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2 or later, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RISCV_BOOT_H
+#define RISCV_BOOT_H
+
+target_ulong riscv_load_kernel(const char *kernel_filename);
+hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
+ uint64_t kernel_entry, hwaddr *start);
+
+#endif /* RISCV_BOOT_H */
--
2.22.0
On Wed, Jun 19, 2019 at 8:51 AM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Split the common RISC-V boot functions into a seperate file. This allows
> us to share the common code.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> hw/riscv/Makefile.objs | 1 +
> hw/riscv/boot.c | 69 +++++++++++++++++++++++++++++++++++++++++
> hw/riscv/sifive_e.c | 17 ++--------
> hw/riscv/sifive_u.c | 17 ++--------
> hw/riscv/spike.c | 21 +++----------
> hw/riscv/virt.c | 51 +++---------------------------
> include/hw/riscv/boot.h | 27 ++++++++++++++++
> 7 files changed, 110 insertions(+), 93 deletions(-)
> create mode 100644 hw/riscv/boot.c
> create mode 100644 include/hw/riscv/boot.h
>
> diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
> index a65027304a..eb9d4f9ffc 100644
> --- a/hw/riscv/Makefile.objs
> +++ b/hw/riscv/Makefile.objs
> @@ -1,3 +1,4 @@
> +obj-y += boot.o
> obj-$(CONFIG_SPIKE) += riscv_htif.o
> obj-$(CONFIG_HART) += riscv_hart.o
> obj-$(CONFIG_SIFIVE_E) += sifive_e.o
> diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
> new file mode 100644
> index 0000000000..62f94aaf8a
> --- /dev/null
> +++ b/hw/riscv/boot.c
> @@ -0,0 +1,69 @@
> +/*
> + * QEMU RISC-V Boot Helper
> + *
> + * Copyright (c) 2017 SiFive, Inc.
> + * Copyright (c) 2019 Alistair Francis <alistair.francis@wdc.com>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms and conditions of the GNU General Public License,
> + * version 2 or later, as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> + * more details.
> + *
> + * You should have received a copy of the GNU General Public License along with
> + * this program. If not, see <http://www.gnu.org/licenses/>.
> + */
> +
> +#include "qemu/osdep.h"
> +#include "qemu/units.h"
> +#include "qemu/error-report.h"
> +#include "exec/cpu-defs.h"
> +#include "hw/loader.h"
> +#include "hw/riscv/boot.h"
> +#include "elf.h"
> +
> +target_ulong riscv_load_kernel(const char *kernel_filename)
> +{
> + uint64_t kernel_entry, kernel_high;
> +
> + if (load_elf(kernel_filename, NULL, NULL, NULL,
> + &kernel_entry, NULL, &kernel_high,
> + 0, EM_RISCV, 1, 0) < 0) {
> + error_report("could not load kernel '%s'", kernel_filename);
> + exit(1);
> + }
> +
> + return kernel_entry;
> +}
> +
> +hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
> + uint64_t kernel_entry, hwaddr *start)
> +{
> + int size;
> +
> + /* We want to put the initrd far enough into RAM that when the
nits: /* should be on a separate line
> + * kernel is uncompressed it will not clobber the initrd. However
> + * on boards without much RAM we must ensure that we still leave
> + * enough room for a decent sized initrd, and on boards with large
> + * amounts of RAM we must avoid the initrd being so far up in RAM
> + * that it is outside lowmem and inaccessible to the kernel.
> + * So for boards with less than 256MB of RAM we put the initrd
> + * halfway into RAM, and for boards with 256MB of RAM or more we put
> + * the initrd at 128MB.
> + */
[snip]
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>
On Wed, Jun 19, 2019 at 8:16 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Wed, Jun 19, 2019 at 8:51 AM Alistair Francis
> <alistair.francis@wdc.com> wrote:
> >
> > Split the common RISC-V boot functions into a seperate file. This allows
> > us to share the common code.
> >
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> > hw/riscv/Makefile.objs | 1 +
> > hw/riscv/boot.c | 69 +++++++++++++++++++++++++++++++++++++++++
> > hw/riscv/sifive_e.c | 17 ++--------
> > hw/riscv/sifive_u.c | 17 ++--------
> > hw/riscv/spike.c | 21 +++----------
> > hw/riscv/virt.c | 51 +++---------------------------
> > include/hw/riscv/boot.h | 27 ++++++++++++++++
> > 7 files changed, 110 insertions(+), 93 deletions(-)
> > create mode 100644 hw/riscv/boot.c
> > create mode 100644 include/hw/riscv/boot.h
> >
> > diff --git a/hw/riscv/Makefile.objs b/hw/riscv/Makefile.objs
> > index a65027304a..eb9d4f9ffc 100644
> > --- a/hw/riscv/Makefile.objs
> > +++ b/hw/riscv/Makefile.objs
> > @@ -1,3 +1,4 @@
> > +obj-y += boot.o
> > obj-$(CONFIG_SPIKE) += riscv_htif.o
> > obj-$(CONFIG_HART) += riscv_hart.o
> > obj-$(CONFIG_SIFIVE_E) += sifive_e.o
> > diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c
> > new file mode 100644
> > index 0000000000..62f94aaf8a
> > --- /dev/null
> > +++ b/hw/riscv/boot.c
> > @@ -0,0 +1,69 @@
> > +/*
> > + * QEMU RISC-V Boot Helper
> > + *
> > + * Copyright (c) 2017 SiFive, Inc.
> > + * Copyright (c) 2019 Alistair Francis <alistair.francis@wdc.com>
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms and conditions of the GNU General Public License,
> > + * version 2 or later, as published by the Free Software Foundation.
> > + *
> > + * This program is distributed in the hope it will be useful, but WITHOUT
> > + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
> > + * more details.
> > + *
> > + * You should have received a copy of the GNU General Public License along with
> > + * this program. If not, see <http://www.gnu.org/licenses/>.
> > + */
> > +
> > +#include "qemu/osdep.h"
> > +#include "qemu/units.h"
> > +#include "qemu/error-report.h"
> > +#include "exec/cpu-defs.h"
> > +#include "hw/loader.h"
> > +#include "hw/riscv/boot.h"
> > +#include "elf.h"
> > +
> > +target_ulong riscv_load_kernel(const char *kernel_filename)
> > +{
> > + uint64_t kernel_entry, kernel_high;
> > +
> > + if (load_elf(kernel_filename, NULL, NULL, NULL,
> > + &kernel_entry, NULL, &kernel_high,
> > + 0, EM_RISCV, 1, 0) < 0) {
> > + error_report("could not load kernel '%s'", kernel_filename);
> > + exit(1);
> > + }
> > +
> > + return kernel_entry;
> > +}
> > +
> > +hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
> > + uint64_t kernel_entry, hwaddr *start)
> > +{
> > + int size;
> > +
> > + /* We want to put the initrd far enough into RAM that when the
>
> nits: /* should be on a separate line
Fixed
>
> > + * kernel is uncompressed it will not clobber the initrd. However
> > + * on boards without much RAM we must ensure that we still leave
> > + * enough room for a decent sized initrd, and on boards with large
> > + * amounts of RAM we must avoid the initrd being so far up in RAM
> > + * that it is outside lowmem and inaccessible to the kernel.
> > + * So for boards with less than 256MB of RAM we put the initrd
> > + * halfway into RAM, and for boards with 256MB of RAM or more we put
> > + * the initrd at 128MB.
> > + */
>
> [snip]
>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> Tested-by: Bin Meng <bmeng.cn@gmail.com>
Thanks!
Alistair
© 2016 - 2025 Red Hat, Inc.