Skip to content

Commit 9d2571d

Browse files
authored
Cortex-M23: Do not use PSPLIM_NS (#791)
According to Armv8-M technical reference manual, if the main extension is not implemented then PSPLIM_NS is RES0. Update the cortex-M23 port to not use the reserved PSPLIM_NS.
1 parent a695b67 commit 9d2571d

File tree

29 files changed

+833
-145
lines changed

29 files changed

+833
-145
lines changed

portable/ARMv8M/non_secure/port.c

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@
6767
#if ( ( configRUN_FREERTOS_SECURE_ONLY == 1 ) && ( configENABLE_TRUSTZONE == 1 ) )
6868
#error TrustZone needs to be disabled in order to run FreeRTOS on the Secure Side.
6969
#endif
70+
71+
/**
72+
* Cortex-M23 does not have non-secure PSPLIM. We should use PSPLIM on Cortex-M23
73+
* only when FreeRTOS runs on secure side.
74+
*/
75+
#if ( ( portHAS_ARMV8M_MAIN_EXTENSION == 0 ) && ( configRUN_FREERTOS_SECURE_ONLY == 0 ) )
76+
#define portUSE_PSPLIM_REGISTER 0
77+
#else
78+
#define portUSE_PSPLIM_REGISTER 1
79+
#endif
7080
/*-----------------------------------------------------------*/
7181

7282
/**
@@ -1185,11 +1195,19 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
11851195
/* Store the value of the LR and PSPLIM registers before the SVC was raised. We need to
11861196
* restore it when we exit from the system call. */
11871197
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
1188-
__asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) );
1198+
#if ( portUSE_PSPLIM_REGISTER == 1 )
1199+
{
1200+
__asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) );
1201+
}
1202+
#endif
11891203

11901204
/* Use the pulSystemCallStack in thread mode. */
11911205
__asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) );
1192-
__asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) );
1206+
#if ( portUSE_PSPLIM_REGISTER == 1 )
1207+
{
1208+
__asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) );
1209+
}
1210+
#endif
11931211

11941212
/* Remember the location where we should copy the stack frame when we exit from
11951213
* the system call. */
@@ -1316,11 +1334,19 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
13161334
/* Store the value of the LR and PSPLIM registers before the SVC was raised.
13171335
* We need to restore it when we exit from the system call. */
13181336
pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry = pulTaskStack[ portOFFSET_TO_LR ];
1319-
__asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) );
1337+
#if ( portUSE_PSPLIM_REGISTER == 1 )
1338+
{
1339+
__asm volatile ( "mrs %0, psplim" : "=r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) );
1340+
}
1341+
#endif
13201342

13211343
/* Use the pulSystemCallStack in thread mode. */
13221344
__asm volatile ( "msr psp, %0" : : "r" ( pulSystemCallStack ) );
1323-
__asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) );
1345+
#if ( portUSE_PSPLIM_REGISTER == 1 )
1346+
{
1347+
__asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.pulSystemCallStackLimit ) );
1348+
}
1349+
#endif
13241350

13251351
/* Remember the location where we should copy the stack frame when we exit from
13261352
* the system call. */
@@ -1415,7 +1441,11 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
14151441
/* Restore the LR and PSPLIM to what they were at the time of
14161442
* system call entry. */
14171443
pulTaskStack[ portOFFSET_TO_LR ] = pxMpuSettings->xSystemCallStackInfo.ulLinkRegisterAtSystemCallEntry;
1418-
__asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) );
1444+
#if ( portUSE_PSPLIM_REGISTER == 1 )
1445+
{
1446+
__asm volatile ( "msr psplim, %0" : : "r" ( pxMpuSettings->xSystemCallStackInfo.ulStackLimitRegisterAtSystemCallEntry ) );
1447+
}
1448+
#endif
14191449

14201450
/* If the hardware used padding to force the stack pointer
14211451
* to be double word aligned, set the stacked xPSR bit[9],

portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portasm.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@
109109
" ldmia r2!, {r0, r3-r6} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */
110110
" subs r2, #20 \n"
111111
" msr psp, r3 \n"
112-
" msr psplim, r4 \n"
113112
" msr control, r5 \n"
114113
" mov lr, r6 \n"
115114
" ldr r4, xSecureContextConst2 \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
@@ -160,7 +159,6 @@
160159
" ldm r0!, {r1-r3} \n" /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
161160
" ldr r4, xSecureContextConst2 \n"
162161
" str r1, [r4] \n" /* Set xSecureContext to this task's value for the same. */
163-
" msr psplim, r2 \n" /* Set this task's PSPLIM value. */
164162
" movs r1, #2 \n" /* r1 = 2. */
165163
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
166164
" adds r0, #32 \n" /* Discard everything up to r0. */
@@ -324,7 +322,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
324322
" \n"
325323
" save_special_regs: \n"
326324
" mrs r3, psp \n" /* r3 = PSP. */
327-
" mrs r4, psplim \n" /* r4 = PSPLIM. */
325+
" movs r4, #0 \n" /* r4 = 0. 0 is stored in the PSPLIM slot. */
328326
" mrs r5, control \n" /* r5 = CONTROL. */
329327
" mov r6, lr \n" /* r6 = LR. */
330328
" stmia r2!, {r0, r3-r6} \n" /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
@@ -392,7 +390,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
392390
" ldmia r2!, {r0, r3-r6} \n" /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */
393391
" subs r2, #20 \n"
394392
" msr psp, r3 \n"
395-
" msr psplim, r4 \n"
396393
" msr control, r5 \n"
397394
" mov lr, r6 \n"
398395
" ldr r4, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
@@ -467,7 +464,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
467464
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
468465
" subs r2, r2, #12 \n" /* Make space for xSecureContext, PSPLIM and LR on the stack. */
469466
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
470-
" mrs r1, psplim \n" /* r1 = PSPLIM. */
467+
" movs r1, #0 \n" /* r1 = 0. 0 is stored in the PSPLIM slot. */
471468
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
472469
" stmia r2!, {r0, r1, r3} \n" /* Store xSecureContext, PSPLIM and LR on the stack. */
473470
" b select_next_task \n"
@@ -477,7 +474,7 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
477474
" ldr r1, [r3] \n" /* Read pxCurrentTCB. */
478475
" subs r2, r2, #44 \n" /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
479476
" str r2, [r1] \n" /* Save the new top of stack in TCB. */
480-
" mrs r1, psplim \n" /* r1 = PSPLIM. */
477+
" movs r1, #0 \n" /* r1 = 0. 0 is stored in the PSPLIM slot. */
481478
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
482479
" stmia r2!, {r0, r1, r3-r7} \n" /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */
483480
" mov r4, r8 \n" /* r4 = r8. */
@@ -496,7 +493,6 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
496493
" ldr r2, [r1] \n" /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
497494
" \n"
498495
" ldmia r2!, {r0, r1, r4} \n" /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
499-
" msr psplim, r1 \n" /* Restore the PSPLIM register value for the task. */
500496
" mov lr, r4 \n" /* LR = r4. */
501497
" ldr r3, xSecureContextConst \n" /* Read the location of xSecureContext i.e. &( xSecureContext ). */
502498
" str r0, [r3] \n" /* Restore the task's xSecureContext. */

portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portasm.c

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,9 @@
109109
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
110110
" subs r1, #16 \n"
111111
" msr psp, r2 \n"
112-
" msr psplim, r3 \n"
112+
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
113+
" msr psplim, r3 \n"
114+
#endif
113115
" msr control, r4 \n"
114116
" mov lr, r5 \n"
115117
" \n"
@@ -155,7 +157,9 @@
155157
" ldr r0, [r1] \n" /* Read top of stack from TCB - The first item in pxCurrentTCB is the task top of stack. */
156158
" \n"
157159
" ldm r0!, {r1-r2} \n" /* Read from stack - r1 = PSPLIM and r2 = EXC_RETURN. */
158-
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
160+
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
161+
" msr psplim, r1 \n" /* Set this task's PSPLIM value. */
162+
#endif
159163
" movs r1, #2 \n" /* r1 = 2. */
160164
" msr CONTROL, r1 \n" /* Switch to use PSP in the thread mode. */
161165
" adds r0, #32 \n" /* Discard everything up to r0. */
@@ -302,7 +306,11 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
302306
" \n"
303307
" save_special_regs: \n"
304308
" mrs r2, psp \n" /* r2 = PSP. */
305-
" mrs r3, psplim \n" /* r3 = PSPLIM. */
309+
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
310+
" mrs r3, psplim \n" /* r3 = PSPLIM. */
311+
#else
312+
" movs r3, #0 \n" /* r3 = 0. 0 is stored in the PSPLIM slot. */
313+
#endif
306314
" mrs r4, control \n" /* r4 = CONTROL. */
307315
" mov r5, lr \n" /* r5 = LR. */
308316
" stmia r1!, {r2-r5} \n" /* Store original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
@@ -370,7 +378,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
370378
" ldmia r1!, {r2-r5} \n" /* r2 = original PSP, r3 = PSPLIM, r4 = CONTROL, r5 = LR. */
371379
" subs r1, #16 \n"
372380
" msr psp, r2 \n"
373-
" msr psplim, r3 \n"
381+
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
382+
" msr psplim, r3 \n"
383+
#endif
374384
" msr control, r4 \n"
375385
" mov lr, r5 \n"
376386
" \n"
@@ -416,7 +426,11 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
416426
" ldr r1, [r2] \n" /* Read pxCurrentTCB. */
417427
" subs r0, r0, #40 \n" /* Make space for PSPLIM, LR and the remaining registers on the stack. */
418428
" str r0, [r1] \n" /* Save the new top of stack in TCB. */
419-
" mrs r2, psplim \n" /* r2 = PSPLIM. */
429+
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
430+
" mrs r2, psplim \n" /* r2 = PSPLIM. */
431+
#else
432+
" movs r2, #0 \n" /* r2 = 0. 0 is stored in the PSPLIM slot. */
433+
#endif
420434
" mov r3, lr \n" /* r3 = LR/EXC_RETURN. */
421435
" stmia r0!, {r2-r7} \n" /* Store on the stack - PSPLIM, LR and low registers that are not automatically saved. */
422436
" mov r4, r8 \n" /* r4 = r8. */
@@ -442,7 +456,9 @@ void vClearInterruptMask( __attribute__( ( unused ) ) uint32_t ulMask ) /* __att
442456
" msr psp, r0 \n" /* Remember the new top of stack for the task. */
443457
" subs r0, r0, #40 \n" /* Move to the starting of the saved context. */
444458
" ldmia r0!, {r2-r7} \n" /* Read from stack - r2 = PSPLIM, r3 = LR and r4-r7 restored. */
445-
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
459+
#if ( configRUN_FREERTOS_SECURE_ONLY == 1 )
460+
" msr psplim, r2 \n" /* Restore the PSPLIM register value for the task. */
461+
#endif
446462
" bx r3 \n"
447463
" \n"
448464
" .align 4 \n"

portable/ARMv8M/non_secure/portable/IAR/ARM_CM23/portasm.s

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ files (__ICCARM__ is defined by the IAR C compiler but not by the IAR assembler.
3737
#define configUSE_MPU_WRAPPERS_V1 0
3838
#endif
3939

40+
4041
EXTERN pxCurrentTCB
4142
EXTERN xSecureContext
4243
EXTERN vTaskSwitchContext
@@ -167,7 +168,6 @@ vRestoreContextOfFirstTask:
167168
ldmia r2!, {r0, r3-r6} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */
168169
subs r2, #20
169170
msr psp, r3
170-
msr psplim, r4
171171
msr control, r5
172172
mov lr, r6
173173
ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
@@ -203,7 +203,6 @@ vRestoreContextOfFirstTask:
203203
ldm r0!, {r1-r3} /* Read from stack - r1 = xSecureContext, r2 = PSPLIM and r3 = EXC_RETURN. */
204204
ldr r4, =xSecureContext
205205
str r1, [r4] /* Set xSecureContext to this task's value for the same. */
206-
msr psplim, r2 /* Set this task's PSPLIM value. */
207206
movs r1, #2 /* r1 = 2. */
208207
msr CONTROL, r1 /* Switch to use PSP in the thread mode. */
209208
adds r0, #32 /* Discard everything up to r0. */
@@ -279,7 +278,7 @@ PendSV_Handler:
279278

280279
save_special_regs:
281280
mrs r3, psp /* r3 = PSP. */
282-
mrs r4, psplim /* r4 = PSPLIM. */
281+
movs r4, #0 /* r4 = 0. 0 is stored in the PSPLIM slot. */
283282
mrs r5, control /* r5 = CONTROL. */
284283
mov r6, lr /* r6 = LR. */
285284
stmia r2!, {r0, r3-r6} /* Store xSecureContext, original PSP (after hardware has saved context), PSPLIM, CONTROL and LR. */
@@ -347,7 +346,6 @@ PendSV_Handler:
347346
ldmia r2!, {r0, r3-r6} /* r0 = xSecureContext, r3 = original PSP, r4 = PSPLIM, r5 = CONTROL, r6 = LR. */
348347
subs r2, #20
349348
msr psp, r3
350-
msr psplim, r4
351349
msr control, r5
352350
mov lr, r6
353351
ldr r4, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
@@ -406,7 +404,7 @@ PendSV_Handler:
406404

407405
subs r2, r2, #12 /* Make space for xSecureContext, PSPLIM and LR on the stack. */
408406
str r2, [r1] /* Save the new top of stack in TCB. */
409-
mrs r1, psplim /* r1 = PSPLIM. */
407+
movs r1, #0 /* r1 = 0. 0 is stored in the PSPLIM slot. */
410408
mov r3, lr /* r3 = LR/EXC_RETURN. */
411409
stmia r2!, {r0, r1, r3} /* Store xSecureContext, PSPLIM and LR on the stack. */
412410

@@ -417,7 +415,7 @@ PendSV_Handler:
417415
ldr r1, [r3] /* Read pxCurrentTCB. */
418416
subs r2, r2, #44 /* Make space for xSecureContext, PSPLIM, LR and the remaining registers on the stack. */
419417
str r2, [r1] /* Save the new top of stack in TCB. */
420-
mrs r1, psplim /* r1 = PSPLIM. */
418+
movs r1, #0 /* r1 = 0. 0 is stored in the PSPLIM slot. */
421419
mov r3, lr /* r3 = LR/EXC_RETURN. */
422420
stmia r2!, {r0, r1, r3-r7} /* Store xSecureContext, PSPLIM, LR and the low registers that are not saved automatically. */
423421
mov r4, r8 /* r4 = r8. */
@@ -436,7 +434,6 @@ PendSV_Handler:
436434
ldr r2, [r1] /* The first item in pxCurrentTCB is the task top of stack. r2 now points to the top of stack. */
437435

438436
ldmia r2!, {r0, r1, r4} /* Read from stack - r0 = xSecureContext, r1 = PSPLIM and r4 = LR. */
439-
msr psplim, r1 /* Restore the PSPLIM register value for the task. */
440437
mov lr, r4 /* LR = r4. */
441438
ldr r3, =xSecureContext /* Read the location of xSecureContext i.e. &( xSecureContext ). */
442439
str r0, [r3] /* Restore the task's xSecureContext. */

0 commit comments

Comments
 (0)