Skip to content

Commit d91cd6f

Browse files
Limoton9wxu
andauthored
RISC-V: Add support for RV32E extension in GCC port (#543)
Co-authored-by: Joseph Julicher <jjulicher@mac.com>
1 parent dc8f8be commit d91cd6f

File tree

3 files changed

+50
-24
lines changed

3 files changed

+50
-24
lines changed

portable/GCC/RISC-V/portASM.S

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -98,35 +98,35 @@ definitions. */
9898
/*-----------------------------------------------------------*/
9999

100100
.macro portUPDATE_MTIMER_COMPARE_REGISTER
101-
load_x t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */
102-
load_x t1, pullNextTime /* Load the address of ullNextTime into t1. */
101+
load_x a0, pullMachineTimerCompareRegister /* Load address of compare register into a0. */
102+
load_x a1, pullNextTime /* Load the address of ullNextTime into a1. */
103103

104104
#if( __riscv_xlen == 32 )
105105

106106
/* Update the 64-bit mtimer compare match value in two 32-bit writes. */
107-
li t4, -1
108-
lw t2, 0(t1) /* Load the low word of ullNextTime into t2. */
109-
lw t3, 4(t1) /* Load the high word of ullNextTime into t3. */
110-
sw t4, 0(t0) /* Low word no smaller than old value to start with - will be overwritten below. */
111-
sw t3, 4(t0) /* Store high word of ullNextTime into compare register. No smaller than new value. */
112-
sw t2, 0(t0) /* Store low word of ullNextTime into compare register. */
107+
li a4, -1
108+
lw a2, 0(a1) /* Load the low word of ullNextTime into a2. */
109+
lw a3, 4(a1) /* Load the high word of ullNextTime into a3. */
110+
sw a4, 0(a0) /* Low word no smaller than old value to start with - will be overwritten below. */
111+
sw a3, 4(a0) /* Store high word of ullNextTime into compare register. No smaller than new value. */
112+
sw a2, 0(a0) /* Store low word of ullNextTime into compare register. */
113113
lw t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */
114-
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). */
115-
sltu t5, t4, t2 /* See if the sum of low words overflowed (what about the zero case?). */
116-
add t6, t3, t5 /* Add overflow to high word of ullNextTime. */
117-
sw t4, 0(t1) /* Store new low word of ullNextTime. */
118-
sw t6, 4(t1) /* Store new high word of ullNextTime. */
114+
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). */
115+
sltu t1, a4, a2 /* See if the sum of low words overflowed (what about the zero case?). */
116+
add t2, a3, t1 /* Add overflow to high word of ullNextTime. */
117+
sw a4, 0(a1) /* Store new low word of ullNextTime. */
118+
sw t2, 4(a1) /* Store new high word of ullNextTime. */
119119

120120
#endif /* __riscv_xlen == 32 */
121121

122122
#if( __riscv_xlen == 64 )
123123

124124
/* Update the 64-bit mtimer compare match value. */
125-
ld t2, 0(t1) /* Load ullNextTime into t2. */
126-
sd t2, 0(t0) /* Store ullNextTime into compare register. */
125+
ld t2, 0(a1) /* Load ullNextTime into t2. */
126+
sd t2, 0(a0) /* Store ullNextTime into compare register. */
127127
ld t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */
128128
add t4, t0, t2 /* Add ullNextTime to the timer increments for one tick. */
129-
sd t4, 0(t1) /* Store ullNextTime. */
129+
sd t4, 0(a1) /* Store ullNextTime. */
130130

131131
#endif /* __riscv_xlen == 64 */
132132
.endm
@@ -206,7 +206,12 @@ pxPortInitialiseStack:
206206
store_x t0, 0(a0) /* mstatus onto the stack. */
207207
addi a0, a0, -portWORD_SIZE /* Space for critical nesting count. */
208208
store_x x0, 0(a0) /* Critical nesting count starts at 0 for every task. */
209+
210+
#ifdef __riscv_32e
211+
addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x11-x15. */
212+
#else
209213
addi a0, a0, -(22 * portWORD_SIZE) /* Space for registers x11-x31. */
214+
#endif
210215
store_x a2, 0(a0) /* Task parameters (pvParameters parameter) goes into register X10/a0 on the stack. */
211216
addi a0, a0, -(6 * portWORD_SIZE) /* Space for registers x5-x9. */
212217
load_x t0, xTaskReturnAddress
@@ -241,6 +246,7 @@ xPortStartFirstTask:
241246
load_x x13, 10 * portWORD_SIZE( sp ) /* a3 */
242247
load_x x14, 11 * portWORD_SIZE( sp ) /* a4 */
243248
load_x x15, 12 * portWORD_SIZE( sp ) /* a5 */
249+
#ifndef __riscv_32e
244250
load_x x16, 13 * portWORD_SIZE( sp ) /* a6 */
245251
load_x x17, 14 * portWORD_SIZE( sp ) /* a7 */
246252
load_x x18, 15 * portWORD_SIZE( sp ) /* s2 */
@@ -257,12 +263,13 @@ xPortStartFirstTask:
257263
load_x x29, 26 * portWORD_SIZE( sp ) /* t4 */
258264
load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */
259265
load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */
266+
#endif
260267

261-
load_x x5, 29 * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */
268+
load_x x5, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */
262269
load_x x6, pxCriticalNesting /* Load the address of xCriticalNesting into x6. */
263270
store_x x5, 0( x6 ) /* Restore the critical nesting value for this task. */
264271

265-
load_x x5, 30 * portWORD_SIZE( sp ) /* Initial mstatus into x5 (t0). */
272+
load_x x5, portMSTATUS_OFFSET * portWORD_SIZE( sp ) /* Initial mstatus into x5 (t0). */
266273
addi x5, x5, 0x08 /* Set MIE bit so the first task starts with interrupts enabled - required as returns with ret not eret. */
267274
csrrw x0, mstatus, x5 /* Interrupts enabled from here! */
268275

portable/GCC/RISC-V/portContext.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,16 @@
4848
* portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip
4949
* specific version of freertos_risc_v_chip_specific_extensions.h. See the
5050
* notes at the top of portASM.S file. */
51-
#define portCONTEXT_SIZE ( 31 * portWORD_SIZE )
51+
#ifdef __riscv_32e
52+
#define portCONTEXT_SIZE ( 15 * portWORD_SIZE )
53+
#define portCRITICAL_NESTING_OFFSET 13
54+
#define portMSTATUS_OFFSET 14
55+
#else
56+
#define portCONTEXT_SIZE ( 31 * portWORD_SIZE )
57+
#define portCRITICAL_NESTING_OFFSET 29
58+
#define portMSTATUS_OFFSET 30
59+
#endif
60+
5261
/*-----------------------------------------------------------*/
5362

5463
.extern pxCurrentTCB
@@ -71,6 +80,7 @@
7180
store_x x13, 10 * portWORD_SIZE( sp )
7281
store_x x14, 11 * portWORD_SIZE( sp )
7382
store_x x15, 12 * portWORD_SIZE( sp )
83+
#ifndef __riscv_32e
7484
store_x x16, 13 * portWORD_SIZE( sp )
7585
store_x x17, 14 * portWORD_SIZE( sp )
7686
store_x x18, 15 * portWORD_SIZE( sp )
@@ -87,12 +97,15 @@
8797
store_x x29, 26 * portWORD_SIZE( sp )
8898
store_x x30, 27 * portWORD_SIZE( sp )
8999
store_x x31, 28 * portWORD_SIZE( sp )
100+
#endif
90101

91102
load_x t0, xCriticalNesting /* Load the value of xCriticalNesting into t0. */
92-
store_x t0, 29 * portWORD_SIZE( sp ) /* Store the critical nesting value to the stack. */
103+
store_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the critical nesting value to the stack. */
104+
93105

94106
csrr t0, mstatus /* Required for MPIE bit. */
95-
store_x t0, 30 * portWORD_SIZE( sp )
107+
store_x t0, portMSTATUS_OFFSET * portWORD_SIZE( sp )
108+
96109

97110
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
98111

@@ -133,10 +146,10 @@
133146
portasmRESTORE_ADDITIONAL_REGISTERS
134147

135148
/* Load mstatus with the interrupt enable bits used by the task. */
136-
load_x t0, 30 * portWORD_SIZE( sp )
149+
load_x t0, portMSTATUS_OFFSET * portWORD_SIZE( sp )
137150
csrw mstatus, t0 /* Required for MPIE bit. */
138151

139-
load_x t0, 29 * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */
152+
load_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */
140153
load_x t1, pxCriticalNesting /* Load the address of xCriticalNesting into t1. */
141154
store_x t0, 0( t1 ) /* Restore the critical nesting value for this task. */
142155

@@ -152,6 +165,7 @@
152165
load_x x13, 10 * portWORD_SIZE( sp )
153166
load_x x14, 11 * portWORD_SIZE( sp )
154167
load_x x15, 12 * portWORD_SIZE( sp )
168+
#ifndef __riscv_32e
155169
load_x x16, 13 * portWORD_SIZE( sp )
156170
load_x x17, 14 * portWORD_SIZE( sp )
157171
load_x x18, 15 * portWORD_SIZE( sp )
@@ -168,6 +182,7 @@
168182
load_x x29, 26 * portWORD_SIZE( sp )
169183
load_x x30, 27 * portWORD_SIZE( sp )
170184
load_x x31, 28 * portWORD_SIZE( sp )
185+
#endif
171186
addi sp, sp, portCONTEXT_SIZE
172187

173188
mret

portable/GCC/RISC-V/portmacro.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,11 @@ typedef portUBASE_TYPE TickType_t;
8080
/* Architecture specifics. */
8181
#define portSTACK_GROWTH ( -1 )
8282
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
83-
#define portBYTE_ALIGNMENT 16
83+
#ifdef __riscv_32e
84+
#define portBYTE_ALIGNMENT 8 /* RV32E uses RISC-V EABI with reduced stack alignment requirements */
85+
#else
86+
#define portBYTE_ALIGNMENT 16
87+
#endif
8488
/*-----------------------------------------------------------*/
8589

8690
/* Scheduler utilities. */

0 commit comments

Comments
 (0)