上下文入栈保存
addi sp, sp, -portCONTEXT_SIZE ----开辟一段栈空间,这里的sp可能是主栈或任务栈
store_x x1, 1 * portWORD_SIZE( sp ) ----依次存储相关寄存器
store_x x5, 2 * portWORD_SIZE( sp )
store_x x6, 3 * portWORD_SIZE( sp )
store_x x7, 4 * portWORD_SIZE( sp )
store_x x8, 5 * portWORD_SIZE( sp )
store_x x9, 6 * portWORD_SIZE( sp )
store_x x10, 7 * portWORD_SIZE( sp )
store_x x11, 8 * portWORD_SIZE( sp )
store_x x12, 9 * portWORD_SIZE( sp )
store_x x13, 10 * portWORD_SIZE( sp )
store_x x14, 11 * portWORD_SIZE( sp )
store_x x15, 12 * portWORD_SIZE( sp )
store_x x16, 13 * portWORD_SIZE( sp )
store_x x17, 14 * portWORD_SIZE( sp )
store_x x18, 15 * portWORD_SIZE( sp )
store_x x19, 16 * portWORD_SIZE( sp )
store_x x20, 17 * portWORD_SIZE( sp )
store_x x21, 18 * portWORD_SIZE( sp )
store_x x22, 19 * portWORD_SIZE( sp )
store_x x23, 20 * portWORD_SIZE( sp )
store_x x24, 21 * portWORD_SIZE( sp )
store_x x25, 22 * portWORD_SIZE( sp )
store_x x26, 23 * portWORD_SIZE( sp )
store_x x27, 24 * portWORD_SIZE( sp )
store_x x28, 25 * portWORD_SIZE( sp )
store_x x29, 26 * portWORD_SIZE( sp )
store_x x30, 27 * portWORD_SIZE( sp )
store_x x31, 28 * portWORD_SIZE( sp )
store_x x3, 31 * portWORD_SIZE( sp )
store_x x4, 32 * portWORD_SIZE( sp )
mv a0, sp
addi a0, a0, portCONTEXT_SIZE
store_x a0, 30 * portWORD_SIZE( sp ) ---将栈起始地址保存到栈空间中
csrr a0, mepc
store_x a0, 0 * portWORD_SIZE( sp ) ---将mepc保存到栈空间中
csrr t0, mscratch
store_x t0, 33 * portWORD_SIZE( sp ) ---将mscratch保存到栈空间中
csrr t0, mstatus /* Required for MPIE bit. */
store_x t0, 29 * portWORD_SIZE( sp ) 将mstatus保存到栈空间中
load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
store_x sp, 0( t0 ) /* Write sp to first TCB member. */
将sp写入pxCurrentTCB->pxTopOfStack
即将sp保存到任务的控制块中,每个任务都有一个全局的控制块
当恢复的时候,也是通过pxCurrentTCB先获取到sp。
检查是同步异常
csrr a0, mcause ---a0=mcause
csrr a1, mepc ---a1=mepc
test_if_asynchronous:
srli a2, a0, __riscv_xlen - 1 --将a0右移63位(64位系统),即获取mcause最高位,赋值为a2
beq a2, x0, handle_synchronous --判断a2是否为0,如果是0,则是同步异常,跳转处理,否则是中断。
异常处理
handle_synchronous:
csrr t0, mcause --获取mcasue到t0中
andi t0, t0, 0x7ff
mv a0, t0
addi a1, a1, 4
store_x a1, 0( sp )
test_if_environment_call:
li t0, 11
bne a0, t0, is_exception
load_x sp, xISRStackTop
call vTaskSwitchContext
j processed_source
is_exception:
csrr t0, mcause
csrr t1, mepc
csrr t2, mtval
mv a0, t0
mv a1, t1
mv a2, t2
mv a3, sp
call enter_interrupt_handler
call riscv_cpu_handle_exception ----异常处理函数
call exit_interrupt_handler
j is_exception
上下文出栈
load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */
load_x sp, 0( t1 ) /* Read sp from first TCB member. */
load_x t0, 0( sp ) --获取中断返回后,要执行的PC,其保存在栈的第一个位置
csrw mepc, t0
/* Load mstatus with the interrupt enable bits used by the task. */
load_x t0, 29 * portWORD_SIZE( sp )
csrw mstatus, t0 恢复mstatus(打开中断)
load_x x1, 1 * portWORD_SIZE( sp )
load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */
load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */
load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */
load_x x8, 5 * portWORD_SIZE( sp ) /* s0/fp */
load_x x9, 6 * portWORD_SIZE( sp ) /* s1 */
load_x x10, 7 * portWORD_SIZE( sp ) /* a0 */
load_x x11, 8 * portWORD_SIZE( sp ) /* a1 */
load_x x12, 9 * portWORD_SIZE( sp ) /* a2 */
load_x x13, 10 * portWORD_SIZE( sp ) /* a3 */
load_x x14, 11 * portWORD_SIZE( sp ) /* a4 */
load_x x15, 12 * portWORD_SIZE( sp ) /* a5 */
load_x x16, 13 * portWORD_SIZE( sp ) /* a6 */
load_x x17, 14 * portWORD_SIZE( sp ) /* a7 */
load_x x18, 15 * portWORD_SIZE( sp ) /* s2 */
load_x x19, 16 * portWORD_SIZE( sp ) /* s3 */
load_x x20, 17 * portWORD_SIZE( sp ) /* s4 */
load_x x21, 18 * portWORD_SIZE( sp ) /* s5 */
load_x x22, 19 * portWORD_SIZE( sp ) /* s6 */
load_x x23, 20 * portWORD_SIZE( sp ) /* s7 */
load_x x24, 21 * portWORD_SIZE( sp ) /* s8 */
load_x x25, 22 * portWORD_SIZE( sp ) /* s9 */
load_x x26, 23 * portWORD_SIZE( sp ) /* s10 */
load_x x27, 24 * portWORD_SIZE( sp ) /* s11 */
load_x x28, 25 * portWORD_SIZE( sp ) /* t3 */
load_x x29, 26 * portWORD_SIZE( sp ) /* t4 */
load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */
load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */
addi sp, sp, portCONTEXT_SIZE -----栈空间释放
mret ---中断返回