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? // which hart (core) is this?
static inline uint64 static inline uint64
r_mhartid() r_mhartid()
@ -331,6 +333,10 @@ sfence_vma()
asm volatile("sfence.vma zero, zero"); 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 PGSIZE 4096 // bytes per page
#define PGSHIFT 12 // bits of offset within a 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 // Sv39, to avoid having to sign-extend virtual addresses
// that have the high bit set. // that have the high bit set.
#define MAXVA (1L << (9 + 9 + 9 + 12 - 1)) #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 # kernel.ld causes this to be aligned
# to a page boundary. # to a page boundary.
# #
#include "riscv.h"
#include "memlayout.h"
.section trampsec .section trampsec
.globl trampoline .globl trampoline
trampoline: trampoline:
@ -20,13 +24,15 @@ uservec:
# in supervisor mode, but with a # in supervisor mode, but with a
# user page table. # user page table.
# #
# sscratch points to where the process's p->trapframe is
# mapped into user space, at TRAPFRAME.
#
# swap a0 and sscratch # save user a0 in sscratch so
# so that a0 is TRAPFRAME # a0 can be used to get at TRAPFRAME.
csrrw a0, sscratch, a0 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 # save the user registers in TRAPFRAME
sd ra, 40(a0) sd ra, 40(a0)
@ -86,20 +92,15 @@ uservec:
.globl userret .globl userret
userret: userret:
# userret(TRAPFRAME, pagetable) # userret(pagetable)
# switch from kernel to user. # switch from kernel to user.
# usertrapret() calls here. # a0: user page table, for satp.
# a0: TRAPFRAME, in user page table.
# a1: user page table, for satp.
# switch to the user page table. # switch to the user page table.
csrw satp, a1 csrw satp, a0
sfence.vma zero, zero sfence.vma zero, zero
# put the saved user a0 in sscratch, so we li a0, TRAPFRAME
# can swap it with our a0 (TRAPFRAME) in the last step.
ld t0, 112(a0)
csrw sscratch, t0
# restore all but a0 from TRAPFRAME # restore all but a0 from TRAPFRAME
ld ra, 40(a0) ld ra, 40(a0)
@ -133,8 +134,8 @@ userret:
ld t5, 272(a0) ld t5, 272(a0)
ld t6, 280(a0) ld t6, 280(a0)
# restore user a0, and save TRAPFRAME in sscratch # restore user a0
csrrw a0, sscratch, a0 ld a0, 112(a0)
# return to user mode and user pc. # return to user mode and user pc.
# usertrapret() set up sstatus and sepc. # usertrapret() set up sstatus and sepc.

View file

@ -96,8 +96,9 @@ usertrapret(void)
// we're back in user space, where usertrap() is correct. // we're back in user space, where usertrap() is correct.
intr_off(); intr_off();
// send syscalls, interrupts, and exceptions to trampoline.S // send syscalls, interrupts, and exceptions to uservec in trampoline.S
w_stvec(TRAMPOLINE + (uservec - trampoline)); uint64 trampoline_uservec = TRAMPOLINE + (uservec - trampoline);
w_stvec(trampoline_uservec);
// set up trapframe values that uservec will need when // set up trapframe values that uservec will need when
// the process next re-enters the kernel. // the process next re-enters the kernel.
@ -121,11 +122,11 @@ usertrapret(void)
// tell trampoline.S the user page table to switch to. // tell trampoline.S the user page table to switch to.
uint64 satp = MAKE_SATP(p->pagetable); 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, // switches to the user page table, restores user registers,
// and switches to user mode with sret. // and switches to user mode with sret.
uint64 fn = TRAMPOLINE + (userret - trampoline); uint64 trampoline_userret = TRAMPOLINE + (userret - trampoline);
((void (*)(uint64,uint64))fn)(TRAPFRAME, satp); ((void (*)(uint64))trampoline_userret)(satp);
} }
// interrupts and exceptions from kernel code go here via kernelvec, // interrupts and exceptions from kernel code go here via kernelvec,