[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Stable-9.0.4 44/57] hw/intc/riscv_aplic: Check and update pending when
From: |
Michael Tokarev |
Subject: |
[Stable-9.0.4 44/57] hw/intc/riscv_aplic: Check and update pending when write sourcecfg |
Date: |
Sat, 9 Nov 2024 15:07:46 +0300 |
From: Yong-Xuan Wang <yongxuan.wang@sifive.com>
The section 4.5.2 of the RISC-V AIA specification says that any write
to a sourcecfg register of an APLIC might (or might not) cause the
corresponding interrupt-pending bit to be set to one if the rectified
input value is high (= 1) under the new source mode.
If an interrupt is asserted before the driver configs its interrupt
type to APLIC, it's pending bit will not be set except a relevant
write to a setip or setipnum register. When we write the interrupt
type to sourcecfg register, if the APLIC device doesn't check
rectified input value and update the pending bit, this interrupt
might never becomes pending.
For APLIC.m, we can manully set pending by setip or setipnum
registers in driver. But for APLIC.w, the pending status totally
depends on the rectified input value, we can't control the pending
status via mmio registers. In this case, hw should check and update
pending status for us when writing sourcecfg registers.
Update QEMU emulation to handle "pre-existing" interrupts.
Signed-off-by: Yong-Xuan Wang <yongxuan.wang@sifive.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20241004104649.13129-1-yongxuan.wang@sifive.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
(cherry picked from commit 2ae6cca1d3389801ee72fc5e58c52573218f3514)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index 32edd6d07b..4a262c82f0 100644
--- a/hw/intc/riscv_aplic.c
+++ b/hw/intc/riscv_aplic.c
@@ -159,31 +159,42 @@ static bool is_kvm_aia(bool msimode)
return kvm_irqchip_in_kernel() && msimode;
}
+static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic,
+ uint32_t irq)
+{
+ uint32_t sourcecfg, sm, raw_input, irq_inverted;
+
+ if (!irq || aplic->num_irqs <= irq) {
+ return false;
+ }
+
+ sourcecfg = aplic->sourcecfg[irq];
+ if (sourcecfg & APLIC_SOURCECFG_D) {
+ return false;
+ }
+
+ sm = sourcecfg & APLIC_SOURCECFG_SM_MASK;
+ if (sm == APLIC_SOURCECFG_SM_INACTIVE) {
+ return false;
+ }
+
+ raw_input = (aplic->state[irq] & APLIC_ISTATE_INPUT) ? 1 : 0;
+ irq_inverted = (sm == APLIC_SOURCECFG_SM_LEVEL_LOW ||
+ sm == APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0;
+
+ return !!(raw_input ^ irq_inverted);
+}
+
static uint32_t riscv_aplic_read_input_word(RISCVAPLICState *aplic,
uint32_t word)
{
- uint32_t i, irq, sourcecfg, sm, raw_input, irq_inverted, ret = 0;
+ uint32_t i, irq, rectified_val, ret = 0;
for (i = 0; i < 32; i++) {
irq = word * 32 + i;
- if (!irq || aplic->num_irqs <= irq) {
- continue;
- }
- sourcecfg = aplic->sourcecfg[irq];
- if (sourcecfg & APLIC_SOURCECFG_D) {
- continue;
- }
-
- sm = sourcecfg & APLIC_SOURCECFG_SM_MASK;
- if (sm == APLIC_SOURCECFG_SM_INACTIVE) {
- continue;
- }
-
- raw_input = (aplic->state[irq] & APLIC_ISTATE_INPUT) ? 1 : 0;
- irq_inverted = (sm == APLIC_SOURCECFG_SM_LEVEL_LOW ||
- sm == APLIC_SOURCECFG_SM_EDGE_FALL) ? 1 : 0;
- ret |= (raw_input ^ irq_inverted) << i;
+ rectified_val = riscv_aplic_irq_rectified_val(aplic, irq);
+ ret |= rectified_val << i;
}
return ret;
@@ -702,6 +713,10 @@ static void riscv_aplic_write(void *opaque, hwaddr addr,
uint64_t value,
(aplic->sourcecfg[irq] == 0)) {
riscv_aplic_set_pending_raw(aplic, irq, false);
riscv_aplic_set_enabled_raw(aplic, irq, false);
+ } else {
+ if (riscv_aplic_irq_rectified_val(aplic, irq)) {
+ riscv_aplic_set_pending_raw(aplic, irq, true);
+ }
}
} else if (aplic->mmode && aplic->msimode &&
(addr == APLIC_MMSICFGADDR)) {
--
2.39.5
- [Stable-9.0.4 34/57] gitlab: make check-[dco|patch] a little more verbose, (continued)
- [Stable-9.0.4 34/57] gitlab: make check-[dco|patch] a little more verbose, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 35/57] dockerfiles: fix default targets for debian-loongarch-cross, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 36/57] Fix calculation of minimum in colo_compare_tcp, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 37/57] net: fix build when libbpf is disabled, but libxdp is enabled, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 38/57] net/tap-win32: Fix gcc 14 format truncation errors, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 39/57] target/arm: Don't assert in regime_is_user() for E10 mmuidx values, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 40/57] target/riscv/csr.c: Fix an access to VXSAT, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 41/57] target/riscv: Correct SXL return value for RV32 in RV64 QEMU, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 43/57] target/riscv: Set vtype.vill on CPU reset, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 42/57] hw/intc: Don't clear pending bits on IRQ lowering, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 44/57] hw/intc/riscv_aplic: Check and update pending when write sourcecfg,
Michael Tokarev <=
- [Stable-9.0.4 45/57] target/riscv/kvm: set 'aia_mode' to default in error path, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 46/57] target/riscv/kvm: clarify how 'riscv-aia' default works, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 49/57] target/ppc: Fix mtDPDES targeting SMT siblings, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 47/57] target/riscv: Fix vcompress with rvv_ta_all_1s, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 48/57] target/ppc: Set ctx->opcode for decode_insn32(), Michael Tokarev, 2024/11/09
- [Stable-9.0.4 50/57] ppc/xive: Fix ESB length overflow on 32-bit hosts, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 51/57] hw/acpi: Fix ordering of BDF in Generic Initiator PCI Device Handle., Michael Tokarev, 2024/11/09
- [Stable-9.0.4 52/57] Revert "target/arm: Fix usage of MMU indexes when EL3 is AArch32", Michael Tokarev, 2024/11/09
- [Stable-9.0.4 53/57] target/arm: Add new MMU indexes for AArch32 Secure PL1&0, Michael Tokarev, 2024/11/09
- [Stable-9.0.4 54/57] target/arm: Fix SVE SDOT/UDOT/USDOT (4-way, indexed), Michael Tokarev, 2024/11/09