Skip to content

Commit

Permalink
M2354: Support baremetal profile (#419)
Browse files Browse the repository at this point in the history
* M2354: Add baremetal profile support into targets.json5

* 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
  • Loading branch information
ccli8 authored Jan 12, 2025
1 parent 32098dc commit ceee63f
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 23 deletions.
77 changes: 54 additions & 23 deletions targets/TARGET_NUVOTON/TARGET_M2354/TARGET_TFM/tfm_ns_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,20 +40,26 @@
* For the 'lock kernel scheduler' approach to work thoroughly, we must also
* address some side issues:
*
* - Prohibit NS secure call from ISR except SVC, so non-preemptive doesn't break.
* - Allow NS secure call in SVC context because it is synchronous. Here, we lock
* interrupt instead of kernel scheduler because svcRtxKernelLock()/svcRtxKernelRestoreLock(...)
* are inaccessible outside rtx_kernel.c. Currently, this is rare case and would cause
* little trouble (see known paths below).
* - Call into secure world straight in interrupt-disabled context. When in
* interrupt-disabled context, NS secure call is guaranteed to be non-preemptive
* naturally.
* - Call into secure world straight at pre-rtos stage. When at pre-rtos stage,
* - NOT SUPPORT NS secure call from ISR except SVC (rtos/baremetal)
* - Support NS secure call in SVC context conditionally (rtos/baremetal)
* - For rtos profile, lock interrupt instead of kernel scheduler because
* svcRtxKernelLock()/svcRtxKernelRestoreLock(...) are inaccessible
* outside rtx_kernel.c. Currently, this is rare case and would cause
* little trouble (see known paths below).
* - For baremetal profile, NS secure call is guaranteed to be non-preemptive
* naturally.
* NOTE: However, per test, TF-M doesn't allow call in SVC context anymore.
* It will trap this as error and possibly reboot the system, except for
* secure context calls like TZ_InitContextSystem_S and firends.
* - Call into secure world straight in interrupt-disabled context (rtos/baremetal)
* NS secure call is guaranteed to be non-preemptive naturally.
* - osKernelLock() will error when kernel state is 'osKernelSuspended'. Address
* it separately. Known path of NS secure call when kernel state is 'osKernelSuspended':
* - default idle thread > osKernelSuspend() > lp_ticker_init > SYS_ResetModule_S/
* CLK_SetModuleClock_S/CLK_EnableModuleClock_S
* - Call into secure world straight at pre-rtos stage (rtos)
* NS secure call is guaranteed to be non-preemptive naturally.
* - osKernelLock() will error when kernel state is 'osKernelSuspended' (rtos).
* Address it separately. Known path of NS secure call when kernel state is
* 'osKernelSuspended':
* default idle thread > osKernelSuspend() > lp_ticker_init > SYS_ResetModule_S/
* CLK_SetModuleClock_S/CLK_EnableModuleClock_S
*
* Known paths of NS secure call in interrupt-disabled context:
* - mbed-os/platform/mbed_sleep_manager.c > sleep_manager_sleep_auto >
Expand All @@ -65,9 +71,10 @@
* CLK_IsRTCClockEnabled_S
*
* Known paths of NS secure call in SVC context:
* - In tickless mode, osKernelStart > svcRtxKernelStart > OS_Tick_Enable >
* - In MBED_TICKLESS mode, osKernelStart > svcRtxKernelStart > OS_Tick_Enable >
* us_ticker_init/lp_ticker_init > SYS_ResetModule_S/CLK_SetModuleClock_S/
* CLK_EnableModuleClock_S
* NOTE: Per above SVC test, this means MBED_TICKLESS mode is not supported.
*/

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

return result;
#else
/*
* Call into secure world straight for baremetal because NS secure
* call is non-preemptive naturally
*/
return fn(arg0, arg1, arg2, arg3);
#endif
} else if (ipsr) {
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_KERNEL, MBED_ERROR_CODE_PROHIBITED_IN_ISR_CONTEXT), "Prohibited in ISR context", (uintptr_t) fn);
}

/* Call into secure world straight in interrupt-disabled context because
* NS secure call is non-preemptive naturally */
/*
* Call into secure world straight in interrupt-disabled context because
* NS secure call is non-preemptive naturally
*/
if (!core_util_are_interrupts_enabled()) {
return fn(arg0, arg1, arg2, arg3);
}

#if MBED_CONF_RTOS_PRESENT
osKernelState_t kernel_state = osKernelGetState();

/* Call into secure world straight at pre-rtos stage because NS secure
* call is non-preemptive naturally */
/*
* Call into secure world straight at pre-rtos stage because NS secure
* call is non-preemptive naturally
*/
if (kernel_state == osKernelInactive || kernel_state == osKernelReady) {
return fn(arg0, arg1, arg2, arg3);
}

/* osKernelLock() will error when kernel state is 'osKernelSuspended'. Address
* it separately. */
/*
* osKernelLock() will error when kernel state is 'osKernelSuspended'. Address
* it separately.
*/
if (kernel_state == osKernelSuspended) {
return fn(arg0, arg1, arg2, arg3);
} else if (kernel_state == osKernelError) {
Expand All @@ -139,6 +163,13 @@ int32_t tfm_ns_interface_dispatch(veneer_fn fn,
MBED_ASSERT(lock_state >= 0);

return result;
#else
/*
* Call into secure world straight for baremetal because NS secure
* call is non-preemptive naturally
*/
return fn(arg0, arg1, arg2, arg3);
#endif
}

/* Override tfm_ns_lock_init()
Expand Down
3 changes: 3 additions & 0 deletions targets/targets.json5
Original file line number Diff line number Diff line change
Expand Up @@ -8232,6 +8232,9 @@
],
"bootloader_supported": true,
"forced_reset_timeout": 5,
"supported_application_profiles": [
"full", "bare-metal"
],
"is_mcu_family_target": true
},
"NU_M2354": { // AKA NUMAKER-M2354
Expand Down

0 comments on commit ceee63f

Please sign in to comment.