diff --git a/portable/GCC/RISC-V/port.c b/portable/GCC/RISC-V/port.c index 32eaa335d6..842767223c 100644 --- a/portable/GCC/RISC-V/port.c +++ b/portable/GCC/RISC-V/port.c @@ -97,6 +97,12 @@ volatile uint64_t * pullMachineTimerCompareRegister = NULL; size_t xCriticalNesting = ( size_t ) 0xaaaaaaaa; size_t * pxCriticalNesting = &xCriticalNesting; +/* + * Counts the interrupt nesting depth. + */ +size_t xInterruptNesting = 0; +size_t * pxInterruptNesting = &xInterruptNesting; + /* Used to catch tasks that attempt to return from their implementing function. */ size_t xTaskReturnAddress = ( size_t ) portTASK_RETURN_ADDRESS; @@ -205,3 +211,9 @@ void vPortEndScheduler( void ) } } /*-----------------------------------------------------------*/ + +BaseType_t xPortIsInsideInterrupt( void ) +{ + return ( xInterruptNesting == 0 ) ? pdFALSE : pdTRUE; +} +/*-----------------------------------------------------------*/ diff --git a/portable/GCC/RISC-V/portASM.S b/portable/GCC/RISC-V/portASM.S index 9d36d78f92..6cd13b7fd6 100644 --- a/portable/GCC/RISC-V/portASM.S +++ b/portable/GCC/RISC-V/portASM.S @@ -162,6 +162,7 @@ definitions. */ * where the global and thread pointers are currently assumed to be constant so * are not saved: * + * xInterruptNesting * xCriticalNesting * x31 * x30 @@ -198,6 +199,8 @@ definitions. */ * pxCode */ pxPortInitialiseStack: + addi a0, a0, -portWORD_SIZE /* Space for interrupt nesting count. */ + addi a0, a0, -portWORD_SIZE /* Space for critical nesting count. */ store_x x0, 0(a0) /* Critical nesting count starts at 0 for every task. */ diff --git a/portable/GCC/RISC-V/portContext.h b/portable/GCC/RISC-V/portContext.h index 0869a82b6c..9c2a7f5053 100644 --- a/portable/GCC/RISC-V/portContext.h +++ b/portable/GCC/RISC-V/portContext.h @@ -57,11 +57,13 @@ * specific version of freertos_risc_v_chip_specific_extensions.h. See the * notes at the top of portASM.S file. */ #ifdef __riscv_32e - #define portCONTEXT_SIZE ( 15 * portWORD_SIZE ) + #define portCONTEXT_SIZE ( 16 * portWORD_SIZE ) #define portCRITICAL_NESTING_OFFSET 14 + #define portINTERRUPT_NESTING_OFFSET 15 #else - #define portCONTEXT_SIZE ( 31 * portWORD_SIZE ) + #define portCONTEXT_SIZE ( 32 * portWORD_SIZE ) #define portCRITICAL_NESTING_OFFSET 30 + #define portINTERRUPT_NESTING_OFFSET 31 #endif #if ( configENABLE_FPU == 1 ) @@ -122,6 +124,8 @@ .extern xISRStackTop .extern xCriticalNesting .extern pxCriticalNesting +.extern xInterruptNesting +.extern pxInterruptNesting /*-----------------------------------------------------------*/ .macro portcontexSAVE_FPU_CONTEXT @@ -306,6 +310,12 @@ store_x x15, 13 * portWORD_SIZE( sp ) load_x t0, xCriticalNesting /* Load the value of xCriticalNesting into t0. */ store_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the critical nesting value to the stack. */ +load_x t0, xInterruptNesting /* Load the value of xInterruptNesting into t0. */ +store_x t0, portINTERRUPT_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the interrupt nesting value to the stack. */ +addi t0, t0, 1 +load_x t1, pxInterruptNesting /* Load the address of xInterruptNesting into t1. */ +store_x t0, 0( t1 ) /* Increment xInterruptNesting by 1 */ + #if( configENABLE_FPU == 1 ) csrr t0, mstatus srl t1, t0, MSTATUS_FS_OFFSET @@ -425,6 +435,10 @@ csrw mstatus, t3 6: #endif /* ifdef portasmSTORE_FPU_CONTEXT */ +load_x t0, portINTERRUPT_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain saved xInterruptNesting value from task's stack. */ +load_x t1, pxInterruptNesting /* Load the address of xInterruptNesting into t1. */ +store_x t0, 0 ( t1 ) /* Restore the interrupt nesting value. */ + load_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */ load_x t1, pxCriticalNesting /* Load the address of xCriticalNesting into t1. */ store_x t0, 0 ( t1 ) /* Restore the critical nesting value for this task. */ diff --git a/portable/GCC/RISC-V/portmacro.h b/portable/GCC/RISC-V/portmacro.h index a516a24673..aaeb69966c 100644 --- a/portable/GCC/RISC-V/portmacro.h +++ b/portable/GCC/RISC-V/portmacro.h @@ -106,6 +106,8 @@ extern void vTaskSwitchContext( void ); } \ } while( 0 ) #define portYIELD_FROM_ISR( x ) portEND_SWITCHING_ISR( x ) + +BaseType_t xPortIsInsideInterrupt( void ); /*-----------------------------------------------------------*/ /* Critical section management. */