From b1a107796313c5a64ee33ca3accff1a701b2cc71 Mon Sep 17 00:00:00 2001 From: rtel Date: Wed, 28 Nov 2018 19:35:40 +0000 Subject: [PATCH] Some efficiency improvements in Risc-V port. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2597 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../Source/portable/GCC/RISC-V-RV32/port.c | 26 +-- .../Source/portable/GCC/RISC-V-RV32/portASM.S | 152 +++++++++++------- 2 files changed, 102 insertions(+), 76 deletions(-) diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c index 2754cb40e..28b4b0477 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c @@ -49,9 +49,10 @@ static void prvTaskExitError( void ); /*-----------------------------------------------------------*/ /* Used to program the machine timer compare register. */ -static uint64_t ullNextTime = 0ULL; -static const uint64_t ullTimerIncrementsForOneTick = ( uint64_t ) ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ); -static volatile uint64_t * const pullMachineTimerCompareRegister = ( volatile uint64_t * const ) ( configCLINT_BASE_ADDRESS + 0x4000 ); +uint64_t ullNextTime = 0ULL; +const uint64_t *pullNextTime = &ullNextTime; +const uint32_t ulTimerIncrementsForOneTick = ( uint32_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 ); /*-----------------------------------------------------------*/ @@ -187,11 +188,11 @@ volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCLI ullNextTime = ( uint64_t ) ulCurrentTimeHigh; ullNextTime <<= 32ULL; ullNextTime |= ( uint64_t ) ulCurrentTimeLow; - ullNextTime += ullTimerIncrementsForOneTick; + ullNextTime += ( uint64_t ) ulTimerIncrementsForOneTick; *pullMachineTimerCompareRegister = ullNextTime; /* Prepare the time to use after the next tick interrupt. */ - ullNextTime += ullTimerIncrementsForOneTick; + ullNextTime += ( uint64_t ) ulTimerIncrementsForOneTick; /* Enable timer interrupt */ __asm volatile( "csrs mie, %0" :: "r"(0x80) ); /* 1<<7 for timer interrupt. */ @@ -209,21 +210,6 @@ volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) configCLINT_BASE_ADDR } /*-----------------------------------------------------------*/ -void Timer_IRQHandler( void ) -{ -extern void vTaskSwitchContext( void ); - - /* Reload for the next timer interrupt. */ - *pullMachineTimerCompareRegister = ullNextTime; - ullNextTime += ullTimerIncrementsForOneTick; - - if( xTaskIncrementTick() != pdFALSE ) - { - vTaskSwitchContext(); - } -} -/*-----------------------------------------------------------*/ - BaseType_t xPortStartScheduler( void ) { extern void xPortStartFirstTask( void ); diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S index 8ffd3a434..5f6c3a10e 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S @@ -28,12 +28,12 @@ */ #if __riscv_xlen == 64 - #error Not implemented yet - change lw to ld, and sw to sd. - #define WORD_SIZE 8 + #error Not implemented yet - change lw to ld, and sw to sd. + #define WORD_SIZE 8 #elif __riscv_xlen == 32 - #define WORD_SIZE 4 + #define WORD_SIZE 4 #else - #error Assembler has not defined __riscv_xlen + #error Assembler has not defined __riscv_xlen #endif #define CONTEXT_SIZE ( 30 * WORD_SIZE ) @@ -42,6 +42,14 @@ .global vPortTrapHandler .extern pxCurrentTCB .extern ulPortTrapHandler +.extern vTaskSwitchContext +.extern Timer_IRQHandler + + +.extern pullMachineTimerCompareRegister +.extern pullNextTime +.extern ulTimerIncrementsForOneTick + /*-----------------------------------------------------------*/ @@ -51,18 +59,18 @@ xPortStartFirstTask: la t0, vPortTrapHandler csrw mtvec, t0 - lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ - lw sp, 0( sp ) /* Read sp from first TCB member. */ + lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ + lw sp, 0( sp ) /* Read sp from first TCB member. */ lw x1, 0( sp ) /* Note for starting the scheduler the exception return address is used as the function return address. */ - lw x5, 2 * WORD_SIZE( sp ) /* t0 */ - lw x6, 3 * WORD_SIZE( sp ) /* t1 */ - lw x7, 4 * WORD_SIZE( sp ) /* t2 */ - lw x8, 5 * WORD_SIZE( sp ) /* s0/fp */ - lw x9, 6 * WORD_SIZE( sp ) /* s1 */ - lw x10, 7 * WORD_SIZE( sp ) /* a0 */ - lw x11, 8 * WORD_SIZE( sp ) /* a1 */ - lw x12, 9 * WORD_SIZE( sp ) /* a2 */ + lw x5, 2 * WORD_SIZE( sp ) /* t0 */ + lw x6, 3 * WORD_SIZE( sp ) /* t1 */ + lw x7, 4 * WORD_SIZE( sp ) /* t2 */ + lw x8, 5 * WORD_SIZE( sp ) /* s0/fp */ + lw x9, 6 * WORD_SIZE( sp ) /* s1 */ + lw x10, 7 * WORD_SIZE( sp ) /* a0 */ + lw x11, 8 * WORD_SIZE( sp ) /* a1 */ + lw x12, 9 * WORD_SIZE( sp ) /* a2 */ lw x13, 10 * WORD_SIZE( sp ) /* a3 */ lw x14, 11 * WORD_SIZE( sp ) /* a4 */ lw x15, 12 * WORD_SIZE( sp ) /* a5 */ @@ -82,8 +90,8 @@ xPortStartFirstTask: lw x29, 26 * WORD_SIZE( sp ) /* t4 */ lw x30, 27 * WORD_SIZE( sp ) /* t5 */ lw x31, 28 * WORD_SIZE( sp ) /* t6 */ - addi sp, sp, CONTEXT_SIZE - csrs mstatus, 8 /* Enable machine interrupts. */ + addi sp, sp, CONTEXT_SIZE + csrs mstatus, 8 /* Enable machine interrupts. */ ret /*-----------------------------------------------------------*/ @@ -120,24 +128,56 @@ vPortTrapHandler: sw x30, 27 * WORD_SIZE( sp ) sw x31, 28 * WORD_SIZE( sp ) - csrr t0, mstatus /* Required for MPIE bit. */ + csrr t0, mstatus /* Required for MPIE bit. */ sw t0, 29 * WORD_SIZE( sp ) - lw t0, pxCurrentTCB /* Load pxCurrentTCB. */ - sw sp, 0( t0 ) /* Write sp to first TCB member. */ + lw t0, pxCurrentTCB /* Load pxCurrentTCB. */ + sw sp, 0( t0 ) /* Write sp to first TCB member. */ csrr a0, mcause csrr a1, mepc mv a2, sp -/*_RB_ Does stack need aligning here? */ - jal ulPortTrapHandler - csrw mepc, a0 - /* Save exception return address. */ - sw a0, 0( sp ) - - lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ - lw sp, 0( sp ) /* Read sp from first TCB member. */ +test_if_environment_call: + li t0, 11 /* 11 == environment call when using qemu. */ + bne a0, t0, test_if_timer + addi a1, a1, 4 /* Synchronous so return to the instruction after the environment call. */ + sw a1, 0( sp ) /* Save updated exception return address. */ +/*_RB_ Does stack need aligning here? */ + jal vTaskSwitchContext + j processed_source + + +test_if_timer: + sw a1, 0( sp ) /* Asynch so save unmodified exception return address. */ + + lui t0, 0x80000 + addi t1,t0, 7 /* 0x80000007 == machine timer interrupt. */ + bne a0, t1, as_yet_unhandled + + lw t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */ + lw t1, pullNextTime /* Load the address of ullNextTime into t1. */ + 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 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, ulTimerIncrementsForOneTick /* 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?). */ + add t6, t3, t5 /* Add overflow to high word of ullNextTime. */ + sw t4, 0(t1) /* Store new low word of ullNextTime. */ + sw t6, 4(t1) /* Store new high word of ullNextTime. */ + jal xTaskIncrementTick + beqz a0, processed_source /* Don't switch context if incrementing tick didn't unblock a task. */ + jal vTaskSwitchContext + j processed_source + +as_yet_unhandled: + j as_yet_unhandled /* External interrupt? */ + +processed_source: + lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ + lw sp, 0( sp ) /* Read sp from first TCB member. */ /* Load mret with the address of the next task. */ lw t0, 0( sp ) @@ -145,37 +185,37 @@ vPortTrapHandler: /* Load mstatus with the interrupt enable bits used by the task. */ lw t0, 29 * WORD_SIZE( sp ) - csrw mstatus, t0 /* Required for MPIE bit. */ + csrw mstatus, t0 /* Required for MPIE bit. */ lw x1, 1 * WORD_SIZE( sp ) - lw x5, 2 * WORD_SIZE( sp ) /* t0 */ - lw x6, 3 * WORD_SIZE( sp ) /* t1 */ - lw x7, 4 * WORD_SIZE( sp ) /* t2 */ - lw x8, 5 * WORD_SIZE( sp ) /* s0/fp */ - lw x9, 6 * WORD_SIZE( sp ) /* s1 */ - lw x10, 7 * WORD_SIZE( sp ) /* a0 */ - lw x11, 8 * WORD_SIZE( sp ) /* a1 */ - lw x12, 9 * WORD_SIZE( sp ) /* a2 */ - lw x13, 10 * WORD_SIZE( sp ) /* a3 */ - lw x14, 11 * WORD_SIZE( sp ) /* a4 */ - lw x15, 12 * WORD_SIZE( sp ) /* a5 */ - lw x16, 13 * WORD_SIZE( sp ) /* a6 */ - lw x17, 14 * WORD_SIZE( sp ) /* a7 */ - lw x18, 15 * WORD_SIZE( sp ) /* s2 */ - lw x19, 16 * WORD_SIZE( sp ) /* s3 */ - lw x20, 17 * WORD_SIZE( sp ) /* s4 */ - lw x21, 18 * WORD_SIZE( sp ) /* s5 */ - lw x22, 19 * WORD_SIZE( sp ) /* s6 */ - lw x23, 20 * WORD_SIZE( sp ) /* s7 */ - lw x24, 21 * WORD_SIZE( sp ) /* s8 */ - lw x25, 22 * WORD_SIZE( sp ) /* s9 */ - lw x26, 23 * WORD_SIZE( sp ) /* s10 */ - lw x27, 24 * WORD_SIZE( sp ) /* s11 */ - lw x28, 25 * WORD_SIZE( sp ) /* t3 */ - lw x29, 26 * WORD_SIZE( sp ) /* t4 */ - lw x30, 27 * WORD_SIZE( sp ) /* t5 */ - lw x31, 28 * WORD_SIZE( sp ) /* t6 */ - addi sp, sp, CONTEXT_SIZE + lw x5, 2 * WORD_SIZE( sp ) /* t0 */ + lw x6, 3 * WORD_SIZE( sp ) /* t1 */ + lw x7, 4 * WORD_SIZE( sp ) /* t2 */ + lw x8, 5 * WORD_SIZE( sp ) /* s0/fp */ + lw x9, 6 * WORD_SIZE( sp ) /* s1 */ + lw x10, 7 * WORD_SIZE( sp ) /* a0 */ + lw x11, 8 * WORD_SIZE( sp ) /* a1 */ + lw x12, 9 * WORD_SIZE( sp ) /* a2 */ + lw x13, 10 * WORD_SIZE( sp ) /* a3 */ + lw x14, 11 * WORD_SIZE( sp ) /* a4 */ + lw x15, 12 * WORD_SIZE( sp ) /* a5 */ + lw x16, 13 * WORD_SIZE( sp ) /* a6 */ + lw x17, 14 * WORD_SIZE( sp ) /* a7 */ + lw x18, 15 * WORD_SIZE( sp ) /* s2 */ + lw x19, 16 * WORD_SIZE( sp ) /* s3 */ + lw x20, 17 * WORD_SIZE( sp ) /* s4 */ + lw x21, 18 * WORD_SIZE( sp ) /* s5 */ + lw x22, 19 * WORD_SIZE( sp ) /* s6 */ + lw x23, 20 * WORD_SIZE( sp ) /* s7 */ + lw x24, 21 * WORD_SIZE( sp ) /* s8 */ + lw x25, 22 * WORD_SIZE( sp ) /* s9 */ + lw x26, 23 * WORD_SIZE( sp ) /* s10 */ + lw x27, 24 * WORD_SIZE( sp ) /* s11 */ + lw x28, 25 * WORD_SIZE( sp ) /* t3 */ + lw x29, 26 * WORD_SIZE( sp ) /* t4 */ + lw x30, 27 * WORD_SIZE( sp ) /* t5 */ + lw x31, 28 * WORD_SIZE( sp ) /* t6 */ + addi sp, sp, CONTEXT_SIZE mret -- 2.39.5