111
111
#define MSTATUS_VS_CLEAN 0x400
112
112
#define MSTATUS_VS_DIRTY 0x600
113
113
#define MSTATUS_VS_OFFSET 9
114
+
114
115
#ifndef __riscv_vector
115
116
#error configENABLE_VPU must not be set to 1 if the hardware does not have VPU
116
117
#endif
@@ -204,57 +205,68 @@ addi sp, sp, ( portFPU_CONTEXT_SIZE )
204
205
/*-----------------------------------------------------------*/
205
206
206
207
.macro portcontexSAVE_VPU_CONTEXT
207
- /* Store the vector registers on groups of 8. Use the length in bytes (vlenb)
208
- to know how much space they need and reserve it in the stack. */
209
- csrr t0 , vlenb
210
- slli t0 , t0 , 3 /* vlenb * 8 */
211
- neg t0 , t0
212
- /* Store the vector registers. */
208
+ /* Un-reserve the space reserved for mstatus and epc. */
209
+ add sp , sp , ( 2 * portWORD_SIZE )
210
+
211
+ csrr t0 , vlenb /* t0 = vlenb. vlenb is the length of each vector register in bytes. */
212
+ slli t0 , t0 , 3 /* t0 = vlenb * 8. t0 now contains the space required to store 8 vector registers. */
213
+ neg t0 , t0
214
+
215
+ /* Store the vector registers in group of 8. */
213
216
add sp , sp , t0
214
- vs8r .v v0 , (sp )
217
+ vs8r .v v0 , (sp ) /* Store v0-v7. */
215
218
add sp , sp , t0
216
- vs8r .v v8 , (sp )
219
+ vs8r .v v8 , (sp ) /* Store v8-v15. */
217
220
add sp , sp , t0
218
- vs8r .v v16 , (sp )
221
+ vs8r .v v16 , (sp ) /* Store v16-v23. */
219
222
add sp , sp , t0
220
- vs8r .v v24 , (sp )
221
- /* Store the VPU registers. */
222
- addi sp , sp , - ( 4 * portWORD_SIZE )
223
- csrr t0 , vstart
223
+ vs8r .v v24 , (sp ) /* Store v24-v31. */
224
+
225
+ /* Store the VPU CSRs. */
226
+ addi sp , sp , - ( 4 * portWORD_SIZE )
227
+ csrr t0 , vstart
224
228
store_x t0 , 0 * portWORD_SIZE ( sp )
225
229
csrr t0 , vcsr
226
230
store_x t0 , 1 * portWORD_SIZE ( sp )
227
231
csrr t0 , vl
228
232
store_x t0 , 2 * portWORD_SIZE ( sp )
229
233
csrr t0 , vtype
230
234
store_x t0 , 3 * portWORD_SIZE ( sp )
235
+
236
+ /* Re-reserve the space for mstatus and epc. */
237
+ add sp , sp , - ( 2 * portWORD_SIZE )
231
238
.endm
232
239
/*-----------------------------------------------------------*/
233
240
234
241
.macro portcontextRESTORE_VPU_CONTEXT
235
- /* Restore the VPU registers. */
236
- load_x t0 , 0 * portWORD_SIZE ( sp )
242
+ /* Un-reserve the space reserved for mstatus and epc. */
243
+ add sp , sp , ( 2 * portWORD_SIZE )
244
+
245
+ /* Restore the VPU CSRs. */
246
+ load_x t0 , 0 * portWORD_SIZE ( sp )
237
247
csrw vstart , t0
238
- load_x t0 , 1 * portWORD_SIZE ( sp )
248
+ load_x t0 , 1 * portWORD_SIZE ( sp )
239
249
csrw vcsr , t0
240
- load_x t0 , 2 * portWORD_SIZE ( sp )
241
- load_x t1 , 3 * portWORD_SIZE ( sp )
242
- /* vlen and vtype can only be updated by using vset*vl* instructions. */
243
- vsetvl x0 , t0 , t1
244
- addi sp , sp , ( 4 * portWORD_SIZE )
245
- /* Load the vector registers on groups of 8. Use the length in bytes (vlenb)
246
- to know how much space they use. */
247
- csrr t0 , vlenb
248
- slli t0 , t0 , 3 /* vlenb * 8 */
250
+ load_x t0 , 2 * portWORD_SIZE ( sp )
251
+ load_x t1 , 3 * portWORD_SIZE ( sp )
252
+ vsetvl x0 , t0 , t1 /* vlen and vtype can only be updated by using vset*vl* instructions. */
253
+ addi sp , sp , ( 4 * portWORD_SIZE )
254
+
255
+ csrr t0 , vlenb /* t0 = vlenb. vlenb is the length of each vector register in bytes. */
256
+ slli t0 , t0 , 3 /* t0 = vlenb * 8. t0 now contains the space required to store 8 vector registers. */
257
+
249
258
/* Restore the vector registers. */
250
259
vl8r .v v24 , (sp )
251
- add sp , sp , t0
260
+ add sp , sp , t0
252
261
vl8r .v v16 , (sp )
253
- add sp , sp , t0
262
+ add sp , sp , t0
254
263
vl8r .v v8 , (sp )
255
- add sp , sp , t0
264
+ add sp , sp , t0
256
265
vl8r .v v0 , (sp )
257
- add sp , sp , t0
266
+ add sp , sp , t0
267
+
268
+ /* Re-reserve the space for mstatus and epc. */
269
+ add sp , sp , - ( 2 * portWORD_SIZE )
258
270
.endm
259
271
/*-----------------------------------------------------------*/
260
272
@@ -310,10 +322,10 @@ store_x t0, portCRITICAL_NESTING_OFFSET * portWORD_SIZE( sp ) /* Store the criti
310
322
srl t1 , t0 , MSTATUS_VS_OFFSET
311
323
andi t1 , t1 , 3
312
324
addi t2 , x0 , 3
313
- bne t1 , t2 , 1f /* If VPU status is not dirty, do not save FPU registers. */
325
+ bne t1 , t2 , 2f /* If VPU status is not dirty, do not save FPU registers. */
314
326
315
327
portcontexSAVE_VPU_CONTEXT
316
- 1 :
328
+ 2 :
317
329
#endif
318
330
319
331
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
@@ -326,29 +338,29 @@ store_x t0, 1 * portWORD_SIZE( sp )
326
338
srl t1 , t0 , MSTATUS_FS_OFFSET
327
339
andi t1 , t1 , 3
328
340
addi t2 , x0 , 3
329
- bne t1 , t2 , 2f
341
+ bne t1 , t2 , 3f
330
342
331
343
li t1 , ~MSTATUS_FS_MASK
332
344
and t0 , t0 , t1
333
345
li t1 , MSTATUS_FS_CLEAN
334
346
or t0 , t0 , t1
335
347
csrw mstatus , t0
336
- 2 :
348
+ 3 :
337
349
#endif
338
350
339
351
#if ( configENABLE_VPU == 1 )
340
352
/* Mark the VPU as clean, if it was dirty and we saved VPU registers. */
341
353
srl t1 , t0 , MSTATUS_VS_OFFSET
342
354
andi t1 , t1 , 3
343
355
addi t2 , x0 , 3
344
- bne t1 , t2 , 2f
356
+ bne t1 , t2 , 4f
345
357
346
358
li t1 , ~MSTATUS_VS_MASK
347
359
and t0 , t0 , t1
348
360
li t1 , MSTATUS_VS_CLEAN
349
361
or t0 , t0 , t1
350
362
csrw mstatus , t0
351
- 2 :
363
+ 4 :
352
364
#endif
353
365
354
366
load_x t0 , pxCurrentTCB /* Load pxCurrentTCB. */
@@ -396,21 +408,21 @@ portasmRESTORE_ADDITIONAL_REGISTERS
396
408
srl t1 , t0 , MSTATUS_VS_OFFSET
397
409
andi t1 , t1 , 3
398
410
addi t2 , x0 , 3
399
- bne t1 , t2 , 3f /* If VPU status is not dirty, do not restore VPU registers. */
411
+ bne t1 , t2 , 5f /* If VPU status is not dirty, do not restore VPU registers. */
400
412
401
413
portcontextRESTORE_VPU_CONTEXT
402
- 3 :
414
+ 5 :
403
415
#endif /* ifdef portasmSTORE_VPU_CONTEXT */
404
416
405
417
#if ( configENABLE_FPU == 1 )
406
418
csrr t0 , mstatus
407
419
srl t1 , t0 , MSTATUS_FS_OFFSET
408
420
andi t1 , t1 , 3
409
421
addi t2 , x0 , 3
410
- bne t1 , t2 , 3f /* If FPU status is not dirty, do not restore FPU registers. */
422
+ bne t1 , t2 , 6f /* If FPU status is not dirty, do not restore FPU registers. */
411
423
412
424
portcontextRESTORE_FPU_CONTEXT
413
- 3 :
425
+ 6 :
414
426
#endif /* ifdef portasmSTORE_FPU_CONTEXT */
415
427
416
428
load_x t0 , portCRITICAL_NESTING_OFFSET * portWORD_SIZE ( sp ) /* Obtain xCriticalNesting value for this task from task's stack. */
0 commit comments