add Minerva support
authorJean-François Nguyen <jf@lambdaconcept.fr>
Wed, 5 Sep 2018 18:36:17 +0000 (20:36 +0200)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Wed, 5 Sep 2018 20:33:04 +0000 (22:33 +0200)
litex/soc/cores/cpu/minerva/__init__.py [new file with mode: 0644]
litex/soc/cores/cpu/minerva/core.py [new file with mode: 0644]
litex/soc/integration/cpu_interface.py
litex/soc/integration/soc_core.py
litex/soc/software/bios/boot-helper-minerva.S [new file with mode: 0644]
litex/soc/software/bios/main.c
litex/soc/software/bios/sdram.c
litex/soc/software/include/base/irq.h
litex/soc/software/include/base/system.h
litex/soc/software/libbase/crt0-minerva.S [new file with mode: 0644]
litex/soc/software/libbase/system.c

diff --git a/litex/soc/cores/cpu/minerva/__init__.py b/litex/soc/cores/cpu/minerva/__init__.py
new file mode 100644 (file)
index 0000000..9ad8629
--- /dev/null
@@ -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 (file)
index 0000000..787c91e
--- /dev/null
@@ -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)
+        ]
index e75b28472c2967687eda65e1672e63bc4c2f1b9c..6ac138117c717ef94daa430f1e47616d0396be9e 100644 (file)
@@ -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"
 
index 6a7bbd40f93920c80649a02633395708003521b2..f407cd0bf08c58226e80f1a9636419089413f233 100644 (file)
@@ -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 (file)
index 0000000..e8bd5c7
--- /dev/null
@@ -0,0 +1,4 @@
+       .section .text, "ax", @progbits
+       .global boot_helper
+boot_helper:
+       jr x13
index 239920bdd44017d195a7286bf5721062cbd4fbd0..fa5b1533f3a819059637f3d6f233420c9e6deb14 100644 (file)
@@ -514,6 +514,8 @@ int main(int i, char **c)
        printf("PicoRV32");
 #elif __vexriscv__
        printf("VexRiscv");
+#elif __minerva__
+       printf("Minerva");
 #else
        printf("Unknown");
 #endif
index 76c5f13e7ae6091f34a8e822b6a6b386159e2414..a5496fc2b40bf1d0a6d41e0fb77fb97cf25fb9fa 100644 (file)
@@ -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
index 83d1ace5ce8fcbadea758c986ecd0decf033a9ed..19f00b1c55b34afb1e053ff8f6b7d0a334265094 100644 (file)
@@ -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
index 27f454032ff449c98777c318b72d3cd94f1bc28c..2d108d2c1a5ddcba882fdf2a746f4ff6343741d8 100644 (file)
@@ -27,7 +27,7 @@ static inline void mtspr(unsigned long add, unsigned long val)
 #endif
 
 
-#if defined(__vexriscv__)
+#if defined(__vexriscv__) || defined(__minerva__)
 #include <csr-defs.h>
 #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 (file)
index 0000000..6f6e9e6
--- /dev/null
@@ -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
index 8ad76066921c7ed1bb31445f67eb66337aacb3fc..83ffd4e5b0fb683d8759011df3894b06d8282897 100644 (file)
@@ -4,7 +4,7 @@
 #include <spr-defs.h>
 #endif
 
-#ifdef __vexriscv__
+#if defined (__vexriscv___) || defined(__minerva__)
 #include <csr-defs.h>
 #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