From ad70206f8eabd0abaf240f5c4e33e65c9c9d4dbe Mon Sep 17 00:00:00 2001 From: rtel Date: Sun, 16 Dec 2018 20:21:29 +0000 Subject: [PATCH] Save changes to the RISC-V port layer before making changes necessary to support pulpino too: + Switch positions of the asm functions used to start the kernel and handle traps to enable one to reference to the other. + Handle external interrupts (working with Renode emulator). + The _sp linker variable is now called __freertos_irq_stack_top. git-svn-id: https://svn.code.sf.net/p/freertos/code/trunk@2603 1d2547de-c912-0410-9cb9-b8ca96c0e9e2 --- .../Source/portable/GCC/RISC-V-RV32/port.c | 15 +-- .../Source/portable/GCC/RISC-V-RV32/portASM.S | 101 ++++++++++-------- .../portable/GCC/RISC-V-RV32/portmacro.h | 17 ++- 3 files changed, 71 insertions(+), 62 deletions(-) diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c index 139d1c833..95ec89e34 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/port.c @@ -39,9 +39,8 @@ static __attribute__ ((aligned(16))) StackType_t xISRStack[ configISR_STACK_SIZE ] = { 0 }; const StackType_t * const xISRStackTop = &( xISRStack[ ( configISR_STACK_SIZE & ~portBYTE_ALIGNMENT_MASK ) - 1 ] ); #else -#warning What should _sp be named? - extern const uint32_t _sp[]; - const uint32_t xISRStackTop = ( uint32_t ) _sp; + extern const uint32_t __freertos_irq_stack_top[]; + const uint32_t xISRStackTop = ( uint32_t ) __freertos_irq_stack_top; #endif /* @@ -227,9 +226,6 @@ volatile uint32_t * const pulTimeLow = ( volatile uint32_t * const ) ( configCLI /* Prepare the time to use after the next tick interrupt. */ ullNextTime += ( uint64_t ) ulTimerIncrementsForOneTick; - - /* Enable timer interrupt. */ - __asm volatile( "csrs mie, %0" :: "r"(0x80) ); /* 1<<7 for timer interrupt. */ } /*-----------------------------------------------------------*/ @@ -254,6 +250,12 @@ extern void xPortStartFirstTask( void ); #endif vPortSetupTimerInterrupt(); + + /* 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 + with pulpino? */ + __asm volatile( "csrs mie, %0" :: "r"(0x880) ); + xPortStartFirstTask(); /* Should not get here as after calling xPortStartFirstTask() only tasks @@ -271,3 +273,4 @@ void vPortEndScheduler( void ) + diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S index e9ba83856..d08c2b082 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portASM.S @@ -50,49 +50,7 @@ .extern pullNextTime .extern ulTimerIncrementsForOneTick .extern xISRStackTop - -/*-----------------------------------------------------------*/ - -.align 8 -xPortStartFirstTask: - - la t0, vPortTrapHandler - csrw mtvec, t0 - - 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 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 - csrs mstatus, 8 /* Enable machine interrupts. */ - ret +.extern vPortHandleInterrupt /*-----------------------------------------------------------*/ @@ -152,7 +110,7 @@ test_if_timer: lui t0, 0x80000 addi t1,t0, 7 /* 0x80000007 == machine timer interrupt. */ - bne a0, t1, as_yet_unhandled + bne a0, t1, test_if_external_interrupt lw t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */ lw t1, pullNextTime /* Load the address of ullNextTime into t1. */ @@ -172,9 +130,15 @@ test_if_timer: jal vTaskSwitchContext j processed_source -as_yet_unhandled: -// ebreak /* External interrupt? */ - j as_yet_unhandled +test_if_external_interrupt: + addi t1, t1, 4 /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */ + bne a0, t1, is_exception /* Only thing left it can be. */ + jal vPortHandleInterrupt + j processed_source + +is_exception: + ebreak + j is_exception processed_source: lw sp, pxCurrentTCB /* Load pxCurrentTCB. */ @@ -219,5 +183,48 @@ processed_source: addi sp, sp, CONTEXT_SIZE mret +/*-----------------------------------------------------------*/ + +.align 8 +xPortStartFirstTask: + + la t0, vPortTrapHandler + csrw mtvec, t0 + + 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 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 + csrs mstatus, 8 /* Enable machine interrupts. */ + ret +/*-----------------------------------------------------------*/ diff --git a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h index c0c1b6b09..65aa9cf5f 100644 --- a/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h +++ b/FreeRTOS/Source/portable/GCC/RISC-V-RV32/portmacro.h @@ -43,10 +43,6 @@ extern "C" { *----------------------------------------------------------- */ -#ifdef __riscv64 - #error This is the RV32 port that supports 32-bit cores only. -#endif - /* Type definitions. */ #define portSTACK_TYPE uint32_t #define portBASE_TYPE long @@ -65,7 +61,12 @@ not need to be guarded with a critical section. */ /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portBYTE_ALIGNMENT 16 +#ifdef __riscv64 + #error This is the RV32 port that has not yet been adapted for 64. + #define portBYTE_ALIGNMENT 16 +#else + #define portBYTE_ALIGNMENT 8 +#endif /*-----------------------------------------------------------*/ @@ -79,15 +80,13 @@ extern void vTaskSwitchContext( void ); /* Critical section management. */ #define portCRITICAL_NESTING_IN_TCB 1 -extern int vPortSetInterruptMask( void ); -extern void vPortClearInterruptMask( int ); extern void vTaskEnterCritical( void ); extern void vTaskExitCritical( void ); #define portSET_INTERRUPT_MASK_FROM_ISR() 0 #define portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedStatusValue ) ( void ) uxSavedStatusValue -#define portDISABLE_INTERRUPTS() __asm volatile( "csrc mstatus, 8" ); __asm volatile( "fence" ) -#define portENABLE_INTERRUPTS() __asm volatile( "csrs mstatus, 8" ); __asm volatile( "fence" ) +#define portDISABLE_INTERRUPTS() __asm volatile( "csrc mstatus, 8" ) +#define portENABLE_INTERRUPTS() __asm volatile( "csrs mstatus, 8" ) #define portENTER_CRITICAL() vTaskEnterCritical() #define portEXIT_CRITICAL() vTaskExitCritical() -- 2.39.5