riscv: Decouple CLIC and PLIC

Try to decouple CLIC and PLIC as much as possible.

Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
Carlo Caione 2022-07-07 17:40:53 +02:00 committed by Carles Cufí
parent 31c5dc2230
commit 56466a14e1
4 changed files with 55 additions and 57 deletions

View file

@ -122,7 +122,7 @@ static inline uint8_t mask8(uint8_t len)
/** /**
* @brief Enable interrupt * @brief Enable interrupt
*/ */
void nuclei_eclic_irq_enable(uint32_t irq) void riscv_clic_irq_enable(uint32_t irq)
{ {
ECLIC_CTRL[irq].INTIE.b.IE = 1; ECLIC_CTRL[irq].INTIE.b.IE = 1;
} }
@ -130,7 +130,7 @@ void nuclei_eclic_irq_enable(uint32_t irq)
/** /**
* @brief Disable interrupt * @brief Disable interrupt
*/ */
void nuclei_eclic_irq_disable(uint32_t irq) void riscv_clic_irq_disable(uint32_t irq)
{ {
ECLIC_CTRL[irq].INTIE.b.IE = 0; ECLIC_CTRL[irq].INTIE.b.IE = 0;
} }
@ -138,7 +138,7 @@ void nuclei_eclic_irq_disable(uint32_t irq)
/** /**
* @brief Get enable status of interrupt * @brief Get enable status of interrupt
*/ */
int nuclei_eclic_irq_is_enabled(uint32_t irq) int riscv_clic_irq_is_enabled(uint32_t irq)
{ {
return ECLIC_CTRL[irq].INTIE.b.IE; return ECLIC_CTRL[irq].INTIE.b.IE;
} }
@ -146,7 +146,7 @@ int nuclei_eclic_irq_is_enabled(uint32_t irq)
/** /**
* @brief Set priority and level of interrupt * @brief Set priority and level of interrupt
*/ */
void nuclei_eclic_irq_priority_set(uint32_t irq, uint32_t pri, uint32_t flags) void riscv_clic_irq_priority_set(uint32_t irq, uint32_t pri, uint32_t flags)
{ {
const uint8_t prio = leftalign8(MIN(pri, max_prio), intctlbits); const uint8_t prio = leftalign8(MIN(pri, max_prio), intctlbits);
const uint8_t level = leftalign8(MIN((irq_get_level(irq) - 1), max_level), nlbits); const uint8_t level = leftalign8(MIN((irq_get_level(irq) - 1), max_level), nlbits);

View file

@ -211,31 +211,20 @@ struct arch_mem_domain {
unsigned int pmp_update_nr; unsigned int pmp_update_nr;
}; };
void arch_irq_enable(unsigned int irq); extern void z_irq_spurious(const void *unused);
void arch_irq_disable(unsigned int irq);
int arch_irq_is_enabled(unsigned int irq); extern void arch_irq_enable(unsigned int irq);
void arch_irq_priority_set(unsigned int irq, unsigned int prio); extern void arch_irq_disable(unsigned int irq);
void z_irq_spurious(const void *unused); extern int arch_irq_is_enabled(unsigned int irq);
extern void z_riscv_irq_priority_set(unsigned int irq, unsigned int prio,
uint32_t flags);
#if defined(CONFIG_RISCV_HAS_PLIC)
#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) \
{ \ { \
Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \ Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
arch_irq_priority_set(irq_p, priority_p); \ z_riscv_irq_priority_set(irq_p, priority_p, flags_p); \
} }
#elif defined(CONFIG_NUCLEI_ECLIC)
void nuclei_eclic_irq_priority_set(unsigned int irq, unsigned int prio, unsigned int flags);
#define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
{ \
Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
nuclei_eclic_irq_priority_set(irq_p, priority_p, flags_p); \
}
#else
#define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
{ \
Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
}
#endif
#define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \ #define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \
{ \ { \

View file

@ -50,11 +50,11 @@ void riscv_plic_set_priority(uint32_t irq, uint32_t priority);
int riscv_plic_get_irq(void); int riscv_plic_get_irq(void);
#endif #endif
#if defined(CONFIG_NUCLEI_ECLIC) #if defined(CONFIG_RISCV_HAS_CLIC)
void nuclei_eclic_irq_enable(uint32_t irq); int riscv_clic_irq_is_enabled(uint32_t irq);
void nuclei_eclic_irq_disable(uint32_t irq); void riscv_clic_irq_disable(uint32_t irq);
int nuclei_eclic_irq_is_enabled(uint32_t irq); void riscv_clic_irq_enable(uint32_t irq);
void nuclei_eclic_set_priority(uint32_t irq, uint32_t priority); void riscv_clic_irq_priority_set(uint32_t irq, uint32_t pri, uint32_t flags);
#endif #endif
#endif /* !_ASMLANGUAGE */ #endif /* !_ASMLANGUAGE */

View file

@ -11,6 +11,30 @@
*/ */
#include <zephyr/irq.h> #include <zephyr/irq.h>
#if defined(CONFIG_RISCV_HAS_CLIC)
void arch_irq_enable(unsigned int irq)
{
riscv_clic_irq_enable(irq);
}
void arch_irq_disable(unsigned int irq)
{
riscv_clic_irq_disable(irq);
}
int arch_irq_is_enabled(unsigned int irq)
{
return riscv_clic_irq_is_enabled(irq);
}
void z_riscv_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
{
riscv_clic_irq_priority_set(irq, prio, flags);
}
#else /* PLIC + HLINT/CLINT or HLINT/CLINT only */
void arch_irq_enable(unsigned int irq) void arch_irq_enable(unsigned int irq)
{ {
uint32_t mie; uint32_t mie;
@ -24,10 +48,6 @@ void arch_irq_enable(unsigned int irq)
return; return;
} }
#endif #endif
#if defined(CONFIG_NUCLEI_ECLIC)
nuclei_eclic_irq_enable(irq);
return;
#endif
/* /*
* CSR mie register is updated using atomic instruction csrrs * CSR mie register is updated using atomic instruction csrrs
@ -51,10 +71,6 @@ void arch_irq_disable(unsigned int irq)
return; return;
} }
#endif #endif
#if defined(CONFIG_NUCLEI_ECLIC)
nuclei_eclic_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.
@ -63,23 +79,6 @@ void arch_irq_disable(unsigned int irq)
__asm__ volatile ("csrrc %0, mie, %1\n" __asm__ volatile ("csrrc %0, mie, %1\n"
: "=r" (mie) : "=r" (mie)
: "r" (1 << irq)); : "r" (1 << irq));
};
void arch_irq_priority_set(unsigned int irq, unsigned int prio)
{
#if defined(CONFIG_RISCV_HAS_PLIC)
unsigned int level = irq_get_level(irq);
if (level == 2) {
irq = irq_from_level_2(irq);
riscv_plic_set_priority(irq, prio);
}
#endif
#if defined(CONFIG_NUCLEI_ECLIC)
nuclei_eclic_set_priority(irq, prio);
#endif
return ;
} }
int arch_irq_is_enabled(unsigned int irq) int arch_irq_is_enabled(unsigned int irq)
@ -94,15 +93,25 @@ int arch_irq_is_enabled(unsigned int irq)
return riscv_plic_irq_is_enabled(irq); return riscv_plic_irq_is_enabled(irq);
} }
#endif #endif
#if defined(CONFIG_NUCLEI_ECLIC)
return nuclei_eclic_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));
} }
#if defined(CONFIG_RISCV_HAS_PLIC)
void z_riscv_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags)
{
unsigned int level = irq_get_level(irq);
if (level == 2) {
irq = irq_from_level_2(irq);
riscv_plic_set_priority(irq, prio);
}
}
#endif /* CONFIG_RISCV_HAS_PLIC */
#endif /* CONFIG_RISCV_HAS_CLIC */
#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) #if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT)
__weak void soc_interrupt_init(void) __weak void soc_interrupt_init(void)
{ {