summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2022-08-09 11:44:02 -0400
committerRobert Morris <[email protected]>2022-08-09 11:44:02 -0400
commit9fc9f755e1f9ec56a452b334f6112028e0ec0329 (patch)
tree5bc1ab85b436fde1bd4f6d72ed9c577919b92141
parentca6fc549341d30730247792b87edceacf1613834 (diff)
downloadxv6-labs-9fc9f755e1f9ec56a452b334f6112028e0ec0329.tar.gz
xv6-labs-9fc9f755e1f9ec56a452b334f6112028e0ec0329.tar.bz2
xv6-labs-9fc9f755e1f9ec56a452b334f6112028e0ec0329.zip
adopt github PR98 (No need to store TRAPFRAME in sscratch register)
-rw-r--r--kernel/riscv.h9
-rw-r--r--kernel/trampoline.S37
-rw-r--r--kernel/trap.c11
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,