adopt github PR98 (No need to store TRAPFRAME in sscratch register)

This commit is contained in:
Robert Morris 2022-08-09 11:44:02 -04:00
parent ca6fc54934
commit 9fc9f755e1
3 changed files with 31 additions and 26 deletions

View file

@ -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

View file

@ -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.

View file

@ -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,