Understanding new RISC-V port layer

Hello everyone.

I’ve started working on FreeRTOS and RISC-V icicle kit from Microchip. My main goal is to develop a port layer to enable SMP branch but I keep falling short of getting the grasp of the definitions.

The source tagged as FreeRTOS 202112.00 works on the HW kit but after upgrading to the latest revision on GitHub (with riscv port upgrades) the cores get trapped with MCAUSE 0xb in trap_from_machine_mode function supplied by Microsemi.

Renode doesn’t work for either of the versions. FreeRTOS 202112.00 version starts the scheduler, but tasks are never executed more than once. GitHub version gets trapped the same way HW kit does.

I need help in understanding the expected implementations from port layer. There are more than a handful of ports available and they all do things differently (which none of them seems to fully work on my case)

With the head revision it is necessary to set the mtvec register to say if you want to use vectored or direct interrupts before starting the scheduler. For example:

/* Set to 1 to use direct mode and set to 0 to use vectored mode.
VECTOR MODE=Direct --> all traps into machine mode cause the pc to be set to the
vector base address (BASE) in the mtvec register.
VECTOR MODE=Vectored --> all synchronous exceptions into machine mode cause the
pc to be set to the BASE, whereas interrupts cause the pc to be set to the
address BASE plus four times the interrupt cause number.
#define mainVECTOR_MODE_DIRECT	0
#if( mainVECTOR_MODE_DIRECT == 1 )
    __asm__ volatile( "csrw mtvec, %0" :: "r"( freertos_risc_v_trap_handler ) );
    __asm__ volatile( "csrw mtvec, %0" :: "r"( ( uintptr_t )freertos_vector_table | 0x1 ) );

Did it work for you @mcergun ?

@aggarg @rtel

Sorry that my reply took so long. I’ve managed to get it working on HW but Renode still seems to be acting weird with the same mcause codes.

Even though renode is not a must for me, it would have been a nice to have for quick tests.

I’m now working on the smp branch to get it up but I can’t get my head around how to initialize stack pointers for multiple harts. All port code depends on pxCurrentTCB to move the pointer, which is made into a macro in the SMP branch now.

Also, I see that portDISABLE_INTERRUPTS now return a mask value. Is this necessary for RISCV arch? As far as I understand, MIE register is like a mask for all interrupts and mstatus.MIE bit is the master switch for controlling interrupts. Is it simply enough to set/reset mstatus.MIE bit for portDISABLE_INTERRUPTS and return a dummy value? If so, then portRESTORE and portENABLE will do exactly the same thing.

We have not added the SMP support to the RISC-V port yet. This document provides details about the SMP specific port changes - FreeRTOS-Kernel/FreeRTOS SMP change description.pdf at smp · FreeRTOS/FreeRTOS-Kernel · GitHub

You can also look at these SMP ports for reference:

Where did you get the Renode project from?

I know SMP port is not yet ready for RISCV. I’m trying to see if I can port it myself with limited assembly experience.

Is there any active work on the port btw?

For renode,
I have tried different versions on 3 different machines:

  • Offline Win10 machine
  • Online Win10 machine
  • Online Ubuntu 22.04 machine

1.12, 1.13 and the version bundled with SoftConsole installations all fail when a script is loaded. Renode just throws exception and closes. I’ve already opened up an issue about this on their github page.

On ubuntu machine, 1.13 version can load up script files. This is the one I’m using.

I meant to ask, are you using the Renode project from our repository - FreeRTOS/FreeRTOS/Demo/RISC-V_Renode_Emulator_SoftConsole at main · FreeRTOS/FreeRTOS · GitHub

No, I am using “/FreeRTOS/FreeRTOS/tree/main/FreeRTOS/Demo/RISC-V_RV64_PolarFire_SoftConsole” (can’t post links)

I use icicle kit startup scripts for renode.