* [PATCH v2 1/1] hw/intc/riscv_aplic: Check and update pending when write sourcecfg
@ 2024-10-04 10:46 Yong-Xuan Wang
2024-10-08 2:44 ` Alistair Francis
0 siblings, 1 reply; 2+ messages in thread
From: Yong-Xuan Wang @ 2024-10-04 10:46 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: greentime.hu, vincent.chen, frank.chang, jim.shu, Yong-Xuan Wang,
Palmer Dabbelt, Alistair Francis, Bin Meng, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei
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>
---
v2:
- fix checkpatch warning
---
hw/intc/riscv_aplic.c | 51 ++++++++++++++++++++++++++++---------------
1 file changed, 33 insertions(+), 18 deletions(-)
diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
index 32edd6d07bb3..4a262c82f078 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.17.1
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH v2 1/1] hw/intc/riscv_aplic: Check and update pending when write sourcecfg
2024-10-04 10:46 [PATCH v2 1/1] hw/intc/riscv_aplic: Check and update pending when write sourcecfg Yong-Xuan Wang
@ 2024-10-08 2:44 ` Alistair Francis
0 siblings, 0 replies; 2+ messages in thread
From: Alistair Francis @ 2024-10-08 2:44 UTC (permalink / raw)
To: Yong-Xuan Wang
Cc: qemu-devel, qemu-riscv, greentime.hu, vincent.chen, frank.chang,
jim.shu, Palmer Dabbelt, Alistair Francis, Bin Meng, Weiwei Li,
Daniel Henrique Barboza, Liu Zhiwei
On Fri, Oct 4, 2024 at 8:47 PM Yong-Xuan Wang <yongxuan.wang@sifive.com> wrote:
>
> 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>
Thanks!
Applied to riscv-to-apply.next
Alistair
>
> ---
> v2:
> - fix checkpatch warning
> ---
> hw/intc/riscv_aplic.c | 51 ++++++++++++++++++++++++++++---------------
> 1 file changed, 33 insertions(+), 18 deletions(-)
>
> diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c
> index 32edd6d07bb3..4a262c82f078 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.17.1
>
>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-10-08 2:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-10-04 10:46 [PATCH v2 1/1] hw/intc/riscv_aplic: Check and update pending when write sourcecfg Yong-Xuan Wang
2024-10-08 2:44 ` Alistair Francis
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).