diff options
author | Peter Maydell <peter.maydell@linaro.org> | 2021-09-01 08:33:02 +0100 |
---|---|---|
committer | Peter Maydell <peter.maydell@linaro.org> | 2021-09-01 08:33:02 +0100 |
commit | ec397e90d21269037280633b6058d1f280e27667 (patch) | |
tree | 2524ceef0aec4dac7564a2287e02d6185e61963a /hw | |
parent | d52dff5d8048d4982437db9606c27bb4127cf9d0 (diff) | |
parent | 8e034ae44dba6291beb07f7f2a932c1e5ab83e98 (diff) | |
download | qemu-ec397e90d21269037280633b6058d1f280e27667.zip qemu-ec397e90d21269037280633b6058d1f280e27667.tar.gz qemu-ec397e90d21269037280633b6058d1f280e27667.tar.bz2 |
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20210901-2' into staging
First RISC-V PR for QEMU 6.2
- Add a config for Shakti UART
- Fixup virt flash node
- Don't override users supplied ISA version
- Fixup some CSR accesses
- Use g_strjoinv() for virt machine PLIC string config
- Fix an overflow in the SiFive CLINT
- Add 64-bit register access helpers
- Replace tcg_const_* with direct constant usage
# gpg: Signature made Wed 01 Sep 2021 03:08:48 BST
# 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-20210901-2: (33 commits)
target/riscv: Use {get,dest}_gpr for RVV
target/riscv: Tidy trans_rvh.c.inc
target/riscv: Use {get,dest}_gpr for RVD
target/riscv: Use {get,dest}_gpr for RVF
target/riscv: Use gen_shift_imm_fn for slli_uw
target/riscv: Use {get,dest}_gpr for RVA
target/riscv: Reorg csr instructions
target/riscv: Fix hgeie, hgeip
target/riscv: Fix rmw_sip, rmw_vsip, rmw_hsip vs write-only operation
target/riscv: Use {get, dest}_gpr for integer load/store
target/riscv: Use get_gpr in branches
target/riscv: Use extracts for sraiw and srliw
target/riscv: Use DisasExtend in shift operations
target/riscv: Add DisasExtend to gen_unary
target/riscv: Move gen_* helpers for RVB
target/riscv: Move gen_* helpers for RVM
target/riscv: Use gen_arith for mulh and mulhu
target/riscv: Remove gen_arith_div*
target/riscv: Add DisasExtend to gen_arith*
target/riscv: Introduce DisasExtend and new helpers
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw')
-rw-r--r-- | hw/char/Kconfig | 3 | ||||
-rw-r--r-- | hw/char/meson.build | 2 | ||||
-rw-r--r-- | hw/core/register.c | 12 | ||||
-rw-r--r-- | hw/intc/sifive_clint.c | 25 | ||||
-rw-r--r-- | hw/riscv/Kconfig | 5 | ||||
-rw-r--r-- | hw/riscv/virt.c | 35 |
6 files changed, 61 insertions, 21 deletions
diff --git a/hw/char/Kconfig b/hw/char/Kconfig index 2e4f620b..6b6cf2f 100644 --- a/hw/char/Kconfig +++ b/hw/char/Kconfig @@ -68,3 +68,6 @@ config SIFIVE_UART config GOLDFISH_TTY bool + +config SHAKTI_UART + bool diff --git a/hw/char/meson.build b/hw/char/meson.build index 8361d0a..7b594f5 100644 --- a/hw/char/meson.build +++ b/hw/char/meson.build @@ -16,7 +16,7 @@ softmmu_ss.add(when: 'CONFIG_SERIAL', if_true: files('serial.c')) softmmu_ss.add(when: 'CONFIG_SERIAL_ISA', if_true: files('serial-isa.c')) softmmu_ss.add(when: 'CONFIG_SERIAL_PCI', if_true: files('serial-pci.c')) softmmu_ss.add(when: 'CONFIG_SERIAL_PCI_MULTI', if_true: files('serial-pci-multi.c')) -softmmu_ss.add(when: 'CONFIG_SHAKTI', if_true: files('shakti_uart.c')) +softmmu_ss.add(when: 'CONFIG_SHAKTI_UART', if_true: files('shakti_uart.c')) softmmu_ss.add(when: 'CONFIG_VIRTIO_SERIAL', if_true: files('virtio-console.c')) softmmu_ss.add(when: 'CONFIG_XEN', if_true: files('xen_console.c')) softmmu_ss.add(when: 'CONFIG_XILINX', if_true: files('xilinx_uartlite.c')) diff --git a/hw/core/register.c b/hw/core/register.c index d6f8c20..95b0150 100644 --- a/hw/core/register.c +++ b/hw/core/register.c @@ -300,6 +300,18 @@ RegisterInfoArray *register_init_block32(DeviceState *owner, data, ops, debug_enabled, memory_size, 32); } +RegisterInfoArray *register_init_block64(DeviceState *owner, + const RegisterAccessInfo *rae, + int num, RegisterInfo *ri, + uint64_t *data, + const MemoryRegionOps *ops, + bool debug_enabled, + uint64_t memory_size) +{ + return register_init_block(owner, rae, num, ri, (void *) + data, ops, debug_enabled, memory_size, 64); +} + void register_finalize_block(RegisterInfoArray *r_array) { object_unparent(OBJECT(&r_array->mem)); diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c index 0f41e5e..99c870c 100644 --- a/hw/intc/sifive_clint.c +++ b/hw/intc/sifive_clint.c @@ -59,8 +59,29 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value, riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0)); 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, timebase_freq); + uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); + + /* + * check if ns_diff overflowed and check if the addition would potentially + * overflow + */ + if ((NANOSECONDS_PER_SECOND > timebase_freq && ns_diff < diff) || + ns_diff > INT64_MAX) { + next = INT64_MAX; + } else { + /* + * as it is very unlikely qemu_clock_get_ns will return a value + * greater than INT64_MAX, no additional check is needed for an + * unsigned integer overflow. + */ + next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + ns_diff; + /* + * if ns_diff is INT64_MAX next may still be outside the range + * of a signed integer. + */ + next = MIN(next, INT64_MAX); + } + timer_mod(cpu->env.timer, next); } diff --git a/hw/riscv/Kconfig b/hw/riscv/Kconfig index 0590f44..ff75add 100644 --- a/hw/riscv/Kconfig +++ b/hw/riscv/Kconfig @@ -22,13 +22,10 @@ config OPENTITAN select IBEX select UNIMP -config SHAKTI - bool - config SHAKTI_C bool select UNIMP - select SHAKTI + select SHAKTI_UART select SIFIVE_CLINT select SIFIVE_PLIC diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 0e55411..5624add 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -454,7 +454,7 @@ static void create_fdt(RISCVVirtState *s, const MemMapEntry *memmap, qemu_fdt_setprop_cell(fdt, name, "interrupts", RTC_IRQ); g_free(name); - name = g_strdup_printf("/soc/flash@%" PRIx64, flashbase); + name = g_strdup_printf("/flash@%" PRIx64, flashbase); qemu_fdt_add_subnode(mc->fdt, name); qemu_fdt_setprop_string(mc->fdt, name, "compatible", "cfi-flash"); qemu_fdt_setprop_sized_cells(mc->fdt, name, "reg", @@ -540,6 +540,24 @@ static FWCfgState *create_fw_cfg(const MachineState *mc) return fw_cfg; } +/* + * Return the per-socket PLIC hart topology configuration string + * (caller must free with g_free()) + */ +static char *plic_hart_config_string(int hart_count) +{ + g_autofree const char **vals = g_new(const char *, hart_count + 1); + int i; + + for (i = 0; i < hart_count; i++) { + vals[i] = VIRT_PLIC_HART_CONFIG; + } + vals[i] = NULL; + + /* g_strjoinv() obliges us to cast away const here */ + return g_strjoinv(",", (char **)vals); +} + static void virt_machine_init(MachineState *machine) { const MemMapEntry *memmap = virt_memmap; @@ -548,13 +566,12 @@ static void virt_machine_init(MachineState *machine) MemoryRegion *main_mem = g_new(MemoryRegion, 1); MemoryRegion *mask_rom = g_new(MemoryRegion, 1); char *plic_hart_config, *soc_name; - size_t plic_hart_config_len; target_ulong start_addr = memmap[VIRT_DRAM].base; target_ulong firmware_end_addr, kernel_start_addr; uint32_t fdt_load_addr; uint64_t kernel_entry; DeviceState *mmio_plic, *virtio_plic, *pcie_plic; - int i, j, base_hartid, hart_count; + int i, base_hartid, hart_count; /* Check socket count limit */ if (VIRT_SOCKETS_MAX < riscv_socket_count(machine)) { @@ -603,17 +620,7 @@ static void virt_machine_init(MachineState *machine) SIFIVE_CLINT_TIMEBASE_FREQ, true); /* Per-socket PLIC hart topology configuration string */ - plic_hart_config_len = - (strlen(VIRT_PLIC_HART_CONFIG) + 1) * hart_count; - plic_hart_config = g_malloc0(plic_hart_config_len); - for (j = 0; j < hart_count; j++) { - if (j != 0) { - strncat(plic_hart_config, ",", plic_hart_config_len); - } - strncat(plic_hart_config, VIRT_PLIC_HART_CONFIG, - plic_hart_config_len); - plic_hart_config_len -= (strlen(VIRT_PLIC_HART_CONFIG) + 1); - } + plic_hart_config = plic_hart_config_string(hart_count); /* Per-socket PLIC */ s->plic[i] = sifive_plic_create( |