blob: 725a59d7f3e0fe956d6a49085920d77fa315afea [file] [log] [blame]
#include <arch/pcr.h>
#include <arch/trap.h>
#include <kstack.h>
#ifdef __riscv64
# define STORE sd
# define LOAD ld
# define LOG_REGBYTES 3
#else
# define STORE sw
# define LOAD lw
# define LOG_REGBYTES 2
#endif
#define REGBYTES (1 << LOG_REGBYTES)
.text
.global save_kernel_tf_asm
save_kernel_tf_asm:
mfpcr a1,ASM_CR(PCR_SR)
STORE s0, 2*REGBYTES(a0)
STORE s1, 3*REGBYTES(a0)
STORE s2, 4*REGBYTES(a0)
STORE s3, 5*REGBYTES(a0)
STORE s4, 6*REGBYTES(a0)
STORE s5, 7*REGBYTES(a0)
STORE s6, 8*REGBYTES(a0)
STORE s7, 9*REGBYTES(a0)
STORE s8, 10*REGBYTES(a0)
STORE s9, 11*REGBYTES(a0)
STORE s10,12*REGBYTES(a0)
STORE s11,13*REGBYTES(a0)
STORE sp, 14*REGBYTES(a0)
STORE a1,32*REGBYTES(a0)
# set EPC to this function's return address
STORE ra,33*REGBYTES(a0)
ret
# Remove these (or this comment) when implementing setjmp on riscv.
.text
.global pop_kernel_ctx
pop_kernel_ctx:
LOAD a1,32*REGBYTES(a0)
LOAD ra,33*REGBYTES(a0)
LOAD s0, 2*REGBYTES(a0)
LOAD s1, 3*REGBYTES(a0)
LOAD s2, 4*REGBYTES(a0)
LOAD s3, 5*REGBYTES(a0)
LOAD s4, 6*REGBYTES(a0)
LOAD s5, 7*REGBYTES(a0)
LOAD s6, 8*REGBYTES(a0)
LOAD s7, 9*REGBYTES(a0)
LOAD s8, 10*REGBYTES(a0)
LOAD s9, 11*REGBYTES(a0)
LOAD s10,12*REGBYTES(a0)
LOAD s11,13*REGBYTES(a0)
LOAD sp, 14*REGBYTES(a0)
mtpcr a1,ASM_CR(PCR_SR)
ret
save_tf: # write the trap frame onto the stack
ret
.globl pop_hw_tf
pop_hw_tf: # write the trap frame onto the stack
# restore SR.{PS, EF, U64} and disable interrupts
LOAD v0,32*REGBYTES(a0)
mfpcr v1, ASM_CR(PCR_SR)
andi v0, v0, (SR_PS | SR_EF | SR_U64)
andi v1, v1, ~(SR_PS | SR_EF | SR_U64 | SR_ET)
or v0, v0, v1
mtpcr v0, ASM_CR(PCR_SR)
# restore gprs
LOAD x1,1*REGBYTES(a0)
mtpcr x1,ASM_CR(PCR_K0)
LOAD x1,2*REGBYTES(a0)
mtpcr x1,ASM_CR(PCR_K1)
move x1,a0
LOAD x3,3*REGBYTES(x1)
LOAD x4,4*REGBYTES(x1)
LOAD x5,5*REGBYTES(x1)
LOAD x6,6*REGBYTES(x1)
LOAD x7,7*REGBYTES(x1)
LOAD x8,8*REGBYTES(x1)
LOAD x9,9*REGBYTES(x1)
LOAD x10,10*REGBYTES(x1)
LOAD x11,11*REGBYTES(x1)
LOAD x12,12*REGBYTES(x1)
LOAD x13,13*REGBYTES(x1)
LOAD x14,14*REGBYTES(x1)
LOAD x15,15*REGBYTES(x1)
LOAD x16,16*REGBYTES(x1)
LOAD x17,17*REGBYTES(x1)
LOAD x18,18*REGBYTES(x1)
LOAD x19,19*REGBYTES(x1)
LOAD x20,20*REGBYTES(x1)
LOAD x21,21*REGBYTES(x1)
LOAD x22,22*REGBYTES(x1)
LOAD x23,23*REGBYTES(x1)
LOAD x24,24*REGBYTES(x1)
LOAD x25,25*REGBYTES(x1)
LOAD x26,26*REGBYTES(x1)
LOAD x27,27*REGBYTES(x1)
LOAD x28,28*REGBYTES(x1)
LOAD x29,29*REGBYTES(x1)
LOAD x30,30*REGBYTES(x1)
LOAD x31,31*REGBYTES(x1)
# gtfo!
LOAD x2,33*REGBYTES(x1)
mtpcr x2,ASM_CR(PCR_EPC)
mfpcr x1,ASM_CR(PCR_K0)
mfpcr x2,ASM_CR(PCR_K1)
eret
.global trap_entry
trap_entry:
mtpcr x1, ASM_CR(PCR_K0) # stash x1 in k0
mfpcr x1, ASM_CR(PCR_SR)
mtpcr x2, ASM_CR(PCR_K1) # stash x2 in k1
# when coming from kernel, continue below its stack
add x2, sp, -SIZEOF_HW_TRAPFRAME
and x1, x1, SR_PS
bnez x1, 1f
# otherwise, start at the top of the per-core stack
mfpcr x1, ASM_CR(PCR_COREID)
lui x2, %hi(core_stacktops)
sll x1, x1, LOG_REGBYTES
add x2, x2, x1
LOAD x2, %lo(core_stacktops)(x2)
add x2, x2, -SIZEOF_HW_TRAPFRAME
1:# save gprs
STORE x3,3*REGBYTES(x2)
STORE x4,4*REGBYTES(x2)
mfpcr x3,ASM_CR(PCR_K0) # retrieve x1
mfpcr x4,ASM_CR(PCR_K1) # retrieve x2
STORE x5,5*REGBYTES(x2)
STORE x6,6*REGBYTES(x2)
STORE x7,7*REGBYTES(x2)
STORE x8,8*REGBYTES(x2)
STORE x9,9*REGBYTES(x2)
STORE x3,1*REGBYTES(x2) # save x1
STORE x4,2*REGBYTES(x2) # save x2
STORE x10,10*REGBYTES(x2)
STORE x11,11*REGBYTES(x2)
STORE x12,12*REGBYTES(x2)
STORE x13,13*REGBYTES(x2)
STORE x14,14*REGBYTES(x2)
STORE x15,15*REGBYTES(x2)
STORE x16,16*REGBYTES(x2)
STORE x17,17*REGBYTES(x2)
STORE x18,18*REGBYTES(x2)
STORE x19,19*REGBYTES(x2)
STORE x20,20*REGBYTES(x2)
STORE x21,21*REGBYTES(x2)
STORE x22,22*REGBYTES(x2)
STORE x23,23*REGBYTES(x2)
STORE x24,24*REGBYTES(x2)
STORE x25,25*REGBYTES(x2)
STORE x26,26*REGBYTES(x2)
STORE x27,27*REGBYTES(x2)
STORE x28,28*REGBYTES(x2)
STORE x29,29*REGBYTES(x2)
STORE x30,30*REGBYTES(x2)
STORE x31,31*REGBYTES(x2)
# get sr, epc, badvaddr, cause
mfpcr x3,ASM_CR(PCR_SR)
mfpcr x4,ASM_CR(PCR_EPC)
mfpcr x5,ASM_CR(PCR_BADVADDR)
mfpcr x6,ASM_CR(PCR_CAUSE)
STORE x3,32*REGBYTES(x2)
STORE x4,33*REGBYTES(x2)
STORE x5,34*REGBYTES(x2)
STORE x6,35*REGBYTES(x2)
move sp, x2
move a0, x2
j handle_trap
.global cpu_halt
.global after_cpu_halt
cpu_halt:
setpcr ASM_CR(PCR_SR), SR_ET
1:b 1b # handle_ipi can advance the PC to break out of this loop.
ret
after_cpu_halt:
clearpcr ASM_CR(PCR_SR), SR_ET