return 0;
}
+static int sbi_trap_nonaia_irq(struct sbi_trap_regs *regs, ulong mcause)
+{
+ mcause &= ~(1UL << (__riscv_xlen - 1));
+ switch (mcause) {
+ case IRQ_M_TIMER:
+ sbi_timer_process();
+ break;
+ case IRQ_M_SOFT:
+ sbi_ipi_process();
+ break;
+ default:
+ return SBI_ENOENT;
+ };
+
+ return 0;
+}
+
+static int sbi_trap_aia_irq(struct sbi_trap_regs *regs, ulong mcause)
+{
+ unsigned long mtopi;
+
+ while ((mtopi = csr_read(CSR_MTOPI))) {
+ mtopi = mtopi >> TOPI_IID_SHIFT;
+ switch (mtopi) {
+ case IRQ_M_TIMER:
+ sbi_timer_process();
+ break;
+ case IRQ_M_SOFT:
+ sbi_ipi_process();
+ break;
+ default:
+ return SBI_ENOENT;
+ }
+ }
+
+ return 0;
+}
+
/**
* Handle trap/interrupt
*
}
if (mcause & (1UL << (__riscv_xlen - 1))) {
- mcause &= ~(1UL << (__riscv_xlen - 1));
- switch (mcause) {
- case IRQ_M_TIMER:
- sbi_timer_process();
- break;
- case IRQ_M_SOFT:
- sbi_ipi_process();
- break;
- default:
- msg = "unhandled external interrupt";
+ if (sbi_hart_has_feature(sbi_scratch_thishart_ptr(),
+ SBI_HART_HAS_AIA))
+ rc = sbi_trap_aia_irq(regs, mcause);
+ else
+ rc = sbi_trap_nonaia_irq(regs, mcause);
+ if (rc) {
+ msg = "unhandled local interrupt";
goto trap_error;
- };
+ }
return regs;
}