From b2b0ba66e58835366abf0656a84491849fc50a90 Mon Sep 17 00:00:00 2001 From: navaneeth Date: Sat, 16 Oct 2021 16:29:00 +0530 Subject: [PATCH 1/4] Fix the support for Ibex. Take care of the module change in instantiation of Ibex core. --- litex/soc/cores/cpu/ibex/core.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/litex/soc/cores/cpu/ibex/core.py b/litex/soc/cores/cpu/ibex/core.py index f4ee87d82..cd1105427 100644 --- a/litex/soc/cores/cpu/ibex/core.py +++ b/litex/soc/cores/cpu/ibex/core.py @@ -210,6 +210,7 @@ class Ibex(CPU): "ibex_register_file_fpga.sv", "ibex_wb_stage.sv", "ibex_core.sv", + "ibex_top.sv" ) platform.add_source(os.path.join(ibexdir, "syn", "rtl", "prim_clock_gating.v")) platform.add_sources(os.path.join(opentitandir, "hw", "ip", "prim", "rtl"), @@ -217,7 +218,7 @@ class Ibex(CPU): "prim_assert.sv" ) platform.add_verilog_include_path(os.path.join(opentitandir, "hw", "ip", "prim", "rtl")) - platform.add_verilog_include_path(os.path.join(ibexdir, "dv", "fcov")) + platform.add_verilog_include_path(os.path.join(opentitandir, "hw", "dv", "sv", "dv_utils")) def set_reset_address(self, reset_address): assert not hasattr(self, "reset_address") @@ -226,4 +227,4 @@ class Ibex(CPU): def do_finalize(self): assert hasattr(self, "reset_address") - self.specials += Instance("ibex_core", **self.cpu_params) + self.specials += Instance("ibex_top", **self.cpu_params) From c8a83461b4340f8814e832bd79df9c060f3601ae Mon Sep 17 00:00:00 2001 From: navaneeth Date: Sun, 17 Oct 2021 12:32:31 +0530 Subject: [PATCH 2/4] 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)){ From ef8bab4c11d58b3d7496ac2732dfd84bc3ff980f Mon Sep 17 00:00:00 2001 From: Navaneeth Date: Mon, 18 Oct 2021 20:02:05 +0530 Subject: [PATCH 3/4] Add support for Ibex interrupt Initial support for a working Ibex interrupt. Tested in Verilator. --- litex/soc/cores/cpu/ibex/crt0.S | 120 +++++++++++++++++++--------- litex/soc/cores/cpu/ibex/csr-defs.h | 6 +- litex/soc/cores/cpu/ibex/irq.h | 10 ++- litex/soc/software/bios/isr.c | 33 +++----- 4 files changed, 104 insertions(+), 65 deletions(-) diff --git a/litex/soc/cores/cpu/ibex/crt0.S b/litex/soc/cores/cpu/ibex/crt0.S index d80d3e25c..dcb598e59 100644 --- a/litex/soc/cores/cpu/ibex/crt0.S +++ b/litex/soc/cores/cpu/ibex/crt0.S @@ -1,44 +1,55 @@ -#define MIE_MEIE 0x800 -#define MIE_MFIE 0x7FFF0000 -#define MIE (MIE_MEIE|MIE_MFIE) +.global main +.global isr +.global _start - .global _start _start: - j reset_vector + j crt_init + nop + nop + nop + nop + nop + nop + nop -reset_vector: - la sp, _fstack - la t0, trap_vector - csrw mtvec, t0 +.balign 256 - // initialize .data - la t0, _fdata - la t1, _edata - la t2, _fdata_rom -1: beq t0, t1, 2f - lw t3, 0(t2) - sw t3, 0(t0) - addi t0, t0, 4 - addi t2, t2, 4 - j 1b -2: +vector_table: + j trap_entry # 0 unused + j trap_entry # 1 unused + j trap_entry # 2 unused + j trap_entry # 3 software + j trap_entry # 4 unused + j trap_entry # 5 unused + j trap_entry # 6 unused + j trap_entry # 7 timer + j trap_entry # 8 unused + j trap_entry # 9 unused + j trap_entry # 10 unused + j trap_entry # 11 external + j trap_entry # 12 unused + j trap_entry # 13 unused + j trap_entry # 14 unused + j trap_entry # 15 unused + j trap_entry # 16 firq0 + j trap_entry # 17 firq1 + j trap_entry # 18 firq2 + j trap_entry # 19 firq3 + j trap_entry # 20 firq4 + j trap_entry # 21 firq5 + j trap_entry # 22 firq6 + j trap_entry # 23 firq7 + j trap_entry # 24 firq8 + j trap_entry # 25 firq9 + j trap_entry # 26 firq10 + j trap_entry # 27 firq11 + j trap_entry # 28 firq12 + j trap_entry # 29 firq13 + j trap_entry # 30 firq14 + j trap_entry # 31 unused - // initialize .bss - la t0, _fbss - la t1, _ebss -1: beq t0, t1, 3f - sw zero, 0(t0) - addi t0, t0, 4 - j 1b -3: - // enable external interrupts - li t0, 0x7FFF0880 - csrs mie, t0 - - call main -1: j 1b - -trap_vector: +.global trap_entry +trap_entry: addi sp, sp, -16*4 sw ra, 0*4(sp) sw t0, 1*4(sp) @@ -75,3 +86,40 @@ trap_vector: lw t6, 15*4(sp) addi sp, sp, 16*4 mret + .text + +crt_init: + la sp, _fstack + la t0, vector_table + csrw mtvec, t0 + +data_init: + la t0, _fdata + la t1, _edata + la t2, _fdata_rom +data_loop: + beq t0, t1, data_done + lw t3, 0(t2) + sw t3, 0(t0) + addi t0, t0, 4 + addi t2, t2, 4 + j data_loop +data_done: + +bss_init: + la t0, _fbss + la t1, _ebss +bss_loop: + beq t0, t1, bss_done + sw zero, 0(t0) + addi t0, t0, 4 + j bss_loop +bss_done: + + li t0, 0x7FFF0880 // enable external interrupts + csrs mie, t0 + call main + +infinit_loop: + j infinit_loop + diff --git a/litex/soc/cores/cpu/ibex/csr-defs.h b/litex/soc/cores/cpu/ibex/csr-defs.h index d98e8dfb7..e8c2b4735 100644 --- a/litex/soc/cores/cpu/ibex/csr-defs.h +++ b/litex/soc/cores/cpu/ibex/csr-defs.h @@ -1,10 +1,12 @@ #ifndef CSR_DEFS__H #define CSR_DEFS__H +/*Reference : https://ibex-core.readthedocs.io/en/latest/03_reference/cs_registers.html# */ + #define CSR_MSTATUS_MIE 0x8 -#define CSR_IRQ_MASK 0xBC0 -#define CSR_IRQ_PENDING 0xFC0 +#define CSR_IRQ_MASK 0x304 +#define CSR_IRQ_PENDING 0x344 #define CSR_DCACHE_INFO 0xCC0 diff --git a/litex/soc/cores/cpu/ibex/irq.h b/litex/soc/cores/cpu/ibex/irq.h index f1dd4c285..79972c3ff 100644 --- a/litex/soc/cores/cpu/ibex/irq.h +++ b/litex/soc/cores/cpu/ibex/irq.h @@ -20,17 +20,21 @@ static inline void irq_setie(unsigned int ie) static inline unsigned int irq_getmask(void) { - return 0; // FIXME + unsigned int mask; + asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); + return mask; } static inline void irq_setmask(unsigned int mask) { - // FIXME + // asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); } static inline unsigned int irq_pending(void) { - return 0;// FIXME + unsigned int pending; + asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING)); + return pending; } #ifdef __cplusplus diff --git a/litex/soc/software/bios/isr.c b/litex/soc/software/bios/isr.c index 2c00a03da..041053c94 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__) || defined(__ibex__) +#elif defined(__cv32e40p__) #define FIRQ_OFFSET 16 #define IRQ_MASK 0x7FFFFFFF @@ -106,36 +106,21 @@ void isr(void) #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) { + __attribute__((unused)) unsigned int irqs; + + irqs = irq_pending() & irq_getmask(); + +#ifdef CSR_UART_BASE #ifndef UART_POLLING - if (cause == (UART_INTERRUPT+FIRQ_OFFSET)){ - uart_isr(); - } + if(irqs & (1 << (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(__microwatt__) void isr(uint64_t vec) From 0fbaa51c71bfe5d2f101a4c1a8d306d4a40a3316 Mon Sep 17 00:00:00 2001 From: Navaneeth Date: Tue, 19 Oct 2021 07:14:36 +0530 Subject: [PATCH 4/4] Change to common isr handler --- litex/soc/cores/cpu/ibex/crt0.S | 2 -- litex/soc/cores/cpu/ibex/csr-defs.h | 5 +++-- litex/soc/cores/cpu/ibex/irq.h | 6 +++--- litex/soc/software/bios/isr.c | 21 +-------------------- 4 files changed, 7 insertions(+), 27 deletions(-) diff --git a/litex/soc/cores/cpu/ibex/crt0.S b/litex/soc/cores/cpu/ibex/crt0.S index dcb598e59..1656711a5 100644 --- a/litex/soc/cores/cpu/ibex/crt0.S +++ b/litex/soc/cores/cpu/ibex/crt0.S @@ -116,8 +116,6 @@ bss_loop: j bss_loop bss_done: - li t0, 0x7FFF0880 // enable external interrupts - csrs mie, t0 call main infinit_loop: diff --git a/litex/soc/cores/cpu/ibex/csr-defs.h b/litex/soc/cores/cpu/ibex/csr-defs.h index e8c2b4735..0480d1f65 100644 --- a/litex/soc/cores/cpu/ibex/csr-defs.h +++ b/litex/soc/cores/cpu/ibex/csr-defs.h @@ -5,9 +5,10 @@ #define CSR_MSTATUS_MIE 0x8 -#define CSR_IRQ_MASK 0x304 +#define CSR_IRQ_MASK 0x304 #define CSR_IRQ_PENDING 0x344 - +#define FIRQ_OFFSET 16 #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 79972c3ff..c11829bfc 100644 --- a/litex/soc/cores/cpu/ibex/irq.h +++ b/litex/soc/cores/cpu/ibex/irq.h @@ -22,19 +22,19 @@ static inline unsigned int irq_getmask(void) { unsigned int mask; asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); - return mask; + return (mask >> FIRQ_OFFSET); } static inline void irq_setmask(unsigned int mask) { - // asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); + asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask << FIRQ_OFFSET)); } static inline unsigned int irq_pending(void) { unsigned int pending; asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING)); - return pending; + return (pending >> FIRQ_OFFSET); } #ifdef __cplusplus diff --git a/litex/soc/software/bios/isr.c b/litex/soc/software/bios/isr.c index 041053c94..a38c29422 100644 --- a/litex/soc/software/bios/isr.c +++ b/litex/soc/software/bios/isr.c @@ -79,7 +79,7 @@ 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)){ @@ -102,25 +102,6 @@ void isr(void) #endif } } -#elif defined(__ibex__) - -#define FIRQ_OFFSET 16 -#define IRQ_MASK 0x7FFFFFFF - -void isr(void) -{ - __attribute__((unused)) unsigned int irqs; - - irqs = irq_pending() & irq_getmask(); - -#ifdef CSR_UART_BASE -#ifndef UART_POLLING - if(irqs & (1 << (UART_INTERRUPT+FIRQ_OFFSET))) - uart_isr(); -#endif -#endif -} - #elif defined(__microwatt__) void isr(uint64_t vec)