diff --git a/portable/GCC/RISC-V/portASM.S b/portable/GCC/RISC-V/portASM.S index 57e9820824..9dde71f6a8 100644 --- a/portable/GCC/RISC-V/portASM.S +++ b/portable/GCC/RISC-V/portASM.S @@ -208,12 +208,12 @@ pxPortInitialiseStack: store_x x0, 0(a0) /* Critical nesting count starts at 0 for every task. */ #ifdef __riscv_32e - addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x11-x15. */ + addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x10-x15. */ #else - addi a0, a0, -(22 * portWORD_SIZE) /* Space for registers x11-x31. */ + addi a0, a0, -(22 * portWORD_SIZE) /* Space for registers x10-x31. */ #endif store_x a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */ - addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9. */ + addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9 + taskReturnAddress. */ load_x t0, xTaskReturnAddress store_x t0, 0(a0) /* Return address onto the stack. */ addi t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */ diff --git a/portable/IAR/RISC-V/portASM.s b/portable/IAR/RISC-V/portASM.s index 136464447e..1a7d1c417a 100644 --- a/portable/IAR/RISC-V/portASM.s +++ b/portable/IAR/RISC-V/portASM.s @@ -107,35 +107,35 @@ definitions. */ CODE portUPDATE_MTIMER_COMPARE_REGISTER MACRO - load_x t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */ - load_x t1, pullNextTime /* Load the address of ullNextTime into t1. */ + load_x a0, pullMachineTimerCompareRegister /* Load address of compare register into a0. */ + load_x a1, pullNextTime /* Load the address of ullNextTime into a1. */ #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 to start with - will be overwritten below. */ - 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. */ + li a4, -1 + lw a2, 0(a1) /* Load the low word of ullNextTime into a2. */ + lw a3, 4(a1) /* Load the high word of ullNextTime into a3. */ + sw a4, 0(a0) /* Low word no smaller than old value to start with - will be overwritten below. */ + sw a3, 4(a0) /* Store high word of ullNextTime into compare register. No smaller than new value. */ + sw a2, 0(a0) /* Store low 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?). */ - 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. */ + add a4, t0, a2 /* Add the low word of ullNextTime to the timer increments for one tick (assumes timer increment for one tick fits in 32-bits). */ + sltu t1, a4, a2 /* See if the sum of low words overflowed (what about the zero case?). */ + add t2, a3, t1 /* Add overflow to high word of ullNextTime. */ + sw a4, 0(a1) /* Store new low word of ullNextTime. */ + sw t2, 4(a1) /* Store new high word of ullNextTime. */ #endif /* __riscv_xlen == 32 */ #if( __riscv_xlen == 64 ) /* Update the 64-bit mtimer compare match value. */ - ld t2, 0(t1) /* Load ullNextTime into t2. */ - sd t2, 0(t0) /* Store ullNextTime into compare register. */ + ld t2, 0(a1) /* Load ullNextTime into t2. */ + sd t2, 0(a0) /* Store ullNextTime into compare register. */ ld 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 ullNextTime to the timer increments for one tick. */ - sd t4, 0(t1) /* Store ullNextTime. */ + sd t4, 0(a1) /* Store ullNextTime. */ #endif /* __riscv_xlen == 64 */ ENDM @@ -205,7 +205,7 @@ portUPDATE_MTIMER_COMPARE_REGISTER MACRO * pxCode */ pxPortInitialiseStack: - csrr t0, CSR_MSTATUS /* Obtain current mstatus value. */ + csrr t0, CSR_MSTATUS /* Obtain current mstatus value. */ andi t0, t0, ~0x8 /* Ensure interrupts are disabled when the stack is restored within an ISR. Required when a task is created after the schedulre has been started, otherwise interrupts would be disabled anyway. */ addi t1, x0, 0x188 /* Generate the value 0x1880, which are the MPIE and MPP bits to set in mstatus. */ slli t1, t1, 4 @@ -215,9 +215,13 @@ pxPortInitialiseStack: store_x t0, 0(a0) /* mstatus onto the stack. */ addi a0, a0, -portWORD_SIZE /* Space for critical nesting count. */ store_x x0, 0(a0) /* Critical nesting count starts at 0 for every task. */ - addi a0, a0, -(22 * portWORD_SIZE) /* Space for registers x11-x31. */ +#ifdef __riscv_32e + addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x10-15. */ +#else + addi a0, a0, -(22 * portWORD_SIZE) /* Space for registers x10-x31. */ +#endif store_x a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */ - addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9. */ + addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9 + taskReturnAddress. */ load_x t0, xTaskReturnAddress store_x t0, 0(a0) /* Return address onto the stack. */ addi t0, x0, portasmADDITIONAL_CONTEXT_SIZE /* The number of chip specific additional registers. */ @@ -250,6 +254,7 @@ xPortStartFirstTask: load_x x13, 10 * portWORD_SIZE( sp ) /* a3 */ load_x x14, 11 * portWORD_SIZE( sp ) /* a4 */ load_x x15, 12 * portWORD_SIZE( sp ) /* a5 */ +#ifndef __riscv_32e load_x x16, 13 * portWORD_SIZE( sp ) /* a6 */ load_x x17, 14 * portWORD_SIZE( sp ) /* a7 */ load_x x18, 15 * portWORD_SIZE( sp ) /* s2 */ @@ -266,12 +271,13 @@ xPortStartFirstTask: load_x x29, 26 * portWORD_SIZE( sp ) /* t4 */ load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */ load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */ +#endif - load_x x5, 29 * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */ + load_x x5, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */ load_x x6, pxCriticalNesting /* Load the address of xCriticalNesting into x6. */ store_x x5, 0( x6 ) /* Restore the critical nesting value for this task. */ - load_x x5, 30 * portWORD_SIZE( sp ) /* Initial mstatus into x5 (t0). */ + load_x x5, portMSTATUS_OFFSET * portWORD_SIZE( sp ) /* Initial mstatus into x5 (t0). */ addi x5, x5, 0x08 /* Set MIE bit so the first task starts with interrupts enabled - required as returns with ret not eret. */ csrrw x0, CSR_MSTATUS, x5 /* Interrupts enabled from here! */ diff --git a/portable/IAR/RISC-V/portContext.h b/portable/IAR/RISC-V/portContext.h index 8b883c87bc..b8f8958494 100644 --- a/portable/IAR/RISC-V/portContext.h +++ b/portable/IAR/RISC-V/portContext.h @@ -48,7 +48,15 @@ * portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip * specific version of freertos_risc_v_chip_specific_extensions.h. See the * notes at the top of portASM.S file. */ -#define portCONTEXT_SIZE ( 31 * portWORD_SIZE ) +#ifdef __riscv_32e + #define portCONTEXT_SIZE ( 15 * portWORD_SIZE ) + #define portCRITICAL_NESTING_OFFSET 13 + #define portMSTATUS_OFFSET 14 +#else + #define portCONTEXT_SIZE ( 31 * portWORD_SIZE ) + #define portCRITICAL_NESTING_OFFSET 29 + #define portMSTATUS_OFFSET 30 +#endif EXTERN pxCurrentTCB EXTERN xISRStackTop @@ -71,6 +79,7 @@ portcontextSAVE_CONTEXT_INTERNAL MACRO store_x x13, 10 * portWORD_SIZE( sp ) store_x x14, 11 * portWORD_SIZE( sp ) store_x x15, 12 * portWORD_SIZE( sp ) +#ifndef __riscv_32e store_x x16, 13 * portWORD_SIZE( sp ) store_x x17, 14 * portWORD_SIZE( sp ) store_x x18, 15 * portWORD_SIZE( sp ) @@ -87,12 +96,13 @@ portcontextSAVE_CONTEXT_INTERNAL MACRO store_x x29, 26 * portWORD_SIZE( sp ) store_x x30, 27 * portWORD_SIZE( sp ) store_x x31, 28 * portWORD_SIZE( sp ) +#endif load_x t0, xCriticalNesting /* Load the value of xCriticalNesting into t0. */ - store_x t0, 29 * portWORD_SIZE( sp ) /* Store the critical nesting value to the stack. */ + store_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the critical nesting value to the stack. */ csrr t0, mstatus /* Required for MPIE bit. */ - store_x t0, 30 * portWORD_SIZE( sp ) + store_x t0, portMSTATUS_OFFSET * portWORD_SIZE( sp ) portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */ @@ -123,7 +133,7 @@ portcontextSAVE_INTERRUPT_CONTEXT MACRO portcontextRESTORE_CONTEXT MACRO load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */ - load_x sp, 0( t1 ) /* Read sp from first TCB member. */ + load_x sp, 0( t1 ) /* Read sp from first TCB member. */ /* Load mepc with the address of the instruction in the task to run next. */ load_x t0, 0( sp ) @@ -133,10 +143,10 @@ portcontextRESTORE_CONTEXT MACRO portasmRESTORE_ADDITIONAL_REGISTERS /* Load mstatus with the interrupt enable bits used by the task. */ - load_x t0, 30 * portWORD_SIZE( sp ) + load_x t0, portMSTATUS_OFFSET * portWORD_SIZE( sp ) csrw mstatus, t0 /* Required for MPIE bit. */ - load_x t0, 29 * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */ + 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. */ @@ -152,6 +162,7 @@ portcontextRESTORE_CONTEXT MACRO load_x x13, 10 * portWORD_SIZE( sp ) load_x x14, 11 * portWORD_SIZE( sp ) load_x x15, 12 * portWORD_SIZE( sp ) +#ifndef __riscv_32e load_x x16, 13 * portWORD_SIZE( sp ) load_x x17, 14 * portWORD_SIZE( sp ) load_x x18, 15 * portWORD_SIZE( sp ) @@ -168,6 +179,7 @@ portcontextRESTORE_CONTEXT MACRO load_x x29, 26 * portWORD_SIZE( sp ) load_x x30, 27 * portWORD_SIZE( sp ) load_x x31, 28 * portWORD_SIZE( sp ) +#endif addi sp, sp, portCONTEXT_SIZE mret diff --git a/portable/IAR/RISC-V/portmacro.h b/portable/IAR/RISC-V/portmacro.h index 50e03e2f8f..7aab094c86 100644 --- a/portable/IAR/RISC-V/portmacro.h +++ b/portable/IAR/RISC-V/portmacro.h @@ -82,7 +82,11 @@ typedef portUBASE_TYPE TickType_t; /* Architecture specifics. */ #define portSTACK_GROWTH ( -1 ) #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) -#define portBYTE_ALIGNMENT 16 +#ifdef __riscv_32e + #define portBYTE_ALIGNMENT 8 /* RV32E uses RISC-V EABI with reduced stack alignment requirements. */ +#else + #define portBYTE_ALIGNMENT 16 +#endif /*-----------------------------------------------------------*/ /* Scheduler utilities. */