aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2021-09-01 08:33:02 +0100
committerPeter Maydell <peter.maydell@linaro.org>2021-09-01 08:33:02 +0100
commitec397e90d21269037280633b6058d1f280e27667 (patch)
tree2524ceef0aec4dac7564a2287e02d6185e61963a /hw
parentd52dff5d8048d4982437db9606c27bb4127cf9d0 (diff)
parent8e034ae44dba6291beb07f7f2a932c1e5ab83e98 (diff)
downloadqemu-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/Kconfig3
-rw-r--r--hw/char/meson.build2
-rw-r--r--hw/core/register.c12
-rw-r--r--hw/intc/sifive_clint.c25
-rw-r--r--hw/riscv/Kconfig5
-rw-r--r--hw/riscv/virt.c35
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(