From cf532a6b7f9e3f6f07f9c013644a9afe0ec52b68 Mon Sep 17 00:00:00 2001 From: rtel Date: Mon, 19 Nov 2018 06:01:29 +0000 Subject: [PATCH] Update Risc-V port to use environment call in place of software interrupt - still very much a work in progress. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2592 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../Source/portable/GCC/RISC-V-RV32/port.c | 25 ++++++++++++++++--- .../Source/portable/GCC/RISC-V-RV32/portASM.S | 15 ++++++----- .../portable/GCC/RISC-V-RV32/portmacro.h | 2 +- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c index 4f09da8ca..ed2c29885 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c @@ -94,6 +94,12 @@ StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t px x28-31 t3-6 Temporaries Caller */ + /* To ensure alignment. */ + //_RB_ pxTopOfStack--; + //_RB_ pxTopOfStack--; + //_RB_pxTopOfStack--; + + /* Numbers correspond to the x register number. */ pxTopOfStack--; *pxTopOfStack = ( StackType_t ) 31; pxTopOfStack--; @@ -185,7 +191,7 @@ volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCTR ullNextTime += ullTimerIncrementsForOneTick; /* Enable timer interrupt */ - __asm volatile( "csrs mie, %0" :: "r"(0x80) ); + __asm volatile( "csrs mie, %0" :: "r"(0x80) ); /* 1<<7 for timer interrupt. */ } /*-----------------------------------------------------------*/ @@ -196,19 +202,21 @@ volatile uint32_t * const ulSoftInterrupt = ( uint32_t * ) configCTRL_BASE; vTaskSwitchContext(); /* Clear software interrupt. */ - *( ( uint32_t * ) configCTRL_BASE ) = 0UL; + *( ( uint32_t * ) configCTRL_BASE ) &= 0x08UL; } /*-----------------------------------------------------------*/ void Timer_IRQHandler( void ) { +extern void vTaskSwitchContext( void ); + /* Reload for the next timer interrupt. */ *pullMachineTimerCompareRegister = ullNextTime; ullNextTime += ullTimerIncrementsForOneTick; if( xTaskIncrementTick() != pdFALSE ) { - portYIELD(); + vTaskSwitchContext(); } } /*-----------------------------------------------------------*/ @@ -217,6 +225,17 @@ BaseType_t xPortStartScheduler( void ) { extern void xPortStartFirstTask( void ); + #if( configASSERT_DEFINED == 1 ) + { + volatile uint32_t mtvec = 0; + + /* Check the least significant two bits of mtvec are 00 - indicating single + vector mode. */ + __asm volatile( "csrr %0, mtvec" : "=r"( mtvec ) ); + configASSERT( ( mtvec & 0x03UL ) == 0 ); + } + #endif + vPortSetupTimerInterrupt(); xPortStartFirstTask(); diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S index d27391d77..f376b61e3 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S @@ -82,14 +82,14 @@ xPortStartFirstTask: addi sp, sp, CONTEXT_SIZE csrs mstatus, 8 /* Enable machine interrupts. */ csrs mie, 8 /* Enable soft interrupt. */ - ret + ret /*-----------------------------------------------------------*/ .align 8 vPortTrapHandler: addi sp, sp, -CONTEXT_SIZE - sw x1, 1( sp ) + sw x1, 1 * WORD_SIZE( sp ) sw x5, 2 * WORD_SIZE( sp ) sw x6, 3 * WORD_SIZE( sp ) sw x7, 4 * WORD_SIZE( sp ) @@ -118,10 +118,6 @@ vPortTrapHandler: sw x30, 27 * WORD_SIZE( sp ) sw x31, 28 * WORD_SIZE( sp ) - /* Save exception return address. */ - csrr t0, mepc - sw t0, 0( sp ) - lw t0, pxCurrentTCB /* Load pxCurrentTCB. */ sw sp, 0( t0 ) /* Write sp from first TCB member. */ @@ -130,6 +126,9 @@ vPortTrapHandler: mv a2, sp jal handle_trap csrw mepc, a0 + /* Save exception return address. */ + sw a0, 0( sp ) + # Remain in M-mode after mret li t0, 0x00001800 /* MSTATUS MPP */ @@ -138,11 +137,11 @@ vPortTrapHandler: lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ lw sp, 0( sp ) /* Read sp from first TCB member. */ - /* Load mret with the address of the first task. */ + /* Load mret with the address of the next task. */ lw t0, 0( sp ) csrw mepc, t0 - lw x1, 1( sp ) + 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 */ diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h index 828e810bb..d1df6815a 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h @@ -70,7 +70,7 @@ not need to be guarded with a critical section. */ /* Scheduler utilities. */ -#define portYIELD() *( ( uint32_t * ) configCTRL_BASE ) = 1UL +#define portYIELD() __asm volatile( "ecall" ); // software interrupt alternative *( ( uint32_t * ) configCTRL_BASE ) |= 0x08UL #define portEND_SWITCHING_ISR( xSwitchRequired ) if( xSwitchRequired ) vPortYield() #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) /*-----------------------------------------------------------*/ -- 2.39.5