From 5c0dcccf48ce65dce0860170de3b6f02d409e4cd Mon Sep 17 00:00:00 2001 From: rtel Date: Wed, 4 Sep 2019 15:46:45 +0000 Subject: [PATCH] RISC-V port updates: The machine timer compare register can now be for any HART, and correct the sequence used to update the 64-bit machine timer compare register on 32-bit cores. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2720 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- FreeRTOS/Source/portable/GCC/RISC-V/port.c | 7 +- FreeRTOS/Source/portable/GCC/RISC-V/portASM.S | 6 +- ...freertos_risc_v_chip_specific_extensions.h | 109 ------------------ FreeRTOS/Source/portable/IAR/RISC-V/port.c | 13 ++- FreeRTOS/Source/portable/IAR/RISC-V/portASM.s | 6 +- 5 files changed, 22 insertions(+), 119 deletions(-) delete mode 100644 FreeRTOS/Source/portable/IAR/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h diff --git a/FreeRTOS/Source/portable/GCC/RISC-V/port.c b/FreeRTOS/Source/portable/GCC/RISC-V/port.c index 1ab1c2e19..4cd9daa93 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V/port.c +++ b/FreeRTOS/Source/portable/GCC/RISC-V/port.c @@ -75,7 +75,8 @@ void vPortSetupTimerInterrupt( void ) __attribute__(( weak )); uint64_t ullNextTime = 0ULL; 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. */ -volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCLINT_BASE_ADDRESS + 0x4000 ); +volatile uint64_t * const pullMachineTimerCompareRegisterBase = ( volatile uint64_t * const ) ( configCLINT_BASE_ADDRESS + 0x4000 ); +volatile uint64_t * pullMachineTimerCompareRegister = 0; /* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task stack checking. A problem in the ISR stack will trigger an assert, not call the @@ -110,6 +111,10 @@ task stack, not the ISR stack). */ uint32_t ulCurrentTimeHigh, ulCurrentTimeLow; volatile uint32_t * const pulTimeHigh = ( volatile uint32_t * const ) ( configCLINT_BASE_ADDRESS + 0xBFFC ); volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCLINT_BASE_ADDRESS + 0xBFF8 ); + volatile uint32_t ulHartId = 0; + + __asm volatile( "csrr %0, mhartid" : "=r"( ulHartId ) ); + pullMachineTimerCompareRegister = &( pullMachineTimerCompareRegisterBase[ ulHartId ] ); do { diff --git a/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S b/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S index df6495f44..436895158 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S +++ b/FreeRTOS/Source/portable/GCC/RISC-V/portASM.S @@ -92,11 +92,13 @@ at the top of this file. */ .extern pxCurrentTCB .extern ulPortTrapHandler .extern vTaskSwitchContext +.extern xTaskIncrementTick .extern Timer_IRQHandler .extern pullMachineTimerCompareRegister .extern pullNextTime .extern uxTimerIncrementsForOneTick /* size_t type so 32-bit on 32-bit core and 64-bits on 64-bit core. */ .extern xISRStackTop +.extern portasmHANDLE_INTERRUPT /*-----------------------------------------------------------*/ @@ -167,10 +169,12 @@ handle_asynchronous: #if( __riscv_xlen == 32 ) /* Update the 64-bit mtimer compare match value in two 32-bit writes. */ + li t4, -1 lw t2, 0(t1) /* Load the low word of ullNextTime into t2. */ lw t3, 4(t1) /* Load the high word of ullNextTime into t3. */ + sw t4, 0(t0) /* Low word no smaller than old value. */ + sw t3, 4(t0) /* Store high word of ullNextTime into compare register. No smaller than new value. */ sw t2, 0(t0) /* Store low word of ullNextTime into compare register. */ - sw t3, 4(t0) /* Store high word of ullNextTime into compare register. */ lw t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */ add t4, t0, t2 /* Add the low word of ullNextTime to the timer increments for one tick (assumes timer increment for one tick fits in 32-bits). */ sltu t5, t4, t2 /* See if the sum of low words overflowed (what about the zero case?). */ diff --git a/FreeRTOS/Source/portable/IAR/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h b/FreeRTOS/Source/portable/IAR/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h deleted file mode 100644 index 9e581431a..000000000 --- a/FreeRTOS/Source/portable/IAR/RISC-V/chip_specific_extensions/Pulpino_Vega_RV32M1RM/freertos_risc_v_chip_specific_extensions.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - * the Software, and t - - o permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS - * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR - * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - -/* - * The FreeRTOS kernel's RISC-V port is split between the the code that is - * common across all currently supported RISC-V chips (implementations of the - * RISC-V ISA), and code that tailors the port to a specific RISC-V chip: - * - * + FreeRTOS\Source\portable\GCC\RISC-V-RV32\portASM.S contains the code that - * is common to all currently supported RISC-V chips. There is only one - * portASM.S file because the same file is built for all RISC-V target chips. - * - * + Header files called freertos_risc_v_chip_specific_extensions.h contain the - * code that tailors the FreeRTOS kernel's RISC-V port to a specific RISC-V - * chip. There are multiple freertos_risc_v_chip_specific_extensions.h files - * as there are multiple RISC-V chip implementations. - * - * !!!NOTE!!! - * TAKE CARE TO INCLUDE THE CORRECT freertos_risc_v_chip_specific_extensions.h - * HEADER FILE FOR THE CHIP IN USE. This is done using the assembler's (not the - * compiler's!) include path. For example, if the chip in use includes a core - * local interrupter (CLINT) and does not include any chip specific register - * extensions then add the path below to the assembler's include path: - * FreeRTOS\Source\portable\GCC\RISC-V-RV32\chip_specific_extensions\RV32I_CLINT_no_extensions - * - */ - -/* - * This freertos_risc_v_chip_specific_extensions.h is for use with Pulpino Ri5cy - * devices, developed and tested using the Vega board RV32M1RM. - */ - -#ifndef __FREERTOS_RISC_V_EXTENSIONS_H__ -#define __FREERTOS_RISC_V_EXTENSIONS_H__ - -#define portasmHAS_CLINT 0 - -/* Constants to define the additional registers found on the Pulpino RI5KY. */ -#define lpstart0 0x7b0 -#define lpend0 0x7b1 -#define lpcount0 0x7b2 -#define lpstart1 0x7b4 -#define lpend1 0x7b5 -#define lpcount1 0x7b6 - -/* Six additional registers to save and restore, as per the #defines above. */ -#define portasmADDITIONAL_CONTEXT_SIZE 6 /* Must be even number on 32-bit cores. */ - -/* Save additional registers found on the Pulpino. */ -.macro portasmSAVE_ADDITIONAL_REGISTERS - addi sp, sp, -(portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE) /* Make room for the additional registers. */ - csrr t0, lpstart0 /* Load additional registers into accessible temporary registers. */ - csrr t1, lpend0 - csrr t2, lpcount0 - csrr t3, lpstart1 - csrr t4, lpend1 - csrr t5, lpcount1 - sw t0, 1 * portWORD_SIZE( sp ) - sw t1, 2 * portWORD_SIZE( sp ) - sw t2, 3 * portWORD_SIZE( sp ) - sw t3, 4 * portWORD_SIZE( sp ) - sw t4, 5 * portWORD_SIZE( sp ) - sw t5, 6 * portWORD_SIZE( sp ) - .endm - -/* Restore the additional registers found on the Pulpino. */ -.macro portasmRESTORE_ADDITIONAL_REGISTERS - lw t0, 1 * portWORD_SIZE( sp ) /* Load additional registers into accessible temporary registers. */ - lw t1, 2 * portWORD_SIZE( sp ) - lw t2, 3 * portWORD_SIZE( sp ) - lw t3, 4 * portWORD_SIZE( sp ) - lw t4, 5 * portWORD_SIZE( sp ) - lw t5, 6 * portWORD_SIZE( sp ) - csrw lpstart0, t0 - csrw lpend0, t1 - csrw lpcount0, t2 - csrw lpstart1, t3 - csrw lpend1, t4 - csrw lpcount1, t5 - addi sp, sp, (portasmADDITIONAL_CONTEXT_SIZE * portWORD_SIZE )/* Remove space added for additional registers. */ - .endm - -#endif /* __FREERTOS_RISC_V_EXTENSIONS_H__ */ diff --git a/FreeRTOS/Source/portable/IAR/RISC-V/port.c b/FreeRTOS/Source/portable/IAR/RISC-V/port.c index 025cb2fae..8c59aef2f 100644 --- a/FreeRTOS/Source/portable/IAR/RISC-V/port.c +++ b/FreeRTOS/Source/portable/IAR/RISC-V/port.c @@ -56,7 +56,7 @@ stack that was used by main before the scheduler was started for use as the interrupt stack after the scheduler has started. */ #ifdef configISR_STACK_SIZE_WORDS static __attribute__ ((aligned(16))) StackType_t xISRStack[ configISR_STACK_SIZE_WORDS ] = { 0 }; - StackType_t xISRStackTop = ( StackType_t ) 0; + const StackType_t xISRStackTop = ( StackType_t ) &( xISRStack[ configISR_STACK_SIZE_WORDS & ~portBYTE_ALIGNMENT_MASK ] ); #else extern const uint32_t __freertos_irq_stack_top[]; const StackType_t xISRStackTop = ( StackType_t ) __freertos_irq_stack_top; @@ -75,7 +75,8 @@ void vPortSetupTimerInterrupt( void ) __attribute__(( weak )); uint64_t ullNextTime = 0ULL; 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. */ -volatile uint64_t * const pullMachineTimerCompareRegister = ( uint64_t * ) ( configCLINT_BASE_ADDRESS + 0x4000 ); +volatile uint64_t * const pullMachineTimerCompareRegisterBase = ( uint64_t * ) ( configCLINT_BASE_ADDRESS + 0x4000 ); +volatile uint64_t * pullMachineTimerCompareRegister = 0; /* Set configCHECK_FOR_STACK_OVERFLOW to 3 to add ISR stack checking to task stack checking. A problem in the ISR stack will trigger an assert, not call the @@ -110,6 +111,10 @@ task stack, not the ISR stack). */ uint32_t ulCurrentTimeHigh, ulCurrentTimeLow; volatile uint32_t * const pulTimeHigh = ( uint32_t * ) ( configCLINT_BASE_ADDRESS + 0xBFFC ); volatile uint32_t * const pulTimeLow = ( uint32_t * ) ( configCLINT_BASE_ADDRESS + 0xBFF8 ); + volatile uint32_t ulHartId = 0; + + __asm volatile( "csrr %0, 0xf14" : "=r"( ulHartId ) ); /* 0xf14 is hartid. */ + pullMachineTimerCompareRegister = &( pullMachineTimerCompareRegisterBase[ ulHartId ] ); do { @@ -133,10 +138,6 @@ task stack, not the ISR stack). */ BaseType_t xPortStartScheduler( void ) { extern void xPortStartFirstTask( void ); -#warning Replicate this change in the GCC version. - #ifdef configISR_STACK_SIZE_WORDS - xISRStackTop = ( ( StackType_t ) &( xISRStack[ configISR_STACK_SIZE_WORDS - 1 ] ) & ~portBYTE_ALIGNMENT_MASK ); - #endif #if( configASSERT_DEFINED == 1 ) { diff --git a/FreeRTOS/Source/portable/IAR/RISC-V/portASM.s b/FreeRTOS/Source/portable/IAR/RISC-V/portASM.s index 9e004dea3..84cf6c950 100644 --- a/FreeRTOS/Source/portable/IAR/RISC-V/portASM.s +++ b/FreeRTOS/Source/portable/IAR/RISC-V/portASM.s @@ -110,7 +110,7 @@ at the top of this file. */ /*-----------------------------------------------------------*/ SECTION `.text`:CODE:NOROOT(2) - CODE + CODE freertos_risc_v_trap_handler: addi sp, sp, -portCONTEXT_SIZE @@ -177,10 +177,12 @@ handle_asynchronous: #if( __riscv_xlen == 32 ) /* Update the 64-bit mtimer compare match value in two 32-bit writes. */ + li t4, -1 lw t2, 0(t1) /* Load the low word of ullNextTime into t2. */ lw t3, 4(t1) /* Load the high word of ullNextTime into t3. */ + sw t4, 0(t0) /* Low word no smaller than old value. */ + sw t3, 4(t0) /* Store high word of ullNextTime into compare register. No smaller than new value. */ sw t2, 0(t0) /* Store low word of ullNextTime into compare register. */ - sw t3, 4(t0) /* Store high word of ullNextTime into compare register. */ lw t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */ add t4, t0, t2 /* Add the low word of ullNextTime to the timer increments for one tick (assumes timer increment for one tick fits in 32-bits). */ sltu t5, t4, t2 /* See if the sum of low words overflowed (what about the zero case?). */ -- 2.39.2