You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
3.4 KiB
142 lines
3.4 KiB
/* |
|
* SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#include "riscv/rvruntime-frames.h" |
|
#include <soc/soc_caps.h> |
|
|
|
.equ SAVE_REGS, 32 |
|
.equ CONTEXT_SIZE, (SAVE_REGS * 4) |
|
/* Macro which first allocates space on the stack to save general |
|
* purpose registers, and then save them. GP register is excluded. |
|
* The default size allocated on the stack is CONTEXT_SIZE, but it |
|
* can be overridden. */ |
|
.macro save_general_regs cxt_size=CONTEXT_SIZE |
|
addi sp, sp, -\cxt_size |
|
sw ra, RV_STK_RA(sp) |
|
sw tp, RV_STK_TP(sp) |
|
sw t0, RV_STK_T0(sp) |
|
sw t1, RV_STK_T1(sp) |
|
sw t2, RV_STK_T2(sp) |
|
sw s0, RV_STK_S0(sp) |
|
sw s1, RV_STK_S1(sp) |
|
sw a0, RV_STK_A0(sp) |
|
sw a1, RV_STK_A1(sp) |
|
sw a2, RV_STK_A2(sp) |
|
sw a3, RV_STK_A3(sp) |
|
sw a4, RV_STK_A4(sp) |
|
sw a5, RV_STK_A5(sp) |
|
sw a6, RV_STK_A6(sp) |
|
sw a7, RV_STK_A7(sp) |
|
sw s2, RV_STK_S2(sp) |
|
sw s3, RV_STK_S3(sp) |
|
sw s4, RV_STK_S4(sp) |
|
sw s5, RV_STK_S5(sp) |
|
sw s6, RV_STK_S6(sp) |
|
sw s7, RV_STK_S7(sp) |
|
sw s8, RV_STK_S8(sp) |
|
sw s9, RV_STK_S9(sp) |
|
sw s10, RV_STK_S10(sp) |
|
sw s11, RV_STK_S11(sp) |
|
sw t3, RV_STK_T3(sp) |
|
sw t4, RV_STK_T4(sp) |
|
sw t5, RV_STK_T5(sp) |
|
sw t6, RV_STK_T6(sp) |
|
.endm |
|
|
|
.macro save_mepc |
|
csrr t0, mepc |
|
sw t0, RV_STK_MEPC(sp) |
|
.endm |
|
|
|
/* Restore the general purpose registers (excluding gp) from the context on |
|
* the stack. The context is then deallocated. The default size is CONTEXT_SIZE |
|
* but it can be overridden. */ |
|
.macro restore_general_regs cxt_size=CONTEXT_SIZE |
|
lw ra, RV_STK_RA(sp) |
|
lw tp, RV_STK_TP(sp) |
|
lw t0, RV_STK_T0(sp) |
|
lw t1, RV_STK_T1(sp) |
|
lw t2, RV_STK_T2(sp) |
|
lw s0, RV_STK_S0(sp) |
|
lw s1, RV_STK_S1(sp) |
|
lw a0, RV_STK_A0(sp) |
|
lw a1, RV_STK_A1(sp) |
|
lw a2, RV_STK_A2(sp) |
|
lw a3, RV_STK_A3(sp) |
|
lw a4, RV_STK_A4(sp) |
|
lw a5, RV_STK_A5(sp) |
|
lw a6, RV_STK_A6(sp) |
|
lw a7, RV_STK_A7(sp) |
|
lw s2, RV_STK_S2(sp) |
|
lw s3, RV_STK_S3(sp) |
|
lw s4, RV_STK_S4(sp) |
|
lw s5, RV_STK_S5(sp) |
|
lw s6, RV_STK_S6(sp) |
|
lw s7, RV_STK_S7(sp) |
|
lw s8, RV_STK_S8(sp) |
|
lw s9, RV_STK_S9(sp) |
|
lw s10, RV_STK_S10(sp) |
|
lw s11, RV_STK_S11(sp) |
|
lw t3, RV_STK_T3(sp) |
|
lw t4, RV_STK_T4(sp) |
|
lw t5, RV_STK_T5(sp) |
|
lw t6, RV_STK_T6(sp) |
|
addi sp,sp, \cxt_size |
|
.endm |
|
|
|
.macro restore_mepc |
|
lw t0, RV_STK_MEPC(sp) |
|
csrw mepc, t0 |
|
.endm |
|
|
|
|
|
/* _panic_handler: handle all exception */ |
|
.section .text.handlers,"ax" |
|
.global _panic_handler |
|
.type _panic_handler, @function |
|
_panic_handler: |
|
save_general_regs RV_STK_FRMSZ |
|
save_mepc |
|
|
|
addi t0, sp, RV_STK_FRMSZ /* Restore sp with the value when trap happened */ |
|
|
|
/* Save CSRs */ |
|
sw t0, RV_STK_SP(sp) |
|
csrr t0, mstatus |
|
sw t0, RV_STK_MSTATUS(sp) |
|
csrr t0, mcause |
|
sw t0, RV_STK_MCAUSE(sp) |
|
csrr t0, mtvec |
|
sw t0, RV_STK_MTVEC(sp) |
|
csrr t0, mhartid |
|
sw t0, RV_STK_MHARTID(sp) |
|
csrr t0, mtval |
|
sw t0, RV_STK_MTVAL(sp) |
|
|
|
csrr a1, mcause /* Exception cause */ |
|
|
|
mv a0, sp /* RvExcFrame *regs */ |
|
call ulp_lp_core_panic_handler |
|
_end: |
|
j _end /* loop forever */ |
|
|
|
|
|
/* _interrupt_handler: handle all interrupt */ |
|
.section .text.handlers,"ax" |
|
.global _interrupt_handler |
|
.type _interrupt_handler, @function |
|
_interrupt_handler: |
|
/* Save registers & mepc to stack */ |
|
save_general_regs |
|
save_mepc |
|
|
|
call ulp_lp_core_intr_handler |
|
|
|
/* Restore registers & mepc from stack */ |
|
restore_mepc |
|
restore_general_regs |
|
/* Exit, this will also re-enable the interrupts */ |
|
mret
|
|
|