adopt github PR98 (No need to store TRAPFRAME in sscratch register)
This commit is contained in:
parent
ca6fc54934
commit
9fc9f755e1
|
@ -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
|
||||
|
|
|
@ -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,13 +24,15 @@ 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)
|
||||
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in a new issue