text: /*
   * Copyright (c) 2020, Arm Limited. All rights reserved.
   *
   * SPDX-License-Identifier: BSD-3-Clause
   *
   */
  
  #include "cmsis.h"
  #include "Driver_Common.h"
  #include "mpu_armv8m_drv.h"
  #include "region.h"
  #include "target_cfg.h"
  #include "tfm_hal_isolation.h"
  
  #ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
  
  #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
  #define PARTITION_REGION_PERIPH      5
  #ifdef TFM_SP_META_PTR_ENABLE
  #define MPU_REGION_SP_META_PTR       7
  #endif /* TFM_SP_META_PTR_ENABLE */
  
  REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);
  REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit);
  REGION_DECLARE(Image$$, TFM_APP_CODE_START, $$Base);
  REGION_DECLARE(Image$$, TFM_APP_CODE_END, $$Base);
  REGION_DECLARE(Image$$, TFM_APP_RW_STACK_START, $$Base);
  REGION_DECLARE(Image$$, TFM_APP_RW_STACK_END, $$Base);
  REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Base);
  REGION_DECLARE(Image$$, ARM_LIB_STACK, $$ZI$$Limit);
  #ifdef TFM_SP_META_PTR_ENABLE
  REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$RW$$Base);
  REGION_DECLARE(Image$$, TFM_SP_META_PTR, $$RW$$Limit);
  #endif /* TFM_SP_META_PTR_ENABLE */
  
  extern const struct memory_region_limits memory_regions;
  #endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
  
  enum tfm_hal_status_t tfm_hal_set_up_static_boundaries(void)
  {
      /* Set up isolation boundaries between SPE and NSPE */
      sau_and_idau_cfg();
  
      if (mpc_init_cfg() != ARM_DRIVER_OK) {
          return TFM_HAL_ERROR_GENERIC;
      }
  
      if (ppc_init_cfg() != ARM_DRIVER_OK) {
          return TFM_HAL_ERROR_GENERIC;
      }
  
      /* Set up static isolation boundaries inside SPE */
  #ifdef CONFIG_TFM_ENABLE_MEMORY_PROTECT
      struct mpu_armv8m_region_cfg_t region_cfg;
  
      mpu_clean();
  
      /* Veneer region */
      region_cfg.region_nr = MPU_REGION_VENEERS;
      region_cfg.region_base = memory_regions.veneer_base;
      region_cfg.region_limit = memory_regions.veneer_limit;
      region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_CODE_IDX;
      region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
      region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
      region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK;
      if (mpu_region_enable(&region_cfg) != MPU_ARMV8M_OK) {
          return TFM_HAL_ERROR_GENERIC;
      }
  
      /* TFM Core unprivileged code region */
      region_cfg.region_nr = MPU_REGION_TFM_UNPRIV_CODE;
      region_cfg.region_base =
          (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);
      region_cfg.region_limit =
          (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit);
      region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_CODE_IDX;
      region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
      region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
      region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK;
      if (mpu_region_enable(&region_cfg) != MPU_ARMV8M_OK) {
          return TFM_HAL_ERROR_GENERIC;
      }
  
      /* NSPM PSP */
      region_cfg.region_nr = MPU_REGION_NS_STACK;
      region_cfg.region_base =
          (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Base);
      region_cfg.region_limit =
          (uint32_t)&REGION_NAME(Image$$, ARM_LIB_STACK, $$ZI$$Limit);
      region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_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;
      if (mpu_region_enable(&region_cfg) != MPU_ARMV8M_OK) {
          return TFM_HAL_ERROR_GENERIC;
      }
  
      /* RO region */
      region_cfg.region_nr = PARTITION_REGION_RO;
      region_cfg.region_base =
          (uint32_t)&REGION_NAME(Image$$, TFM_APP_CODE_START, $$Base);
      region_cfg.region_limit =
          (uint32_t)&REGION_NAME(Image$$, TFM_APP_CODE_END, $$Base);
      region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_CODE_IDX;
      region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
      region_cfg.attr_sh = MPU_ARMV8M_SH_NONE;
      region_cfg.attr_exec = MPU_ARMV8M_XN_EXEC_OK;
      if (mpu_region_enable(&region_cfg) != MPU_ARMV8M_OK) {
          return TFM_HAL_ERROR_GENERIC;
      }
  
      /* RW, ZI and stack as one region */
      region_cfg.region_nr = PARTITION_REGION_RW_STACK;
      region_cfg.region_base =
          (uint32_t)&REGION_NAME(Image$$, TFM_APP_RW_STACK_START, $$Base);
      region_cfg.region_limit =
          (uint32_t)&REGION_NAME(Image$$, TFM_APP_RW_STACK_END, $$Base);
      region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_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;
      if (mpu_region_enable(&region_cfg) != MPU_ARMV8M_OK) {
          return TFM_HAL_ERROR_GENERIC;
      }
  
  #ifdef TFM_SP_META_PTR_ENABLE
      /* TFM partition metadata pointer region */
      region_cfg.region_nr = MPU_REGION_SP_META_PTR;
      region_cfg.region_base =
          (uint32_t)&REGION_NAME(Image$$, TFM_SP_META_PTR, $$RW$$Base);
      region_cfg.region_limit =
          (uint32_t)&REGION_NAME(Image$$, TFM_SP_META_PTR, $$RW$$Limit);
      region_cfg.region_attridx = MPU_ARMV8M_MAIR_ATTR_DATA_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;
      if (mpu_region_enable(&region_cfg) != MPU_ARMV8M_OK) {
          return TFM_HAL_ERROR_GENERIC;
      }
  #endif
  
      mpu_enable(PRIVILEGED_DEFAULT_ENABLE, HARDFAULT_NMI_ENABLE);
  #endif /* CONFIG_TFM_ENABLE_MEMORY_PROTECT */
  
      return TFM_HAL_SUCCESS;
  }
  