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