commit fd35517351566adb975cfdfc44ee161ba9668aff
parent 7c287998a02dd6c4033142c34776fdaa04a0fb3d
Author: Brian Swetland <swetland@frotz.net>
Date: Mon, 25 Apr 2022 01:17:28 -0700
traps: test trap handling from svc mode
- installs general purpose trap handler (some dump state)
- enable sw ints to get timer ticks from the bios
- enter user mode
Diffstat:
3 files changed, 180 insertions(+), 0 deletions(-)
diff --git a/misc/traps-entry.S b/misc/traps-entry.S
@@ -0,0 +1,109 @@
+// Copyright 2022, Brian Swetland <swetland@frotz.net>
+// Licensed under the Apache License, Version 2.0
+
+#include <hw/riscv.h>
+
+.globl svc_exception_entry
+svc_exception_entry:
+ // swap active sp with value in SSCRATCH (svc stack)
+ // interupts have been disabled on exception entry
+ csrrw sp, CSR_SSCRATCH, sp
+
+ // todo: beqz svc_nested_irq_entry
+
+ // save previous registers to stack
+ addi sp, sp, - (32 * 4)
+ sw x1, 0x04(sp)
+ sw x3, 0x0C(sp)
+ sw x4, 0x10(sp)
+ sw x5, 0x14(sp)
+ sw x6, 0x18(sp)
+ sw x7, 0x1C(sp)
+ sw x8, 0x20(sp)
+ sw x9, 0x24(sp)
+ sw x10, 0x28(sp)
+ sw x11, 0x2C(sp)
+ sw x12, 0x30(sp)
+ sw x13, 0x34(sp)
+ sw x14, 0x38(sp)
+ sw x15, 0x3C(sp)
+ sw x16, 0x40(sp)
+ sw x17, 0x44(sp)
+ sw x18, 0x48(sp)
+ sw x19, 0x4C(sp)
+ sw x20, 0x50(sp)
+ sw x21, 0x54(sp)
+ sw x22, 0x58(sp)
+ sw x23, 0x5C(sp)
+ sw x24, 0x60(sp)
+ sw x25, 0x64(sp)
+ sw x26, 0x68(sp)
+ sw x27, 0x6C(sp)
+ sw x28, 0x70(sp)
+ sw x29, 0x74(sp)
+ sw x30, 0x78(sp)
+ sw x31, 0x7C(sp)
+
+ // save user pc (hw stashed it in SEPC)
+ csrr t0, CSR_SEPC
+ sw t0, 0x00(sp)
+
+ // save user sp (we stashed it in SSCRATCH)
+ // and stick 0 in CSR_SSCRATCH so we can detect nested irqs
+ csrrw t0, CSR_SSCRATCH, x0
+ sw t0, 0x08(sp)
+
+ mv a0, sp
+ jal svc_exception_handler
+
+ // save svc sp in SSCRATCH for next interrupt
+ addi t0, sp, (32 * 4)
+ csrw CSR_SSCRATCH, t0
+
+ // user pc goes into SEPC for sret
+ lw t0, 0x00(sp)
+ csrw CSR_SEPC, t0
+
+ lw x1, 0x04(sp)
+ lw x3, 0x0C(sp)
+ lw x4, 0x10(sp)
+ lw x5, 0x14(sp)
+ lw x6, 0x18(sp)
+ lw x7, 0x1C(sp)
+ lw x8, 0x20(sp)
+ lw x9, 0x24(sp)
+ lw x10, 0x28(sp)
+ lw x11, 0x2C(sp)
+ lw x12, 0x30(sp)
+ lw x13, 0x34(sp)
+ lw x14, 0x38(sp)
+ lw x15, 0x3C(sp)
+ lw x16, 0x40(sp)
+ lw x17, 0x44(sp)
+ lw x18, 0x48(sp)
+ lw x19, 0x4C(sp)
+ lw x20, 0x50(sp)
+ lw x21, 0x54(sp)
+ lw x22, 0x58(sp)
+ lw x23, 0x5C(sp)
+ lw x24, 0x60(sp)
+ lw x25, 0x64(sp)
+ lw x26, 0x68(sp)
+ lw x27, 0x6C(sp)
+ lw x28, 0x70(sp)
+ lw x29, 0x74(sp)
+ lw x30, 0x78(sp)
+ lw x31, 0x7C(sp)
+
+ // grab user sp back off of the svc stack
+ lw sp, 0x08(sp)
+
+ // save previous pc (hw stashed it in MEPC)
+ sret
+
+.globl enter_mode_u
+enter_mode_u: // (a0, a1, user_pc, user_sp)
+ csrw CSR_SEPC, a2
+ mv sp, a3
+ sret
+
diff --git a/misc/traps.c b/misc/traps.c
@@ -0,0 +1,66 @@
+// Copyright 2022, Brian Swetland <swetland@frotz.net>
+// Licensed under the Apache License, Version 2.0
+
+#include <hw/riscv.h>
+#include <hw/debug.h>
+
+#define MEMORY_BASE (0x80000000)
+#define MEMORY_SIZE (128*1024*1024)
+#define MEMORY_TOP (MEMORY_BASE + MEMORY_SIZE)
+
+#define SVC_SP (MEMORY_TOP)
+#define USER_SP (MEMORY_TOP - (1024*1024))
+
+extern void svc_exception_entry(void);
+
+void svc_exception_handler(uint32_t regs[32]) {
+ uint32_t cause = csr_read(CSR_SCAUSE);
+ uint32_t val = csr_read(CSR_STVAL);
+ xprintf("SUPERVISOR EXCEPTION %08x %08x %08x\n",
+ cause, val, (unsigned) regs);
+
+ xprintf("pc %08x ra %08x sp %08x gp %08x\n",
+ regs[0], regs[1], regs[2], regs[3]);
+ xprintf("tp %08x t0 %08x t1 %08x t2 %08x\n",
+ regs[4], regs[5], regs[6], regs[7]);
+ xprintf("fp %08x s1 %08x a0 %08x a1 %08x\n",
+ regs[8], regs[9], regs[10], regs[11]);
+ xprintf("a2 %08x a3 %08x a4 %08x a5 %08x\n",
+ regs[12], regs[13], regs[14], regs[15]);
+
+ if (cause == EXCn_ECALL_UMODE) {
+ // advance return address to next instr
+ regs[0] += 4;
+ }
+
+ csr_clr(CSR_SIP, INTb_SVC_SW);
+}
+
+void enter_mode_u(uint32_t a0, uint32_t a1, uint32_t user_pc, uint32_t user_sp);
+
+void user_start(uint32_t hartid, uint32_t fdt) {
+ xprintf("Hello, User Mode hartid=%08x fdt=%08x\n", hartid, fdt);
+
+ // illegal write from user mode
+ // csr_write(CSR_MEPC, 0x42);
+
+ // syscall
+ asm volatile ("ecall");
+
+ for (;;) ;
+}
+
+void start(uint32_t hartid, uint32_t fdt) {
+ xprintf("Hello, Trap Test %08x %08x\n", hartid, fdt);
+
+ // set svc exception vector and stack pointer
+ csr_write(CSR_STVEC, (uintptr_t) svc_exception_entry);
+ csr_write(CSR_SSCRATCH, SVC_SP);
+
+ csr_set(CSR_SIE, INTb_SVC_SW);
+
+ enter_mode_u(hartid, fdt, (uintptr_t)user_start, USER_SP);
+
+ for (;;) ;
+}
+
diff --git a/project/traps.mk b/project/traps.mk
@@ -0,0 +1,5 @@
+
+APP_NAME := traps
+APP_SRC := hw/src/start.S misc/traps-entry.S misc/traps.c
+APP_SRC += hw/src/debug.c $(LIBC_SRC)
+include make/app.mk