#include "os_config.h" #if __riscv_xlen == 64 #define REG_BYTES 8 #define STORE sd #define LOAD ld #define FSTORE fsd #define FLOAD fld #elif __riscv_xlen == 32 #define REG_BYTES 4 #define STORE sw #define LOAD lw #define FSTORE fsw #define FLOAD flw #else #error Assembler did not define __riscv_xlen #endif #define CONTEXT_SIZE (32 * REG_BYTES) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// //// CODE #ifdef OS_CFG_CPU_CLZ_ASM_PRESENT .section .text.cpu_clz,"ax",%progbits .align 8 .func .global cpu_clz cpu_clz: clz a0, a0 ret .endfunc #endif .section .text.os_port_context_switch_to,"ax",%progbits .align 8 .func .global os_port_context_switch_to .extern os_port_on_switch_success os_port_context_switch_to: /* machine mode, disable ISR */ li t0, 0x1800 csrw mstatus, t0 /* first save interrupt stack */ la t0, _eusrstack addi t0, t0, -512 csrw mscratch,t0 /* restore sp */ LOAD sp, (a0) csrrw sp, mscratch, sp jal os_port_on_switch_success csrrw sp, mscratch, sp /* restore mstatus.MPIE */ LOAD a0, 0*REG_BYTES(sp) csrs mstatus, a0 /* restore mepc */ LOAD a0, 2 * REG_BYTES(sp) csrw mepc, a0 /* return address */ LOAD x1, 1 * REG_BYTES(sp) LOAD x4, 4 * REG_BYTES(sp) LOAD x5, 5 * REG_BYTES(sp) LOAD x6, 6 * REG_BYTES(sp) LOAD x7, 7 * REG_BYTES(sp) LOAD x8, 8 * REG_BYTES(sp) LOAD x9, 9 * REG_BYTES(sp) LOAD x10, 10 * REG_BYTES(sp) LOAD x11, 11 * REG_BYTES(sp) LOAD x12, 12 * REG_BYTES(sp) LOAD x13, 13 * REG_BYTES(sp) LOAD x14, 14 * REG_BYTES(sp) LOAD x15, 15 * REG_BYTES(sp) LOAD x16, 16 * REG_BYTES(sp) LOAD x17, 17 * REG_BYTES(sp) LOAD x18, 18 * REG_BYTES(sp) LOAD x19, 19 * REG_BYTES(sp) LOAD x20, 20 * REG_BYTES(sp) LOAD x21, 21 * REG_BYTES(sp) LOAD x22, 22 * REG_BYTES(sp) LOAD x23, 23 * REG_BYTES(sp) LOAD x24, 24 * REG_BYTES(sp) LOAD x25, 25 * REG_BYTES(sp) LOAD x26, 26 * REG_BYTES(sp) LOAD x27, 27 * REG_BYTES(sp) LOAD x28, 28 * REG_BYTES(sp) LOAD x29, 29 * REG_BYTES(sp) LOAD x30, 30 * REG_BYTES(sp) LOAD x31, 31 * REG_BYTES(sp) addi sp, sp, CONTEXT_SIZE /* load float reg */ #if (OS_CFG_CPU_MPU_PRESENT) FLOAD f0, 0 * REG_BYTES(sp) FLOAD f1, 1 * REG_BYTES(sp) FLOAD f2, 2 * REG_BYTES(sp) FLOAD f3, 3 * REG_BYTES(sp) FLOAD f4, 4 * REG_BYTES(sp) FLOAD f5, 5 * REG_BYTES(sp) FLOAD f6, 6 * REG_BYTES(sp) FLOAD f7, 7 * REG_BYTES(sp) FLOAD f8, 8 * REG_BYTES(sp) FLOAD f9, 9 * REG_BYTES(sp) FLOAD f10, 10 * REG_BYTES(sp) FLOAD f11, 11 * REG_BYTES(sp) FLOAD f12, 12 * REG_BYTES(sp) FLOAD f13, 13 * REG_BYTES(sp) FLOAD f14, 14 * REG_BYTES(sp) FLOAD f15, 15 * REG_BYTES(sp) FLOAD f16, 16 * REG_BYTES(sp) FLOAD f17, 17 * REG_BYTES(sp) FLOAD f18, 18 * REG_BYTES(sp) FLOAD f19, 19 * REG_BYTES(sp) FLOAD f20, 20 * REG_BYTES(sp) FLOAD f21, 21 * REG_BYTES(sp) FLOAD f22, 22 * REG_BYTES(sp) FLOAD f23, 23 * REG_BYTES(sp) FLOAD f24, 24 * REG_BYTES(sp) FLOAD f25, 25 * REG_BYTES(sp) FLOAD f26, 26 * REG_BYTES(sp) FLOAD f27, 27 * REG_BYTES(sp) FLOAD f28, 28 * REG_BYTES(sp) FLOAD f29, 29 * REG_BYTES(sp) FLOAD f30, 30 * REG_BYTES(sp) FLOAD f31, 31 * REG_BYTES(sp) addi sp, sp, 32 * REG_BYTES #endif mret .endfunc .section .text.SW_Handler,"ax",%progbits .align 8 .func .global SW_Handler .extern g_os_port_switch_from_sp .extern g_os_port_switch_to_sp .extern os_isr_enter .extern os_isr_leave .extern os_port_on_switch_success .extern g_t0 SW_Handler: #if (OS_CFG_CPU_FPU_PRESENT) addi sp, sp, -32 * REG_BYTES FSTORE f0, 0 * REG_BYTES(sp) FSTORE f1, 1 * REG_BYTES(sp) FSTORE f2, 2 * REG_BYTES(sp) FSTORE f3, 3 * REG_BYTES(sp) FSTORE f4, 4 * REG_BYTES(sp) FSTORE f5, 5 * REG_BYTES(sp) FSTORE f6, 6 * REG_BYTES(sp) FSTORE f7, 7 * REG_BYTES(sp) FSTORE f8, 8 * REG_BYTES(sp) FSTORE f9, 9 * REG_BYTES(sp) FSTORE f10, 10 * REG_BYTES(sp) FSTORE f11, 11 * REG_BYTES(sp) FSTORE f12, 12 * REG_BYTES(sp) FSTORE f13, 13 * REG_BYTES(sp) FSTORE f14, 14 * REG_BYTES(sp) FSTORE f15, 15 * REG_BYTES(sp) FSTORE f16, 16 * REG_BYTES(sp) FSTORE f17, 17 * REG_BYTES(sp) FSTORE f18, 18 * REG_BYTES(sp) FSTORE f19, 19 * REG_BYTES(sp) FSTORE f20, 20 * REG_BYTES(sp) FSTORE f21, 21 * REG_BYTES(sp) FSTORE f22, 22 * REG_BYTES(sp) FSTORE f23, 23 * REG_BYTES(sp) FSTORE f24, 24 * REG_BYTES(sp) FSTORE f25, 25 * REG_BYTES(sp) FSTORE f26, 26 * REG_BYTES(sp) FSTORE f27, 27 * REG_BYTES(sp) FSTORE f28, 28 * REG_BYTES(sp) FSTORE f29, 29 * REG_BYTES(sp) FSTORE f30, 30 * REG_BYTES(sp) FSTORE f31, 31 * REG_BYTES(sp) #endif addi sp, sp, -CONTEXT_SIZE // 留出栈空间 STORE t0, 5*REG_BYTES(sp) // 保存 t0 li t0, 0x80 STORE t0, 0 * REG_BYTES(sp) // 设置 MPIE csrr t0, mepc STORE t0, 2*REG_BYTES(sp) // 保存正在运行任务的 pc 指针 STORE x1, 1 * REG_BYTES(sp) // return address STORE x4, 4 * REG_BYTES(sp) STORE x6, 6 * REG_BYTES(sp) STORE x7, 7 * REG_BYTES(sp) STORE x8, 8 * REG_BYTES(sp) STORE x9, 9 * REG_BYTES(sp) STORE x10, 10 * REG_BYTES(sp) STORE x11, 11 * REG_BYTES(sp) STORE x12, 12 * REG_BYTES(sp) STORE x13, 13 * REG_BYTES(sp) STORE x14, 14 * REG_BYTES(sp) STORE x15, 15 * REG_BYTES(sp) STORE x16, 16 * REG_BYTES(sp) STORE x17, 17 * REG_BYTES(sp) STORE x18, 18 * REG_BYTES(sp) STORE x19, 19 * REG_BYTES(sp) STORE x20, 20 * REG_BYTES(sp) STORE x21, 21 * REG_BYTES(sp) STORE x22, 22 * REG_BYTES(sp) STORE x23, 23 * REG_BYTES(sp) STORE x24, 24 * REG_BYTES(sp) STORE x25, 25 * REG_BYTES(sp) STORE x26, 26 * REG_BYTES(sp) STORE x27, 27 * REG_BYTES(sp) STORE x28, 28 * REG_BYTES(sp) STORE x29, 29 * REG_BYTES(sp) STORE x30, 30 * REG_BYTES(sp) STORE x31, 31 * REG_BYTES(sp) la s0, g_os_port_switch_from_sp LOAD s1, 0(s0) STORE sp, 0(s1) // 将 sp 存入 g_os_port_switch_from_sp // 切换到 isr stack csrrw sp,mscratch,sp jal os_port_on_switch_success csrrw sp,mscratch,sp la s0, g_os_port_switch_to_sp LOAD s1, 0(s0) LOAD sp, 0(s1) // 将 sp 指向 g_os_port_switch_to_sp 栈 LOAD a0, 2 * REG_BYTES(sp) // 加载/恢复 mepc csrw mepc, a0 LOAD x1, 1*REG_BYTES(sp) li t0, 0x1800 csrs mstatus, t0 // 确保 M 模式 LOAD t0, 0*REG_BYTES(sp) // 加载 mstatus csrs mstatus, t0 // 恢复 mstatus LOAD x4, 4 * REG_BYTES(sp) LOAD x5, 5 * REG_BYTES(sp) LOAD x6, 6 * REG_BYTES(sp) LOAD x7, 7 * REG_BYTES(sp) LOAD x8, 8 * REG_BYTES(sp) LOAD x9, 9 * REG_BYTES(sp) LOAD x10, 10 * REG_BYTES(sp) LOAD x11, 11 * REG_BYTES(sp) LOAD x12, 12 * REG_BYTES(sp) LOAD x13, 13 * REG_BYTES(sp) LOAD x14, 14 * REG_BYTES(sp) LOAD x15, 15 * REG_BYTES(sp) LOAD x16, 16 * REG_BYTES(sp) LOAD x17, 17 * REG_BYTES(sp) LOAD x18, 18 * REG_BYTES(sp) LOAD x19, 19 * REG_BYTES(sp) LOAD x20, 20 * REG_BYTES(sp) LOAD x21, 21 * REG_BYTES(sp) LOAD x22, 22 * REG_BYTES(sp) LOAD x23, 23 * REG_BYTES(sp) LOAD x24, 24 * REG_BYTES(sp) LOAD x25, 25 * REG_BYTES(sp) LOAD x26, 26 * REG_BYTES(sp) LOAD x27, 27 * REG_BYTES(sp) LOAD x28, 28 * REG_BYTES(sp) LOAD x29, 29 * REG_BYTES(sp) LOAD x30, 30 * REG_BYTES(sp) LOAD x31, 31 * REG_BYTES(sp) addi sp, sp, CONTEXT_SIZE // 恢复栈指针 /* load float reg */ #if (OS_CFG_CPU_FPU_PRESENT) FLOAD f0, 0 * REG_BYTES(sp) FLOAD f1, 1 * REG_BYTES(sp) FLOAD f2, 2 * REG_BYTES(sp) FLOAD f3, 3 * REG_BYTES(sp) FLOAD f4, 4 * REG_BYTES(sp) FLOAD f5, 5 * REG_BYTES(sp) FLOAD f6, 6 * REG_BYTES(sp) FLOAD f7, 7 * REG_BYTES(sp) FLOAD f8, 8 * REG_BYTES(sp) FLOAD f9, 9 * REG_BYTES(sp) FLOAD f10, 10 * REG_BYTES(sp) FLOAD f11, 11 * REG_BYTES(sp) FLOAD f12, 12 * REG_BYTES(sp) FLOAD f13, 13 * REG_BYTES(sp) FLOAD f14, 14 * REG_BYTES(sp) FLOAD f15, 15 * REG_BYTES(sp) FLOAD f16, 16 * REG_BYTES(sp) FLOAD f17, 17 * REG_BYTES(sp) FLOAD f18, 18 * REG_BYTES(sp) FLOAD f19, 19 * REG_BYTES(sp) FLOAD f20, 20 * REG_BYTES(sp) FLOAD f21, 21 * REG_BYTES(sp) FLOAD f22, 22 * REG_BYTES(sp) FLOAD f23, 23 * REG_BYTES(sp) FLOAD f24, 24 * REG_BYTES(sp) FLOAD f25, 25 * REG_BYTES(sp) FLOAD f26, 26 * REG_BYTES(sp) FLOAD f27, 27 * REG_BYTES(sp) FLOAD f28, 28 * REG_BYTES(sp) FLOAD f29, 29 * REG_BYTES(sp) FLOAD f30, 30 * REG_BYTES(sp) FLOAD f31, 31 * REG_BYTES(sp) addi sp, sp, 32 * REG_BYTES #endif mret // 从 M 模式退出 .endfunc .align 4 .end