aboutsummaryrefslogtreecommitdiff
path: root/platform/ext/target/mps3/fvp_sse300/spm_hal.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/ext/target/mps3/fvp_sse300/spm_hal.c')
-rw-r--r--platform/ext/target/mps3/fvp_sse300/spm_hal.c203
1 files changed, 203 insertions, 0 deletions
diff --git a/platform/ext/target/mps3/fvp_sse300/spm_hal.c b/platform/ext/target/mps3/fvp_sse300/spm_hal.c
new file mode 100644
index 0000000000..45205aa00b
--- /dev/null
+++ b/platform/ext/target/mps3/fvp_sse300/spm_hal.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stdio.h>
+#include "cmsis.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"
+#include "region.h"
+
+/* 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 6
+#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_init_isolation_hw(void)
+{
+ enum tfm_plat_err_t err = TFM_PLAT_ERR_SUCCESS;
+
+ sau_and_idau_cfg();
+
+ err = ppc_init_cfg();
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ ERROR_MSG("Error during initial PPC configuration!");
+ return err;
+ }
+
+ err = mpc_init_cfg();
+ if (err != TFM_PLAT_ERR_SUCCESS) {
+ ERROR_MSG("Error during initial MPC configuration!");
+ return err;
+ }
+
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+enum tfm_plat_err_t tfm_spm_hal_configure_default_isolation(
+ uint32_t partition_idx,
+ const struct tfm_spm_partition_platform_data_t *platform_data)
+{
+#if defined(CONFIG_TFM_ENABLE_MEMORY_PROTECT) && (TFM_LVL != 1)
+ bool privileged = tfm_is_partition_privileged(partition_idx);
+ struct mpu_armv8m_region_cfg_t region_cfg;
+#endif
+
+ if (!platform_data) {
+ return 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) {
+ 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, &region_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_mask);
+ }
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+void MPC_Handler(void)
+{
+ /* Clear MPC interrupt flag and pending MPC IRQ */
+ mpc_clear_irq();
+ NVIC_ClearPendingIRQ(MPC_IRQn);
+
+ /* Print fault message and block execution */
+ ERROR_MSG("Oops... MPC fault!!!");
+
+ /* Inform TF-M core that isolation boundary has been violated */
+ tfm_access_violation_handler();
+}
+
+void PPC_Handler(void)
+{
+ /* Clear PPC interrupt flag and pending PPC IRQ */
+ ppc_clear_irq();
+ NVIC_ClearPendingIRQ(PPC_IRQn);
+
+ /* Print fault message*/
+ ERROR_MSG("Oops... PPC fault!!!");
+
+ /* Inform TF-M core that isolation boundary has been violated */
+ tfm_access_violation_handler();
+}
+
+uint32_t tfm_spm_hal_get_ns_VTOR(void)
+{
+ return memory_regions.non_secure_code_start;
+}
+
+uint32_t tfm_spm_hal_get_ns_MSP(void)
+{
+ return *((uint32_t *)memory_regions.non_secure_code_start);
+}
+
+uint32_t tfm_spm_hal_get_ns_entry_point(void)
+{
+ return *((uint32_t *)(memory_regions.non_secure_code_start+ 4));
+}
+
+enum tfm_plat_err_t tfm_spm_hal_set_secure_irq_priority(IRQn_Type irq_line,
+ uint32_t priority)
+{
+ uint32_t quantized_priority = priority >> (8U - __NVIC_PRIO_BITS);
+ NVIC_SetPriority(irq_line, quantized_priority);
+ return TFM_PLAT_ERR_SUCCESS;
+}
+
+void tfm_spm_hal_clear_pending_irq(IRQn_Type irq_line)
+{
+ NVIC_ClearPendingIRQ(irq_line);
+}
+
+void tfm_spm_hal_enable_irq(IRQn_Type irq_line)
+{
+ NVIC_EnableIRQ(irq_line);
+}
+
+void tfm_spm_hal_disable_irq(IRQn_Type irq_line)
+{
+ NVIC_DisableIRQ(irq_line);
+}
+
+enum irq_target_state_t tfm_spm_hal_set_irq_target_state(
+ IRQn_Type irq_line,
+ enum irq_target_state_t target_state)
+{
+ uint32_t result;
+
+ if (target_state == TFM_IRQ_TARGET_STATE_SECURE) {
+ result = NVIC_ClearTargetState(irq_line);
+ } else {
+ result = NVIC_SetTargetState(irq_line);
+ }
+
+ if (result) {
+ return TFM_IRQ_TARGET_STATE_NON_SECURE;
+ } else {
+ return TFM_IRQ_TARGET_STATE_SECURE;
+ }
+}
+
+enum tfm_plat_err_t tfm_spm_hal_enable_fault_handlers(void)
+{
+ return enable_fault_handlers();
+}
+
+enum tfm_plat_err_t tfm_spm_hal_system_reset_cfg(void)
+{
+ return system_reset_cfg();
+}
+
+enum tfm_plat_err_t tfm_spm_hal_init_debug(void)
+{
+ return init_debug();
+}
+
+enum tfm_plat_err_t tfm_spm_hal_nvic_interrupt_target_state_cfg(void)
+{
+ return nvic_interrupt_target_state_cfg();
+}
+
+enum tfm_plat_err_t tfm_spm_hal_nvic_interrupt_enable(void)
+{
+ return nvic_interrupt_enable();
+}