diff --git a/kernel/liteos_m/arch/risc-v/riscv32/gcc/los_dispatch.S b/kernel/liteos_m/arch/risc-v/riscv32/gcc/los_dispatch.S index c798df06..0f9074fa 100644 --- a/kernel/liteos_m/arch/risc-v/riscv32/gcc/los_dispatch.S +++ b/kernel/liteos_m/arch/risc-v/riscv32/gcc/los_dispatch.S @@ -107,14 +107,14 @@ HalTaskContextSwitch: PUSH_ALL_REG - + // a0保存着 mstatus // clear mpie - li a2, RISCV_MSTATUS_MPIE - not a2, a2 + li a2, RISCV_MSTATUS_MPIE // 0x00000080 + not a2, a2 // 0xffffff7f and a0, a0, a2 // get mie - andi a1, a0, RISCV_MSTATUS_MIE + andi a1, a0, RISCV_MSTATUS_MIE // 0x00000008 // must be in machine mode ori a1, a1, 0x180 @@ -125,24 +125,25 @@ HalTaskContextSwitch: li a2, RISCV_MSTATUS_MIE not a2, a2 and a0, a0, a2 - + // a0 清除 mie后的 mstatus SREG a0, 16 * REGBYTES(sp) - // 把当前程序地址压栈,用于异常地址 + // 返回地址 SREG ra, 17 * REGBYTES(sp) la a1, g_losTask - lw a0, 0(a1) - sw sp, TASK_CB_KERNEL_SP(a0) + lw a0, 0(a1) // g_losTask->runTask + // 把当前sp指针保存到 g_losTask->runTask->stackPointer + sw sp, TASK_CB_KERNEL_SP(a0) // TASK_CB_KERNEL_SP==0 - lw a0, 4(a1) - sw a0, 0(a1) + lw a0, 4(a1) // g_losTask->newTask + sw a0, 0(a1) // g_losTask->runTask=g_losTask->newTask HalStartToRun: la a1, g_losTask - lw a0, 4(a1) + lw a0, 4(a1) // g_losTask->newTask // retireve stack pointer - lw sp, TASK_CB_KERNEL_SP(a0) + lw sp, TASK_CB_KERNEL_SP(a0) // sp=g_losTask->newTask->stackPointer // enable global interrupts lw t0, 16 * REGBYTES(sp) @@ -150,7 +151,7 @@ HalStartToRun: // retrieve the address at which exception happened lw t0, 17 * REGBYTES(sp) - csrw mepc, t0 + csrw mepc, t0 // 修改mepc,随后调用mret就会跳转到这个地址 // retrieve the registers POP_ALL_REG diff --git a/kernel/liteos_m/arch/risc-v/riscv32/gcc/los_exc.S b/kernel/liteos_m/arch/risc-v/riscv32/gcc/los_exc.S index 7a504ff6..2e2cd62d 100644 --- a/kernel/liteos_m/arch/risc-v/riscv32/gcc/los_exc.S +++ b/kernel/liteos_m/arch/risc-v/riscv32/gcc/los_exc.S @@ -145,14 +145,15 @@ HalTrapEntry: csrw mscratch, sp la t0, g_excInfo lh t1, 0(t0) + // 不为0时跳转 bnez t1, 1f la sp, __except_stack_top 1: addi t1, t1, 0x1 - sh t1, 0(t0) + sh t1, 0(t0) // g_excInfo->nestCnt++ call HalExcEntry la t0, g_excInfo - sh zero, 0(t0) + sh zero, 0(t0) // g_excInfo->nestCnt=0 csrr sp, mscratch addi sp, sp, 4 * REGBYTES lw t0, 16 * REGBYTES(sp) @@ -170,19 +171,28 @@ HalTrapEntry: .global HalTrapVector .equ TRAP_INTERRUPT_MODE_MASK, 0x80000000 .align 4 +// cpu产生异常时会自动跳转到这个地址 +// 产生中断时硬件会自动把返回地址保存到mepc中 +// 可调用mret将mepc恢复到pc中 HalTrapVector: PUSH_CALLER_REG + // mcause保存异常原因 读取到a0中 csrr a0, mcause li a1, TRAP_INTERRUPT_MODE_MASK - li a2, MCAUSE_INT_ID_MASK + li a2, MCAUSE_INT_ID_MASK // 0x7FFFFFFF and a1, a0, a1 and a0, a2, a0 + // 等于0时跳转 beqz a1, HalTrapEntry // 异常处理退出不会返回到这里 + // 保存线程sp指针 csrw mscratch, sp la sp, __start_and_irq_stack_top + // 处理中断 a0 保存着异常原因,如果最高位为0 则为中断号 jal HalHwiInterruptDone + // 恢复线程sp指针 csrr sp, mscratch + // 切线程都是在线程栈中完成的 call HalIrqEndCheckNeedSched // HalIrqEndCheckNeedSched如果切换了任务,这里会从切换后的任务返回 POP_CALLER_REG