/**************************************************************************//**
 * @item     CosyOS-III Port
 * @file     port_rv32.h
 * @brief    RISC-V32 Core Port File
 * @author   迟凯峰
 * @version  v3.0.8
 * @date     2026.08.15
 ******************************************************************************/

#ifndef __PORT_RV32_H
#define __PORT_RV32_H

/* INCLUDE */
#include "port_x32.h"
#include "mcucfg_rv32.h"
#include SYSCFG_STANDARDHEAD
#include "os_cmsis.h"
#include "os_stack.h"


/* CONST & ATTRIBUTE */
#define MCUCFG_STACK_ALIGN        __ALIGNED(16)
#define MCUCFG_TASKSTACK_REALLOC  __DISABLED__
#if (MCUCFG_FPU_AUTOSTORE == __ENABLED__)
#define MCUCFG_PUSH_FPU          (32 * MCUCFG_FPUBYTES)
#else
#define MCUCFG_PUSH_FPU           0
#endif
#if !defined ( __riscv_32e )
#define MCUCFG_PUSH_REG          (32 * MCUCFG_REGBYTES)
#else
#define MCUCFG_PUSH_REG          (16 * MCUCFG_REGBYTES)
#endif
#define MCUCFG_BASICSTACKSIZE    (MCUCFG_PUSH_FPU + MCUCFG_PUSH_REG)


/* TaskCtrl */
#define mTaskCtrl_Head_           m_sp_t psp;
#define mTaskCtrl_Tail_           m_sp_t psp_top;


/*
 * SysTick
 */
#if (MCUCFG_SYSTICK_AUTOCONFIG == __ENABLED__)
/* 自动配置 */
#define MCUCFG_SYSTICK_COUNTMODE   1             /*!< 计数方式，1：从零向上计数至重装载值溢出 */
#define MCUCFG_SYSTICK_LIMITVALUE (1UL << 32)    /*!< 极限值 */
#define MCUCFG_SYSTICK_CURRVALUE  *(volatile s_u32_t *)(0xE000F008) /*!< 当前值寄存器 */
#define MCUCFG_SYSTICK_CLK         MCUCFG_SYSCLK
#define MCUCFG_SYSTICK_COUNT1CYC  (SYSCFG_SYSTICK_CYCLE * MCUCFG_SYSTICK_CLK * 1UL)
#define MCUCFG_SYSTICK_LOADVALUE  (MCUCFG_SYSTICK_COUNT1CYC - 1)
#define MCUCFG_SYSTICK_MAXVALUE    MCUCFG_SYSTICK_LOADVALUE
#define MCUCFG_SYSTICK_MINVALUE    0
#if (MCUCFG_SYSTICK_COUNT1CYC > MCUCFG_SYSTICK_LIMITVALUE)
#error 系统滴答定时器溢出。
#endif
#define mSysTick_SetLOAD()        *(volatile s_u32_t *)(0xE000F010) = MCUCFG_SYSTICK_LOADVALUE
#define mSysTick_SetCTRL()        *(volatile s_u32_t *)(0xE000F000) = 0x2F
#define mSysTick_INIT() \
do{ \
	mSysTick_SetPRI(); \
	mSysTick_SetLOAD(); \
	mSysTick_SetCTRL(); \
}while(false)

#else
/* 手动配置 */
  #if (MCUCFG_SYSTICK_COUNTMODE == 1 || MCUCFG_SYSTICK_COUNTMODE == 2)
#define MCUCFG_SYSTICK_MAXVALUE   (MCUCFG_SYSTICK_LOADVALUE)
#define MCUCFG_SYSTICK_MINVALUE    0
#define MCUCFG_SYSTICK_COUNT1CYC  (MCUCFG_SYSTICK_LOADVALUE + 1UL)

#elif (MCUCFG_SYSTICK_COUNTMODE == 3 || MCUCFG_SYSTICK_COUNTMODE == 4)
#define MCUCFG_SYSTICK_LIMITVALUE (1UL << MCUCFG_SYSTICK_BITS)
#define MCUCFG_SYSTICK_MAXVALUE   (MCUCFG_SYSTICK_LIMITVALUE)
#define MCUCFG_SYSTICK_MINVALUE   (MCUCFG_SYSTICK_LOADVALUE)
#define MCUCFG_SYSTICK_COUNT1CYC  (MCUCFG_SYSTICK_MAXVALUE - MCUCFG_SYSTICK_MINVALUE)
#endif

#define mSysTick_INIT()  mSysTick_SetPRI()
#endif


/*
 * SysTick_Handler + PendSV_Handler
 */

/* SysTick */
#define mSysTick_SetPRI() \
	*(volatile s_u8_t *)(0xE000E400 + MCUCFG_TIMn_IRQn) = 0xFF

/* PendSV */
#define mPendSV_SetPRI() \
	*(volatile s_u8_t *)(0xE000E400 + MCUCFG_XXXx_IRQn) = 0xFF

#define mPendSV_Set() \
	*(volatile s_u32_t *)(0xE000E200 + MCUCFG_XXXx_IRQn / 32 * 4) = 0x01UL << (MCUCFG_XXXx_IRQn % 32)

#define mPendSV_Clear() \
	*(volatile s_u32_t *)(0xE000E280 + MCUCFG_XXXx_IRQn / 32 * 4) = 0x01UL << (MCUCFG_XXXx_IRQn % 32)

#define mPendSV_INIT()   mPendSV_SetPRI()

/* 内核锁 */
#define mSysINT_Disable() \
	*(volatile s_u32_t *)(0xE000E180 + MCUCFG_XXXx_IRQn / 32 * 4) = (0x01UL << (MCUCFG_XXXx_IRQn % 32)) \
                                                                  | (0x01UL << (MCUCFG_TIMn_IRQn % 32))
#define mSysINT_Enable() \
	*(volatile s_u32_t *)(0xE000E100 + MCUCFG_XXXx_IRQn / 32 * 4) = (0x01UL << (MCUCFG_XXXx_IRQn % 32)) \
                                                                  | (0x01UL << (MCUCFG_TIMn_IRQn % 32))
__STATIC_FORCEINLINE void __mu_disable_sysirq(void)
{
	mSysINT_Disable();
	__ASM("fence.i");
}

__STATIC_FORCEINLINE void __mu_enable_sysirq(void)
{
	__ASM("fence rw, rw");
	mSysINT_Enable();
}


/* CosyOS初始化 */
#define mCosyOS_INIT() \
do{ \
	mPendSV_INIT(); \
	mSysTick_INIT(); \
}while(false)


/* CosyOS低功耗 */
#define mCosyOS_IDLE()  __WFI()


/* 任务栈 */
#define MCUCFG_TASKSTACK_MODE __PSP__

#define mTaskStack_Init() \
do{ \
	node_news->psp_top = (m_sp_t)node_news->bsp + node_news->stacksize; \
	if(node_news->psp_top % 16){ \
		node_news->psp_top /= 16; \
		node_news->psp_top *= 16; \
		node_news->stacksize = node_news->psp_top - (m_sp_t)node_news->bsp; \
	} \
	mTaskStack_CheckInit(); \
	mTaskStack_Reset(); \
}while(false)

#define mTaskStack_Reset() \
do{ \
	node_news->psp = node_news->psp_top; \
	node_news->psp -= MCUCFG_BASICSTACKSIZE; \
	*(volatile s_u32_t *)(node_news->psp + MCUCFG_PUSH_FPU) = (s_u32_t)node_news->entry; /* x0(mepc) */ \
}while(false)

/* 栈监控 */
#if (SYSCFG_DEBUGGING == __ENABLED__)
#define mTaskStack_Check0()    s_task_current->psp_top - __get_SP() + MCUCFG_PUSH_FPU
#define mTaskStack_Check()     s_stack_check((s_u8_t *)(s_task_current->psp_top), s_task_current->stacksize)
#define mTaskStack_CheckInit() s_stack_check_init((s_u8_t *)(node_news->psp_top), node_news->stacksize)

#else
#define mTaskStack_CheckInit()
#endif


/* 内存访问屏障 */
#define __mx_MMB()  __ASM("fence rw, rw")


#endif
