#include "string.h"\r
\r
#ifdef configCLINT_BASE_ADDRESS\r
- #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.\r
+ #warning The configCLINT_BASE_ADDRESS constant has been deprecated. configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS are currently being derived from the (possibly 0) configCLINT_BASE_ADDRESS setting. Please update to define configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS dirctly in place of configCLINT_BASE_ADDRESS.\r
#endif\r
\r
#ifndef configMTIME_BASE_ADDRESS\r
configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS definitions. For\r
backward compatibility derive the newer definitions from the old if the old\r
definition is found. */\r
-#if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS )\r
+#if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS ) && ( configCLINT_BASE_ADDRESS == 0 )\r
+ /* Legacy case where configCLINT_BASE_ADDRESS was defined as 0 to indicate\r
+ there was no CLINT. Equivalent now is to set the MTIME and MTIMECMP\r
+ addresses to 0. */\r
+ #define configMTIME_BASE_ADDRESS ( 0 )\r
+ #define configMTIMECMP_BASE_ADDRESS ( 0 )\r
+#elif defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS )\r
+ /* Legacy case where configCLINT_BASE_ADDRESS was set to the base address of\r
+ the CLINT. Equivalent now is to derive the MTIME and MTIMECMP addresses\r
+ from the CLINT address. */\r
#define configMTIME_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0xBFF8UL )\r
#define configMTIMECMP_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0x4000UL )\r
#elif !defined( configMTIME_BASE_ADDRESS ) || !defined( configMTIMECMP_BASE_ADDRESS )\r
- #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\r
+ #error configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. Set them to zero if there is no MTIME (machine time) clock. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html\r
#endif\r
\r
\r
#ifndef __FREERTOS_RISC_V_EXTENSIONS_H__\r
#define __FREERTOS_RISC_V_EXTENSIONS_H__\r
\r
-#define portasmHAS_CLINT 1\r
+#define portasmHAS_MTIME 1\r
#define portasmADDITIONAL_CONTEXT_SIZE 0 /* Must be even number on 32-bit cores. */\r
\r
portasmSAVE_ADDITIONAL_REGISTERS MACRO\r
/* Standard includes. */\r
#include "string.h"\r
\r
-#ifndef configCLINT_BASE_ADDRESS\r
- #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.\r
+#ifdef configCLINT_BASE_ADDRESS\r
+ #warning The configCLINT_BASE_ADDRESS constant has been deprecated. configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS are currently being derived from the (possibly 0) configCLINT_BASE_ADDRESS setting. Please update to define configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS dirctly in place of configCLINT_BASE_ADDRESS.\r
+#endif\r
+\r
+#ifndef configMTIME_BASE_ADDRESS\r
+ #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.\r
+#endif\r
+\r
+#ifndef configMTIMECMP_BASE_ADDRESS\r
+ #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.\r
#endif\r
\r
/* Let the user override the pre-loading of the initial LR with the address of\r
uint64_t ullNextTime = 0ULL;\r
const uint64_t *pullNextTime = &ullNextTime;\r
const size_t uxTimerIncrementsForOneTick = ( size_t ) ( ( configCPU_CLOCK_HZ ) / ( configTICK_RATE_HZ ) ); /* Assumes increment won't go over 32-bits. */\r
-volatile uint64_t * const pullMachineTimerCompareRegisterBase = ( uint64_t * ) ( ( configCLINT_BASE_ADDRESS ) + 0x4000 );\r
-volatile uint64_t * pullMachineTimerCompareRegister = 0;\r
+uint32_t const ullMachineTimerCompareRegisterBase = configMTIMECMP_BASE_ADDRESS;\r
+volatile uint64_t * pullMachineTimerCompareRegister = NULL;\r
+\r
/* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task\r
stack checking. A problem in the ISR stack will trigger an assert, not call the\r
stack overflow hook function (because the stack overflow hook is specific to a\r
\r
/*-----------------------------------------------------------*/\r
\r
-#if( configCLINT_BASE_ADDRESS != 0 )\r
+#if( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 )\r
\r
void vPortSetupTimerInterrupt( void )\r
{\r
uint32_t ulCurrentTimeHigh, ulCurrentTimeLow;\r
- volatile uint32_t * const pulTimeHigh = ( uint32_t * ) ( configCLINT_BASE_ADDRESS + 0xBFFC );\r
- volatile uint32_t * const pulTimeLow = ( uint32_t * ) ( configCLINT_BASE_ADDRESS + 0xBFF8 );\r
- volatile uint32_t ulHartId = 0;\r
+ volatile uint32_t * const pulTimeHigh = ( uint32_t * ) ( ( configMTIME_BASE_ADDRESS ) + 4UL ); /* 8-byte typer so high 32-bit word is 4 bytes up. */\r
+ volatile uint32_t * const pulTimeLow = ( uint32_t * ) ( configMTIME_BASE_ADDRESS );\r
+ volatile uint32_t ulHartId;\r
\r
__asm volatile( "csrr %0, 0xf14" : "=r"( ulHartId ) ); /* 0xf14 is hartid. */\r
- pullMachineTimerCompareRegister = &( pullMachineTimerCompareRegisterBase[ ulHartId ] );\r
+ pullMachineTimerCompareRegister = ( volatile uint64_t * ) ( ullMachineTimerCompareRegisterBase + ( ulHartId * sizeof( uint64_t ) ) );\r
\r
do\r
{\r
} while( ulCurrentTimeHigh != *pulTimeHigh );\r
\r
ullNextTime = ( uint64_t ) ulCurrentTimeHigh;\r
- ullNextTime <<= 32ULL;\r
+ ullNextTime <<= 32ULL; /* High 4-byte word is 32-bits up. */\r
ullNextTime |= ( uint64_t ) ulCurrentTimeLow;\r
ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick;\r
*pullMachineTimerCompareRegister = ullNextTime;\r
ullNextTime += ( uint64_t ) uxTimerIncrementsForOneTick;\r
}\r
\r
-#endif /* ( configCLINT_BASE_ADDRESS != 0 ) */\r
+#endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIME_BASE_ADDRESS != 0 ) */\r
/*-----------------------------------------------------------*/\r
\r
BaseType_t xPortStartScheduler( void )\r
configure whichever clock is to be used to generate the tick interrupt. */\r
vPortSetupTimerInterrupt();\r
\r
- #if( configCLINT_BASE_ADDRESS != 0 )\r
+ #if( ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) )\r
{\r
/* Enable mtime and external interrupts. 1<<7 for timer interrupt, 1<<11\r
for external interrupt. _RB_ What happens here when mtime is not present as\r
/* Enable external interrupts. */\r
__asm volatile( "csrs 0x304, %0" :: "r"(0x800) ); /* 304 is mie. */\r
}\r
- #endif /* configCLINT_BASE_ADDRESS */\r
+ #endif /* ( configMTIME_BASE_ADDRESS != 0 ) && ( configMTIMECMP_BASE_ADDRESS != 0 ) */\r
\r
xPortStartFirstTask();\r
\r
\r
/* Check the freertos_risc_v_chip_specific_extensions.h and/or command line\r
definitions. */\r
-#ifndef portasmHAS_CLINT\r
- #error freertos_risc_v_chip_specific_extensions.h must define portasmHAS_CLINT to either 1 (CLINT present) or 0 (clint not present).\r
+#if defined( portasmHAS_CLINT ) && defined( portasmHAS_MTIME )\r
+ #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.\r
+#endif\r
+\r
+#ifdef portasmHAS_CLINT\r
+ #warning The portasmHAS_CLINT constant has been depracted. Please replace it with portasmHAS_CLINT. For now portasmHAS_MTIME is derived from portasmHAS_CLINT.\r
+ #define portasmHAS_MTIME portasmHAS_CLINT\r
+#endif\r
+\r
+#ifndef portasmHAS_MTIME\r
+ #error freertos_risc_v_chip_specific_extensions.h must define portasmHAS_MTIME to either 1 (MTIME clock present) or 0 (MTIME clock not present).\r
#endif\r
\r
#ifndef portasmHANDLE_INTERRUPT\r
\r
handle_asynchronous:\r
\r
-#if( portasmHAS_CLINT != 0 )\r
+#if( portasmHAS_MTIME != 0 )\r
\r
test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */\r
\r
addi t1, t1, 4 /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */\r
bne a0, t1, as_yet_unhandled /* Something as yet unhandled. */\r
\r
-#endif /* portasmHAS_CLINT */\r
+#endif /* portasmHAS_MTIME */\r
\r
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */\r
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. */\r
\r
xPortStartFirstTask:\r
\r
-#if( portasmHAS_CLINT != 0 )\r
+#if( portasmHAS_MTIME != 0 )\r
/* If there is a clint then interrupts can branch directly to the FreeRTOS\r
trap handler. Otherwise the interrupt controller will need to be configured\r
outside of this file. */\r
warnings. */\r
#pragma diag_suppress=Pa082\r
\r
+/* configCLINT_BASE_ADDRESS is a legacy definition that was replaced by the\r
+configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS definitions. For\r
+backward compatibility derive the newer definitions from the old if the old\r
+definition is found. */\r
+#if defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS ) && ( configCLINT_BASE_ADDRESS == 0 )\r
+ /* Legacy case where configCLINT_BASE_ADDRESS was defined as 0 to indicate\r
+ there was no CLINT. Equivalent now is to set the MTIME and MTIMECMP\r
+ addresses to 0. */\r
+ #define configMTIME_BASE_ADDRESS ( 0 )\r
+ #define configMTIMECMP_BASE_ADDRESS ( 0 )\r
+#elif defined( configCLINT_BASE_ADDRESS ) && !defined( configMTIME_BASE_ADDRESS )\r
+ /* Legacy case where configCLINT_BASE_ADDRESS was set to the base address of\r
+ the CLINT. Equivalent now is to derive the MTIME and MTIMECMP addresses\r
+ from the CLINT address. */\r
+ #define configMTIME_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0xBFF8UL )\r
+ #define configMTIMECMP_BASE_ADDRESS ( ( configCLINT_BASE_ADDRESS ) + 0x4000UL )\r
+#elif !defined( configMTIME_BASE_ADDRESS ) || !defined( configMTIMECMP_BASE_ADDRESS )\r
+ #error configMTIME_BASE_ADDRESS and configMTIMECMP_BASE_ADDRESS must be defined in FreeRTOSConfig.h. Set them to zero if there is no MTIME (machine time) clock. See https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html\r
+#endif\r
+\r
+\r
\r
#ifdef __cplusplus\r
}\r