| #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 |