From: Jean-François Nguyen Date: Wed, 5 Sep 2018 18:36:17 +0000 (+0200) Subject: add Minerva support X-Git-Tag: 24jan2021_ls180~1626 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8f377307d8b257dbd1e74805c8519abdc04e884d;p=litex.git add Minerva support --- diff --git a/litex/soc/cores/cpu/minerva/__init__.py b/litex/soc/cores/cpu/minerva/__init__.py new file mode 100644 index 00000000..9ad8629d --- /dev/null +++ b/litex/soc/cores/cpu/minerva/__init__.py @@ -0,0 +1 @@ +from litex.soc.cores.cpu.minerva.core import Minerva diff --git a/litex/soc/cores/cpu/minerva/core.py b/litex/soc/cores/cpu/minerva/core.py new file mode 100644 index 00000000..787c91ec --- /dev/null +++ b/litex/soc/cores/cpu/minerva/core.py @@ -0,0 +1,26 @@ +import os + +from migen import * + +from litex.soc.interconnect import wishbone + +from minerva.core import Minerva as MinervaCPU + + +class Minerva(Module): + def __init__(self, platform, cpu_reset_address, variant=None): + assert variant is None, "Unsupported variant %s" % variant + self.reset = Signal() + self.ibus = wishbone.Interface() + self.dbus = wishbone.Interface() + self.interrupt = Signal(32) + + ### + + self.submodules.cpu = MinervaCPU(reset_address=cpu_reset_address) + self.comb += [ + self.cpu.reset.eq(self.reset), + self.cpu.external_interrupt.eq(self.interrupt), + self.cpu.ibus.connect(self.ibus), + self.cpu.dbus.connect(self.dbus) + ] diff --git a/litex/soc/integration/cpu_interface.py b/litex/soc/integration/cpu_interface.py index e75b2847..6ac13811 100644 --- a/litex/soc/integration/cpu_interface.py +++ b/litex/soc/integration/cpu_interface.py @@ -10,7 +10,8 @@ cpu_endianness = { "lm32": "big", "or1k": "big", "picorv32": "little", - "vexriscv": "little" + "vexriscv": "little", + "minerva": "little", } def get_cpu_mak(cpu, variant): @@ -54,6 +55,14 @@ def get_cpu_mak(cpu, variant): triple = "riscv32-unknown-elf" cpuflags = "-D__vexriscv__ -march=rv32im -mabi=ilp32" clang = False + elif cpu == "minerva": + assert not clang, "minerva not supported with clang." + if which("riscv64-unknown-elf-gcc"): + triple = "riscv64-unknown-elf" + else: + triple = "riscv32-unknown-elf" + cpuflags = "-D__minerva__ -march=rv32i -mabi=ilp32" + clang = False else: raise ValueError("Unsupported CPU type: "+cpu) @@ -72,7 +81,8 @@ def get_linker_output_format(cpu_type): "lm32": "elf32-lm32", "or1k": "elf32-or1k", "picorv32": "elf32-littleriscv", - "vexriscv": "elf32-littleriscv" + "vexriscv": "elf32-littleriscv", + "minerva": "elf32-littleriscv", } return "OUTPUT_FORMAT(\"" + linker_output_formats[cpu_type] + "\")\n" diff --git a/litex/soc/integration/soc_core.py b/litex/soc/integration/soc_core.py index 6a7bbd40..f407cd0b 100644 --- a/litex/soc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -4,7 +4,7 @@ from operator import itemgetter from migen import * from litex.soc.cores import identifier, timer, uart -from litex.soc.cores.cpu import lm32, mor1kx, picorv32, vexriscv +from litex.soc.cores.cpu import lm32, mor1kx, picorv32, vexriscv, minerva from litex.soc.interconnect.csr import * from litex.soc.interconnect import wishbone, csr_bus, wishbone2csr from litex.soc.integration.cpu_interface import cpu_endianness @@ -149,6 +149,8 @@ class SoCCore(Module): self.add_cpu_or_bridge(picorv32.PicoRV32(platform, self.cpu_reset_address, self.cpu_variant)) elif cpu_type == "vexriscv": self.add_cpu_or_bridge(vexriscv.VexRiscv(platform, self.cpu_reset_address, self.cpu_variant)) + elif cpu_type == "minerva": + self.add_cpu_or_bridge(minerva.Minerva(platform, self.cpu_reset_address, self.cpu_variant)) else: raise ValueError("Unsupported CPU type: {}".format(cpu_type)) self.add_wb_master(self.cpu_or_bridge.ibus) @@ -358,7 +360,7 @@ class SoCCore(Module): def soc_core_args(parser): parser.add_argument("--cpu-type", default=None, - help="select CPU: lm32, or1k, riscv32") + help="select CPU: lm32, mor1kx, picorv32, vexriscv, minerva") parser.add_argument("--cpu-variant", default=None, help="select CPU variant") parser.add_argument("--integrated-rom-size", default=None, type=int, diff --git a/litex/soc/software/bios/boot-helper-minerva.S b/litex/soc/software/bios/boot-helper-minerva.S new file mode 100644 index 00000000..e8bd5c76 --- /dev/null +++ b/litex/soc/software/bios/boot-helper-minerva.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 239920bd..fa5b1533 100644 --- a/litex/soc/software/bios/main.c +++ b/litex/soc/software/bios/main.c @@ -514,6 +514,8 @@ int main(int i, char **c) printf("PicoRV32"); #elif __vexriscv__ printf("VexRiscv"); +#elif __minerva__ + printf("Minerva"); #else printf("Unknown"); #endif diff --git a/litex/soc/software/bios/sdram.c b/litex/soc/software/bios/sdram.c index 76c5f13e..a5496fc2 100644 --- a/litex/soc/software/bios/sdram.c +++ b/litex/soc/software/bios/sdram.c @@ -22,6 +22,8 @@ static void cdelay(int i) __asm__ volatile("nop"); #elif defined (__vexriscv__) __asm__ volatile("nop"); +#elif defined (__minerva__) + __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 83d1ace5..19f00b1c 100644 --- a/litex/soc/software/include/base/irq.h +++ b/litex/soc/software/include/base/irq.h @@ -40,6 +40,8 @@ static inline unsigned int irq_getie(void) return _irq_enabled != 0; #elif defined (__vexriscv__) return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; +#elif defined (__minerva__) + return (csrr(mstatus) & CSR_MSTATUS_MIE) != 0; #else #error Unsupported architecture #endif @@ -61,6 +63,8 @@ static inline void irq_setie(unsigned int ie) _irq_disable(); #elif defined (__vexriscv__) if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); +#elif defined (__minerva__) + if(ie) csrs(mstatus,CSR_MSTATUS_MIE); else csrc(mstatus,CSR_MSTATUS_MIE); #else #error Unsupported architecture #endif @@ -82,6 +86,10 @@ static inline unsigned int irq_getmask(void) unsigned int mask; asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); return mask; +#elif defined (__minerva__) + unsigned int mask; + asm volatile ("csrr %0, %1" : "=r"(mask) : "i"(CSR_IRQ_MASK)); + return mask; #else #error Unsupported architecture #endif @@ -99,6 +107,8 @@ static inline void irq_setmask(unsigned int mask) _irq_setmask(~mask); #elif defined (__vexriscv__) asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); +#elif defined (__minerva__) + asm volatile ("csrw %0, %1" :: "i"(CSR_IRQ_MASK), "r"(mask)); #else #error Unsupported architecture #endif @@ -118,6 +128,10 @@ static inline unsigned int irq_pending(void) unsigned int pending; asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING)); return pending; +#elif defined (__minerva__) + unsigned int pending; + asm volatile ("csrr %0, %1" : "=r"(pending) : "i"(CSR_IRQ_PENDING)); + return pending; #else #error Unsupported architecture #endif diff --git a/litex/soc/software/include/base/system.h b/litex/soc/software/include/base/system.h index 27f45403..2d108d2c 100644 --- a/litex/soc/software/include/base/system.h +++ b/litex/soc/software/include/base/system.h @@ -27,7 +27,7 @@ static inline void mtspr(unsigned long add, unsigned long val) #endif -#if defined(__vexriscv__) +#if defined(__vexriscv__) || defined(__minerva__) #include #define csrr(reg) ({ unsigned long __tmp; \ asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ diff --git a/litex/soc/software/libbase/crt0-minerva.S b/litex/soc/software/libbase/crt0-minerva.S new file mode 100644 index 00000000..6f6e9e6c --- /dev/null +++ b/litex/soc/software/libbase/crt0-minerva.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 8ad76066..83ffd4e5 100644 --- a/litex/soc/software/libbase/system.c +++ b/litex/soc/software/libbase/system.c @@ -4,7 +4,7 @@ #include #endif -#ifdef __vexriscv__ +#if defined (__vexriscv___) || defined(__minerva__) #include #endif @@ -50,6 +50,9 @@ void flush_cpu_icache(void) "nop\n" "nop\n" ); +#elif defined (__minerva__) + /* no instruction cache */ + asm volatile("nop"); #else #error Unsupported architecture #endif @@ -89,6 +92,9 @@ void flush_cpu_dcache(void) for(register unsigned long idx = 0;idx < cache_way_size;idx += cache_line_size){ asm volatile("mv x10, %0 \n .word(0b01110000000001010101000000001111)"::"r"(idx)); } +#elif defined (__minerva__) + /* no data cache */ + asm volatile("nop"); #else #error Unsupported architecture #endif