diff options
author | Stefan Hajnoczi <stefanha@redhat.com> | 2022-09-07 08:02:43 -0400 |
---|---|---|
committer | Stefan Hajnoczi <stefanha@redhat.com> | 2022-09-07 08:02:43 -0400 |
commit | e46e2628e9fcce39e7ae28ac8c24bcc643ac48eb (patch) | |
tree | d1ff2666ea19d71c4f20f5c6a04a3067ce637771 /hw/intc | |
parent | 946e9bccf12f2bcc3ca471b820738fb22d14fc80 (diff) | |
parent | f0551560b5c01b1dcbed1ac46ca0bd1155330f5f (diff) | |
download | qemu-e46e2628e9fcce39e7ae28ac8c24bcc643ac48eb.zip qemu-e46e2628e9fcce39e7ae28ac8c24bcc643ac48eb.tar.gz qemu-e46e2628e9fcce39e7ae28ac8c24bcc643ac48eb.tar.bz2 |
Merge tag 'pull-riscv-to-apply-20220907' of https://github.com/alistair23/qemu into staging
First RISC-V PR for QEMU 7.2
* Update [m|h]tinst CSR in interrupt handling
* Force disable extensions if priv spec version does not match
* fix shifts shamt value for rv128c
* move zmmul out of the experimental
* virt: pass random seed to fdt
* Add checks for supported extension combinations
* Upgrade OpenSBI to v1.1
* Fix typo and restore Pointer Masking functionality for RISC-V
* Add mask agnostic behaviour (rvv_ma_all_1s) for vector extension
* Add Zihintpause support
* opentitan: bump opentitan version
* microchip_pfsoc: fix kernel panics due to missing peripherals
* Remove additional priv version check for mcountinhibit
* virt machine device tree improvements
* Add xicondops in ISA entry
* Use official extension names for AIA CSRs
# -----BEGIN PGP SIGNATURE-----
#
# iQEzBAABCAAdFiEE9sSsRtSTSGjTuM6PIeENKd+XcFQFAmMYUCUACgkQIeENKd+X
# cFRpEQf/T1FFcGq3TZrEPmqMdFPUSb+SEJNgwYFfloqkNjB2HIFbd2tKWAE1Tgjr
# esV00p7YPyox1Ct+fKdwSxDxRSN9OI56v+nI8ZFwluVu7vpChuTFmOHur8rNxl1T
# 8MZgP2kMxMOJSnyHCS2iV9AUFdTExS65DbmlAKzi5fpBtt9jYTPSXsI49MP8+Ku/
# 1gdv5ZF5BXDJsGs7xHvE92dRzQEVN+As64IjlknFHHpmCM1b+Ah3GekXUbKmBuDG
# /NaZyZNPCYxdRmPm/D7k0SOMZSJ9sLyhXTetZ0ZpBxG1ioClX37yS5wn4NLsCz/2
# fXrnML+MQFUKZ03AZ9lWvxcu7kXfWA==
# =7mGD
# -----END PGP SIGNATURE-----
# gpg: Signature made Wed 07 Sep 2022 04:02:45 EDT
# gpg: using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [unknown]
# gpg: WARNING: This key is not certified with a trusted signature!
# gpg: There is no indication that the signature belongs to the owner.
# Primary key fingerprint: F6C4 AC46 D493 4868 D3B8 CE8F 21E1 0D29 DF97 7054
* tag 'pull-riscv-to-apply-20220907' of https://github.com/alistair23/qemu: (44 commits)
target/riscv: Update the privilege field for sscofpmf CSRs
hw/riscv: virt: Add PMU DT node to the device tree
target/riscv: Add few cache related PMU events
target/riscv: Simplify counter predicate function
target/riscv: Add sscofpmf extension support
target/riscv: Add vstimecmp support
target/riscv: Add stimecmp support
hw/intc: Move mtimer/mtimecmp to aclint
target/riscv: Use official extension names for AIA CSRs
target/riscv: Add xicondops in ISA entry
hw/core: fix platform bus node name
hw/riscv: virt: fix syscon subnode paths
hw/riscv: virt: fix the plic's address cells
hw/riscv: virt: fix uart node name
target/riscv: Remove additional priv version check for mcountinhibit
hw/riscv: microchip_pfsoc: fix kernel panics due to missing peripherals
hw/riscv: opentitan: bump opentitan version
target/riscv: Fix priority of csr related check in riscv_csrrw_check
hw/riscv: remove 'fdt' param from riscv_setup_rom_reset_vec()
target/riscv: Add Zihintpause support
...
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'hw/intc')
-rw-r--r-- | hw/intc/riscv_aclint.c | 48 | ||||
-rw-r--r-- | hw/intc/riscv_imsic.c | 4 |
2 files changed, 37 insertions, 15 deletions
diff --git a/hw/intc/riscv_aclint.c b/hw/intc/riscv_aclint.c index e7942c4..eee0464 100644 --- a/hw/intc/riscv_aclint.c +++ b/hw/intc/riscv_aclint.c @@ -32,6 +32,7 @@ #include "hw/intc/riscv_aclint.h" #include "qemu/timer.h" #include "hw/irq.h" +#include "migration/vmstate.h" typedef struct riscv_aclint_mtimer_callback { RISCVAclintMTimerState *s; @@ -65,19 +66,22 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, uint64_t rtc_r = cpu_riscv_read_rtc(mtimer); - cpu->env.timecmp = value; - if (cpu->env.timecmp <= rtc_r) { + /* Compute the relative hartid w.r.t the socket */ + hartid = hartid - mtimer->hartid_base; + + mtimer->timecmp[hartid] = value; + if (mtimer->timecmp[hartid] <= rtc_r) { /* * If we're setting an MTIMECMP value in the "past", * immediately raise the timer interrupt */ - qemu_irq_raise(mtimer->timer_irqs[hartid - mtimer->hartid_base]); + qemu_irq_raise(mtimer->timer_irqs[hartid]); return; } /* otherwise, set up the future timer interrupt */ - qemu_irq_lower(mtimer->timer_irqs[hartid - mtimer->hartid_base]); - diff = cpu->env.timecmp - rtc_r; + qemu_irq_lower(mtimer->timer_irqs[hartid]); + diff = mtimer->timecmp[hartid] - rtc_r; /* back to ns (note args switched in muldiv64) */ uint64_t ns_diff = muldiv64(diff, NANOSECONDS_PER_SECOND, timebase_freq); @@ -102,7 +106,7 @@ static void riscv_aclint_mtimer_write_timecmp(RISCVAclintMTimerState *mtimer, next = MIN(next, INT64_MAX); } - timer_mod(cpu->env.timer, next); + timer_mod(mtimer->timers[hartid], next); } /* @@ -133,11 +137,11 @@ static uint64_t riscv_aclint_mtimer_read(void *opaque, hwaddr addr, "aclint-mtimer: invalid hartid: %zu", hartid); } else if ((addr & 0x7) == 0) { /* timecmp_lo for RV32/RV64 or timecmp for RV64 */ - uint64_t timecmp = env->timecmp; + uint64_t timecmp = mtimer->timecmp[hartid]; return (size == 4) ? (timecmp & 0xFFFFFFFF) : timecmp; } else if ((addr & 0x7) == 4) { /* timecmp_hi */ - uint64_t timecmp = env->timecmp; + uint64_t timecmp = mtimer->timecmp[hartid]; return (timecmp >> 32) & 0xFFFFFFFF; } else { qemu_log_mask(LOG_UNIMP, @@ -177,7 +181,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, } else if ((addr & 0x7) == 0) { if (size == 4) { /* timecmp_lo for RV32/RV64 */ - uint64_t timecmp_hi = env->timecmp >> 32; + uint64_t timecmp_hi = mtimer->timecmp[hartid] >> 32; riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, timecmp_hi << 32 | (value & 0xFFFFFFFF)); } else { @@ -188,7 +192,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, } else if ((addr & 0x7) == 4) { if (size == 4) { /* timecmp_hi for RV32/RV64 */ - uint64_t timecmp_lo = env->timecmp; + uint64_t timecmp_lo = mtimer->timecmp[hartid]; riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), hartid, value << 32 | (timecmp_lo & 0xFFFFFFFF)); } else { @@ -234,7 +238,7 @@ static void riscv_aclint_mtimer_write(void *opaque, hwaddr addr, } riscv_aclint_mtimer_write_timecmp(mtimer, RISCV_CPU(cpu), mtimer->hartid_base + i, - env->timecmp); + mtimer->timecmp[i]); } return; } @@ -284,6 +288,8 @@ static void riscv_aclint_mtimer_realize(DeviceState *dev, Error **errp) s->timer_irqs = g_new(qemu_irq, s->num_harts); qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts); + s->timers = g_new0(QEMUTimer *, s->num_harts); + s->timecmp = g_new0(uint64_t, s->num_harts); /* Claim timer interrupt bits */ for (i = 0; i < s->num_harts; i++) { RISCVCPU *cpu = RISCV_CPU(qemu_get_cpu(s->hartid_base + i)); @@ -310,6 +316,18 @@ static void riscv_aclint_mtimer_reset_enter(Object *obj, ResetType type) riscv_aclint_mtimer_write(mtimer, mtimer->time_base, 0, 8); } +static const VMStateDescription vmstate_riscv_mtimer = { + .name = "riscv_mtimer", + .version_id = 1, + .minimum_version_id = 1, + .fields = (VMStateField[]) { + VMSTATE_VARRAY_UINT32(timecmp, RISCVAclintMTimerState, + num_harts, 0, + vmstate_info_uint64, uint64_t), + VMSTATE_END_OF_LIST() + } +}; + static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) { DeviceClass *dc = DEVICE_CLASS(klass); @@ -317,6 +335,7 @@ static void riscv_aclint_mtimer_class_init(ObjectClass *klass, void *data) device_class_set_props(dc, riscv_aclint_mtimer_properties); ResettableClass *rc = RESETTABLE_CLASS(klass); rc->phases.enter = riscv_aclint_mtimer_reset_enter; + dc->vmsd = &vmstate_riscv_mtimer; } static const TypeInfo riscv_aclint_mtimer_info = { @@ -336,6 +355,7 @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, { int i; DeviceState *dev = qdev_new(TYPE_RISCV_ACLINT_MTIMER); + RISCVAclintMTimerState *s = RISCV_ACLINT_MTIMER(dev); assert(num_harts <= RISCV_ACLINT_MAX_HARTS); assert(!(addr & 0x7)); @@ -366,11 +386,11 @@ DeviceState *riscv_aclint_mtimer_create(hwaddr addr, hwaddr size, riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, dev); } - cb->s = RISCV_ACLINT_MTIMER(dev); + cb->s = s; cb->num = i; - env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, + s->timers[i] = timer_new_ns(QEMU_CLOCK_VIRTUAL, &riscv_aclint_mtimer_cb, cb); - env->timecmp = 0; + s->timecmp[i] = 0; qdev_connect_gpio_out(dev, i, qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER)); diff --git a/hw/intc/riscv_imsic.c b/hw/intc/riscv_imsic.c index 8615e4c..4d4d5b5 100644 --- a/hw/intc/riscv_imsic.c +++ b/hw/intc/riscv_imsic.c @@ -344,9 +344,11 @@ static void riscv_imsic_realize(DeviceState *dev, Error **errp) /* Force select AIA feature and setup CSR read-modify-write callback */ if (env) { - riscv_set_feature(env, RISCV_FEATURE_AIA); if (!imsic->mmode) { + rcpu->cfg.ext_ssaia = true; riscv_cpu_set_geilen(env, imsic->num_pages - 1); + } else { + rcpu->cfg.ext_smaia = true; } riscv_cpu_set_aia_ireg_rmw_fn(env, (imsic->mmode) ? PRV_M : PRV_S, riscv_imsic_rmw, imsic); |