Add test firmware
authorJean THOMAS <git0@pub.jeanthomas.me>
Wed, 10 Jun 2020 14:51:03 +0000 (16:51 +0200)
committerJean THOMAS <git0@pub.jeanthomas.me>
Wed, 10 Jun 2020 14:51:03 +0000 (16:51 +0200)
examples/firmware/.gitignore [new file with mode: 0644]
examples/firmware/Makefile [new file with mode: 0644]
examples/firmware/entry.S [new file with mode: 0644]
examples/firmware/link.ld [new file with mode: 0644]
examples/firmware/main.c [new file with mode: 0644]

diff --git a/examples/firmware/.gitignore b/examples/firmware/.gitignore
new file mode 100644 (file)
index 0000000..64c574e
--- /dev/null
@@ -0,0 +1,3 @@
+*.o
+*.bin
+*.elf
diff --git a/examples/firmware/Makefile b/examples/firmware/Makefile
new file mode 100644 (file)
index 0000000..f86e259
--- /dev/null
@@ -0,0 +1,26 @@
+OBJS := main.o entry.o
+
+TRIPLE := riscv64-unknown-elf
+
+CC      := $(TRIPLE)-gcc
+AS      := $(TRIPLE)-as
+OBJCOPY := $(TRIPLE)-objcopy
+PYTHON  := python
+
+CFLAGS  := -march=rv32i -mabi=ilp32 -nostdlib -Os -I../../libgram/include
+LDFLAGS := -march=rv32i -mabi=ilp32 -nostdlib -Tlink.ld -L../../libgram -lgram
+
+%.o: %.c
+       $(CC) $(CFLAGS) -c $< -o $@
+
+%.o: %.S
+       $(CC) $(CFLAGS) -c $< -o $@
+
+main.bin: $(OBJS) link.ld ../../libgram/libgram.a
+       $(CC) $(LDFLAGS) $(OBJS) ../../libgram/libgram.a -o main.elf
+       $(OBJCOPY) -O binary main.elf main.bin
+
+main.img.bin: main.bin
+       $(PYTHON) -m lambdasoc.software.bios.util.mkmscimg --little $< -o $@
+
+all: main.img.bin
diff --git a/examples/firmware/entry.S b/examples/firmware/entry.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
diff --git a/examples/firmware/link.ld b/examples/firmware/link.ld
new file mode 100644 (file)
index 0000000..1cc22fe
--- /dev/null
@@ -0,0 +1,59 @@
+OUTPUT_FORMAT("elf32-littleriscv")
+ENTRY(_start)
+
+MEMORY
+{
+       rom : ORIGIN = 0x00007000, LENGTH = 0x1000
+       ram : ORIGIN = 0x00004000, LENGTH = 0x1000
+}
+
+SECTIONS
+{
+       .text :
+       {
+               _ftext = .;
+               *entry*.o(.text)
+               *(.text .stub .text.* .gnu.linkonce.t.*)
+               _etext = .;
+       } > rom
+
+       .rodata :
+       {
+               . = ALIGN(8);
+               _frodata = .;
+               *(.rodata .rodata.* .gnu.linkonce.r.*)
+               *(.rodata1)
+
+               /* Make sure the file is aligned on disk as well
+                  as in memory; CRC calculation requires that. */
+               FILL(0);
+               . = ALIGN(8);
+               _erodata = .;
+       } > rom
+
+       .bss :
+       {
+               . = ALIGN(8);
+               _fbss = .;
+               *(.dynsbss)
+               *(.sbss .sbss.* .gnu.linkonce.sb.*)
+               *(.scommon)
+               *(.dynbss)
+               *(.bss .bss.* .gnu.linkonce.b.*)
+               *(COMMON)
+               . = ALIGN(8);
+               _ebss = .;
+               _end = .;
+       } > ram
+
+       /DISCARD/ :
+       {
+               *(.eh_frame)
+               *(.comment)
+               *(.data .data.* .gnu.linkonce.d.*)
+               *(.data1)
+               *(.sdata .sdata.* .gnu.linkonce.s.*)
+       }
+}
+
+PROVIDE(_fstack = ORIGIN(ram) + LENGTH(ram) - 8);
diff --git a/examples/firmware/main.c b/examples/firmware/main.c
new file mode 100644 (file)
index 0000000..6c12a4e
--- /dev/null
@@ -0,0 +1,69 @@
+#include <stdlib.h>
+#include <stdint.h>
+#include <gram.h>
+
+static inline uint32_t read32(const void *addr)
+{
+       return *(volatile uint32_t *)addr;
+}
+
+static inline void write32(void *addr, uint32_t value)
+{
+       *(volatile uint32_t *)addr = value;
+}
+
+struct uart_regs {
+       uint32_t divisor;
+       uint32_t rx_data;
+       uint32_t rx_rdy;
+       uint32_t rx_err;
+       uint32_t tx_data;
+       uint32_t tx_rdy;
+       uint32_t zero0; // reserved
+       uint32_t zero1; // reserved
+       uint32_t ev_status;
+       uint32_t ev_pending;
+       uint32_t ev_enable;
+};
+
+void uart_write(char c)
+{
+       struct uart_regs *regs = 0x5000;
+       while (!read32(&regs->tx_rdy));
+       write32(&regs->tx_data, c);
+}
+
+void uart_writestr(const char *c) {
+       while (*c) {
+               uart_write(*c);
+               c++;
+       }
+}
+
+void isr(void) {
+
+}
+
+int main(void) {
+       uart_writestr("Firmware launched...\n");
+
+       uart_writestr("DRAM init... ");
+       struct gramCtx ctx;
+       gram_init(&ctx, (void*)0x10000000, (void*)0x00009000, (void*)0x00008000);
+       uart_writestr("done\n");
+
+       uart_writestr("DRAM test... ");
+       volatile uint32_t *ram = 0x10000000;
+       for (size_t i = 0; i < 1000; i++) {
+               ram[i] = 0xdeadbeef << (i%32);
+       }
+
+       for (size_t i = 0; i < 1000; i++) {
+               if (ram[i] != 0xdeadbeef << (i%32)) {
+                       uart_writestr("fail\n");
+               }
+       }
+       uart_writestr("done\n");
+
+       return 0;
+}
\ No newline at end of file