diff options
Diffstat (limited to 'platform/ext/target/arm/mps2/an519/spm_hal.c')
-rw-r--r-- | platform/ext/target/arm/mps2/an519/spm_hal.c | 160 |
1 files changed, 160 insertions, 0 deletions
diff --git a/platform/ext/target/arm/mps2/an519/spm_hal.c b/platform/ext/target/arm/mps2/an519/spm_hal.c new file mode 100644 index 0000000000..02cd47a97b --- /dev/null +++ b/platform/ext/target/arm/mps2/an519/spm_hal.c @@ -0,0 +1,160 @@ +/* + * 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" + +/* Import MPC driver */ +extern ARM_DRIVER_MPC Driver_SRAM1_MPC; + +/* Get address of memory regions to configure MPU */ +extern const struct memory_region_limits memory_regions; + +enum tfm_plat_err_t tfm_spm_hal_configure_default_isolation( + uint32_t partition_idx, + const struct platform_data_t *platform_data) +{ + bool privileged = tfm_is_partition_privileged(partition_idx); + + if (!platform_data) { + return TFM_PLAT_ERR_INVALID_INPUT; + } + + 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; +} + +void MPC_Handler(void) +{ + /* Clear MPC interrupt flag and pending MPC IRQ */ + Driver_SRAM1_MPC.ClearInterrupt(); + 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) +{ + /* + * Due to an issue on the FVP, the PPC fault doesn't trigger a + * PPC IRQ which is handled by the PPC_handler. + * In the FVP execution, this code is not execute. + */ + + /* 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(); +} |