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,