aboutsummaryrefslogtreecommitdiff
path: root/target/riscv
diff options
context:
space:
mode:
authorMichael Clark <mjc@sifive.com>2019-03-16 01:20:54 +0000
committerPalmer Dabbelt <palmer@sifive.com>2019-03-19 05:14:39 -0700
commitd26f5a423438e579d3ff0ca35e44edb966a36233 (patch)
treef274bdd1f5eb6f9d8434403683cb9d486c6cceb0 /target/riscv
parent5836c3eccedb6dfab16b8f606f2de24b8938b69c (diff)
downloadqemu-d26f5a423438e579d3ff0ca35e44edb966a36233.zip
qemu-d26f5a423438e579d3ff0ca35e44edb966a36233.tar.gz
qemu-d26f5a423438e579d3ff0ca35e44edb966a36233.tar.bz2
RISC-V: Change local interrupts from edge to level
This effectively changes riscv_cpu_update_mip from edge to level. i.e. cpu_interrupt or cpu_reset_interrupt are called regardless of the current interrupt level. Fixes WFI doesn't return when a IPI is issued: - https://github.com/riscv/riscv-qemu/issues/132 To test: 1) Apply RISC-V Linux CPU hotplug patch: - http://lists.infradead.org/pipermail/linux-riscv/2018-May/000603.html 2) Enable CONFIG_CPU_HOTPLUG in linux .config 3) Try to offline and online cpus: echo 1 > /sys/devices/system/cpu/cpu2/online echo 0 > /sys/devices/system/cpu/cpu2/online echo 1 > /sys/devices/system/cpu/cpu2/online Reported-by: Atish Patra <atishp04@gmail.com> Cc: Atish Patra <atishp04@gmail.com> Cc: Alistair Francis <Alistair.Francis@wdc.com> Signed-off-by: Michael Clark <mjc@sifive.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Diffstat (limited to 'target/riscv')
-rw-r--r--target/riscv/cpu_helper.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/target/riscv/cpu_helper.c b/target/riscv/cpu_helper.c
index 555756d..073bdcf 100644
--- a/target/riscv/cpu_helper.c
+++ b/target/riscv/cpu_helper.c
@@ -95,9 +95,9 @@ uint32_t riscv_cpu_update_mip(RISCVCPU *cpu, uint32_t mask, uint32_t value)
cmp = atomic_cmpxchg(&env->mip, old, new);
} while (old != cmp);
- if (new && !old) {
+ if (new) {
cpu_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
- } else if (!new && old) {
+ } else {
cpu_reset_interrupt(CPU(cpu), CPU_INTERRUPT_HARD);
}