diff options
author | Anup Patel <apatel@ventanamicro.com> | 2021-04-06 14:37:42 +0300 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2022-02-15 18:03:55 +0300 |
commit | 222132f48c8efd3b2c84b0883df18216b170bf3d (patch) | |
tree | 8e034d195e217a8a11cc95bcd8de9a0ae701bc49 /lib | |
parent | 65b4c7c01e7447c4d762af905a5051e13361b31e (diff) | |
download | opensbi-222132f48c8efd3b2c84b0883df18216b170bf3d.tar.xz |
lib: sbi: Add sbi_trap_set_external_irqfn() API
This patch adds sbi_trap_set_external_irqfn() API which can be used by
OpenSBI platform code to set a callback function for external interrupts.
The RISC-V AIA IMSIC driver will use this API to implement inter-processor
interrupts on-top-of MSIs.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Signed-off-by: Anup Patel <apatel@ventanamicro.com>
Reviewed-by: Atish Patra <atishp@rivosinc.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/sbi/sbi_trap.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/lib/sbi/sbi_trap.c b/lib/sbi/sbi_trap.c index bc8961f..faab90a 100644 --- a/lib/sbi/sbi_trap.c +++ b/lib/sbi/sbi_trap.c @@ -195,6 +195,27 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs, return 0; } +static int default_irqfn(struct sbi_trap_regs *regs) +{ + return SBI_ENODEV; +} + +static int (*ext_irqfn)(struct sbi_trap_regs *regs) = default_irqfn; + +/** + * Set external irq handler function + * + * This function is called by OpenSBI platform code to set a handler for + * external interrupts + * + * @param fn function pointer for handling external irqs + */ +void sbi_trap_set_external_irqfn(int (*fn)(struct sbi_trap_regs *regs)) +{ + if (fn) + ext_irqfn = fn; +} + static int sbi_trap_nonaia_irq(struct sbi_trap_regs *regs, ulong mcause) { mcause &= ~(1UL << (__riscv_xlen - 1)); @@ -205,6 +226,8 @@ static int sbi_trap_nonaia_irq(struct sbi_trap_regs *regs, ulong mcause) case IRQ_M_SOFT: sbi_ipi_process(); break; + case IRQ_M_EXT: + return ext_irqfn(regs); default: return SBI_ENOENT; }; @@ -214,6 +237,7 @@ static int sbi_trap_nonaia_irq(struct sbi_trap_regs *regs, ulong mcause) static int sbi_trap_aia_irq(struct sbi_trap_regs *regs, ulong mcause) { + int rc; unsigned long mtopi; while ((mtopi = csr_read(CSR_MTOPI))) { @@ -225,6 +249,11 @@ static int sbi_trap_aia_irq(struct sbi_trap_regs *regs, ulong mcause) case IRQ_M_SOFT: sbi_ipi_process(); break; + case IRQ_M_EXT: + rc = ext_irqfn(regs); + if (rc) + return rc; + break; default: return SBI_ENOENT; } |