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         # call usertrap()
  98         jalr t0
  99 
 100 .globl userret
 101 userret:
 102         # usertrap() returns here, with user satp in a0.
 103         # return from kernel to user.
 104 
 105         # switch to the user page table.
 106         sfence.vma zero, zero
 107         csrw satp, a0
 108         sfence.vma zero, zero
 109 
 110         li a0, TRAPFRAME
 111 
 112         # restore all but a0 from TRAPFRAME
 113         ld ra, 40(a0)
 114         ld sp, 48(a0)
 115         ld gp, 56(a0)
 116         ld tp, 64(a0)
 117         ld t0, 72(a0)
 118         ld t1, 80(a0)
 119         ld t2, 88(a0)
 120         ld s0, 96(a0)
 121         ld s1, 104(a0)
 122         ld a1, 120(a0)
 123         ld a2, 128(a0)
 124         ld a3, 136(a0)
 125         ld a4, 144(a0)
 126         ld a5, 152(a0)
 127         ld a6, 160(a0)
 128         ld a7, 168(a0)
 129         ld s2, 176(a0)
 130         ld s3, 184(a0)
 131         ld s4, 192(a0)
 132         ld s5, 200(a0)
 133         ld s6, 208(a0)
 134         ld s7, 216(a0)
 135         ld s8, 224(a0)
 136         ld s9, 232(a0)
 137         ld s10, 240(a0)
 138         ld s11, 248(a0)
 139         ld t3, 256(a0)
 140         ld t4, 264(a0)
 141         ld t5, 272(a0)
 142         ld t6, 280(a0)
 143 
 144     # restore user a0
 145         ld a0, 112(a0)
 146         
 147         # return to user mode and user pc.
 148         # usertrapret() set up sstatus and sepc.
 149         sret

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