uservec before userret in trampoline, to match book and kernelvec
This commit is contained in:
parent
8d30e21b59
commit
fa2e2e3c81
|
@ -8,8 +8,10 @@
|
||||||
.globl kernelvec
|
.globl kernelvec
|
||||||
.align 4
|
.align 4
|
||||||
kernelvec:
|
kernelvec:
|
||||||
|
// make room to save registers.
|
||||||
addi sp, sp, -256
|
addi sp, sp, -256
|
||||||
|
|
||||||
|
// save the registers.
|
||||||
sd ra, 0(sp)
|
sd ra, 0(sp)
|
||||||
sd sp, 8(sp)
|
sd sp, 8(sp)
|
||||||
sd gp, 16(sp)
|
sd gp, 16(sp)
|
||||||
|
@ -42,8 +44,10 @@ kernelvec:
|
||||||
sd t5, 232(sp)
|
sd t5, 232(sp)
|
||||||
sd t6, 240(sp)
|
sd t6, 240(sp)
|
||||||
|
|
||||||
|
// call the C trap handler in trap.c
|
||||||
call kerneltrap
|
call kerneltrap
|
||||||
|
|
||||||
|
// restore registers.
|
||||||
ld ra, 0(sp)
|
ld ra, 0(sp)
|
||||||
ld sp, 8(sp)
|
ld sp, 8(sp)
|
||||||
ld gp, 16(sp)
|
ld gp, 16(sp)
|
||||||
|
@ -78,6 +82,7 @@ kernelvec:
|
||||||
|
|
||||||
addi sp, sp, 256
|
addi sp, sp, 256
|
||||||
|
|
||||||
|
// return to whatever we were doing in the kernel.
|
||||||
sret
|
sret
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -2,77 +2,21 @@
|
||||||
# code to switch between user and kernel space.
|
# code to switch between user and kernel space.
|
||||||
#
|
#
|
||||||
# this code is mapped at the same virtual address
|
# this code is mapped at the same virtual address
|
||||||
# in user and kernel space so that it continues
|
# (TRAMPOLINE) in user and kernel space so that
|
||||||
# to work when it switches page tables.
|
# 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.
|
# to a page boundary.
|
||||||
#
|
#
|
||||||
.section trampsec
|
.section trampsec
|
||||||
.globl trampoline
|
.globl trampoline
|
||||||
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
|
.align 4
|
||||||
.globl uservec
|
.globl uservec
|
||||||
uservec:
|
uservec:
|
||||||
#
|
#
|
||||||
# trap.c set stvec to point here, so
|
# trap.c sets stvec to point here, so
|
||||||
# user interrupts and exceptions start here,
|
# traps from user space start here,
|
||||||
# in supervisor mode, but with a
|
# in supervisor mode, but with a
|
||||||
# user page table.
|
# user page table.
|
||||||
#
|
#
|
||||||
|
@ -139,3 +83,59 @@ uservec:
|
||||||
|
|
||||||
# jump to usertrap(), which does not return
|
# jump to usertrap(), which does not return
|
||||||
jr t0
|
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
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
struct spinlock tickslock;
|
struct spinlock tickslock;
|
||||||
uint ticks;
|
uint ticks;
|
||||||
|
|
||||||
extern char trampoline[], uservec[];
|
extern char trampoline[], uservec[], userret[];
|
||||||
|
|
||||||
// in kernelvec.S, calls kerneltrap().
|
// in kernelvec.S, calls kerneltrap().
|
||||||
void kernelvec();
|
void kernelvec();
|
||||||
|
@ -123,7 +123,8 @@ usertrapret(void)
|
||||||
// jump to trampoline.S at the top of memory, which
|
// jump to 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.
|
||||||
((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,
|
// interrupts and exceptions from kernel code go here via kernelvec,
|
||||||
|
|
Loading…
Reference in a new issue