CLINT vs mtime in FreeRTOS RISC-V port

kj-lin wrote on Tuesday, August 27, 2019:

Hi,

We are porting an RISC-V platfrom for Amazon FreeRTOS Qualification Program but get the mtime porting issue.

In FreeRTOS RISC-V port, the default implementation about mtime in “port.c” and “portASM.S” files can only be used if there is a CLINT by specifying “configCLINT_BASE_ADDRESS” and “portasmHAS_CLINT”.
It includes setup mtime to generate the tick interrupts, enable mtime interrupt in xPortStartScheduler() and handle mtime interrupt.
However, the default implementation is based on Sifive’s CLINT memory-mapped control registers specification, which makes the porting not generic enough.

How can we port a RISC-V core without modifying generic “port.c” and “portASM.S” files,
if the core uses the “mie.mtie” and generates mcause=0x8000[]0007 mtime interrupt but has a different CLINT memory-mapped control registers layout from SiFive?

rtel wrote on Tuesday, August 27, 2019:

The RISC-V port is quite new so this is good information as I didn’t
realise the CLINT was not a standard interface. At this time your only
option would be to configure the port as if it didn’t have a CLINT then
follow the instructions for when configCLINT_BASE_ADDRESS is 0. We can
then work together to see what would be necessary to support your port
too. If it is just a matter of having registers at different offsets,
or even bits in registers in different places, it may be possible to use
the port specific extensions header files in some way - on the other
hand if the CLINT is completely different in functionality we would have
to re-think (also re-thing what CLINT actually means).

If you are happy to provide more information here, such as links to data
sheets, etc. then please post links to the information we will need. If
you prefer at this time to keep this development offline then you can
contact me directly using r dot barry at freertos dot org.

kj-lin wrote on Wednesday, August 28, 2019:

Hi Richard,

Thanks for the reply.

I got the “CLINT” is a name used at Sifive to cover local interrupts that do not pass through the PLIC,
including software interrupts, timer interrupts and any additional local interrupts made visible in the mip/mie CSRs bits 16 and above.
But it is NOT a standard keyowrd/interface in RISC-V specifiecation.

Our core doesn’t have the “CLINT” based registers design, but it provides 64-bit memory-mapped registers for mtime and mtimecmp.
And the mtime interrupt will only be taken if interrupt is enabled and the MTIE bit is set in the mie register.

Our machine timer control registers map are :

Offset address:
0x00 : mtime
0x08 : mtimecmp (hart 0)
0x10 : mtimecmp (hart 1)
… : …
0x08+8*N : mtimecmp (hart N)

Actually, the “mtime” and “mtimecmp” are standard registers defined in RISC-V Privileged specification and request to be exposed as 64-bit memory-mapped registers.
Perphas we should consider to replace “configCLINT_BASE_ADDRESS” with “configMTIME_ADDRESS” and “configMTIMECMP_ADDRESS” definition in FreeRTOSConfig.h.
It seems that we can have the porting more generic if the two definitions are used for timer setup and tick interrupt handler implemation in FreeRTOS RISC-V port.

Currently, the option for me is to set configCLINT_BASE_ADDRESS and portasmHAS_CLINT to both 0 to bypass the default implemation about mtime, including mtime interrupt pending.
However, it is a pity that i can NOT leverage the code of vPortSetupTimerInterrupt() and ‘test_if_mtimer’ in freertos_risc_v_trap_handler.

rtel wrote on Wednesday, August 28, 2019:

Your suggestion seems to be a reasonable approach. The ‘live copy’ (not
yet checked in) of the RISC-V port has some minor updates to support
multiple HARTs (the current code assumes only one HART). That may also
suffer from the same assumptions so once that has been checked in I will
look at removing the dependency between the mtimer and CLINT. It would
be great at that time if you could validate any updates made work for
you. In the mean time it would be helpful if you could create an
example of an update that would work for you that we could then use as a
reference/merge.

kj-lin wrote on Thursday, August 29, 2019:

To make the smallest modifications, I just simply replace configCLINT_BASE_ADDRESS wth configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS defined in FreeRTOSConfig.h file, and also replace portasmHAS_CLINT with portasmHAS_MTIME defined in freertos_risc_v_chip_specific_extensions.h file.
The default timer/tick handling in port.c and portASM.S files are implemented based on the definitions.

The examples are as attached.