xv6-65oo2/kernel/trampoline.S

142 lines
3.5 KiB
ArmAsm
Raw Normal View History

2019-05-31 13:45:59 +00:00
#
# code to switch between user and kernel space.
#
# this code is mapped at the same virtual address
# (TRAMPOLINE) in user and kernel space so that
# it continues to work when it switches page tables.
2019-05-31 13:45:59 +00:00
#
# kernel.ld causes this to be aligned
2019-05-31 13:45:59 +00:00
# to a page boundary.
#
2019-07-26 08:53:46 +00:00
.section trampsec
.globl trampoline
trampoline:
.align 4
2019-07-26 08:53:46 +00:00
.globl uservec
uservec:
2019-05-31 13:45:59 +00:00
#
# trap.c sets stvec to point here, so
# traps from user space start here,
2019-05-31 13:45:59 +00:00
# in supervisor mode, but with a
# user page table.
#
# sscratch points to where the process's p->tf is
2019-07-22 18:54:40 +00:00
# mapped into user space, at TRAPFRAME.
2019-05-31 13:45:59 +00:00
#
2019-05-31 13:45:59 +00:00
# swap a0 and sscratch
# so that a0 is p->tf
csrrw a0, sscratch, a0
# save the user registers in p->tf
sd ra, 40(a0)
sd sp, 48(a0)
sd gp, 56(a0)
sd tp, 64(a0)
sd t0, 72(a0)
sd t1, 80(a0)
sd t2, 88(a0)
sd s0, 96(a0)
sd s1, 104(a0)
sd a1, 120(a0)
sd a2, 128(a0)
sd a3, 136(a0)
sd a4, 144(a0)
sd a5, 152(a0)
sd a6, 160(a0)
sd a7, 168(a0)
sd s2, 176(a0)
sd s3, 184(a0)
sd s4, 192(a0)
sd s5, 200(a0)
sd s6, 208(a0)
sd s7, 216(a0)
sd s8, 224(a0)
sd s9, 232(a0)
sd s10, 240(a0)
sd s11, 248(a0)
sd t3, 256(a0)
sd t4, 264(a0)
sd t5, 272(a0)
sd t6, 280(a0)
2019-05-31 13:45:59 +00:00
# save the user a0 in p->tf->a0
csrr t0, sscratch
sd t0, 112(a0)
2019-05-31 13:45:59 +00:00
# restore kernel stack pointer from p->tf->kernel_sp
ld sp, 8(a0)
2019-07-10 12:57:51 +00:00
# make tp hold the current hartid, from p->tf->kernel_hartid
2019-06-05 15:42:03 +00:00
ld tp, 32(a0)
2019-05-31 13:45:59 +00:00
# remember the address of usertrap(), p->tf->kernel_trap
ld t0, 16(a0)
# restore kernel page table from p->tf->kernel_satp
ld t1, 0(a0)
sfence.vma zero, zero
2019-05-31 13:45:59 +00:00
csrw satp, t1
# a0 is no longer valid, since the kernel page
# table does not specially map p->td.
# 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