| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- .altmacro
- .macro SAVE_GP n
- sd x\n, \n*8(sp)
- .endm
- .macro LOAD_GP n
- ld x\n, \n*8(sp)
- .endm
- .section .text
- .globl trap_from_kernel
- .globl trap_from_user
- .globl return_to_user
- .align 2
- # just like a function call
- trap_from_kernel:
- # save s*
- addi sp, sp, -17*8
- sd ra, 1*8(sp)
- sd t0, 2*8(sp)
- sd t1, 3*8(sp)
- sd t2, 4*8(sp)
- sd t3, 5*8(sp)
- sd t4, 6*8(sp)
- sd t5, 7*8(sp)
- sd t6, 8*8(sp)
- sd a0, 9*8(sp)
- sd a1, 10*8(sp)
- sd a2, 11*8(sp)
- sd a3, 12*8(sp)
- sd a4, 13*8(sp)
- sd a5, 14*8(sp)
- sd a6, 15*8(sp)
- sd a7, 16*8(sp)
- call kernel_trap_entry
- # restore s*
- ld ra, 1*8(sp)
- ld t0, 2*8(sp)
- ld t1, 3*8(sp)
- ld t2, 4*8(sp)
- ld t3, 5*8(sp)
- ld t4, 6*8(sp)
- ld t5, 7*8(sp)
- ld t6, 8*8(sp)
- ld a0, 9*8(sp)
- ld a1, 10*8(sp)
- ld a2, 11*8(sp)
- ld a3, 12*8(sp)
- ld a4, 13*8(sp)
- ld a5, 14*8(sp)
- ld a6, 15*8(sp)
- ld a7, 16*8(sp)
- addi sp, sp, 17*8
- sret
- trap_from_user:
- # swap sp and sscratch(previously stored user TrapContext's address in return_to_user)
- csrrw sp, sscratch, sp
- sd x1, 1*8(sp)
- .set n, 3
- .rept 29
- SAVE_GP %n
- .set n, n+1
- .endr
- csrr t0, sstatus
- csrr t1, sepc
- sd t0, 32*8(sp) # save sstatus into the TrapContext
- sd t1, 33*8(sp) # save sepc into the TrapContext
- csrr t2, sscratch
- sd t2, 2*8(sp) # save user stack pointer into the TrapContext
- ld ra, 35*8(sp)
- ld s0, 36*8(sp)
- ld s1, 37*8(sp)
- ld s2, 38*8(sp)
- ld s3, 39*8(sp)
- ld s4, 40*8(sp)
- ld s5, 41*8(sp)
- ld s6, 42*8(sp)
- ld s7, 43*8(sp)
- ld s8, 44*8(sp)
- ld s9, 45*8(sp)
- ld s10, 46*8(sp)
- ld s11, 47*8(sp)
- ld fp, 48*8(sp)
- ld tp, 49*8(sp)
- ld sp, 34*8(sp)
- ret
- # a0: pointer to TrapContext in user space (constant)
- return_to_user:
- # sscratch store the TrapContext's address
- csrw sscratch, a0
- # offset in TrapContext's order
- sd sp, 34*8(a0)
- sd ra, 35*8(a0)
- sd s0, 36*8(a0)
- sd s1, 37*8(a0)
- sd s2, 38*8(a0)
- sd s3, 39*8(a0)
- sd s4, 40*8(a0)
- sd s5, 41*8(a0)
- sd s6, 42*8(a0)
- sd s7, 43*8(a0)
- sd s8, 44*8(a0)
- sd s9, 45*8(a0)
- sd s10, 46*8(a0)
- sd s11, 47*8(a0)
- sd fp, 48*8(a0)
- sd tp, 49*8(a0)
- mv sp, a0
- # now sp points to TrapContext in kernel space
- # restore sstatus and sepc
- ld t0, 32*8(sp)
- ld t1, 33*8(sp)
- csrw sstatus, t0
- csrw sepc, t1
- # save x* expect x0 and sp
- ld x1, 1*8(sp)
- .set n, 3
- .rept 29
- LOAD_GP %n
- .set n, n+1
- .endr
- ld sp, 2*8(sp)
- sret
|