Skip to content

Commit 7798c34

Browse files
committed
M2354: Fix NS secure call in baremetal profile and SVC context
1. Support NS secure call in baremetal profile 2. Update comment on NS secure call in SVC context
1 parent 24eee35 commit 7798c34

File tree

1 file changed

+54
-23
lines changed

1 file changed

+54
-23
lines changed

targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/tfm_ns_interface.c

Lines changed: 54 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,26 @@
4040
* For the 'lock kernel scheduler' approach to work thoroughly, we must also
4141
* address some side issues:
4242
*
43-
* - Prohibit NS secure call from ISR except SVC, so non-preemptive doesn't break.
44-
* - Allow NS secure call in SVC context because it is synchronous. Here, we lock
45-
* interrupt instead of kernel scheduler because svcRtxKernelLock()/svcRtxKernelRestoreLock(...)
46-
* are inaccessible outside rtx_kernel.c. Currently, this is rare case and would cause
47-
* little trouble (see known paths below).
48-
* - Call into secure world straight in interrupt-disabled context. When in
49-
* interrupt-disabled context, NS secure call is guaranteed to be non-preemptive
50-
* naturally.
51-
* - Call into secure world straight at pre-rtos stage. When at pre-rtos stage,
43+
* - NOT SUPPORT NS secure call from ISR except SVC (rtos/baremetal)
44+
* - Support NS secure call in SVC context conditionally (rtos/baremetal)
45+
* - For rtos profile, lock interrupt instead of kernel scheduler because
46+
* svcRtxKernelLock()/svcRtxKernelRestoreLock(...) are inaccessible
47+
* outside rtx_kernel.c. Currently, this is rare case and would cause
48+
* little trouble (see known paths below).
49+
* - For baremetal profile, NS secure call is guaranteed to be non-preemptive
50+
* naturally.
51+
* NOTE: However, per test, TF-M doesn't allow call in SVC context anymore.
52+
* It will trap this as error and possibly reboot the system, except for
53+
* secure context calls like TZ_InitContextSystem_S and firends.
54+
* - Call into secure world straight in interrupt-disabled context (rtos/baremetal)
5255
* NS secure call is guaranteed to be non-preemptive naturally.
53-
* - osKernelLock() will error when kernel state is 'osKernelSuspended'. Address
54-
* it separately. Known path of NS secure call when kernel state is 'osKernelSuspended':
55-
* - default idle thread > osKernelSuspend() > lp_ticker_init > SYS_ResetModule_S/
56-
* CLK_SetModuleClock_S/CLK_EnableModuleClock_S
56+
* - Call into secure world straight at pre-rtos stage (rtos)
57+
* NS secure call is guaranteed to be non-preemptive naturally.
58+
* - osKernelLock() will error when kernel state is 'osKernelSuspended' (rtos).
59+
* Address it separately. Known path of NS secure call when kernel state is
60+
* 'osKernelSuspended':
61+
* default idle thread > osKernelSuspend() > lp_ticker_init > SYS_ResetModule_S/
62+
* CLK_SetModuleClock_S/CLK_EnableModuleClock_S
5763
*
5864
* Known paths of NS secure call in interrupt-disabled context:
5965
* - mbed-os/platform/mbed_sleep_manager.c > sleep_manager_sleep_auto >
@@ -65,9 +71,10 @@
6571
* CLK_IsRTCClockEnabled_S
6672
*
6773
* Known paths of NS secure call in SVC context:
68-
* - In tickless mode, osKernelStart > svcRtxKernelStart > OS_Tick_Enable >
74+
* - In MBED_TICKLESS mode, osKernelStart > svcRtxKernelStart > OS_Tick_Enable >
6975
* us_ticker_init/lp_ticker_init > SYS_ResetModule_S/CLK_SetModuleClock_S/
7076
* CLK_EnableModuleClock_S
77+
* NOTE: Per above SVC test, this means MBED_TICKLESS mode is not supported.
7178
*/
7279

7380
struct ns_interface_state
@@ -87,34 +94,51 @@ int32_t tfm_ns_interface_dispatch(veneer_fn fn,
8794
/* Prohibit NS secure call from ISR except SVC, so non-preemptive doesn't break */
8895
uint32_t ipsr = __get_IPSR();
8996
if (ipsr == 11U) {
90-
/* Allow NS secure call in SVC context because it is synchronous. Here,
91-
* we lock interrupt instead of kernel scheduler because svcRtxKernelLock()/
92-
* svcRtxKernelRestoreLock(...) are inaccessible outside rtx_kernel.c. */
97+
/* Support NS secure call in SVC context */
98+
#if MBED_CONF_RTOS_PRESENT
99+
/*
100+
* Lock interrupt instead of kernel scheduler because svcRtxKernelLock()/
101+
* svcRtxKernelRestoreLock(...) are inaccessible outside rtx_kernel.c
102+
*/
93103
core_util_critical_section_enter();
94104
int32_t result = fn(arg0, arg1, arg2, arg3);
95105
core_util_critical_section_exit();
96106

97107
return result;
108+
#else
109+
/*
110+
* Call into secure world straight for baremetal because NS secure
111+
* call is non-preemptive naturally
112+
*/
113+
return fn(arg0, arg1, arg2, arg3);
114+
#endif
98115
} else if (ipsr) {
99116
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_PROHIBITED_IN_ISR_CONTEXT), "Prohibited in ISR context", (uintptr_t) fn);
100117
}
101118

102-
/* Call into secure world straight in interrupt-disabled context because
103-
* NS secure call is non-preemptive naturally */
119+
/*
120+
* Call into secure world straight in interrupt-disabled context because
121+
* NS secure call is non-preemptive naturally
122+
*/
104123
if (!core_util_are_interrupts_enabled()) {
105124
return fn(arg0, arg1, arg2, arg3);
106125
}
107126

127+
#if MBED_CONF_RTOS_PRESENT
108128
osKernelState_t kernel_state = osKernelGetState();
109129

110-
/* Call into secure world straight at pre-rtos stage because NS secure
111-
* call is non-preemptive naturally */
130+
/*
131+
* Call into secure world straight at pre-rtos stage because NS secure
132+
* call is non-preemptive naturally
133+
*/
112134
if (kernel_state == osKernelInactive || kernel_state == osKernelReady) {
113135
return fn(arg0, arg1, arg2, arg3);
114136
}
115137

116-
/* osKernelLock() will error when kernel state is 'osKernelSuspended'. Address
117-
* it separately. */
138+
/*
139+
* osKernelLock() will error when kernel state is 'osKernelSuspended'. Address
140+
* it separately.
141+
*/
118142
if (kernel_state == osKernelSuspended) {
119143
return fn(arg0, arg1, arg2, arg3);
120144
} else if (kernel_state == osKernelError) {
@@ -139,6 +163,13 @@ int32_t tfm_ns_interface_dispatch(veneer_fn fn,
139163
MBED_ASSERT(lock_state >= 0);
140164

141165
return result;
166+
#else
167+
/*
168+
* Call into secure world straight for baremetal because NS secure
169+
* call is non-preemptive naturally
170+
*/
171+
return fn(arg0, arg1, arg2, arg3);
172+
#endif
142173
}
143174

144175
/* Override tfm_ns_lock_init()

0 commit comments

Comments
 (0)