From 9c936f211c626d0c83252e76a64c45e81e56e723 Mon Sep 17 00:00:00 2001 From: Stefan Date: Tue, 17 Aug 2021 09:37:49 +0200 Subject: [PATCH] add bare-metal test image and update .gitignore --- .gitignore | 4 ++ bare_metal_test/Makefile | 34 +++++++++ bare_metal_test/bare | Bin 0 -> 6336 bytes bare_metal_test/bare.c | 52 ++++++++++++++ bare_metal_test/init.S | 137 +++++++++++++++++++++++++++++++++++++ bare_metal_test/riscv32.ld | 34 +++++++++ 6 files changed, 261 insertions(+) create mode 100644 bare_metal_test/Makefile create mode 100755 bare_metal_test/bare create mode 100644 bare_metal_test/bare.c create mode 100644 bare_metal_test/init.S create mode 100644 bare_metal_test/riscv32.ld diff --git a/.gitignore b/.gitignore index 7af67f87..aceeab82 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,7 @@ rust_payload/target rust_payload/Cargo.lock fw_payload.* *.dtb +*.bmp +*.bin +*.elf +*.img diff --git a/bare_metal_test/Makefile b/bare_metal_test/Makefile new file mode 100644 index 00000000..0b316554 --- /dev/null +++ b/bare_metal_test/Makefile @@ -0,0 +1,34 @@ +TARGET ?= bare +SRC_DIRS ?= . + +PREFIX ?= ../buildroot-2021.05/output/host/bin/riscv32-buildroot-linux-gnu- +CC := $(PREFIX)cc +AS := $(PREFIX)as +LD := $(PREFIX)ld +OBJDUMP := $(PREFIX)objcopy + +SRCS := $(wildcard *.S) +SRCS += $(wildcard *.c) +OBJS := $(addsuffix .o,$(basename $(SRCS))) +DEPS := $(OBJS:.o=.d) + +INC_DIRS := $(shell find $(SRC_DIRS) -type d) +INC_FLAGS := $(addprefix -I,$(INC_DIRS)) + +CFLAGS += -O3 -march=rv32ima -mabi=ilp32 -fno-stack-protector -fno-pie +ASFLAGS += -march=rv32ima -mabi=ilp32 +LDFLAGS += -static -nostdlib -nostartfiles -nodefaultlibs -Triscv32.ld -Wl,--no-as-needed + +$(TARGET): $(OBJS) + $(CC) $(LDFLAGS) $(OBJS) -o $@ $(LOADLIBES) $(LDLIBS) + +$(TARGET).img: $(TARGET) + riscv32-elf-objcopy -O binary $< $@ + +.PHONY: clean +clean: + $(RM) $(TARGET) $(OBJS) $(DEPS) + +.PHONY: run +run: $(TARGET).img + ../rvc -d ../dts.dtb -b $(TARGET).img diff --git a/bare_metal_test/bare b/bare_metal_test/bare new file mode 100755 index 0000000000000000000000000000000000000000..45102ac32cbe02cc335d7bb7c315b41666eca303 GIT binary patch literal 6336 zcmeHLO-vg{6n?wo*)gb6otlPLRjbA0fFZD11Ohecfdtv4KT#7RHI-WAY-|Utf|u+r zN^+{v%8(L67yyDqnx5B5RwW{p`}&F(P;Jto^jAYg$#526Gzb?qUz-)d&BvackS)#pL1mU1^vj&Gf$99ot9 zF6gEWQ($B9$@Zlvk7eov$o^4~nR6hAE`uDlKpHne>Z__ueWl9ucdG3FL6wGtGG)bO`et1AKk7^E25P8?43r!A6V?aqbUg zIXhkB{^=vd`(| zioRr(E15ww1+jCwS8}~_WnQu z>80C+GL_n@4?h83AU${hFf%=UR?nPYDK8cs8;cs5pS&?XS(uy{DV81Y&Y(VO8e@h@ zke5-FjI8y-n&QyXRWd{7P-jgY-&Lz5Fo+$~@v*gy7-->}ZPOZqCokeCE#up45T*eB zG#?WA-$sq{(_60s9Qu*d`GiyO#0>IZ6{x<4{57-~$lp+*dZDGCMSiW7KY{)n>PS`E zNWX~u8pi*E2M~T1^&c@`8ae5oBL~=DrJdrTTq%2o4S6?DbIg}2o^uE2k{JcS>E~Uy zybKmBJLQT8!IYbki0~}O%cE(&B?DbOSRw23idTR<4&N$#0bsaymOSe^a?c6)LMVBq z+a4H2%d^lMuf{e493x{LJDP?6Umg1=4)bHJB9hi(0Dv9^ig~$zuS_-8%_B#6wo4y w3s-yHpJJSe4m#r%Trphq&0V;H+l>O!UA&mZKy2>exhGI-k9&-9=U)={H|wAH+yDRo literal 0 HcmV?d00001 diff --git a/bare_metal_test/bare.c b/bare_metal_test/bare.c new file mode 100644 index 00000000..79c66384 --- /dev/null +++ b/bare_metal_test/bare.c @@ -0,0 +1,52 @@ +#include + +#define UART_THR (*(volatile unsigned char*)0x10000000) +#define UART_LSR (*(volatile unsigned char*)0x10000005) +#define UART_LSR_THRE 0x20 + +// wait for Transfer Hold Register to clear, then write character to print it +void uart_putc(unsigned char c) { + while (UART_THR || !(UART_LSR & UART_LSR_THRE)) {} + UART_THR = c; +} + +void print(const char* str) { + while (*str) { + uart_putc(*str++); + } +} + +static bool got_ssip = false; +volatile static long long a = 0xaaaaffffffff; + +// runs in supervisor mode via mideleg (machine-mode trap delegation) +void handle_trap(void) { + print("[bare/trap] got SSIP!\n"); + got_ssip = true; +} + +// called from assembly, runs in supervisor mode (via sret) +int main(void) { + print("[bare] in main()\n"); + + print("[bare] testing arithmetic...\n"); + + long long b = a * 400LLU * -1; + if (b != -0x10AAB2FFFFFFE70LL) { + print("[bare] got wrong result :(\n"); + } else { + print("[bare] got correct result!\n"); + } + + print("[bare] testing trap handler...\n"); + __asm volatile("csrw sip, 0x2"); + + while (!got_ssip) {} + + print("[bare] selftest done!\n"); + print("[bare] now go run something more exciting...\n"); + + while (true) {} + + return 0; +} diff --git a/bare_metal_test/init.S b/bare_metal_test/init.S new file mode 100644 index 00000000..16d2a6b8 --- /dev/null +++ b/bare_metal_test/init.S @@ -0,0 +1,137 @@ +#define SLL32 sll +#define STORE sw +#define LOAD lw +#define LWU lw +#define LOG_REGBYTES 2 +#define REGBYTES (1 << LOG_REGBYTES) + + .section .entry, "ax", %progbits + .align 4 + .globl _start +_start: + csrw mie, zero + csrw mip, zero + lla a3, _start_hang + csrw mtvec, a3 + lla a3, _s_trap_entry + csrw stvec, a3 + + # enable supervisor software interrupt + li a3, 0x2 + csrw sie, a3 + csrw mie, a3 + csrw mideleg, a3 + li a3, 0x00b + csrs mstatus, a3 + + lla sp, _estack + lla a3, main + csrw mepc, a3 + li a3, 0x800 + csrs mstatus, a3 + mret + j _start_hang + + .section .entry, "ax", %progbits + .align 4 + .globl _start_hang +_start_hang: + j _start_hang + + .section .entry, "ax", %progbits + .align 4 + .globl _trap_entry +_s_trap_entry: + + addi sp,sp,-320 + + # save gprs + STORE x1,1*REGBYTES(x2) + STORE x3,3*REGBYTES(x2) + STORE x4,4*REGBYTES(x2) + STORE x5,5*REGBYTES(x2) + STORE x6,6*REGBYTES(x2) + STORE x7,7*REGBYTES(x2) + STORE x8,8*REGBYTES(x2) + STORE x9,9*REGBYTES(x2) + STORE x10,10*REGBYTES(x2) + STORE x11,11*REGBYTES(x2) + STORE x12,12*REGBYTES(x2) + STORE x13,13*REGBYTES(x2) + STORE x14,14*REGBYTES(x2) + STORE x15,15*REGBYTES(x2) + STORE x16,16*REGBYTES(x2) + STORE x17,17*REGBYTES(x2) + STORE x18,18*REGBYTES(x2) + STORE x19,19*REGBYTES(x2) + STORE x20,20*REGBYTES(x2) + STORE x21,21*REGBYTES(x2) + STORE x22,22*REGBYTES(x2) + STORE x23,23*REGBYTES(x2) + STORE x24,24*REGBYTES(x2) + STORE x25,25*REGBYTES(x2) + STORE x26,26*REGBYTES(x2) + STORE x27,27*REGBYTES(x2) + STORE x28,28*REGBYTES(x2) + STORE x29,29*REGBYTES(x2) + STORE x30,30*REGBYTES(x2) + STORE x31,31*REGBYTES(x2) + + # get sr, epc, badvaddr, cause + csrr s0, sstatus + csrr t1, sepc + csrr t2, stval + csrr t3, scause + STORE t0, 2*REGBYTES(x2) + STORE s0, 32*REGBYTES(x2) + STORE t1, 33*REGBYTES(x2) + STORE t2, 34*REGBYTES(x2) + STORE t3, 35*REGBYTES(x2) + + move a0, sp + jal handle_trap + + mv a0, sp + addi sp, sp, 320 + + LOAD t0, 32*REGBYTES(a0) + LOAD t1, 33*REGBYTES(a0) + csrw sstatus, t0 + csrw sepc, t1 + + # restore x registers + LOAD x1,1*REGBYTES(a0) + LOAD x2,2*REGBYTES(a0) + LOAD x3,3*REGBYTES(a0) + LOAD x4,4*REGBYTES(a0) + LOAD x5,5*REGBYTES(a0) + LOAD x6,6*REGBYTES(a0) + LOAD x7,7*REGBYTES(a0) + LOAD x8,8*REGBYTES(a0) + LOAD x9,9*REGBYTES(a0) + LOAD x11,11*REGBYTES(a0) + LOAD x12,12*REGBYTES(a0) + LOAD x13,13*REGBYTES(a0) + LOAD x14,14*REGBYTES(a0) + LOAD x15,15*REGBYTES(a0) + LOAD x16,16*REGBYTES(a0) + LOAD x17,17*REGBYTES(a0) + LOAD x18,18*REGBYTES(a0) + LOAD x19,19*REGBYTES(a0) + LOAD x20,20*REGBYTES(a0) + LOAD x21,21*REGBYTES(a0) + LOAD x22,22*REGBYTES(a0) + LOAD x23,23*REGBYTES(a0) + LOAD x24,24*REGBYTES(a0) + LOAD x25,25*REGBYTES(a0) + LOAD x26,26*REGBYTES(a0) + LOAD x27,27*REGBYTES(a0) + LOAD x28,28*REGBYTES(a0) + LOAD x29,29*REGBYTES(a0) + LOAD x30,30*REGBYTES(a0) + LOAD x31,31*REGBYTES(a0) + # restore a0 last + LOAD x10,10*REGBYTES(a0) + + # gtfo + sret diff --git a/bare_metal_test/riscv32.ld b/bare_metal_test/riscv32.ld new file mode 100644 index 00000000..f609fa32 --- /dev/null +++ b/bare_metal_test/riscv32.ld @@ -0,0 +1,34 @@ +MEMORY +{ + RAM : ORIGIN = 0x80000000, LENGTH = 31M +} + +_estack = ORIGIN(RAM) + LENGTH(RAM); + +SECTIONS +{ + .text : + { + . = ALIGN(4); + *(.entry) + *(.text) + *(.text*) + *(.rodata) + *(.rodata*) + } >RAM + + .data : + { + . = ALIGN(4); + *(.data) + *(.data*) + } >RAM + + .bss : + { + . = ALIGN(4); + *(.bss) + *(.bss*) + *(COMMON) + } >RAM +}