Software interrupt for RISC-V

Hi, We are currently using FreeRTOS for our RISC-V development. One particular case I came across is that FreeRTOS trap_handlder doens’t handle at Software interrupts. So as far as I can understand, it checks if the source of the trap is async (i.e external IRQ or timer IRQ) or sync (probably due to illegal access). However In our code we rely on issuing a software interrupt to the core to do some stuff. So what happens is that FreeRTOS check its an async interrupt but yet not an external interrupt and goes and raise an assert (i.e ebreak instruction!!). Is that actually the intended behavior? Am i missing something in here? Is there a workaround for this? Regards, Bassem

Software interrupt for RISC-V

Does your core have a CLINT? How are you generating the software interrupt (which instruction or instructions) – is it sync or async? Please reference line numbers here https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S to describe the path taken through the code when you raise the software interrupt.

Software interrupt for RISC-V

Yes we have a CLINT. We are generating SWI by writing 0x01 to the MSIP register of the CLINT (for whatever core we want to trigger). Based on the link you posted, sequence as follows: * We start at L105 (https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S#l105), with MSIP of CLINT (and mcause) have a value of 0x80000003 * In L144 (https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S#l144), mcuase is loaded in a0 (i.e a0 = 0x80000003) * We go all the way to L161 (https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S#l161) as its asynchornous interrupt so we want to check for timer. we load 0x80000007 in t1 * in L162 in-equality test sucseed (a0 = 0x80000003 and t1 = 0x80000007), we got to L200 * in L201 (https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S#l201) t1 is loaded with 0x8000000b to test for external interrupt * in L202 (https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S#l202) in-equality test sucseed (a0 = 0x80000003 and t1 = 0x8000000b). * Trap code L225 (https://sourceforge.net/p/freertos/code/HEAD/tree/trunk/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S#l225) Regards, Bassem

Software interrupt for RISC-V

Thanks that is very helpful. So if I understand correctly, as well as checking for 0x80000007 to see if the exception was generated by a machine timer, we also need to check for 0x80000003 to see if the exception was generated by a machine (at this time, as only machine mode is supported, although that will change) software interrupt – is that correct? If so, how should the software interrupt be handled? It could be a separate callback into the application code which would be clean but require the application writer to provide more. Or it could use the same callback as the external interrupts as the cause register can be read in the handler to determine if it was a software interrupt – that would be much more clunky for the application writer and make the asm code a bit more complex. Either way I think this is a small change. Thoughts? My preference would be the first method – have the user provide an ‘software interrupt’ handler.

Software interrupt for RISC-V

Thanks for the reply.
  • Yes, your understanding is correct. we need to account for SWI (mcause = 0x80000003)
  • In my local branch I did a small patch that implemented option two. My main reasons were: 1- Have a single entry point (and exit) for my interrupts (and use mcause to figure out the reason). 2- Avoid adding an extra user configuration for our application developers 3- That same function can used as a trap handler without the OS if required (that’s actually what we do intially until starting the FreeRTOS, which replaces mvec with its own).
  • One last question, Is it necessary ( or a policy) for FreeRTOS to check the exact source of interrupt and trap if unhandled? I would have expected that FreeRTOS would only capture the Timer TICK and pass every thing else up whatever the source of Interrupt is (i.e no need of the cause check in the first palce) (mainly talking about asynchronous interrupts).
Regards, Bassem

Software interrupt for RISC-V

Grateful if you can post your patched asm file. To answer your question – not policy – this is a new port and we want to see how people use the code and make sure we are providing what they want/need, so this is a good conversation. The port will get developed over time to add in more functionality.

Software interrupt for RISC-V

Sorry fo the late reply. See the attached file. I took a different approach to remove the check on the source of the interrupt altogether (after checking its not a timer interrupt).