summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorRobert Morris <[email protected]>2019-07-26 09:38:22 -0400
committerRobert Morris <[email protected]>2019-07-26 09:38:22 -0400
commitfa2e2e3c81b2686229acc204ece380953a8031ea (patch)
tree67c055fc880e8d286124814fff649c170434ea3e /kernel
parent8d30e21b59d2f6d48e593cd6c2399d0743971155 (diff)
downloadxv6-labs-fa2e2e3c81b2686229acc204ece380953a8031ea.tar.gz
xv6-labs-fa2e2e3c81b2686229acc204ece380953a8031ea.tar.bz2
xv6-labs-fa2e2e3c81b2686229acc204ece380953a8031ea.zip
uservec before userret in trampoline, to match book and kernelvec
Diffstat (limited to 'kernel')
-rw-r--r--kernel/kernelvec.S5
-rw-r--r--kernel/trampoline.S122
-rw-r--r--kernel/trap.c5
3 files changed, 69 insertions, 63 deletions
diff --git a/kernel/kernelvec.S b/kernel/kernelvec.S
index 9aabe96..222b172 100644
--- a/kernel/kernelvec.S
+++ b/kernel/kernelvec.S
@@ -8,8 +8,10 @@
.globl kernelvec
.align 4
kernelvec:
+ // make room to save registers.
addi sp, sp, -256
+ // save the registers.
sd ra, 0(sp)
sd sp, 8(sp)
sd gp, 16(sp)
@@ -42,8 +44,10 @@ kernelvec:
sd t5, 232(sp)
sd t6, 240(sp)
+ // call the C trap handler in trap.c
call kerneltrap
+ // restore registers.
ld ra, 0(sp)
ld sp, 8(sp)
ld gp, 16(sp)
@@ -78,6 +82,7 @@ kernelvec:
addi sp, sp, 256
+ // return to whatever we were doing in the kernel.
sret
#
diff --git a/kernel/trampoline.S b/kernel/trampoline.S
index bc31974..6e436d2 100644
--- a/kernel/trampoline.S
+++ b/kernel/trampoline.S
@@ -2,77 +2,21 @@
# code to switch between user and kernel space.
#
# this code is mapped at the same virtual address
- # in user and kernel space so that it continues
- # to work when it switches page tables.
+ # (TRAMPOLINE) in user and kernel space so that
+ # it continues to work when it switches page tables.
#
- # kernel.ld causes userret to be aligned
+ # kernel.ld causes this to be aligned
# to a page boundary.
#
.section trampsec
.globl trampoline
trampoline:
-.globl userret
-userret:
- # userret(trapframe, pagetable)
- # switch from kernel to user.
- # usertrapret() calls here.
- # a0: p->tf in user page table
- # a1: new value for satp, for user page table
-
- # switch to the user page table.
- sfence.vma zero, zero
- csrw satp, a1
-
- # put the saved user a0 in sscratch, so we
- # can swap it with our a0 (p->tf) in the last step.
- ld t0, 112(a0)
- csrw sscratch, t0
-
- # restore all but a0 from p->tf
- ld ra, 40(a0)
- ld sp, 48(a0)
- ld gp, 56(a0)
- ld tp, 64(a0)
- ld t0, 72(a0)
- ld t1, 80(a0)
- ld t2, 88(a0)
- ld s0, 96(a0)
- ld s1, 104(a0)
- ld a1, 120(a0)
- ld a2, 128(a0)
- ld a3, 136(a0)
- ld a4, 144(a0)
- ld a5, 152(a0)
- ld a6, 160(a0)
- ld a7, 168(a0)
- ld s2, 176(a0)
- ld s3, 184(a0)
- ld s4, 192(a0)
- ld s5, 200(a0)
- ld s6, 208(a0)
- ld s7, 216(a0)
- ld s8, 224(a0)
- ld s9, 232(a0)
- ld s10, 240(a0)
- ld s11, 248(a0)
- ld t3, 256(a0)
- ld t4, 264(a0)
- ld t5, 272(a0)
- ld t6, 280(a0)
-
- # restore user a0, and save p->tf in sscratch
- csrrw a0, sscratch, a0
-
- # return to user mode and user pc.
- # usertrapret() set up sstatus and sepc.
- sret
-
.align 4
.globl uservec
uservec:
#
- # trap.c set stvec to point here, so
- # user interrupts and exceptions start here,
+ # trap.c sets stvec to point here, so
+ # traps from user space start here,
# in supervisor mode, but with a
# user page table.
#
@@ -139,3 +83,59 @@ uservec:
# jump to usertrap(), which does not return
jr t0
+
+.globl userret
+userret:
+ # userret(trapframe, pagetable)
+ # switch from kernel to user.
+ # usertrapret() calls here.
+ # a0: p->tf in user page table
+ # a1: new value for satp, for user page table
+
+ # switch to the user page table.
+ sfence.vma zero, zero
+ csrw satp, a1
+
+ # put the saved user a0 in sscratch, so we
+ # can swap it with our a0 (p->tf) in the last step.
+ ld t0, 112(a0)
+ csrw sscratch, t0
+
+ # restore all but a0 from p->tf
+ ld ra, 40(a0)
+ ld sp, 48(a0)
+ ld gp, 56(a0)
+ ld tp, 64(a0)
+ ld t0, 72(a0)
+ ld t1, 80(a0)
+ ld t2, 88(a0)
+ ld s0, 96(a0)
+ ld s1, 104(a0)
+ ld a1, 120(a0)
+ ld a2, 128(a0)
+ ld a3, 136(a0)
+ ld a4, 144(a0)
+ ld a5, 152(a0)
+ ld a6, 160(a0)
+ ld a7, 168(a0)
+ ld s2, 176(a0)
+ ld s3, 184(a0)
+ ld s4, 192(a0)
+ ld s5, 200(a0)
+ ld s6, 208(a0)
+ ld s7, 216(a0)
+ ld s8, 224(a0)
+ ld s9, 232(a0)
+ ld s10, 240(a0)
+ ld s11, 248(a0)
+ ld t3, 256(a0)
+ ld t4, 264(a0)
+ ld t5, 272(a0)
+ ld t6, 280(a0)
+
+ # restore user a0, and save p->tf in sscratch
+ csrrw a0, sscratch, a0
+
+ # return to user mode and user pc.
+ # usertrapret() set up sstatus and sepc.
+ sret
diff --git a/kernel/trap.c b/kernel/trap.c
index ad2d0f8..ce7a65a 100644
--- a/kernel/trap.c
+++ b/kernel/trap.c
@@ -9,7 +9,7 @@
struct spinlock tickslock;
uint ticks;
-extern char trampoline[], uservec[];
+extern char trampoline[], uservec[], userret[];
// in kernelvec.S, calls kerneltrap().
void kernelvec();
@@ -123,7 +123,8 @@ usertrapret(void)
// jump to trampoline.S at the top of memory, which
// switches to the user page table, restores user registers,
// and switches to user mode with sret.
- ((void (*)(uint64,uint64))TRAMPOLINE)(TRAPFRAME, satp);
+ uint64 fn = TRAMPOLINE + (userret - trampoline);
+ ((void (*)(uint64,uint64))fn)(TRAPFRAME, satp);
}
// interrupts and exceptions from kernel code go here via kernelvec,