From: Jean THOMAS Date: Wed, 10 Jun 2020 14:51:03 +0000 (+0200) Subject: Add test firmware X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=520d200c3f6c64e1a73f72dfed64158df64e8b50;p=gram.git Add test firmware --- diff --git a/examples/firmware/.gitignore b/examples/firmware/.gitignore new file mode 100644 index 0000000..64c574e --- /dev/null +++ b/examples/firmware/.gitignore @@ -0,0 +1,3 @@ +*.o +*.bin +*.elf diff --git a/examples/firmware/Makefile b/examples/firmware/Makefile new file mode 100644 index 0000000..f86e259 --- /dev/null +++ b/examples/firmware/Makefile @@ -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 index 0000000..6f6e9e6 --- /dev/null +++ b/examples/firmware/entry.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/examples/firmware/link.ld b/examples/firmware/link.ld new file mode 100644 index 0000000..1cc22fe --- /dev/null +++ b/examples/firmware/link.ld @@ -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 index 0000000..6c12a4e --- /dev/null +++ b/examples/firmware/main.c @@ -0,0 +1,69 @@ +#include +#include +#include + +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(®s->tx_rdy)); + write32(®s->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