summaryrefslogtreecommitdiff
path: root/src/kernel/trap
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/trap')
-rw-r--r--src/kernel/trap/handler.cc50
-rw-r--r--src/kernel/trap/trampoline.S98
-rw-r--r--src/kernel/trap/trap.S10
3 files changed, 153 insertions, 5 deletions
diff --git a/src/kernel/trap/handler.cc b/src/kernel/trap/handler.cc
index df4f202..4bb8c06 100644
--- a/src/kernel/trap/handler.cc
+++ b/src/kernel/trap/handler.cc
@@ -4,6 +4,7 @@
#include "kernel/proc.h"
#include "kernel/timer.h"
+extern void usertrapret();
void panic(const char *s)
{
@@ -123,4 +124,53 @@ namespace Trap
}
}
}
+}
+
+extern "C" void usertrap()
+{
+ asm volatile("csrw stvec, %0" : : "r"(Trap::kernelvec));
+
+ uint64 scause;
+ asm volatile("csrr %0, scause" : "=r"(scause));
+
+ struct Proc *p = myproc();
+
+ extern struct Proc procs[];
+ for(int i = 0; i < 10; ++i)
+ if(procs[i].state == RUNNING)
+ p = &procs[i];
+
+ uint64 sepc;
+ asm volatile("csrr %0, sepc" : "=r"(sepc));
+ p->tf->epc = sepc;
+
+ if(scause == 8)
+ {
+ p->tf->epc += 4;
+
+ uint64 syscall_num = p->tf->a7;
+
+ if (syscall_num == 1)
+ {
+ char c = (char)p->tf->a0;
+ Drivers::uart_putc(c);
+ }
+ else
+ {
+ Drivers::uart_puts("Unknown Syscall\n");
+ }
+ }
+ else if ((scause & (1L << 63)) && (scause & 0xF) == 5)
+ {
+ Timer::set_next_trigger();
+ ProcManager::yield();
+ }
+ else
+ {
+ Drivers::uart_puts("Unexpected User Trap!\n");
+ while (1)
+ ;
+ }
+
+ forkret();
} \ No newline at end of file
diff --git a/src/kernel/trap/trampoline.S b/src/kernel/trap/trampoline.S
new file mode 100644
index 0000000..478d345
--- /dev/null
+++ b/src/kernel/trap/trampoline.S
@@ -0,0 +1,98 @@
+.section .text
+.globl trampoline
+.globl uservec
+.globl userret
+
+.align 12
+trampoline:
+.align 4
+uservec:
+
+ csrrw a0, sscratch, a0
+
+ sd ra, 40(a0)
+ sd sp, 48(a0)
+ sd gp, 56(a0)
+ sd tp, 64(a0)
+ sd t0, 72(a0)
+ sd t1, 80(a0)
+ sd t2, 88(a0)
+ sd s0, 96(a0)
+ sd s1, 104(a0)
+ sd a1, 120(a0)
+ sd a2, 128(a0)
+ sd a3, 136(a0)
+ sd a4, 144(a0)
+ sd a5, 152(a0)
+ sd a6, 160(a0)
+ sd a7, 168(a0)
+ sd s2, 176(a0)
+ sd s3, 184(a0)
+ sd s4, 192(a0)
+ sd s5, 200(a0)
+ sd s6, 208(a0)
+ sd s7, 216(a0)
+ sd s8, 224(a0)
+ sd s9, 232(a0)
+ sd s10, 240(a0)
+ sd s11, 248(a0)
+ sd t3, 256(a0)
+ sd t4, 264(a0)
+ sd t5, 272(a0)
+ sd t6, 280(a0)
+
+ csrr t0, sscratch
+ sd t0, 112(a0)
+
+ ld sp, 8(a0)
+ ld tp, 32(a0)
+ ld t0, 16(a0)
+ ld t1, 0(a0)
+
+ csrw satp, t1
+ sfence.vma zero, zero
+
+ jr t0
+
+.align 4
+userret:
+
+ csrw satp, a1
+ sfence.vma zero, zero
+
+ csrw sscratch, a0
+
+ ld ra, 40(a0)
+ ld sp, 48(a0)
+ ld gp, 56(a0)
+ ld tp, 64(a0)
+ ld t0, 72(a0)
+ ld t1, 80(a0)
+ ld t2, 88(a0)
+ ld s0, 96(a0)
+ ld s1, 104(a0)
+ ld a1, 120(a0)
+ ld a2, 128(a0)
+ ld a3, 136(a0)
+ ld a4, 144(a0)
+ ld a5, 152(a0)
+ ld a6, 160(a0)
+ ld a7, 168(a0)
+ ld s2, 176(a0)
+ ld s3, 184(a0)
+ ld s4, 192(a0)
+ ld s5, 200(a0)
+ ld s6, 208(a0)
+ ld s7, 216(a0)
+ ld s8, 224(a0)
+ ld s9, 232(a0)
+ ld s10, 240(a0)
+ ld s11, 248(a0)
+ ld t3, 256(a0)
+ ld t4, 264(a0)
+ ld t5, 272(a0)
+ ld t6, 280(a0)
+
+ ld a0, 112(a0)
+
+ sret \ No newline at end of file
diff --git a/src/kernel/trap/trap.S b/src/kernel/trap/trap.S
index ffce52a..573248e 100644
--- a/src/kernel/trap/trap.S
+++ b/src/kernel/trap/trap.S
@@ -1,10 +1,11 @@
.section .text
.global kernelvec
-.align 4
+.global uservec
+.global userret
+.align 12
kernelvec:
-
- addi sp, sp, -256
+ addi sp, sp, -288
sd ra, 40(sp)
sd sp, 48(sp)
@@ -82,6 +83,5 @@ kernelvec:
ld t5, 272(sp)
ld t6, 280(sp)
- addi sp, sp, 256
-
+ addi sp, sp, 288
sret \ No newline at end of file