From 2a8756ed7d64f8fed6ad50fb062f7118e47c856c Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Sat, 3 Mar 2018 14:30:07 +1300 Subject: RISC-V: Replace hardcoded constants with enum values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The RISC-V device-tree code has a number of hard-coded constants and this change moves them into header enums. Cc: Sagar Karandikar Cc: Bastian Koppelmann Signed-off-by: Michael Clark Signed-off-by: Palmer Dabbelt Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- hw/riscv/sifive_clint.c | 9 +++------ hw/riscv/sifive_u.c | 6 ++++-- hw/riscv/spike.c | 6 ++++-- hw/riscv/virt.c | 6 ++++-- include/hw/riscv/sifive_clint.h | 4 ++++ include/hw/riscv/sifive_u.h | 4 ++++ include/hw/riscv/spike.h | 4 ++++ include/hw/riscv/virt.h | 4 ++++ 8 files changed, 31 insertions(+), 12 deletions(-) diff --git a/hw/riscv/sifive_clint.c b/hw/riscv/sifive_clint.c index 4893453b70..7cc606e065 100644 --- a/hw/riscv/sifive_clint.c +++ b/hw/riscv/sifive_clint.c @@ -26,13 +26,10 @@ #include "hw/riscv/sifive_clint.h" #include "qemu/timer.h" -/* See: riscv-pk/machine/sbi_entry.S and arch/riscv/kernel/time.c */ -#define TIMER_FREQ (10 * 1000 * 1000) - static uint64_t cpu_riscv_read_rtc(void) { - return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), TIMER_FREQ, - NANOSECONDS_PER_SECOND); + return muldiv64(qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL), + SIFIVE_CLINT_TIMEBASE_FREQ, NANOSECONDS_PER_SECOND); } /* @@ -59,7 +56,7 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value) diff = cpu->env.timecmp - rtc_r; /* back to ns (note args switched in muldiv64) */ next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + - muldiv64(diff, NANOSECONDS_PER_SECOND, TIMER_FREQ); + muldiv64(diff, NANOSECONDS_PER_SECOND, SIFIVE_CLINT_TIMEBASE_FREQ); timer_mod(cpu->env.timer, next); } diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 66616bacd7..1bd2bde9b8 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -122,7 +122,8 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap, g_free(nodename); qemu_fdt_add_subnode(fdt, "/cpus"); - qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", 10000000); + qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", + SIFIVE_CLINT_TIMEBASE_FREQ); qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0); qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1); @@ -131,7 +132,8 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap, char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu); char *isa = riscv_isa_string(&s->soc.harts[cpu]); qemu_fdt_add_subnode(fdt, nodename); - qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 1000000000); + qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", + SIFIVE_U_CLOCK_FREQ); qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48"); qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa); qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv"); diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 62857e4fa0..ae82f4eb63 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -115,7 +115,8 @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap, g_free(nodename); qemu_fdt_add_subnode(fdt, "/cpus"); - qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", 10000000); + qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", + SIFIVE_CLINT_TIMEBASE_FREQ); qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0); qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1); @@ -124,7 +125,8 @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap, char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu); char *isa = riscv_isa_string(&s->soc.harts[cpu]); qemu_fdt_add_subnode(fdt, nodename); - qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 1000000000); + qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", + SPIKE_CLOCK_FREQ); qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48"); qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa); qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv"); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 4f69eb2cff..2480dad11f 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -145,7 +145,8 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap, g_free(nodename); qemu_fdt_add_subnode(fdt, "/cpus"); - qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", 10000000); + qemu_fdt_setprop_cell(fdt, "/cpus", "timebase-frequency", + SIFIVE_CLINT_TIMEBASE_FREQ); qemu_fdt_setprop_cell(fdt, "/cpus", "#size-cells", 0x0); qemu_fdt_setprop_cell(fdt, "/cpus", "#address-cells", 0x1); @@ -155,7 +156,8 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap, char *intc = g_strdup_printf("/cpus/cpu@%d/interrupt-controller", cpu); char *isa = riscv_isa_string(&s->soc.harts[cpu]); qemu_fdt_add_subnode(fdt, nodename); - qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", 1000000000); + qemu_fdt_setprop_cell(fdt, nodename, "clock-frequency", + VIRT_CLOCK_FREQ); qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48"); qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa); qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv"); diff --git a/include/hw/riscv/sifive_clint.h b/include/hw/riscv/sifive_clint.h index aaa2a58c6e..e2865be1d1 100644 --- a/include/hw/riscv/sifive_clint.h +++ b/include/hw/riscv/sifive_clint.h @@ -47,4 +47,8 @@ enum { SIFIVE_TIME_BASE = 0xBFF8 }; +enum { + SIFIVE_CLINT_TIMEBASE_FREQ = 10000000 +}; + #endif diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h index 662e8a1c1a..be38aa09da 100644 --- a/include/hw/riscv/sifive_u.h +++ b/include/hw/riscv/sifive_u.h @@ -50,6 +50,10 @@ enum { SIFIVE_U_UART1_IRQ = 4 }; +enum { + SIFIVE_U_CLOCK_FREQ = 1000000000 +}; + #define SIFIVE_U_PLIC_HART_CONFIG "MS" #define SIFIVE_U_PLIC_NUM_SOURCES 127 #define SIFIVE_U_PLIC_NUM_PRIORITIES 7 diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h index cb55a14d30..d85a64e33d 100644 --- a/include/hw/riscv/spike.h +++ b/include/hw/riscv/spike.h @@ -42,6 +42,10 @@ enum { SPIKE_DRAM }; +enum { + SPIKE_CLOCK_FREQ = 1000000000 +}; + #if defined(TARGET_RISCV32) #define SPIKE_V1_09_1_CPU TYPE_RISCV_CPU_RV32GCSU_V1_09_1 #define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_RV32GCSU_V1_10_0 diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 7525647e63..2fbe808da5 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -55,6 +55,10 @@ enum { VIRTIO_NDEV = 10 }; +enum { + VIRT_CLOCK_FREQ = 1000000000 +}; + #define VIRT_PLIC_HART_CONFIG "MS" #define VIRT_PLIC_NUM_SOURCES 127 #define VIRT_PLIC_NUM_PRIORITIES 7 -- cgit v1.2.1 From 77ff5bba315d4453ae97ff90ba7698fb1ccc077c Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Sat, 3 Mar 2018 16:23:03 +1300 Subject: RISC-V: Make virt board description match spike MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This makes 'qemu-system-riscv64 -machine help' output more tidy and consistent. Cc: Sagar Karandikar Cc: Bastian Koppelmann Signed-off-by: Michael Clark Signed-off-by: Palmer Dabbelt Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- hw/riscv/virt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 2480dad11f..df06fc7207 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -407,7 +407,7 @@ static const TypeInfo riscv_virt_board_device = { static void riscv_virt_board_machine_init(MachineClass *mc) { - mc->desc = "RISC-V VirtIO Board (Privileged spec v1.10)"; + mc->desc = "RISC-V VirtIO Board (Privileged ISA v1.10)"; mc->init = riscv_virt_board_init; mc->max_cpus = 8; /* hardcoded limit in BBL */ } -- cgit v1.2.1 From 6b01e3277e0e189a8f064b94c4f761e4efadd758 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Sun, 4 Mar 2018 11:15:09 +1300 Subject: RISC-V: Use ROM base address and size from memmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Another case of replacing hard coded constants, this time referring to the definition in the virt machine's memmap. Cc: Sagar Karandikar Cc: Bastian Koppelmann Signed-off-by: Michael Clark Signed-off-by: Palmer Dabbelt Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- hw/riscv/virt.c | 4 ++-- include/hw/riscv/virt.h | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index df06fc7207..3cc9c8090b 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -341,11 +341,11 @@ static void riscv_virt_board_init(MachineState *machine) }; /* copy in the reset vector */ - copy_le32_to_phys(ROM_BASE, reset_vec, sizeof(reset_vec)); + copy_le32_to_phys(memmap[VIRT_MROM].base, reset_vec, sizeof(reset_vec)); /* copy in the device tree */ qemu_fdt_dumpdtb(s->fdt, s->fdt_size); - cpu_physical_memory_write(ROM_BASE + sizeof(reset_vec), + cpu_physical_memory_write(memmap[VIRT_MROM].base + sizeof(reset_vec), s->fdt, s->fdt_size); /* create PLIC hart topology configuration string */ diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 2fbe808da5..655e85ddbd 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -23,8 +23,6 @@ #define VIRT(obj) \ OBJECT_CHECK(RISCVVirtState, (obj), TYPE_RISCV_VIRT_BOARD) -enum { ROM_BASE = 0x1000 }; - typedef struct { /*< private >*/ SysBusDevice parent_obj; -- cgit v1.2.1 From b7938980fbd3209fd94b17c98c54ec044b762417 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Sun, 4 Mar 2018 11:32:17 +1300 Subject: RISC-V: Remove identity_translate from load_elf MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When load_elf is called with NULL as an argument to the address translate callback, it does an identity translation. This commit removes the redundant identity_translate callback. Cc: Sagar Karandikar Cc: Bastian Koppelmann Signed-off-by: Michael Clark Signed-off-by: Palmer Dabbelt Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- hw/riscv/sifive_e.c | 7 +------ hw/riscv/sifive_u.c | 7 +------ hw/riscv/spike.c | 7 +------ hw/riscv/virt.c | 7 +------ 4 files changed, 4 insertions(+), 24 deletions(-) diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index 487244890e..3e523a0734 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -82,16 +82,11 @@ static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) } } -static uint64_t identity_translate(void *opaque, uint64_t addr) -{ - return addr; -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; - if (load_elf(kernel_filename, identity_translate, NULL, + if (load_elf(kernel_filename, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, ELF_MACHINE, 1, 0) < 0) { error_report("qemu: could not load kernel '%s'", kernel_filename); diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 1bd2bde9b8..adc6c22662 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -68,16 +68,11 @@ static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) } } -static uint64_t identity_translate(void *opaque, uint64_t addr) -{ - return addr; -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; - if (load_elf(kernel_filename, identity_translate, NULL, + if (load_elf(kernel_filename, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, ELF_MACHINE, 1, 0) < 0) { error_report("qemu: could not load kernel '%s'", kernel_filename); diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index ae82f4eb63..cf7f9bcc39 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -59,16 +59,11 @@ static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) } } -static uint64_t identity_translate(void *opaque, uint64_t addr) -{ - return addr; -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; - if (load_elf_ram_sym(kernel_filename, identity_translate, NULL, + if (load_elf_ram_sym(kernel_filename, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, ELF_MACHINE, 1, 0, NULL, true, htif_symbol_callback) < 0) { error_report("qemu: could not load kernel '%s'", kernel_filename); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 3cc9c8090b..c2aa795981 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -62,16 +62,11 @@ static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) } } -static uint64_t identity_translate(void *opaque, uint64_t addr) -{ - return addr; -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; - if (load_elf(kernel_filename, identity_translate, NULL, + if (load_elf(kernel_filename, NULL, NULL, &kernel_entry, NULL, &kernel_high, 0, ELF_MACHINE, 1, 0) < 0) { error_report("qemu: could not load kernel '%s'", kernel_filename); -- cgit v1.2.1 From 42b3a4b7ccbbf419df926939b273fe3b8a6dca1f Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Sun, 4 Mar 2018 13:27:37 +1300 Subject: RISC-V: Remove unused class definitions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes a whole lot of unnecessary boilerplate code. Machines don't need to be objects. The expansion of the SOC object model for the RISC-V machines will happen in the future as SiFive plans to add their FE310 and FU540 SOCs to QEMU. However, it seems that this present boilerplate is complete unnecessary. Cc: Sagar Karandikar Cc: Bastian Koppelmann Signed-off-by: Michael Clark Signed-off-by: Palmer Dabbelt Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- hw/riscv/riscv_hart.c | 6 ------ hw/riscv/sifive_e.c | 25 ------------------------- hw/riscv/sifive_u.c | 25 ------------------------- hw/riscv/spike.c | 20 -------------------- hw/riscv/virt.c | 25 ------------------------- include/hw/riscv/sifive_e.h | 5 ----- include/hw/riscv/sifive_u.h | 5 ----- include/hw/riscv/spike.h | 7 ------- include/hw/riscv/virt.h | 5 ----- 9 files changed, 123 deletions(-) diff --git a/hw/riscv/riscv_hart.c b/hw/riscv/riscv_hart.c index 14e3c186fe..75ba7ed579 100644 --- a/hw/riscv/riscv_hart.c +++ b/hw/riscv/riscv_hart.c @@ -68,16 +68,10 @@ static void riscv_harts_class_init(ObjectClass *klass, void *data) dc->realize = riscv_harts_realize; } -static void riscv_harts_init(Object *obj) -{ - /* RISCVHartArrayState *s = SIFIVE_COREPLEX(obj); */ -} - static const TypeInfo riscv_harts_info = { .name = TYPE_RISCV_HART_ARRAY, .parent = TYPE_SYS_BUS_DEVICE, .instance_size = sizeof(RISCVHartArrayState), - .instance_init = riscv_harts_init, .class_init = riscv_harts_class_init, }; diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index 3e523a0734..22dc526713 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -194,24 +194,6 @@ static void riscv_sifive_e_init(MachineState *machine) } } -static int riscv_sifive_e_sysbus_device_init(SysBusDevice *sysbusdev) -{ - return 0; -} - -static void riscv_sifive_e_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = riscv_sifive_e_sysbus_device_init; -} - -static const TypeInfo riscv_sifive_e_device = { - .name = TYPE_SIFIVE_E, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(SiFiveEState), - .class_init = riscv_sifive_e_class_init, -}; - static void riscv_sifive_e_machine_init(MachineClass *mc) { mc->desc = "RISC-V Board compatible with SiFive E SDK"; @@ -220,10 +202,3 @@ static void riscv_sifive_e_machine_init(MachineClass *mc) } DEFINE_MACHINE("sifive_e", riscv_sifive_e_machine_init) - -static void riscv_sifive_e_register_types(void) -{ - type_register_static(&riscv_sifive_e_device); -} - -type_init(riscv_sifive_e_register_types); diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index adc6c22662..5bb495ab9a 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -301,31 +301,6 @@ static void riscv_sifive_u_init(MachineState *machine) SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE); } -static int riscv_sifive_u_sysbus_device_init(SysBusDevice *sysbusdev) -{ - return 0; -} - -static void riscv_sifive_u_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = riscv_sifive_u_sysbus_device_init; -} - -static const TypeInfo riscv_sifive_u_device = { - .name = TYPE_SIFIVE_U, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(SiFiveUState), - .class_init = riscv_sifive_u_class_init, -}; - -static void riscv_sifive_u_register_types(void) -{ - type_register_static(&riscv_sifive_u_device); -} - -type_init(riscv_sifive_u_register_types); - static void riscv_sifive_u_machine_init(MachineClass *mc) { mc->desc = "RISC-V Board compatible with SiFive U SDK"; diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index cf7f9bcc39..44eab94e17 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -334,18 +334,6 @@ static void spike_v1_09_1_board_init(MachineState *machine) smp_cpus, SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE); } -static const TypeInfo spike_v_1_09_1_device = { - .name = TYPE_RISCV_SPIKE_V1_09_1_BOARD, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(SpikeState), -}; - -static const TypeInfo spike_v_1_10_0_device = { - .name = TYPE_RISCV_SPIKE_V1_10_0_BOARD, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(SpikeState), -}; - static void spike_v1_09_1_machine_init(MachineClass *mc) { mc->desc = "RISC-V Spike Board (Privileged ISA v1.9.1)"; @@ -363,11 +351,3 @@ 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_spike_board_register_types(void) -{ - type_register_static(&spike_v_1_09_1_device); - type_register_static(&spike_v_1_10_0_device); -} - -type_init(riscv_spike_board_register_types); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index c2aa795981..88b9ad5093 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -382,24 +382,6 @@ static void riscv_virt_board_init(MachineState *machine) serial_hd(0), DEVICE_LITTLE_ENDIAN); } -static int riscv_virt_board_sysbus_device_init(SysBusDevice *sysbusdev) -{ - return 0; -} - -static void riscv_virt_board_class_init(ObjectClass *klass, void *data) -{ - SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass); - k->init = riscv_virt_board_sysbus_device_init; -} - -static const TypeInfo riscv_virt_board_device = { - .name = TYPE_RISCV_VIRT_BOARD, - .parent = TYPE_SYS_BUS_DEVICE, - .instance_size = sizeof(RISCVVirtState), - .class_init = riscv_virt_board_class_init, -}; - static void riscv_virt_board_machine_init(MachineClass *mc) { mc->desc = "RISC-V VirtIO Board (Privileged ISA v1.10)"; @@ -408,10 +390,3 @@ static void riscv_virt_board_machine_init(MachineClass *mc) } DEFINE_MACHINE("virt", riscv_virt_board_machine_init) - -static void riscv_virt_board_register_types(void) -{ - type_register_static(&riscv_virt_board_device); -} - -type_init(riscv_virt_board_register_types); diff --git a/include/hw/riscv/sifive_e.h b/include/hw/riscv/sifive_e.h index 0aebc576c1..12ad6d2ebb 100644 --- a/include/hw/riscv/sifive_e.h +++ b/include/hw/riscv/sifive_e.h @@ -19,11 +19,6 @@ #ifndef HW_SIFIVE_E_H #define HW_SIFIVE_E_H -#define TYPE_SIFIVE_E "riscv.sifive_e" - -#define SIFIVE_E(obj) \ - OBJECT_CHECK(SiFiveEState, (obj), TYPE_SIFIVE_E) - typedef struct SiFiveEState { /*< private >*/ SysBusDevice parent_obj; diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h index be38aa09da..94a390566e 100644 --- a/include/hw/riscv/sifive_u.h +++ b/include/hw/riscv/sifive_u.h @@ -19,11 +19,6 @@ #ifndef HW_SIFIVE_U_H #define HW_SIFIVE_U_H -#define TYPE_SIFIVE_U "riscv.sifive_u" - -#define SIFIVE_U(obj) \ - OBJECT_CHECK(SiFiveUState, (obj), TYPE_SIFIVE_U) - typedef struct SiFiveUState { /*< private >*/ SysBusDevice parent_obj; diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h index d85a64e33d..8410430614 100644 --- a/include/hw/riscv/spike.h +++ b/include/hw/riscv/spike.h @@ -19,12 +19,6 @@ #ifndef HW_SPIKE_H #define HW_SPIKE_H -#define TYPE_RISCV_SPIKE_V1_09_1_BOARD "riscv.spike_v1_9_1" -#define TYPE_RISCV_SPIKE_V1_10_0_BOARD "riscv.spike_v1_10" - -#define SPIKE(obj) \ - OBJECT_CHECK(SpikeState, (obj), TYPE_RISCV_SPIKE_BOARD) - typedef struct { /*< private >*/ SysBusDevice parent_obj; @@ -35,7 +29,6 @@ typedef struct { int fdt_size; } SpikeState; - enum { SPIKE_MROM, SPIKE_CLINT, diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 655e85ddbd..b91a4125dd 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -19,10 +19,6 @@ #ifndef HW_VIRT_H #define HW_VIRT_H -#define TYPE_RISCV_VIRT_BOARD "riscv.virt" -#define VIRT(obj) \ - OBJECT_CHECK(RISCVVirtState, (obj), TYPE_RISCV_VIRT_BOARD) - typedef struct { /*< private >*/ SysBusDevice parent_obj; @@ -45,7 +41,6 @@ enum { VIRT_DRAM }; - enum { UART0_IRQ = 10, VIRTIO_IRQ = 1, /* 1 to 8 */ -- cgit v1.2.1 From 6296a799b14142ccb813b678227ae9e6bf0ffa79 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Sun, 4 Mar 2018 13:50:12 +1300 Subject: RISC-V: Include instruction hex in disassembly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was added to help debug issues using -d in_asm. It is useful to see the instruction bytes, as one can detect if one is trying to execute ASCII or device-tree magic. Cc: Sagar Karandikar Cc: Bastian Koppelmann Signed-off-by: Michael Clark Signed-off-by: Palmer Dabbelt Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- disas/riscv.c | 39 ++++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/disas/riscv.c b/disas/riscv.c index 74ad16eacd..2cecf0d855 100644 --- a/disas/riscv.c +++ b/disas/riscv.c @@ -2769,25 +2769,6 @@ static void format_inst(char *buf, size_t buflen, size_t tab, rv_decode *dec) char tmp[64]; const char *fmt; - if (dec->op == rv_op_illegal) { - size_t len = inst_length(dec->inst); - switch (len) { - case 2: - snprintf(buf, buflen, "(0x%04" PRIx64 ")", dec->inst); - break; - case 4: - snprintf(buf, buflen, "(0x%08" PRIx64 ")", dec->inst); - break; - case 6: - snprintf(buf, buflen, "(0x%012" PRIx64 ")", dec->inst); - break; - default: - snprintf(buf, buflen, "(0x%016" PRIx64 ")", dec->inst); - break; - } - return; - } - fmt = opcode_data[dec->op].format; while (*fmt) { switch (*fmt) { @@ -3004,6 +2985,11 @@ disasm_inst(char *buf, size_t buflen, rv_isa isa, uint64_t pc, rv_inst inst) format_inst(buf, buflen, 16, &dec); } +#define INST_FMT_2 "%04" PRIx64 " " +#define INST_FMT_4 "%08" PRIx64 " " +#define INST_FMT_6 "%012" PRIx64 " " +#define INST_FMT_8 "%016" PRIx64 " " + static int print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa) { @@ -3031,6 +3017,21 @@ print_insn_riscv(bfd_vma memaddr, struct disassemble_info *info, rv_isa isa) } } + switch (len) { + case 2: + (*info->fprintf_func)(info->stream, INST_FMT_2, inst); + break; + case 4: + (*info->fprintf_func)(info->stream, INST_FMT_4, inst); + break; + case 6: + (*info->fprintf_func)(info->stream, INST_FMT_6, inst); + break; + default: + (*info->fprintf_func)(info->stream, INST_FMT_8, inst); + break; + } + disasm_inst(buf, sizeof(buf), isa, memaddr, inst); (*info->fprintf_func)(info->stream, "%s", buf); -- cgit v1.2.1 From 1dc34be1c90b2d3006078d9d331e53a849cdecf3 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Mon, 30 Apr 2018 11:06:31 +1200 Subject: RISC-V: Fix missing break statement in disassembler MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes an issue when disassembling rv128 c.sqsp, where the code erroneously fell through to c.swsp. Cc: Palmer Dabbelt Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Alistair Francis Cc: Peter Maydell Signed-off-by: Michael Clark Reviewed-by: Richard Henderson Reviewed-by: Philippe Mathieu-Daudé --- disas/riscv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/disas/riscv.c b/disas/riscv.c index 2cecf0d855..7fd1019623 100644 --- a/disas/riscv.c +++ b/disas/riscv.c @@ -1470,8 +1470,9 @@ static void decode_inst_opcode(rv_decode *dec, rv_isa isa) if (isa == rv128) { op = rv_op_c_sqsp; } else { - op = rv_op_c_fsdsp; break; + op = rv_op_c_fsdsp; } + break; case 6: op = rv_op_c_swsp; break; case 7: if (isa == rv32) { -- cgit v1.2.1 From 4996b128745d93d859b434ff365d4e418bd9095d Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Mon, 5 Mar 2018 19:20:53 +1300 Subject: RISC-V: Make some header guards more specific MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Sagar Karandikar Cc: Bastian Koppelmann Signed-off-by: Michael Clark Signed-off-by: Palmer Dabbelt Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- include/hw/riscv/spike.h | 4 ++-- include/hw/riscv/virt.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/hw/riscv/spike.h b/include/hw/riscv/spike.h index 8410430614..641b70da67 100644 --- a/include/hw/riscv/spike.h +++ b/include/hw/riscv/spike.h @@ -16,8 +16,8 @@ * this program. If not, see . */ -#ifndef HW_SPIKE_H -#define HW_SPIKE_H +#ifndef HW_RISCV_SPIKE_H +#define HW_RISCV_SPIKE_H typedef struct { /*< private >*/ diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index b91a4125dd..3a4f23e8d0 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -16,8 +16,8 @@ * this program. If not, see . */ -#ifndef HW_VIRT_H -#define HW_VIRT_H +#ifndef HW_RISCV_VIRT_H +#define HW_RISCV_VIRT_H typedef struct { /*< private >*/ -- cgit v1.2.1 From 5b5583806b16ca9ddc454e2a5892b1fea575e470 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Mon, 5 Mar 2018 19:24:08 +1300 Subject: RISC-V: Make virt header comment title consistent MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Sagar Karandikar Cc: Bastian Koppelmann Signed-off-by: Michael Clark Signed-off-by: Palmer Dabbelt Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- include/hw/riscv/virt.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h index 3a4f23e8d0..91163d6cbf 100644 --- a/include/hw/riscv/virt.h +++ b/include/hw/riscv/virt.h @@ -1,5 +1,5 @@ /* - * SiFive VirtIO Board + * QEMU RISC-V VirtIO machine interface * * Copyright (c) 2017 SiFive, Inc. * -- cgit v1.2.1 From 89854803ce3efb16fbc94604e652f152f5102569 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Mon, 5 Mar 2018 20:22:30 +1300 Subject: RISC-V: Remove EM_RISCV ELF_MACHINE indirection MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pointless indirection. Other ports use EM_ constants directly. Cc: Sagar Karandikar Cc: Bastian Koppelmann Signed-off-by: Michael Clark Signed-off-by: Palmer Dabbelt Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Alistair Francis --- hw/riscv/sifive_e.c | 2 +- hw/riscv/sifive_u.c | 2 +- hw/riscv/spike.c | 2 +- hw/riscv/virt.c | 2 +- target/riscv/cpu.h | 1 - 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index 22dc526713..6fa2238185 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -88,7 +88,7 @@ static uint64_t load_kernel(const char *kernel_filename) if (load_elf(kernel_filename, NULL, NULL, &kernel_entry, NULL, &kernel_high, - 0, ELF_MACHINE, 1, 0) < 0) { + 0, EM_RISCV, 1, 0) < 0) { error_report("qemu: could not load kernel '%s'", kernel_filename); exit(1); } diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 5bb495ab9a..84afed4c3b 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -74,7 +74,7 @@ static uint64_t load_kernel(const char *kernel_filename) if (load_elf(kernel_filename, NULL, NULL, &kernel_entry, NULL, &kernel_high, - 0, ELF_MACHINE, 1, 0) < 0) { + 0, EM_RISCV, 1, 0) < 0) { error_report("qemu: could not load kernel '%s'", kernel_filename); exit(1); } diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 44eab94e17..9e18c618bf 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -64,7 +64,7 @@ static uint64_t load_kernel(const char *kernel_filename) uint64_t kernel_entry, kernel_high; if (load_elf_ram_sym(kernel_filename, NULL, NULL, - &kernel_entry, NULL, &kernel_high, 0, ELF_MACHINE, 1, 0, + &kernel_entry, NULL, &kernel_high, 0, EM_RISCV, 1, 0, NULL, true, htif_symbol_callback) < 0) { error_report("qemu: could not load kernel '%s'", kernel_filename); exit(1); diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 88b9ad5093..7ef9ba26de 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -68,7 +68,7 @@ static uint64_t load_kernel(const char *kernel_filename) if (load_elf(kernel_filename, NULL, NULL, &kernel_entry, NULL, &kernel_high, - 0, ELF_MACHINE, 1, 0) < 0) { + 0, EM_RISCV, 1, 0) < 0) { error_report("qemu: could not load kernel '%s'", kernel_filename); exit(1); } diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 41e06ac0f9..9871e6feb1 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -34,7 +34,6 @@ #define TCG_GUEST_DEFAULT_MO 0 -#define ELF_MACHINE EM_RISCV #define CPUArchState struct CPURISCVState #include "qemu-common.h" -- cgit v1.2.1 From 8d196c43d7e247edbda7be7b1597ea184f6b498e Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Sat, 17 Mar 2018 21:15:40 -0700 Subject: RISC-V: Remove erroneous comment from translate.c Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark Reviewed-by: Palmer Dabbelt Reviewed-by: Alistair Francis --- target/riscv/translate.c | 1 - 1 file changed, 1 deletion(-) diff --git a/target/riscv/translate.c b/target/riscv/translate.c index 808eab7f50..c3a029afef 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -280,7 +280,6 @@ static void gen_arith(DisasContext *ctx, uint32_t opc, int rd, int rs1, tcg_gen_andi_tl(source2, source2, 0x1F); tcg_gen_sar_tl(source1, source1, source2); break; - /* fall through to SRA */ #endif case OPC_RISC_SRA: tcg_gen_andi_tl(source2, source2, TARGET_LONG_BITS - 1); -- cgit v1.2.1 From 79f86934267135080e13e02b52c74371220d8e06 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Mon, 5 Mar 2018 13:28:00 +1300 Subject: RISC-V: Update E and I extension order Section 22.8 Subset Naming Convention of the RISC-V ISA Specification defines the canonical order for extensions in the ISA string. It is silent on the position of the E extension however E is a substitute for I so it must come early in the extension list order. A comment is added to state E and I are mutually exclusive, as the E extension will be added to the RISC-V port in the future. Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark Reviewed-by: Alistair Francis --- target/riscv/cpu.c | 2 +- target/riscv/cpu.h | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 5a527fbba0..4e5a56d4e3 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -26,7 +26,7 @@ /* RISC-V CPU definitions */ -static const char riscv_exts[26] = "IMAFDQECLBJTPVNSUHKORWXYZG"; +static const char riscv_exts[26] = "IEMAFDQCLBJTPVNSUHKORWXYZG"; const char * const riscv_int_regnames[] = { "zero", "ra ", "sp ", "gp ", "tp ", "t0 ", "t1 ", "t2 ", diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 9871e6feb1..1dcbdbe6f7 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -71,6 +71,7 @@ #define RV(x) ((target_ulong)1 << (x - 'A')) #define RVI RV('I') +#define RVE RV('E') /* E and I are mutually exclusive */ #define RVM RV('M') #define RVA RV('A') #define RVF RV('F') -- cgit v1.2.1 From 33e3bc8d77b6ce95e622bdc0fce622d35b7ee56c Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Tue, 6 Mar 2018 09:48:41 +1300 Subject: RISC-V: Hardwire satp to 0 for no-mmu case satp is WARL so it should not trap on illegal writes, rather it can be hardwired to zero and silently ignore illegal writes. It seems the RISC-V WARL behaviour is preferred to having to trap overhead versus simply reading back the value and checking if the write took (saves hundreds of cycles and more complex trap handling code). Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark Reviewed-by: Alistair Francis --- target/riscv/op_helper.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 7c6068bac9..101dac1ee8 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -255,7 +255,7 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, } case CSR_SATP: /* CSR_SPTBR */ { if (!riscv_feature(env, RISCV_FEATURE_MMU)) { - goto do_illegal; + break; } if (env->priv_ver <= PRIV_VERSION_1_09_1 && (val_to_write ^ env->sptbr)) { @@ -465,7 +465,10 @@ target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno) return env->scounteren; case CSR_SCAUSE: return env->scause; - case CSR_SPTBR: + case CSR_SATP: /* CSR_SPTBR */ + if (!riscv_feature(env, RISCV_FEATURE_MMU)) { + return 0; + } if (env->priv_ver >= PRIV_VERSION_1_10_0) { return env->satp; } else { -- cgit v1.2.1 From 67185dad16284467dba9b6159f9ec9ec53689582 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Fri, 16 Mar 2018 12:12:00 -0700 Subject: RISC-V: Clear mtval/stval on exceptions without info mtval/stval must be set on all exceptions but zero is a legal value if there is no exception specific info. Placing the instruction bytes for illegal instruction exceptions in mtval/stval is an optional feature and is currently not supported by QEMU RISC-V. Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark Reviewed-by: Alistair Francis --- target/riscv/helper.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/target/riscv/helper.c b/target/riscv/helper.c index 02cbcea2b7..95889f23b9 100644 --- a/target/riscv/helper.c +++ b/target/riscv/helper.c @@ -466,6 +466,10 @@ void riscv_cpu_do_interrupt(CPUState *cs) ": badaddr 0x" TARGET_FMT_lx, env->mhartid, env->badaddr); } env->sbadaddr = env->badaddr; + } else { + /* otherwise we must clear sbadaddr/stval + * todo: support populating stval on illegal instructions */ + env->sbadaddr = 0; } target_ulong s = env->mstatus; @@ -487,6 +491,10 @@ void riscv_cpu_do_interrupt(CPUState *cs) ": badaddr 0x" TARGET_FMT_lx, env->mhartid, env->badaddr); } env->mbadaddr = env->badaddr; + } else { + /* otherwise we must clear mbadaddr/mtval + * todo: support populating mtval on illegal instructions */ + env->mbadaddr = 0; } target_ulong s = env->mstatus; -- cgit v1.2.1 From e21659057066f2f4d42fa51a62ff07a23a632e40 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Mon, 9 Apr 2018 12:06:30 +1200 Subject: RISC-V: Allow S-mode mxr access when priv ISA >= v1.10 The mstatus.MXR alias in sstatus should only be writable by S-mode if the privileged ISA version >= v1.10. Also MXR was masked in sstatus CSR read but not sstatus CSR writes. Now we correctly mask sstatus.mxr in both read and write. Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark Reviewed-by: Alistair Francis --- target/riscv/op_helper.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 101dac1ee8..f45ac7306c 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -234,7 +234,10 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, target_ulong ms = env->mstatus; target_ulong mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS - | SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD; + | SSTATUS_SUM | SSTATUS_SD; + if (env->priv_ver >= PRIV_VERSION_1_10_0) { + mask |= SSTATUS_MXR; + } ms = (ms & ~mask) | (val_to_write & mask); csr_write_helper(env, ms, CSR_MSTATUS); break; @@ -441,7 +444,7 @@ target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno) case CSR_SSTATUS: { target_ulong mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS - | SSTATUS_SUM | SSTATUS_SD; + | SSTATUS_SUM | SSTATUS_SD; if (env->priv_ver >= PRIV_VERSION_1_10_0) { mask |= SSTATUS_MXR; } -- cgit v1.2.1 From 8c59f5c1b5aabbad92871bf62bb302fef017e322 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Mon, 9 Apr 2018 11:33:05 +1200 Subject: RISC-V: Use [ms]counteren CSRs when priv ISA >= v1.10 Privileged ISA v1.9.1 defines mscounteren and mucounteren: * mscounteren contains a mask of counters available to S-mode * mucounteren contains a mask of counters available to U-mode Privileged ISA v1.10 defines mcounteren and scounteren: * mcounteren contains a mask of counters available to S-mode * scounteren contains a mask of counters available to U-mode mcounteren and scounteren CSR registers were implemented however they were not honoured for counter accesses when the privilege ISA was >= v1.10. This fix solves the issue by coalescing the counter enable registers. In addition the code now generates illegal instruction exceptions for accesses to the counter enabled registers depending on the privileged ISA version. - Coalesce mscounteren and mcounteren into one variable - Coalesce mucounteren and scounteren into one variable - Makes mcounteren and scounteren CSR accesses generate illegal instructions when the privileged ISA <= v1.9.1 - Makes mscounteren and mucounteren CSR accesses generate illegal instructions when the privileged ISA >= v1.10 Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark --- target/riscv/cpu.h | 6 ++--- target/riscv/op_helper.c | 62 +++++++++++++++++++++++++++++++++++++----------- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 1dcbdbe6f7..34abc383e3 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -151,10 +151,8 @@ struct CPURISCVState { target_ulong mcause; target_ulong mtval; /* since: priv-1.10.0 */ - uint32_t mucounteren; - uint32_t mscounteren; - target_ulong scounteren; /* since: priv-1.10.0 */ - target_ulong mcounteren; /* since: priv-1.10.0 */ + target_ulong scounteren; + target_ulong mcounteren; target_ulong sscratch; target_ulong mscratch; diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index f45ac7306c..7416412b18 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -225,11 +225,19 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, qemu_log_mask(LOG_UNIMP, "CSR_MCYCLEH: write not implemented"); goto do_illegal; case CSR_MUCOUNTEREN: - env->mucounteren = val_to_write; - break; + if (env->priv_ver <= PRIV_VERSION_1_09_1) { + env->scounteren = val_to_write; + break; + } else { + goto do_illegal; + } case CSR_MSCOUNTEREN: - env->mscounteren = val_to_write; - break; + if (env->priv_ver <= PRIV_VERSION_1_09_1) { + env->mcounteren = val_to_write; + break; + } else { + goto do_illegal; + } case CSR_SSTATUS: { target_ulong ms = env->mstatus; target_ulong mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE @@ -286,8 +294,12 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, env->stvec = val_to_write >> 2 << 2; break; case CSR_SCOUNTEREN: - env->scounteren = val_to_write; - break; + if (env->priv_ver >= PRIV_VERSION_1_10_0) { + env->scounteren = val_to_write; + break; + } else { + goto do_illegal; + } case CSR_SSCRATCH: env->sscratch = val_to_write; break; @@ -308,8 +320,12 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, env->mtvec = val_to_write >> 2 << 2; break; case CSR_MCOUNTEREN: - env->mcounteren = val_to_write; - break; + if (env->priv_ver >= PRIV_VERSION_1_10_0) { + env->mcounteren = val_to_write; + break; + } else { + goto do_illegal; + } case CSR_MSCRATCH: env->mscratch = val_to_write; break; @@ -347,6 +363,8 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, case CSR_PMPADDR15: pmpaddr_csr_write(env, csrno - CSR_PMPADDR0, val_to_write); break; +#endif +#if !defined(CONFIG_USER_ONLY) do_illegal: #endif default: @@ -362,8 +380,8 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno) { #ifndef CONFIG_USER_ONLY - target_ulong ctr_en = env->priv == PRV_U ? env->mucounteren : - env->priv == PRV_S ? env->mscounteren : -1U; + target_ulong ctr_en = env->priv == PRV_U ? env->scounteren : + env->priv == PRV_S ? env->mcounteren : -1U; #else target_ulong ctr_en = -1; #endif @@ -438,9 +456,17 @@ target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno) #endif break; case CSR_MUCOUNTEREN: - return env->mucounteren; + if (env->priv_ver <= PRIV_VERSION_1_09_1) { + return env->scounteren; + } else { + break; /* illegal instruction */ + } case CSR_MSCOUNTEREN: - return env->mscounteren; + if (env->priv_ver <= PRIV_VERSION_1_09_1) { + return env->mcounteren; + } else { + break; /* illegal instruction */ + } case CSR_SSTATUS: { target_ulong mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS @@ -465,7 +491,11 @@ target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno) case CSR_STVEC: return env->stvec; case CSR_SCOUNTEREN: - return env->scounteren; + if (env->priv_ver >= PRIV_VERSION_1_10_0) { + return env->scounteren; + } else { + break; /* illegal instruction */ + } case CSR_SCAUSE: return env->scause; case CSR_SATP: /* CSR_SPTBR */ @@ -510,7 +540,11 @@ target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno) case CSR_MTVEC: return env->mtvec; case CSR_MCOUNTEREN: - return env->mcounteren; + if (env->priv_ver >= PRIV_VERSION_1_10_0) { + return env->mcounteren; + } else { + break; /* illegal instruction */ + } case CSR_MEDELEG: return env->medeleg; case CSR_MIDELEG: -- cgit v1.2.1 From 6fce529c4b3ecbff17bbd930f6beaac9a6067114 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Fri, 6 Apr 2018 12:46:19 +1200 Subject: RISC-V: Add mcycle/minstret support for -icount auto Previously the mycycle/minstret CSRs and rdcycle/rdinstret psuedo instructions would return the time as a proxy for an increasing instruction counter in the absence of having a precise instruction count. If QEMU is invoked with -icount, the mcycle/minstret CSRs and rdcycle/rdinstret psuedo instructions will return the instruction count. Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark Reviewed-by: Alistair Francis --- target/riscv/op_helper.c | 28 ++++++++++++++++++++++++++-- target/riscv/translate.c | 2 ++ 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 7416412b18..3512462f4f 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -434,25 +434,49 @@ target_ulong csr_read_helper(CPURISCVState *env, target_ulong csrno) case CSR_INSTRET: case CSR_CYCLE: if (ctr_ok) { +#if !defined(CONFIG_USER_ONLY) + if (use_icount) { + return cpu_get_icount(); + } else { + return cpu_get_host_ticks(); + } +#else return cpu_get_host_ticks(); +#endif } break; #if defined(TARGET_RISCV32) case CSR_INSTRETH: case CSR_CYCLEH: if (ctr_ok) { +#if !defined(CONFIG_USER_ONLY) + if (use_icount) { + return cpu_get_icount() >> 32; + } else { + return cpu_get_host_ticks() >> 32; + } +#else return cpu_get_host_ticks() >> 32; +#endif } break; #endif #ifndef CONFIG_USER_ONLY case CSR_MINSTRET: case CSR_MCYCLE: - return cpu_get_host_ticks(); + if (use_icount) { + return cpu_get_icount(); + } else { + return cpu_get_host_ticks(); + } case CSR_MINSTRETH: case CSR_MCYCLEH: #if defined(TARGET_RISCV32) - return cpu_get_host_ticks() >> 32; + if (use_icount) { + return cpu_get_icount() >> 32; + } else { + return cpu_get_host_ticks() >> 32; + } #endif break; case CSR_MUCOUNTEREN: diff --git a/target/riscv/translate.c b/target/riscv/translate.c index c3a029afef..c0e6a044d3 100644 --- a/target/riscv/translate.c +++ b/target/riscv/translate.c @@ -1390,6 +1390,7 @@ static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc, break; default: tcg_gen_movi_tl(imm_rs1, rs1); + gen_io_start(); switch (opc) { case OPC_RISC_CSRRW: gen_helper_csrrw(dest, cpu_env, source1, csr_store); @@ -1413,6 +1414,7 @@ static void gen_system(CPURISCVState *env, DisasContext *ctx, uint32_t opc, gen_exception_illegal(ctx); return; } + gen_io_end(); gen_set_gpr(rd, dest); /* end tb since we may be changing priv modes, to get mmu_index right */ tcg_gen_movi_tl(cpu_pc, ctx->next_pc); -- cgit v1.2.1 From 1d1ee55274860bfcc511d50d83c84394c2685ba8 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Tue, 6 Mar 2018 10:17:11 +1300 Subject: RISC-V: Make mtvec/stvec ignore vectored traps Vectored traps for asynchrounous interrupts are optional. The mtvec/stvec mode field is WARL and hence does not trap if an illegal value is written. Illegal values are ignored. Later we can add RISCV_FEATURE_VECTORED_TRAPS however until then the correct behavior for WARL (Write Any, Read Legal) fields is to drop writes to unsupported bits. Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark --- target/riscv/op_helper.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index 3512462f4f..af0c52a484 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -287,11 +287,12 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, env->sepc = val_to_write; break; case CSR_STVEC: - if (val_to_write & 1) { + /* bits [1:0] encode mode; 0 = direct, 1 = vectored, 2 >= reserved */ + if ((val_to_write & 3) == 0) { + env->stvec = val_to_write >> 2 << 2; + } else { qemu_log_mask(LOG_UNIMP, "CSR_STVEC: vectored traps not supported"); - goto do_illegal; } - env->stvec = val_to_write >> 2 << 2; break; case CSR_SCOUNTEREN: if (env->priv_ver >= PRIV_VERSION_1_10_0) { @@ -313,11 +314,12 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, env->mepc = val_to_write; break; case CSR_MTVEC: - if (val_to_write & 1) { + /* bits [1:0] indicate mode; 0 = direct, 1 = vectored, 2 >= reserved */ + if ((val_to_write & 3) == 0) { + env->mtvec = val_to_write >> 2 << 2; + } else { qemu_log_mask(LOG_UNIMP, "CSR_MTVEC: vectored traps not supported"); - goto do_illegal; } - env->mtvec = val_to_write >> 2 << 2; break; case CSR_MCOUNTEREN: if (env->priv_ver >= PRIV_VERSION_1_10_0) { -- cgit v1.2.1 From b8643bd6084be1787a6dc8768a7a1983921fc945 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Tue, 6 Mar 2018 10:33:31 +1300 Subject: RISC-V: No traps on writes to misa,minstret,mcycle These fields are marked WARL (Write Any Values, Reads Legal Values) in the RISC-V Privileged Architecture Specification so instead of raising exceptions, illegal writes are silently dropped. Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark --- target/riscv/op_helper.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c index af0c52a484..3abf52453c 100644 --- a/target/riscv/op_helper.c +++ b/target/riscv/op_helper.c @@ -213,17 +213,19 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, break; } case CSR_MINSTRET: - qemu_log_mask(LOG_UNIMP, "CSR_MINSTRET: write not implemented"); - goto do_illegal; + /* minstret is WARL so unsupported writes are ignored */ + break; case CSR_MCYCLE: - qemu_log_mask(LOG_UNIMP, "CSR_MCYCLE: write not implemented"); - goto do_illegal; + /* mcycle is WARL so unsupported writes are ignored */ + break; +#if defined(TARGET_RISCV32) case CSR_MINSTRETH: - qemu_log_mask(LOG_UNIMP, "CSR_MINSTRETH: write not implemented"); - goto do_illegal; + /* minstreth is WARL so unsupported writes are ignored */ + break; case CSR_MCYCLEH: - qemu_log_mask(LOG_UNIMP, "CSR_MCYCLEH: write not implemented"); - goto do_illegal; + /* mcycleh is WARL so unsupported writes are ignored */ + break; +#endif case CSR_MUCOUNTEREN: if (env->priv_ver <= PRIV_VERSION_1_09_1) { env->scounteren = val_to_write; @@ -337,10 +339,9 @@ void csr_write_helper(CPURISCVState *env, target_ulong val_to_write, case CSR_MBADADDR: env->mbadaddr = val_to_write; break; - case CSR_MISA: { - qemu_log_mask(LOG_UNIMP, "CSR_MISA: misa writes not supported"); - goto do_illegal; - } + case CSR_MISA: + /* misa is WARL so unsupported writes are ignored */ + break; case CSR_PMPCFG0: case CSR_PMPCFG1: case CSR_PMPCFG2: -- cgit v1.2.1 From 5aec3247c190f10654250203a1742490ae7343a2 Mon Sep 17 00:00:00 2001 From: Michael Clark Date: Sun, 4 Mar 2018 11:52:13 +1300 Subject: RISC-V: Mark ROM read-only after copying in code The sifive_u machine already marks its ROM readonly however it has the wrong base address for its mask ROM. This patch fixes the sifive_u mask ROM base address. This commit makes all other boards consistently use mask_rom as the variable name for their ROMs. Boards that use device tree now check that that the device tree fits in the assigned ROM space using the new qemu_fdt_totalsize(void *fdt) interface, adding a bounds check and error message. This can detect truncation. Cc: Sagar Karandikar Cc: Bastian Koppelmann Cc: Palmer Dabbelt Cc: Alistair Francis Signed-off-by: Michael Clark Reviewed-by: Alistair Francis --- hw/riscv/sifive_e.c | 20 +++++++--------- hw/riscv/sifive_u.c | 51 +++++++++++++++++++++------------------ hw/riscv/spike.c | 69 +++++++++++++++++++++++++++++++---------------------- hw/riscv/virt.c | 43 ++++++++++++++++++--------------- 4 files changed, 101 insertions(+), 82 deletions(-) diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index 6fa2238185..e4ecb7aa4b 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -74,14 +74,6 @@ static const struct MemmapEntry { [SIFIVE_E_DTIM] = { 0x80000000, 0x4000 } }; -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) -{ - int i; - for (i = 0; i < (len >> 2); i++) { - stl_phys(&address_space_memory, pa + (i << 2), rom[i]); - } -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; @@ -112,6 +104,7 @@ static void riscv_sifive_e_init(MachineState *machine) MemoryRegion *main_mem = g_new(MemoryRegion, 1); MemoryRegion *mask_rom = g_new(MemoryRegion, 1); MemoryRegion *xip_mem = g_new(MemoryRegion, 1); + int i; /* Initialize SOC */ object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY); @@ -131,7 +124,7 @@ static void riscv_sifive_e_init(MachineState *machine) memmap[SIFIVE_E_DTIM].base, main_mem); /* Mask ROM */ - memory_region_init_ram(mask_rom, NULL, "riscv.sifive.e.mrom", + memory_region_init_rom(mask_rom, NULL, "riscv.sifive.e.mrom", memmap[SIFIVE_E_MROM].size, &error_fatal); memory_region_add_subregion(sys_mem, memmap[SIFIVE_E_MROM].base, mask_rom); @@ -185,9 +178,12 @@ static void riscv_sifive_e_init(MachineState *machine) 0x00028067, /* 0x1004: jr t0 */ }; - /* copy in the reset vector */ - copy_le32_to_phys(memmap[SIFIVE_E_MROM].base, reset_vec, sizeof(reset_vec)); - memory_region_set_readonly(mask_rom, true); + /* copy in the reset vector in little_endian byte order */ + for (i = 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] = cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[SIFIVE_E_MROM].base, &address_space_memory); if (machine->kernel_filename) { load_kernel(machine->kernel_filename); diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 84afed4c3b..c05dcbba95 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -47,12 +47,14 @@ #include "exec/address-spaces.h" #include "elf.h" +#include + static const struct MemmapEntry { hwaddr base; hwaddr size; } sifive_u_memmap[] = { [SIFIVE_U_DEBUG] = { 0x0, 0x100 }, - [SIFIVE_U_MROM] = { 0x1000, 0x2000 }, + [SIFIVE_U_MROM] = { 0x1000, 0x11000 }, [SIFIVE_U_CLINT] = { 0x2000000, 0x10000 }, [SIFIVE_U_PLIC] = { 0xc000000, 0x4000000 }, [SIFIVE_U_UART0] = { 0x10013000, 0x1000 }, @@ -60,14 +62,6 @@ static const struct MemmapEntry { [SIFIVE_U_DRAM] = { 0x80000000, 0x0 }, }; -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) -{ - int i; - for (i = 0; i < (len >> 2); i++) { - stl_phys(&address_space_memory, pa + (i << 2), rom[i]); - } -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; @@ -221,9 +215,10 @@ static void riscv_sifive_u_init(MachineState *machine) const struct MemmapEntry *memmap = sifive_u_memmap; SiFiveUState *s = g_new0(SiFiveUState, 1); - MemoryRegion *sys_memory = get_system_memory(); + MemoryRegion *system_memory = get_system_memory(); MemoryRegion *main_mem = g_new(MemoryRegion, 1); - MemoryRegion *boot_rom = g_new(MemoryRegion, 1); + MemoryRegion *mask_rom = g_new(MemoryRegion, 1); + int i; /* Initialize SOC */ object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY); @@ -239,17 +234,17 @@ static void riscv_sifive_u_init(MachineState *machine) /* register RAM */ memory_region_init_ram(main_mem, NULL, "riscv.sifive.u.ram", machine->ram_size, &error_fatal); - memory_region_add_subregion(sys_memory, memmap[SIFIVE_U_DRAM].base, + memory_region_add_subregion(system_memory, memmap[SIFIVE_U_DRAM].base, main_mem); /* create device tree */ create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline); /* boot rom */ - memory_region_init_ram(boot_rom, NULL, "riscv.sifive.u.mrom", - memmap[SIFIVE_U_MROM].base, &error_fatal); - memory_region_set_readonly(boot_rom, true); - memory_region_add_subregion(sys_memory, 0x0, boot_rom); + memory_region_init_rom(mask_rom, NULL, "riscv.sifive.u.mrom", + memmap[SIFIVE_U_MROM].size, &error_fatal); + memory_region_add_subregion(system_memory, memmap[SIFIVE_U_MROM].base, + mask_rom); if (machine->kernel_filename) { load_kernel(machine->kernel_filename); @@ -272,13 +267,23 @@ static void riscv_sifive_u_init(MachineState *machine) /* dtb: */ }; - /* copy in the reset vector */ - copy_le32_to_phys(memmap[SIFIVE_U_MROM].base, reset_vec, sizeof(reset_vec)); + /* copy in the reset vector in little_endian byte order */ + for (i = 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] = cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[SIFIVE_U_MROM].base, &address_space_memory); /* copy in the device tree */ - qemu_fdt_dumpdtb(s->fdt, s->fdt_size); - cpu_physical_memory_write(memmap[SIFIVE_U_MROM].base + - sizeof(reset_vec), s->fdt, s->fdt_size); + if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > + memmap[SIFIVE_U_MROM].size - sizeof(reset_vec)) { + error_report("not enough space to store device-tree"); + exit(1); + } + qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); + rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), + memmap[SIFIVE_U_MROM].base + sizeof(reset_vec), + &address_space_memory); /* MMIO */ s->plic = sifive_plic_create(memmap[SIFIVE_U_PLIC].base, @@ -292,9 +297,9 @@ static void riscv_sifive_u_init(MachineState *machine) SIFIVE_U_PLIC_CONTEXT_BASE, SIFIVE_U_PLIC_CONTEXT_STRIDE, memmap[SIFIVE_U_PLIC].size); - sifive_uart_create(sys_memory, memmap[SIFIVE_U_UART0].base, + sifive_uart_create(system_memory, memmap[SIFIVE_U_UART0].base, serial_hd(0), SIFIVE_PLIC(s->plic)->irqs[SIFIVE_U_UART0_IRQ]); - /* sifive_uart_create(sys_memory, memmap[SIFIVE_U_UART1].base, + /* sifive_uart_create(system_memory, memmap[SIFIVE_U_UART1].base, serial_hd(1), SIFIVE_PLIC(s->plic)->irqs[SIFIVE_U_UART1_IRQ]); */ sifive_clint_create(memmap[SIFIVE_U_CLINT].base, memmap[SIFIVE_U_CLINT].size, smp_cpus, diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 9e18c618bf..f94e2b6707 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -42,23 +42,17 @@ #include "exec/address-spaces.h" #include "elf.h" +#include + static const struct MemmapEntry { hwaddr base; hwaddr size; } spike_memmap[] = { - [SPIKE_MROM] = { 0x1000, 0x2000 }, + [SPIKE_MROM] = { 0x1000, 0x11000 }, [SPIKE_CLINT] = { 0x2000000, 0x10000 }, [SPIKE_DRAM] = { 0x80000000, 0x0 }, }; -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) -{ - int i; - for (i = 0; i < (len >> 2); i++) { - stl_phys(&address_space_memory, pa + (i << 2), rom[i]); - } -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; @@ -173,7 +167,8 @@ static void spike_v1_10_0_board_init(MachineState *machine) SpikeState *s = g_new0(SpikeState, 1); MemoryRegion *system_memory = get_system_memory(); MemoryRegion *main_mem = g_new(MemoryRegion, 1); - MemoryRegion *boot_rom = g_new(MemoryRegion, 1); + MemoryRegion *mask_rom = g_new(MemoryRegion, 1); + int i; /* Initialize SOC */ object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY); @@ -196,9 +191,10 @@ static void spike_v1_10_0_board_init(MachineState *machine) create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline); /* boot rom */ - memory_region_init_ram(boot_rom, NULL, "riscv.spike.bootrom", - s->fdt_size + 0x2000, &error_fatal); - memory_region_add_subregion(system_memory, 0x0, boot_rom); + memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom", + memmap[SPIKE_MROM].size, &error_fatal); + memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base, + mask_rom); if (machine->kernel_filename) { load_kernel(machine->kernel_filename); @@ -221,16 +217,26 @@ static void spike_v1_10_0_board_init(MachineState *machine) /* dtb: */ }; - /* copy in the reset vector */ - copy_le32_to_phys(memmap[SPIKE_MROM].base, reset_vec, sizeof(reset_vec)); + /* copy in the reset vector in little_endian byte order */ + for (i = 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] = cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[SPIKE_MROM].base, &address_space_memory); /* copy in the device tree */ - qemu_fdt_dumpdtb(s->fdt, s->fdt_size); - cpu_physical_memory_write(memmap[SPIKE_MROM].base + sizeof(reset_vec), - s->fdt, s->fdt_size); + if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > + memmap[SPIKE_MROM].size - sizeof(reset_vec)) { + error_report("not enough space to store device-tree"); + exit(1); + } + qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); + rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), + memmap[SPIKE_MROM].base + sizeof(reset_vec), + &address_space_memory); /* initialize HTIF using symbols found in load_kernel */ - htif_mm_init(system_memory, boot_rom, &s->soc.harts[0].env, serial_hd(0)); + htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(0)); /* Core Local Interruptor (timer and IPI) */ sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size, @@ -244,7 +250,8 @@ static void spike_v1_09_1_board_init(MachineState *machine) SpikeState *s = g_new0(SpikeState, 1); MemoryRegion *system_memory = get_system_memory(); MemoryRegion *main_mem = g_new(MemoryRegion, 1); - MemoryRegion *boot_rom = g_new(MemoryRegion, 1); + MemoryRegion *mask_rom = g_new(MemoryRegion, 1); + int i; /* Initialize SOC */ object_initialize(&s->soc, sizeof(s->soc), TYPE_RISCV_HART_ARRAY); @@ -264,9 +271,10 @@ static void spike_v1_09_1_board_init(MachineState *machine) main_mem); /* boot rom */ - memory_region_init_ram(boot_rom, NULL, "riscv.spike.bootrom", - 0x40000, &error_fatal); - memory_region_add_subregion(system_memory, 0x0, boot_rom); + memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom", + memmap[SPIKE_MROM].size, &error_fatal); + memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base, + mask_rom); if (machine->kernel_filename) { load_kernel(machine->kernel_filename); @@ -319,15 +327,20 @@ static void spike_v1_09_1_board_init(MachineState *machine) g_free(isa); size_t config_string_len = strlen(config_string); - /* copy in the reset vector */ - copy_le32_to_phys(memmap[SPIKE_MROM].base, reset_vec, sizeof(reset_vec)); + /* copy in the reset vector in little_endian byte order */ + for (i = 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] = cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[SPIKE_MROM].base, &address_space_memory); /* copy in the config string */ - cpu_physical_memory_write(memmap[SPIKE_MROM].base + sizeof(reset_vec), - config_string, config_string_len); + rom_add_blob_fixed_as("mrom.reset", config_string, config_string_len, + memmap[SPIKE_MROM].base + sizeof(reset_vec), + &address_space_memory); /* initialize HTIF using symbols found in load_kernel */ - htif_mm_init(system_memory, boot_rom, &s->soc.harts[0].env, serial_hd(0)); + htif_mm_init(system_memory, mask_rom, &s->soc.harts[0].env, serial_hd(0)); /* Core Local Interruptor (timer and IPI) */ sifive_clint_create(memmap[SPIKE_CLINT].base, memmap[SPIKE_CLINT].size, diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 7ef9ba26de..ad03113e0f 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -40,13 +40,15 @@ #include "exec/address-spaces.h" #include "elf.h" +#include + static const struct MemmapEntry { hwaddr base; hwaddr size; } virt_memmap[] = { [VIRT_DEBUG] = { 0x0, 0x100 }, - [VIRT_MROM] = { 0x1000, 0x2000 }, - [VIRT_TEST] = { 0x4000, 0x1000 }, + [VIRT_MROM] = { 0x1000, 0x11000 }, + [VIRT_TEST] = { 0x100000, 0x1000 }, [VIRT_CLINT] = { 0x2000000, 0x10000 }, [VIRT_PLIC] = { 0xc000000, 0x4000000 }, [VIRT_UART0] = { 0x10000000, 0x100 }, @@ -54,14 +56,6 @@ static const struct MemmapEntry { [VIRT_DRAM] = { 0x80000000, 0x0 }, }; -static void copy_le32_to_phys(hwaddr pa, uint32_t *rom, size_t len) -{ - int i; - for (i = 0; i < (len >> 2); i++) { - stl_phys(&address_space_memory, pa + (i << 2), rom[i]); - } -} - static uint64_t load_kernel(const char *kernel_filename) { uint64_t kernel_entry, kernel_high; @@ -272,7 +266,7 @@ static void riscv_virt_board_init(MachineState *machine) RISCVVirtState *s = g_new0(RISCVVirtState, 1); MemoryRegion *system_memory = get_system_memory(); MemoryRegion *main_mem = g_new(MemoryRegion, 1); - MemoryRegion *boot_rom = g_new(MemoryRegion, 1); + MemoryRegion *mask_rom = g_new(MemoryRegion, 1); char *plic_hart_config; size_t plic_hart_config_len; int i; @@ -299,9 +293,10 @@ static void riscv_virt_board_init(MachineState *machine) fdt = create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline); /* boot rom */ - memory_region_init_ram(boot_rom, NULL, "riscv_virt_board.bootrom", - s->fdt_size + 0x2000, &error_fatal); - memory_region_add_subregion(system_memory, 0x0, boot_rom); + memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom", + memmap[VIRT_MROM].size, &error_fatal); + memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base, + mask_rom); if (machine->kernel_filename) { uint64_t kernel_entry = load_kernel(machine->kernel_filename); @@ -335,13 +330,23 @@ static void riscv_virt_board_init(MachineState *machine) /* dtb: */ }; - /* copy in the reset vector */ - copy_le32_to_phys(memmap[VIRT_MROM].base, reset_vec, sizeof(reset_vec)); + /* copy in the reset vector in little_endian byte order */ + for (i = 0; i < sizeof(reset_vec) >> 2; i++) { + reset_vec[i] = cpu_to_le32(reset_vec[i]); + } + rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec), + memmap[VIRT_MROM].base, &address_space_memory); /* copy in the device tree */ - qemu_fdt_dumpdtb(s->fdt, s->fdt_size); - cpu_physical_memory_write(memmap[VIRT_MROM].base + sizeof(reset_vec), - s->fdt, s->fdt_size); + if (fdt_pack(s->fdt) || fdt_totalsize(s->fdt) > + memmap[VIRT_MROM].size - sizeof(reset_vec)) { + error_report("not enough space to store device-tree"); + exit(1); + } + qemu_fdt_dumpdtb(s->fdt, fdt_totalsize(s->fdt)); + rom_add_blob_fixed_as("mrom.fdt", s->fdt, fdt_totalsize(s->fdt), + memmap[VIRT_MROM].base + sizeof(reset_vec), + &address_space_memory); /* create PLIC hart topology configuration string */ plic_hart_config_len = (strlen(VIRT_PLIC_HART_CONFIG) + 1) * smp_cpus; -- cgit v1.2.1