Replace portasmHAS_CLINT with configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS definitions in the GCC RISC-V port - portasmHAS_CLIT will still work by deriving the new definitions from the old.

This commit is contained in:
Richard Barry 2020-01-07 01:14:36 +00:00
parent eaf9318df8
commit fbb23055cd
5 changed files with 49 additions and 17 deletions

View file

@ -59,7 +59,7 @@
#ifndef __FREERTOS_RISC_V_EXTENSIONS_H__ #ifndef __FREERTOS_RISC_V_EXTENSIONS_H__
#define __FREERTOS_RISC_V_EXTENSIONS_H__ #define __FREERTOS_RISC_V_EXTENSIONS_H__
#define portasmHAS_CLINT 0 #define portasmHAS_MTIME 0
/* Constants to define the additional registers found on the Pulpino RI5KY. */ /* Constants to define the additional registers found on the Pulpino RI5KY. */
#define lpstart0 0x7b0 #define lpstart0 0x7b0

View file

@ -53,7 +53,7 @@
#ifndef __FREERTOS_RISC_V_EXTENSIONS_H__ #ifndef __FREERTOS_RISC_V_EXTENSIONS_H__
#define __FREERTOS_RISC_V_EXTENSIONS_H__ #define __FREERTOS_RISC_V_EXTENSIONS_H__
#define portasmHAS_CLINT 1 #define portasmHAS_MTIME 1
#define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */ #define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */
.macro portasmSAVE_ADDITIONAL_REGISTERS .macro portasmSAVE_ADDITIONAL_REGISTERS

View file

@ -37,8 +37,16 @@
/* Standard includes. */ /* Standard includes. */
#include "string.h" #include "string.h"
#ifndef configCLINT_BASE_ADDRESS #ifdef configCLINT_BASE_ADDRESS
#warning configCLINT_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a Core Local Interrupter (CLINT) then set configCLINT_BASE_ADDRESS to the CLINT base address. Otherwise set configCLINT_BASE_ADDRESS to 0. #warning The configCLINT_BASE_ADDRESS constant has been deprecated. configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS are currently being derived from configCLINT_BASE_ADDRESS. Please update to define configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS dirctly in place of configCLINT_BASE_ADDRESS.
#endif
#ifndef configMTIME_BASE_ADDRESS
#warning configMTIME_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtime register then set configMTIME_BASE_ADDRESS to the mapped address. Otherwise set configMTIME_BASE_ADDRESS to 0.
#endif
#ifndef configMTIMECMP_BASE_ADDRESS
#warning configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. If the target chip includes a memory-mapped mtimecmp register then set configMTIMECMP_BASE_ADDRESS to the mapped address. Otherwise set configMTIMECMP_BASE_ADDRESS to 0.
#endif #endif
/* Let the user override the pre-loading of the initial LR with the address of /* Let the user override the pre-loading of the initial LR with the address of
@ -83,7 +91,7 @@ void vPortSetupTimerInterrupt( void ) __attribute__(( weak ));
uint64_t ullNextTime = 0ULL; uint64_t ullNextTime = 0ULL;
const uint64_t *pullNextTime = &ullNextTime; const uint64_t *pullNextTime = &ullNextTime;
const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */ const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */
uint32_t const ullMachineTimerCompareRegisterBase = ( uint64_t const ) ( ( configCLINT_BASE_ADDRESS ) + 0x4000 ); uint32_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS;
volatile uint64_t * pullMachineTimerCompareRegister = NULL; volatile uint64_t * pullMachineTimerCompareRegister = NULL;
/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task /* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task
@ -108,13 +116,13 @@ task stack, not the ISR stack). */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if( configCLINT_BASE_ADDRESS != 0 ) #if( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )
void vPortSetupTimerInterrupt( void ) void vPortSetupTimerInterrupt( void )
{ {
uint32_t ulCurrentTimeHigh, ulCurrentTimeLow; uint32_t ulCurrentTimeHigh, ulCurrentTimeLow;
volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( configCLINT_BASE_ADDRESS + 0xBFFC ); volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( ( configMTIME_BASE_ADDRESS ) + 4UL ); /* 8-byte typer so high 32-bit word is 4 bytes up. */
volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCLINT_BASE_ADDRESS + 0xBFF8 ); volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configMTIME_BASE_ADDRESS );
volatile uint32_t ulHartId; volatile uint32_t ulHartId;
__asm volatile( "csrr %0, mhartid" : "=r"( ulHartId ) ); __asm volatile( "csrr %0, mhartid" : "=r"( ulHartId ) );
@ -127,7 +135,7 @@ task stack, not the ISR stack). */
} while( ulCurrentTimeHigh != *pulTimeHigh ); } while( ulCurrentTimeHigh != *pulTimeHigh );
ullNextTime = ( uint64_t ) ulCurrentTimeHigh; ullNextTime = ( uint64_t ) ulCurrentTimeHigh;
ullNextTime <<= 32ULL; ullNextTime <<= 32ULL; /* High 4-byte word is 32-bits up. */
ullNextTime |= ( uint64_t ) ulCurrentTimeLow; ullNextTime |= ( uint64_t ) ulCurrentTimeLow;
ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick; ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick;
*pullMachineTimerCompareRegister = ullNextTime; *pullMachineTimerCompareRegister = ullNextTime;
@ -136,7 +144,7 @@ task stack, not the ISR stack). */
ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick; ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick;
} }
#endif /* ( configCLINT_BASE_ADDRESS != 0 ) */ #endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIME_BASE_ADDRESS != 0 ) */
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
BaseType_t xPortStartScheduler( void ) BaseType_t xPortStartScheduler( void )
@ -170,7 +178,7 @@ extern void xPortStartFirstTask( void );
configure whichever clock is to be used to generate the tick interrupt. */ configure whichever clock is to be used to generate the tick interrupt. */
vPortSetupTimerInterrupt(); vPortSetupTimerInterrupt();
#if( configCLINT_BASE_ADDRESS != 0 ) #if( ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) )
{ {
/* Enable mtime and external interrupts. 1<<7 for timer interrupt, 1<<11 /* Enable mtime and external interrupts. 1<<7 for timer interrupt, 1<<11
for external interrupt. _RB_ What happens here when mtime is not present as for external interrupt. _RB_ What happens here when mtime is not present as
@ -182,7 +190,7 @@ extern void xPortStartFirstTask( void );
/* Enable external interrupts. */ /* Enable external interrupts. */
__asm volatile( "csrs mie, %0" :: "r"(0x800) ); __asm volatile( "csrs mie, %0" :: "r"(0x800) );
} }
#endif /* configCLINT_BASE_ADDRESS */ #endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) */
xPortStartFirstTask(); xPortStartFirstTask();

View file

@ -71,8 +71,17 @@
/* Check the freertos_risc_v_chip_specific_extensions.h and/or command line /* Check the freertos_risc_v_chip_specific_extensions.h and/or command line
definitions. */ definitions. */
#ifndef portasmHAS_CLINT #if defined( portasmHAS_CLINT ) && defined( portasmHAS_MTIME )
#error freertos_risc_v_chip_specific_extensions.h must define portasmHAS_CLINT to either 1 (CLINT present) or 0 (clint not present). #error The portasmHAS_CLINT constant has been depracted. Please replace it with portasmHAS_CLINT. portasmHAS_CLINT and portasmHAS_MTIME cannot both be defined at once.
#endif
#ifdef portasmHAS_CLINT
#warning The portasmHAS_CLINT constant has been depracted. Please replace it with portasmHAS_CLINT. For now portasmHAS_MTIME is derived from portasmHAS_CLINT.
#define portasmHAS_MTIME portasmHAS_CLINT
#endif
#ifndef portasmHAS_MTIME
#error freertos_risc_v_chip_specific_extensions.h must define portasmHAS_MTIME to either 1 (MTIME clock present) or 0 (MTIME clock not present).
#endif #endif
#ifndef portasmHANDLE_INTERRUPT #ifndef portasmHANDLE_INTERRUPT
@ -153,7 +162,7 @@ test_if_asynchronous:
handle_asynchronous: handle_asynchronous:
#if( portasmHAS_CLINT != 0 ) #if( portasmHAS_MTIME != 0 )
test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */ test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */
@ -205,7 +214,7 @@ handle_asynchronous:
addi t1, t1, 4 /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */ addi t1, t1, 4 /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */
bne a0, t1, as_yet_unhandled /* Something as yet unhandled. */ bne a0, t1, as_yet_unhandled /* Something as yet unhandled. */
#endif /* portasmHAS_CLINT */ #endif /* portasmHAS_MTIME */
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */ load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
jal portasmHANDLE_INTERRUPT /* Jump to the interrupt handler if there is no CLINT or if there is a CLINT and it has been determined that an external interrupt is pending. */ jal portasmHANDLE_INTERRUPT /* Jump to the interrupt handler if there is no CLINT or if there is a CLINT and it has been determined that an external interrupt is pending. */
@ -284,7 +293,7 @@ processed_source:
.func .func
xPortStartFirstTask: xPortStartFirstTask:
#if( portasmHAS_CLINT != 0 ) #if( portasmHAS_MTIME != 0 )
/* If there is a clint then interrupts can branch directly to the FreeRTOS /* If there is a clint then interrupts can branch directly to the FreeRTOS
trap handler. Otherwise the interrupt controller will need to be configured trap handler. Otherwise the interrupt controller will need to be configured
outside of this file. */ outside of this file. */

View file

@ -153,6 +153,21 @@ not necessary for to use this port. They are defined so the common demo files
#endif #endif
#define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" ) #define portMEMORY_BARRIER() __asm volatile( "" ::: "memory" )
/*-----------------------------------------------------------*/
/* configCLINT_BASE_ADDRESS is a legacy definition that was replaced by the
configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS definitions. For
backward compatibility derive the newer definitions from the old if the old
definition is found. */
#if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS )
#define configMTIME_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0xBFF8UL )
#define configMTIMECMP_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0x4000UL )
#elif !defined( configMTIME_BASE_ADDRESS ) || !defined( configMTIMECMP_BASE_ADDRESS )
#error configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html
#endif
#ifdef __cplusplus #ifdef __cplusplus
} }