Hi,
I’m currently using the RISC-V port of FreeRTOS and I’ve run into an issue in the xPortStartFirstTask function of portASM.S.
Interrupts are supposed to be enabled by restoring the mstatus value saved in the task’s stack with:
load_x t0, 29 * portWORD_SIZE( sp ) /* mstatus */
csrrw x0, mstatus, t0 /* Interrupts enabled from here! */
However during the task initialization, the saved value is simply mstatus | 0x1880. But at the time, interrupts are disabled, so the value is always 0x1880 and not 0x1888 which would mean interrupts are enabled. So when it’s restored in xPortStartFirstTask, it means mstatus is just set to 0x1880. Since the function ends with a simple ret instruction, and not mret, mstatus remains at 0x1880 and interrupts remain disabled until the next time portENABLE_INTERRUPTS hopefully gets called.
I think the function should instead set mepc to the correct return value with:
csrw mepc, x1
and end with
mret
just like the function processed_source. This way, the MIE bit of mstatus gets set with the mret instruction.
It could even jump to processed_source like so:
#if( portasmHAS_CLINT != 0 )
/* If there is a clint then interrupts can branch directly to the FreeRTOS
trap handler. Otherwise the interrupt controller will need to be configured
outside of this file. */
la t0, freertos_risc_v_trap_handler
csrw mtvec, t0
#endif /* portasmHAS_CLILNT */
j processed_source
What do you think?