mirror of https://gitee.com/openkylin/qemu.git
A collection of RISC-V improvements:
- Improve the sifive_u DTB generation - Add QSPI NOR flash to Microchip PFSoC - Fix a bug in the Hypervisor HLVX/HLV/HSV instructions - Fix some mstatus mask defines - Ibex PLIC improvements - OpenTitan memory layout update - Initial steps towards support for 32-bit CPUs on 64-bit builds -----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEE9sSsRtSTSGjTuM6PIeENKd+XcFQFAl/cRU4ACgkQIeENKd+X cFTAPgf/dHOYiBeSZr0eg03LwpqiJ5ziVrvE9nvAjml8CsDvwlx6roEMT1Ynyquq zs8sPb4a1Ro7rHBofHFqgHp8TO6wAiw2nDrT8YEt1iARO5Oh5IuHqs/wi8SNB2QF d1Dv8/zIBOkK5+Fg/DQHTrPgq4fJZwY2jnVZAyUBuMW5UkvCVlJI4zGPwYyh+4ZS xTWogMzSbyer3evfTg8f8AhvCGQMITwLo6Nxc4wj3bf1ZE8Br9UxorqPme4UwJ+r Ip9/jXDlKI9BeE85XoOrQJNLR7OzLgdQ1S/LjeBYLQmsltOD49YcH6a6AX3YjDwW Jj6GgXBTFGIUXbxc3ADpoMJQp+xDSA== =Vj2m -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20201217-1' into staging A collection of RISC-V improvements: - Improve the sifive_u DTB generation - Add QSPI NOR flash to Microchip PFSoC - Fix a bug in the Hypervisor HLVX/HLV/HSV instructions - Fix some mstatus mask defines - Ibex PLIC improvements - OpenTitan memory layout update - Initial steps towards support for 32-bit CPUs on 64-bit builds # gpg: Signature made Fri 18 Dec 2020 05:59:42 GMT # gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054 # gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full] # Primary key fingerprint: F6C4 AC46 D493 4868 D3B8 CE8F 21E1 0D29 DF97 7054 * remotes/alistair/tags/pull-riscv-to-apply-20201217-1: (23 commits) riscv/opentitan: Update the OpenTitan memory layout hw/riscv: Use the CPU to determine if 32-bit target/riscv: cpu: Set XLEN independently from target target/riscv: csr: Remove compile time XLEN checks target/riscv: cpu_helper: Remove compile time XLEN checks target/riscv: cpu: Remove compile time XLEN checks target/riscv: Specify the XLEN for CPUs target/riscv: Add a riscv_cpu_is_32bit() helper function target/riscv: fpu_helper: Match function defs in HELPER macros hw/riscv: sifive_u: Remove compile time XLEN checks hw/riscv: spike: Remove compile time XLEN checks hw/riscv: virt: Remove compile time XLEN checks hw/riscv: boot: Remove compile time XLEN checks riscv: virt: Remove target macro conditionals riscv: spike: Remove target macro conditionals target/riscv: Add a TYPE_RISCV_CPU_BASE CPU hw/riscv: Expand the is 32-bit check to support more CPUs intc/ibex_plic: Clear interrupts that occur during claim process target/riscv: Fix definition of MSTATUS_TW and MSTATUS_TSR target/riscv: Fix the bug of HLVX/HLV/HSV ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
a05f8ecd88
|
@ -80,7 +80,7 @@ void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
|
|||
|
||||
if (!ac || !ac->name) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: write to undefined device state "
|
||||
"(written value: %#" PRIx64 ")\n", prefix, val);
|
||||
"(written value: 0x%" PRIx64 ")\n", prefix, val);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -89,14 +89,14 @@ void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
|
|||
test = (old_val ^ val) & ac->rsvd;
|
||||
if (test) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: change of value in reserved bit"
|
||||
"fields: %#" PRIx64 ")\n", prefix, test);
|
||||
"fields: 0x%" PRIx64 ")\n", prefix, test);
|
||||
}
|
||||
|
||||
test = val & ac->unimp;
|
||||
if (test) {
|
||||
qemu_log_mask(LOG_UNIMP,
|
||||
"%s:%s writing %#" PRIx64 " to unimplemented bits:" \
|
||||
" %#" PRIx64 "\n",
|
||||
"%s:%s writing 0x%" PRIx64 " to unimplemented bits:" \
|
||||
" 0x%" PRIx64 "\n",
|
||||
prefix, reg->access->name, val, ac->unimp);
|
||||
}
|
||||
|
||||
|
@ -112,7 +112,7 @@ void register_write(RegisterInfo *reg, uint64_t val, uint64_t we,
|
|||
}
|
||||
|
||||
if (debug) {
|
||||
qemu_log("%s:%s: write of value %#" PRIx64 "\n", prefix, ac->name,
|
||||
qemu_log("%s:%s: write of value 0x%" PRIx64 "\n", prefix, ac->name,
|
||||
new_val);
|
||||
}
|
||||
|
||||
|
@ -150,7 +150,7 @@ uint64_t register_read(RegisterInfo *reg, uint64_t re, const char* prefix,
|
|||
}
|
||||
|
||||
if (debug) {
|
||||
qemu_log("%s:%s: read of value %#" PRIx64 "\n", prefix,
|
||||
qemu_log("%s:%s: read of value 0x%" PRIx64 "\n", prefix,
|
||||
ac->name, ret);
|
||||
}
|
||||
|
||||
|
@ -193,7 +193,7 @@ void register_write_memory(void *opaque, hwaddr addr,
|
|||
|
||||
if (!reg) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: write to unimplemented register " \
|
||||
"at address: %#" PRIx64 "\n", reg_array->prefix, addr);
|
||||
"at address: 0x%" PRIx64 "\n", reg_array->prefix, addr);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ uint64_t register_read_memory(void *opaque, hwaddr addr,
|
|||
|
||||
if (!reg) {
|
||||
qemu_log_mask(LOG_GUEST_ERROR, "%s: read to unimplemented register " \
|
||||
"at address: %#" PRIx64 "\n", reg_array->prefix, addr);
|
||||
"at address: 0x%" PRIx64 "\n", reg_array->prefix, addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,16 +43,23 @@ static void ibex_plic_irqs_set_pending(IbexPlicState *s, int irq, bool level)
|
|||
{
|
||||
int pending_num = irq / 32;
|
||||
|
||||
if (!level) {
|
||||
/*
|
||||
* If the level is low make sure we clear the hidden_pending.
|
||||
*/
|
||||
s->hidden_pending[pending_num] &= ~(1 << (irq % 32));
|
||||
}
|
||||
|
||||
if (s->claimed[pending_num] & 1 << (irq % 32)) {
|
||||
/*
|
||||
* The interrupt has been claimed, but not completed.
|
||||
* The pending bit can't be set.
|
||||
* Save the pending level for after the interrupt is completed.
|
||||
*/
|
||||
s->hidden_pending[pending_num] |= level << (irq % 32);
|
||||
return;
|
||||
} else {
|
||||
s->pending[pending_num] |= level << (irq % 32);
|
||||
}
|
||||
|
||||
s->pending[pending_num] |= level << (irq % 32);
|
||||
}
|
||||
|
||||
static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
|
||||
|
|
|
@ -33,24 +33,16 @@
|
|||
|
||||
#include <libfdt.h>
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
#define fw_dynamic_info_data(__val) cpu_to_le32(__val)
|
||||
#else
|
||||
#define fw_dynamic_info_data(__val) cpu_to_le64(__val)
|
||||
#endif
|
||||
|
||||
bool riscv_is_32_bit(MachineState *machine)
|
||||
bool riscv_is_32bit(RISCVHartArrayState harts)
|
||||
{
|
||||
if (!strncmp(machine->cpu_type, "rv32", 4)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
RISCVCPU hart = harts.harts[0];
|
||||
|
||||
return riscv_cpu_is_32bit(&hart.env);
|
||||
}
|
||||
|
||||
target_ulong riscv_calc_kernel_start_addr(MachineState *machine,
|
||||
target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState harts,
|
||||
target_ulong firmware_end_addr) {
|
||||
if (riscv_is_32_bit(machine)) {
|
||||
if (riscv_is_32bit(harts)) {
|
||||
return QEMU_ALIGN_UP(firmware_end_addr, 4 * MiB);
|
||||
} else {
|
||||
return QEMU_ALIGN_UP(firmware_end_addr, 2 * MiB);
|
||||
|
@ -218,16 +210,24 @@ uint32_t riscv_load_fdt(hwaddr dram_base, uint64_t mem_size, void *fdt)
|
|||
return fdt_addr;
|
||||
}
|
||||
|
||||
void riscv_rom_copy_firmware_info(hwaddr rom_base, hwaddr rom_size,
|
||||
uint32_t reset_vec_size, uint64_t kernel_entry)
|
||||
void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
|
||||
hwaddr rom_size, uint32_t reset_vec_size,
|
||||
uint64_t kernel_entry)
|
||||
{
|
||||
struct fw_dynamic_info dinfo;
|
||||
size_t dinfo_len;
|
||||
|
||||
dinfo.magic = fw_dynamic_info_data(FW_DYNAMIC_INFO_MAGIC_VALUE);
|
||||
dinfo.version = fw_dynamic_info_data(FW_DYNAMIC_INFO_VERSION);
|
||||
dinfo.next_mode = fw_dynamic_info_data(FW_DYNAMIC_INFO_NEXT_MODE_S);
|
||||
dinfo.next_addr = fw_dynamic_info_data(kernel_entry);
|
||||
if (sizeof(dinfo.magic) == 4) {
|
||||
dinfo.magic = cpu_to_le32(FW_DYNAMIC_INFO_MAGIC_VALUE);
|
||||
dinfo.version = cpu_to_le32(FW_DYNAMIC_INFO_VERSION);
|
||||
dinfo.next_mode = cpu_to_le32(FW_DYNAMIC_INFO_NEXT_MODE_S);
|
||||
dinfo.next_addr = cpu_to_le32(kernel_entry);
|
||||
} else {
|
||||
dinfo.magic = cpu_to_le64(FW_DYNAMIC_INFO_MAGIC_VALUE);
|
||||
dinfo.version = cpu_to_le64(FW_DYNAMIC_INFO_VERSION);
|
||||
dinfo.next_mode = cpu_to_le64(FW_DYNAMIC_INFO_NEXT_MODE_S);
|
||||
dinfo.next_addr = cpu_to_le64(kernel_entry);
|
||||
}
|
||||
dinfo.options = 0;
|
||||
dinfo.boot_hart = 0;
|
||||
dinfo_len = sizeof(dinfo);
|
||||
|
@ -247,28 +247,25 @@ void riscv_rom_copy_firmware_info(hwaddr rom_base, hwaddr rom_size,
|
|||
&address_space_memory);
|
||||
}
|
||||
|
||||
void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
|
||||
hwaddr rom_size, uint64_t kernel_entry,
|
||||
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState harts,
|
||||
hwaddr start_addr,
|
||||
hwaddr rom_base, hwaddr rom_size,
|
||||
uint64_t kernel_entry,
|
||||
uint32_t fdt_load_addr, void *fdt)
|
||||
{
|
||||
int i;
|
||||
uint32_t start_addr_hi32 = 0x00000000;
|
||||
|
||||
#if defined(TARGET_RISCV64)
|
||||
start_addr_hi32 = start_addr >> 32;
|
||||
#endif
|
||||
if (!riscv_is_32bit(harts)) {
|
||||
start_addr_hi32 = start_addr >> 32;
|
||||
}
|
||||
/* reset vector */
|
||||
uint32_t reset_vec[10] = {
|
||||
0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */
|
||||
0x02828613, /* addi a2, t0, %pcrel_lo(1b) */
|
||||
0xf1402573, /* csrr a0, mhartid */
|
||||
#if defined(TARGET_RISCV32)
|
||||
0x0202a583, /* lw a1, 32(t0) */
|
||||
0x0182a283, /* lw t0, 24(t0) */
|
||||
#elif defined(TARGET_RISCV64)
|
||||
0x0202b583, /* ld a1, 32(t0) */
|
||||
0x0182b283, /* ld t0, 24(t0) */
|
||||
#endif
|
||||
0,
|
||||
0,
|
||||
0x00028067, /* jr t0 */
|
||||
start_addr, /* start: .dword */
|
||||
start_addr_hi32,
|
||||
|
@ -276,6 +273,13 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
|
|||
0x00000000,
|
||||
/* fw_dyn: */
|
||||
};
|
||||
if (riscv_is_32bit(harts)) {
|
||||
reset_vec[3] = 0x0202a583; /* lw a1, 32(t0) */
|
||||
reset_vec[4] = 0x0182a283; /* lw t0, 24(t0) */
|
||||
} else {
|
||||
reset_vec[3] = 0x0202b583; /* ld a1, 32(t0) */
|
||||
reset_vec[4] = 0x0182b283; /* ld t0, 24(t0) */
|
||||
}
|
||||
|
||||
/* copy in the reset vector in little_endian byte order */
|
||||
for (i = 0; i < ARRAY_SIZE(reset_vec); i++) {
|
||||
|
@ -283,7 +287,7 @@ void riscv_setup_rom_reset_vec(hwaddr start_addr, hwaddr rom_base,
|
|||
}
|
||||
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
|
||||
rom_base, &address_space_memory);
|
||||
riscv_rom_copy_firmware_info(rom_base, rom_size, sizeof(reset_vec),
|
||||
riscv_rom_copy_firmware_info(machine, rom_base, rom_size, sizeof(reset_vec),
|
||||
kernel_entry);
|
||||
|
||||
return;
|
||||
|
|
|
@ -113,6 +113,8 @@ static const struct MemmapEntry {
|
|||
[MICROCHIP_PFSOC_MMUART2] = { 0x20102000, 0x1000 },
|
||||
[MICROCHIP_PFSOC_MMUART3] = { 0x20104000, 0x1000 },
|
||||
[MICROCHIP_PFSOC_MMUART4] = { 0x20106000, 0x1000 },
|
||||
[MICROCHIP_PFSOC_SPI0] = { 0x20108000, 0x1000 },
|
||||
[MICROCHIP_PFSOC_SPI1] = { 0x20109000, 0x1000 },
|
||||
[MICROCHIP_PFSOC_I2C1] = { 0x2010b000, 0x1000 },
|
||||
[MICROCHIP_PFSOC_GEM0] = { 0x20110000, 0x2000 },
|
||||
[MICROCHIP_PFSOC_GEM1] = { 0x20112000, 0x2000 },
|
||||
|
@ -121,6 +123,7 @@ static const struct MemmapEntry {
|
|||
[MICROCHIP_PFSOC_GPIO2] = { 0x20122000, 0x1000 },
|
||||
[MICROCHIP_PFSOC_ENVM_CFG] = { 0x20200000, 0x1000 },
|
||||
[MICROCHIP_PFSOC_ENVM_DATA] = { 0x20220000, 0x20000 },
|
||||
[MICROCHIP_PFSOC_QSPI_XIP] = { 0x21000000, 0x1000000 },
|
||||
[MICROCHIP_PFSOC_IOSCB] = { 0x30000000, 0x10000000 },
|
||||
[MICROCHIP_PFSOC_DRAM_LO] = { 0x80000000, 0x40000000 },
|
||||
[MICROCHIP_PFSOC_DRAM_LO_ALIAS] = { 0xc0000000, 0x40000000 },
|
||||
|
@ -185,6 +188,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
|
|||
MemoryRegion *e51_dtim_mem = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *l2lim_mem = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *envm_data = g_new(MemoryRegion, 1);
|
||||
MemoryRegion *qspi_xip_mem = g_new(MemoryRegion, 1);
|
||||
char *plic_hart_config;
|
||||
size_t plic_hart_config_len;
|
||||
NICInfo *nd;
|
||||
|
@ -344,6 +348,14 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
|
|||
qdev_get_gpio_in(DEVICE(s->plic), MICROCHIP_PFSOC_MMUART4_IRQ),
|
||||
serial_hd(4));
|
||||
|
||||
/* SPI */
|
||||
create_unimplemented_device("microchip.pfsoc.spi0",
|
||||
memmap[MICROCHIP_PFSOC_SPI0].base,
|
||||
memmap[MICROCHIP_PFSOC_SPI0].size);
|
||||
create_unimplemented_device("microchip.pfsoc.spi1",
|
||||
memmap[MICROCHIP_PFSOC_SPI1].base,
|
||||
memmap[MICROCHIP_PFSOC_SPI1].size);
|
||||
|
||||
/* I2C1 */
|
||||
create_unimplemented_device("microchip.pfsoc.i2c1",
|
||||
memmap[MICROCHIP_PFSOC_I2C1].base,
|
||||
|
@ -401,6 +413,15 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
|
|||
sysbus_realize(SYS_BUS_DEVICE(&s->ioscb), errp);
|
||||
sysbus_mmio_map(SYS_BUS_DEVICE(&s->ioscb), 0,
|
||||
memmap[MICROCHIP_PFSOC_IOSCB].base);
|
||||
|
||||
/* QSPI Flash */
|
||||
memory_region_init_rom(qspi_xip_mem, OBJECT(dev),
|
||||
"microchip.pfsoc.qspi_xip",
|
||||
memmap[MICROCHIP_PFSOC_QSPI_XIP].size,
|
||||
&error_fatal);
|
||||
memory_region_add_subregion(system_memory,
|
||||
memmap[MICROCHIP_PFSOC_QSPI_XIP].base,
|
||||
qspi_xip_mem);
|
||||
}
|
||||
|
||||
static void microchip_pfsoc_soc_class_init(ObjectClass *oc, void *data)
|
||||
|
|
|
@ -35,22 +35,33 @@ static const struct MemmapEntry {
|
|||
[IBEX_DEV_ROM] = { 0x00008000, 16 * KiB },
|
||||
[IBEX_DEV_RAM] = { 0x10000000, 0x10000 },
|
||||
[IBEX_DEV_FLASH] = { 0x20000000, 0x80000 },
|
||||
[IBEX_DEV_UART] = { 0x40000000, 0x10000 },
|
||||
[IBEX_DEV_GPIO] = { 0x40010000, 0x10000 },
|
||||
[IBEX_DEV_SPI] = { 0x40020000, 0x10000 },
|
||||
[IBEX_DEV_FLASH_CTRL] = { 0x40030000, 0x10000 },
|
||||
[IBEX_DEV_PINMUX] = { 0x40070000, 0x10000 },
|
||||
[IBEX_DEV_RV_TIMER] = { 0x40080000, 0x10000 },
|
||||
[IBEX_DEV_PLIC] = { 0x40090000, 0x10000 },
|
||||
[IBEX_DEV_PWRMGR] = { 0x400A0000, 0x10000 },
|
||||
[IBEX_DEV_RSTMGR] = { 0x400B0000, 0x10000 },
|
||||
[IBEX_DEV_CLKMGR] = { 0x400C0000, 0x10000 },
|
||||
[IBEX_DEV_AES] = { 0x40110000, 0x10000 },
|
||||
[IBEX_DEV_HMAC] = { 0x40120000, 0x10000 },
|
||||
[IBEX_DEV_ALERT_HANDLER] = { 0x40130000, 0x10000 },
|
||||
[IBEX_DEV_NMI_GEN] = { 0x40140000, 0x10000 },
|
||||
[IBEX_DEV_USBDEV] = { 0x40150000, 0x10000 },
|
||||
[IBEX_DEV_PADCTRL] = { 0x40160000, 0x10000 }
|
||||
[IBEX_DEV_UART] = { 0x40000000, 0x1000 },
|
||||
[IBEX_DEV_GPIO] = { 0x40040000, 0x1000 },
|
||||
[IBEX_DEV_SPI] = { 0x40050000, 0x1000 },
|
||||
[IBEX_DEV_I2C] = { 0x40080000, 0x1000 },
|
||||
[IBEX_DEV_PATTGEN] = { 0x400e0000, 0x1000 },
|
||||
[IBEX_DEV_RV_TIMER] = { 0x40100000, 0x1000 },
|
||||
[IBEX_DEV_SENSOR_CTRL] = { 0x40110000, 0x1000 },
|
||||
[IBEX_DEV_OTP_CTRL] = { 0x40130000, 0x4000 },
|
||||
[IBEX_DEV_PWRMGR] = { 0x40400000, 0x1000 },
|
||||
[IBEX_DEV_RSTMGR] = { 0x40410000, 0x1000 },
|
||||
[IBEX_DEV_CLKMGR] = { 0x40420000, 0x1000 },
|
||||
[IBEX_DEV_PINMUX] = { 0x40460000, 0x1000 },
|
||||
[IBEX_DEV_PADCTRL] = { 0x40470000, 0x1000 },
|
||||
[IBEX_DEV_USBDEV] = { 0x40500000, 0x1000 },
|
||||
[IBEX_DEV_FLASH_CTRL] = { 0x41000000, 0x1000 },
|
||||
[IBEX_DEV_PLIC] = { 0x41010000, 0x1000 },
|
||||
[IBEX_DEV_AES] = { 0x41100000, 0x1000 },
|
||||
[IBEX_DEV_HMAC] = { 0x41110000, 0x1000 },
|
||||
[IBEX_DEV_KMAC] = { 0x41120000, 0x1000 },
|
||||
[IBEX_DEV_KEYMGR] = { 0x41130000, 0x1000 },
|
||||
[IBEX_DEV_CSRNG] = { 0x41150000, 0x1000 },
|
||||
[IBEX_DEV_ENTROPY] = { 0x41160000, 0x1000 },
|
||||
[IBEX_DEV_EDNO] = { 0x41170000, 0x1000 },
|
||||
[IBEX_DEV_EDN1] = { 0x41180000, 0x1000 },
|
||||
[IBEX_DEV_ALERT_HANDLER] = { 0x411b0000, 0x1000 },
|
||||
[IBEX_DEV_NMI_GEN] = { 0x411c0000, 0x1000 },
|
||||
[IBEX_DEV_OTBN] = { 0x411d0000, 0x10000 },
|
||||
};
|
||||
|
||||
static void opentitan_board_init(MachineState *machine)
|
||||
|
@ -156,30 +167,52 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
|
|||
memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.spi",
|
||||
memmap[IBEX_DEV_SPI].base, memmap[IBEX_DEV_SPI].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
|
||||
memmap[IBEX_DEV_FLASH_CTRL].base, memmap[IBEX_DEV_FLASH_CTRL].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.i2c",
|
||||
memmap[IBEX_DEV_I2C].base, memmap[IBEX_DEV_I2C].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.pattgen",
|
||||
memmap[IBEX_DEV_PATTGEN].base, memmap[IBEX_DEV_PATTGEN].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.rv_timer",
|
||||
memmap[IBEX_DEV_RV_TIMER].base, memmap[IBEX_DEV_RV_TIMER].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.sensor_ctrl",
|
||||
memmap[IBEX_DEV_SENSOR_CTRL].base, memmap[IBEX_DEV_SENSOR_CTRL].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.otp_ctrl",
|
||||
memmap[IBEX_DEV_OTP_CTRL].base, memmap[IBEX_DEV_OTP_CTRL].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.pwrmgr",
|
||||
memmap[IBEX_DEV_PWRMGR].base, memmap[IBEX_DEV_PWRMGR].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.rstmgr",
|
||||
memmap[IBEX_DEV_RSTMGR].base, memmap[IBEX_DEV_RSTMGR].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.clkmgr",
|
||||
memmap[IBEX_DEV_CLKMGR].base, memmap[IBEX_DEV_CLKMGR].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
|
||||
memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.padctrl",
|
||||
memmap[IBEX_DEV_PADCTRL].base, memmap[IBEX_DEV_PADCTRL].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
|
||||
memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.flash_ctrl",
|
||||
memmap[IBEX_DEV_FLASH_CTRL].base, memmap[IBEX_DEV_FLASH_CTRL].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.aes",
|
||||
memmap[IBEX_DEV_AES].base, memmap[IBEX_DEV_AES].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.hmac",
|
||||
memmap[IBEX_DEV_HMAC].base, memmap[IBEX_DEV_HMAC].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.pinmux",
|
||||
memmap[IBEX_DEV_PINMUX].base, memmap[IBEX_DEV_PINMUX].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.kmac",
|
||||
memmap[IBEX_DEV_KMAC].base, memmap[IBEX_DEV_KMAC].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.keymgr",
|
||||
memmap[IBEX_DEV_KEYMGR].base, memmap[IBEX_DEV_KEYMGR].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.csrng",
|
||||
memmap[IBEX_DEV_CSRNG].base, memmap[IBEX_DEV_CSRNG].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.entropy",
|
||||
memmap[IBEX_DEV_ENTROPY].base, memmap[IBEX_DEV_ENTROPY].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.edn0",
|
||||
memmap[IBEX_DEV_EDNO].base, memmap[IBEX_DEV_EDNO].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.edn1",
|
||||
memmap[IBEX_DEV_EDN1].base, memmap[IBEX_DEV_EDN1].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.alert_handler",
|
||||
memmap[IBEX_DEV_ALERT_HANDLER].base, memmap[IBEX_DEV_ALERT_HANDLER].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.nmi_gen",
|
||||
memmap[IBEX_DEV_NMI_GEN].base, memmap[IBEX_DEV_NMI_GEN].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.usbdev",
|
||||
memmap[IBEX_DEV_USBDEV].base, memmap[IBEX_DEV_USBDEV].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.padctrl",
|
||||
memmap[IBEX_DEV_PADCTRL].base, memmap[IBEX_DEV_PADCTRL].size);
|
||||
create_unimplemented_device("riscv.lowrisc.ibex.otbn",
|
||||
memmap[IBEX_DEV_OTBN].base, memmap[IBEX_DEV_OTBN].size);
|
||||
}
|
||||
|
||||
static void lowrisc_ibex_soc_class_init(ObjectClass *oc, void *data)
|
||||
|
|
|
@ -60,12 +60,6 @@
|
|||
|
||||
#include <libfdt.h>
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
# define BIOS_FILENAME "opensbi-riscv32-generic-fw_dynamic.bin"
|
||||
#else
|
||||
# define BIOS_FILENAME "opensbi-riscv64-generic-fw_dynamic.bin"
|
||||
#endif
|
||||
|
||||
static const struct MemmapEntry {
|
||||
hwaddr base;
|
||||
hwaddr size;
|
||||
|
@ -93,7 +87,7 @@ static const struct MemmapEntry {
|
|||
#define GEM_REVISION 0x10070109
|
||||
|
||||
static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
|
||||
uint64_t mem_size, const char *cmdline)
|
||||
uint64_t mem_size, const char *cmdline, bool is_32_bit)
|
||||
{
|
||||
MachineState *ms = MACHINE(qdev_get_machine());
|
||||
void *fdt;
|
||||
|
@ -176,11 +170,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
|
||||
if (is_32_bit) {
|
||||
qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv32");
|
||||
} else {
|
||||
qemu_fdt_setprop_string(fdt, nodename, "mmu-type", "riscv,sv48");
|
||||
}
|
||||
isa = riscv_isa_string(&s->soc.u_cpus.harts[cpu - 1]);
|
||||
} else {
|
||||
isa = riscv_isa_string(&s->soc.e_cpus.harts[0]);
|
||||
|
@ -385,6 +379,21 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
|
|||
qemu_fdt_setprop_cell(fdt, nodename, "reg", 0x0);
|
||||
g_free(nodename);
|
||||
|
||||
nodename = g_strdup_printf("/soc/serial@%lx",
|
||||
(long)memmap[SIFIVE_U_DEV_UART1].base);
|
||||
qemu_fdt_add_subnode(fdt, nodename);
|
||||
qemu_fdt_setprop_string(fdt, nodename, "compatible", "sifive,uart0");
|
||||
qemu_fdt_setprop_cells(fdt, nodename, "reg",
|
||||
0x0, memmap[SIFIVE_U_DEV_UART1].base,
|
||||
0x0, memmap[SIFIVE_U_DEV_UART1].size);
|
||||
qemu_fdt_setprop_cells(fdt, nodename, "clocks",
|
||||
prci_phandle, PRCI_CLK_TLCLK);
|
||||
qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
|
||||
qemu_fdt_setprop_cell(fdt, nodename, "interrupts", SIFIVE_U_UART1_IRQ);
|
||||
|
||||
qemu_fdt_setprop_string(fdt, "/aliases", "serial1", nodename);
|
||||
g_free(nodename);
|
||||
|
||||
nodename = g_strdup_printf("/soc/serial@%lx",
|
||||
(long)memmap[SIFIVE_U_DEV_UART0].base);
|
||||
qemu_fdt_add_subnode(fdt, nodename);
|
||||
|
@ -456,7 +465,8 @@ static void sifive_u_machine_init(MachineState *machine)
|
|||
qemu_allocate_irq(sifive_u_machine_reset, NULL, 0));
|
||||
|
||||
/* create device tree */
|
||||
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
|
||||
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
|
||||
riscv_is_32bit(s->soc.u_cpus));
|
||||
|
||||
if (s->start_in_flash) {
|
||||
/*
|
||||
|
@ -485,11 +495,18 @@ static void sifive_u_machine_init(MachineState *machine)
|
|||
break;
|
||||
}
|
||||
|
||||
firmware_end_addr = riscv_find_and_load_firmware(machine, BIOS_FILENAME,
|
||||
start_addr, NULL);
|
||||
if (riscv_is_32bit(s->soc.u_cpus)) {
|
||||
firmware_end_addr = riscv_find_and_load_firmware(machine,
|
||||
"opensbi-riscv32-generic-fw_dynamic.bin",
|
||||
start_addr, NULL);
|
||||
} else {
|
||||
firmware_end_addr = riscv_find_and_load_firmware(machine,
|
||||
"opensbi-riscv64-generic-fw_dynamic.bin",
|
||||
start_addr, NULL);
|
||||
}
|
||||
|
||||
if (machine->kernel_filename) {
|
||||
kernel_start_addr = riscv_calc_kernel_start_addr(machine,
|
||||
kernel_start_addr = riscv_calc_kernel_start_addr(s->soc.u_cpus,
|
||||
firmware_end_addr);
|
||||
|
||||
kernel_entry = riscv_load_kernel(machine->kernel_filename,
|
||||
|
@ -516,9 +533,9 @@ static void sifive_u_machine_init(MachineState *machine)
|
|||
/* Compute the fdt load address in dram */
|
||||
fdt_load_addr = riscv_load_fdt(memmap[SIFIVE_U_DEV_DRAM].base,
|
||||
machine->ram_size, s->fdt);
|
||||
#if defined(TARGET_RISCV64)
|
||||
start_addr_hi32 = start_addr >> 32;
|
||||
#endif
|
||||
if (!riscv_is_32bit(s->soc.u_cpus)) {
|
||||
start_addr_hi32 = (uint64_t)start_addr >> 32;
|
||||
}
|
||||
|
||||
/* reset vector */
|
||||
uint32_t reset_vec[11] = {
|
||||
|
@ -526,13 +543,8 @@ static void sifive_u_machine_init(MachineState *machine)
|
|||
0x00000297, /* 1: auipc t0, %pcrel_hi(fw_dyn) */
|
||||
0x02828613, /* addi a2, t0, %pcrel_lo(1b) */
|
||||
0xf1402573, /* csrr a0, mhartid */
|
||||
#if defined(TARGET_RISCV32)
|
||||
0x0202a583, /* lw a1, 32(t0) */
|
||||
0x0182a283, /* lw t0, 24(t0) */
|
||||
#elif defined(TARGET_RISCV64)
|
||||
0x0202b583, /* ld a1, 32(t0) */
|
||||
0x0182b283, /* ld t0, 24(t0) */
|
||||
#endif
|
||||
0,
|
||||
0,
|
||||
0x00028067, /* jr t0 */
|
||||
start_addr, /* start: .dword */
|
||||
start_addr_hi32,
|
||||
|
@ -540,6 +552,14 @@ static void sifive_u_machine_init(MachineState *machine)
|
|||
0x00000000,
|
||||
/* fw_dyn: */
|
||||
};
|
||||
if (riscv_is_32bit(s->soc.u_cpus)) {
|
||||
reset_vec[4] = 0x0202a583; /* lw a1, 32(t0) */
|
||||
reset_vec[5] = 0x0182a283; /* lw t0, 24(t0) */
|
||||
} else {
|
||||
reset_vec[4] = 0x0202b583; /* ld a1, 32(t0) */
|
||||
reset_vec[5] = 0x0182b283; /* ld t0, 24(t0) */
|
||||
}
|
||||
|
||||
|
||||
/* copy in the reset vector in little_endian byte order */
|
||||
for (i = 0; i < ARRAY_SIZE(reset_vec); i++) {
|
||||
|
@ -548,7 +568,7 @@ static void sifive_u_machine_init(MachineState *machine)
|
|||
rom_add_blob_fixed_as("mrom.reset", reset_vec, sizeof(reset_vec),
|
||||
memmap[SIFIVE_U_DEV_MROM].base, &address_space_memory);
|
||||
|
||||
riscv_rom_copy_firmware_info(memmap[SIFIVE_U_DEV_MROM].base,
|
||||
riscv_rom_copy_firmware_info(machine, memmap[SIFIVE_U_DEV_MROM].base,
|
||||
memmap[SIFIVE_U_DEV_MROM].size,
|
||||
sizeof(reset_vec), kernel_entry);
|
||||
}
|
||||
|
|
|
@ -43,17 +43,6 @@
|
|||
#include "sysemu/qtest.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
|
||||
/*
|
||||
* Not like other RISC-V machines that use plain binary bios images,
|
||||
* keeping ELF files here was intentional because BIN files don't work
|
||||
* for the Spike machine as HTIF emulation depends on ELF parsing.
|
||||
*/
|
||||
#if defined(TARGET_RISCV32)
|
||||
# define BIOS_FILENAME "opensbi-riscv32-generic-fw_dynamic.elf"
|
||||
#else
|
||||
# define BIOS_FILENAME "opensbi-riscv64-generic-fw_dynamic.elf"
|
||||
#endif
|
||||
|
||||
static const struct MemmapEntry {
|
||||
hwaddr base;
|
||||
hwaddr size;
|
||||
|
@ -64,7 +53,7 @@ static const struct MemmapEntry {
|
|||
};
|
||||
|
||||
static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
|
||||
uint64_t mem_size, const char *cmdline)
|
||||
uint64_t mem_size, const char *cmdline, bool is_32_bit)
|
||||
{
|
||||
void *fdt;
|
||||
uint64_t addr, size;
|
||||
|
@ -115,11 +104,11 @@ static void create_fdt(SpikeState *s, const struct MemmapEntry *memmap,
|
|||
cpu_name = g_strdup_printf("/cpus/cpu@%d",
|
||||
s->soc[socket].hartid_base + cpu);
|
||||
qemu_fdt_add_subnode(fdt, cpu_name);
|
||||
#if defined(TARGET_RISCV32)
|
||||
qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32");
|
||||
#else
|
||||
qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
|
||||
#endif
|
||||
if (is_32_bit) {
|
||||
qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32");
|
||||
} else {
|
||||
qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
|
||||
}
|
||||
name = riscv_isa_string(&s->soc[socket].harts[cpu]);
|
||||
qemu_fdt_setprop_string(fdt, cpu_name, "riscv,isa", name);
|
||||
g_free(name);
|
||||
|
@ -254,7 +243,8 @@ static void spike_board_init(MachineState *machine)
|
|||
main_mem);
|
||||
|
||||
/* create device tree */
|
||||
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
|
||||
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
|
||||
riscv_is_32bit(s->soc[0]));
|
||||
|
||||
/* boot rom */
|
||||
memory_region_init_rom(mask_rom, NULL, "riscv.spike.mrom",
|
||||
|
@ -262,12 +252,25 @@ static void spike_board_init(MachineState *machine)
|
|||
memory_region_add_subregion(system_memory, memmap[SPIKE_MROM].base,
|
||||
mask_rom);
|
||||
|
||||
firmware_end_addr = riscv_find_and_load_firmware(machine, BIOS_FILENAME,
|
||||
memmap[SPIKE_DRAM].base,
|
||||
htif_symbol_callback);
|
||||
/*
|
||||
* Not like other RISC-V machines that use plain binary bios images,
|
||||
* keeping ELF files here was intentional because BIN files don't work
|
||||
* for the Spike machine as HTIF emulation depends on ELF parsing.
|
||||
*/
|
||||
if (riscv_is_32bit(s->soc[0])) {
|
||||
firmware_end_addr = riscv_find_and_load_firmware(machine,
|
||||
"opensbi-riscv32-generic-fw_dynamic.elf",
|
||||
memmap[SPIKE_DRAM].base,
|
||||
htif_symbol_callback);
|
||||
} else {
|
||||
firmware_end_addr = riscv_find_and_load_firmware(machine,
|
||||
"opensbi-riscv64-generic-fw_dynamic.elf",
|
||||
memmap[SPIKE_DRAM].base,
|
||||
htif_symbol_callback);
|
||||
}
|
||||
|
||||
if (machine->kernel_filename) {
|
||||
kernel_start_addr = riscv_calc_kernel_start_addr(machine,
|
||||
kernel_start_addr = riscv_calc_kernel_start_addr(s->soc[0],
|
||||
firmware_end_addr);
|
||||
|
||||
kernel_entry = riscv_load_kernel(machine->kernel_filename,
|
||||
|
@ -296,7 +299,8 @@ static void spike_board_init(MachineState *machine)
|
|||
fdt_load_addr = riscv_load_fdt(memmap[SPIKE_DRAM].base,
|
||||
machine->ram_size, s->fdt);
|
||||
/* load the reset vector */
|
||||
riscv_setup_rom_reset_vec(memmap[SPIKE_DRAM].base, memmap[SPIKE_MROM].base,
|
||||
riscv_setup_rom_reset_vec(machine, s->soc[0], memmap[SPIKE_DRAM].base,
|
||||
memmap[SPIKE_MROM].base,
|
||||
memmap[SPIKE_MROM].size, kernel_entry,
|
||||
fdt_load_addr, s->fdt);
|
||||
|
||||
|
@ -317,7 +321,7 @@ static void spike_machine_class_init(ObjectClass *oc, void *data)
|
|||
mc->init = spike_board_init;
|
||||
mc->max_cpus = SPIKE_CPUS_MAX;
|
||||
mc->is_default = true;
|
||||
mc->default_cpu_type = SPIKE_V1_10_0_CPU;
|
||||
mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
|
||||
mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids;
|
||||
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
|
||||
mc->get_default_cpu_node_id = riscv_numa_get_default_cpu_node_id;
|
||||
|
|
|
@ -43,12 +43,6 @@
|
|||
#include "hw/pci/pci.h"
|
||||
#include "hw/pci-host/gpex.h"
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
# define BIOS_FILENAME "opensbi-riscv32-generic-fw_dynamic.bin"
|
||||
#else
|
||||
# define BIOS_FILENAME "opensbi-riscv64-generic-fw_dynamic.bin"
|
||||
#endif
|
||||
|
||||
static const struct MemmapEntry {
|
||||
hwaddr base;
|
||||
hwaddr size;
|
||||
|
@ -177,7 +171,7 @@ static void create_pcie_irq_map(void *fdt, char *nodename,
|
|||
}
|
||||
|
||||
static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
|
||||
uint64_t mem_size, const char *cmdline)
|
||||
uint64_t mem_size, const char *cmdline, bool is_32_bit)
|
||||
{
|
||||
void *fdt;
|
||||
int i, cpu, socket;
|
||||
|
@ -240,11 +234,11 @@ static void create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
|
|||
cpu_name = g_strdup_printf("/cpus/cpu@%d",
|
||||
s->soc[socket].hartid_base + cpu);
|
||||
qemu_fdt_add_subnode(fdt, cpu_name);
|
||||
#if defined(TARGET_RISCV32)
|
||||
qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32");
|
||||
#else
|
||||
qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
|
||||
#endif
|
||||
if (is_32_bit) {
|
||||
qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv32");
|
||||
} else {
|
||||
qemu_fdt_setprop_string(fdt, cpu_name, "mmu-type", "riscv,sv48");
|
||||
}
|
||||
name = riscv_isa_string(&s->soc[socket].harts[cpu]);
|
||||
qemu_fdt_setprop_string(fdt, cpu_name, "riscv,isa", name);
|
||||
g_free(name);
|
||||
|
@ -606,7 +600,8 @@ static void virt_machine_init(MachineState *machine)
|
|||
main_mem);
|
||||
|
||||
/* create device tree */
|
||||
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline);
|
||||
create_fdt(s, memmap, machine->ram_size, machine->kernel_cmdline,
|
||||
riscv_is_32bit(s->soc[0]));
|
||||
|
||||
/* boot rom */
|
||||
memory_region_init_rom(mask_rom, NULL, "riscv_virt_board.mrom",
|
||||
|
@ -614,11 +609,18 @@ static void virt_machine_init(MachineState *machine)
|
|||
memory_region_add_subregion(system_memory, memmap[VIRT_MROM].base,
|
||||
mask_rom);
|
||||
|
||||
firmware_end_addr = riscv_find_and_load_firmware(machine, BIOS_FILENAME,
|
||||
start_addr, NULL);
|
||||
if (riscv_is_32bit(s->soc[0])) {
|
||||
firmware_end_addr = riscv_find_and_load_firmware(machine,
|
||||
"opensbi-riscv32-generic-fw_dynamic.bin",
|
||||
start_addr, NULL);
|
||||
} else {
|
||||
firmware_end_addr = riscv_find_and_load_firmware(machine,
|
||||
"opensbi-riscv64-generic-fw_dynamic.bin",
|
||||
start_addr, NULL);
|
||||
}
|
||||
|
||||
if (machine->kernel_filename) {
|
||||
kernel_start_addr = riscv_calc_kernel_start_addr(machine,
|
||||
kernel_start_addr = riscv_calc_kernel_start_addr(s->soc[0],
|
||||
firmware_end_addr);
|
||||
|
||||
kernel_entry = riscv_load_kernel(machine->kernel_filename,
|
||||
|
@ -654,7 +656,8 @@ static void virt_machine_init(MachineState *machine)
|
|||
fdt_load_addr = riscv_load_fdt(memmap[VIRT_DRAM].base,
|
||||
machine->ram_size, s->fdt);
|
||||
/* load the reset vector */
|
||||
riscv_setup_rom_reset_vec(start_addr, virt_memmap[VIRT_MROM].base,
|
||||
riscv_setup_rom_reset_vec(machine, s->soc[0], start_addr,
|
||||
virt_memmap[VIRT_MROM].base,
|
||||
virt_memmap[VIRT_MROM].size, kernel_entry,
|
||||
fdt_load_addr, s->fdt);
|
||||
|
||||
|
@ -704,7 +707,7 @@ static void virt_machine_class_init(ObjectClass *oc, void *data)
|
|||
mc->desc = "RISC-V VirtIO board";
|
||||
mc->init = virt_machine_init;
|
||||
mc->max_cpus = VIRT_CPUS_MAX;
|
||||
mc->default_cpu_type = VIRT_CPU;
|
||||
mc->default_cpu_type = TYPE_RISCV_CPU_BASE;
|
||||
mc->pci_allow_0_address = true;
|
||||
mc->possible_cpu_arch_ids = riscv_numa_possible_cpu_arch_ids;
|
||||
mc->cpu_index_to_instance_props = riscv_numa_cpu_index_to_props;
|
||||
|
|
|
@ -22,10 +22,11 @@
|
|||
|
||||
#include "exec/cpu-defs.h"
|
||||
#include "hw/loader.h"
|
||||
#include "hw/riscv/riscv_hart.h"
|
||||
|
||||
bool riscv_is_32_bit(MachineState *machine);
|
||||
bool riscv_is_32bit(RISCVHartArrayState harts);
|
||||
|
||||
target_ulong riscv_calc_kernel_start_addr(MachineState *machine,
|
||||
target_ulong riscv_calc_kernel_start_addr(RISCVHartArrayState harts,
|
||||
target_ulong firmware_end_addr);
|
||||
target_ulong riscv_find_and_load_firmware(MachineState *machine,
|
||||
const char *default_machine_firmware,
|
||||
|
@ -41,10 +42,13 @@ target_ulong riscv_load_kernel(const char *kernel_filename,
|
|||
hwaddr riscv_load_initrd(const char *filename, uint64_t mem_size,
|
||||
uint64_t kernel_entry, hwaddr *start);
|
||||
uint32_t riscv_load_fdt(hwaddr dram_start, uint64_t dram_size, void *fdt);
|
||||
void riscv_setup_rom_reset_vec(hwaddr saddr, hwaddr rom_base,
|
||||
hwaddr rom_size, uint64_t kernel_entry,
|
||||
void riscv_setup_rom_reset_vec(MachineState *machine, RISCVHartArrayState harts,
|
||||
hwaddr saddr,
|
||||
hwaddr rom_base, hwaddr rom_size,
|
||||
uint64_t kernel_entry,
|
||||
uint32_t fdt_load_addr, void *fdt);
|
||||
void riscv_rom_copy_firmware_info(hwaddr rom_base, hwaddr rom_size,
|
||||
void riscv_rom_copy_firmware_info(MachineState *machine, hwaddr rom_base,
|
||||
hwaddr rom_size,
|
||||
uint32_t reset_vec_size,
|
||||
uint64_t kernel_entry);
|
||||
|
||||
|
|
|
@ -97,6 +97,8 @@ enum {
|
|||
MICROCHIP_PFSOC_MMUART2,
|
||||
MICROCHIP_PFSOC_MMUART3,
|
||||
MICROCHIP_PFSOC_MMUART4,
|
||||
MICROCHIP_PFSOC_SPI0,
|
||||
MICROCHIP_PFSOC_SPI1,
|
||||
MICROCHIP_PFSOC_I2C1,
|
||||
MICROCHIP_PFSOC_GEM0,
|
||||
MICROCHIP_PFSOC_GEM1,
|
||||
|
@ -105,6 +107,7 @@ enum {
|
|||
MICROCHIP_PFSOC_GPIO2,
|
||||
MICROCHIP_PFSOC_ENVM_CFG,
|
||||
MICROCHIP_PFSOC_ENVM_DATA,
|
||||
MICROCHIP_PFSOC_QSPI_XIP,
|
||||
MICROCHIP_PFSOC_IOSCB,
|
||||
MICROCHIP_PFSOC_DRAM_LO,
|
||||
MICROCHIP_PFSOC_DRAM_LO_ALIAS,
|
||||
|
|
|
@ -55,19 +55,30 @@ enum {
|
|||
IBEX_DEV_UART,
|
||||
IBEX_DEV_GPIO,
|
||||
IBEX_DEV_SPI,
|
||||
IBEX_DEV_FLASH_CTRL,
|
||||
IBEX_DEV_I2C,
|
||||
IBEX_DEV_PATTGEN,
|
||||
IBEX_DEV_RV_TIMER,
|
||||
IBEX_DEV_AES,
|
||||
IBEX_DEV_HMAC,
|
||||
IBEX_DEV_PLIC,
|
||||
IBEX_DEV_SENSOR_CTRL,
|
||||
IBEX_DEV_OTP_CTRL,
|
||||
IBEX_DEV_PWRMGR,
|
||||
IBEX_DEV_RSTMGR,
|
||||
IBEX_DEV_CLKMGR,
|
||||
IBEX_DEV_PINMUX,
|
||||
IBEX_DEV_PADCTRL,
|
||||
IBEX_DEV_USBDEV,
|
||||
IBEX_DEV_FLASH_CTRL,
|
||||
IBEX_DEV_PLIC,
|
||||
IBEX_DEV_AES,
|
||||
IBEX_DEV_HMAC,
|
||||
IBEX_DEV_KMAC,
|
||||
IBEX_DEV_KEYMGR,
|
||||
IBEX_DEV_CSRNG,
|
||||
IBEX_DEV_ENTROPY,
|
||||
IBEX_DEV_EDNO,
|
||||
IBEX_DEV_EDN1,
|
||||
IBEX_DEV_ALERT_HANDLER,
|
||||
IBEX_DEV_NMI_GEN,
|
||||
IBEX_DEV_USBDEV,
|
||||
IBEX_DEV_PADCTRL,
|
||||
IBEX_DEV_OTBN,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
|
|
@ -47,10 +47,4 @@ enum {
|
|||
SPIKE_DRAM
|
||||
};
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
#define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_BASE32
|
||||
#elif defined(TARGET_RISCV64)
|
||||
#define SPIKE_V1_10_0_CPU TYPE_RISCV_CPU_BASE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -89,10 +89,4 @@ enum {
|
|||
#define FDT_INT_MAP_WIDTH (FDT_PCI_ADDR_CELLS + FDT_PCI_INT_CELLS + 1 + \
|
||||
FDT_PLIC_ADDR_CELLS + FDT_PLIC_INT_CELLS)
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
#define VIRT_CPU TYPE_RISCV_CPU_BASE32
|
||||
#elif defined(TARGET_RISCV64)
|
||||
#define VIRT_CPU TYPE_RISCV_CPU_BASE64
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -108,6 +108,15 @@ const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
|
|||
}
|
||||
}
|
||||
|
||||
bool riscv_cpu_is_32bit(CPURISCVState *env)
|
||||
{
|
||||
if (env->misa & RV64) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void set_misa(CPURISCVState *env, target_ulong misa)
|
||||
{
|
||||
env->misa_mask = env->misa = misa;
|
||||
|
@ -142,29 +151,50 @@ static void riscv_any_cpu_init(Object *obj)
|
|||
set_priv_version(env, PRIV_VERSION_1_11_0);
|
||||
}
|
||||
|
||||
static void riscv_base_cpu_init(Object *obj)
|
||||
#if defined(TARGET_RISCV64)
|
||||
static void rv64_base_cpu_init(Object *obj)
|
||||
{
|
||||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
/* We set this in the realise function */
|
||||
set_misa(env, 0);
|
||||
set_misa(env, RV64);
|
||||
}
|
||||
|
||||
static void rvxx_sifive_u_cpu_init(Object *obj)
|
||||
static void rv64_sifive_u_cpu_init(Object *obj)
|
||||
{
|
||||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
set_misa(env, RVXLEN | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
||||
set_misa(env, RV64 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
||||
set_priv_version(env, PRIV_VERSION_1_10_0);
|
||||
}
|
||||
|
||||
static void rvxx_sifive_e_cpu_init(Object *obj)
|
||||
static void rv64_sifive_e_cpu_init(Object *obj)
|
||||
{
|
||||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
set_misa(env, RVXLEN | RVI | RVM | RVA | RVC | RVU);
|
||||
set_misa(env, RV64 | RVI | RVM | RVA | RVC | RVU);
|
||||
set_priv_version(env, PRIV_VERSION_1_10_0);
|
||||
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
||||
}
|
||||
#else
|
||||
static void rv32_base_cpu_init(Object *obj)
|
||||
{
|
||||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
/* We set this in the realise function */
|
||||
set_misa(env, RV32);
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
static void rv32_sifive_u_cpu_init(Object *obj)
|
||||
{
|
||||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
set_misa(env, RV32 | RVI | RVM | RVA | RVF | RVD | RVC | RVS | RVU);
|
||||
set_priv_version(env, PRIV_VERSION_1_10_0);
|
||||
}
|
||||
|
||||
static void rv32_sifive_e_cpu_init(Object *obj)
|
||||
{
|
||||
CPURISCVState *env = &RISCV_CPU(obj)->env;
|
||||
set_misa(env, RV32 | RVI | RVM | RVA | RVC | RVU);
|
||||
set_priv_version(env, PRIV_VERSION_1_10_0);
|
||||
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
||||
}
|
||||
|
||||
static void rv32_ibex_cpu_init(Object *obj)
|
||||
{
|
||||
|
@ -182,7 +212,6 @@ static void rv32_imafcu_nommu_cpu_init(Object *obj)
|
|||
set_resetvec(env, DEFAULT_RSTVEC);
|
||||
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
static ObjectClass *riscv_cpu_class_by_name(const char *cpu_model)
|
||||
|
@ -218,10 +247,10 @@ static void riscv_cpu_dump_state(CPUState *cs, FILE *f, int flags)
|
|||
#ifndef CONFIG_USER_ONLY
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mhartid ", env->mhartid);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatus ", (target_ulong)env->mstatus);
|
||||
#ifdef TARGET_RISCV32
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
|
||||
(target_ulong)(env->mstatus >> 32));
|
||||
#endif
|
||||
if (riscv_cpu_is_32bit(env)) {
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "mstatush ",
|
||||
(target_ulong)(env->mstatus >> 32));
|
||||
}
|
||||
if (riscv_has_ext(env, RVH)) {
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "hstatus ", env->hstatus);
|
||||
qemu_fprintf(f, " %s " TARGET_FMT_lx "\n", "vsstatus ",
|
||||
|
@ -334,11 +363,12 @@ static void riscv_cpu_reset(DeviceState *dev)
|
|||
|
||||
static void riscv_cpu_disas_set_info(CPUState *s, disassemble_info *info)
|
||||
{
|
||||
#if defined(TARGET_RISCV32)
|
||||
info->print_insn = print_insn_riscv32;
|
||||
#elif defined(TARGET_RISCV64)
|
||||
info->print_insn = print_insn_riscv64;
|
||||
#endif
|
||||
RISCVCPU *cpu = RISCV_CPU(s);
|
||||
if (riscv_cpu_is_32bit(&cpu->env)) {
|
||||
info->print_insn = print_insn_riscv32;
|
||||
} else {
|
||||
info->print_insn = print_insn_riscv64;
|
||||
}
|
||||
}
|
||||
|
||||
static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
||||
|
@ -349,7 +379,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|||
RISCVCPUClass *mcc = RISCV_CPU_GET_CLASS(dev);
|
||||
int priv_version = PRIV_VERSION_1_11_0;
|
||||
int vext_version = VEXT_VERSION_0_07_1;
|
||||
target_ulong target_misa = 0;
|
||||
target_ulong target_misa = env->misa;
|
||||
Error *local_err = NULL;
|
||||
|
||||
cpu_exec_realizefn(cs, &local_err);
|
||||
|
@ -384,8 +414,8 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|||
|
||||
set_resetvec(env, cpu->cfg.resetvec);
|
||||
|
||||
/* If misa isn't set (rv32 and rv64 machines) set it here */
|
||||
if (!env->misa) {
|
||||
/* If only XLEN is set for misa, then set misa from properties */
|
||||
if (env->misa == RV32 || env->misa == RV64) {
|
||||
/* Do some ISA extension error checking */
|
||||
if (cpu->cfg.ext_i && cpu->cfg.ext_e) {
|
||||
error_setg(errp,
|
||||
|
@ -481,7 +511,7 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
|
|||
set_vext_version(env, vext_version);
|
||||
}
|
||||
|
||||
set_misa(env, RVXLEN | target_misa);
|
||||
set_misa(env, target_misa);
|
||||
}
|
||||
|
||||
riscv_cpu_register_gdb_regs_for_features(cs);
|
||||
|
@ -632,15 +662,15 @@ static const TypeInfo riscv_cpu_type_infos[] = {
|
|||
},
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_ANY, riscv_any_cpu_init),
|
||||
#if defined(TARGET_RISCV32)
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, riscv_base_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_BASE32, rv32_base_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_IBEX, rv32_ibex_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rvxx_sifive_e_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E31, rv32_sifive_e_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E34, rv32_imafcu_nommu_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rvxx_sifive_u_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U34, rv32_sifive_u_cpu_init),
|
||||
#elif defined(TARGET_RISCV64)
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, riscv_base_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rvxx_sifive_e_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rvxx_sifive_u_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_BASE64, rv64_base_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_E51, rv64_sifive_e_cpu_init),
|
||||
DEFINE_CPU(TYPE_RISCV_CPU_SIFIVE_U54, rv64_sifive_u_cpu_init),
|
||||
#endif
|
||||
};
|
||||
|
||||
|
|
|
@ -44,6 +44,12 @@
|
|||
#define TYPE_RISCV_CPU_SIFIVE_U34 RISCV_CPU_TYPE_NAME("sifive-u34")
|
||||
#define TYPE_RISCV_CPU_SIFIVE_U54 RISCV_CPU_TYPE_NAME("sifive-u54")
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE32
|
||||
#elif defined(TARGET_RISCV64)
|
||||
# define TYPE_RISCV_CPU_BASE TYPE_RISCV_CPU_BASE64
|
||||
#endif
|
||||
|
||||
#define RV32 ((target_ulong)1 << (TARGET_LONG_BITS - 2))
|
||||
#define RV64 ((target_ulong)2 << (TARGET_LONG_BITS - 2))
|
||||
|
||||
|
@ -378,6 +384,8 @@ FIELD(TB_FLAGS, VILL, 8, 1)
|
|||
/* Is a Hypervisor instruction load/store allowed? */
|
||||
FIELD(TB_FLAGS, HLSX, 9, 1)
|
||||
|
||||
bool riscv_cpu_is_32bit(CPURISCVState *env);
|
||||
|
||||
/*
|
||||
* A simplification for VLMAX
|
||||
* = (1 << LMUL) * VLEN / (8 * (1 << SEW))
|
||||
|
|
|
@ -379,8 +379,8 @@
|
|||
#define MSTATUS_MXR 0x00080000
|
||||
#define MSTATUS_VM 0x1F000000 /* until: priv-1.9.1 */
|
||||
#define MSTATUS_TVM 0x00100000 /* since: priv-1.10 */
|
||||
#define MSTATUS_TW 0x20000000 /* since: priv-1.10 */
|
||||
#define MSTATUS_TSR 0x40000000 /* since: priv-1.10 */
|
||||
#define MSTATUS_TW 0x00200000 /* since: priv-1.10 */
|
||||
#define MSTATUS_TSR 0x00400000 /* since: priv-1.10 */
|
||||
#define MSTATUS_GVA 0x4000000000ULL
|
||||
#define MSTATUS_MPV 0x8000000000ULL
|
||||
|
||||
|
@ -437,9 +437,7 @@
|
|||
#define HSTATUS_VGEIN 0x0003F000
|
||||
#define HSTATUS_VTVM 0x00100000
|
||||
#define HSTATUS_VTSR 0x00400000
|
||||
#if defined(TARGET_RISCV64)
|
||||
#define HSTATUS_VSXL 0x300000000
|
||||
#endif
|
||||
#define HSTATUS_VSXL 0x300000000
|
||||
|
||||
#define HSTATUS32_WPRI 0xFF8FF87E
|
||||
#define HSTATUS64_WPRI 0xFFFFFFFFFF8FF87EULL
|
||||
|
|
|
@ -367,7 +367,8 @@ static int get_physical_address(CPURISCVState *env, hwaddr *physical,
|
|||
vm = get_field(env->hgatp, HGATP_MODE);
|
||||
widened = 2;
|
||||
}
|
||||
sum = get_field(env->mstatus, MSTATUS_SUM);
|
||||
/* status.SUM will be ignored if execute on background */
|
||||
sum = get_field(env->mstatus, MSTATUS_SUM) || use_background;
|
||||
switch (vm) {
|
||||
case VM_1_10_SV32:
|
||||
levels = 2; ptidxbits = 10; ptesize = 4; break;
|
||||
|
@ -446,11 +447,13 @@ restart:
|
|||
return TRANSLATE_PMP_FAIL;
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
target_ulong pte = address_space_ldl(cs->as, pte_addr, attrs, &res);
|
||||
#elif defined(TARGET_RISCV64)
|
||||
target_ulong pte = address_space_ldq(cs->as, pte_addr, attrs, &res);
|
||||
#endif
|
||||
target_ulong pte;
|
||||
if (riscv_cpu_is_32bit(env)) {
|
||||
pte = address_space_ldl(cs->as, pte_addr, attrs, &res);
|
||||
} else {
|
||||
pte = address_space_ldq(cs->as, pte_addr, attrs, &res);
|
||||
}
|
||||
|
||||
if (res != MEMTX_OK) {
|
||||
return TRANSLATE_FAIL;
|
||||
}
|
||||
|
|
|
@ -102,44 +102,65 @@ static int ctr(CPURISCVState *env, int csrno)
|
|||
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
break;
|
||||
#if defined(TARGET_RISCV32)
|
||||
case CSR_CYCLEH:
|
||||
if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
|
||||
get_field(env->mcounteren, HCOUNTEREN_CY)) {
|
||||
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
if (riscv_cpu_is_32bit(env)) {
|
||||
switch (csrno) {
|
||||
case CSR_CYCLEH:
|
||||
if (!get_field(env->hcounteren, HCOUNTEREN_CY) &&
|
||||
get_field(env->mcounteren, HCOUNTEREN_CY)) {
|
||||
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
break;
|
||||
case CSR_TIMEH:
|
||||
if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
|
||||
get_field(env->mcounteren, HCOUNTEREN_TM)) {
|
||||
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
break;
|
||||
case CSR_INSTRETH:
|
||||
if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
|
||||
get_field(env->mcounteren, HCOUNTEREN_IR)) {
|
||||
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
break;
|
||||
case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
|
||||
if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
|
||||
get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
|
||||
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CSR_TIMEH:
|
||||
if (!get_field(env->hcounteren, HCOUNTEREN_TM) &&
|
||||
get_field(env->mcounteren, HCOUNTEREN_TM)) {
|
||||
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
break;
|
||||
case CSR_INSTRETH:
|
||||
if (!get_field(env->hcounteren, HCOUNTEREN_IR) &&
|
||||
get_field(env->mcounteren, HCOUNTEREN_IR)) {
|
||||
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
break;
|
||||
case CSR_HPMCOUNTER3H...CSR_HPMCOUNTER31H:
|
||||
if (!get_field(env->hcounteren, 1 << (csrno - CSR_HPMCOUNTER3H)) &&
|
||||
get_field(env->mcounteren, 1 << (csrno - CSR_HPMCOUNTER3H))) {
|
||||
return -RISCV_EXCP_VIRT_INSTRUCTION_FAULT;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ctr32(CPURISCVState *env, int csrno)
|
||||
{
|
||||
if (!riscv_cpu_is_32bit(env)) {
|
||||
return -RISCV_EXCP_ILLEGAL_INST;
|
||||
}
|
||||
|
||||
return ctr(env, csrno);
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
static int any(CPURISCVState *env, int csrno)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int any32(CPURISCVState *env, int csrno)
|
||||
{
|
||||
if (!riscv_cpu_is_32bit(env)) {
|
||||
return -RISCV_EXCP_ILLEGAL_INST;
|
||||
}
|
||||
|
||||
return any(env, csrno);
|
||||
|
||||
}
|
||||
|
||||
static int smode(CPURISCVState *env, int csrno)
|
||||
{
|
||||
return -!riscv_has_ext(env, RVS);
|
||||
|
@ -161,6 +182,16 @@ static int hmode(CPURISCVState *env, int csrno)
|
|||
return -RISCV_EXCP_ILLEGAL_INST;
|
||||
}
|
||||
|
||||
static int hmode32(CPURISCVState *env, int csrno)
|
||||
{
|
||||
if (!riscv_cpu_is_32bit(env)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hmode(env, csrno);
|
||||
|
||||
}
|
||||
|
||||
static int pmp(CPURISCVState *env, int csrno)
|
||||
{
|
||||
return -!riscv_feature(env, RISCV_FEATURE_PMP);
|
||||
|
@ -310,7 +341,6 @@ static int read_instret(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
|
@ -324,7 +354,6 @@ static int read_instreth(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif /* TARGET_RISCV32 */
|
||||
|
||||
#if defined(CONFIG_USER_ONLY)
|
||||
static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
|
@ -333,13 +362,11 @@ static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
*val = cpu_get_host_ticks() >> 32;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else /* CONFIG_USER_ONLY */
|
||||
|
||||
|
@ -355,7 +382,6 @@ static int read_time(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
uint64_t delta = riscv_cpu_virt_enabled(env) ? env->htimedelta : 0;
|
||||
|
@ -367,7 +393,6 @@ static int read_timeh(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
*val = (env->rdtime_fn(env->rdtime_fn_arg) + delta) >> 32;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Machine constants */
|
||||
|
||||
|
@ -406,19 +431,17 @@ static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP;
|
|||
static const target_ulong hip_writable_mask = MIP_VSSIP | MIP_VSTIP | MIP_VSEIP;
|
||||
static const target_ulong vsip_writable_mask = MIP_VSSIP;
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
static const char valid_vm_1_10[16] = {
|
||||
static const char valid_vm_1_10_32[16] = {
|
||||
[VM_1_10_MBARE] = 1,
|
||||
[VM_1_10_SV32] = 1
|
||||
};
|
||||
#elif defined(TARGET_RISCV64)
|
||||
static const char valid_vm_1_10[16] = {
|
||||
|
||||
static const char valid_vm_1_10_64[16] = {
|
||||
[VM_1_10_MBARE] = 1,
|
||||
[VM_1_10_SV39] = 1,
|
||||
[VM_1_10_SV48] = 1,
|
||||
[VM_1_10_SV57] = 1
|
||||
};
|
||||
#endif /* CONFIG_USER_ONLY */
|
||||
|
||||
/* Machine Information Registers */
|
||||
static int read_zero(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
|
@ -441,7 +464,11 @@ static int read_mstatus(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
|
||||
static int validate_vm(CPURISCVState *env, target_ulong vm)
|
||||
{
|
||||
return valid_vm_1_10[vm & 0xf];
|
||||
if (riscv_cpu_is_32bit(env)) {
|
||||
return valid_vm_1_10_32[vm & 0xf];
|
||||
} else {
|
||||
return valid_vm_1_10_64[vm & 0xf];
|
||||
}
|
||||
}
|
||||
|
||||
static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
|
||||
|
@ -459,13 +486,14 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
|
|||
MSTATUS_SPP | MSTATUS_FS | MSTATUS_MPRV | MSTATUS_SUM |
|
||||
MSTATUS_MPP | MSTATUS_MXR | MSTATUS_TVM | MSTATUS_TSR |
|
||||
MSTATUS_TW;
|
||||
#if defined(TARGET_RISCV64)
|
||||
/*
|
||||
* RV32: MPV and GVA are not in mstatus. The current plan is to
|
||||
* add them to mstatush. For now, we just don't support it.
|
||||
*/
|
||||
mask |= MSTATUS_MPV | MSTATUS_GVA;
|
||||
#endif
|
||||
|
||||
if (!riscv_cpu_is_32bit(env)) {
|
||||
/*
|
||||
* RV32: MPV and GVA are not in mstatus. The current plan is to
|
||||
* add them to mstatush. For now, we just don't support it.
|
||||
*/
|
||||
mask |= MSTATUS_MPV | MSTATUS_GVA;
|
||||
}
|
||||
|
||||
mstatus = (mstatus & ~mask) | (val & mask);
|
||||
|
||||
|
@ -477,7 +505,6 @@ static int write_mstatus(CPURISCVState *env, int csrno, target_ulong val)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef TARGET_RISCV32
|
||||
static int read_mstatush(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
*val = env->mstatus >> 32;
|
||||
|
@ -497,7 +524,6 @@ static int write_mstatush(CPURISCVState *env, int csrno, target_ulong val)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int read_misa(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
|
@ -895,10 +921,10 @@ static int write_satp(CPURISCVState *env, int csrno, target_ulong val)
|
|||
static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
*val = env->hstatus;
|
||||
#ifdef TARGET_RISCV64
|
||||
/* We only support 64-bit VSXL */
|
||||
*val = set_field(*val, HSTATUS_VSXL, 2);
|
||||
#endif
|
||||
if (!riscv_cpu_is_32bit(env)) {
|
||||
/* We only support 64-bit VSXL */
|
||||
*val = set_field(*val, HSTATUS_VSXL, 2);
|
||||
}
|
||||
/* We only support little endian */
|
||||
*val = set_field(*val, HSTATUS_VSBE, 0);
|
||||
return 0;
|
||||
|
@ -907,11 +933,9 @@ static int read_hstatus(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
static int write_hstatus(CPURISCVState *env, int csrno, target_ulong val)
|
||||
{
|
||||
env->hstatus = val;
|
||||
#ifdef TARGET_RISCV64
|
||||
if (get_field(val, HSTATUS_VSXL) != 2) {
|
||||
if (!riscv_cpu_is_32bit(env) && get_field(val, HSTATUS_VSXL) != 2) {
|
||||
qemu_log_mask(LOG_UNIMP, "QEMU does not support mixed HSXLEN options.");
|
||||
}
|
||||
#endif
|
||||
if (get_field(val, HSTATUS_VSBE) != 0) {
|
||||
qemu_log_mask(LOG_UNIMP, "QEMU does not support big endian guests.");
|
||||
}
|
||||
|
@ -1053,11 +1077,7 @@ static int read_htimedelta(CPURISCVState *env, int csrno, target_ulong *val)
|
|||
return -RISCV_EXCP_ILLEGAL_INST;
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
*val = env->htimedelta & 0xffffffff;
|
||||
#else
|
||||
*val = env->htimedelta;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1067,15 +1087,14 @@ static int write_htimedelta(CPURISCVState *env, int csrno, target_ulong val)
|
|||
return -RISCV_EXCP_ILLEGAL_INST;
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
|
||||
#else
|
||||
env->htimedelta = val;
|
||||
#endif
|
||||
if (riscv_cpu_is_32bit(env)) {
|
||||
env->htimedelta = deposit64(env->htimedelta, 0, 32, (uint64_t)val);
|
||||
} else {
|
||||
env->htimedelta = val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
static int read_htimedeltah(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
{
|
||||
if (!env->rdtime_fn) {
|
||||
|
@ -1095,7 +1114,6 @@ static int write_htimedeltah(CPURISCVState *env, int csrno, target_ulong val)
|
|||
env->htimedelta = deposit64(env->htimedelta, 32, 32, (uint64_t)val);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Virtual CSR Registers */
|
||||
static int read_vsstatus(CPURISCVState *env, int csrno, target_ulong *val)
|
||||
|
@ -1374,26 +1392,20 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
|||
/* User Timers and Counters */
|
||||
[CSR_CYCLE] = { ctr, read_instret },
|
||||
[CSR_INSTRET] = { ctr, read_instret },
|
||||
#if defined(TARGET_RISCV32)
|
||||
[CSR_CYCLEH] = { ctr, read_instreth },
|
||||
[CSR_INSTRETH] = { ctr, read_instreth },
|
||||
#endif
|
||||
[CSR_CYCLEH] = { ctr32, read_instreth },
|
||||
[CSR_INSTRETH] = { ctr32, read_instreth },
|
||||
|
||||
/* In privileged mode, the monitor will have to emulate TIME CSRs only if
|
||||
* rdtime callback is not provided by machine/platform emulation */
|
||||
[CSR_TIME] = { ctr, read_time },
|
||||
#if defined(TARGET_RISCV32)
|
||||
[CSR_TIMEH] = { ctr, read_timeh },
|
||||
#endif
|
||||
[CSR_TIMEH] = { ctr32, read_timeh },
|
||||
|
||||
#if !defined(CONFIG_USER_ONLY)
|
||||
/* Machine Timers and Counters */
|
||||
[CSR_MCYCLE] = { any, read_instret },
|
||||
[CSR_MINSTRET] = { any, read_instret },
|
||||
#if defined(TARGET_RISCV32)
|
||||
[CSR_MCYCLEH] = { any, read_instreth },
|
||||
[CSR_MINSTRETH] = { any, read_instreth },
|
||||
#endif
|
||||
[CSR_MCYCLEH] = { any32, read_instreth },
|
||||
[CSR_MINSTRETH] = { any32, read_instreth },
|
||||
|
||||
/* Machine Information Registers */
|
||||
[CSR_MVENDORID] = { any, read_zero },
|
||||
|
@ -1410,9 +1422,7 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
|||
[CSR_MTVEC] = { any, read_mtvec, write_mtvec },
|
||||
[CSR_MCOUNTEREN] = { any, read_mcounteren, write_mcounteren },
|
||||
|
||||
#if defined(TARGET_RISCV32)
|
||||
[CSR_MSTATUSH] = { any, read_mstatush, write_mstatush },
|
||||
#endif
|
||||
[CSR_MSTATUSH] = { any32, read_mstatush, write_mstatush },
|
||||
|
||||
[CSR_MSCOUNTEREN] = { any, read_mscounteren, write_mscounteren },
|
||||
|
||||
|
@ -1452,9 +1462,7 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
|||
[CSR_HGEIP] = { hmode, read_hgeip, write_hgeip },
|
||||
[CSR_HGATP] = { hmode, read_hgatp, write_hgatp },
|
||||
[CSR_HTIMEDELTA] = { hmode, read_htimedelta, write_htimedelta },
|
||||
#if defined(TARGET_RISCV32)
|
||||
[CSR_HTIMEDELTAH] = { hmode, read_htimedeltah, write_htimedeltah},
|
||||
#endif
|
||||
[CSR_HTIMEDELTAH] = { hmode32, read_htimedeltah, write_htimedeltah},
|
||||
|
||||
[CSR_VSSTATUS] = { hmode, read_vsstatus, write_vsstatus },
|
||||
[CSR_VSIP] = { hmode, NULL, NULL, rmw_vsip },
|
||||
|
@ -1477,9 +1485,7 @@ static riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
|
|||
[CSR_HPMCOUNTER3 ... CSR_HPMCOUNTER31] = { ctr, read_zero },
|
||||
[CSR_MHPMCOUNTER3 ... CSR_MHPMCOUNTER31] = { any, read_zero },
|
||||
[CSR_MHPMEVENT3 ... CSR_MHPMEVENT31] = { any, read_zero },
|
||||
#if defined(TARGET_RISCV32)
|
||||
[CSR_HPMCOUNTER3H ... CSR_HPMCOUNTER31H] = { ctr, read_zero },
|
||||
[CSR_MHPMCOUNTER3H ... CSR_MHPMCOUNTER31H] = { any, read_zero },
|
||||
#endif
|
||||
[CSR_HPMCOUNTER3H ... CSR_HPMCOUNTER31H] = { ctr32, read_zero },
|
||||
[CSR_MHPMCOUNTER3H ... CSR_MHPMCOUNTER31H] = { any32, read_zero },
|
||||
#endif /* !CONFIG_USER_ONLY */
|
||||
};
|
||||
|
|
|
@ -223,7 +223,6 @@ target_ulong helper_fcvt_wu_s(CPURISCVState *env, uint64_t rs1)
|
|||
return (int32_t)float32_to_uint32(frs1, &env->fp_status);
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV64)
|
||||
uint64_t helper_fcvt_l_s(CPURISCVState *env, uint64_t rs1)
|
||||
{
|
||||
float32 frs1 = check_nanbox_s(rs1);
|
||||
|
@ -235,7 +234,6 @@ uint64_t helper_fcvt_lu_s(CPURISCVState *env, uint64_t rs1)
|
|||
float32 frs1 = check_nanbox_s(rs1);
|
||||
return float32_to_uint64(frs1, &env->fp_status);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint64_t helper_fcvt_s_w(CPURISCVState *env, target_ulong rs1)
|
||||
{
|
||||
|
@ -247,7 +245,6 @@ uint64_t helper_fcvt_s_wu(CPURISCVState *env, target_ulong rs1)
|
|||
return nanbox_s(uint32_to_float32((uint32_t)rs1, &env->fp_status));
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV64)
|
||||
uint64_t helper_fcvt_s_l(CPURISCVState *env, uint64_t rs1)
|
||||
{
|
||||
return nanbox_s(int64_to_float32(rs1, &env->fp_status));
|
||||
|
@ -257,7 +254,6 @@ uint64_t helper_fcvt_s_lu(CPURISCVState *env, uint64_t rs1)
|
|||
{
|
||||
return nanbox_s(uint64_to_float32(rs1, &env->fp_status));
|
||||
}
|
||||
#endif
|
||||
|
||||
target_ulong helper_fclass_s(uint64_t rs1)
|
||||
{
|
||||
|
@ -336,7 +332,6 @@ target_ulong helper_fcvt_wu_d(CPURISCVState *env, uint64_t frs1)
|
|||
return (int32_t)float64_to_uint32(frs1, &env->fp_status);
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV64)
|
||||
uint64_t helper_fcvt_l_d(CPURISCVState *env, uint64_t frs1)
|
||||
{
|
||||
return float64_to_int64(frs1, &env->fp_status);
|
||||
|
@ -346,7 +341,6 @@ uint64_t helper_fcvt_lu_d(CPURISCVState *env, uint64_t frs1)
|
|||
{
|
||||
return float64_to_uint64(frs1, &env->fp_status);
|
||||
}
|
||||
#endif
|
||||
|
||||
uint64_t helper_fcvt_d_w(CPURISCVState *env, target_ulong rs1)
|
||||
{
|
||||
|
@ -358,7 +352,6 @@ uint64_t helper_fcvt_d_wu(CPURISCVState *env, target_ulong rs1)
|
|||
return uint32_to_float64((uint32_t)rs1, &env->fp_status);
|
||||
}
|
||||
|
||||
#if defined(TARGET_RISCV64)
|
||||
uint64_t helper_fcvt_d_l(CPURISCVState *env, uint64_t rs1)
|
||||
{
|
||||
return int64_to_float64(rs1, &env->fp_status);
|
||||
|
@ -368,7 +361,6 @@ uint64_t helper_fcvt_d_lu(CPURISCVState *env, uint64_t rs1)
|
|||
{
|
||||
return uint64_to_float64(rs1, &env->fp_status);
|
||||
}
|
||||
#endif
|
||||
|
||||
target_ulong helper_fclass_d(uint64_t frs1)
|
||||
{
|
||||
|
|
|
@ -27,16 +27,12 @@ DEF_HELPER_FLAGS_3(flt_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
|
|||
DEF_HELPER_FLAGS_3(feq_s, TCG_CALL_NO_RWG, tl, env, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_w_s, TCG_CALL_NO_RWG, tl, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_wu_s, TCG_CALL_NO_RWG, tl, env, i64)
|
||||
#if defined(TARGET_RISCV64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_l_s, TCG_CALL_NO_RWG, tl, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_lu_s, TCG_CALL_NO_RWG, tl, env, i64)
|
||||
#endif
|
||||
DEF_HELPER_FLAGS_2(fcvt_l_s, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_lu_s, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_s_w, TCG_CALL_NO_RWG, i64, env, tl)
|
||||
DEF_HELPER_FLAGS_2(fcvt_s_wu, TCG_CALL_NO_RWG, i64, env, tl)
|
||||
#if defined(TARGET_RISCV64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_s_l, TCG_CALL_NO_RWG, i64, env, tl)
|
||||
DEF_HELPER_FLAGS_2(fcvt_s_lu, TCG_CALL_NO_RWG, i64, env, tl)
|
||||
#endif
|
||||
DEF_HELPER_FLAGS_2(fcvt_s_l, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_s_lu, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_1(fclass_s, TCG_CALL_NO_RWG_SE, tl, i64)
|
||||
|
||||
/* Floating Point - Double Precision */
|
||||
|
@ -54,16 +50,12 @@ DEF_HELPER_FLAGS_3(flt_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
|
|||
DEF_HELPER_FLAGS_3(feq_d, TCG_CALL_NO_RWG, tl, env, i64, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_w_d, TCG_CALL_NO_RWG, tl, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_wu_d, TCG_CALL_NO_RWG, tl, env, i64)
|
||||
#if defined(TARGET_RISCV64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_l_d, TCG_CALL_NO_RWG, tl, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_lu_d, TCG_CALL_NO_RWG, tl, env, i64)
|
||||
#endif
|
||||
DEF_HELPER_FLAGS_2(fcvt_l_d, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_lu_d, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_d_w, TCG_CALL_NO_RWG, i64, env, tl)
|
||||
DEF_HELPER_FLAGS_2(fcvt_d_wu, TCG_CALL_NO_RWG, i64, env, tl)
|
||||
#if defined(TARGET_RISCV64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_d_l, TCG_CALL_NO_RWG, i64, env, tl)
|
||||
DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, tl)
|
||||
#endif
|
||||
DEF_HELPER_FLAGS_2(fcvt_d_l, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_2(fcvt_d_lu, TCG_CALL_NO_RWG, i64, env, i64)
|
||||
DEF_HELPER_FLAGS_1(fclass_d, TCG_CALL_NO_RWG_SE, tl, i64)
|
||||
|
||||
/* Special functions */
|
||||
|
|
Loading…
Reference in New Issue