forked from Mirrors/opensbi
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>
This commit is contained in:
@@ -205,6 +205,8 @@ struct sbi_trap_info {
|
|||||||
int sbi_trap_redirect(struct sbi_trap_regs *regs,
|
int sbi_trap_redirect(struct sbi_trap_regs *regs,
|
||||||
struct sbi_trap_info *trap);
|
struct sbi_trap_info *trap);
|
||||||
|
|
||||||
|
void sbi_trap_set_external_irqfn(int (*fn)(struct sbi_trap_regs *regs));
|
||||||
|
|
||||||
struct sbi_trap_regs *sbi_trap_handler(struct sbi_trap_regs *regs);
|
struct sbi_trap_regs *sbi_trap_handler(struct sbi_trap_regs *regs);
|
||||||
|
|
||||||
void __noreturn sbi_trap_exit(const struct sbi_trap_regs *regs);
|
void __noreturn sbi_trap_exit(const struct sbi_trap_regs *regs);
|
||||||
|
@@ -195,6 +195,27 @@ int sbi_trap_redirect(struct sbi_trap_regs *regs,
|
|||||||
return 0;
|
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)
|
static int sbi_trap_nonaia_irq(struct sbi_trap_regs *regs, ulong mcause)
|
||||||
{
|
{
|
||||||
mcause &= ~(1UL << (__riscv_xlen - 1));
|
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:
|
case IRQ_M_SOFT:
|
||||||
sbi_ipi_process();
|
sbi_ipi_process();
|
||||||
break;
|
break;
|
||||||
|
case IRQ_M_EXT:
|
||||||
|
return ext_irqfn(regs);
|
||||||
default:
|
default:
|
||||||
return SBI_ENOENT;
|
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)
|
static int sbi_trap_aia_irq(struct sbi_trap_regs *regs, ulong mcause)
|
||||||
{
|
{
|
||||||
|
int rc;
|
||||||
unsigned long mtopi;
|
unsigned long mtopi;
|
||||||
|
|
||||||
while ((mtopi = csr_read(CSR_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:
|
case IRQ_M_SOFT:
|
||||||
sbi_ipi_process();
|
sbi_ipi_process();
|
||||||
break;
|
break;
|
||||||
|
case IRQ_M_EXT:
|
||||||
|
rc = ext_irqfn(regs);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return SBI_ENOENT;
|
return SBI_ENOENT;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user