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>
diff --git a/docs/technical_references/design_docs/hardware_abstraction_layer.rst b/docs/technical_references/design_docs/hardware_abstraction_layer.rst
index b574a3d..16db247 100644
--- a/docs/technical_references/design_docs/hardware_abstraction_layer.rst
+++ b/docs/technical_references/design_docs/hardware_abstraction_layer.rst
@@ -252,56 +252,56 @@
------------------------
The memory access attributes are encoded as bit fields, you can logic OR them to
have a combination of the atrributes, for example
-``TFM_HAL_MEM_ATTR_UNPRIVILEGED | TFM_HAL_MEM_ATTR_READABLE`` is unprivileged
+``TFM_HAL_ACCESS_UNPRIVILEGED | TFM_HAL_ACCESS_READABLE`` is unprivileged
readable. The data type is `uint32_t`.
-TFM_HAL_MEM_ATTR_EXECUTABLE
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
+TFM_HAL_ACCESS_EXECUTABLE
+^^^^^^^^^^^^^^^^^^^^^^^^^
The memory is executable.
.. code-block:: c
- #define TFM_HAL_MEM_ATTR_EXECUTABLE (1UL << 0)
+ #define TFM_HAL_ACCESS_EXECUTABLE (1UL << 0)
-TFM_HAL_MEM_ATTR_READABLE
-^^^^^^^^^^^^^^^^^^^^^^^^^
+TFM_HAL_ACCESS_READABLE
+^^^^^^^^^^^^^^^^^^^^^^^
The memory is readable.
.. code-block:: c
- #define TFM_HAL_MEM_ATTR_READABLE (1UL << 1)
+ #define TFM_HAL_ACCESS_READABLE (1UL << 1)
-TFM_HAL_MEM_ATTR_WRITABLE
-^^^^^^^^^^^^^^^^^^^^^^^^^
+TFM_HAL_ACCESS_WRITABLE
+^^^^^^^^^^^^^^^^^^^^^^^
The memory is writable.
.. code-block:: c
- #define TFM_HAL_MEM_ATTR_WRITABLE (1UL << 2)
+ #define TFM_HAL_ACCESS_WRITABLE (1UL << 2)
-TFM_HAL_MEM_ATTR_UNPRIVILEGED
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+TFM_HAL_ACCESS_UNPRIVILEGED
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
The memory is unprivileged mode accessible.
.. code-block:: c
- #define TFM_HAL_MEM_ATTR_UNPRIVILEGED (1UL << 3)
+ #define TFM_HAL_ACCESS_UNPRIVILEGED (1UL << 3)
-TFM_HAL_MEM_ATTR_DEVICE
-^^^^^^^^^^^^^^^^^^^^^^^
+TFM_HAL_ACCESS_DEVICE
+^^^^^^^^^^^^^^^^^^^^^
The memory is a MMIO device.
.. code-block:: c
- #define TFM_HAL_MEM_ATTR_DEVICE (1UL << 4)
+ #define TFM_HAL_ACCESS_DEVICE (1UL << 4)
-TFM_HAL_MEM_ATTR_NS
-^^^^^^^^^^^^^^^^^^^
+TFM_HAL_ACCESS_NS
+^^^^^^^^^^^^^^^^^
The memory is accessible from :term:`NSPE`
.. code-block:: c
- #define TFM_HAL_MEM_ATTR_NS (1UL << 5)
+ #define TFM_HAL_ACCESS_NS (1UL << 5)
APIs
----
@@ -311,7 +311,7 @@
.. code-block:: c
- tfm_hal_status_t tfm_hal_set_up_static_boundaries(void)
+ enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void)
**Description**
@@ -332,31 +332,31 @@
- ``TFM_HAL_SUCCESS`` - the isolation boundaries have been set up.
- ``TFM_HAL_ERROR_GENERIC`` - failed to set up the isolation boundaries.
-tfm_hal_mpu_update_partition_boundary
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+tfm_hal_update_boundaries()
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
**Prototype**
.. code-block:: c
- enum tfm_hal_status_t tfm_hal_mpu_update_partition_boundary(uintptr_t start,
- uintptr_t end);
+ enum tfm_hal_status_t tfm_hal_update_boundaries(
+ const struct partition_load_info_t *p_ldinf,
+ void *p_boundaries);
**Description**
-This API updates the partition isolation boundary for isolation level 3.
-Inside the partition isolation boundary is the private data of the running
-Secure Partition.
-This boundary is updated dynamically when :term:`SPM` switches Partitions in
-isolation level 3.
+This API updates the partition isolation boundary for isolation level 2 and 3.
+The isolation boundary includes the thread privilege and the partition private
+data.
+In isolation level 2, the :term:`SPM` only updates the partition thread
+privilege. In isolation level 3, the :term:`SPM` updates the partition thread
+privilege, and protects each partition's private data.
-The access permissions of the boundary is all privileged mode read-write.
-
-Platforms decide which :term:`MPU` region the paritition boundary uses.
+The access permissions outside the boundary is platform-dependent.
**Parameter**
-- ``start`` - start address of the partition boundary.
-- ``end`` - end address of the partition boundary.
+- ``p_ldinf`` - Partition load information.
+- ``p_boundaries`` - Platform boundary handle for the partition.
**Return Values**
@@ -400,6 +400,40 @@
- ``TFM_HAL_ERROR_INVALID_INPUT`` - Invalid inputs.
- ``TFM_HAL_ERROR_GENERIC`` - An error occurred.
+tfm_hal_bind_boundaries()
+^^^^^^^^^^^^^^^^^^^^^^^^^
+**Prototype**
+
+.. code-block:: c
+
+ enum tfm_hal_status_t tfm_hal_bind_boundaries(
+ const struct partition_load_info_t *p_ldinf,
+ void **pp_boundaries);
+
+**Description**
+
+This API binds partition with the platform via a boundary handle.
+
+**Parameter**
+
+- ``p_ldinf`` - Partition load information.
+- ``pp_boundaries`` - Pointer of a the partition's platform boundary handle.
+
+**Return Values**
+
+- ``TFM_HAL_SUCCESS`` - the handle has been binded successfully.
+- ``TFM_HAL_ERROR_GENERIC`` - failed to bind the handle.
+
+.. Note::
+
+ The platform maintains the platform-specific settings for SPM further usage,
+ such as updating partition hardware boundaries or checking resource
+ accessibility. The platform needs to manage the settings with an internal
+ mechanism, and returns a handle to SPM. SPM delivers this handle back to
+ platform when necessary. And SPM checks this handle to decide if the
+ platform-specific settings need to be updated. Hence multiple partitions can
+ have the same handle if they have the same platform-specific settings.
+
Log API
=======
The log API is used by the :term:`TF-M` :doc:`log system <tfm_log_system_design_document>`.
diff --git a/platform/ext/target/arm/mps2/an521/mmio_defs.h b/platform/ext/target/arm/mps2/an521/mmio_defs.h
new file mode 100644
index 0000000..7d3455e
--- /dev/null
+++ b/platform/ext/target/arm/mps2/an521/mmio_defs.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2021, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __MMIO_DEFS_H__
+#define __MMIO_DEFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include "tfm_peripherals_def.h"
+
+/* Boundary handle binding macros. */
+#define HANDLE_PER_ATTR_BITS (0x4)
+#define HANDLE_ATTR_PRIV_MASK ((1 << HANDLE_PER_ATTR_BITS) - 1)
+#if TFM_LVL == 3
+#define HANDLE_ATTR_RW_POS (1 << (HANDLE_PER_ATTR_BITS - 1))
+#define HANDLE_ATTR_INDEX_MASK (HANDLE_ATTR_RW_POS - 1)
+#define HANDLE_INDEX_BITS (0x8)
+#define HANDLE_INDEX_MASK (((1 << HANDLE_INDEX_BITS) -1) << 24)
+#define HANDLE_ENCODE_INDEX(attr, idx) \
+ do { \
+ (attr) |= (((idx) << 24) & HANDLE_INDEX_MASK); \
+ (idx)++; \
+ } while (0)
+#endif
+
+/* Allowed named MMIO of this platform */
+const uintptr_t partition_named_mmio_list[] = {
+ (uintptr_t)TFM_PERIPHERAL_TIMER0,
+ (uintptr_t)TFM_PERIPHERAL_STD_UART,
+};
+
+/*
+ * Platform AN521 only has named MMIO.
+ * If the platform has numbered MMIO, define them in another list.
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __MMIO_DEFS_H__ */
diff --git a/platform/ext/target/arm/mps2/an521/native_drivers/mpu_armv8m_drv.c b/platform/ext/target/arm/mps2/an521/native_drivers/mpu_armv8m_drv.c
index 8231811..04b0f93 100644
--- a/platform/ext/target/arm/mps2/an521/native_drivers/mpu_armv8m_drv.c
+++ b/platform/ext/target/arm/mps2/an521/native_drivers/mpu_armv8m_drv.c
@@ -7,16 +7,15 @@
#include "mpu_armv8m_drv.h"
#include "cmsis_cpu.h"
-#include "fih.h"
/*
* FixMe:
* This is a beta quality driver for MPU in v8M. To be finalized.
*/
-fih_int mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev,
- uint32_t privdef_en,
- uint32_t hfnmi_en)
+enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev,
+ uint32_t privdef_en,
+ uint32_t hfnmi_en)
{
/*No error checking*/
@@ -46,32 +45,33 @@
__DSB();
__ISB();
- FIH_RET(fih_int_encode(MPU_ARMV8M_OK));
+ return MPU_ARMV8M_OK;
}
-fih_int mpu_armv8m_disable(struct mpu_armv8m_dev_t *dev)
+enum mpu_armv8m_error_t mpu_armv8m_disable(struct mpu_armv8m_dev_t *dev)
{
MPU_Type *mpu = (MPU_Type *)dev->base;
/* Reset all fields as enable does full setup */
mpu->CTRL = 0;
- FIH_RET(fih_int_encode(MPU_ARMV8M_OK));
+ return MPU_ARMV8M_OK;
}
-
-fih_int mpu_armv8m_region_enable(struct mpu_armv8m_dev_t *dev,
- struct mpu_armv8m_region_cfg_t *region_cfg)
+enum mpu_armv8m_error_t mpu_armv8m_region_enable(
+ struct mpu_armv8m_dev_t *dev,
+ struct mpu_armv8m_region_cfg_t *region_cfg)
{
MPU_Type *mpu = (MPU_Type *)dev->base;
+ enum mpu_armv8m_error_t ret_val = MPU_ARMV8M_OK;
uint32_t ctrl_before;
uint32_t base_cfg;
uint32_t limit_cfg;
/*FIXME : Add complete error checking*/
if ((region_cfg->region_base & ~MPU_RBAR_BASE_Msk) != 0) {
- FIH_RET(fih_int_encode(MPU_ARMV8M_ERROR));
+ return MPU_ARMV8M_ERROR;
}
/* region_limit doesn't need to be aligned but the scatter
* file needs to be setup to ensure that partitions do not overlap.
@@ -107,12 +107,11 @@
__DSB();
__ISB();
- FIH_RET(fih_int_encode(MPU_ARMV8M_OK));
+ return ret_val;
}
-
-fih_int mpu_armv8m_region_disable(struct mpu_armv8m_dev_t *dev,
- uint32_t region_nr)
+enum mpu_armv8m_error_t mpu_armv8m_region_disable(struct mpu_armv8m_dev_t *dev,
+ uint32_t region_nr)
{
MPU_Type *mpu = (MPU_Type *)dev->base;
@@ -131,25 +130,18 @@
/*Restore main MPU control*/
mpu->CTRL = ctrl_before;
- FIH_RET(fih_int_encode(MPU_ARMV8M_OK));
+ return MPU_ARMV8M_OK;
}
-fih_int mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev)
+enum mpu_armv8m_error_t mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev)
{
MPU_Type *mpu = (MPU_Type *)dev->base;
uint32_t i = (mpu->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
- fih_int fih_rc = fih_int_encode(MPU_ARMV8M_ERROR);
while (i > 0) {
- FIH_CALL(mpu_armv8m_region_disable, fih_rc, dev, i - 1);
+ mpu_armv8m_region_disable(dev, i - 1);
i--;
}
-#ifdef TFM_FIH_PROFILE_ON
- if (i > 0) {
- FIH_PANIC;
- }
-#endif
-
- FIH_RET(fih_int_encode(MPU_ARMV8M_OK));
+ return MPU_ARMV8M_OK;
}
diff --git a/platform/ext/target/arm/mps2/an521/native_drivers/mpu_armv8m_drv.h b/platform/ext/target/arm/mps2/an521/native_drivers/mpu_armv8m_drv.h
index 78da639..fe0a206 100644
--- a/platform/ext/target/arm/mps2/an521/native_drivers/mpu_armv8m_drv.h
+++ b/platform/ext/target/arm/mps2/an521/native_drivers/mpu_armv8m_drv.h
@@ -11,7 +11,6 @@
#include <stdint.h>
#include "cmsis.h"
-#include "fih.h"
#define PRIVILEGED_DEFAULT_ENABLE 1
#define HARDFAULT_NMI_ENABLE 1
@@ -81,9 +80,9 @@
* \note This function doesn't check if dev is NULL.
*/
-fih_int mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev,
- uint32_t privdef_en,
- uint32_t hfnmi_en);
+enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev,
+ uint32_t privdef_en,
+ uint32_t hfnmi_en);
/**
* \brief Disable MPU
@@ -94,7 +93,7 @@
*
* \note This function doesn't check if dev is NULL.
*/
-fih_int mpu_armv8m_disable(struct mpu_armv8m_dev_t *dev);
+enum mpu_armv8m_error_t mpu_armv8m_disable(struct mpu_armv8m_dev_t *dev);
/**
* \brief Disable MPU and clean all regions
@@ -105,7 +104,7 @@
*
* \note This function doesn't check if dev is NULL.
*/
-fih_int mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev);
+enum mpu_armv8m_error_t mpu_armv8m_clean(struct mpu_armv8m_dev_t *dev);
/**
* \brief Enable MPU Region
@@ -117,8 +116,9 @@
*
* \note This function doesn't check if dev is NULL.
*/
-fih_int mpu_armv8m_region_enable(struct mpu_armv8m_dev_t *dev,
- struct mpu_armv8m_region_cfg_t *region_cfg);
+enum mpu_armv8m_error_t mpu_armv8m_region_enable(
+ struct mpu_armv8m_dev_t *dev,
+ struct mpu_armv8m_region_cfg_t *region_cfg);
/**
* \brief Disable MPU Region
@@ -130,7 +130,7 @@
*
* \note This function doesn't check if dev is NULL.
*/
-fih_int mpu_armv8m_region_disable(struct mpu_armv8m_dev_t *dev,
- uint32_t region_nr);
+enum mpu_armv8m_error_t mpu_armv8m_region_disable(struct mpu_armv8m_dev_t *dev,
+ uint32_t region_nr);
#endif /* __MPU_ARMV8M_DRV_H__ */
diff --git a/platform/ext/target/arm/mps2/an521/spm_hal.c b/platform/ext/target/arm/mps2/an521/spm_hal.c
index 33e20b5..045129b 100644
--- a/platform/ext/target/arm/mps2/an521/spm_hal.c
+++ b/platform/ext/target/arm/mps2/an521/spm_hal.c
@@ -5,15 +5,11 @@
*
*/
-#include <stdio.h>
#include "cmsis.h"
-#include "fih.h"
#include "tfm_spm_hal.h"
#include "tfm_platform_core_api.h"
#include "target_cfg.h"
#include "Driver_MPC.h"
-#include "mpu_armv8m_drv.h"
-#include "region_defs.h"
#include "utilities.h"
/* Import MPC driver */
@@ -22,105 +18,6 @@
/* Get address of memory regions to configure MPU */
extern const struct memory_region_limits memory_regions;
-struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
-
-#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
-#define PARTITION_REGION_PERIPH_START 5
-#define PARTITION_REGION_PERIPH_MAX_NUM 2
-
-uint32_t periph_num_count = 0;
-#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
-
-#ifdef TFM_FIH_PROFILE_ON
-fih_int tfm_spm_hal_configure_default_isolation(
- bool privileged,
- const struct platform_data_t *platform_data)
-#else /* TFM_FIH_PROFILE_ON */
-enum tfm_plat_err_t tfm_spm_hal_configure_default_isolation(
- bool privileged,
- const struct platform_data_t *platform_data)
-#endif /* TFM_FIH_PROFILE_ON */
-{
- fih_int fih_rc = FIH_FAILURE;
-#if defined(CONFIG_TFM_ENABLE_MEMORY_PROTECT) && (TFM_LVL != 1)
- struct mpu_armv8m_region_cfg_t region_cfg;
-#endif
-
- if (!platform_data) {
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_INVALID_INPUT));
- }
-
-#if defined(CONFIG_TFM_ENABLE_MEMORY_PROTECT) && (TFM_LVL != 1)
- if (!privileged) {
- region_cfg.region_nr = PARTITION_REGION_PERIPH_START + periph_num_count;
- periph_num_count++;
- if (periph_num_count >= PARTITION_REGION_PERIPH_MAX_NUM) {
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_MAX_VALUE));
- }
- region_cfg.region_base = platform_data->periph_start;
- region_cfg.region_limit = platform_data->periph_limit;
- region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX;
- region_cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
- region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
- region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
-
-#ifdef TFM_FIH_PROFILE_ON
- FIH_CALL(mpu_armv8m_disable, fih_rc, &dev_mpu_s);
-
- FIH_CALL(mpu_armv8m_region_enable, fih_rc, &dev_mpu_s, ®ion_cfg);
- if (fih_not_eq(fih_rc, fih_int_encode(MPU_ARMV8M_OK))) {
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_SYSTEM_ERR));
- }
-
- FIH_CALL(mpu_armv8m_enable, fih_rc, &dev_mpu_s,
- PRIVILEGED_DEFAULT_ENABLE, HARDFAULT_NMI_ENABLE);
- if (fih_not_eq(fih_rc, fih_int_encode(MPU_ARMV8M_OK))) {
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_SYSTEM_ERR));
- }
-#else /* TFM_FIH_PROFILE_ON */
- mpu_armv8m_disable(&dev_mpu_s);
-
- if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg)
- != MPU_ARMV8M_OK) {
- return TFM_PLAT_ERR_SYSTEM_ERR;
- }
- mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,
- HARDFAULT_NMI_ENABLE);
-#endif /* TFM_FIH_PROFILE_ON */
- }
-#endif /* defined(CONFIG_TFM_ENABLE_MEMORY_PROTECT) && (TFM_LVL != 1) */
-
- if (platform_data->periph_ppc_bank != PPC_SP_DO_NOT_CONFIGURE) {
-#ifdef TFM_FIH_PROFILE_ON
- FIH_CALL(ppc_configure_to_secure, fih_rc,
- platform_data->periph_ppc_bank,
- platform_data->periph_ppc_loc);
- if (privileged) {
- FIH_CALL(ppc_clr_secure_unpriv, fih_rc,
- platform_data->periph_ppc_bank,
- platform_data->periph_ppc_loc);
- } else {
- FIH_CALL(ppc_en_secure_unpriv, fih_rc,
- platform_data->periph_ppc_bank,
- platform_data->periph_ppc_loc);
- }
-#else /* TFM_FIH_PROFILE_ON */
- ppc_configure_to_secure(platform_data->periph_ppc_bank,
- platform_data->periph_ppc_loc);
- if (privileged) {
- ppc_clr_secure_unpriv(platform_data->periph_ppc_bank,
- platform_data->periph_ppc_loc);
- } else {
- ppc_en_secure_unpriv(platform_data->periph_ppc_bank,
- platform_data->periph_ppc_loc);
- }
-#endif /* TFM_FIH_PROFILE_ON */
- }
-
- fih_rc = fih_int_encode(TFM_PLAT_ERR_SUCCESS);
- FIH_RET(fih_rc);
-}
-
void MPC_Handler(void)
{
/* Clear MPC interrupt flag and pending MPC IRQ */
@@ -218,21 +115,10 @@
return system_reset_cfg();
}
-#ifdef TFM_FIH_PROFILE_ON
-fih_int tfm_spm_hal_init_debug(void)
-{
- fih_int fih_rc = FIH_FAILURE;
-
- FIH_CALL(init_debug, fih_rc);
-
- FIH_RET(fih_rc);
-}
-#else /* TFM_FIH_PROFILE_ON */
enum tfm_plat_err_t tfm_spm_hal_init_debug(void)
{
return init_debug();
}
-#endif /* TFM_FIH_PROFILE_ON */
enum tfm_plat_err_t tfm_spm_hal_nvic_interrupt_target_state_cfg(void)
{
@@ -244,16 +130,69 @@
return nvic_interrupt_enable();
}
-#ifdef TFM_FIH_PROFILE_ON
-fih_int tfm_spm_hal_verify_isolation_hw(void)
-{
- fih_int fih_rc = FIH_INT_INIT(TFM_PLAT_ERR_SYSTEM_ERR);
+#ifndef TFM_PSA_API
- FIH_CALL(verify_isolation_hw, fih_rc);
- if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
- FIH_PANIC;
+#include "mpu_armv8m_drv.h"
+#include "region_defs.h"
+
+struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
+
+#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
+#define PARTITION_REGION_PERIPH_START 5
+#define PARTITION_REGION_PERIPH_MAX_NUM 2
+
+uint32_t periph_num_count = 0;
+#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
+
+enum tfm_plat_err_t tfm_spm_hal_configure_default_isolation(
+ bool privileged,
+ const struct platform_data_t *platform_data)
+{
+#if defined(CONFIG_TFM_ENABLE_MEMORY_PROTECT) && (TFM_LVL != 1)
+ struct mpu_armv8m_region_cfg_t region_cfg;
+#endif
+
+ if (!platform_data) {
+ return TFM_PLAT_ERR_INVALID_INPUT;
}
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_SUCCESS));
+#if defined(CONFIG_TFM_ENABLE_MEMORY_PROTECT) && (TFM_LVL != 1)
+ if (!privileged) {
+ region_cfg.region_nr = PARTITION_REGION_PERIPH_START + periph_num_count;
+ periph_num_count++;
+ if (periph_num_count >= PARTITION_REGION_PERIPH_MAX_NUM) {
+ return TFM_PLAT_ERR_MAX_VALUE;
+ }
+ region_cfg.region_base = platform_data->periph_start;
+ region_cfg.region_limit = platform_data->periph_limit;
+ region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX;
+ region_cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
+ region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
+ region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
+
+ mpu_armv8m_disable(&dev_mpu_s);
+
+ if (mpu_armv8m_region_enable(&dev_mpu_s, ®ion_cfg)
+ != MPU_ARMV8M_OK) {
+ return TFM_PLAT_ERR_SYSTEM_ERR;
+ }
+ mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,
+ HARDFAULT_NMI_ENABLE);
+ }
+#endif /* defined(CONFIG_TFM_ENABLE_MEMORY_PROTECT) && (TFM_LVL != 1) */
+
+ if (platform_data->periph_ppc_bank != PPC_SP_DO_NOT_CONFIGURE) {
+ ppc_configure_to_secure(platform_data->periph_ppc_bank,
+ platform_data->periph_ppc_loc);
+ if (privileged) {
+ ppc_clr_secure_unpriv(platform_data->periph_ppc_bank,
+ platform_data->periph_ppc_loc);
+ } else {
+ ppc_en_secure_unpriv(platform_data->periph_ppc_bank,
+ platform_data->periph_ppc_loc);
+ }
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
}
-#endif /* TFM_FIH_PROFILE_ON */
+#endif
diff --git a/platform/ext/target/arm/mps2/an521/target_cfg.c b/platform/ext/target/arm/mps2/an521/target_cfg.c
index 8849ab3..c5432ca 100644
--- a/platform/ext/target/arm/mps2/an521/target_cfg.c
+++ b/platform/ext/target/arm/mps2/an521/target_cfg.c
@@ -21,10 +21,6 @@
#include "region_defs.h"
#include "tfm_plat_defs.h"
#include "region.h"
-#include "fih.h"
-#ifdef TFM_FIH_PROFILE_ON
-#include "mpc_sie200_drv.h"
-#endif
#ifdef PSA_API_TEST_IPC
#define PSA_FF_TEST_SECURE_UART2
@@ -206,7 +202,7 @@
return TFM_PLAT_ERR_SUCCESS;
}
-fih_int init_debug(void)
+enum tfm_plat_err_t init_debug(void)
{
volatile struct sysctrl_t *sys_ctrl =
(struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
@@ -243,7 +239,7 @@
*/
#endif
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_SUCCESS));
+ return TFM_PLAT_ERR_SUCCESS;
}
/*----------------- NVIC interrupt target state to NS configuration ----------*/
@@ -371,21 +367,13 @@
#define NR_SAU_INIT_STEP 3
-fih_int sau_and_idau_cfg(void)
+void sau_and_idau_cfg(void)
{
struct spctrl_def *spctrl = CMSDK_SPCTRL;
uint32_t i;
- FIH_CFI_STEP_INIT(NR_SAU_INIT_STEP);
-
/* Enables SAU */
-#ifdef TFM_FIH_PROFILE_ON
TZ_SAU_Enable();
- TZ_SAU_Enable();
-#endif
- TZ_SAU_Enable();
-
- FIH_CFI_STEP_DECREMENT();
for (i = 0; i < ARRAY_SIZE(sau_cfg); i++) {
SAU->RNR = i;
@@ -395,20 +383,8 @@
SAU_RLAR_ENABLE_Msk;
}
- FIH_CFI_STEP_DECREMENT();
-
/* Allows SAU to define the code region as a NSC */
spctrl->nsccfg |= NSCCFG_CODENSC;
-
- FIH_CFI_STEP_DECREMENT();
-
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_SUCCESS));
-
- /*
- * Dummy operation to avoid unused variable warning of the saved FIH counter
- * variable.
- */
- FIH_CFI_STEP_ERR_RESET();
}
/*------------------- Memory configuration functions -------------------------*/
@@ -418,30 +394,21 @@
#define NR_MPC_INIT_STEP 6
#endif
-fih_int mpc_init_cfg(void)
+int32_t mpc_init_cfg(void)
{
- int32_t ret = ARM_DRIVER_ERROR;
- fih_int fih_rc = FIH_FAILURE;
-
- FIH_CFI_STEP_INIT(NR_MPC_INIT_STEP);
+ int32_t ret = ARM_DRIVER_OK;
ret = Driver_SRAM1_MPC.Initialize();
- FIH_CFI_STEP_DECREMENT();
if (ret != ARM_DRIVER_OK) {
- fih_rc = fih_int_encode(ret);
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
+ return ret;
}
ret = Driver_SRAM1_MPC.ConfigRegion(
memory_regions.non_secure_partition_base,
memory_regions.non_secure_partition_limit,
ARM_MPC_ATTR_NONSECURE);
- FIH_CFI_STEP_DECREMENT();
if (ret != ARM_DRIVER_OK) {
- fih_rc = fih_int_encode(ret);
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
+ return ret;
}
#ifdef BL2
@@ -449,46 +416,31 @@
ret = Driver_SRAM1_MPC.ConfigRegion(memory_regions.secondary_partition_base,
memory_regions.secondary_partition_limit,
ARM_MPC_ATTR_NONSECURE);
- FIH_CFI_STEP_DECREMENT();
if (ret != ARM_DRIVER_OK) {
- fih_rc = fih_int_encode(ret);
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
+ return ret;
}
#endif /* BL2 */
ret = Driver_SRAM2_MPC.Initialize();
- FIH_CFI_STEP_DECREMENT();
if (ret != ARM_DRIVER_OK) {
- fih_rc = fih_int_encode(ret);
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
+ return ret;
}
ret = Driver_SRAM2_MPC.ConfigRegion(NS_DATA_START, NS_DATA_LIMIT,
ARM_MPC_ATTR_NONSECURE);
- FIH_CFI_STEP_DECREMENT();
if (ret != ARM_DRIVER_OK) {
- fih_rc = fih_int_encode(ret);
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
+ return ret;
}
/* Lock down the MPC configuration */
ret = Driver_SRAM1_MPC.LockDown();
- FIH_CFI_STEP_DECREMENT();
if (ret != ARM_DRIVER_OK) {
- fih_rc = fih_int_encode(ret);
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
+ return ret;
}
ret = Driver_SRAM2_MPC.LockDown();
- FIH_CFI_STEP_DECREMENT();
if (ret != ARM_DRIVER_OK) {
- fih_rc = fih_int_encode(ret);
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
+ return ret;
}
/* Add barriers to assure the MPC configuration is done before continue
@@ -497,22 +449,17 @@
__DSB();
__ISB();
- fih_rc = fih_int_encode(ARM_DRIVER_OK);
-
-Done:
- FIH_RET(fih_rc);
+ return ARM_DRIVER_OK;
}
/*---------------------- PPC configuration functions -------------------------*/
#define NR_PPC_INIT_STEP 4
-fih_int ppc_init_cfg(void)
+void ppc_init_cfg(void)
{
struct spctrl_def* spctrl = CMSDK_SPCTRL;
struct nspctrl_def* nspctrl = CMSDK_NSPCTRL;
- FIH_CFI_STEP_INIT(NR_PPC_INIT_STEP);
-
/* Grant non-secure access to peripherals in the PPC0
* (timer0 and 1, dualtimer, watchdog, mhu 0 and 1)
*/
@@ -552,8 +499,6 @@
(1U << CMSDK_FPGA_AUDIO_PPC_POS) |
(1U << CMSDK_FPGA_IO_PPC_POS);
- FIH_CFI_STEP_DECREMENT();
-
/* Grant non-secure access to all peripherals on AHB EXP:
* Make sure that all possible peripherals are enabled by default
*/
@@ -569,8 +514,6 @@
(1U << CMSDK_DMA2_PPC_POS) |
(1U << CMSDK_DMA3_PPC_POS);
- FIH_CFI_STEP_DECREMENT();
-
/* in NS, grant un-privileged for UART0 */
nspctrl->apbnspppcexp1 |= (1U << CMSDK_UART0_APB_PPC_POS);
@@ -578,56 +521,36 @@
nspctrl->apbnspppcexp2 |= (1U << CMSDK_FPGA_SCC_PPC_POS) |
(1U << CMSDK_FPGA_IO_PPC_POS);
- FIH_CFI_STEP_DECREMENT();
-
/* Configure the response to a security violation as a
* bus error instead of RAZ/WI
*/
spctrl->secrespcfg |= 1U;
-
- FIH_CFI_STEP_DECREMENT();
-
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_SUCCESS));
-
- /*
- * Dummy operation to avoid unused variable warning of the saved FIH counter
- * variable.
- */
- FIH_CFI_STEP_ERR_RESET();
}
-fih_int ppc_configure_to_non_secure(enum ppc_bank_e bank, uint16_t pos)
+void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint16_t pos)
{
/* Setting NS flag for peripheral to enable NS access */
struct spctrl_def* spctrl = CMSDK_SPCTRL;
((uint32_t*)&(spctrl->ahbnsppc0))[bank] |= (1U << pos);
-
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_SUCCESS));
}
-fih_int ppc_configure_to_secure(enum ppc_bank_e bank, uint16_t pos)
+void ppc_configure_to_secure(enum ppc_bank_e bank, uint16_t pos)
{
/* Clear NS flag for peripheral to prevent NS access */
struct spctrl_def* spctrl = CMSDK_SPCTRL;
((uint32_t*)&(spctrl->ahbnsppc0))[bank] &= ~(1U << pos);
-
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_SUCCESS));
}
-fih_int ppc_en_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
+void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
{
struct spctrl_def* spctrl = CMSDK_SPCTRL;
((uint32_t*)&(spctrl->ahbspppc0))[bank] |= (1U << pos);
-
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_SUCCESS));
}
-fih_int ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
+void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint16_t pos)
{
struct spctrl_def* spctrl = CMSDK_SPCTRL;
((uint32_t*)&(spctrl->ahbspppc0))[bank] &= ~(1U << pos);
-
- FIH_RET(fih_int_encode(TFM_PLAT_ERR_SUCCESS));
}
void ppc_clear_irq(void)
@@ -636,88 +559,3 @@
/* Clear APB PPC EXP2 IRQ */
spctrl->secppcintclr = CMSDK_APB_PPCEXP2_INT_POS_MASK;
}
-
-#ifdef TFM_FIH_PROFILE_ON
-#ifdef BL2
-#define NR_VERIFY_STEP 4
-#else
-#define NR_VERIFY_STEP 3
-#endif
-
-fih_int verify_isolation_hw(void)
-{
- enum tfm_plat_err_t ret = ARM_DRIVER_ERROR;
- ARM_MPC_SEC_ATTR attr;
- fih_int fih_rc = FIH_FAILURE;
-
- FIH_CFI_STEP_INIT(NR_VERIFY_STEP);
-
- /* Check SAU config */
- if (!(SAU->CTRL & SAU_CTRL_ENABLE_Msk ||
- SAU->CTRL | SAU_CTRL_ALLNS_Msk)) {
- FIH_PANIC;
- }
-
- FIH_CFI_STEP_DECREMENT();
-
- /* Check MPC config */
- ret = Driver_SRAM1_MPC.GetRegionConfig(
- memory_regions.non_secure_partition_base,
- memory_regions.non_secure_partition_limit,
- &attr);
- FIH_CFI_STEP_DECREMENT();
- if (ret != ARM_DRIVER_OK) {
- fih_rc = FIH_FAILURE;
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
- }
-
- if (attr != ARM_MPC_ATTR_NONSECURE) {
- fih_rc = FIH_FAILURE;
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
- }
-
-#ifdef BL2
- ret = Driver_SRAM1_MPC.GetRegionConfig(
- memory_regions.secondary_partition_base,
- memory_regions.secondary_partition_limit,
- &attr);
- FIH_CFI_STEP_DECREMENT();
- if (ret != ARM_DRIVER_OK) {
- fih_rc = FIH_FAILURE;
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
- }
-
- if (attr != ARM_MPC_ATTR_NONSECURE) {
- fih_rc = FIH_FAILURE;
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
- }
-#endif
-
- ret = Driver_SRAM2_MPC.GetRegionConfig(NS_DATA_START, NS_DATA_LIMIT, &attr);
- FIH_CFI_STEP_DECREMENT();
- if (ret != ARM_DRIVER_OK) {
- fih_rc = FIH_FAILURE;
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
- }
-
- if (attr != ARM_MPC_ATTR_NONSECURE) {
- fih_rc = FIH_FAILURE;
- FIH_CFI_STEP_ERR_RESET();
- goto Done;
- }
-
- /* Todo: Check PPC config */
-
- /* Todo: Check static MPU config */
-
- fih_rc = FIH_SUCCESS;
-
-Done:
- FIH_RET(fih_rc);
-}
-#endif /* TFM_FIH_PROFILE_ON */
diff --git a/platform/ext/target/arm/mps2/an521/target_cfg.h b/platform/ext/target/arm/mps2/an521/target_cfg.h
index 25cc28a..32f9721 100644
--- a/platform/ext/target/arm/mps2/an521/target_cfg.h
+++ b/platform/ext/target/arm/mps2/an521/target_cfg.h
@@ -21,7 +21,6 @@
#include "tfm_peripherals_def.h"
#include "tfm_plat_defs.h"
#include "arm_uart_drv.h"
-#include "fih.h"
#define TFM_DRIVER_STDIO Driver_USART0
#define NS_DRIVER_STDIO Driver_USART0
@@ -82,32 +81,32 @@
*
* \return Returns error code.
*/
-fih_int mpc_init_cfg(void);
+int32_t mpc_init_cfg(void);
/**
* \brief Configures the Peripheral Protection Controller.
*/
-fih_int ppc_init_cfg(void);
+void ppc_init_cfg(void);
/**
* \brief Restict access to peripheral to secure
*/
-fih_int ppc_configure_to_secure(enum ppc_bank_e bank, uint16_t loc);
+void ppc_configure_to_secure(enum ppc_bank_e bank, uint16_t loc);
/**
* \brief Allow non-secure access to peripheral
*/
-fih_int ppc_configure_to_non_secure(enum ppc_bank_e bank, uint16_t loc);
+void ppc_configure_to_non_secure(enum ppc_bank_e bank, uint16_t loc);
/**
* \brief Enable secure unprivileged access to peripheral
*/
-fih_int ppc_en_secure_unpriv(enum ppc_bank_e bank, uint16_t pos);
+void ppc_en_secure_unpriv(enum ppc_bank_e bank, uint16_t pos);
/**
* \brief Clear secure unprivileged access to peripheral
*/
-fih_int ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint16_t pos);
+void ppc_clr_secure_unpriv(enum ppc_bank_e bank, uint16_t pos);
/**
* \brief Clears PPC interrupt.
@@ -117,7 +116,7 @@
/**
* \brief Configures SAU and IDAU.
*/
-fih_int sau_and_idau_cfg(void);
+void sau_and_idau_cfg(void);
/**
* \brief Enables the fault handlers and sets priorities.
@@ -138,7 +137,7 @@
*
* \return Returns values as specified by the \ref fih_int
*/
-fih_int init_debug(void);
+enum tfm_plat_err_t init_debug(void);
/**
* \brief Configures all external interrupts to target the
@@ -158,18 +157,4 @@
*/
enum tfm_plat_err_t nvic_interrupt_enable(void);
-#ifdef TFM_FIH_PROFILE_ON
-/**
- * \brief This function verifies the settings of HW used for memory isolation,
- * to make sure that important settings was not skipped due to fault
- * injection attacks.
- *
- * This function is called during TF-M core late startup, before passing
- * execution to non-secure code.
- *
- * \return Returns values as specified by the \ref fih_int.
- */
-fih_int verify_isolation_hw(void);
-#endif /* TFM_FIH_PROFILE_ON */
-
#endif /* __TARGET_CFG_H__ */
diff --git a/platform/ext/target/arm/mps2/an521/tfm_hal_isolation.c b/platform/ext/target/arm/mps2/an521/tfm_hal_isolation.c
index 77ece5f..3027402 100644
--- a/platform/ext/target/arm/mps2/an521/tfm_hal_isolation.c
+++ b/platform/ext/target/arm/mps2/an521/tfm_hal_isolation.c
@@ -5,16 +5,28 @@
*
*/
+#include "array.h"
#include "cmsis.h"
#include "Driver_Common.h"
-#include "fih.h"
+#include "mmio_defs.h"
#include "mpu_armv8m_drv.h"
#include "region.h"
#include "target_cfg.h"
#include "tfm_hal_isolation.h"
+#include "tfm_peripherals_def.h"
+#include "tfm_core_utils.h"
+#include "load/partition_defs.h"
+#include "load/asset_defs.h"
+#include "load/spm_load_api.h"
+
+/* It can be retrieved from the MPU_TYPE register. */
+#define MPU_REGION_NUM 16
#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
+static uint32_t n_configured_regions = 0;
+struct mpu_armv8m_dev_t dev_mpu_s = {MPU_BASE};
#if TFM_LVL == 3
+static uint32_t idx_boundary_handle = 0;
REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base);
REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit);
REGION_DECLARE(Image$$, PT_RO_START, $$Base);
@@ -22,9 +34,7 @@
REGION_DECLARE(Image$$, PT_PRIV_RWZI_START, $$Base);
REGION_DECLARE(Image$$, PT_PRIV_RWZI_END, $$Base);
-static uint32_t g_static_region_cnt;
-
-static struct mpu_armv8m_region_cfg_t isolation_regions[] = {
+const static struct mpu_armv8m_region_cfg_t isolation_regions[] = {
{
0, /* will be updated before using */
(uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Base),
@@ -44,7 +54,7 @@
MPU_ARMV8M_SH_NONE,
},
/* For isolation Level 3, set up static isolation for privileged data.
- * Unprivileged data is dynamically set during Partition sheduling.
+ * Unprivileged data is dynamically set during Partition scheduling.
*/
{
0, /* will be updated before using */
@@ -57,16 +67,6 @@
},
};
#else /* TFM_LVL == 3 */
-#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0]))
-
-#define MPU_REGION_VENEERS 0
-#define MPU_REGION_TFM_UNPRIV_CODE 1
-#define MPU_REGION_NS_STACK 2
-#define PARTITION_REGION_RO 3
-#define PARTITION_REGION_RW_STACK 4
-#ifdef TFM_SP_META_PTR_ENABLE
-#define MPU_REGION_SP_META_PTR 7
-#endif /* TFM_SP_META_PTR_ENABLE */
REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Base);
REGION_DECLARE(Load$$LR$$, LR_VENEER, $$Limit);
@@ -86,7 +86,7 @@
const struct mpu_armv8m_region_cfg_t region_cfg[] = {
/* Veneer region */
{
- MPU_REGION_VENEERS,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Base),
(uint32_t)®ION_NAME(Load$$LR$$, LR_VENEER, $$Limit),
MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
@@ -96,7 +96,7 @@
},
/* TFM Core unprivileged code region */
{
- MPU_REGION_TFM_UNPRIV_CODE,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Base),
(uint32_t)®ION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit),
MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
@@ -106,7 +106,7 @@
},
/* NSPM PSP */
{
- MPU_REGION_NS_STACK,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Image$$, ER_INITIAL_PSP, $$ZI$$Base),
(uint32_t)®ION_NAME(Image$$, ER_INITIAL_PSP, $$ZI$$Limit),
MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
@@ -116,7 +116,7 @@
},
/* RO region */
{
- PARTITION_REGION_RO,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Image$$, TFM_APP_CODE_START, $$Base),
(uint32_t)®ION_NAME(Image$$, TFM_APP_CODE_END, $$Base),
MPU_ARMV8M_MAIR_ATTR_CODE_IDX,
@@ -126,7 +126,7 @@
},
/* RW, ZI and stack as one region */
{
- PARTITION_REGION_RW_STACK,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Image$$, TFM_APP_RW_STACK_START, $$Base),
(uint32_t)®ION_NAME(Image$$, TFM_APP_RW_STACK_END, $$Base),
MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
@@ -137,7 +137,7 @@
#ifdef TFM_SP_META_PTR_ENABLE
/* TFM partition metadata pointer region */
{
- MPU_REGION_SP_META_PTR,
+ 0, /* will be updated before using */
(uint32_t)®ION_NAME(Image$$, TFM_SP_META_PTR, $$RW$$Base),
(uint32_t)®ION_NAME(Image$$, TFM_SP_META_PTR, $$RW$$Limit),
MPU_ARMV8M_MAIR_ATTR_DATA_IDX,
@@ -150,103 +150,6 @@
#endif /* TFM_LVL == 3 */
#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
-#ifdef TFM_FIH_PROFILE_ON
-fih_int tfm_hal_set_up_static_boundaries(void)
-{
- fih_int fih_rc = fih_int_encode(TFM_HAL_ERROR_GENERIC);
-
- /* Set up isolation boundaries between SPE and NSPE */
- FIH_CALL(sau_and_idau_cfg, fih_rc);
- if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) {
- FIH_PANIC;
- }
-
- FIH_CALL(mpc_init_cfg, fih_rc);
- if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) {
- FIH_PANIC;
- }
-
- FIH_CALL(ppc_init_cfg, fih_rc);
- if (fih_not_eq(fih_rc, fih_int_encode(TFM_PLAT_ERR_SUCCESS))) {
- FIH_PANIC;
- }
-
- /* Set up static isolation boundaries inside SPE */
-#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
- int32_t i;
- struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
-
- FIH_CALL(mpu_armv8m_clean, fih_rc, &dev_mpu_s);
- if (fih_not_eq(fih_rc, fih_int_encode(MPU_ARMV8M_OK))) {
- FIH_PANIC;
- }
-
-#if TFM_LVL == 3
- uint32_t cnt;
-
- /* Update MPU region numbers. The numbers start from 0 and are continuous */
- cnt = sizeof(isolation_regions) / sizeof(isolation_regions[0]);
- g_static_region_cnt = cnt;
- for (i = 0; i < cnt; i++) {
- /* Update region number */
- isolation_regions[i].region_nr = i;
- /* Enable regions */
- FIH_CALL(mpu_armv8m_region_enable, fih_rc, &dev_mpu_s,
- &isolation_regions[i]);
- if (fih_not_eq(fih_rc, fih_int_encode(MPU_ARMV8M_OK))) {
- FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
- }
- }
-#else /* TFM_LVL == 3 */
- for (i = 0; i < ARRAY_SIZE(region_cfg); i++) {
-
- FIH_CALL(mpu_armv8m_region_enable, fih_rc, &dev_mpu_s,
- (struct mpu_armv8m_region_cfg_t *)®ion_cfg[i]);
- if (fih_not_eq(fih_rc, fih_int_encode(MPU_ARMV8M_OK))) {
- FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
- }
- }
-#endif /* TFM_LVL == 3 */
-
- /* Enable MPU */
- FIH_CALL(mpu_armv8m_enable, fih_rc, &dev_mpu_s,
- PRIVILEGED_DEFAULT_ENABLE, HARDFAULT_NMI_ENABLE);
- if (fih_not_eq(fih_rc, fih_int_encode(MPU_ARMV8M_OK))) {
- FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
- }
-#endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
-
- fih_rc = fih_int_encode(TFM_HAL_SUCCESS);
- FIH_RET(fih_rc);
-}
-
-#if TFM_LVL == 3
-fih_int tfm_hal_mpu_update_partition_boundary(uintptr_t start,
- uintptr_t end)
-{
- fih_int fih_rc = fih_int_encode(TFM_HAL_ERROR_GENERIC);
- struct mpu_armv8m_region_cfg_t cfg;
- struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
-
- /* Partition boundary regions is right after static regions */
- cfg.region_nr = g_static_region_cnt;
- cfg.region_base = start;
- cfg.region_limit = end;
- cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_IDX;
- cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
- cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
- cfg.attr_sh = MPU_ARMV8M_SH_NONE;
-
- FIH_CALL(mpu_armv8m_region_enable, fih_rc, &dev_mpu_s, &cfg);
- if (fih_not_eq(fih_rc, fih_int_encode(MPU_ARMV8M_OK))) {
- FIH_RET(fih_int_encode(TFM_HAL_ERROR_GENERIC));
- }
-
- fih_rc = fih_int_encode(TFM_HAL_SUCCESS);
- FIH_RET(fih_rc);
-}
-#endif /* TFM_LVL == 3 */
-#else /* TFM_FIH_PROFILE_ON */
enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void)
{
/* Set up isolation boundaries between SPE and NSPE */
@@ -258,34 +161,44 @@
/* Set up static isolation boundaries inside SPE */
#ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
+ struct mpu_armv8m_region_cfg_t localcfg;
int32_t i;
- struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
mpu_armv8m_clean(&dev_mpu_s);
#if TFM_LVL == 3
- uint32_t cnt;
-
- /* Update MPU region numbers. The numbers start from 0 and are continuous */
- cnt = sizeof(isolation_regions) / sizeof(isolation_regions[0]);
- g_static_region_cnt = cnt;
- for (i = 0; i < cnt; i++) {
+ /*
+ * Update MPU region numbers. The numbers start from 0 and are continuous.
+ * Under isolation level3, at lease one MPU region is reserved for private
+ * data asset.
+ */
+ if (ARRAY_SIZE(isolation_regions) >= MPU_REGION_NUM) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ for (i = 0; i < ARRAY_SIZE(isolation_regions); i++) {
+ spm_memcpy(&localcfg, &isolation_regions[i], sizeof(localcfg));
/* Update region number */
- isolation_regions[i].region_nr = i;
+ localcfg.region_nr = i;
/* Enable regions */
- if (mpu_armv8m_region_enable(&dev_mpu_s, &isolation_regions[i])
- != MPU_ARMV8M_OK) {
+ if (mpu_armv8m_region_enable(&dev_mpu_s, &localcfg) != MPU_ARMV8M_OK) {
return TFM_HAL_ERROR_GENERIC;
}
}
+ n_configured_regions = i;
#else /* TFM_LVL == 3 */
+ if (ARRAY_SIZE(region_cfg) > MPU_REGION_NUM) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
for (i = 0; i < ARRAY_SIZE(region_cfg); i++) {
+ spm_memcpy(&localcfg, ®ion_cfg[i], sizeof(localcfg));
+ localcfg.region_nr = i;
if (mpu_armv8m_region_enable(&dev_mpu_s,
- (struct mpu_armv8m_region_cfg_t *)®ion_cfg[i])
+ (struct mpu_armv8m_region_cfg_t *)&localcfg)
!= MPU_ARMV8M_OK) {
return TFM_HAL_ERROR_GENERIC;
}
}
+ n_configured_regions = i;
#endif /* TFM_LVL == 3 */
/* Enable MPU */
@@ -299,27 +212,227 @@
return TFM_HAL_SUCCESS;
}
-#if TFM_LVL == 3
-enum tfm_hal_status_t tfm_hal_mpu_update_partition_boundary(uintptr_t start,
- uintptr_t end)
+/*
+ * Implementation of tfm_hal_bind_boundaries() on AN521:
+ *
+ * The API encodes some attributes into a handle and returns it to SPM.
+ * The attributes include isolation boundaries, privilege, and mmio information.
+ * When scheduler switches running partitions, SPM compares the handle between
+ * partitions to know if boundary update is necessary. If update is required,
+ * SPM passes the handle to platform to do platform settings and update
+ * isolation boundaries.
+ *
+ * The handle should be unique under isolation level 3. The implementation
+ * encodes an index at the highest 8 bits to assure handle uniqueness. While
+ * under isolation level 1/2, handles may not be unique.
+ *
+ * The encoding format assignment:
+ * - For isolation level 3
+ * BIT | 31 24 | 23 20 | ... | 7 4 | 3 0 |
+ * | Unique Index | Region Attr 5 | ... | Region Attr 1 | Privileged |
+ *
+ * In which the "Region Attr i" is:
+ * BIT | 3 | 2 0 |
+ * | 1: RW, 0: RO | MMIO Index |
+ *
+ * - For isolation level 1/2
+ * BIT | 31 0 |
+ * | 1: privileged, 0: unprivileged |
+ *
+ * This is a reference implementation on AN521, and may have some limitations.
+ * 1. The maximum number of allowed MMIO regions is 5.
+ * 2. Highest 8 bits are for index. It supports 256 unique handles at most.
+ */
+enum tfm_hal_status_t tfm_hal_bind_boundaries(
+ const struct partition_load_info_t *p_ldinf,
+ void **pp_boundaries)
{
- struct mpu_armv8m_region_cfg_t cfg;
- enum mpu_armv8m_error_t mpu_err;
- struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
+ uint32_t i, j;
+ bool privileged;
+ const struct asset_desc_t *p_asset;
+ struct platform_data_t *plat_data_ptr;
+#if TFM_LVL == 2
+ struct mpu_armv8m_region_cfg_t localcfg;
+#elif TFM_LVL == 3
+ uint32_t partition_attrs = 0;
+#endif
- /* Partition boundary regions is right after static regions */
- cfg.region_nr = g_static_region_cnt;
- cfg.region_base = start;
- cfg.region_limit = end;
- cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_IDX;
- cfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
- cfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
- cfg.attr_sh = MPU_ARMV8M_SH_NONE;
- mpu_err = mpu_armv8m_region_enable(&dev_mpu_s, &cfg);
- if (mpu_err != MPU_ARMV8M_OK) {
+ if (!p_ldinf || !pp_boundaries) {
return TFM_HAL_ERROR_GENERIC;
}
+
+#if TFM_LVL == 1
+ privileged = true;
+#else
+ privileged = !!(p_ldinf->flags & SPM_PART_FLAG_PSA_ROT);
+#endif
+
+ p_asset = (const struct asset_desc_t *)LOAD_INFO_ASSET(p_ldinf);
+
+ /*
+ * Validate if the named MMIO of partition is allowed by the platform.
+ * Otherwise, skip validation.
+ *
+ * NOTE: Need to add validation of numbered MMIO if platform requires.
+ */
+ for (i = 0; i < p_ldinf->nassets; i++) {
+ if (!(p_asset[i].attr & ASSET_ATTR_NAMED_MMIO)) {
+ continue;
+ }
+ for (j = 0; j < ARRAY_SIZE(partition_named_mmio_list); j++) {
+ if (p_asset[i].dev.dev_ref == partition_named_mmio_list[j]) {
+ break;
+ }
+ }
+
+ if (j == ARRAY_SIZE(partition_named_mmio_list)) {
+ /* The MMIO asset is not in the allowed list of platform. */
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ /* Assume PPC & MPC settings are required even under level 1 */
+ plat_data_ptr = REFERENCE_TO_PTR(p_asset[i].dev.dev_ref,
+ struct platform_data_t *);
+
+ ppc_configure_to_secure(plat_data_ptr->periph_ppc_bank,
+ plat_data_ptr->periph_ppc_loc);
+ if (privileged) {
+ ppc_clr_secure_unpriv(plat_data_ptr->periph_ppc_bank,
+ plat_data_ptr->periph_ppc_loc);
+ } else {
+ ppc_en_secure_unpriv(plat_data_ptr->periph_ppc_bank,
+ plat_data_ptr->periph_ppc_loc);
+ }
+#if TFM_LVL == 2
+ /*
+ * Static boundaries are set. Set up MPU region for MMIO.
+ * Setup regions for unprivileged assets only.
+ */
+ if (!privileged) {
+ localcfg.region_base = plat_data_ptr->periph_start;
+ localcfg.region_limit = plat_data_ptr->periph_limit;
+ localcfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX;
+ localcfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
+ localcfg.attr_sh = MPU_ARMV8M_SH_NONE;
+ localcfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
+ localcfg.region_nr = n_configured_regions++;
+
+ if (mpu_armv8m_region_enable(&dev_mpu_s, &localcfg)
+ != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ }
+#elif TFM_LVL == 3
+ /* Encode MMIO attributes into the "partition_attrs". */
+ partition_attrs <<= HANDLE_PER_ATTR_BITS;
+ partition_attrs |= ((j + 1) & HANDLE_ATTR_INDEX_MASK);
+ if (p_asset[i].attr & ASSET_ATTR_READ_WRITE) {
+ partition_attrs |= HANDLE_ATTR_RW_POS;
+ }
+#endif
+ }
+
+#if TFM_LVL == 3
+ partition_attrs <<= HANDLE_PER_ATTR_BITS;
+ partition_attrs |= ((uint8_t)privileged) & HANDLE_ATTR_PRIV_MASK;
+ /*
+ * Highest 8 bits are reserved for index, if they are non-zero, MMIO numbers
+ * must have exceeded the limit of 5.
+ */
+ if (partition_attrs & HANDLE_INDEX_MASK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ HANDLE_ENCODE_INDEX(partition_attrs, idx_boundary_handle);
+ *pp_boundaries = (void *)partition_attrs;
+#else
+ *pp_boundaries = (void *)(((uint32_t)privileged) & HANDLE_ATTR_PRIV_MASK);
+#endif
+
return TFM_HAL_SUCCESS;
}
-#endif /* TFM_LVL == 3 */
-#endif /* TFM_FIH_PROFILE_ON */
+
+enum tfm_hal_status_t tfm_hal_update_boundaries(
+ const struct partition_load_info_t *p_ldinf,
+ void *p_boundaries)
+{
+ CONTROL_Type ctrl;
+ uint32_t local_handle = (uint32_t)p_boundaries;
+ bool privileged = !!(local_handle & HANDLE_ATTR_PRIV_MASK);
+#if TFM_LVL == 3
+ struct mpu_armv8m_region_cfg_t localcfg;
+ uint32_t i, mmio_index;
+ struct platform_data_t *plat_data_ptr;
+ struct asset_desc_t *rt_mem;
+#endif
+
+ /* Privileged level is required to be set always */
+ ctrl.w = __get_CONTROL();
+ ctrl.b.nPRIV = privileged ? 0 : 1;
+ __set_CONTROL(ctrl.w);
+
+#if TFM_LVL == 3
+ if (!p_ldinf) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+
+ /* Update regions, for unprivileged partitions only */
+ if (privileged) {
+ return TFM_HAL_SUCCESS;
+ }
+
+ /* Setup runtime memory first */
+ localcfg.attr_exec = MPU_ARMV8M_XN_EXEC_NEVER;
+ localcfg.attr_sh = MPU_ARMV8M_SH_NONE;
+ localcfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_IDX;
+ localcfg.attr_access = MPU_ARMV8M_AP_RW_PRIV_UNPRIV;
+ rt_mem = (struct asset_desc_t *)LOAD_INFO_ASSET(p_ldinf);
+ /*
+ * AN521 shortcut: The first item is the only runtime memory asset.
+ * Platforms with many memory assets please check this part.
+ */
+ for (i = 0;
+ i < p_ldinf->nassets && !(rt_mem[i].attr & ASSET_ATTR_MMIO);
+ i++) {
+ localcfg.region_nr = n_configured_regions + i;
+ localcfg.region_base = rt_mem[i].mem.start;
+ localcfg.region_limit = rt_mem[i].mem.limit;
+
+ if (mpu_armv8m_region_enable(&dev_mpu_s, &localcfg) != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ }
+
+ /* Named MMIO part */
+ local_handle = local_handle & (~HANDLE_INDEX_MASK);
+ local_handle >>= HANDLE_PER_ATTR_BITS;
+ mmio_index = local_handle & HANDLE_ATTR_INDEX_MASK;
+
+ localcfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DEVICE_IDX;
+
+ i = n_configured_regions + i;
+ while (mmio_index && i < MPU_REGION_NUM) {
+ plat_data_ptr =
+ (struct platform_data_t *)partition_named_mmio_list[mmio_index - 1];
+ localcfg.region_nr = i++;
+ localcfg.attr_access = (local_handle & HANDLE_ATTR_RW_POS)?
+ MPU_ARMV8M_AP_RW_PRIV_UNPRIV :
+ MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
+ localcfg.region_base = plat_data_ptr->periph_start;
+ localcfg.region_limit = plat_data_ptr->periph_limit;
+
+ if (mpu_armv8m_region_enable(&dev_mpu_s, &localcfg) != MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+
+ local_handle >>= HANDLE_PER_ATTR_BITS;
+ mmio_index = local_handle & HANDLE_ATTR_INDEX_MASK;
+ }
+
+ /* Disable unused regions */
+ while (i < MPU_REGION_NUM) {
+ if (mpu_armv8m_region_disable(&dev_mpu_s, i++)!= MPU_ARMV8M_OK) {
+ return TFM_HAL_ERROR_GENERIC;
+ }
+ }
+#endif
+ return TFM_HAL_SUCCESS;
+}
diff --git a/platform/include/tfm_hal_isolation.h b/platform/include/tfm_hal_isolation.h
index 18a8c50..120cdf5 100644
--- a/platform/include/tfm_hal_isolation.h
+++ b/platform/include/tfm_hal_isolation.h
@@ -10,8 +10,9 @@
#include <stddef.h>
#include <stdint.h>
-#include "fih.h"
#include "tfm_hal_defs.h"
+#include "load/partition_defs.h"
+#include "load/asset_defs.h"
#ifdef __cplusplus
extern "C" {
@@ -26,6 +27,7 @@
#define TFM_HAL_ACCESS_NS (1UL << 5)
#ifdef TFM_FIH_PROFILE_ON
+#include "fih.h"
/**
* \brief Sets up the static isolation boundaries which are constant throughout
* the runtime of the system, including the SPE/NSPE and partition
@@ -36,24 +38,20 @@
*/
fih_int tfm_hal_set_up_static_boundaries(void);
-#if TFM_LVL == 3
/**
- * \brief Updates the partition isolation boundary for isolation level 3.
- * The boundary protects the private data of the running partition.
- * The boundary is updated with SPM switching partition in level 3.
+ * \brief Update the isolation boundaries.
*
- * \param[in] start start address of the partition boundary.
- * \param[in] end end address of the partition boundary.
+ * \param[in] p_ldinf Partition load information.
+ * \param[in] p_boundaries Platform boundary handle for partition.
*
- * \return TFM_HAL_SUCCESS - the isolation boundary has been set up.
- * TFM_HAL_ERROR_GENERIC - failed to set up the isolation boundary.
+ * \return TFM_HAL_SUCCESS The isolation boundaries update succeeded.
+ * TFM_HAL_ERROR_GENERIC Failed to update the isolation boundaries.
*
* \note When FIH_ENABLE_DOUBLE_VARS is enabled, the return code will be
* wrapped and protected in \ref fih_int structure.
*/
-fih_int tfm_hal_mpu_update_partition_boundary(uintptr_t start,
- uintptr_t end);
-#endif
+fih_int tfm_hal_update_boundaries(const struct partition_load_info_t *p_ldinf,
+ void *p_boundaries);
#else /* TFM_FIH_PROFILE_ON */
/**
* \brief Sets up the static isolation boundaries which are constant throughout
@@ -62,30 +60,21 @@
*
* \return TFM_HAL_SUCCESS - the isolation boundaries have been set up.
* TFM_HAL_ERROR_GENERIC - failed to set up the isolation boundaries.
- *
- * \note When FIH_ENABLE_DOUBLE_VARS is enabled, the return code will be
- * wrapped and protected in \ref fih_int structure.
*/
enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void);
-#if TFM_LVL == 3
/**
- * \brief Updates the partition isolation boundary for isolation level 3.
- * The boundary protects the private data of the running partition.
- * The boundary is updated with SPM switching partition in level 3.
+ * \brief Update the isolation boundaries.
*
- * \param[in] start start address of the partition boundary.
- * \param[in] end end address of the partition boundary.
+ * \param[in] p_ldinf Partition load information.
+ * \param[in] p_boundaries Platform boundary handle for partition.
*
- * \return TFM_HAL_SUCCESS - the isolation boundary has been set up.
- * TFM_HAL_ERROR_GENERIC - failed to set up the isolation boundary.
- *
- * \note When FIH_ENABLE_DOUBLE_VARS is enabled, the return code will be
- * wrapped and protected in \ref fih_int structure.
+ * \return TFM_HAL_SUCCESS The isolation boundaries update succeeded.
+ * TFM_HAL_ERROR_GENERIC Failed to update the isolation boundaries.
*/
-enum tfm_hal_status_t tfm_hal_mpu_update_partition_boundary(uintptr_t start,
- uintptr_t end);
-#endif
+enum tfm_hal_status_t tfm_hal_update_boundaries(
+ const struct partition_load_info_t *p_ldinf,
+ void *p_boundaries);
#endif /* TFM_FIH_PROFILE_ON */
/**
@@ -108,6 +97,28 @@
size_t size,
uint32_t attr);
+/**
+ * \brief This API binds partition boundaries with the platform. The platform
+ * maintains the platform-specific settings for SPM further
+ * usage, such as update partition hardware boundaries or
+ * check resource accessibility. The platform needs to manage
+ * the settings with internal mechanism, and return a handle
+ * to SPM. SPM delivers this handle back to platform when
+ * necessary. And SPM checks this handle to decide if the
+ * platform-specific settings need to be updated. Hence
+ * multiple partitions can have the same handle if they have
+ * the same platform-specific settings, depending on isolation level.
+ *
+ * \param[in] p_ldinf Partition load information.
+ * \param[in] pp_boundaries Pointer of the boundary handle
+ *
+ * \return TFM_HAL_SUCCESS - A platform handle binding success.
+ * TFM_HAL_ERROR_GENERIC - Error occured while binding.
+ */
+enum tfm_hal_status_t tfm_hal_bind_boundaries(
+ const struct partition_load_info_t *p_ldinf,
+ void **pp_boundaries);
+
#ifdef __cplusplus
}
#endif
diff --git a/platform/include/tfm_spm_hal.h b/platform/include/tfm_spm_hal.h
index 91e9807..3ea57aa 100644
--- a/platform/include/tfm_spm_hal.h
+++ b/platform/include/tfm_spm_hal.h
@@ -322,8 +322,7 @@
*
* \return True if the access is granted, false otherwise.
*/
-bool tfm_spm_hal_has_access_to_region(const void *p, size_t s,
- int flags);
+bool tfm_spm_hal_has_access_to_region(const void *p, size_t s, int flags);
#endif /* !defined(__SAUREGION_PRESENT) || (__SAUREGION_PRESENT == 0) */
#endif /* __TFM_SPM_HAL_H__ */
diff --git a/secure_fw/spm/cmsis_psa/spm_ipc.c b/secure_fw/spm/cmsis_psa/spm_ipc.c
index 12f65a0..a578a18 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.c
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.c
@@ -266,34 +266,6 @@
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 @@
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 @@
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 @@
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 1c28475..64d8cac 100644
--- a/secure_fw/spm/cmsis_psa/spm_ipc.h
+++ b/secure_fw/spm/cmsis_psa/spm_ipc.h
@@ -85,7 +85,7 @@
*/
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 @@
*/
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 0987f07..60a0124 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 @@
} 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 @@
}
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 e88e2d1..b5af2c5 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 26597b2..d8fbc16 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) + \