Skip to content

Commit

Permalink
OS/RTThread: initial changes to support RT-Thread running in S-Mode
Browse files Browse the repository at this point in the history
Take care when running in S-Mode, macro SMODE_RTOS must be defined

Signed-off-by: Huaqi Fang <[email protected]>
  • Loading branch information
fanghuaqi committed Dec 16, 2024
1 parent 06d28ce commit 53f30f3
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 54 deletions.
57 changes: 57 additions & 0 deletions NMSIS/Core/Include/riscv_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -1096,6 +1096,63 @@
#define DCAUSE_FAULT_STORE_PMP 0x1
#define DCAUSE_FAULT_STORE_INST 0x2

#ifdef SMODE_RTOS
#define CSR_XSTATUS CSR_SSTATUS
#define CSR_XTVEC CSR_STVEC
#define CSR_XCOUNTEREN CSR_SCOUNTEREN
#define CSR_XIE CSR_SIE
#define CSR_XIP CSR_SIP
#define CSR_XSCRATCH CSR_SSCRATCH
#define CSR_XEPC CSR_SEPC
#define CSR_XCAUSE CSR_SCAUSE
#define CSR_XTVAL CSR_STVAL
#define CSR_XENVCFG CSR_SENVCFG
#define CSR_XTVT CSR_STVT
#define CSR_XTVT2 CSR_STVT2
#define CSR_XSCRATCHCSWL CSR_SSCRATCHCSWL
#define CSR_XSCRATCHCSW CSR_SSCRATCHCSW
#define CSR_XDCAUSE CSR_SDCAUSE
#define CSR_JALXNXTI CSR_JALSNXTI
#define CSR_XINTSTATUS CSR_SINTSTATUS
#define CSR_XNXTI CSR_SNXTI
#define CSR_PUSHXEPC CSR_PUSHSEPC
#define CSR_PUSHXCAUSE CSR_PUSHSCAUSE
#define XRET sret
#define eclic_xsip_handler eclic_ssip_handler
#define eclic_xtip_handler eclic_stip_handler
#define XSTATUS_XIE SSTATUS_SIE
#define x_exc_entry exc_entry_s
#define x_irq_entry irq_entry_s
#else
#define CSR_XSTATUS CSR_MSTATUS
#define CSR_XTVEC CSR_MTVEC
#define CSR_XCOUNTEREN CSR_MCOUNTEREN
#define CSR_XIE CSR_MIE
#define CSR_XIP CSR_MIP
#define CSR_XSCRATCH CSR_MSCRATCH
#define CSR_XEPC CSR_MEPC
#define CSR_XCAUSE CSR_MCAUSE
#define CSR_XSUBM CSR_MSUBM
#define CSR_XTVAL CSR_MTVAL
#define CSR_XENVCFG CSR_MENVCFG
#define CSR_XTVT CSR_MTVT
#define CSR_XTVT2 CSR_MTVT2
#define CSR_XSCRATCHCSWL CSR_MSCRATCHCSWL
#define CSR_XSCRATCHCSW CSR_MSCRATCHCSW
#define CSR_XDCAUSE CSR_MDCAUSE
#define CSR_JALXNXTI CSR_JALMNXTI
#define CSR_XINTSTATUS CSR_MINTSTATUS
#define CSR_XNXTI CSR_MNXTI
#define CSR_PUSHXEPC CSR_PUSHMEPC
#define CSR_PUSHXCAUSE CSR_PUSHMCAUSE
#define XRET mret
#define eclic_xsip_handler eclic_msip_handler
#define eclic_xtip_handler eclic_mtip_handler
#define XSTATUS_XIE MSTATUS_MIE
#define x_exc_entry exc_entry
#define x_irq_entry irq_entry
#endif

/** @} */ /** End of Doxygen Group NMSIS_Core_CSR_Encoding **/

#ifdef __cplusplus
Expand Down
59 changes: 50 additions & 9 deletions OS/RTThread/libcpu/risc-v/nuclei/cpuport.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@

#include "cpuport.h"

#ifndef BOOT_HARTID
#define EXECUTE_HARTID 0
#else
#define EXECUTE_HARTID BOOT_HARTID
#endif


#define SYSTICK_TICK_CONST (SOC_TIMER_FREQ / RT_TICK_PER_SECOND)

#ifndef configKERNEL_INTERRUPT_PRIORITY
Expand All @@ -26,7 +33,13 @@
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 255
#endif

#define portINITIAL_MSTATUS ( MSTATUS_MPP | MSTATUS_MPIE | MSTATUS_FS_INITIAL | MSTATUS_VS_INITIAL)
#ifdef SMODE_RTOS
#define SysTick_Handler eclic_stip_handler
#define portINITIAL_XSTATUS ( SSTATUS_SPP | SSTATUS_SPIE | MSTATUS_FS_INITIAL | MSTATUS_VS_INITIAL)
#else
#define SysTick_Handler eclic_mtip_handler
#define portINITIAL_XSTATUS ( MSTATUS_MPP | MSTATUS_MPIE | MSTATUS_FS_INITIAL | MSTATUS_VS_INITIAL)
#endif

volatile rt_ubase_t rt_interrupt_from_thread = 0;
volatile rt_ubase_t rt_interrupt_to_thread = 0;
Expand Down Expand Up @@ -64,7 +77,7 @@ struct rt_hw_stack_frame {
rt_ubase_t t5; /* x30 - t5 - temporary register 5 */
rt_ubase_t t6; /* x31 - t6 - temporary register 6 */
#endif
rt_ubase_t mstatus; /* - machine status register */
rt_ubase_t xstatus; /* - m/s status register */
};

/**
Expand Down Expand Up @@ -100,7 +113,7 @@ rt_uint8_t* rt_hw_stack_init(void* tentry,
frame->a0 = (rt_ubase_t)parameter;
frame->epc = (rt_ubase_t)tentry;

frame->mstatus = portINITIAL_MSTATUS;
frame->xstatus = portINITIAL_XSTATUS;

return stk;
}
Expand All @@ -116,7 +129,15 @@ void rt_hw_context_switch_interrupt(rt_ubase_t from, rt_ubase_t to)

rt_interrupt_to_thread = to;
rt_thread_switch_interrupt_flag = 1;
portYIELD();
/* Set a software interrupt(SWI) request to request a context switch. */
#ifdef SMODE_RTOS
SysTimer_SetHartSWIRQ(EXECUTE_HARTID);
#else
SysTimer_SetSWIRQ();
#endif
/* Barriers are normally not required but do ensure the code is completely
within the specified behaviour for the architecture. */
__RWMB();
}

void rt_hw_context_switch(rt_ubase_t from, rt_ubase_t to)
Expand All @@ -139,7 +160,11 @@ void rt_hw_cpu_shutdown()
void xPortTaskSwitch(void)
{
/* Clear Software IRQ, A MUST */
#ifdef SMODE_RTOS
SysTimer_ClearHartSWIRQ(EXECUTE_HARTID);
#else
SysTimer_ClearSWIRQ();
#endif
rt_thread_switch_interrupt_flag = 0;
// make from thread to be to thread
// If there is another swi interrupt triggered by other harts
Expand All @@ -152,6 +177,18 @@ void vPortSetupTimerInterrupt(void)
{
uint64_t ticks = SYSTICK_TICK_CONST;

#ifdef SMODE_RTOS
SysTick_HartConfig(ticks, EXECUTE_HARTID);
ECLIC_DisableIRQ_S(SysTimer_IRQn);
ECLIC_SetLevelIRQ_S(SysTimer_IRQn, configKERNEL_INTERRUPT_PRIORITY);
ECLIC_SetShvIRQ_S(SysTimer_IRQn, ECLIC_NON_VECTOR_INTERRUPT);
ECLIC_EnableIRQ_S(SysTimer_IRQn);

/* Set SWI interrupt level to lowest level/priority, SysTimerSW as Vector Interrupt */
ECLIC_SetShvIRQ_S(SysTimerSW_IRQn, ECLIC_VECTOR_INTERRUPT);
ECLIC_SetLevelIRQ_S(SysTimerSW_IRQn, configKERNEL_INTERRUPT_PRIORITY);
ECLIC_EnableIRQ_S(SysTimerSW_IRQn);
#else
/* Make SWI and SysTick the lowest priority interrupts. */
/* Stop and clear the SysTimer. SysTimer as Non-Vector Interrupt */
SysTick_Config(ticks);
Expand All @@ -164,6 +201,8 @@ void vPortSetupTimerInterrupt(void)
ECLIC_SetShvIRQ(SysTimerSW_IRQn, ECLIC_VECTOR_INTERRUPT);
ECLIC_SetLevelIRQ(SysTimerSW_IRQn, configKERNEL_INTERRUPT_PRIORITY);
ECLIC_EnableIRQ(SysTimerSW_IRQn);

#endif
}


Expand Down Expand Up @@ -201,16 +240,18 @@ void rt_hw_board_init()
rt_system_heap_init(rt_heap_begin_get(), rt_heap_end_get());
#endif

__disable_irq();
rt_hw_interrupt_disable();
}

#define SysTick_Handler eclic_mtip_handler

/* This is the timer interrupt service routine. */
void SysTick_Handler(void)
{
// Reload timer
#ifdef SMODE_RTOS
SysTick_HartReload(SYSTICK_TICK_CONST, EXECUTE_HARTID);
#else
SysTick_Reload(SYSTICK_TICK_CONST);
#endif

/* enter interrupt */
rt_interrupt_enter();
Expand Down Expand Up @@ -242,10 +283,10 @@ char rt_hw_console_getchar(void)

rt_base_t rt_hw_interrupt_disable(void)
{
return __RV_CSR_READ_CLEAR(CSR_MSTATUS, MSTATUS_MIE);
return __RV_CSR_READ_CLEAR(CSR_XSTATUS, XSTATUS_XIE);
}

void rt_hw_interrupt_enable(rt_base_t level)
{
__RV_CSR_WRITE(CSR_MSTATUS, level);
__RV_CSR_WRITE(CSR_XSTATUS, level);
}
10 changes: 0 additions & 10 deletions OS/RTThread/libcpu/risc-v/nuclei/cpuport.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,16 +19,6 @@
extern "C" {
#endif

/* Scheduler utilities. */
#define portYIELD() \
{ \
/* Set a software interrupt(SWI) request to request a context switch. */ \
SysTimer_SetSWIRQ(); \
/* Barriers are normally not required but do ensure the code is completely \
within the specified behaviour for the architecture. */ \
__RWMB(); \
}


#ifdef __cplusplus
}
Expand Down
28 changes: 14 additions & 14 deletions OS/RTThread/libcpu/risc-v/nuclei/gcc/context_gcc.S
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ rt_hw_context_switch_to:
The stack that was used by main()
before the scheduler is started is
no longer required after the scheduler is started.
Interrupt stack pointer is stored in CSR_MSCRATCH */
Interrupt stack pointer is stored in CSR_XSCRATCH */
la t0, _sp
csrw CSR_MSCRATCH, t0
csrw CSR_XSCRATCH, t0
LOAD sp, 0x0(a0) /* Read sp from first TCB member(a0) */

/* Pop PC from stack and set MEPC */
LOAD t0, 0 * REGBYTES(sp)
csrw CSR_MEPC, t0
csrw CSR_XEPC, t0
/* Pop mstatus from stack and set it */
LOAD t0, (portRegNum - 1) * REGBYTES(sp)
csrw CSR_MSTATUS, t0
csrw CSR_XSTATUS, t0
/* Interrupt still disable here */
/* Restore Registers from Stack */
LOAD x1, 1 * REGBYTES(sp) /* RA */
Expand Down Expand Up @@ -89,14 +89,14 @@ rt_hw_context_switch_to:

addi sp, sp, portCONTEXT_SIZE

mret
XRET

.size rt_hw_context_switch_to, . - rt_hw_context_switch_to

.align 2
.global eclic_msip_handler
.type eclic_msip_handler, @function
eclic_msip_handler:
.global eclic_xsip_handler
.type eclic_xsip_handler, @function
eclic_xsip_handler:
addi sp, sp, -portCONTEXT_SIZE
STORE x1, 1 * REGBYTES(sp) /* RA */
STORE x5, 2 * REGBYTES(sp)
Expand Down Expand Up @@ -129,7 +129,7 @@ eclic_msip_handler:
STORE x31, 28 * REGBYTES(sp)
#endif
/* Push mstatus to stack */
csrr t0, CSR_MSTATUS
csrr t0, CSR_XSTATUS
STORE t0, (portRegNum - 1) * REGBYTES(sp)

/* Push additional registers */
Expand All @@ -138,7 +138,7 @@ eclic_msip_handler:
LOAD t0, rt_interrupt_from_thread
STORE sp, 0(t0)

csrr t0, CSR_MEPC
csrr t0, CSR_XEPC
STORE t0, 0(sp)

jal xPortTaskSwitch
Expand All @@ -149,12 +149,12 @@ eclic_msip_handler:

/* Pop PC from stack and set MEPC */
LOAD t0, 0 * REGBYTES(sp)
csrw CSR_MEPC, t0
csrw CSR_XEPC, t0
/* Pop additional registers */

/* Pop mstatus from stack and set it */
LOAD t0, (portRegNum - 1) * REGBYTES(sp)
csrw CSR_MSTATUS, t0
csrw CSR_XSTATUS, t0
/* Interrupt still disable here */
/* Restore Registers from Stack */
LOAD x1, 1 * REGBYTES(sp) /* RA */
Expand Down Expand Up @@ -189,6 +189,6 @@ eclic_msip_handler:
#endif

addi sp, sp, portCONTEXT_SIZE
mret
XRET

.size eclic_msip_handler, . - eclic_msip_handler
.size eclic_xsip_handler, . - eclic_xsip_handler
Loading

0 comments on commit 53f30f3

Please sign in to comment.