diff --git a/Port/port_x32/RISC-V32/port_rv32_HWS.S b/Port/port_x32/RISC-V32/port_rv32_HWS.S new file mode 100644 index 00000000..813604c1 --- /dev/null +++ b/Port/port_x32/RISC-V32/port_rv32_HWS.S @@ -0,0 +1,287 @@ +/**************************************************************************//** + * @item CosyOS-III Port + * @file port_rv32_HWS.S + * @brief RISC-V32 Core Port File for Hardware Stack + * @note x4(tp)、mscratch、0xE000E040 专用于任务切换,不允许用户使用。 + * @author 迟凯峰 + * @version v3.0.6 + * @date 2026.08.09 + **************************************************************************//** + + * 断点测试 + + 1.断点测试功能是为了有效验证,内核解锁后的 break point 1、2 是否等效于仍然处于 + 服务层临界区的保护之中,这取决于处理器的微内核架构。 + 2.开启断点测试后,如果 break point 1、2 已不在服务层临界区的保护之中,必会调用 + test_breakpoint_hook,用户可在该钩子函数中用打印或点灯等方式来报告测试未通过。 + 3.如果通过了断点测试,可确信 break point 1、2 等效于仍然处于服务层临界区的保护 + 之中,此时,用户可手动关闭断点防护功能(LINE: 79)提高任务切换效率。 + 4.断点测试不是必须的,如果您不追求卓越性能,可不必进行断点测试,默认已开启断点 + 防护功能,可确保任务切换的安全、可靠。 + 5.测试时间:10分钟即可,如果连续测试10分钟仍未报告测试失败,说明已经通过了测试。 + 6.test_breakpoint_hook,需用户自行实现。 + */ +#if (0) // 断点测试开关 +#define __TEST_BREAKPOINT +#endif +//////////////////////////////////////////////////////////////////////////////// + +#include "syscfg.h" +#include "mcucfg_rv32.h" + +#define fstore fsw +#define store sw +#define load lw +#define fload flw + +//////////////////////////////////////////////////////////////////////////////// + +/* PendSV 软中断 */ + +.global OS_PendSV_Handler +.align 2 +OS_PendSV_Handler: // hardware push Caller + +#if defined ( __TEST_BREAKPOINT ) + la tp, test_breakpoint_hook + csrw mscratch, tp +#endif + +/* push Callee */ +#if !defined ( __riscv_32e ) + addi sp, sp,-32 * MCUCFG_REGBYTES +#else + addi sp, sp,-16 * MCUCFG_REGBYTES +#endif + store x8, 8 * MCUCFG_REGBYTES(sp) + store x9, 9 * MCUCFG_REGBYTES(sp) +#if !defined ( __riscv_32e ) + store x18, 18 * MCUCFG_REGBYTES(sp) + store x19, 19 * MCUCFG_REGBYTES(sp) + store x20, 20 * MCUCFG_REGBYTES(sp) + store x21, 21 * MCUCFG_REGBYTES(sp) + store x22, 22 * MCUCFG_REGBYTES(sp) + store x23, 23 * MCUCFG_REGBYTES(sp) + store x24, 24 * MCUCFG_REGBYTES(sp) + store x25, 25 * MCUCFG_REGBYTES(sp) + store x26, 26 * MCUCFG_REGBYTES(sp) + store x27, 27 * MCUCFG_REGBYTES(sp) +#endif + + call sPendSV_Handler + beqz a0, 2f // 直接返回 + la s1, s_task_current + addi s0, a0, -1 + beqz s0, 1f // 恢复现场 + +/* push mepc */ + csrr a0, mepc +#if (1) // 断点防护功能(默认开启) + la t0, _break_point_ + 4 + bltu t0, a0, 0f + addi t0, t0, -4 + bltu a0, t0, 0f + csrr a0, mscratch +#endif +0: store a0, 0 * MCUCFG_REGBYTES(sp) + +/* 任务-PC 监控 */ +#if (SYSCFG_TASKPC_MONITOR == 1) + la a1, s_pc + sw a0, (a1) +#endif + +/* 内核上锁 */// 使服务层临界区连续 +1: li a0, 0xFF + lui tp, (0xE000E040 >> 12) + sw a0, (0xE000E040 & 0xFFF)(tp) + fence.i + +/* 返回至 _task_switch_ */ + la a0, _task_switch_ + csrw mepc, a0 + mret // hardware pop Caller + +/* pop Callee */ +2: load x8, 8 * MCUCFG_REGBYTES(sp) + load x9, 9 * MCUCFG_REGBYTES(sp) +#if defined ( __riscv_32e ) + addi sp, sp, 16 * MCUCFG_REGBYTES +#else + load x18, 18 * MCUCFG_REGBYTES(sp) + load x19, 19 * MCUCFG_REGBYTES(sp) + load x20, 20 * MCUCFG_REGBYTES(sp) + load x21, 21 * MCUCFG_REGBYTES(sp) + load x22, 22 * MCUCFG_REGBYTES(sp) + load x23, 23 * MCUCFG_REGBYTES(sp) + load x24, 24 * MCUCFG_REGBYTES(sp) + load x25, 25 * MCUCFG_REGBYTES(sp) + load x26, 26 * MCUCFG_REGBYTES(sp) + load x27, 27 * MCUCFG_REGBYTES(sp) + addi sp, sp, 32 * MCUCFG_REGBYTES +#endif + mret // hardware pop Caller + +//////////////////////////////////////////////////////////////////////////////// + +/* 任务切换 */ + +.local _task_switch_ +.align 2 +_task_switch_: + + beqz s0, 1f // 恢复现场 +/* push Caller */ + store x1, 1 * MCUCFG_REGBYTES(sp) + store x5, 5 * MCUCFG_REGBYTES(sp) + store x6, 6 * MCUCFG_REGBYTES(sp) + store x7, 7 * MCUCFG_REGBYTES(sp) + store x10, 10 * MCUCFG_REGBYTES(sp) + store x11, 11 * MCUCFG_REGBYTES(sp) + store x12, 12 * MCUCFG_REGBYTES(sp) + store x13, 13 * MCUCFG_REGBYTES(sp) + store x14, 14 * MCUCFG_REGBYTES(sp) + store x15, 15 * MCUCFG_REGBYTES(sp) +#if !defined ( __riscv_32e ) + store x16, 16 * MCUCFG_REGBYTES(sp) + store x17, 17 * MCUCFG_REGBYTES(sp) + store x28, 28 * MCUCFG_REGBYTES(sp) + store x29, 29 * MCUCFG_REGBYTES(sp) + store x30, 30 * MCUCFG_REGBYTES(sp) + store x31, 31 * MCUCFG_REGBYTES(sp) +#endif + +/* push FPU */ +#if (MCUCFG_FPU_AUTOSTORE == 1) + addi sp, sp,-32 * MCUCFG_FPUBYTES + fstore f0, 0 * MCUCFG_FPUBYTES(sp) + fstore f1, 1 * MCUCFG_FPUBYTES(sp) + fstore f2, 2 * MCUCFG_FPUBYTES(sp) + fstore f3, 3 * MCUCFG_FPUBYTES(sp) + fstore f4, 4 * MCUCFG_FPUBYTES(sp) + fstore f5, 5 * MCUCFG_FPUBYTES(sp) + fstore f6, 6 * MCUCFG_FPUBYTES(sp) + fstore f7, 7 * MCUCFG_FPUBYTES(sp) + fstore f8, 8 * MCUCFG_FPUBYTES(sp) + fstore f9, 9 * MCUCFG_FPUBYTES(sp) + fstore f10, 10 * MCUCFG_FPUBYTES(sp) + fstore f11, 11 * MCUCFG_FPUBYTES(sp) + fstore f12, 12 * MCUCFG_FPUBYTES(sp) + fstore f13, 13 * MCUCFG_FPUBYTES(sp) + fstore f14, 14 * MCUCFG_FPUBYTES(sp) + fstore f15, 15 * MCUCFG_FPUBYTES(sp) + fstore f16, 16 * MCUCFG_FPUBYTES(sp) + fstore f17, 17 * MCUCFG_FPUBYTES(sp) + fstore f18, 18 * MCUCFG_FPUBYTES(sp) + fstore f19, 19 * MCUCFG_FPUBYTES(sp) + fstore f20, 20 * MCUCFG_FPUBYTES(sp) + fstore f21, 21 * MCUCFG_FPUBYTES(sp) + fstore f22, 22 * MCUCFG_FPUBYTES(sp) + fstore f23, 23 * MCUCFG_FPUBYTES(sp) + fstore f24, 24 * MCUCFG_FPUBYTES(sp) + fstore f25, 25 * MCUCFG_FPUBYTES(sp) + fstore f26, 26 * MCUCFG_FPUBYTES(sp) + fstore f27, 27 * MCUCFG_FPUBYTES(sp) + fstore f28, 28 * MCUCFG_FPUBYTES(sp) + fstore f29, 29 * MCUCFG_FPUBYTES(sp) + fstore f30, 30 * MCUCFG_FPUBYTES(sp) + fstore f31, 31 * MCUCFG_FPUBYTES(sp) +#endif + + lw t0, (s1) + sw sp, (t0) + fence rw, rw + +/* 恢复现场 */ +1: la t1, s_task_news + lw t0, (t1) + lw sp, (t0) + sw t0, (s1) + +#if defined ( __TEST_BREAKPOINT ) + li a0, (0x0001UL << (MCUCFG_XXXx_IRQn % 32) ) + li a1, (0xE000E200 + MCUCFG_XXXx_IRQn / 32 * 4) + sw a0, (a1) // 触发 PendSV +#endif + +/* pop FPU */ +#if (MCUCFG_FPU_AUTOSTORE == 1) + fload f0, 0 * MCUCFG_FPUBYTES(sp) + fload f1, 1 * MCUCFG_FPUBYTES(sp) + fload f2, 2 * MCUCFG_FPUBYTES(sp) + fload f3, 3 * MCUCFG_FPUBYTES(sp) + fload f4, 4 * MCUCFG_FPUBYTES(sp) + fload f5, 5 * MCUCFG_FPUBYTES(sp) + fload f6, 6 * MCUCFG_FPUBYTES(sp) + fload f7, 7 * MCUCFG_FPUBYTES(sp) + fload f8, 8 * MCUCFG_FPUBYTES(sp) + fload f9, 9 * MCUCFG_FPUBYTES(sp) + fload f10, 10 * MCUCFG_FPUBYTES(sp) + fload f11, 11 * MCUCFG_FPUBYTES(sp) + fload f12, 12 * MCUCFG_FPUBYTES(sp) + fload f13, 13 * MCUCFG_FPUBYTES(sp) + fload f14, 14 * MCUCFG_FPUBYTES(sp) + fload f15, 15 * MCUCFG_FPUBYTES(sp) + fload f16, 16 * MCUCFG_FPUBYTES(sp) + fload f17, 17 * MCUCFG_FPUBYTES(sp) + fload f18, 18 * MCUCFG_FPUBYTES(sp) + fload f19, 19 * MCUCFG_FPUBYTES(sp) + fload f20, 20 * MCUCFG_FPUBYTES(sp) + fload f21, 21 * MCUCFG_FPUBYTES(sp) + fload f22, 22 * MCUCFG_FPUBYTES(sp) + fload f23, 23 * MCUCFG_FPUBYTES(sp) + fload f24, 24 * MCUCFG_FPUBYTES(sp) + fload f25, 25 * MCUCFG_FPUBYTES(sp) + fload f26, 26 * MCUCFG_FPUBYTES(sp) + fload f27, 27 * MCUCFG_FPUBYTES(sp) + fload f28, 28 * MCUCFG_FPUBYTES(sp) + fload f29, 29 * MCUCFG_FPUBYTES(sp) + fload f30, 30 * MCUCFG_FPUBYTES(sp) + fload f31, 31 * MCUCFG_FPUBYTES(sp) + addi sp, sp, 32 * MCUCFG_FPUBYTES +#endif +/* pop mepc to mscratch */ + load a0, 0 * MCUCFG_REGBYTES(sp) + csrw mscratch, a0 + +/* pop Caller & Callee */ + load x1, 1 * MCUCFG_REGBYTES(sp) + load x5, 5 * MCUCFG_REGBYTES(sp) + load x6, 6 * MCUCFG_REGBYTES(sp) + load x7, 7 * MCUCFG_REGBYTES(sp) + load x8, 8 * MCUCFG_REGBYTES(sp) + load x9, 9 * MCUCFG_REGBYTES(sp) + load x10, 10 * MCUCFG_REGBYTES(sp) + load x11, 11 * MCUCFG_REGBYTES(sp) + load x12, 12 * MCUCFG_REGBYTES(sp) + load x13, 13 * MCUCFG_REGBYTES(sp) + load x14, 14 * MCUCFG_REGBYTES(sp) + load x15, 15 * MCUCFG_REGBYTES(sp) +#if defined ( __riscv_32e ) + addi sp, sp, 16 * MCUCFG_REGBYTES +#else + load x16, 16 * MCUCFG_REGBYTES(sp) + load x17, 17 * MCUCFG_REGBYTES(sp) + load x18, 18 * MCUCFG_REGBYTES(sp) + load x19, 19 * MCUCFG_REGBYTES(sp) + load x20, 20 * MCUCFG_REGBYTES(sp) + load x21, 21 * MCUCFG_REGBYTES(sp) + load x22, 22 * MCUCFG_REGBYTES(sp) + load x23, 23 * MCUCFG_REGBYTES(sp) + load x24, 24 * MCUCFG_REGBYTES(sp) + load x25, 25 * MCUCFG_REGBYTES(sp) + load x26, 26 * MCUCFG_REGBYTES(sp) + load x27, 27 * MCUCFG_REGBYTES(sp) + load x28, 28 * MCUCFG_REGBYTES(sp) + load x29, 29 * MCUCFG_REGBYTES(sp) + load x30, 30 * MCUCFG_REGBYTES(sp) + load x31, 31 * MCUCFG_REGBYTES(sp) + addi sp, sp, 32 * MCUCFG_REGBYTES +#endif + + sw zero, (0xE000E040 & 0xFFF)(tp) // 内核解锁(退出服务层临界区) + +_break_point_: + csrr tp, mscratch // break point 1 + jr tp // break point 2 +