/**************************************************************************//**
 * @item     CosyOS-III Port
 * @file     port_rv32_SWS.S
 * @brief    RISC-V32 Core Port File for Software Stack
 * @note     对处理器特权模式无要求。
 * @note     x4(tp)寄存器默认未保护，如需保护可自行开启。
 * @author   迟凯峰
 * @version  v3.0.7
 * @date     2026.08.14
 ******************************************************************************/

#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:

/* push Caller & Callee */
#if !defined ( __riscv_32e )
	addi sp, sp,-32 * MCUCFG_REGBYTES
#else
	addi sp, sp,-16 * MCUCFG_REGBYTES
#endif
	store    x1,  1 * MCUCFG_REGBYTES(sp)
////store    x4,  4 * MCUCFG_REGBYTES(sp) // default not store/load x4
	store    x5,  5 * MCUCFG_REGBYTES(sp)
	store    x6,  6 * MCUCFG_REGBYTES(sp)
	store    x7,  7 * MCUCFG_REGBYTES(sp)
	store    x8,  8 * MCUCFG_REGBYTES(sp)
	store    x9,  9 * 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   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)
	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

	call    sPendSV_Handler
	beqz    a0,  2f // 直接返回
	la      s1,  s_task_current
	addi    s0,  a0, -1
	beqz    s0,  1f // 恢复现场

/* push mepc */
	csrr    a0,  mepc
	store   a0,   0 * MCUCFG_REGBYTES(sp)

/* 任务-PC 监控 */
#if (SYSCFG_TASKPC_MONITOR == 1)
	la      a1,  s_pc
	sw      a0, (a1)
#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)

/* 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 */
	load    a0,   0 * MCUCFG_REGBYTES(sp)
	csrw    mepc, a0

/* pop Caller & Callee */
2:	load    x1,   1 * MCUCFG_REGBYTES(sp)
////load    x4,   4 * MCUCFG_REGBYTES(sp) // default not store/load x4
	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

	mret

