diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/riscv.h | 9 | ||||
| -rw-r--r-- | kernel/trampoline.S | 37 | ||||
| -rw-r--r-- | kernel/trap.c | 11 | 
3 files changed, 31 insertions, 26 deletions
| diff --git a/kernel/riscv.h b/kernel/riscv.h index 1691faf..1f8a503 100644 --- a/kernel/riscv.h +++ b/kernel/riscv.h @@ -1,3 +1,5 @@ +#ifndef __ASSEMBLER__ +  // which hart (core) is this?  static inline uint64  r_mhartid() @@ -331,6 +333,10 @@ sfence_vma()    asm volatile("sfence.vma zero, zero");  } +typedef uint64 pte_t; +typedef uint64 *pagetable_t; // 512 PTEs + +#endif // __ASSEMBLER__  #define PGSIZE 4096 // bytes per page  #define PGSHIFT 12  // bits of offset within a page @@ -361,6 +367,3 @@ sfence_vma()  // Sv39, to avoid having to sign-extend virtual addresses  // that have the high bit set.  #define MAXVA (1L << (9 + 9 + 9 + 12 - 1)) - -typedef uint64 pte_t; -typedef uint64 *pagetable_t; // 512 PTEs diff --git a/kernel/trampoline.S b/kernel/trampoline.S index fabaaf9..2ce4886 100644 --- a/kernel/trampoline.S +++ b/kernel/trampoline.S @@ -8,6 +8,10 @@  	# kernel.ld causes this to be aligned          # to a page boundary.          # + +#include "riscv.h" +#include "memlayout.h" +  	.section trampsec  .globl trampoline  trampoline: @@ -20,14 +24,16 @@ uservec:          # in supervisor mode, but with a          # user page table.          # -        # sscratch points to where the process's p->trapframe is -        # mapped into user space, at TRAPFRAME. -        # -         -	# swap a0 and sscratch -        # so that a0 is TRAPFRAME -        csrrw a0, sscratch, a0 +        # save user a0 in sscratch so +        # a0 can be used to get at TRAPFRAME. +        csrw sscratch, a0 + +        # each process has a separate p->trapframe memory area, +        # but it's mapped to the same virtual address +        # (TRAPFRAME) in every process. +        li a0, TRAPFRAME +                  # save the user registers in TRAPFRAME          sd ra, 40(a0)          sd sp, 48(a0) @@ -86,20 +92,15 @@ uservec:  .globl userret  userret: -        # userret(TRAPFRAME, pagetable) +        # userret(pagetable)          # switch from kernel to user. -        # usertrapret() calls here. -        # a0: TRAPFRAME, in user page table. -        # a1: user page table, for satp. +        # a0: user page table, for satp.          # switch to the user page table. -        csrw satp, a1 +        csrw satp, a0          sfence.vma zero, zero -        # put the saved user a0 in sscratch, so we -        # can swap it with our a0 (TRAPFRAME) in the last step. -        ld t0, 112(a0) -        csrw sscratch, t0 +        li a0, TRAPFRAME          # restore all but a0 from TRAPFRAME          ld ra, 40(a0) @@ -133,8 +134,8 @@ userret:          ld t5, 272(a0)          ld t6, 280(a0) -	# restore user a0, and save TRAPFRAME in sscratch -        csrrw a0, sscratch, a0 +	# restore user a0 +        ld a0, 112(a0)          # return to user mode and user pc.          # usertrapret() set up sstatus and sepc. diff --git a/kernel/trap.c b/kernel/trap.c index a63249e..75fb3ec 100644 --- a/kernel/trap.c +++ b/kernel/trap.c @@ -96,8 +96,9 @@ usertrapret(void)    // we're back in user space, where usertrap() is correct.    intr_off(); -  // send syscalls, interrupts, and exceptions to trampoline.S -  w_stvec(TRAMPOLINE + (uservec - trampoline)); +  // send syscalls, interrupts, and exceptions to uservec in trampoline.S +  uint64 trampoline_uservec = TRAMPOLINE + (uservec - trampoline); +  w_stvec(trampoline_uservec);    // set up trapframe values that uservec will need when    // the process next re-enters the kernel. @@ -121,11 +122,11 @@ usertrapret(void)    // tell trampoline.S the user page table to switch to.    uint64 satp = MAKE_SATP(p->pagetable); -  // jump to trampoline.S at the top of memory, which  +  // jump to userret in trampoline.S at the top of memory, which     // switches to the user page table, restores user registers,    // and switches to user mode with sret. -  uint64 fn = TRAMPOLINE + (userret - trampoline); -  ((void (*)(uint64,uint64))fn)(TRAPFRAME, satp); +  uint64 trampoline_userret = TRAMPOLINE + (userret - trampoline); +  ((void (*)(uint64))trampoline_userret)(satp);  }  // interrupts and exceptions from kernel code go here via kernelvec, | 
