riscv32: riscv-privilege: Platform-Level Interrupt Controller support
Updated the riscv-privilege SOC family to account for SOCs supporting a Platform-level Interrupt Controller (PLIC) as specified by the riscv privilege architecture. riscv-privilege SOCs supporting a PLIC have to implement the following list of APIs: void riscv_plic_irq_enable(uint32_t irq); void riscv_plic_irq_disable(uint32_t irq); int riscv_plic_irq_is_enabled(uint32_t irq); void riscv_plic_set_priority(uint32_t irq, uint32_t priority); int riscv_plic_get_irq(void); Change-Id: I0228574967348d572afc98a79257c697efc4309e Signed-off-by: Jean-Paul Etienne <fractalclone@gmail.com>
This commit is contained in:
parent
d1bd80a4a9
commit
4b8ae8863c
5 changed files with 51 additions and 1 deletions
|
@ -19,6 +19,12 @@ void _irq_spurious(void *unused)
|
||||||
mcause &= SOC_MCAUSE_EXP_MASK;
|
mcause &= SOC_MCAUSE_EXP_MASK;
|
||||||
|
|
||||||
printk("Spurious interrupt detected! IRQ: %d\n", (int)mcause);
|
printk("Spurious interrupt detected! IRQ: %d\n", (int)mcause);
|
||||||
|
#if defined(CONFIG_RISCV_HAS_PLIC)
|
||||||
|
if (mcause == RISCV_MACHINE_EXT_IRQ) {
|
||||||
|
printk("PLIC interrupt line causing the IRQ: %d\n",
|
||||||
|
riscv_plic_get_irq());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
_NanoFatalErrorHandler(_NANO_ERR_SPURIOUS_INT, &_default_esf);
|
_NanoFatalErrorHandler(_NANO_ERR_SPURIOUS_INT, &_default_esf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,4 +15,11 @@ config SOC_FAMILY
|
||||||
default "riscv-privilege"
|
default "riscv-privilege"
|
||||||
depends on SOC_FAMILY_RISCV_PRIVILEGE
|
depends on SOC_FAMILY_RISCV_PRIVILEGE
|
||||||
|
|
||||||
|
config RISCV_HAS_PLIC
|
||||||
|
bool "Does the SOC provide support for a Platform Level Interrupt Controller"
|
||||||
|
default n
|
||||||
|
depends on SOC_FAMILY_RISCV_PRIVILEGE
|
||||||
|
help
|
||||||
|
Does the SOC provide support for a Platform Level Interrupt Controller
|
||||||
|
|
||||||
source "arch/riscv32/soc/riscv-privilege/*/Kconfig.defconfig.series"
|
source "arch/riscv32/soc/riscv-privilege/*/Kconfig.defconfig.series"
|
||||||
|
|
|
@ -17,6 +17,8 @@
|
||||||
#define RISCV_MACHINE_TIMER_IRQ 7 /* Machine Timer Interrupt */
|
#define RISCV_MACHINE_TIMER_IRQ 7 /* Machine Timer Interrupt */
|
||||||
#define RISCV_MACHINE_EXT_IRQ 11 /* Machine External Interrupt */
|
#define RISCV_MACHINE_EXT_IRQ 11 /* Machine External Interrupt */
|
||||||
|
|
||||||
|
#define RISCV_MAX_GENERIC_IRQ 11 /* Max Generic Interrupt */
|
||||||
|
|
||||||
/* Exception numbers */
|
/* Exception numbers */
|
||||||
#define RISCV_MACHINE_ECALL_EXP 11 /* Machine ECALL instruction */
|
#define RISCV_MACHINE_ECALL_EXP 11 /* Machine ECALL instruction */
|
||||||
|
|
||||||
|
@ -57,6 +59,14 @@
|
||||||
void soc_interrupt_init(void);
|
void soc_interrupt_init(void);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(CONFIG_RISCV_HAS_PLIC)
|
||||||
|
void riscv_plic_irq_enable(uint32_t irq);
|
||||||
|
void riscv_plic_irq_disable(uint32_t irq);
|
||||||
|
int riscv_plic_irq_is_enabled(uint32_t irq);
|
||||||
|
void riscv_plic_set_priority(uint32_t irq, uint32_t priority);
|
||||||
|
int riscv_plic_get_irq(void);
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* !_ASMLANGUAGE */
|
#endif /* !_ASMLANGUAGE */
|
||||||
|
|
||||||
#endif /* __SOC_COMMON_H_ */
|
#endif /* __SOC_COMMON_H_ */
|
||||||
|
|
|
@ -11,11 +11,17 @@
|
||||||
*/
|
*/
|
||||||
#include <irq.h>
|
#include <irq.h>
|
||||||
|
|
||||||
/* TODO: account for RISCV PLIC */
|
|
||||||
void _arch_irq_enable(unsigned int irq)
|
void _arch_irq_enable(unsigned int irq)
|
||||||
{
|
{
|
||||||
uint32_t mie;
|
uint32_t mie;
|
||||||
|
|
||||||
|
#if defined(CONFIG_RISCV_HAS_PLIC)
|
||||||
|
if (irq > RISCV_MAX_GENERIC_IRQ) {
|
||||||
|
riscv_plic_irq_enable(irq);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* CSR mie register is updated using atomic instruction csrrs
|
* CSR mie register is updated using atomic instruction csrrs
|
||||||
* (atomic read and set bits in CSR register)
|
* (atomic read and set bits in CSR register)
|
||||||
|
@ -29,6 +35,13 @@ void _arch_irq_disable(unsigned int irq)
|
||||||
{
|
{
|
||||||
uint32_t mie;
|
uint32_t mie;
|
||||||
|
|
||||||
|
#if defined(CONFIG_RISCV_HAS_PLIC)
|
||||||
|
if (irq > RISCV_MAX_GENERIC_IRQ) {
|
||||||
|
riscv_plic_irq_disable(irq);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use atomic instruction csrrc to disable device interrupt in mie CSR.
|
* Use atomic instruction csrrc to disable device interrupt in mie CSR.
|
||||||
* (atomic read and clear bits in CSR register)
|
* (atomic read and clear bits in CSR register)
|
||||||
|
@ -42,6 +55,11 @@ int _arch_irq_is_enabled(unsigned int irq)
|
||||||
{
|
{
|
||||||
uint32_t mie;
|
uint32_t mie;
|
||||||
|
|
||||||
|
#if defined(CONFIG_RISCV_HAS_PLIC)
|
||||||
|
if (irq > RISCV_MAX_GENERIC_IRQ)
|
||||||
|
return riscv_plic_irq_is_enabled(irq);
|
||||||
|
#endif
|
||||||
|
|
||||||
__asm__ volatile ("csrr %0, mie" : "=r" (mie));
|
__asm__ volatile ("csrr %0, mie" : "=r" (mie));
|
||||||
|
|
||||||
return !!(mie & (1 << irq));
|
return !!(mie & (1 << irq));
|
||||||
|
|
|
@ -72,11 +72,20 @@ void _irq_spurious(void *unused);
|
||||||
*
|
*
|
||||||
* @return The vector assigned to this interrupt
|
* @return The vector assigned to this interrupt
|
||||||
*/
|
*/
|
||||||
|
#if defined(CONFIG_RISCV_HAS_PLIC)
|
||||||
|
#define _ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
|
||||||
|
({ \
|
||||||
|
_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
|
||||||
|
riscv_plic_set_priority(irq_p, priority_p); \
|
||||||
|
irq_p; \
|
||||||
|
})
|
||||||
|
#else
|
||||||
#define _ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
|
#define _ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
|
||||||
({ \
|
({ \
|
||||||
_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
|
_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
|
||||||
irq_p; \
|
irq_p; \
|
||||||
})
|
})
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* use atomic instruction csrrc to lock global irq
|
* use atomic instruction csrrc to lock global irq
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue