diff options
Diffstat (limited to 'src/kernel/trap')
| -rw-r--r-- | src/kernel/trap/handler.cc | 50 | ||||
| -rw-r--r-- | src/kernel/trap/trampoline.S | 98 | ||||
| -rw-r--r-- | src/kernel/trap/trap.S | 10 |
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 |
