ax-cpu 0.8.4

Privileged instruction and structure abstractions for various CPU architectures
.section .text
.balign 4
.global trap_vector_base
trap_vector_base:
    // UnikernelTls keeps the CPU-area prefix in sscratch and task TLS in tp.
    // Preserve interrupted temporaries in the CPU-owned runtime anchor before
    // selecting a stack from sstatus.SPP.
    csrrw   t0, sscratch, t0
    STR     t1, t0, {entry_scratch1_index}
    csrr    t1, sscratch
    STR     t1, t0, {entry_scratch0_index}
    csrw    sscratch, t0

    csrr    t1, sstatus
    andi    t1, t1, 1 << 8
    beqz    t1, .Ltrap_from_user

    addi    sp, sp, -{trapframe_size}
    STR     zero, sp, 0
    PUSH_GENERAL_REGS
    LDR     t1, t0, {entry_scratch0_index}
    STR     t1, sp, 5
    LDR     t1, t0, {entry_scratch1_index}
    STR     t1, sp, 6
    addi    t1, sp, {trapframe_size}
    STR     t1, sp, 2
    j       .Ltrap_saved

.Ltrap_from_user:
    LDR     t1, t0, {user_trap_frame_index}
    STR     sp, t1, 2
    mv      sp, t1
    PUSH_GENERAL_REGS
    LDR     t1, t0, {entry_scratch0_index}
    STR     t1, sp, 5
    LDR     t1, t0, {entry_scratch1_index}
    STR     t1, sp, 6

.Ltrap_saved:
    csrr    t1, sepc
    csrr    t2, sstatus
    STR     t1, sp, 32
    STR     t2, sp, 33
    csrw    sscratch, t0
    .option push
    .option norelax
    lla     gp, __global_pointer$
    .option pop

    andi    t2, t2, 1 << 8
    beqz    t2, .Lexit_user
    mv      a0, sp
    la      ra, .Ltrap_return
    j       riscv_trap_handler

.Lexit_user:
    csrr    t0, sscratch
    LDR     sp, t0, {kernel_stack_pointer_index}
    LDR     s0, sp, 0
    LDR     s1, sp, 1
    LDR     s2, sp, 2
    LDR     s3, sp, 3
    LDR     s4, sp, 4
    LDR     s5, sp, 5
    LDR     s6, sp, 6
    LDR     s7, sp, 7
    LDR     s8, sp, 8
    LDR     s9, sp, 9
    LDR     s10, sp, 10
    LDR     s11, sp, 11
    LDR     ra, sp, 12
    LDR     gp, sp, 13
    LDR     tp, sp, 14
    addi    sp, sp, 16 * XLENB
    ret

.global enter_user
enter_user:
    addi    sp, sp, -16 * XLENB
    STR     s0, sp, 0
    STR     s1, sp, 1
    STR     s2, sp, 2
    STR     s3, sp, 3
    STR     s4, sp, 4
    STR     s5, sp, 5
    STR     s6, sp, 6
    STR     s7, sp, 7
    STR     s8, sp, 8
    STR     s9, sp, 9
    STR     s10, sp, 10
    STR     s11, sp, 11
    STR     ra, sp, 12
    STR     gp, sp, 13
    STR     tp, sp, 14
    csrr    t0, sscratch
    STR     sp, t0, {kernel_stack_pointer_index}
    STR     a0, t0, {user_trap_frame_index}
    mv      sp, a0

.Ltrap_return:
    LDR     t0, sp, 32
    LDR     t1, sp, 33
    csrw    sepc, t0
    csrw    sstatus, t1
    andi    t2, t1, 1 << 8
    beqz    t2, .Lrestore_user_context
    RESTORE_KERNEL_CONTEXT
    j       .Lrestore_context_done
.Lrestore_user_context:
    RESTORE_USER_CONTEXT
.Lrestore_context_done:
    LDR     sp, sp, 2
    sret