Files
k-os/crates/adapter-riscv/src/trap/vector.rs

119 lines
2.1 KiB
Rust

use core::arch::global_asm;
global_asm!(
r#"
.section .text
.align 4
.globl trap_vector
trap_vector:
csrrw sp, sscratch, sp
bnez sp, _from_user
csrrw sp, sscratch, sp
_from_user:
addi sp, sp, -272
sd x1, 8(sp)
sd x3, 24(sp)
sd x4, 32(sp)
sd x5, 40(sp)
sd x6, 48(sp)
sd x7, 56(sp)
sd x8, 64(sp)
sd x9, 72(sp)
sd x10, 80(sp)
sd x11, 88(sp)
sd x12, 96(sp)
sd x13, 104(sp)
sd x14, 112(sp)
sd x15, 120(sp)
sd x16, 128(sp)
sd x17, 136(sp)
sd x18, 144(sp)
sd x19, 152(sp)
sd x20, 160(sp)
sd x21, 168(sp)
sd x22, 176(sp)
sd x23, 184(sp)
sd x24, 192(sp)
sd x25, 200(sp)
sd x26, 208(sp)
sd x27, 216(sp)
sd x28, 224(sp)
sd x29, 232(sp)
sd x30, 240(sp)
sd x31, 248(sp)
csrr t0, sscratch
sd t0, 16(sp)
csrr t0, sepc
sd t0, 256(sp)
csrr t0, sstatus
sd t0, 264(sp)
mv a0, sp
call trap_handler_rust
j _restore_frame
# trap_return(frame): resume `frame` as if returning from the trap that saved it.
.globl trap_return
trap_return:
mv sp, a0
_restore_frame:
ld t0, 256(sp)
csrw sepc, t0
ld t0, 264(sp)
csrw sstatus, t0
andi t1, t0, 0x100
bnez t1, _restore_smode
ld t0, 16(sp)
csrw sscratch, t0
_restore_smode:
ld x1, 8(sp)
ld x3, 24(sp)
ld x4, 32(sp)
ld x6, 48(sp)
ld x7, 56(sp)
ld x8, 64(sp)
ld x9, 72(sp)
ld x10, 80(sp)
ld x11, 88(sp)
ld x12, 96(sp)
ld x13, 104(sp)
ld x14, 112(sp)
ld x15, 120(sp)
ld x16, 128(sp)
ld x17, 136(sp)
ld x18, 144(sp)
ld x19, 152(sp)
ld x20, 160(sp)
ld x21, 168(sp)
ld x22, 176(sp)
ld x23, 184(sp)
ld x24, 192(sp)
ld x25, 200(sp)
ld x26, 208(sp)
ld x27, 216(sp)
ld x28, 224(sp)
ld x29, 232(sp)
ld x30, 240(sp)
ld x31, 248(sp)
# t0 (x5) is restored last on each path; it is the only scratch register.
csrr t0, sstatus
andi t0, t0, 0x100
bnez t0, _sret_smode
ld x5, 40(sp)
addi sp, sp, 272
csrrw sp, sscratch, sp
sret
_sret_smode:
ld x5, 40(sp)
addi sp, sp, 272
sret
"#
);