From 22c3923644e9804183217cf8de80c42721860fed Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Thu, 23 Apr 2020 08:04:04 +0200 Subject: [PATCH 1/6] initial SERV integration. --- litex/soc/cores/cpu/__init__.py | 18 +++-- litex/soc/cores/cpu/serv/__init__.py | 1 + litex/soc/cores/cpu/serv/core.py | 91 ++++++++++++++++++++++ litex/soc/integration/soc_core.py | 3 + litex/soc/software/bios/boot-helper-serv.S | 4 + litex/soc/software/bios/main.c | 2 + litex/soc/software/bios/sdram.c | 2 + litex/soc/software/include/base/irq.h | 10 +++ litex/soc/software/libbase/crt0-serv.S | 63 +++++++++++++++ litex/soc/software/libbase/system.c | 4 + 10 files changed, 190 insertions(+), 8 deletions(-) create mode 100644 litex/soc/cores/cpu/serv/__init__.py create mode 100644 litex/soc/cores/cpu/serv/core.py create mode 100644 litex/soc/software/bios/boot-helper-serv.S create mode 100644 litex/soc/software/libbase/crt0-serv.S diff --git a/litex/soc/cores/cpu/__init__.py b/litex/soc/cores/cpu/__init__.py index db9fdab7b..d0b11a50e 100644 --- a/litex/soc/cores/cpu/__init__.py +++ b/litex/soc/cores/cpu/__init__.py @@ -37,17 +37,19 @@ from litex.soc.cores.cpu.minerva import Minerva from litex.soc.cores.cpu.rocket import RocketRV64 from litex.soc.cores.cpu.microwatt import Microwatt from litex.soc.cores.cpu.blackparrot import BlackParrotRV64 +from litex.soc.cores.cpu.serv import SERV CPUS = { - "None" : CPUNone, - "lm32" : LM32, - "mor1kx" : MOR1KX, - "picorv32" : PicoRV32, - "vexriscv" : VexRiscv, - "minerva" : Minerva, - "rocket" : RocketRV64, - "microwatt" : Microwatt, + "None" : CPUNone, + "lm32" : LM32, + "mor1kx" : MOR1KX, + "picorv32" : PicoRV32, + "vexriscv" : VexRiscv, + "minerva" : Minerva, + "rocket" : RocketRV64, + "microwatt" : Microwatt, "blackparrot" : BlackParrotRV64, + "serv" : SERV } # CPU Variants/Extensions Definition --------------------------------------------------------------- diff --git a/litex/soc/cores/cpu/serv/__init__.py b/litex/soc/cores/cpu/serv/__init__.py new file mode 100644 index 000000000..b46284ac8 --- /dev/null +++ b/litex/soc/cores/cpu/serv/__init__.py @@ -0,0 +1 @@ +from litex.soc.cores.cpu.serv.core import SERV diff --git a/litex/soc/cores/cpu/serv/core.py b/litex/soc/cores/cpu/serv/core.py new file mode 100644 index 000000000..8128fda5a --- /dev/null +++ b/litex/soc/cores/cpu/serv/core.py @@ -0,0 +1,91 @@ +# This file is Copyright (c) 2020 Florent Kermarrec + +# License: BSD + +import os + +from migen import * + +from litex.soc.interconnect import wishbone +from litex.soc.cores.cpu import CPU + + +CPU_VARIANTS = ["standard"] + + +class SERV(CPU): + name = "serv" + data_width = 32 + endianness = "little" + gcc_triple = ("riscv64-unknown-elf", "riscv32-unknown-elf", "riscv-none-embed", + "riscv64-linux", "riscv-sifive-elf", "riscv64-none-elf") + linker_output_format = "elf32-littleriscv" + io_regions = {0x80000000: 0x80000000} # origin, length + + @property + def gcc_flags(self): + flags = "-march=rv32i " + flags += "-mabi=ilp32 " + flags += "-D__serv__ " + return flags + + def __init__(self, platform, variant="standard"): + assert variant in CPU_VARIANTS, "Unsupported variant %s" % variant + self.platform = platform + self.variant = variant + self.reset = Signal() + self.ibus = ibus = wishbone.Interface() + self.dbus = dbus = wishbone.Interface() + self.buses = [self.ibus, dbus] + self.interrupt = Signal(32) + + # # # + + self.cpu_params = dict( + # clock / reset + i_clk = ClockSignal(), + i_i_rst = ResetSignal(), + + # timer irq + i_i_timer_irq = 0, + + # ibus + o_o_ibus_adr = ibus.adr, + o_o_ibus_cyc = ibus.cyc, + i_i_ibus_rdt = ibus.dat_r, + i_i_ibus_ack = ibus.ack, + + + # dbus + o_o_dbus_adr = dbus.adr, + o_o_dbus_dat = dbus.dat_w, + o_o_dbus_sel = dbus.sel, + o_o_dbus_we = dbus.we, + o_o_dbus_cyc = dbus.cyc, + i_i_dbus_rdt = dbus.dat_r, + i_i_dbus_ack = dbus.ack, + ) + self.comb += [ + ibus.stb.eq(ibus.cyc), + dbus.stb.eq(dbus.cyc), + ] + + # add verilog sources + self.add_sources(platform) + + def set_reset_address(self, reset_address): + assert not hasattr(self, "reset_address") + self.reset_address = reset_address + self.cpu_params.update(p_RESET_PC=reset_address) + + @staticmethod + def add_sources(platform): + # FIXME: add SERV as submodule + os.system("git clone https://github.com/olofk/serv") + vdir = os.path.join("serv", "rtl") + platform.add_source_dir(vdir) + platform.add_verilog_include_path(vdir) + + def do_finalize(self): + assert hasattr(self, "reset_address") + self.specials += Instance("serv_top", **self.cpu_params) diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 3eb0016c7..ab8704ced 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -132,6 +132,9 @@ class SoCCore(LiteXSoC): self.cpu_type = cpu_type self.cpu_variant = cpu_variant + if cpu_type == "serv": + self.add_constant("UART_POLLING") # FIXME: use UART in polling mode for SERV bringup + self.integrated_rom_size = integrated_rom_size self.integrated_rom_initialized = integrated_rom_init != [] self.integrated_sram_size = integrated_sram_size diff --git a/litex/soc/software/bios/boot-helper-serv.S b/litex/soc/software/bios/boot-helper-serv.S new file mode 100644 index 000000000..e8bd5c760 --- /dev/null +++ b/litex/soc/software/bios/boot-helper-serv.S @@ -0,0 +1,4 @@ + .section .text, "ax", @progbits + .global boot_helper +boot_helper: + jr x13 diff --git a/litex/soc/software/bios/main.c b/litex/soc/software/bios/main.c index 0d2e6d863..1d68210c9 100644 --- a/litex/soc/software/bios/main.c +++ b/litex/soc/software/bios/main.c @@ -647,6 +647,8 @@ int main(int i, char **c) printf("RocketRV64[imac]"); #elif __blackparrot__ printf("BlackParrotRV64[ia]"); +#elif __serv__ + printf("SERV"); #else printf("Unknown"); #endif diff --git a/litex/soc/software/bios/sdram.c b/litex/soc/software/bios/sdram.c index 53333cd84..de49a942d 100644 --- a/litex/soc/software/bios/sdram.c +++ b/litex/soc/software/bios/sdram.c @@ -48,6 +48,8 @@ __attribute__((unused)) static void cdelay(int i) __asm__ volatile("nop"); #elif defined (__blackparrot__) __asm__ volatile("nop"); +#elif defined (__serv__) + __asm__ volatile("nop"); #else #error Unsupported architecture #endif diff --git a/litex/soc/software/include/base/irq.h b/litex/soc/software/include/base/irq.h index 7ff9b4033..00dad8a2b 100644 --- a/litex/soc/software/include/base/irq.h +++ b/litex/soc/software/include/base/irq.h @@ -75,6 +75,8 @@ static inline unsigned int irq_getie(void) return 0; // FIXME #elif defined (__blackparrot__) return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0;//TODO +#elif defined (__serv__) + return 0; /* FIXME */ #else #error Unsupported architecture #endif @@ -104,6 +106,8 @@ static inline void irq_setie(unsigned int ie) // FIXME #elif defined (__blackparrot__) if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE);//TODO:BP +#elif defined (__serv__) + /* FIXME */ #else #error Unsupported architecture #endif @@ -135,6 +139,8 @@ static inline unsigned int irq_getmask(void) return 0; // FIXME #elif defined (__blackparrot__) //TODO:BP +#elif defined (__serv__) + return 0; /* FIXME */ #else #error Unsupported architecture #endif @@ -160,6 +166,8 @@ static inline void irq_setmask(unsigned int mask) // FIXME #elif defined (__blackparrot__) //TODO:BP +#elif defined (__serv__) + /* FIXME */ #else #error Unsupported architecture #endif @@ -189,6 +197,8 @@ static inline unsigned int irq_pending(void) return 0; // FIXME #elif defined (__blackparrot__) return csr_readl(PLIC_PENDING) >> 1;//TODO:BP +#elif defined (__serv__) + return 0;/* FIXME */ #else #error Unsupported architecture #endif diff --git a/litex/soc/software/libbase/crt0-serv.S b/litex/soc/software/libbase/crt0-serv.S new file mode 100644 index 000000000..6f6e9e6c0 --- /dev/null +++ b/litex/soc/software/libbase/crt0-serv.S @@ -0,0 +1,63 @@ +#define MIE_MEIE 0x800 + + .global _start +_start: + j reset_vector + +reset_vector: + la sp, _fstack + la t0, trap_vector + csrw mtvec, t0 + + // initialize .bss + la t0, _fbss + la t1, _ebss +1: beq t0, t1, 2f + sw zero, 0(t0) + addi t0, t0, 4 + j 1b +2: + // enable external interrupts + li t0, MIE_MEIE + csrs mie, t0 + + call main +1: j 1b + +trap_vector: + addi sp, sp, -16*4 + sw ra, 0*4(sp) + sw t0, 1*4(sp) + sw t1, 2*4(sp) + sw t2, 3*4(sp) + sw a0, 4*4(sp) + sw a1, 5*4(sp) + sw a2, 6*4(sp) + sw a3, 7*4(sp) + sw a4, 8*4(sp) + sw a5, 9*4(sp) + sw a6, 10*4(sp) + sw a7, 11*4(sp) + sw t3, 12*4(sp) + sw t4, 13*4(sp) + sw t5, 14*4(sp) + sw t6, 15*4(sp) + call isr + lw ra, 0*4(sp) + lw t0, 1*4(sp) + lw t1, 2*4(sp) + lw t2, 3*4(sp) + lw a0, 4*4(sp) + lw a1, 5*4(sp) + lw a2, 6*4(sp) + lw a3, 7*4(sp) + lw a4, 8*4(sp) + lw a5, 9*4(sp) + lw a6, 10*4(sp) + lw a7, 11*4(sp) + lw t3, 12*4(sp) + lw t4, 13*4(sp) + lw t5, 14*4(sp) + lw t6, 15*4(sp) + addi sp, sp, 16*4 + mret diff --git a/litex/soc/software/libbase/system.c b/litex/soc/software/libbase/system.c index e8b3e5055..49d23ac6d 100644 --- a/litex/soc/software/libbase/system.c +++ b/litex/soc/software/libbase/system.c @@ -62,6 +62,8 @@ void flush_cpu_icache(void) #elif defined (__blackparrot__) /* TODO: BP do something useful here! */ asm volatile("nop"); +#elif defined (__serv__) + /* no instruction cache */ #else #error Unsupported architecture #endif @@ -114,6 +116,8 @@ void flush_cpu_dcache(void) #elif defined (__blackparrot__) /* FIXME: do something useful here! */ asm volatile("nop"); +#elif defined (__serv__) + /* no data cache */ #else #error Unsupported architecture #endif From 2efd939d06ba7903892fc5a742838b49ab1728fb Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sun, 26 Apr 2020 16:26:15 +0200 Subject: [PATCH 2/6] serv: fix ibus/dbus byte/word addressing inconsistency, add missing ibus.sel (thanks @GregDavill). --- litex/soc/cores/cpu/serv/core.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/litex/soc/cores/cpu/serv/core.py b/litex/soc/cores/cpu/serv/core.py index 8128fda5a..ab73cea22 100644 --- a/litex/soc/cores/cpu/serv/core.py +++ b/litex/soc/cores/cpu/serv/core.py @@ -36,7 +36,7 @@ class SERV(CPU): self.reset = Signal() self.ibus = ibus = wishbone.Interface() self.dbus = dbus = wishbone.Interface() - self.buses = [self.ibus, dbus] + self.buses = [ibus, dbus] self.interrupt = Signal(32) # # # @@ -50,14 +50,13 @@ class SERV(CPU): i_i_timer_irq = 0, # ibus - o_o_ibus_adr = ibus.adr, + o_o_ibus_adr = Cat(Signal(2), ibus.adr), o_o_ibus_cyc = ibus.cyc, i_i_ibus_rdt = ibus.dat_r, i_i_ibus_ack = ibus.ack, - # dbus - o_o_dbus_adr = dbus.adr, + o_o_dbus_adr = Cat(Signal(2), dbus.adr), o_o_dbus_dat = dbus.dat_w, o_o_dbus_sel = dbus.sel, o_o_dbus_we = dbus.we, @@ -67,6 +66,7 @@ class SERV(CPU): ) self.comb += [ ibus.stb.eq(ibus.cyc), + ibus.sel.eq(0xf), dbus.stb.eq(dbus.cyc), ] From 1f9db583fd47c82d42e51058774d3654fae16883 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sun, 26 Apr 2020 21:05:47 +0200 Subject: [PATCH 3/6] serv/cores: fix verilog top level (use serv_rf_top instead of serv_top), working :). --- litex/soc/cores/cpu/serv/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litex/soc/cores/cpu/serv/core.py b/litex/soc/cores/cpu/serv/core.py index ab73cea22..e24853c4a 100644 --- a/litex/soc/cores/cpu/serv/core.py +++ b/litex/soc/cores/cpu/serv/core.py @@ -88,4 +88,4 @@ class SERV(CPU): def do_finalize(self): assert hasattr(self, "reset_address") - self.specials += Instance("serv_top", **self.cpu_params) + self.specials += Instance("serv_rf_top", **self.cpu_params) From 71778ad226858624494419b5b1cc538e91a7194a Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 27 Apr 2020 10:27:44 +0200 Subject: [PATCH 4/6] serv: update copyrights (Greg Davill found the typos/issues). --- litex/soc/cores/cpu/serv/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litex/soc/cores/cpu/serv/core.py b/litex/soc/cores/cpu/serv/core.py index e24853c4a..4cda01d80 100644 --- a/litex/soc/cores/cpu/serv/core.py +++ b/litex/soc/cores/cpu/serv/core.py @@ -1,5 +1,5 @@ # This file is Copyright (c) 2020 Florent Kermarrec - +# This file is Copyright (c) 2020 Greg Davill # License: BSD import os From fb9e369a193ba43a46d0e5651859b1809e8ab9b6 Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 27 Apr 2020 13:26:45 +0200 Subject: [PATCH 5/6] serv: connect reset. --- litex/soc/cores/cpu/serv/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/litex/soc/cores/cpu/serv/core.py b/litex/soc/cores/cpu/serv/core.py index 4cda01d80..c919fb532 100644 --- a/litex/soc/cores/cpu/serv/core.py +++ b/litex/soc/cores/cpu/serv/core.py @@ -44,7 +44,7 @@ class SERV(CPU): self.cpu_params = dict( # clock / reset i_clk = ClockSignal(), - i_i_rst = ResetSignal(), + i_i_rst = ResetSignal() | self.reset, # timer irq i_i_timer_irq = 0, From 1d1a4ecd28aeb3196e7ae2adeb97e25204613a3a Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Mon, 27 Apr 2020 13:46:12 +0200 Subject: [PATCH 6/6] software/irq: cleanup and make explicit that irqs are not supported with Microwatt and SERV, fix compilation warning. --- litex/soc/software/bios/isr.c | 6 ++--- litex/soc/software/include/base/irq.h | 32 +++++++++++++-------------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/litex/soc/software/bios/isr.c b/litex/soc/software/bios/isr.c index 971bd37b6..f33cdac43 100644 --- a/litex/soc/software/bios/isr.c +++ b/litex/soc/software/bios/isr.c @@ -8,7 +8,7 @@ #include #include - + #if defined(__blackparrot__) /*TODO: Update this function for BP*/ // void isr(void); @@ -21,7 +21,7 @@ void isr(void) onetime++; } } -#elif defined(__rocket__) +#elif defined(__rocket__) void plic_init(void); void plic_init(void) { @@ -65,7 +65,7 @@ void isr(void) void isr(void); void isr(void) { - unsigned int irqs; + __attribute__((unused)) unsigned int irqs; irqs = irq_pending() & irq_getmask(); diff --git a/litex/soc/software/include/base/irq.h b/litex/soc/software/include/base/irq.h index 00dad8a2b..6a2f73944 100644 --- a/litex/soc/software/include/base/irq.h +++ b/litex/soc/software/include/base/irq.h @@ -72,11 +72,11 @@ static inline unsigned int irq_getie(void) #elif defined (__rocket__) return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; #elif defined (__microwatt__) - return 0; // FIXME -#elif defined (__blackparrot__) - return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0;//TODO + return 0; /* No interrupt support on Microwatt */ +#elif defined (__blackparrot__) + return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; /* FIXME */ #elif defined (__serv__) - return 0; /* FIXME */ + return 0; /* No interrupt support on SERV */ #else #error Unsupported architecture #endif @@ -103,11 +103,11 @@ static inline void irq_setie(unsigned int ie) #elif defined (__rocket__) if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); #elif defined (__microwatt__) - // FIXME + /* No interrupt support on Microwatt */ #elif defined (__blackparrot__) - if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE);//TODO:BP + if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); /* FIXME */ #elif defined (__serv__) - /* FIXME */ + /* No interrupt support on SERV */ #else #error Unsupported architecture #endif @@ -136,11 +136,11 @@ static inline unsigned int irq_getmask(void) #elif defined (__rocket__) return *((unsigned int *)PLIC_ENABLED) >> 1; #elif defined (__microwatt__) - return 0; // FIXME + return 0; /* No interrupt support on Microwatt */ #elif defined (__blackparrot__) - //TODO:BP -#elif defined (__serv__) return 0; /* FIXME */ +#elif defined (__serv__) + return 0; /* No interrupt support on SERV */ #else #error Unsupported architecture #endif @@ -163,11 +163,11 @@ static inline void irq_setmask(unsigned int mask) #elif defined (__rocket__) *((unsigned int *)PLIC_ENABLED) = mask << 1; #elif defined (__microwatt__) - // FIXME + /* No interrupt support on Microwatt */ #elif defined (__blackparrot__) - //TODO:BP -#elif defined (__serv__) /* FIXME */ +#elif defined (__serv__) + /* No interrupt support on SERV */ #else #error Unsupported architecture #endif @@ -194,11 +194,11 @@ static inline unsigned int irq_pending(void) #elif defined (__rocket__) return *((unsigned int *)PLIC_PENDING) >> 1; #elif defined (__microwatt__) - return 0; // FIXME + return 0; /* No interrupt support on Microwatt */ #elif defined (__blackparrot__) - return csr_readl(PLIC_PENDING) >> 1;//TODO:BP + return csr_readl(PLIC_PENDING) >> 1; /* FIXME */ #elif defined (__serv__) - return 0;/* FIXME */ + return 0; /* No interrupt support on SERV */ #else #error Unsupported architecture #endif