From c8a83461b4340f8814e832bd79df9c060f3601ae Mon Sep 17 00:00:00 2001 From: navaneeth Date: Sun, 17 Oct 2021 12:32:31 +0530 Subject: [PATCH] Add initial changes to add IRQ support In the waveform IRQ pending seems to be going high but the call to ISR() doesn't happen. --- litex/soc/cores/cpu/ibex/core.py | 3 ++- litex/soc/cores/cpu/ibex/crt0.S | 6 +++-- litex/soc/cores/cpu/ibex/csr-defs.h | 11 +++++++++ litex/soc/cores/cpu/ibex/irq.h | 36 +++++++++++++++++++++++++++++ litex/soc/cores/cpu/ibex/system.h | 24 +++++++++++++++++++ litex/soc/software/bios/isr.c | 36 ++++++++++++++++++++++++++++- 6 files changed, 112 insertions(+), 4 deletions(-) create mode 100644 litex/soc/cores/cpu/ibex/csr-defs.h diff --git a/litex/soc/cores/cpu/ibex/core.py b/litex/soc/cores/cpu/ibex/core.py index cd1105427..f1a08d872 100644 --- a/litex/soc/cores/cpu/ibex/core.py +++ b/litex/soc/cores/cpu/ibex/core.py @@ -124,6 +124,7 @@ class Ibex(CPU): self.dbus = wishbone.Interface() self.periph_buses = [self.ibus, self.dbus] self.memory_buses = [] + self.interrupt = Signal(15) ibus = Record(obi_layout) dbus = Record(obi_layout) @@ -170,7 +171,7 @@ class Ibex(CPU): i_irq_software_i = 0, i_irq_timer_i = 0, i_irq_external_i = 0, - i_irq_fast_i = 0, + i_irq_fast_i = self.interrupt, i_irq_nm_i = 0, # Debug. diff --git a/litex/soc/cores/cpu/ibex/crt0.S b/litex/soc/cores/cpu/ibex/crt0.S index 99adef168..d80d3e25c 100644 --- a/litex/soc/cores/cpu/ibex/crt0.S +++ b/litex/soc/cores/cpu/ibex/crt0.S @@ -1,4 +1,6 @@ -#define MIE_MEIE 0x800 +#define MIE_MEIE 0x800 +#define MIE_MFIE 0x7FFF0000 +#define MIE (MIE_MEIE|MIE_MFIE) .global _start _start: @@ -30,7 +32,7 @@ reset_vector: j 1b 3: // enable external interrupts - li t0, MIE_MEIE + li t0, 0x7FFF0880 csrs mie, t0 call main diff --git a/litex/soc/cores/cpu/ibex/csr-defs.h b/litex/soc/cores/cpu/ibex/csr-defs.h new file mode 100644 index 000000000..d98e8dfb7 --- /dev/null +++ b/litex/soc/cores/cpu/ibex/csr-defs.h @@ -0,0 +1,11 @@ +#ifndef CSR_DEFS__H +#define CSR_DEFS__H + +#define CSR_MSTATUS_MIE 0x8 + +#define CSR_IRQ_MASK 0xBC0 +#define CSR_IRQ_PENDING 0xFC0 + +#define CSR_DCACHE_INFO 0xCC0 + +#endif /* CSR_DEFS__H */ diff --git a/litex/soc/cores/cpu/ibex/irq.h b/litex/soc/cores/cpu/ibex/irq.h index 7374cf506..f1dd4c285 100644 --- a/litex/soc/cores/cpu/ibex/irq.h +++ b/litex/soc/cores/cpu/ibex/irq.h @@ -1,4 +1,40 @@ #ifndef __IRQ_H #define __IRQ_H +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +static inline unsigned int irq_getie(void) +{ + 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; // FIXME +} + +static inline void irq_setmask(unsigned int mask) +{ + // FIXME +} + +static inline unsigned int irq_pending(void) +{ + return 0;// FIXME +} + +#ifdef __cplusplus +} +#endif + #endif /* __IRQ_H */ diff --git a/litex/soc/cores/cpu/ibex/system.h b/litex/soc/cores/cpu/ibex/system.h index 262446a62..b506ede8b 100644 --- a/litex/soc/cores/cpu/ibex/system.h +++ b/litex/soc/cores/cpu/ibex/system.h @@ -1,6 +1,8 @@ #ifndef __SYSTEM_H #define __SYSTEM_H +#include + #ifdef __cplusplus extern "C" { #endif @@ -12,6 +14,28 @@ void flush_l2_cache(void); void busy_wait(unsigned int ms); void busy_wait_us(unsigned int us); +#define csrr(reg) ({ unsigned long __tmp; \ + asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ + __tmp; }) + +#define csrw(reg, val) ({ \ + if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ + asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ + else \ + asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) + +#define csrs(reg, bit) ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrs x0, " #reg ", %0" :: "i"(bit)); \ + else \ + asm volatile ("csrrs x0, " #reg ", %0" :: "r"(bit)); }) + +#define csrc(reg, bit) ({ \ + if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ + asm volatile ("csrrc x0, " #reg ", %0" :: "i"(bit)); \ + else \ + asm volatile ("csrrc x0, " #reg ", %0" :: "r"(bit)); }) + #ifdef __cplusplus } #endif diff --git a/litex/soc/software/bios/isr.c b/litex/soc/software/bios/isr.c index a38c29422..2c00a03da 100644 --- a/litex/soc/software/bios/isr.c +++ b/litex/soc/software/bios/isr.c @@ -68,7 +68,7 @@ void isr(void) *((unsigned int *)PLIC_CLAIM) = claim; } } -#elif defined(__cv32e40p__) +#elif defined(__cv32e40p__) || defined(__ibex__) #define FIRQ_OFFSET 16 #define IRQ_MASK 0x7FFFFFFF @@ -79,7 +79,41 @@ void isr(void) void isr(void) { unsigned int cause = csrr(mcause) & IRQ_MASK; + puts("isr"); + if (csrr(mcause) & 0x80000000) { +#ifndef UART_POLLING + if (cause == (UART_INTERRUPT+FIRQ_OFFSET)){ + uart_isr(); + } +#endif + } else { +#ifdef RISCV_TEST + int gp; + asm volatile ("mv %0, gp" : "=r"(gp)); + printf("E %d\n", cause); + if (cause == INVINST) { + printf("Inv Instr\n"); + for(;;); + } + if (cause == ECALL) { + printf("Ecall (gp: %d)\n", gp); + csrw(mepc, csrr(mepc)+4); + } +#endif + } +} +#elif defined(__ibex__) +#define FIRQ_OFFSET 16 +#define IRQ_MASK 0x7FFFFFFF +#define INVINST 2 +#define ECALL 11 +#define RISCV_TEST + +void isr(void) +{ + unsigned int cause = csrr(mcause) & IRQ_MASK; + puts("isr"); if (csrr(mcause) & 0x80000000) { #ifndef UART_POLLING if (cause == (UART_INTERRUPT+FIRQ_OFFSET)){