root/kernel/trampoline.S

/* [<][>][^][v][top][bottom][index][help] */
   1         #
   2         # low-level code to handle traps from user space into
   3         # the kernel, and returns from kernel to user.
   4         #
   5         # the kernel maps the page holding this code
   6         # at the same virtual address (TRAMPOLINE)
   7         # in user and kernel space so that it continues
   8         # to work when it switches page tables.
   9         # kernel.ld causes this code to start at 
  10         # a page boundary.
  11         #
  12 
  13 #include "riscv.h"
  14 #include "memlayout.h"
  15 
  16 .section trampsec
  17 .globl trampoline
  18 .globl usertrap
  19 trampoline:
  20 .align 4
  21 .globl uservec
  22 uservec:    
  23         #
  24         # trap.c sets stvec to point here, so
  25         # traps from user space start here,
  26         # in supervisor mode, but with a
  27         # user page table.
  28         #
  29 
  30         # save user a0 in sscratch so
  31         # a0 can be used to get at TRAPFRAME.
  32         csrw sscratch, a0
  33 
  34         # each process has a separate p->trapframe memory area,
  35         # but it's mapped to the same virtual address
  36         # (TRAPFRAME) in every process's user page table.
  37         li a0, TRAPFRAME
  38         
  39         # save the user registers in TRAPFRAME
  40         sd ra, 40(a0)
  41         sd sp, 48(a0)
  42         sd gp, 56(a0)
  43         sd tp, 64(a0)
  44         sd t0, 72(a0)
  45         sd t1, 80(a0)
  46         sd t2, 88(a0)
  47         sd s0, 96(a0)
  48         sd s1, 104(a0)
  49         sd a1, 120(a0)
  50         sd a2, 128(a0)
  51         sd a3, 136(a0)
  52         sd a4, 144(a0)
  53         sd a5, 152(a0)
  54         sd a6, 160(a0)
  55         sd a7, 168(a0)
  56         sd s2, 176(a0)
  57         sd s3, 184(a0)
  58         sd s4, 192(a0)
  59         sd s5, 200(a0)
  60         sd s6, 208(a0)
  61         sd s7, 216(a0)
  62         sd s8, 224(a0)
  63         sd s9, 232(a0)
  64         sd s10, 240(a0)
  65         sd s11, 248(a0)
  66         sd t3, 256(a0)
  67         sd t4, 264(a0)
  68         sd t5, 272(a0)
  69         sd t6, 280(a0)
  70 
  71         # save the user a0 in p->trapframe->a0
  72         csrr t0, sscratch
  73         sd t0, 112(a0)
  74 
  75         # initialize kernel stack pointer, from p->trapframe->kernel_sp
  76         ld sp, 8(a0)
  77 
  78         # make tp hold the current hartid, from p->trapframe->kernel_hartid
  79         ld tp, 32(a0)
  80 
  81         # load the address of usertrap(), from p->trapframe->kernel_trap
  82         ld t0, 16(a0)
  83 
  84         # fetch the kernel page table address, from p->trapframe->kernel_satp.
  85         ld t1, 0(a0)
  86 
  87         # wait for any previous memory operations to complete, so that
  88         # they use the user page table.
  89         sfence.vma zero, zero
  90 
  91         # install the kernel page table.
  92         csrw satp, t1
  93 
  94         # flush now-stale user entries from the TLB.
  95         sfence.vma zero, zero
  96 
  97         # jump to usertrap(), which does not return
  98         jr t0
  99 
 100 .globl userret
 101 userret:
 102         # userret(pagetable)
 103         # called by usertrapret() in trap.c to
 104         # switch from kernel to user.
 105         # a0: user page table, for satp.
 106 
 107         # switch to the user page table.
 108         sfence.vma zero, zero
 109         csrw satp, a0
 110         sfence.vma zero, zero
 111 
 112         li a0, TRAPFRAME
 113 
 114         # restore all but a0 from TRAPFRAME
 115         ld ra, 40(a0)
 116         ld sp, 48(a0)
 117         ld gp, 56(a0)
 118         ld tp, 64(a0)
 119         ld t0, 72(a0)
 120         ld t1, 80(a0)
 121         ld t2, 88(a0)
 122         ld s0, 96(a0)
 123         ld s1, 104(a0)
 124         ld a1, 120(a0)
 125         ld a2, 128(a0)
 126         ld a3, 136(a0)
 127         ld a4, 144(a0)
 128         ld a5, 152(a0)
 129         ld a6, 160(a0)
 130         ld a7, 168(a0)
 131         ld s2, 176(a0)
 132         ld s3, 184(a0)
 133         ld s4, 192(a0)
 134         ld s5, 200(a0)
 135         ld s6, 208(a0)
 136         ld s7, 216(a0)
 137         ld s8, 224(a0)
 138         ld s9, 232(a0)
 139         ld s10, 240(a0)
 140         ld s11, 248(a0)
 141         ld t3, 256(a0)
 142         ld t4, 264(a0)
 143         ld t5, 272(a0)
 144         ld t6, 280(a0)
 145 
 146         # restore user a0
 147         ld a0, 112(a0)
 148         
 149         # return to user mode and user pc.
 150         # usertrapret() set up sstatus and sepc.
 151         sret

/* [<][>][^][v][top][bottom][index][help] */