mirror of
https://gitee.com/cosyos/cosyos.git
synced 2026-08-17 08:42:13 +08:00
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user