diff options
author | Ken Liu <Ken.Liu@arm.com> | 2021-05-12 17:54:48 +0800 |
---|---|---|
committer | Shawn Shan <Shawn.Shan@arm.com> | 2021-09-17 10:12:17 +0800 |
commit | ce58bfc1dd16672a1d6d284a85b98ecefb44c0cc (patch) | |
tree | 7f5172cb5bbc1184c79b3c59485a547e6aed2d2a /secure_fw | |
parent | 2089b2dc58aa9e590080d45f43c3cf1c1b42d8bb (diff) | |
download | trusted-firmware-m-ce58bfc1dd16672a1d6d284a85b98ecefb44c0cc.tar.gz |
Plaform: AN521: Introduce platform binding HAL
This API (tfm_hal_bind_boundaries) binds partition with platform by
a p_boundaries handle, to let platform records partition info and
apply specific settings. Check the API comment for details.
The patch also:
- Updates the boundary update HAL API.
- Updates the HAL design document.
- Removes the FIH on AN521.
Change-Id: I77bba50d16fc6bb034aff3f4a7a8dfefecf345ec
Signed-off-by: Ken Liu <Ken.Liu@arm.com>
Co-authored-by: Mingyang Sun <mingyang.sun@arm.com>
Diffstat (limited to 'secure_fw')
-rw-r--r-- | secure_fw/spm/cmsis_psa/spm_ipc.c | 170 | ||||
-rw-r--r-- | secure_fw/spm/cmsis_psa/spm_ipc.h | 9 | ||||
-rw-r--r-- | secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c | 12 | ||||
-rw-r--r-- | secure_fw/spm/include/load/asset_defs.h | 2 | ||||
-rw-r--r-- | secure_fw/spm/include/load/spm_load_api.h | 2 |
5 files changed, 40 insertions, 155 deletions
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c index 12f65a075e..a578a18ca5 100644 --- a/secure_fw/spm/cmsis_psa/spm_ipc.c +++ b/secure_fw/spm/cmsis_psa/spm_ipc.c @@ -266,34 +266,6 @@ struct tfm_msg_body_t *tfm_spm_get_msg_by_signal(struct partition_t *partition, return msg; } -#if TFM_LVL != 1 -/** - * \brief Change the privilege mode for partition thread mode. - * - * \param[in] privileged Privileged mode, - * \ref TFM_PARTITION_PRIVILEGED_MODE - * and \ref TFM_PARTITION_UNPRIVILEGED_MODE - * - * \note Barrier instructions are not called by this function, and if - * it is called in thread mode, it might be necessary to call - * them after this function returns. - */ -static void tfm_spm_partition_change_privilege(uint32_t privileged) -{ - CONTROL_Type ctrl; - - ctrl.w = __get_CONTROL(); - - if (privileged == TFM_PARTITION_PRIVILEGED_MODE) { - ctrl.b.nPRIV = 0; - } else { - ctrl.b.nPRIV = 1; - } - - __set_CONTROL(ctrl.w); -} -#endif /* if(TFM_LVL != 1) */ - uint32_t tfm_spm_partition_get_privileged_mode(uint32_t partition_flags) { #if TFM_LVL == 1 @@ -666,13 +638,11 @@ int32_t tfm_spm_get_client_id(bool ns_caller) uint32_t tfm_spm_init(void) { - uint32_t i; - bool privileged; struct partition_t *partition; struct tfm_core_thread_t *pth, *p_ns_entry_thread = NULL; - const struct platform_data_t *platform_data_p; const struct partition_load_info_t *p_ldinf; - struct asset_desc_t *p_asset_load; + void *p_boundaries = NULL; + #ifdef TFM_FIH_PROFILE_ON fih_int fih_rc = FIH_FAILURE; #endif @@ -703,54 +673,21 @@ uint32_t tfm_spm_init(void) load_irqs_assuredly(partition); } - /* Init mmio assets */ - if (p_ldinf->nassets > 0) { - if (tfm_spm_partition_get_privileged_mode(p_ldinf->flags) == - TFM_PARTITION_PRIVILEGED_MODE) { - privileged = true; - } else { - privileged = false; - } + /* Bind the partition with plaform. */ +#if TFM_FIH_PROFILE_ON + FIH_CALL(tfm_hal_bind_boundaries, fih_rc, partition->p_ldinf, + &p_boundaries); + if (fih_not_eq(fih_rc, fih_int_encode(TFM_HAL_SUCCESS))) { + tfm_core_panic(); } - - p_asset_load = (struct asset_desc_t *)LOAD_INFO_ASSET(p_ldinf); - for (i = 0; i < p_ldinf->nassets; i++) { - /* Skip the memory-based asset */ - if (!(p_asset_load[i].attr & ASSET_ATTR_NAMED_MMIO)) { - continue; - } - - platform_data_p = REFERENCE_TO_PTR(p_asset_load[i].dev.dev_ref, - struct platform_data_t *); - - /* - * TODO: some partitions declare MMIO not exist on specific - * platforms, and the platform defines a dummy NULL reference - * for these MMIO items, which cause 'nassets' to contain several - * NULL items. Skip these NULL items initialization temporarily to - * avoid HAL API panic. - * Eventually, these platform-specific partitions need to be moved - * into a platform-specific folder. Then this workaround can be - * removed. - */ - if (!platform_data_p) { - continue; - } - -#ifdef TFM_FIH_PROFILE_ON - FIH_CALL(tfm_spm_hal_configure_default_isolation, fih_rc, - privileged, platform_data_p); - if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) { - tfm_core_panic(); - } #else /* TFM_FIH_PROFILE_ON */ - if (tfm_spm_hal_configure_default_isolation(privileged, - platform_data_p) != TFM_PLAT_ERR_SUCCESS) { - tfm_core_panic(); - } -#endif /* TFM_FIH_PROFILE_ON */ + if (tfm_hal_bind_boundaries(partition->p_ldinf, + &p_boundaries) != TFM_HAL_SUCCESS) { + tfm_core_panic(); } +#endif /* TFM_FIH_PROFILE_ON */ + partition->p_boundaries = p_boundaries; partition->signals_allowed |= PSA_DOORBELL; tfm_event_init(&partition->event); @@ -795,80 +732,27 @@ uint32_t tfm_spm_init(void) return p_ns_entry_thread->arch_ctx.lr; } -#if TFM_LVL != 1 -static void set_up_boundary(const struct partition_load_info_t *p_ldinf) -{ -#if TFM_LVL == 3 -#if defined(TFM_FIH_PROFILE_ON) && (TFM_LVL == 3) - fih_int fih_rc = FIH_FAILURE; -#endif - /* - * FIXME: To implement isolations among partitions in isolation level 3, - * each partition needs to run in unprivileged mode. Currently some - * PRoTs cannot work in unprivileged mode, make them privileged now. - */ - if (!(p_ldinf->flags & SPM_PART_FLAG_PSA_ROT)) { - struct asset_desc_t *p_asset = - (struct asset_desc_t *)LOAD_INFO_ASSET(p_ldinf); - /* Partition must have private data as the first asset in LVL3 */ - if (p_ldinf->nassets == 0) { - tfm_core_panic(); - } - if (p_asset->attr & ASSET_ATTR_NAMED_MMIO) { - tfm_core_panic(); - } - /* FIXME: only MPU-based implementations are supported currently */ -#ifdef TFM_FIH_PROFILE_ON - FIH_CALL(tfm_hal_mpu_update_partition_boundary, fih_rc, - p_asset->mem.start, p_asset->mem.limit); - if (fih_not_eq(fih_rc, fih_int_encode(TFM_HAL_SUCCESS))) { - tfm_core_panic(); - } -#else /* TFM_FIH_PROFILE_ON */ - if (tfm_hal_mpu_update_partition_boundary(p_asset->mem.start, - p_asset->mem.limit) - != TFM_HAL_SUCCESS) { - tfm_core_panic(); - } -#endif /* TFM_FIH_PROFILE_ON */ - } -#else /* TFM_LVL == 3 */ - (void)p_ldinf; -#endif /* TFM_LVL == 3 */ -} -#endif /* TFM_LVL != 1 */ - -void tfm_set_up_isolation_boundary(const struct partition_t *partition) -{ -#if TFM_LVL != 1 - const struct partition_load_info_t *p_ldinf; - uint32_t is_privileged; - - p_ldinf = partition->p_ldinf; - is_privileged = p_ldinf->flags & SPM_PART_FLAG_PSA_ROT ? - TFM_PARTITION_PRIVILEGED_MODE : - TFM_PARTITION_UNPRIVILEGED_MODE; - - tfm_spm_partition_change_privilege(is_privileged); - - set_up_boundary(p_ldinf); -#else /* TFM_LVL != 1 */ - (void)partition; -#endif /* TFM_LVL != 1 */ -} - void tfm_pendsv_do_schedule(struct tfm_arch_ctx_t *p_actx) { - struct partition_t *p_next_partition; + struct partition_t *p_part_curr, *p_part_next; struct tfm_core_thread_t *pth_next = tfm_core_thrd_get_next(); struct tfm_core_thread_t *pth_curr = tfm_core_thrd_get_curr(); if (pth_next != NULL && pth_curr != pth_next) { - p_next_partition = TO_CONTAINER(pth_next, - struct partition_t, - sp_thread); - tfm_set_up_isolation_boundary(p_next_partition); + p_part_curr = TO_CONTAINER(pth_curr, struct partition_t, sp_thread); + p_part_next = TO_CONTAINER(pth_next, struct partition_t, sp_thread); + /* + * If required, let the platform update boundary based on its + * implementation. Change privilege, MPU or other configurations. + */ + if (p_part_curr->p_boundaries != p_part_next->p_boundaries) { + if (tfm_hal_update_boundaries(p_part_next->p_ldinf, + p_part_next->p_boundaries) + != TFM_HAL_SUCCESS) { + tfm_core_panic(); + } + } tfm_core_thrd_switch_context(p_actx, pth_curr, pth_next); } diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.h b/secure_fw/spm/cmsis_psa/spm_ipc.h index 1c28475aef..64d8cac80e 100644 --- a/secure_fw/spm/cmsis_psa/spm_ipc.h +++ b/secure_fw/spm/cmsis_psa/spm_ipc.h @@ -85,7 +85,7 @@ struct tfm_msg_body_t { */ struct partition_t { const struct partition_load_info_t *p_ldinf; - void *p_platform; + void *p_boundaries; void *p_interrupts; void *p_metadata; struct tfm_core_thread_t sp_thread; @@ -376,13 +376,6 @@ uint32_t tfm_spm_get_caller_privilege_mode(void); */ int32_t tfm_spm_get_client_id(bool ns_caller); -/** - * \brief Set up the isolation boundary of the given partition. - * - * \param[in] partition The partition of which the boundary is set up. - */ -void tfm_set_up_isolation_boundary(const struct partition_t *partition); - /* * PendSV specified function. * diff --git a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c index 0987f078d7..60a0124eea 100644 --- a/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c +++ b/secure_fw/spm/cmsis_psa/tfm_core_svcalls_ipc.c @@ -15,8 +15,10 @@ #include "tfm_core_utils.h" #include "tfm_svcalls.h" #include "utilities.h" +#include "load/spm_load_api.h" #include "ffm/tfm_boot_data.h" #include "ffm/psa_api.h" +#include "tfm_hal_isolation.h" #include "tfm_hal_spm_logdev.h" #include "load/partition_defs.h" #include "psa/client.h" @@ -151,7 +153,10 @@ uint32_t tfm_flih_prepare_depriv_flih(uintptr_t ctx, uint32_t *svc_args) } else { p_stat_ctx = (struct tfm_state_context_t *)irq_sp_thread->arch_ctx.sp; tfm_core_thrd_set_curr(irq_sp_thread); - tfm_set_up_isolation_boundary(irq_sp); + if (curr_sp->p_boundaries != irq_sp->p_boundaries) { + tfm_hal_update_boundaries(irq_sp->p_ldinf, + irq_sp->p_boundaries); + } tfm_arch_set_psplim(irq_sp_thread->stk_btm); } @@ -195,7 +200,10 @@ uint32_t tfm_flih_return_to_isr(uintptr_t ctx, psa_flih_result_t result) } if (curr_sp != prev_sp) { - tfm_set_up_isolation_boundary(prev_sp); + if (prev_sp->p_boundaries != curr_sp->p_boundaries) { + tfm_hal_update_boundaries(prev_sp->p_ldinf, + prev_sp->p_boundaries); + } tfm_core_thrd_set_curr(&(prev_sp->sp_thread)); tfm_arch_set_psplim(prev_sp->sp_thread.stk_btm); } diff --git a/secure_fw/spm/include/load/asset_defs.h b/secure_fw/spm/include/load/asset_defs.h index e88e2d1d13..b5af2c54cc 100644 --- a/secure_fw/spm/include/load/asset_defs.h +++ b/secure_fw/spm/include/load/asset_defs.h @@ -24,7 +24,7 @@ struct asset_desc_t { union { - struct { /* Memory asset type */ + struct { /* Memory-based asset type */ uintptr_t start; uintptr_t limit; } mem; diff --git a/secure_fw/spm/include/load/spm_load_api.h b/secure_fw/spm/include/load/spm_load_api.h index 26597b2924..d8fbc166a9 100644 --- a/secure_fw/spm/include/load/spm_load_api.h +++ b/secure_fw/spm/include/load/spm_load_api.h @@ -19,7 +19,7 @@ #define NO_MORE_PARTITION NULL /* Length of extendable variables in partition load type */ -#define LOAD_INFO_EXT_LENGTH 2 +#define LOAD_INFO_EXT_LENGTH (2) /* Argument "pldinf" must be a "struct partition_load_info_t *". */ #define LOAD_INFSZ_BYTES(pldinf) \ (sizeof(*(pldinf)) + LOAD_INFO_EXT_LENGTH * sizeof(uintptr_t) + \ |