From 3506a5e82d3305c53051fe8895ea88f75b0e4508 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Tue, 14 May 2024 10:04:13 +0200 Subject: [PATCH] cores/cpu/vexriscv_smp: Prepare IRQ support based on Rocket IRQ support (not yet working). --- litex/soc/cores/cpu/vexriscv_smp/core.py | 4 ++-- litex/soc/cores/cpu/vexriscv_smp/crt0.S | 5 +++++ litex/soc/cores/cpu/vexriscv_smp/irq.h | 22 ++++++++++++++++------ 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/litex/soc/cores/cpu/vexriscv_smp/core.py b/litex/soc/cores/cpu/vexriscv_smp/core.py index 08320049a..2fe30c20c 100755 --- a/litex/soc/cores/cpu/vexriscv_smp/core.py +++ b/litex/soc/cores/cpu/vexriscv_smp/core.py @@ -168,8 +168,8 @@ class VexRiscvSMP(CPU): @property def gcc_flags(self): flags = f" -march={VexRiscvSMP.get_arch()} -mabi={VexRiscvSMP.get_abi()}" - flags += f" -D__vexriscv__" - flags += f" -DUART_POLLING" + flags += f" -D__vexriscv_smp__" + #flags += f" -DUART_POLLING" return flags # Reserved Interrupts. diff --git a/litex/soc/cores/cpu/vexriscv_smp/crt0.S b/litex/soc/cores/cpu/vexriscv_smp/crt0.S index ec18b8ecd..595891a6e 100644 --- a/litex/soc/cores/cpu/vexriscv_smp/crt0.S +++ b/litex/soc/cores/cpu/vexriscv_smp/crt0.S @@ -102,6 +102,11 @@ bss_loop: j bss_loop bss_done: + call plic_init // initialize external interrupt controller + li t0, 0x800 // external interrupt sources only (using LiteX timer); + // NOTE: must still enable mstatus.MIE! + csrw mie,t0 + call main infinit_loop: j infinit_loop diff --git a/litex/soc/cores/cpu/vexriscv_smp/irq.h b/litex/soc/cores/cpu/vexriscv_smp/irq.h index 558adc4f1..4dceaf8b8 100644 --- a/litex/soc/cores/cpu/vexriscv_smp/irq.h +++ b/litex/soc/cores/cpu/vexriscv_smp/irq.h @@ -9,30 +9,40 @@ extern "C" { #include #include +// VexRiscv-SMP uses a Platform-Level Interrupt Controller (PLIC) which +// is programmed and queried via a set of MMIO registerss + +#define PLIC_BASE 0xf0c00000L // Base address and per-pin priority array +#define PLIC_PENDING 0xf0c01000L // Bit field matching currently pending pins +#define PLIC_ENABLED 0xf0c02000L // Bit field corresponding to the current mask +#define PLIC_THRSHLD 0xf0e00000L // Per-pin priority must be >= this to trigger +#define PLIC_CLAIM 0xf0e00004L // Claim & completion register address + +#define PLIC_EXT_IRQ_BASE 1 // CHECKME/FIXME. + static inline unsigned int irq_getie(void) { - return 0; + return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; } static inline void irq_setie(unsigned int ie) { - + if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); } static inline unsigned int irq_getmask(void) { - - return 0; + return *((unsigned int *)PLIC_ENABLED) >> 1; } static inline void irq_setmask(unsigned int mask) { - + *((unsigned int *)PLIC_ENABLED) = mask << 1; } static inline unsigned int irq_pending(void) { - return 0; + return *((unsigned int *)PLIC_PENDING) >> 1; } #ifdef __cplusplus