From 53f30f3d55cc110094373f03002ba432488438b2 Mon Sep 17 00:00:00 2001 From: Huaqi Fang <578567190@qq.com> Date: Mon, 16 Dec 2024 16:55:48 +0800 Subject: [PATCH] OS/RTThread: initial changes to support RT-Thread running in S-Mode Take care when running in S-Mode, macro SMODE_RTOS must be defined Signed-off-by: Huaqi Fang <578567190@qq.com> --- NMSIS/Core/Include/riscv_encoding.h | 57 ++++++++++++++++++ OS/RTThread/libcpu/risc-v/nuclei/cpuport.c | 59 ++++++++++++++++--- OS/RTThread/libcpu/risc-v/nuclei/cpuport.h | 10 ---- .../libcpu/risc-v/nuclei/gcc/context_gcc.S | 28 ++++----- .../libcpu/risc-v/nuclei/gcc/interrupt_gcc.S | 46 ++++++++------- .../Common/Source/GCC/startup_evalsoc.S | 8 +++ 6 files changed, 154 insertions(+), 54 deletions(-) diff --git a/NMSIS/Core/Include/riscv_encoding.h b/NMSIS/Core/Include/riscv_encoding.h index a2ab7c00..b7129b2b 100644 --- a/NMSIS/Core/Include/riscv_encoding.h +++ b/NMSIS/Core/Include/riscv_encoding.h @@ -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 diff --git a/OS/RTThread/libcpu/risc-v/nuclei/cpuport.c b/OS/RTThread/libcpu/risc-v/nuclei/cpuport.c index c4a0ec39..0bf8464c 100644 --- a/OS/RTThread/libcpu/risc-v/nuclei/cpuport.c +++ b/OS/RTThread/libcpu/risc-v/nuclei/cpuport.c @@ -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 @@ -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; @@ -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 */ }; /** @@ -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; } @@ -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) @@ -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 @@ -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); @@ -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 } @@ -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(); @@ -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); } diff --git a/OS/RTThread/libcpu/risc-v/nuclei/cpuport.h b/OS/RTThread/libcpu/risc-v/nuclei/cpuport.h index a1ac152c..ce2f1ccd 100644 --- a/OS/RTThread/libcpu/risc-v/nuclei/cpuport.h +++ b/OS/RTThread/libcpu/risc-v/nuclei/cpuport.h @@ -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 } diff --git a/OS/RTThread/libcpu/risc-v/nuclei/gcc/context_gcc.S b/OS/RTThread/libcpu/risc-v/nuclei/gcc/context_gcc.S index d41ca9f8..f1b83b08 100644 --- a/OS/RTThread/libcpu/risc-v/nuclei/gcc/context_gcc.S +++ b/OS/RTThread/libcpu/risc-v/nuclei/gcc/context_gcc.S @@ -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 */ @@ -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) @@ -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 */ @@ -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 @@ -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 */ @@ -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 diff --git a/OS/RTThread/libcpu/risc-v/nuclei/gcc/interrupt_gcc.S b/OS/RTThread/libcpu/risc-v/nuclei/gcc/interrupt_gcc.S index 08cd10b4..3a9a28e4 100644 --- a/OS/RTThread/libcpu/risc-v/nuclei/gcc/interrupt_gcc.S +++ b/OS/RTThread/libcpu/risc-v/nuclei/gcc/interrupt_gcc.S @@ -20,8 +20,8 @@ * \remarks * - All the interrupt requests will be ignored by CPU. */ -.macro DISABLE_MIE - csrc CSR_MSTATUS, MSTATUS_MIE +.macro DISABLE_XIE + csrc CSR_XSTATUS, XSTATUS_XIE .endm /** @@ -34,7 +34,7 @@ */ /* Save caller registers */ .macro SAVE_CONTEXT - csrrw sp, CSR_MSCRATCHCSWL, sp + csrrw sp, CSR_XSCRATCHCSWL, sp /* Allocate stack space for context saving */ #ifndef __riscv_32e addi sp, sp, -20*REGBYTES @@ -98,7 +98,7 @@ /* De-allocate the stack space */ addi sp, sp, 14*REGBYTES #endif /* __riscv_32e */ - csrrw sp, CSR_MSCRATCHCSWL, sp + csrrw sp, CSR_XSCRATCHCSWL, sp .endm /** @@ -108,11 +108,13 @@ */ .macro SAVE_CSR_CONTEXT /* Store CSR mcause to stack using pushmcause */ - csrrwi x0, CSR_PUSHMCAUSE, 11 + csrrwi x0, CSR_PUSHXCAUSE, 11 /* Store CSR mepc to stack using pushmepc */ - csrrwi x0, CSR_PUSHMEPC, 12 + csrrwi x0, CSR_PUSHXEPC, 12 +#ifndef SMODE_RTOS /* Store CSR msub to stack using pushmsub */ csrrwi x0, CSR_PUSHMSUBM, 13 +#endif .endm /** @@ -121,12 +123,14 @@ * This macro restore MSUBM, MEPC, MCAUSE from stack. */ .macro RESTORE_CSR_CONTEXT +#ifndef SMODE_RTOS LOAD x5, 13*REGBYTES(sp) - csrw CSR_MSUBM, x5 + csrw CSR_XSUBM, x5 +#endif LOAD x5, 12*REGBYTES(sp) - csrw CSR_MEPC, x5 + csrw CSR_XEPC, x5 LOAD x5, 11*REGBYTES(sp) - csrw CSR_MCAUSE, x5 + csrw CSR_XCAUSE, x5 .endm /** @@ -141,9 +145,9 @@ .section .text.trap /* In CLIC mode, the exeception entry must be 64bytes aligned */ .align 6 -.global exc_entry -.type exc_entry, @function -exc_entry: +.global x_exc_entry +.type x_exc_entry, @function +x_exc_entry: /* Save the caller saving registers (context) */ SAVE_CONTEXT /* Save the necessary CSR registers */ @@ -169,9 +173,9 @@ exc_entry: RESTORE_CONTEXT /* Return to regular code */ - mret + XRET - .size exc_entry, . - exc_entry + .size x_exc_entry, . - x_exc_entry /** * \brief Non-Vector Interrupt Entry @@ -186,10 +190,10 @@ exc_entry: .section .text.irq /* In CLIC mode, the interrupt entry must be 4bytes aligned */ .align 2 -.global irq_entry -.type irq_entry, @function +.global x_irq_entry +.type x_irq_entry, @function /* This label will be set to MTVT2 register */ -irq_entry: +x_irq_entry: /* Save the caller saving registers (context) */ SAVE_CONTEXT /* Save the necessary CSR registers */ @@ -200,10 +204,10 @@ irq_entry: * is not 0, then automatically enable the mstatus.MIE, and * jump to its vector-entry-label, and update the link register */ - csrrw ra, CSR_JALMNXTI, ra + csrrw ra, CSR_JALXNXTI, ra /* Critical section with interrupts disabled */ - DISABLE_MIE + DISABLE_XIE /* Restore the necessary CSR registers */ RESTORE_CSR_CONTEXT @@ -211,9 +215,9 @@ irq_entry: RESTORE_CONTEXT /* Return to regular code */ - mret + XRET - .size irq_entry, . - irq_entry + .size x_irq_entry, . - x_irq_entry /* Default Handler for Exceptions / Interrupts */ .global default_intexc_handler diff --git a/SoC/evalsoc/Common/Source/GCC/startup_evalsoc.S b/SoC/evalsoc/Common/Source/GCC/startup_evalsoc.S index ef7672f0..c2417e7f 100644 --- a/SoC/evalsoc/Common/Source/GCC/startup_evalsoc.S +++ b/SoC/evalsoc/Common/Source/GCC/startup_evalsoc.S @@ -381,7 +381,11 @@ __skip_init: #else #ifdef RTOS_RTTHREAD // Call entry function when using RT-Thread +#ifdef SMODE_RTOS + call main_entry +#else call entry +#endif #else call main #endif @@ -420,7 +424,11 @@ smp_main: 2: #ifdef RTOS_RTTHREAD // Call entry function when using RT-Thread +#ifdef SMODE_RTOS + call main_entry +#else call entry +#endif #else call main #endif