diff --git a/litex/soc/cores/cpu/ibex/core.py b/litex/soc/cores/cpu/ibex/core.py index f4ee87d82..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. @@ -210,6 +211,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 +219,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 +228,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) diff --git a/litex/soc/cores/cpu/ibex/crt0.S b/litex/soc/cores/cpu/ibex/crt0.S index 99adef168..1656711a5 100644 --- a/litex/soc/cores/cpu/ibex/crt0.S +++ b/litex/soc/cores/cpu/ibex/crt0.S @@ -1,42 +1,55 @@ -#define MIE_MEIE 0x800 +.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, MIE_MEIE - 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) @@ -73,3 +86,38 @@ 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: + + 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 new file mode 100644 index 000000000..0480d1f65 --- /dev/null +++ b/litex/soc/cores/cpu/ibex/csr-defs.h @@ -0,0 +1,14 @@ +#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 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 7374cf506..c11829bfc 100644 --- a/litex/soc/cores/cpu/ibex/irq.h +++ b/litex/soc/cores/cpu/ibex/irq.h @@ -1,4 +1,44 @@ #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) +{ + unsigned int mask; + asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); + return (mask >> FIRQ_OFFSET); +} + +static inline void irq_setmask(unsigned int 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 >> FIRQ_OFFSET); +} + +#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