From 6164a55c6b54f1d9a24cd828ac90d827249fe262 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Fri, 14 Jun 2024 11:26:43 +0200 Subject: [PATCH] cpu/cva6: Switch to common PLIC handling code to make it similar to other PLIC based CPU and avoid code "duplication". --- litex/soc/cores/cpu/cva6/core.py | 1 + litex/soc/cores/cpu/cva6/irq.h | 23 +++++++++--------- litex/soc/software/libbase/isr.c | 41 +------------------------------- 3 files changed, 14 insertions(+), 51 deletions(-) diff --git a/litex/soc/cores/cpu/cva6/core.py b/litex/soc/cores/cpu/cva6/core.py index abb9882d9..d69791a63 100644 --- a/litex/soc/cores/cpu/cva6/core.py +++ b/litex/soc/cores/cpu/cva6/core.py @@ -90,6 +90,7 @@ class CVA6(CPU): def gcc_flags(self): flags = GCC_FLAGS[self.variant] flags += "-D__cva6__ " + flags += "-D__riscv_plic__ " #flags += f" -DUART_POLLING" return flags diff --git a/litex/soc/cores/cpu/cva6/irq.h b/litex/soc/cores/cpu/cva6/irq.h index 96d9c8464..2555d6e1c 100644 --- a/litex/soc/cores/cpu/cva6/irq.h +++ b/litex/soc/cores/cpu/cva6/irq.h @@ -9,15 +9,16 @@ extern "C" { #include #include -#define PLIC_SOURCE_0 0x0c000004L // source 0 priority -#define PLIC_SOURCE_1 0x0c000008L // source 1 priority -#define PLIC_PENDING 0x0c001000L // start of pending array -#define PLIC_M_ENABLE 0x0c002000L // Start of Hart 0 M-mode enables -#define PLIC_S_ENABLE 0x0c002100L // Start of Hart 0 S-mode enables -#define PLIC_M_THRESHOLD 0x0c200000L // hart 0 M-mode priority threshold -#define PLIC_M_CLAIM 0x0c200004L // hart 0 M-mode priority claim/complete -#define PLIC_S_THRESHOLD 0x0c200100L // hart 0 S-mode priority threshold -#define PLIC_S_CLAIM 0x0c200104L // hart 0 S-mode priority claim/complete +// The CVA6 uses a Platform-Level Interrupt Controller (PLIC) which +// is programmed and queried via a set of MMIO registers. + +#define PLIC_BASE 0x0c000000L // Base address and per-pin priority array +#define PLIC_PENDING 0x0c001000L // Bit field matching currently pending pins +#define PLIC_ENABLED 0x0c002000L // Bit field corresponding to the current mask +#define PLIC_THRSHLD 0x0c200000L // Per-pin priority must be >= this to trigger +#define PLIC_CLAIM 0x0c200004L // Claim & completion register address + +#define PLIC_EXT_IRQ_BASE 1 static inline unsigned int irq_getie(void) { @@ -31,12 +32,12 @@ static inline void irq_setie(unsigned int ie) static inline unsigned int irq_getmask(void) { - return *((unsigned int *)PLIC_M_ENABLE) >> 1; + return *((unsigned int *)PLIC_ENABLED) >> 1; } static inline void irq_setmask(unsigned int mask) { - *((unsigned int *)PLIC_M_ENABLE) = mask << 1; + *((unsigned int *)PLIC_ENABLED) = mask << 1; } static inline unsigned int irq_pending(void) diff --git a/litex/soc/software/libbase/isr.c b/litex/soc/software/libbase/isr.c index 71adac143..c18a5ad7a 100644 --- a/litex/soc/software/libbase/isr.c +++ b/litex/soc/software/libbase/isr.c @@ -153,47 +153,8 @@ void isr_dec(void) mtdec(0x000000000ffffff); } -#elif defined(__cva6__) -void plic_init(void); -void plic_init(void) -{ - int i; - - // priorities for interrupt pins 0...7 - for (i = 0; i < 8; i++) - *((unsigned int *)PLIC_SOURCE_0 + i) = 1; - // enable interrupt pins 0...7 (M-mode) - *((unsigned int *)PLIC_M_ENABLE) = 0xff; - // set priority threshold to 0 (any priority > 0 triggers interrupt) - *((unsigned int *)PLIC_M_THRESHOLD) = 0; -} - -void isr(void) -{ - unsigned int claim; - - while ((claim = *((unsigned int *)PLIC_M_CLAIM))) { - switch (claim - 1) { - case UART_INTERRUPT: - uart_isr(); - break; - default: - printf("## PLIC: Unhandled claim: %d\n", claim); - printf("# plic_enabled: %08x\n", irq_getmask()); - printf("# plic_pending: %08x\n", irq_pending()); - printf("# mepc: %016lx\n", csrr(mepc)); - printf("# mcause: %016lx\n", csrr(mcause)); - printf("# mtval: %016lx\n", csrr(mtval)); - printf("# mie: %016lx\n", csrr(mie)); - printf("# mip: %016lx\n", csrr(mip)); - printf("###########################\n\n"); - break; - } - *((unsigned int *)PLIC_M_CLAIM) = claim; - } -} - #else + struct irq_table { isr_t isr;