diff options
-rw-r--r-- | hw/riscv/boot.c | 13 | ||||
-rw-r--r-- | hw/riscv/sifive_e.c | 5 | ||||
-rw-r--r-- | hw/riscv/sifive_u.c | 142 | ||||
-rw-r--r-- | hw/riscv/spike.c | 30 | ||||
-rw-r--r-- | hw/riscv/virt.c | 6 | ||||
-rw-r--r-- | include/hw/riscv/boot.h | 6 | ||||
-rw-r--r-- | include/hw/riscv/sifive_u.h | 3 | ||||
-rw-r--r-- | linux-user/riscv/signal.c | 3 | ||||
-rw-r--r-- | pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin | bin | 49472 -> 49520 bytes | |||
-rw-r--r-- | pc-bios/opensbi-riscv32-virt-fw_jump.bin | bin | 41280 -> 49504 bytes | |||
-rw-r--r-- | pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin | bin | 53760 -> 57936 bytes | |||
-rw-r--r-- | pc-bios/opensbi-riscv64-virt-fw_jump.bin | bin | 49664 -> 57920 bytes | |||
m--------- | roms/opensbi | 0 | ||||
-rw-r--r-- | target/riscv/cpu.c | 10 | ||||
-rw-r--r-- | target/riscv/cpu.h | 1 | ||||
-rw-r--r-- | target/riscv/cpu_helper.c | 18 |
16 files changed, 158 insertions, 79 deletions
diff --git a/hw/riscv/boot.c b/hw/riscv/boot.c index b8e765277d..726300a171 100644 --- a/hw/riscv/boot.c +++ b/hw/riscv/boot.c @@ -36,7 +36,8 @@ void riscv_find_and_load_firmware(MachineState *machine, const char *default_machine_firmware, - hwaddr firmware_load_addr) + hwaddr firmware_load_addr, + symbol_fn_t sym_cb) { char *firmware_filename = NULL; @@ -76,7 +77,7 @@ void riscv_find_and_load_firmware(MachineState *machine, if (firmware_filename) { /* If not "none" load the firmware */ - riscv_load_firmware(firmware_filename, firmware_load_addr); + riscv_load_firmware(firmware_filename, firmware_load_addr, sym_cb); g_free(firmware_filename); } } @@ -96,12 +97,14 @@ char *riscv_find_firmware(const char *firmware_filename) } target_ulong riscv_load_firmware(const char *firmware_filename, - hwaddr firmware_load_addr) + hwaddr firmware_load_addr, + symbol_fn_t sym_cb) { uint64_t firmware_entry, firmware_start, firmware_end; - if (load_elf(firmware_filename, NULL, NULL, NULL, &firmware_entry, - &firmware_start, &firmware_end, NULL, 0, EM_RISCV, 1, 0) > 0) { + if (load_elf_ram_sym(firmware_filename, NULL, NULL, NULL, + &firmware_entry, &firmware_start, &firmware_end, NULL, + 0, EM_RISCV, 1, 0, NULL, true, sym_cb) > 0) { return firmware_entry; } diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c index 646553a7c3..b53109521e 100644 --- a/hw/riscv/sifive_e.c +++ b/hw/riscv/sifive_e.c @@ -123,8 +123,6 @@ static void riscv_sifive_e_soc_init(Object *obj) object_initialize_child(obj, "cpus", &s->cpus, sizeof(s->cpus), TYPE_RISCV_HART_ARRAY, &error_abort, NULL); - object_property_set_str(OBJECT(&s->cpus), SIFIVE_E_CPU, "cpu-type", - &error_abort); object_property_set_int(OBJECT(&s->cpus), ms->smp.cpus, "num-harts", &error_abort); sysbus_init_child_obj(obj, "riscv.sifive.e.gpio0", @@ -141,6 +139,8 @@ static void riscv_sifive_e_soc_realize(DeviceState *dev, Error **errp) SiFiveESoCState *s = RISCV_E_SOC(dev); MemoryRegion *sys_mem = get_system_memory(); + object_property_set_str(OBJECT(&s->cpus), ms->cpu_type, "cpu-type", + &error_abort); object_property_set_bool(OBJECT(&s->cpus), true, "realized", &error_abort); @@ -219,6 +219,7 @@ static void riscv_sifive_e_machine_init(MachineClass *mc) mc->desc = "RISC-V Board compatible with SiFive E SDK"; mc->init = riscv_sifive_e_init; mc->max_cpus = 1; + mc->default_cpu_type = SIFIVE_E_CPU; } DEFINE_MACHINE("sifive_e", riscv_sifive_e_machine_init) diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c index 998666c91f..bed10fcfa8 100644 --- a/hw/riscv/sifive_u.c +++ b/hw/riscv/sifive_u.c @@ -34,6 +34,7 @@ #include "qemu/log.h" #include "qemu/error-report.h" #include "qapi/error.h" +#include "qapi/visitor.h" #include "hw/boards.h" #include "hw/loader.h" #include "hw/sysbus.h" @@ -159,7 +160,11 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap, qemu_fdt_add_subnode(fdt, nodename); /* cpu 0 is the management hart that does not have mmu */ if (cpu != 0) { +#if defined(TARGET_RISCV32) + qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32"); +#else qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48"); +#endif isa = riscv_isa_string(&s->soc.u_cpus.harts[cpu - 1]); } else { isa = riscv_isa_string(&s->soc.e_cpus.harts[0]); @@ -312,7 +317,7 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap, g_free(nodename); } -static void riscv_sifive_u_init(MachineState *machine) +static void sifive_u_machine_init(MachineState *machine) { const struct MemmapEntry *memmap = sifive_u_memmap; SiFiveUState *s = RISCV_U_MACHINE(machine); @@ -326,6 +331,8 @@ static void riscv_sifive_u_init(MachineState *machine) object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc), TYPE_RISCV_U_SOC, &error_abort, NULL); + object_property_set_uint(OBJECT(&s->soc), s->serial, "serial", + &error_abort); object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_abort); @@ -345,7 +352,7 @@ static void riscv_sifive_u_init(MachineState *machine) create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline); riscv_find_and_load_firmware(machine, BIOS_FILENAME, - memmap[SIFIVE_U_DRAM].base); + memmap[SIFIVE_U_DRAM].base, NULL); if (machine->kernel_filename) { uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename, @@ -403,6 +410,76 @@ static void riscv_sifive_u_init(MachineState *machine) &address_space_memory); } +static bool sifive_u_machine_get_start_in_flash(Object *obj, Error **errp) +{ + SiFiveUState *s = RISCV_U_MACHINE(obj); + + return s->start_in_flash; +} + +static void sifive_u_machine_set_start_in_flash(Object *obj, bool value, Error **errp) +{ + SiFiveUState *s = RISCV_U_MACHINE(obj); + + s->start_in_flash = value; +} + +static void sifive_u_machine_get_serial(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + visit_type_uint32(v, name, (uint32_t *)opaque, errp); +} + +static void sifive_u_machine_set_serial(Object *obj, Visitor *v, const char *name, + void *opaque, Error **errp) +{ + visit_type_uint32(v, name, (uint32_t *)opaque, errp); +} + +static void sifive_u_machine_instance_init(Object *obj) +{ + SiFiveUState *s = RISCV_U_MACHINE(obj); + + s->start_in_flash = false; + object_property_add_bool(obj, "start-in-flash", sifive_u_machine_get_start_in_flash, + sifive_u_machine_set_start_in_flash, NULL); + object_property_set_description(obj, "start-in-flash", + "Set on to tell QEMU's ROM to jump to " + "flash. Otherwise QEMU will jump to DRAM", + NULL); + + s->serial = OTP_SERIAL; + object_property_add(obj, "serial", "uint32", sifive_u_machine_get_serial, + sifive_u_machine_set_serial, NULL, &s->serial, NULL); + object_property_set_description(obj, "serial", "Board serial number", NULL); +} + +static void sifive_u_machine_class_init(ObjectClass *oc, void *data) +{ + MachineClass *mc = MACHINE_CLASS(oc); + + mc->desc = "RISC-V Board compatible with SiFive U SDK"; + mc->init = sifive_u_machine_init; + mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + SIFIVE_U_COMPUTE_CPU_COUNT; + mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1; + mc->default_cpus = mc->min_cpus; +} + +static const TypeInfo sifive_u_machine_typeinfo = { + .name = MACHINE_TYPE_NAME("sifive_u"), + .parent = TYPE_MACHINE, + .class_init = sifive_u_machine_class_init, + .instance_init = sifive_u_machine_instance_init, + .instance_size = sizeof(SiFiveUState), +}; + +static void sifive_u_machine_init_register_types(void) +{ + type_register_static(&sifive_u_machine_typeinfo); +} + +type_init(sifive_u_machine_init_register_types) + static void riscv_sifive_u_soc_init(Object *obj) { MachineState *ms = MACHINE(qdev_get_machine()); @@ -438,38 +515,10 @@ static void riscv_sifive_u_soc_init(Object *obj) TYPE_SIFIVE_U_PRCI); sysbus_init_child_obj(obj, "otp", &s->otp, sizeof(s->otp), TYPE_SIFIVE_U_OTP); - qdev_prop_set_uint32(DEVICE(&s->otp), "serial", OTP_SERIAL); sysbus_init_child_obj(obj, "gem", &s->gem, sizeof(s->gem), TYPE_CADENCE_GEM); } -static bool sifive_u_get_start_in_flash(Object *obj, Error **errp) -{ - SiFiveUState *s = RISCV_U_MACHINE(obj); - - return s->start_in_flash; -} - -static void sifive_u_set_start_in_flash(Object *obj, bool value, Error **errp) -{ - SiFiveUState *s = RISCV_U_MACHINE(obj); - - s->start_in_flash = value; -} - -static void riscv_sifive_u_machine_instance_init(Object *obj) -{ - SiFiveUState *s = RISCV_U_MACHINE(obj); - - s->start_in_flash = false; - object_property_add_bool(obj, "start-in-flash", sifive_u_get_start_in_flash, - sifive_u_set_start_in_flash, NULL); - object_property_set_description(obj, "start-in-flash", - "Set on to tell QEMU's ROM to jump to " - "flash. Otherwise QEMU will jump to DRAM", - NULL); -} - static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp) { MachineState *ms = MACHINE(qdev_get_machine()); @@ -558,6 +607,7 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp) object_property_set_bool(OBJECT(&s->prci), true, "realized", &err); sysbus_mmio_map(SYS_BUS_DEVICE(&s->prci), 0, memmap[SIFIVE_U_PRCI].base); + qdev_prop_set_uint32(DEVICE(&s->otp), "serial", s->serial); object_property_set_bool(OBJECT(&s->otp), true, "realized", &err); sysbus_mmio_map(SYS_BUS_DEVICE(&s->otp), 0, memmap[SIFIVE_U_OTP].base); @@ -584,10 +634,16 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp) memmap[SIFIVE_U_GEM_MGMT].base, memmap[SIFIVE_U_GEM_MGMT].size); } +static Property riscv_sifive_u_soc_props[] = { + DEFINE_PROP_UINT32("serial", SiFiveUSoCState, serial, OTP_SERIAL), + DEFINE_PROP_END_OF_LIST() +}; + static void riscv_sifive_u_soc_class_init(ObjectClass *oc, void *data) { DeviceClass *dc = DEVICE_CLASS(oc); + device_class_set_props(dc, riscv_sifive_u_soc_props); dc->realize = riscv_sifive_u_soc_realize; /* Reason: Uses serial_hds in realize function, thus can't be used twice */ dc->user_creatable = false; @@ -607,29 +663,3 @@ static void riscv_sifive_u_soc_register_types(void) } type_init(riscv_sifive_u_soc_register_types) - -static void riscv_sifive_u_machine_class_init(ObjectClass *oc, void *data) -{ - MachineClass *mc = MACHINE_CLASS(oc); - - mc->desc = "RISC-V Board compatible with SiFive U SDK"; - mc->init = riscv_sifive_u_init; - mc->max_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + SIFIVE_U_COMPUTE_CPU_COUNT; - mc->min_cpus = SIFIVE_U_MANAGEMENT_CPU_COUNT + 1; - mc->default_cpus = mc->min_cpus; -} - -static const TypeInfo riscv_sifive_u_machine_typeinfo = { - .name = MACHINE_TYPE_NAME("sifive_u"), - .parent = TYPE_MACHINE, - .class_init = riscv_sifive_u_machine_class_init, - .instance_init = riscv_sifive_u_machine_instance_init, - .instance_size = sizeof(SiFiveUState), -}; - -static void riscv_sifive_u_machine_init_register_types(void) -{ - type_register_static(&riscv_sifive_u_machine_typeinfo); -} - -type_init(riscv_sifive_u_machine_init_register_types) diff --git a/hw/riscv/spike.c b/hw/riscv/spike.c index 5053fe4590..d0c4843712 100644 --- a/hw/riscv/spike.c +++ b/hw/riscv/spike.c @@ -45,6 +45,12 @@ #include <libfdt.h> +#if defined(TARGET_RISCV32) +# define BIOS_FILENAME "opensbi-riscv32-spike-fw_jump.elf" +#else +# define BIOS_FILENAME "opensbi-riscv64-spike-fw_jump.elf" +#endif + static const struct MemmapEntry { hwaddr base; hwaddr size; @@ -102,7 +108,11 @@ 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); +#if defined(TARGET_RISCV32) + qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32"); +#else qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48"); +#endif qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa); qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv"); qemu_fdt_setprop_string(fdt, nodename, "status", "okay"); @@ -183,8 +193,24 @@ static void spike_board_init(MachineState *machine) memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base, mask_rom); + riscv_find_and_load_firmware(machine, BIOS_FILENAME, + memmap[SPIKE_DRAM].base, + htif_symbol_callback); + if (machine->kernel_filename) { - riscv_load_kernel(machine->kernel_filename, htif_symbol_callback); + uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename, + htif_symbol_callback); + + if (machine->initrd_filename) { + hwaddr start; + hwaddr end = riscv_load_initrd(machine->initrd_filename, + machine->ram_size, kernel_entry, + &start); + qemu_fdt_setprop_cell(s->fdt, "/chosen", + "linux,initrd-start", start); + qemu_fdt_setprop_cell(s->fdt, "/chosen", "linux,initrd-end", + end); + } } /* reset vector */ @@ -450,7 +476,7 @@ static void spike_machine_init(MachineClass *mc) { mc->desc = "RISC-V Spike Board"; mc->init = spike_board_init; - mc->max_cpus = 1; + mc->max_cpus = 8; mc->is_default = true; mc->default_cpu_type = SPIKE_V1_10_0_CPU; } diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 85ec9e22aa..daae3ebdbb 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -229,7 +229,11 @@ 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); +#if defined(TARGET_RISCV32) + qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32"); +#else qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48"); +#endif qemu_fdt_setprop_string(fdt, nodename, "riscv,isa", isa); qemu_fdt_setprop_string(fdt, nodename, "compatible", "riscv"); qemu_fdt_setprop_string(fdt, nodename, "status", "okay"); @@ -507,7 +511,7 @@ static void riscv_virt_board_init(MachineState *machine) mask_rom); riscv_find_and_load_firmware(machine, BIOS_FILENAME, - memmap[VIRT_DRAM].base); + memmap[VIRT_DRAM].base, NULL); if (machine->kernel_filename) { uint64_t kernel_entry = riscv_load_kernel(machine->kernel_filename, diff --git a/include/hw/riscv/boot.h b/include/hw/riscv/boot.h index df80051fbc..474a940ad5 100644 --- a/include/hw/riscv/boot.h +++ b/include/hw/riscv/boot.h @@ -24,10 +24,12 @@ void riscv_find_and_load_firmware(MachineState *machine, const char *default_machine_firmware, - hwaddr firmware_load_addr); + hwaddr firmware_load_addr, + symbol_fn_t sym_cb); char *riscv_find_firmware(const char *firmware_filename); target_ulong riscv_load_firmware(const char *firmware_filename, - hwaddr firmware_load_addr); + hwaddr firmware_load_addr, + symbol_fn_t sym_cb); target_ulong riscv_load_kernel(const char *kernel_filename, symbol_fn_t sym_cb); hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size, diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h index 82667b5746..16c297ec5f 100644 --- a/include/hw/riscv/sifive_u.h +++ b/include/hw/riscv/sifive_u.h @@ -42,6 +42,8 @@ typedef struct SiFiveUSoCState { SiFiveUPRCIState prci; SiFiveUOTPState otp; CadenceGEMState gem; + + uint32_t serial; } SiFiveUSoCState; #define TYPE_RISCV_U_MACHINE MACHINE_TYPE_NAME("sifive_u") @@ -59,6 +61,7 @@ typedef struct SiFiveUState { int fdt_size; bool start_in_flash; + uint32_t serial; } SiFiveUState; enum { diff --git a/linux-user/riscv/signal.c b/linux-user/riscv/signal.c index 83ecc6f799..67a95dbc7b 100644 --- a/linux-user/riscv/signal.c +++ b/linux-user/riscv/signal.c @@ -40,8 +40,9 @@ struct target_ucontext { unsigned long uc_flags; struct target_ucontext *uc_link; target_stack_t uc_stack; - struct target_sigcontext uc_mcontext; target_sigset_t uc_sigmask; + uint8_t __unused[1024 / 8 - sizeof(target_sigset_t)]; + struct target_sigcontext uc_mcontext QEMU_ALIGNED(16); }; struct target_rt_sigframe { diff --git a/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin b/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin Binary files differindex bab13f597a..3e0da54080 100644 --- a/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin +++ b/pc-bios/opensbi-riscv32-sifive_u-fw_jump.bin diff --git a/pc-bios/opensbi-riscv32-virt-fw_jump.bin b/pc-bios/opensbi-riscv32-virt-fw_jump.bin Binary files differindex c9654e7047..bc56ed61fd 100644 --- a/pc-bios/opensbi-riscv32-virt-fw_jump.bin +++ b/pc-bios/opensbi-riscv32-virt-fw_jump.bin diff --git a/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin b/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin Binary files differindex 77f4dc8f83..1acee86dc7 100644 --- a/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin +++ b/pc-bios/opensbi-riscv64-sifive_u-fw_jump.bin diff --git a/pc-bios/opensbi-riscv64-virt-fw_jump.bin b/pc-bios/opensbi-riscv64-virt-fw_jump.bin Binary files differindex 31e74d12ea..c62f2b449b 100644 --- a/pc-bios/opensbi-riscv64-virt-fw_jump.bin +++ b/pc-bios/opensbi-riscv64-virt-fw_jump.bin diff --git a/roms/opensbi b/roms/opensbi -Subproject ac5e821d50be631f26274765a59bc1b444ffd86 +Subproject 9f1b72ce66d659e91013b358939e832fb27223f diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 4e578239d3..059d71f2c7 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -164,6 +164,15 @@ static void rv32imacu_nommu_cpu_init(Object *obj) set_feature(env, RISCV_FEATURE_PMP); } +static void rv32imafcu_nommu_cpu_init(Object *obj) +{ + CPURISCVState *env = &RISCV_CPU(obj)->env; + set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVC | RVU); + set_priv_version(env, PRIV_VERSION_1_10_0); + set_resetvec(env, DEFAULT_RSTVEC); + set_feature(env, RISCV_FEATURE_PMP); +} + #elif defined(TARGET_RISCV64) static void riscv_base64_cpu_init(Object *obj) @@ -610,6 +619,7 @@ static const TypeInfo riscv_cpu_type_infos[] = { #if defined(TARGET_RISCV32) DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base32_cpu_init), DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32imacu_nommu_cpu_init), + DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32imafcu_nommu_cpu_init), DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32gcsu_priv1_10_0_cpu_init), /* Depreacted */ DEFINE_CPU(TYPE_RISCV_CPU_RV32IMACU_NOMMU, rv32imacu_nommu_cpu_init), diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h index 7d21addbab..d0e7f5b9c5 100644 --- a/target/riscv/cpu.h +++ b/target/riscv/cpu.h @@ -36,6 +36,7 @@ #define TYPE_RISCV_CPU_BASE32 RISCV_CPU_TYPE_NAME("rv32") #define TYPE_RISCV_CPU_BASE64 RISCV_CPU_TYPE_NAME("rv64") #define TYPE_RISCV_CPU_SIFIVE_E31 RISCV_CPU_TYPE_NAME("sifive-e31") +#define TYPE_RISCV_CPU_SIFIVE_E34 RISCV_CPU_TYPE_NAME("sifive-e34") #define TYPE_RISCV_CPU_SIFIVE_E51 RISCV_CPU_TYPE_NAME("sifive-e51") #define TYPE_RISCV_CPU_SIFIVE_U34 RISCV_CPU_TYPE_NAME("sifive-u34") #define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54") diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c index d3ba9efb02..bc80aa87cf 100644 --- a/target/riscv/cpu_helper.c +++ b/target/riscv/cpu_helper.c @@ -452,10 +452,11 @@ restart: hwaddr pte_addr; if (two_stage && first_stage) { + int vbase_prot; hwaddr vbase; /* Do the second stage translation on the base PTE address. */ - get_physical_address(env, &vbase, prot, base, access_type, + get_physical_address(env, &vbase, &vbase_prot, base, access_type, mmu_idx, false, true); pte_addr = vbase + idx * ptesize; @@ -558,12 +559,7 @@ restart: /* for superpage mappings, make a fake leaf PTE for the TLB's benefit. */ target_ulong vpn = addr >> PGSHIFT; - if (i == 0) { - *physical = (ppn | (vpn & ((1L << (ptshift + widened)) - 1))) << - PGSHIFT; - } else { - *physical = (ppn | (vpn & ((1L << ptshift) - 1))) << PGSHIFT; - } + *physical = (ppn | (vpn & ((1L << ptshift) - 1))) << PGSHIFT; /* set permissions on the TLB entry */ if ((pte & PTE_R) || ((pte & PTE_X) && mxr)) { @@ -706,7 +702,7 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, #ifndef CONFIG_USER_ONLY vaddr im_address; hwaddr pa = 0; - int prot; + int prot, prot2; bool pmp_violation = false; bool m_mode_two_stage = false; bool hs_mode_two_stage = false; @@ -756,13 +752,15 @@ bool riscv_cpu_tlb_fill(CPUState *cs, vaddr address, int size, /* Second stage lookup */ im_address = pa; - ret = get_physical_address(env, &pa, &prot, im_address, + ret = get_physical_address(env, &pa, &prot2, im_address, access_type, mmu_idx, false, true); qemu_log_mask(CPU_LOG_MMU, "%s 2nd-stage address=%" VADDR_PRIx " ret %d physical " TARGET_FMT_plx " prot %d\n", - __func__, im_address, ret, pa, prot); + __func__, im_address, ret, pa, prot2); + + prot &= prot2; if (riscv_feature(env, RISCV_FEATURE_PMP) && (ret == TRANSLATE_SUCCESS) && |