Closed Popebl closed 3 months ago
I don't think it's necessary. You can just return from the interrupt but if there is another pending you'll just take an interrupt again. So you may as well process all that are available and avoid the extra privilege switch.
Linux does the same thing with stopi. https://github.com/torvalds/linux/blob/master/drivers/irqchip/irq-riscv-intc.c#L41
What confuses me the most is the behavior of TOPEI and STOPEI after executing csrrw rd, mtopei/stopei, x0. It seems that mtopei/stopei will be set to 0. Is the while loop used to handle interrupts that occur during the ISR process?
What confuses me the most is the behavior of TOPEI and STOPEI after executing csrrw rd, mtopei/stopei, x0. It seems that mtopei/stopei will be set to 0.
The write is ignored. This is what the spec says:
A write to a *topei CSR claims the reported interrupt identity by clearing its pending bit in the interrupt file. The value written is ignored; rather, the current readable value of the register determines which interrupt-pending bit is cleared.
Is the while loop used to handle interrupts that occur during the ISR process?
Yes.
I found the following description in Section 3.9, 'Top External Interrupt CSRs,' of the RISC-V Advanced Interrupt Architecture Version 1.0, revised on June 30, 2023.
A read of a *topei CSR returns zero either if no interrupt is both pending in the interrupt file’s eip
array and enabled in its eie array, or if eithreshold is not zero and no pending-and-enabled interrupt
has an identity number less than the value of eithreshold. Otherwise, the value returned from a read
of *topei has this format:
It is almost always a mistake to write to a *topei CSR without a simultaneous read to
learn which interrupt was claimed.
So, I believe the scrrw
instruction is used to read and claim the highest-priority pending-and-enabled interrupt, and topei
will not be written to zero, but will change to indicate the next highest-priority pending-and-enabled interrupt.
Is my understanding correct?
I am examining the function of TOPEI in QEMU. The read-modify-write operation on TOPEI involves two steps: first, it reads the highest-priority pending-and-enabled interrupt, and second, it writes an ignore value to clear the top pending interrupt. Therefore, on the second access, TOPEI should report the next highest-priority pending-and-enabled interrupt.
https://github.com/qemu/qemu/blob/master/hw/intc/riscv_imsic.c#L112
static int riscv_imsic_topei_rmw(RISCVIMSICState *imsic, uint32_t page,
target_ulong *val, target_ulong new_val,
target_ulong wr_mask)
{
uint32_t base, topei = riscv_imsic_topei(imsic, page);
/* Read pending and enabled interrupt with highest priority */
if (val) {
*val = topei;
}
/* Writes ignore value and clear top pending interrupt */
if (topei && wr_mask) {
topei >>= IMSIC_TOPEI_IID_SHIFT;
base = page * imsic->num_irqs;
if (topei) {
imsic->eistate[base + topei] &= ~IMSIC_EISTATE_PENDING;
}
riscv_imsic_update(imsic, page);
}
return 0;
}
Thanks very much with best regards!
According to this link, a while loop is used to process IMSIC external interrupts. I’m wondering why this while loop is necessary?
his while loop is not mentioned in the RISC-V Advanced Interrupt Architecture Version 1.0, Revised 2023-06-30, Section 3.10 on interrupt delivery and handling.
With best regards.