xv6-65oo2/kernel/trampoline.S

143 lines
3.4 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.
#
#include "riscv.h"
#include "memlayout.h"
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.
#
# 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
2019-07-26 14:17:02 +00:00
# save the user registers in TRAPFRAME
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->trapframe->a0
2019-05-31 13:45:59 +00:00
csrr t0, sscratch
sd t0, 112(a0)
2019-05-31 13:45:59 +00:00
# restore kernel stack pointer from p->trapframe->kernel_sp
2019-05-31 13:45:59 +00:00
ld sp, 8(a0)
# make tp hold the current hartid, from p->trapframe->kernel_hartid
2019-06-05 15:42:03 +00:00
ld tp, 32(a0)
# load the address of usertrap(), p->trapframe->kernel_trap
2019-05-31 13:45:59 +00:00
ld t0, 16(a0)
# restore kernel page table from p->trapframe->kernel_satp
2019-05-31 13:45:59 +00:00
ld t1, 0(a0)
csrw satp, t1
2019-09-03 20:29:48 +00:00
sfence.vma zero, zero
2019-05-31 13:45:59 +00:00
# a0 is no longer valid, since the kernel page
# table does not specially map p->tf.
2019-05-31 13:45:59 +00:00
# jump to usertrap(), which does not return
jr t0
.globl userret
userret:
# userret(pagetable)
# switch from kernel to user.
# a0: user page table, for satp.
2019-09-03 20:29:48 +00:00
# switch to the user page table.
csrw satp, a0
2019-09-03 20:29:48 +00:00
sfence.vma zero, zero
li a0, TRAPFRAME
2019-07-26 14:17:02 +00:00
# restore all but a0 from TRAPFRAME
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
ld a0, 112(a0)
# return to user mode and user pc.
# usertrapret() set up sstatus and sepc.
sret