>From 8011b74e7eadc1b8113d8bdf347ab8ea29d19da8 Mon Sep 17 00:00:00 2001
From: Michael Eager
Date: Thu, 23 Aug 2018 16:58:27 -0700
Subject: [PATCH] RISC-V - Dynamic parameterization of RISC-V memory map
Memory parameters for RISC-V boards can be read from a configuration
file using the -readconfig command line option. The configuration file
should have a section for the board and memory. The configuration for
the VirtIO board has the following configuration variables:
[riscv-virt-mem]
debug-base = "0x0"
debug-size = "0x100"
mrom-base = "0x1000"
mrom-size = "0x11000"
test-base = "0x100000"
test-size = "0x1000"
clint-base = "0x2000000"
clint-size = "0x10000"
plic-base = "0xc000000"
plic-size = "0x4000000"
uart0-base = "0x10000000"
uart0-size = "0x100"
virtio-base = "0x10001000"
virtio-size = "0x1000"
dram-base = "0x80000000"
dram-size = "0x0"
Values must be enclosed within quotes.
Signed-off-by: Michael Eager
---
hw/riscv/riscv.config | 89 +++++++++++++++++++++++++++++++++++++++++
hw/riscv/sifive_e.c | 109 ++++++++++++++++++++++++++++++++++++++++----------
hw/riscv/sifive_u.c | 109 +++++++++++++++++++++++++++++++++++++++++++++-----
hw/riscv/spike.c | 75 ++++++++++++++++++++++++++++++++--
hw/riscv/virt.c | 85 ++++++++++++++++++++++++++++++++++-----
5 files changed, 423 insertions(+), 44 deletions(-)
create mode 100644 hw/riscv/riscv.config
diff --git a/hw/riscv/riscv.config b/hw/riscv/riscv.config
new file mode 100644
index 0000000..86426c6
--- /dev/null
+++ b/hw/riscv/riscv.config
@@ -0,0 +1,89 @@
+# Memory map for RISC-V VirtIO board
+[riscv-virt-mem]
+ debug-base = "0x0"
+ debug-size = "0x100"
+ mrom-base = "0x1000"
+ mrom-size = "0x11000"
+ test-base = "0x100000"
+ test-size = "0x1000"
+ clint-base = "0x2000000"
+ clint-size = "0x10000"
+ plic-base = "0xc000000"
+ plic-size = "0x4000000"
+ uart0-base = "0x10000000"
+ uart0-size = "0x100"
+ virtio-base = "0x10001000"
+ virtio-size = "0x1000"
+ dram-base = "0x80000000"
+ dram-size = "0x0"
+
+# Memory map for RISC-V Sifive E board
+[riscv-sifive-e-mem]
+ debug-base = "0x0"
+ debug-size = "0x100"
+ mrom-base = "0x1000"
+ mrom-size = "0x2000"
+ otp-base = "0x20000"
+ otp-size = "0x2000"
+ test-base = "0x100000"
+ test-size = "0x1000"
+ clint-base = "0x2000000"
+ clint-size = "0x10000"
+ plic-base = "0xc000000"
+ plic-size = "0x4000000"
+ aon-base = "0x10000000"
+ aon-size = "0x8000"
+ prci-base = "0x10008000"
+ prci-size = "0x8000"
+ otp_ctrl-base = "0x10010000"
+ otp_ctrl-size = "0x1000"
+ gpio0-base = "0x10012000"
+ gpio0-size = "0x1000"
+ uart0-base = "0x10013000"
+ uart0-size = "0x1000"
+ qspi0-base = "0x10014000"
+ qspi0-size = "0x1000"
+ pwm0-base = "0x10015000"
+ pwm0-size = "0x1000"
+ uart1-base = "0x10023000"
+ uart1-size = "0x1000"
+ qspi1-base = "0x10024000"
+ qspi1-size = "0x1000"
+ pwm1-base = "0x10025000"
+ pwm1-size = "0x1000"
+ qspi2-base = "0x10034000"
+ qspi2-size = "0x1000"
+ pwm2-base = "0x10035000"
+ pwm2-size = "0x1000"
+ xip-base = "0x20000000"
+ xip-size = "0x20000000"
+ dtim-base = " 0x80000000"
+ dtim-size = "0x4000"
+
+[riscv-sifive-u-mem]
+ debug-base = "0x0"
+ debug-size = "0x100"
+ mrom-base = "0x1000"
+ mrom-size = "0x11000"
+ test-base = "0x100000"
+ test-size = "0x1000"
+ clint-base = "0x2000000"
+ clint-size = "0x10000"
+ plic-base = "0xc000000"
+ plic-size = "0x4000000"
+ uart0-base = "0x10013000"
+ uart0-size = "0x1000"
+ uart1-base = "0x10023000"
+ uart1-size = "0x1000"
+ dram-base = "0x80000000"
+ dram-size = "0x0"
+ gem-base = "0x100900FC"
+ gem-size = "0x2000"
+
+[riscv-spike-mem]
+ mrom-base = "0x1000"
+ mrom-spike = "0x11000"
+ clint-base = "0x2000000"
+ clint-spike = "0x10000"
+ dram-base = "0x80000000"
+ dram-spike = "0x0"
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index 16b547e..98cd480 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -31,6 +31,8 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
#include "qapi/error.h"
#include "hw/hw.h"
#include "hw/boards.h"
@@ -50,32 +52,86 @@
#include "exec/address-spaces.h"
#include "elf.h"
-static const struct MemmapEntry {
+static struct MemmapEntry {
hwaddr base;
hwaddr size;
+ const char *name;
} sifive_e_memmap[] = {
- [SIFIVE_E_DEBUG] = { 0x0, 0x100 },
- [SIFIVE_E_MROM] = { 0x1000, 0x2000 },
- [SIFIVE_E_OTP] = { 0x20000, 0x2000 },
- [SIFIVE_E_TEST] = { 0x100000, 0x1000 },
- [SIFIVE_E_CLINT] = { 0x2000000, 0x10000 },
- [SIFIVE_E_PLIC] = { 0xc000000, 0x4000000 },
- [SIFIVE_E_AON] = { 0x10000000, 0x8000 },
- [SIFIVE_E_PRCI] = { 0x10008000, 0x8000 },
- [SIFIVE_E_OTP_CTRL] = { 0x10010000, 0x1000 },
- [SIFIVE_E_GPIO0] = { 0x10012000, 0x1000 },
- [SIFIVE_E_UART0] = { 0x10013000, 0x1000 },
- [SIFIVE_E_QSPI0] = { 0x10014000, 0x1000 },
- [SIFIVE_E_PWM0] = { 0x10015000, 0x1000 },
- [SIFIVE_E_UART1] = { 0x10023000, 0x1000 },
- [SIFIVE_E_QSPI1] = { 0x10024000, 0x1000 },
- [SIFIVE_E_PWM1] = { 0x10025000, 0x1000 },
- [SIFIVE_E_QSPI2] = { 0x10034000, 0x1000 },
- [SIFIVE_E_PWM2] = { 0x10035000, 0x1000 },
- [SIFIVE_E_XIP] = { 0x20000000, 0x20000000 },
- [SIFIVE_E_DTIM] = { 0x80000000, 0x4000 }
+ [SIFIVE_E_DEBUG] = { 0x0, 0x100, "debug" },
+ [SIFIVE_E_MROM] = { 0x1000, 0x2000, "mrom" },
+ [SIFIVE_E_OTP] = { 0x20000, 0x2000, "otp" },
+ [SIFIVE_E_TEST] = { 0x100000, 0x1000, "test" },
+ [SIFIVE_E_CLINT] = { 0x2000000, 0x10000, "clint" },
+ [SIFIVE_E_PLIC] = { 0xc000000, 0x4000000, "plic" },
+ [SIFIVE_E_AON] = { 0x10000000, 0x8000, "aon" },
+ [SIFIVE_E_PRCI] = { 0x10008000, 0x8000, "prci" },
+ [SIFIVE_E_OTP_CTRL] = { 0x10010000, 0x1000, "otp_ctrl" },
+ [SIFIVE_E_GPIO0] = { 0x10012000, 0x1000, "gpio0" },
+ [SIFIVE_E_UART0] = { 0x10013000, 0x1000, "uart0" },
+ [SIFIVE_E_QSPI0] = { 0x10014000, 0x1000, "qspi0" },
+ [SIFIVE_E_PWM0] = { 0x10015000, 0x1000, "pwm0" },
+ [SIFIVE_E_UART1] = { 0x10023000, 0x1000, "uart1" },
+ [SIFIVE_E_QSPI1] = { 0x10024000, 0x1000, "qspi1" },
+ [SIFIVE_E_PWM1] = { 0x10025000, 0x1000, "pwm1" },
+ [SIFIVE_E_QSPI2] = { 0x10034000, 0x1000, "qspi2" },
+ [SIFIVE_E_PWM2] = { 0x10035000, 0x1000, "pwm2" },
+ [SIFIVE_E_XIP] = { 0x20000000, 0x20000000, "xip" },
+ [SIFIVE_E_DTIM] = { 0x80000000, 0x4000, "dtim" },
+ { 0, 0, 0 }
};
+static QemuOptsList qemu_riscv_sifive_e_opts = {
+ .name = "riscv-sifive-e-mem",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_riscv_sifive_e_opts.head),
+ .desc = {
+ /* No options defined -- accept any option. */
+ { /* End of list */ }
+ },
+};
+
+static int riscv_sifive_e_parse_1(QemuOpts *opts, const char *name,
+ const char *suffix, hwaddr *ret)
+{
+ const char *value;
+ hwaddr uval;
+ char buf[32];
+ char *endptr;
+
+ strcpy(buf, name);
+ strcat(buf, suffix);
+ value = qemu_opt_get(opts, buf);
+ if (value) {
+ if (strlen(value) == 0) {
+ error_report("invalid format for riscv-sifive_e-mem[%s]", buf);
+ return 1;
+ }
+ uval = strtoll(value, &endptr, 0);
+ if (errno == 0 && ((endptr - value) == strlen(value))) {
+ *ret = uval;
+ }
+ else {
+ error_report("invalid value for riscv-sifive_e-mem[%s] = \"%s\"", buf, value);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Parse configuration values and overwrite defaults. */
+static int riscv_sifive_e_parse(void *opaque, QemuOpts *opts, Error **errp)
+{
+ struct MemmapEntry *entry;
+
+ for (entry = sifive_e_memmap; entry->name != NULL; entry++) {
+ if (riscv_sifive_e_parse_1(opts, entry->name, "-base", &entry->base))
+ exit(EXIT_FAILURE);
+ if (riscv_sifive_e_parse_1(opts, entry->name, "-size", &entry->size))
+ exit(EXIT_FAILURE);
+ }
+
+ return 0;
+}
+
static uint64_t load_kernel(const char *kernel_filename)
{
uint64_t kernel_entry, kernel_high;
@@ -108,6 +164,10 @@ static void riscv_sifive_e_init(MachineState *machine)
int i;
+ /* Read configuration file */
+ qemu_opts_foreach(qemu_find_opts("riscv-sifive-e-mem"),
+ riscv_sifive_e_parse, NULL, NULL);
+
/* Initialize harts */
object_initialize(&s->cpus, sizeof(s->cpus), TYPE_RISCV_HART_ARRAY);
object_property_add_child(OBJECT(machine), "cpus", OBJECT(&s->cpus),
@@ -204,3 +264,10 @@ static void riscv_sifive_e_machine_init(MachineClass *mc)
}
DEFINE_MACHINE("sifive_e", riscv_sifive_e_machine_init)
+
+static void riscv_sifive_e_opts_init(void)
+{
+ qemu_add_opts(&qemu_riscv_sifive_e_opts);
+}
+
+opts_init(riscv_sifive_e_opts_init);
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index fc84ab4..87338cd 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -28,6 +28,8 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
#include "qapi/error.h"
#include "hw/hw.h"
#include "hw/boards.h"
@@ -51,23 +53,95 @@
#include
-static const struct MemmapEntry {
+static struct MemmapEntry {
hwaddr base;
hwaddr size;
+ const char *name;
} sifive_u_memmap[] = {
- [SIFIVE_U_DEBUG] = { 0x0, 0x100 },
- [SIFIVE_U_MROM] = { 0x1000, 0x11000 },
- [SIFIVE_U_TEST] = { 0x100000, 0x1000 },
- [SIFIVE_U_CLINT] = { 0x2000000, 0x10000 },
- [SIFIVE_U_PLIC] = { 0xc000000, 0x4000000 },
- [SIFIVE_U_UART0] = { 0x10013000, 0x1000 },
- [SIFIVE_U_UART1] = { 0x10023000, 0x1000 },
- [SIFIVE_U_DRAM] = { 0x80000000, 0x0 },
- [SIFIVE_U_GEM] = { 0x100900FC, 0x2000 },
+ [SIFIVE_U_DEBUG] = { 0x0, 0x100, "debug" },
+ [SIFIVE_U_MROM] = { 0x1000, 0x11000, "mrom" },
+ [SIFIVE_U_TEST] = { 0x100000, 0x1000, "test" },
+ [SIFIVE_U_CLINT] = { 0x2000000, 0x10000, "clint" },
+ [SIFIVE_U_PLIC] = { 0xc000000, 0x4000000, "plic" },
+ [SIFIVE_U_UART0] = { 0x10013000, 0x1000, "uart0" },
+ [SIFIVE_U_UART1] = { 0x10023000, 0x1000, "uart1" },
+ [SIFIVE_U_DRAM] = { 0x80000000, 0x0, "dram" },
+ [SIFIVE_U_GEM] = { 0x100900FC, 0x2000, "gem" },
+ { 0, 0, 0 }
+};
+
+static QemuOptsList qemu_riscv_sifive_u_opts = {
+ .name = "riscv-sifive-u-mem",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_riscv_sifive_u_opts.head),
+ .desc = {
+ /* No options defined -- accept any option. */
+ { /* End of list */ }
+ },
};
#define GEM_REVISION 0x10070109
+static QemuOptsList qemu_sifive_u_opts = {
+ .name = "sifive_u",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_sifive_u_opts.head),
+ .desc = {
+ /* No options defined -- accept any option. */
+ { /* End of list */ }
+ },
+};
+
+static int riscv_sifive_u_parse_1(QemuOpts *opts, const char *name,
+ const char *suffix, hwaddr *ret)
+{
+ const char *value;
+ hwaddr uval;
+ char buf[32];
+ char *endptr;
+
+ strcpy(buf, name);
+ strcat(buf, suffix);
+ value = qemu_opt_get(opts, buf);
+ if (value) {
+ if (strlen(value) == 0) {
+ error_report("invalid format for riscv-sifive_u-mem[%s]", buf);
+ return 1;
+ }
+ uval = strtoll(value, &endptr, 0);
+ if (errno == 0 && ((endptr - value) == strlen(value))) {
+ *ret = uval;
+ }
+ else {
+ error_report("invalid value for riscv-sifive_u-mem[%s] = \"%s\"", buf, value);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Parse configuration values and overwrite defaults. */
+static int riscv_sifive_u_parse(void *opaque, QemuOpts *opts, Error **errp)
+{
+ struct MemmapEntry *entry;
+
+ for (entry = sifive_u_memmap; entry->name != NULL; entry++) {
+ if (riscv_sifive_u_parse_1(opts, entry->name, "-base", &entry->base))
+ exit(EXIT_FAILURE);
+ if (riscv_sifive_u_parse_1(opts, entry->name, "-size", &entry->size))
+ exit(EXIT_FAILURE);
+ }
+
+ return 0;
+}
+
+static void riscv_sifive_u_readconfig(void)
+{
+#if 0
+ QemuOpts *opts = qemu_find_opts("sifive_u");
+#endif
+
+ puts ("riscv_sifive_u_readconfig called\n");
+}
+
static uint64_t load_kernel(const char *kernel_filename)
{
uint64_t kernel_entry, kernel_high;
@@ -258,6 +332,13 @@ static void riscv_sifive_u_init(MachineState *machine)
int i;
+ /* Read configuration file */
+ qemu_opts_foreach(qemu_find_opts("riscv-sifive-u-mem"),
+ riscv_sifive_u_parse, NULL, NULL);
+
+ /* Read configuration file */
+ riscv_sifive_u_readconfig();
+
/* Initialize harts */
object_initialize(&s->cpus, sizeof(s->cpus), TYPE_RISCV_HART_ARRAY);
object_property_add_child(OBJECT(machine), "cpus", OBJECT(&s->cpus),
@@ -370,3 +451,11 @@ static void riscv_sifive_u_machine_init(MachineClass *mc)
}
DEFINE_MACHINE("sifive_u", riscv_sifive_u_machine_init)
+
+
+static void riscv_sifive_u_opts_init(void)
+{
+ qemu_add_opts(&qemu_riscv_sifive_u_opts);
+}
+
+opts_init(riscv_sifive_u_opts_init);
diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c
index b0f0e97..84b548d 100644
--- a/hw/riscv/spike.c
+++ b/hw/riscv/spike.c
@@ -26,6 +26,8 @@
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
#include "qapi/error.h"
#include "hw/hw.h"
#include "hw/boards.h"
@@ -44,15 +46,69 @@
#include
-static const struct MemmapEntry {
+static struct MemmapEntry {
hwaddr base;
hwaddr size;
+ const char *name;
} spike_memmap[] = {
- [SPIKE_MROM] = { 0x1000, 0x11000 },
- [SPIKE_CLINT] = { 0x2000000, 0x10000 },
- [SPIKE_DRAM] = { 0x80000000, 0x0 },
+ [SPIKE_MROM] = { 0x1000, 0x11000, "mrom" },
+ [SPIKE_CLINT] = { 0x2000000, 0x10000, "clint" },
+ [SPIKE_DRAM] = { 0x80000000, 0x0, "dram" },
+ { 0, 0, 0 }
};
+static QemuOptsList qemu_riscv_spike_opts = {
+ .name = "riscv-spike-mem",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_riscv_spike_opts.head),
+ .desc = {
+ /* No options defined -- accept any option. */
+ { /* End of list */ }
+ },
+};
+
+static int riscv_spike_parse_1(QemuOpts *opts, const char *name,
+ const char *suffix, hwaddr *ret)
+{
+ const char *value;
+ hwaddr uval;
+ char buf[32];
+ char *endptr;
+
+ strcpy(buf, name);
+ strcat(buf, suffix);
+ value = qemu_opt_get(opts, buf);
+ if (value) {
+ if (strlen(value) == 0) {
+ error_report("invalid format for riscv-spike-mem[%s]", buf);
+ return 1;
+ }
+ uval = strtoll(value, &endptr, 0);
+ if (errno == 0 && ((endptr - value) == strlen(value))) {
+ *ret = uval;
+ }
+ else {
+ error_report("invalid value for riscv-spike-mem[%s] = \"%s\"", buf, value);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Parse configuration values and overwrite defaults. */
+static int riscv_spike_parse(void *opaque, QemuOpts *opts, Error **errp)
+{
+ struct MemmapEntry *entry;
+
+ for (entry = spike_memmap; entry->name != NULL; entry++) {
+ if (riscv_spike_parse_1(opts, entry->name, "-base", &entry->base))
+ exit(EXIT_FAILURE);
+ if (riscv_spike_parse_1(opts, entry->name, "-size", &entry->size))
+ exit(EXIT_FAILURE);
+ }
+
+ return 0;
+}
+
static uint64_t load_kernel(const char *kernel_filename)
{
uint64_t kernel_entry, kernel_high;
@@ -172,6 +228,10 @@ static void spike_v1_10_0_board_init(MachineState *machine)
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
int i;
+ /* Read configuration file */
+ qemu_opts_foreach(qemu_find_opts("riscv-sparc-mem"),
+ riscv_spike_parse, NULL, NULL);
+
/* Initialize SOC */
object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
TYPE_RISCV_HART_ARRAY, &error_abort, NULL);
@@ -364,3 +424,10 @@ static void spike_v1_10_0_machine_init(MachineClass *mc)
DEFINE_MACHINE("spike_v1.9.1", spike_v1_09_1_machine_init)
DEFINE_MACHINE("spike_v1.10", spike_v1_10_0_machine_init)
+
+static void riscv_sifive_spike_opts_init(void)
+{
+ qemu_add_opts(&qemu_riscv_spike_opts);
+}
+
+opts_init(riscv_sifive_spike_opts_init);
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 66dc4e0..b10fbe7 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -22,6 +22,8 @@
#include "qemu/units.h"
#include "qemu/log.h"
#include "qemu/error-report.h"
+#include "qemu/option.h"
+#include "qemu/config-file.h"
#include "qapi/error.h"
#include "hw/hw.h"
#include "hw/boards.h"
@@ -44,20 +46,74 @@
#include
-static const struct MemmapEntry {
+static struct MemmapEntry {
hwaddr base;
hwaddr size;
+ const char *name;
} virt_memmap[] = {
- [VIRT_DEBUG] = { 0x0, 0x100 },
- [VIRT_MROM] = { 0x1000, 0x11000 },
- [VIRT_TEST] = { 0x100000, 0x1000 },
- [VIRT_CLINT] = { 0x2000000, 0x10000 },
- [VIRT_PLIC] = { 0xc000000, 0x4000000 },
- [VIRT_UART0] = { 0x10000000, 0x100 },
- [VIRT_VIRTIO] = { 0x10001000, 0x1000 },
- [VIRT_DRAM] = { 0x80000000, 0x0 },
+ [VIRT_DEBUG] = { 0x0, 0x100, "debug" },
+ [VIRT_MROM] = { 0x1000, 0x11000, "mrom" },
+ [VIRT_TEST] = { 0x100000, 0x1000, "test" },
+ [VIRT_CLINT] = { 0x2000000, 0x10000, "clint" },
+ [VIRT_PLIC] = { 0xc000000, 0x4000000, "plic" },
+ [VIRT_UART0] = { 0x10000000, 0x100, "uart0" },
+ [VIRT_VIRTIO] = { 0x10001000, 0x1000, "virtio" },
+ [VIRT_DRAM] = { 0x80000000, 0x0, "dram" },
+ { 0, 0, 0 }
};
+static QemuOptsList qemu_riscv_virt_opts = {
+ .name = "riscv-virt-mem",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_riscv_virt_opts.head),
+ .desc = {
+ /* No options defined -- accept any option. */
+ { /* End of list */ }
+ },
+};
+
+static int riscv_virt_parse_1(QemuOpts *opts, const char *name,
+ const char *suffix, hwaddr *ret)
+{
+ const char *value;
+ hwaddr uval;
+ char buf[32];
+ char *endptr;
+
+ strcpy(buf, name);
+ strcat(buf, suffix);
+ value = qemu_opt_get(opts, buf);
+ if (value) {
+ if (strlen(value) == 0) {
+ error_report("invalid format for riscv-virt-mem[%s]", buf);
+ return 1;
+ }
+ uval = strtoll(value, &endptr, 0);
+ if (errno == 0 && ((endptr - value) == strlen(value))) {
+ *ret = uval;
+ }
+ else {
+ error_report("invalid value for riscv-virt-mem[%s] = \"%s\"", buf, value);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* Parse configuration values and overwrite defaults. */
+static int riscv_virt_parse(void *opaque, QemuOpts *opts, Error **errp)
+{
+ struct MemmapEntry *entry;
+
+ for (entry = virt_memmap; entry->name != NULL; entry++) {
+ if (riscv_virt_parse_1(opts, entry->name, "-base", &entry->base))
+ exit(EXIT_FAILURE);
+ if (riscv_virt_parse_1(opts, entry->name, "-size", &entry->size))
+ exit(EXIT_FAILURE);
+ }
+
+ return 0;
+}
+
static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
uint64_t mem_size, const char *cmdline)
{
@@ -236,6 +292,10 @@ static void riscv_virt_board_init(MachineState *machine)
void *fdt;
hwaddr firmware_entry;
+ /* Read configuration file */
+ qemu_opts_foreach(qemu_find_opts("riscv-virt-mem"),
+ riscv_virt_parse, NULL, NULL);
+
/* Initialize SOC */
object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
TYPE_RISCV_HART_ARRAY, &error_abort, NULL);
@@ -352,3 +412,10 @@ static void riscv_virt_board_machine_init(MachineClass *mc)
}
DEFINE_MACHINE("virt", riscv_virt_board_machine_init)
+
+static void riscv_sifive_virt_opts_init(void)
+{
+ qemu_add_opts(&qemu_riscv_virt_opts);
+}
+
+opts_init(riscv_sifive_virt_opts_init);
--
1.8.3.1