diff options
author | Anup Patel <apatel@ventanamicro.com> | 2021-04-06 16:10:00 +0530 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2022-02-15 20:33:31 +0530 |
commit | 65b4c7c01e7447c4d762af905a5051e13361b31e (patch) | |
tree | bdb410d856a468c92187c1eb8f1e5ab992966a03 | |
parent | 8f9607006789512ceae703e82e62566873a83aaa (diff) | |
download | opensbi-65b4c7c01e7447c4d762af905a5051e13361b31e.zip opensbi-65b4c7c01e7447c4d762af905a5051e13361b31e.tar.gz opensbi-65b4c7c01e7447c4d762af905a5051e13361b31e.tar.bz2 |
lib: sbi: Use AIA CSRs for local interrupts when available
We should use AIA CSRs to process local interrupts whenever AIA
is available.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
-rw-r--r-- | lib/sbi/sbi_trap.c | 57 |
1 files changed, 46 insertions, 11 deletions
diff --git a/lib/sbi/sbi_trap.c b/lib/sbi/sbi_trap.c index 8d20e04..bc8961f 100644 --- a/lib/sbi/sbi_trap.c +++ b/lib/sbi/sbi_trap.c @@ -195,6 +195,44 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs, 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 * @@ -225,18 +263,15 @@ struct sbi_trap_regs *sbi_trap_handler(struct sbi_trap_regs *regs) } 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; } |