Platform: Move isolation hw code to SPM hal

Moves code related to hardware specific aspects of MPU, PPC, MPC and SAU
to SPM hal. Leaves the code parts that use cmse defined interface to
access these peripherals in secure_sw folder.

Change-Id: I594847686cac51ee0f9fae217152b6e90723bb9e
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/platform/ext/Mps2AN519.cmake b/platform/ext/Mps2AN519.cmake
index 74cbb9a..a890294 100755
--- a/platform/ext/Mps2AN519.cmake
+++ b/platform/ext/Mps2AN519.cmake
@@ -96,7 +96,9 @@
   message(FATAL_ERROR "Configuration variable BUILD_TARGET_CFG (true|false) is undefined!")
 elseif(BUILD_TARGET_CFG)
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/mps2/an519/target_cfg.c")
-  list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/mps2/an519/spm_hal.c")
+  list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an519/spm_hal.c")
+  list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an519/native_drivers/mpu_armv8m_drv.c")
+  embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
 endif()
 
 if (NOT DEFINED BUILD_TARGET_HARDWARE_KEYS)
diff --git a/platform/ext/Mps2AN521.cmake b/platform/ext/Mps2AN521.cmake
index f44db7b..0b388ce 100755
--- a/platform/ext/Mps2AN521.cmake
+++ b/platform/ext/Mps2AN521.cmake
@@ -113,7 +113,9 @@
   message(FATAL_ERROR "Configuration variable BUILD_TARGET_CFG (true|false) is undefined!")
 elseif(BUILD_TARGET_CFG)
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/mps2/an521/target_cfg.c")
-  list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/mps2/an521/spm_hal.c")
+  list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an521/spm_hal.c")
+  list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an521/native_drivers/mpu_armv8m_drv.c")
+  embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
 endif()
 
 if (NOT DEFINED BUILD_TARGET_HARDWARE_KEYS)
diff --git a/platform/ext/musca_a.cmake b/platform/ext/musca_a.cmake
index 3789170..985c3bc 100755
--- a/platform/ext/musca_a.cmake
+++ b/platform/ext/musca_a.cmake
@@ -96,7 +96,9 @@
   message(FATAL_ERROR "Configuration variable BUILD_TARGET_CFG (true|false) is undefined!")
 elseif(BUILD_TARGET_CFG)
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/musca_a/target_cfg.c")
-  list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/musca_a/spm_hal.c")
+  list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_a/spm_hal.c")
+  list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_a/Native_Driver/mpu_armv8m_drv.c")
+  embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
 endif()
 
 if (NOT DEFINED BUILD_TARGET_HARDWARE_KEYS)
diff --git a/secure_fw/spm/mpu_armv8m_drv.c b/platform/ext/target/mps2/an519/native_drivers/mpu_armv8m_drv.c
similarity index 98%
rename from secure_fw/spm/mpu_armv8m_drv.c
rename to platform/ext/target/mps2/an519/native_drivers/mpu_armv8m_drv.c
index a374a13..e540be2 100644
--- a/secure_fw/spm/mpu_armv8m_drv.c
+++ b/platform/ext/target/mps2/an519/native_drivers/mpu_armv8m_drv.c
@@ -10,8 +10,7 @@
 
 /*
  * FixMe:
- * This is a beta quality driver for MPU in v8M. To be finalized and integrated
- * into platform code
+ * This is a beta quality driver for MPU in v8M. To be finalized.
  */
 
 enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev,
diff --git a/secure_fw/spm/mpu_armv8m_drv.h b/platform/ext/target/mps2/an519/native_drivers/mpu_armv8m_drv.h
similarity index 95%
rename from secure_fw/spm/mpu_armv8m_drv.h
rename to platform/ext/target/mps2/an519/native_drivers/mpu_armv8m_drv.h
index 6d4c11e..0abf7fd 100644
--- a/secure_fw/spm/mpu_armv8m_drv.h
+++ b/platform/ext/target/mps2/an519/native_drivers/mpu_armv8m_drv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -12,11 +12,13 @@
 
 #include "cmsis.h"
 
+#define PRIVILEGED_DEFAULT_ENABLE 1
+#define HARDFAULT_NMI_ENABLE      1
+
 struct mpu_armv8m_dev_t {
     const uint32_t base;
 };
 
-
 enum mpu_armv8m_error_t {
     MPU_ARMV8M_OK,
     MPU_ARMV8M_ERROR
diff --git a/platform/ext/target/mps2/an519/spm_hal.c b/platform/ext/target/mps2/an519/spm_hal.c
index 6f98696..a520043 100644
--- a/platform/ext/target/mps2/an519/spm_hal.c
+++ b/platform/ext/target/mps2/an519/spm_hal.c
@@ -5,15 +5,301 @@
  *

  */

 

+#include <stdio.h>

 #include "platform/include/tfm_spm_hal.h"

 #include "spm_api.h"

 #include "spm_db.h"

+#include "tfm_platform_api.h"

+#include "target_cfg.h"

+#include "Driver_MPC.h"

+#include "mpu_armv8m_drv.h"

+#include "region_defs.h"

+#include "secure_utilities.h"

 

-void tfm_spm_hal_init_platform_data(uint32_t partition_id,

-        struct tfm_spm_partition_platform_data_t *platform_data)

+/* Import MPC driver */

+extern ARM_DRIVER_MPC Driver_SRAM1_MPC;

+

+struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };

+

+void tfm_spm_hal_init_isolation_hw(void)

 {

-    platform_data->periph_start = 0;

-    platform_data->periph_limit = 0;

-    platform_data->periph_ppc_bank = 0;

-    platform_data->periph_ppc_loc = 0;

+    /* Configures non-secure memory spaces in the target */

+    sau_and_idau_cfg();

+    mpc_init_cfg();

+    ppc_init_cfg();

 }

+

+void tfm_spm_hal_configure_default_isolation(

+        const struct tfm_spm_partition_platform_data_t *platform_data)

+{

+    if (platform_data) {

+        ppc_configure_to_secure(platform_data->periph_ppc_bank,

+                                platform_data->periph_ppc_loc);

+    }

+}

+

+#if TFM_LVL != 1

+

+#define MPU_REGION_VENEERS           0

+#define MPU_REGION_TFM_UNPRIV_CODE   1

+#define MPU_REGION_TFM_UNPRIV_DATA   2

+#define MPU_REGION_NS_DATA           3

+#define PARTITION_REGION_RO          4

+#define PARTITION_REGION_RW_STACK    5

+#define PARTITION_REGION_PERIPH      6

+#define PARTITION_REGION_SHARE       7

+

+REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);

+REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit);

+REGION_DECLARE(Image$$, TFM_UNPRIV_RO_DATA, $$RW$$Base);

+REGION_DECLARE(Image$$, TFM_UNPRIV_RO_DATA, $$ZI$$Limit);

+REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);

+REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);

+

+static enum spm_err_t tfm_spm_mpu_init(void)

+{

+    struct mpu_armv8m_region_cfg_t region_cfg;

+

+    mpu_armv8m_clean(&dev_mpu_s);

+

+    /* Veneer region */

+    region_cfg.region_nr = MPU_REGION_VENEERS;

+    region_cfg.region_base = CMSE_VENEER_REGION_START;

+    region_cfg.region_limit = CMSE_VENEER_REGION_LIMIT;

+    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    /* 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.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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    /* TFM Core unprivileged data region */

+    region_cfg.region_nr = MPU_REGION_TFM_UNPRIV_DATA;

+    region_cfg.region_base =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_RO_DATA, $$RW$$Base);

+    region_cfg.region_limit =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_RO_DATA, $$ZI$$Limit);

+    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_NEVER;

+    if (mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    /* TFM Core unprivileged non-secure data region */

+    region_cfg.region_nr = MPU_REGION_NS_DATA;

+    region_cfg.region_base = NS_DATA_START;

+    region_cfg.region_limit = NS_DATA_LIMIT;

+    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return SPM_ERR_OK;

+}

+

+enum spm_err_t tfm_spm_hal_partition_sandbox_config(

+        const struct tfm_spm_partition_memory_data_t *memory_data,

+        const struct tfm_spm_partition_platform_data_t *platform_data)

+{

+    /* This function takes a partition id and enables the

+     * SPM partition for that partition

+     */

+

+    struct mpu_armv8m_region_cfg_t region_cfg;

+

+    mpu_armv8m_disable(&dev_mpu_s);

+

+    /* Configure Regions */

+    if (memory_data->ro_start) {

+        /* RO region */

+        region_cfg.region_nr = PARTITION_REGION_RO;

+        region_cfg.region_base = memory_data->ro_start;

+        region_cfg.region_limit = memory_data->ro_limit;

+        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_armv8m_region_enable(&dev_mpu_s, &region_cfg)

+            != MPU_ARMV8M_OK) {

+            return SPM_ERR_INVALID_CONFIG;

+        }

+    }

+

+    /* RW, ZI and stack as one region */

+    region_cfg.region_nr = PARTITION_REGION_RW_STACK;

+    region_cfg.region_base = memory_data->rw_start;

+    region_cfg.region_limit = memory_data->stack_top;

+    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    if (platform_data) {

+        /* Peripheral */

+        region_cfg.region_nr = PARTITION_REGION_PERIPH;

+        region_cfg.region_base = platform_data->periph_start;

+        region_cfg.region_limit = platform_data->periph_limit;

+        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_armv8m_region_enable(&dev_mpu_s, &region_cfg)

+            != MPU_ARMV8M_OK) {

+            return SPM_ERR_INVALID_CONFIG;

+        }

+

+        ppc_en_secure_unpriv(platform_data->periph_ppc_bank,

+                             platform_data->periph_ppc_loc);

+    }

+

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return SPM_ERR_OK;

+}

+

+enum spm_err_t tfm_spm_hal_partition_sandbox_deconfig(

+        const struct tfm_spm_partition_memory_data_t *memory_data,

+        const struct tfm_spm_partition_platform_data_t *platform_data)

+{

+    /* This function takes a partition id and disables the

+     * SPM partition for that partition

+     */

+

+    if (platform_data) {

+        /* Peripheral */

+        ppc_clr_secure_unpriv(platform_data->periph_ppc_bank,

+                              platform_data->periph_ppc_loc);

+    }

+

+    mpu_armv8m_disable(&dev_mpu_s);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_RO);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_RW_STACK);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_PERIPH);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_SHARE);

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return SPM_ERR_OK;

+}

+

+/**

+ * Set share region to which the partition needs access

+ */

+enum spm_err_t tfm_spm_hal_set_share_region(

+        enum tfm_buffer_share_region_e share)

+{

+    struct mpu_armv8m_region_cfg_t region_cfg;

+    enum spm_err_t res = SPM_ERR_INVALID_CONFIG;

+    uint32_t scratch_base =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);

+    uint32_t scratch_limit =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);

+

+    mpu_armv8m_disable(&dev_mpu_s);

+

+    if (share == TFM_BUFFER_SHARE_DISABLE) {

+        mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_SHARE);

+    } else {

+

+        region_cfg.region_nr = PARTITION_REGION_SHARE;

+        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;

+        switch (share) {

+        case TFM_BUFFER_SHARE_SCRATCH:

+            /* Use scratch area for SP-to-SP data sharing */

+            region_cfg.region_base = scratch_base;

+            region_cfg.region_limit = scratch_limit;

+            res = SPM_ERR_OK;

+            break;

+        case TFM_BUFFER_SHARE_NS_CODE:

+            region_cfg.region_base = NS_CODE_START;

+            region_cfg.region_limit = NS_CODE_LIMIT;

+            /* Only allow read access to NS code region and keep

+             * exec.never attribute

+             */

+            region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;

+            res = SPM_ERR_OK;

+            break;

+        default:

+            /* Leave res to be set to SPM_ERR_INVALID_CONFIG */

+            break;

+        }

+        if (res == SPM_ERR_OK) {

+            mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg);

+        }

+    }

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return res;

+}

+

+#endif /* TFM_LVL != 1 */

+

+void tfm_spm_hal_setup_isolation_hw(void)

+{

+#if TFM_LVL != 1

+    if (tfm_spm_mpu_init() != SPM_ERR_OK) {

+        ERROR_MSG("Failed to set up initial MPU configuration! Halting.");

+        while (1) {

+            ;

+        }

+    }

+#endif

+}

+

+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 */

+    LOG_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*/

+    LOG_MSG("Oops... PPC fault!!!");

+

+    /* Inform TF-M core that isolation boundary has been violated */

+    tfm_access_violation_handler();

+}

+

diff --git a/platform/ext/target/mps2/an519/target_cfg.c b/platform/ext/target/mps2/an519/target_cfg.c
index e73378b..edc9bb3 100644
--- a/platform/ext/target/mps2/an519/target_cfg.c
+++ b/platform/ext/target/mps2/an519/target_cfg.c
@@ -31,6 +31,20 @@
 #define PERIPHERALS_BASE_NS_START (0x40000000)
 #define PERIPHERALS_BASE_NS_END   (0x4FFFFFFF)
 
+struct tfm_spm_partition_platform_data_t tfm_peripheral_uart1 = {
+        UART1_BASE_S,
+        UART1_BASE_S + 0xFFF,
+        PPC_SP_APB_PPC_EXP1,
+        CMSDK_UART1_APB_PPC_POS
+};
+
+struct tfm_spm_partition_platform_data_t tfm_peripheral_fpga_io = {
+        MPS2_IO_FPGAIO_BASE_S,
+        MPS2_IO_FPGAIO_BASE_S + 0xFFF,
+        PPC_SP_APB_PPC_EXP2,
+        CMSDK_FPGA_IO_PPC_POS
+};
+
 void enable_fault_handlers(void)
 {
     /* Fault handles enable registers are not present in a baseline
diff --git a/platform/ext/target/mps2/an519/target_cfg.h b/platform/ext/target/mps2/an519/target_cfg.h
index 39280c7..e60a866 100644
--- a/platform/ext/target/mps2/an519/target_cfg.h
+++ b/platform/ext/target/mps2/an519/target_cfg.h
@@ -17,6 +17,8 @@
 #ifndef __SSE200_TARGET_CFG_H__
 #define __SSE200_TARGET_CFG_H__
 
+#include "tfm_peripherals_def.h"
+
 /**
  * \brief Defines the word offsets of Slave Peripheral Protection Controller
  *        Registers
@@ -42,24 +44,15 @@
 };
 
 /**
- * \brief BusFault, UsageFault, MemManageFault and SecureFault
- *        are not present on AN519 so the body of this function
- *        is empty
+ * Holds the data necessary to do isolation for a specific peripheral.
  */
-void enable_fault_handlers(void);
-
-/**
- * \brief Configures all external interrupts to target the
- *        NS state, apart for the ones associated to secure
- *        peripherals (plus MPC and PPC)
- */
-void nvic_interrupt_target_state_cfg();
-
-/**
- * \brief This function enable the interrupts associated
- *        to the secure peripherals (plus MPC and PPC)
- */
-void nvic_interrupt_enable();
+struct tfm_spm_partition_platform_data_t
+{
+    uint32_t periph_start;
+    uint32_t periph_limit;
+    uint16_t periph_ppc_bank;
+    uint16_t periph_ppc_loc;
+};
 
 /**
  * \brief Configures the Memory Protection Controller.
diff --git a/platform/ext/target/mps2/an519/tfm_peripherals_def.h b/platform/ext/target/mps2/an519/tfm_peripherals_def.h
new file mode 100644
index 0000000..ca09d67
--- /dev/null
+++ b/platform/ext/target/mps2/an519/tfm_peripherals_def.h
@@ -0,0 +1,19 @@
+/*

+ * Copyright (c) 2018, Arm Limited. All rights reserved.

+ *

+ * SPDX-License-Identifier: BSD-3-Clause

+ *

+ */

+

+#ifndef __TFM_PERIPHERALS_DEF_H__

+#define __TFM_PERIPHERALS_DEF_H__

+

+struct tfm_spm_partition_platform_data_t;

+

+extern struct tfm_spm_partition_platform_data_t tfm_peripheral_uart1;

+extern struct tfm_spm_partition_platform_data_t tfm_peripheral_fpga_io;

+

+#define TFM_PERIPHERAL_FPGA_IO   (&tfm_peripheral_fpga_io)

+#define TFM_PERIPHERAL_UART1     (&tfm_peripheral_uart1)

+

+#endif /* __TFM_PERIPHERALS_DEF_H__ */

diff --git a/secure_fw/spm/mpu_armv8m_drv.c b/platform/ext/target/mps2/an521/native_drivers/mpu_armv8m_drv.c
similarity index 98%
copy from secure_fw/spm/mpu_armv8m_drv.c
copy to platform/ext/target/mps2/an521/native_drivers/mpu_armv8m_drv.c
index a374a13..e540be2 100644
--- a/secure_fw/spm/mpu_armv8m_drv.c
+++ b/platform/ext/target/mps2/an521/native_drivers/mpu_armv8m_drv.c
@@ -10,8 +10,7 @@
 
 /*
  * FixMe:
- * This is a beta quality driver for MPU in v8M. To be finalized and integrated
- * into platform code
+ * This is a beta quality driver for MPU in v8M. To be finalized.
  */
 
 enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev,
diff --git a/secure_fw/spm/mpu_armv8m_drv.h b/platform/ext/target/mps2/an521/native_drivers/mpu_armv8m_drv.h
similarity index 95%
copy from secure_fw/spm/mpu_armv8m_drv.h
copy to platform/ext/target/mps2/an521/native_drivers/mpu_armv8m_drv.h
index 6d4c11e..0abf7fd 100644
--- a/secure_fw/spm/mpu_armv8m_drv.h
+++ b/platform/ext/target/mps2/an521/native_drivers/mpu_armv8m_drv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -12,11 +12,13 @@
 
 #include "cmsis.h"
 
+#define PRIVILEGED_DEFAULT_ENABLE 1
+#define HARDFAULT_NMI_ENABLE      1
+
 struct mpu_armv8m_dev_t {
     const uint32_t base;
 };
 
-
 enum mpu_armv8m_error_t {
     MPU_ARMV8M_OK,
     MPU_ARMV8M_ERROR
diff --git a/platform/ext/target/mps2/an521/spm_hal.c b/platform/ext/target/mps2/an521/spm_hal.c
index 6f98696..e26496a 100644
--- a/platform/ext/target/mps2/an521/spm_hal.c
+++ b/platform/ext/target/mps2/an521/spm_hal.c
@@ -5,15 +5,301 @@
  *

  */

 

+#include <stdio.h>

 #include "platform/include/tfm_spm_hal.h"

 #include "spm_api.h"

 #include "spm_db.h"

+#include "tfm_platform_api.h"

+#include "target_cfg.h"

+#include "Driver_MPC.h"

+#include "mpu_armv8m_drv.h"

+#include "region_defs.h"

+#include "secure_utilities.h"

 

-void tfm_spm_hal_init_platform_data(uint32_t partition_id,

-        struct tfm_spm_partition_platform_data_t *platform_data)

+/* Import MPC driver */

+extern ARM_DRIVER_MPC Driver_SRAM1_MPC;

+

+struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };

+

+void tfm_spm_hal_init_isolation_hw(void)

 {

-    platform_data->periph_start = 0;

-    platform_data->periph_limit = 0;

-    platform_data->periph_ppc_bank = 0;

-    platform_data->periph_ppc_loc = 0;

+    /* Configures non-secure memory spaces in the target */

+    sau_and_idau_cfg();

+    mpc_init_cfg();

+    ppc_init_cfg();

 }

+

+void tfm_spm_hal_configure_default_isolation(

+                  const struct tfm_spm_partition_platform_data_t *platform_data)

+{

+    if (platform_data) {

+        ppc_configure_to_secure(platform_data->periph_ppc_bank,

+                                platform_data->periph_ppc_loc);

+    }

+}

+

+#if TFM_LVL != 1

+

+#define MPU_REGION_VENEERS           0

+#define MPU_REGION_TFM_UNPRIV_CODE   1

+#define MPU_REGION_TFM_UNPRIV_DATA   2

+#define MPU_REGION_NS_DATA           3

+#define PARTITION_REGION_RO          4

+#define PARTITION_REGION_RW_STACK    5

+#define PARTITION_REGION_PERIPH      6

+#define PARTITION_REGION_SHARE       7

+

+REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);

+REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit);

+REGION_DECLARE(Image$$, TFM_UNPRIV_RO_DATA, $$RW$$Base);

+REGION_DECLARE(Image$$, TFM_UNPRIV_RO_DATA, $$ZI$$Limit);

+REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);

+REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);

+

+static enum spm_err_t tfm_spm_mpu_init(void)

+{

+    struct mpu_armv8m_region_cfg_t region_cfg;

+

+    mpu_armv8m_clean(&dev_mpu_s);

+

+    /* Veneer region */

+    region_cfg.region_nr = MPU_REGION_VENEERS;

+    region_cfg.region_base = CMSE_VENEER_REGION_START;

+    region_cfg.region_limit = CMSE_VENEER_REGION_LIMIT;

+    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    /* 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.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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    /* TFM Core unprivileged data region */

+    region_cfg.region_nr = MPU_REGION_TFM_UNPRIV_DATA;

+    region_cfg.region_base =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_RO_DATA, $$RW$$Base);

+    region_cfg.region_limit =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_RO_DATA, $$ZI$$Limit);

+    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_NEVER;

+    if (mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    /* TFM Core unprivileged non-secure data region */

+    region_cfg.region_nr = MPU_REGION_NS_DATA;

+    region_cfg.region_base = NS_DATA_START;

+    region_cfg.region_limit = NS_DATA_LIMIT;

+    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return SPM_ERR_OK;

+}

+

+enum spm_err_t tfm_spm_hal_partition_sandbox_config(

+                  const struct tfm_spm_partition_memory_data_t *memory_data,

+                  const struct tfm_spm_partition_platform_data_t *platform_data)

+{

+    /* This function takes a partition id and enables the

+     * SPM partition for that partition

+     */

+

+    struct mpu_armv8m_region_cfg_t region_cfg;

+

+    mpu_armv8m_disable(&dev_mpu_s);

+

+    /* Configure Regions */

+    if (memory_data->ro_start) {

+        /* RO region */

+        region_cfg.region_nr = PARTITION_REGION_RO;

+        region_cfg.region_base = memory_data->ro_start;

+        region_cfg.region_limit = memory_data->ro_limit;

+        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_armv8m_region_enable(&dev_mpu_s, &region_cfg)

+            != MPU_ARMV8M_OK) {

+            return SPM_ERR_INVALID_CONFIG;

+        }

+    }

+

+    /* RW, ZI and stack as one region */

+    region_cfg.region_nr = PARTITION_REGION_RW_STACK;

+    region_cfg.region_base = memory_data->rw_start;

+    region_cfg.region_limit = memory_data->stack_top;

+    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    if (platform_data) {

+        /* Peripheral */

+        region_cfg.region_nr = PARTITION_REGION_PERIPH;

+        region_cfg.region_base = platform_data->periph_start;

+        region_cfg.region_limit = platform_data->periph_limit;

+        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_armv8m_region_enable(&dev_mpu_s, &region_cfg)

+            != MPU_ARMV8M_OK) {

+            return SPM_ERR_INVALID_CONFIG;

+        }

+

+        ppc_en_secure_unpriv(platform_data->periph_ppc_bank,

+                             platform_data->periph_ppc_loc);

+    }

+

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return SPM_ERR_OK;

+}

+

+enum spm_err_t tfm_spm_hal_partition_sandbox_deconfig(

+                  const struct tfm_spm_partition_memory_data_t *memory_data,

+                  const struct tfm_spm_partition_platform_data_t *platform_data)

+{

+    /* This function takes a partition id and disables the

+     * SPM partition for that partition

+     */

+

+    if (platform_data) {

+        /* Peripheral */

+        ppc_clr_secure_unpriv(platform_data->periph_ppc_bank,

+                              platform_data->periph_ppc_loc);

+    }

+

+    mpu_armv8m_disable(&dev_mpu_s);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_RO);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_RW_STACK);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_PERIPH);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_SHARE);

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return SPM_ERR_OK;

+}

+

+/**

+ * Set share region to which the partition needs access

+ */

+enum spm_err_t tfm_spm_hal_set_share_region(

+                                           enum tfm_buffer_share_region_e share)

+{

+    struct mpu_armv8m_region_cfg_t region_cfg;

+    enum spm_err_t res = SPM_ERR_INVALID_CONFIG;

+    uint32_t scratch_base =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);

+    uint32_t scratch_limit =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);

+

+    mpu_armv8m_disable(&dev_mpu_s);

+

+    if (share == TFM_BUFFER_SHARE_DISABLE) {

+        mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_SHARE);

+    } else {

+

+        region_cfg.region_nr = PARTITION_REGION_SHARE;

+        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;

+        switch (share) {

+        case TFM_BUFFER_SHARE_SCRATCH:

+            /* Use scratch area for SP-to-SP data sharing */

+            region_cfg.region_base = scratch_base;

+            region_cfg.region_limit = scratch_limit;

+            res = SPM_ERR_OK;

+            break;

+        case TFM_BUFFER_SHARE_NS_CODE:

+            region_cfg.region_base = NS_CODE_START;

+            region_cfg.region_limit = NS_CODE_LIMIT;

+            /* Only allow read access to NS code region and keep

+             * exec.never attribute

+             */

+            region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;

+            res = SPM_ERR_OK;

+            break;

+        default:

+            /* Leave res to be set to SPM_ERR_INVALID_CONFIG */

+            break;

+        }

+        if (res == SPM_ERR_OK) {

+            mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg);

+        }

+    }

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return res;

+}

+

+#endif /* TFM_LVL != 1 */

+

+void tfm_spm_hal_setup_isolation_hw(void)

+{

+#if TFM_LVL != 1

+    if (tfm_spm_mpu_init() != SPM_ERR_OK) {

+        ERROR_MSG("Failed to set up initial MPU configuration! Halting.");

+        while (1) {

+            ;

+        }

+    }

+#endif

+}

+

+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 */

+    LOG_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*/

+    LOG_MSG("Oops... PPC fault!!!");

+

+    /* Inform TF-M core that isolation boundary has been violated */

+    tfm_access_violation_handler();

+}

+

diff --git a/platform/ext/target/mps2/an521/target_cfg.c b/platform/ext/target/mps2/an521/target_cfg.c
index 4d69786..54ea719 100644
--- a/platform/ext/target/mps2/an521/target_cfg.c
+++ b/platform/ext/target/mps2/an521/target_cfg.c
@@ -31,6 +31,20 @@
 #define PERIPHERALS_BASE_NS_START (0x40000000)
 #define PERIPHERALS_BASE_NS_END   (0x4FFFFFFF)
 
+struct tfm_spm_partition_platform_data_t tfm_peripheral_uart1 = {
+        UART1_BASE_S,
+        UART1_BASE_S + 0xFFF,
+        PPC_SP_APB_PPC_EXP1,
+        CMSDK_UART1_APB_PPC_POS
+};
+
+struct tfm_spm_partition_platform_data_t tfm_peripheral_fpga_io = {
+        MPS2_IO_FPGAIO_BASE_S,
+        MPS2_IO_FPGAIO_BASE_S + 0xFFF,
+        PPC_SP_APB_PPC_EXP2,
+        CMSDK_FPGA_IO_PPC_POS
+};
+
 void enable_fault_handlers(void)
 {
     /* Enables BUS, MEM, USG and Secure faults */
diff --git a/platform/ext/target/mps2/an521/target_cfg.h b/platform/ext/target/mps2/an521/target_cfg.h
index 26c5cda..1b9e050 100644
--- a/platform/ext/target/mps2/an521/target_cfg.h
+++ b/platform/ext/target/mps2/an521/target_cfg.h
@@ -17,6 +17,8 @@
 #ifndef __SSE200_TARGET_CFG_H__
 #define __SSE200_TARGET_CFG_H__
 
+#include "tfm_peripherals_def.h"
+
 enum ppc_bank_e
 {
     PPC_SP_AHB_PPC0 = 0,
@@ -38,23 +40,15 @@
 };
 
 /**
- * \brief Enables the fault handlers BusFault, UsageFault,
- *        MemManageFault and SecureFault.
+ * Holds the data necessary to do isolation for a specific peripheral.
  */
-void enable_fault_handlers(void);
-
-/**
- * \brief Configures all external interrupts to target the
- *        NS state, apart for the ones associated to secure
- *        peripherals (plus MPC and PPC)
- */
-void nvic_interrupt_target_state_cfg();
-
-/**
- * \brief This function enable the interrupts associated
- *        to the secure peripherals (plus MPC and PPC)
- */
-void nvic_interrupt_enable();
+struct tfm_spm_partition_platform_data_t
+{
+    uint32_t periph_start;
+    uint32_t periph_limit;
+    uint16_t periph_ppc_bank;
+    uint16_t periph_ppc_loc;
+};
 
 /**
  * \brief Configures the Memory Protection Controller.
diff --git a/platform/ext/target/mps2/an521/tfm_peripherals_def.h b/platform/ext/target/mps2/an521/tfm_peripherals_def.h
new file mode 100644
index 0000000..ca09d67
--- /dev/null
+++ b/platform/ext/target/mps2/an521/tfm_peripherals_def.h
@@ -0,0 +1,19 @@
+/*

+ * Copyright (c) 2018, Arm Limited. All rights reserved.

+ *

+ * SPDX-License-Identifier: BSD-3-Clause

+ *

+ */

+

+#ifndef __TFM_PERIPHERALS_DEF_H__

+#define __TFM_PERIPHERALS_DEF_H__

+

+struct tfm_spm_partition_platform_data_t;

+

+extern struct tfm_spm_partition_platform_data_t tfm_peripheral_uart1;

+extern struct tfm_spm_partition_platform_data_t tfm_peripheral_fpga_io;

+

+#define TFM_PERIPHERAL_FPGA_IO   (&tfm_peripheral_fpga_io)

+#define TFM_PERIPHERAL_UART1     (&tfm_peripheral_uart1)

+

+#endif /* __TFM_PERIPHERALS_DEF_H__ */

diff --git a/secure_fw/spm/mpu_armv8m_drv.c b/platform/ext/target/musca_a/Native_Driver/mpu_armv8m_drv.c
similarity index 98%
copy from secure_fw/spm/mpu_armv8m_drv.c
copy to platform/ext/target/musca_a/Native_Driver/mpu_armv8m_drv.c
index a374a13..e540be2 100644
--- a/secure_fw/spm/mpu_armv8m_drv.c
+++ b/platform/ext/target/musca_a/Native_Driver/mpu_armv8m_drv.c
@@ -10,8 +10,7 @@
 
 /*
  * FixMe:
- * This is a beta quality driver for MPU in v8M. To be finalized and integrated
- * into platform code
+ * This is a beta quality driver for MPU in v8M. To be finalized.
  */
 
 enum mpu_armv8m_error_t mpu_armv8m_enable(struct mpu_armv8m_dev_t *dev,
diff --git a/secure_fw/spm/mpu_armv8m_drv.h b/platform/ext/target/musca_a/Native_Driver/mpu_armv8m_drv.h
similarity index 95%
copy from secure_fw/spm/mpu_armv8m_drv.h
copy to platform/ext/target/musca_a/Native_Driver/mpu_armv8m_drv.h
index 6d4c11e..0abf7fd 100644
--- a/secure_fw/spm/mpu_armv8m_drv.h
+++ b/platform/ext/target/musca_a/Native_Driver/mpu_armv8m_drv.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017, Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2018, Arm Limited. All rights reserved.
  *
  * SPDX-License-Identifier: BSD-3-Clause
  *
@@ -12,11 +12,13 @@
 
 #include "cmsis.h"
 
+#define PRIVILEGED_DEFAULT_ENABLE 1
+#define HARDFAULT_NMI_ENABLE      1
+
 struct mpu_armv8m_dev_t {
     const uint32_t base;
 };
 
-
 enum mpu_armv8m_error_t {
     MPU_ARMV8M_OK,
     MPU_ARMV8M_ERROR
diff --git a/platform/ext/target/musca_a/spm_hal.c b/platform/ext/target/musca_a/spm_hal.c
index 6f98696..a520043 100644
--- a/platform/ext/target/musca_a/spm_hal.c
+++ b/platform/ext/target/musca_a/spm_hal.c
@@ -5,15 +5,301 @@
  *

  */

 

+#include <stdio.h>

 #include "platform/include/tfm_spm_hal.h"

 #include "spm_api.h"

 #include "spm_db.h"

+#include "tfm_platform_api.h"

+#include "target_cfg.h"

+#include "Driver_MPC.h"

+#include "mpu_armv8m_drv.h"

+#include "region_defs.h"

+#include "secure_utilities.h"

 

-void tfm_spm_hal_init_platform_data(uint32_t partition_id,

-        struct tfm_spm_partition_platform_data_t *platform_data)

+/* Import MPC driver */

+extern ARM_DRIVER_MPC Driver_SRAM1_MPC;

+

+struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };

+

+void tfm_spm_hal_init_isolation_hw(void)

 {

-    platform_data->periph_start = 0;

-    platform_data->periph_limit = 0;

-    platform_data->periph_ppc_bank = 0;

-    platform_data->periph_ppc_loc = 0;

+    /* Configures non-secure memory spaces in the target */

+    sau_and_idau_cfg();

+    mpc_init_cfg();

+    ppc_init_cfg();

 }

+

+void tfm_spm_hal_configure_default_isolation(

+        const struct tfm_spm_partition_platform_data_t *platform_data)

+{

+    if (platform_data) {

+        ppc_configure_to_secure(platform_data->periph_ppc_bank,

+                                platform_data->periph_ppc_loc);

+    }

+}

+

+#if TFM_LVL != 1

+

+#define MPU_REGION_VENEERS           0

+#define MPU_REGION_TFM_UNPRIV_CODE   1

+#define MPU_REGION_TFM_UNPRIV_DATA   2

+#define MPU_REGION_NS_DATA           3

+#define PARTITION_REGION_RO          4

+#define PARTITION_REGION_RW_STACK    5

+#define PARTITION_REGION_PERIPH      6

+#define PARTITION_REGION_SHARE       7

+

+REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);

+REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit);

+REGION_DECLARE(Image$$, TFM_UNPRIV_RO_DATA, $$RW$$Base);

+REGION_DECLARE(Image$$, TFM_UNPRIV_RO_DATA, $$ZI$$Limit);

+REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);

+REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);

+

+static enum spm_err_t tfm_spm_mpu_init(void)

+{

+    struct mpu_armv8m_region_cfg_t region_cfg;

+

+    mpu_armv8m_clean(&dev_mpu_s);

+

+    /* Veneer region */

+    region_cfg.region_nr = MPU_REGION_VENEERS;

+    region_cfg.region_base = CMSE_VENEER_REGION_START;

+    region_cfg.region_limit = CMSE_VENEER_REGION_LIMIT;

+    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    /* 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.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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    /* TFM Core unprivileged data region */

+    region_cfg.region_nr = MPU_REGION_TFM_UNPRIV_DATA;

+    region_cfg.region_base =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_RO_DATA, $$RW$$Base);

+    region_cfg.region_limit =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_RO_DATA, $$ZI$$Limit);

+    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_NEVER;

+    if (mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    /* TFM Core unprivileged non-secure data region */

+    region_cfg.region_nr = MPU_REGION_NS_DATA;

+    region_cfg.region_base = NS_DATA_START;

+    region_cfg.region_limit = NS_DATA_LIMIT;

+    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return SPM_ERR_OK;

+}

+

+enum spm_err_t tfm_spm_hal_partition_sandbox_config(

+        const struct tfm_spm_partition_memory_data_t *memory_data,

+        const struct tfm_spm_partition_platform_data_t *platform_data)

+{

+    /* This function takes a partition id and enables the

+     * SPM partition for that partition

+     */

+

+    struct mpu_armv8m_region_cfg_t region_cfg;

+

+    mpu_armv8m_disable(&dev_mpu_s);

+

+    /* Configure Regions */

+    if (memory_data->ro_start) {

+        /* RO region */

+        region_cfg.region_nr = PARTITION_REGION_RO;

+        region_cfg.region_base = memory_data->ro_start;

+        region_cfg.region_limit = memory_data->ro_limit;

+        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_armv8m_region_enable(&dev_mpu_s, &region_cfg)

+            != MPU_ARMV8M_OK) {

+            return SPM_ERR_INVALID_CONFIG;

+        }

+    }

+

+    /* RW, ZI and stack as one region */

+    region_cfg.region_nr = PARTITION_REGION_RW_STACK;

+    region_cfg.region_base = memory_data->rw_start;

+    region_cfg.region_limit = memory_data->stack_top;

+    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {

+        return SPM_ERR_INVALID_CONFIG;

+    }

+

+    if (platform_data) {

+        /* Peripheral */

+        region_cfg.region_nr = PARTITION_REGION_PERIPH;

+        region_cfg.region_base = platform_data->periph_start;

+        region_cfg.region_limit = platform_data->periph_limit;

+        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_armv8m_region_enable(&dev_mpu_s, &region_cfg)

+            != MPU_ARMV8M_OK) {

+            return SPM_ERR_INVALID_CONFIG;

+        }

+

+        ppc_en_secure_unpriv(platform_data->periph_ppc_bank,

+                             platform_data->periph_ppc_loc);

+    }

+

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return SPM_ERR_OK;

+}

+

+enum spm_err_t tfm_spm_hal_partition_sandbox_deconfig(

+        const struct tfm_spm_partition_memory_data_t *memory_data,

+        const struct tfm_spm_partition_platform_data_t *platform_data)

+{

+    /* This function takes a partition id and disables the

+     * SPM partition for that partition

+     */

+

+    if (platform_data) {

+        /* Peripheral */

+        ppc_clr_secure_unpriv(platform_data->periph_ppc_bank,

+                              platform_data->periph_ppc_loc);

+    }

+

+    mpu_armv8m_disable(&dev_mpu_s);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_RO);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_RW_STACK);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_PERIPH);

+    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_SHARE);

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return SPM_ERR_OK;

+}

+

+/**

+ * Set share region to which the partition needs access

+ */

+enum spm_err_t tfm_spm_hal_set_share_region(

+        enum tfm_buffer_share_region_e share)

+{

+    struct mpu_armv8m_region_cfg_t region_cfg;

+    enum spm_err_t res = SPM_ERR_INVALID_CONFIG;

+    uint32_t scratch_base =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);

+    uint32_t scratch_limit =

+        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);

+

+    mpu_armv8m_disable(&dev_mpu_s);

+

+    if (share == TFM_BUFFER_SHARE_DISABLE) {

+        mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_SHARE);

+    } else {

+

+        region_cfg.region_nr = PARTITION_REGION_SHARE;

+        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;

+        switch (share) {

+        case TFM_BUFFER_SHARE_SCRATCH:

+            /* Use scratch area for SP-to-SP data sharing */

+            region_cfg.region_base = scratch_base;

+            region_cfg.region_limit = scratch_limit;

+            res = SPM_ERR_OK;

+            break;

+        case TFM_BUFFER_SHARE_NS_CODE:

+            region_cfg.region_base = NS_CODE_START;

+            region_cfg.region_limit = NS_CODE_LIMIT;

+            /* Only allow read access to NS code region and keep

+             * exec.never attribute

+             */

+            region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;

+            res = SPM_ERR_OK;

+            break;

+        default:

+            /* Leave res to be set to SPM_ERR_INVALID_CONFIG */

+            break;

+        }

+        if (res == SPM_ERR_OK) {

+            mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg);

+        }

+    }

+    mpu_armv8m_enable(&dev_mpu_s, PRIVILEGED_DEFAULT_ENABLE,

+                      HARDFAULT_NMI_ENABLE);

+

+    return res;

+}

+

+#endif /* TFM_LVL != 1 */

+

+void tfm_spm_hal_setup_isolation_hw(void)

+{

+#if TFM_LVL != 1

+    if (tfm_spm_mpu_init() != SPM_ERR_OK) {

+        ERROR_MSG("Failed to set up initial MPU configuration! Halting.");

+        while (1) {

+            ;

+        }

+    }

+#endif

+}

+

+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 */

+    LOG_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*/

+    LOG_MSG("Oops... PPC fault!!!");

+

+    /* Inform TF-M core that isolation boundary has been violated */

+    tfm_access_violation_handler();

+}

+

diff --git a/platform/ext/target/musca_a/target_cfg.h b/platform/ext/target/musca_a/target_cfg.h
index 6e93ff5..3d59934 100755
--- a/platform/ext/target/musca_a/target_cfg.h
+++ b/platform/ext/target/musca_a/target_cfg.h
@@ -17,6 +17,8 @@
 #ifndef __TARGET_CFG_H__
 #define __TARGET_CFG_H__
 
+#include "tfm_peripherals_def.h"
+
 enum ppc_bank_e
 {
     PPC_SP_AHB_PPC0 = 0,
@@ -38,23 +40,15 @@
 };
 
 /**
- * \brief Enables the fault handlers BusFault, UsageFault,
- *        MemManageFault and SecureFault.
+ * Holds the data necessary to do isolation for a specific peripheral.
  */
-void enable_fault_handlers(void);
-
-/**
- * \brief Configures all external interrupts to target the
- *        NS state, apart for the ones associated to secure
- *        peripherals (plus MPC and PPC)
- */
-void nvic_interrupt_target_state_cfg();
-
-/**
- * \brief This function enables the interrupts associated
- *        to the secure peripherals (plus MPC and PPC)
- */
-void nvic_interrupt_enable();
+struct tfm_spm_partition_platform_data_t
+{
+    uint32_t periph_start;
+    uint32_t periph_limit;
+    uint16_t periph_ppc_bank;
+    uint16_t periph_ppc_loc;
+};
 
 /**
  * \brief Configures the Memory Protection Controller.
diff --git a/platform/ext/target/musca_a/tfm_peripherals_def.h b/platform/ext/target/musca_a/tfm_peripherals_def.h
new file mode 100644
index 0000000..2bd251e
--- /dev/null
+++ b/platform/ext/target/musca_a/tfm_peripherals_def.h
@@ -0,0 +1,13 @@
+/*

+ * Copyright (c) 2018, Arm Limited. All rights reserved.

+ *

+ * SPDX-License-Identifier: BSD-3-Clause

+ *

+ */

+

+#ifndef __TFM_PERIPHERALS_DEF_H__

+#define __TFM_PERIPHERALS_DEF_H__

+

+struct tfm_spm_partition_platform_data_t;

+

+#endif /* __TFM_PERIPHERALS_DEF_H__ */

diff --git a/platform/include/tfm_spm_hal.h b/platform/include/tfm_spm_hal.h
index bbd0001..24e987b 100644
--- a/platform/include/tfm_spm_hal.h
+++ b/platform/include/tfm_spm_hal.h
@@ -9,26 +9,143 @@
 #define __TFM_SPM_HAL_H__

 

 #include <stdint.h>

+#include "tfm_secure_api.h"

+#include "spm_api.h"

 

 /**

- * Holds the data necessary to do isolation for a specific peripheral.

- */

-struct tfm_spm_partition_platform_data_t

-{

-    uint32_t periph_start;

-    uint32_t periph_limit;

-    uint16_t periph_ppc_bank;

-    uint16_t periph_ppc_loc;

-};

-

-/**

- * \brief Initialise the platform related fields of a partition DB record.

+ * \brief Holds peripheral specific data fields required to manage the

+ *        peripherals isolation

  *

- * \param[in] partition_id     The id of the partition

- * \param[in] platform_data    The platform fields of the partition DB record to

- *                             init

+ * This structure has to be defined in the platform directory, and may have

+ * different definition for each platform. The structure should contain fields

+ * that describe the peripheral for the functions that are prototyped in this

+ * file and are responsible for configuring the isolation of the peripherals.

+ *

+ * Pointers to structures of this type are managed by the SPM, and passed to the

+ * necessary function on isolation request. The pointers are also defined by the

+ * platform in the header file tfm_peripherals_def.h. For details on this, see

+ * the documentation of that file.

  */

-void tfm_spm_hal_init_platform_data(uint32_t partition_id,

-        struct tfm_spm_partition_platform_data_t *platform_data);

+struct tfm_spm_partition_platform_data_t;

+

+#if TFM_LVL != 1

+/**

+ * \brief Holds SPM db fields that define the memory regions used by a

+ *        partition.

+ */

+struct tfm_spm_partition_memory_data_t

+{

+    uint32_t code_start;   /*!< Start of the code memory of this partition. */

+    uint32_t code_limit;   /*!< Address of the byte beyond the end of the code

+                            *   memory of this partition.

+                            */

+    uint32_t ro_start;     /*!< Start of the read only memory of this

+                            *   partition.

+                            */

+    uint32_t ro_limit;     /*!< Address of the byte beyond the end of the read

+                            *   only memory of this partition.

+                            */

+    uint32_t rw_start;     /*!< Start of the data region of this partition. */

+    uint32_t rw_limit;     /*!< Address of the byte beyond the end of the data

+                            *   region of this partition.

+                            */

+    uint32_t zi_start;     /*!< Start of the zero initialised data region of

+                            *   this partition.

+                            */

+    uint32_t zi_limit;     /*!< Address of the byte beyond the end of the zero

+                            *   initialised region of this partition.

+                            */

+    uint32_t stack_bottom; /*!< The bottom of the stack for the partition. */

+    uint32_t stack_top;    /*!< The top of the stack for the partition. */

+};

+#endif

+

+/**

+ * \brief This function initialises the HW used for isolation, and sets the

+ *        default configuration for them.

+ *

+ * This function is called during TF-M core early startup, before DB init

+ */

+void tfm_spm_hal_init_isolation_hw(void);

+

+/**

+ * \brief This function initialises the HW used for isolation, and sets the

+ *        default configuration for them.

+ * This function is called during TF-M core early startup, after DB init

+ */

+void tfm_spm_hal_setup_isolation_hw(void);

+

+/**

+ * \brief Configure peripherals for a partition based on the platfotm data from

+ *        the DB

+ *

+ * This function is called during partition initialisation (before calling the

+ * init function for the partition)

+ *

+ * \param[in] platform_data    The platform fields of the partition DB record to

+ *                             be used for configuration. Can be NULL.

+ */

+void tfm_spm_hal_configure_default_isolation(

+                 const struct tfm_spm_partition_platform_data_t *platform_data);

+

+/**

+ * \brief Enables the fault handlers

+ */

+void enable_fault_handlers(void);

+

+/**

+ * \brief Configures all external interrupts to target the

+ *        NS state, apart for the ones associated to secure

+ *        peripherals (plus MPC and PPC)

+ */

+void nvic_interrupt_target_state_cfg(void);

+

+/**

+ * \brief This function enable the interrupts associated

+ *        to the secure peripherals (plus the isolation boundary violation

+ *        interrupts)

+ */

+void nvic_interrupt_enable(void);

+

+

+#if TFM_LVL != 1

+/**

+ * \brief Configure the sandbox for a partition.

+ *

+ * \param[in] memory_data      The memory ranges from the partition DB for this

+ *                             partition

+ * \param[in] platform_data    The platform fields of the partition DB record

+ *                             for this partition. Can be NULL.

+ *

+ * \return Returns the result operation as per \ref spm_err_t

+ */

+enum spm_err_t tfm_spm_hal_partition_sandbox_config(

+                 const struct tfm_spm_partition_memory_data_t *memory_data,

+                 const struct tfm_spm_partition_platform_data_t *platform_data);

+

+/**

+ * \brief Deconfigure the sandbox for a partition.

+ *

+ * \param[in] memory_data      The memory ranges from the partition DB for this

+ *                             partition

+ * \param[in] platform_data    The platform fields of the partition DB record

+ *                             for this partition. Can be NULL.

+ *

+ * \return Returns the result operation as per \ref spm_err_t

+ */

+enum spm_err_t tfm_spm_hal_partition_sandbox_deconfig(

+                 const struct tfm_spm_partition_memory_data_t *memory_data,

+                 const struct tfm_spm_partition_platform_data_t *platform_data);

+

+/**

+ * \brief Set the share region mode

+ *

+ * \param[in] share      The mode to set

+ *

+ * \return Returns the result operation as per \ref spm_err_t

+ */

+enum spm_err_t tfm_spm_hal_set_share_region(

+                                          enum tfm_buffer_share_region_e share);

+#endif

 

 #endif /* __TFM_SPM_HAL_H__ */

diff --git a/platform/readme.md b/platform/readme.md
index 6e75bc5..6233895 100644
--- a/platform/readme.md
+++ b/platform/readme.md
@@ -3,6 +3,33 @@
 `NOTE` This folder and subfolders, especially the target folder, are likely to
 be refactored and updated to improve the overall structure of dependencies.
 
+## Interfacing with TF-M core
+
+### platform/ext/target/<target_platform>/tfm_peripherals_def.h
+This file should enumerate the hardware peripherals that are available for TF-M
+on the platform. The name of the peripheral used by a service is set in its
+manifest file. The platform have to provide a macro for each of the provided
+peripherals, that is substituted to a pointer to type
+`struct tfm_spm_partition_platform_data_t`. The memory that the pointer points
+to is allocated by the platform code. The pointer gets stored in the partitions
+database in SPM, and it is provided to the SPM HAL functions.
+
+#### Peripherals currently used by the services in TF-M
+ - `TFM_PERIPHERAL_FPGA_IO` FPGA system control and I/O
+ - `TFM_PERIPHERAL_UART1` UART1
+
+`NOTE` If a platform doesn't support a peripheral, that is used by a service,
+then the service cannot be used on the given platform. Using a peripheral in
+TF-M that is not supported by the platform results in compile error.
+
+### platform/include/tfm_spm_hal.h
+This file contains the declarations of functions that a platform implementation
+has to provide for TF-M. For details see the comments in the file.
+
+### secure_fw/core/tfm_platform_api.h
+This file contains declarations of functions that can be or have to be called
+from platform implementations. For details see the comments in the file.
+
 ## Sub-folders
 
 ### include
@@ -18,4 +45,4 @@
 
 --------------
 
-*Copyright (c) 2017, Arm Limited. All rights reserved.*
+*Copyright (c) 2017-2018, Arm Limited. All rights reserved.*
diff --git a/secure_fw/core/tfm_core.c b/secure_fw/core/tfm_core.c
index 3cc4f1e..8212ab7 100644
--- a/secure_fw/core/tfm_core.c
+++ b/secure_fw/core/tfm_core.c
@@ -9,7 +9,7 @@
 #include "region_defs.h"
 #include "tfm_core.h"
 #include "tfm_internal.h"
-#include "target_cfg.h"
+#include "platform/include/tfm_spm_hal.h"
 #include "uart_stdout.h"
 #include "secure_utilities.h"
 #include "secure_fw/spm/spm_api.h"
@@ -22,6 +22,15 @@
 __asm("  .global __ARM_use_no_argv\n");
 #endif
 
+#if defined ( __GNUC__ )
+/* The macro cmse_nsfptr_create defined in the gcc library uses the non-standard
+ * gcc C lanuage extension 'typeof'. TF-M is built with '-std=c99' so typeof
+ * cannot be used in the code. As a workaround cmse_nsfptr_create is redefined
+ * here to use only standard language elements. */
+#undef cmse_nsfptr_create
+#define cmse_nsfptr_create(p) ((intptr_t) (p) & ~1)
+#endif
+
 #ifndef TFM_LVL
 #error TFM_LVL is not defined!
 #endif
@@ -100,7 +109,7 @@
     /* Clears LSB of the function address to indicate the function-call
      * will perform the switch from secure to non-secure
      */
-    ns_entry = (nsfptr_t) (entry_ptr & (~0x1));
+    ns_entry = (nsfptr_t) cmse_nsfptr_create(entry_ptr);
 }
 
 int32_t tfm_core_init(void)
@@ -120,10 +129,7 @@
     printf("TFM level is: %d\r\n", TFM_LVL);
 #endif
 
-    /* Configures non-secure memory spaces in the target */
-    sau_and_idau_cfg();
-    mpc_init_cfg();
-    ppc_init_cfg();
+    tfm_spm_hal_init_isolation_hw();
     configure_ns_code();
 
     /* Configures all interrupts to retarget NS state, except for
@@ -146,14 +152,9 @@
     tfm_core_init();
 
     tfm_spm_db_init();
-#if TFM_LVL != 1
-    if (tfm_spm_mpu_init() != SPM_ERR_OK) {
-        ERROR_MSG("Failed to set up initial MPU configuration! Halting.");
-        while (1) {
-            ;
-        }
-    }
-#endif
+
+    tfm_spm_hal_setup_isolation_hw();
+
     tfm_spm_partition_set_state(TFM_SP_CORE_ID, SPM_PARTITION_STATE_RUNNING);
 
     extern uint32_t Stack_Mem[];
diff --git a/secure_fw/core/tfm_handler.c b/secure_fw/core/tfm_handler.c
index 0986f27..1a7150b 100644
--- a/secure_fw/core/tfm_handler.c
+++ b/secure_fw/core/tfm_handler.c
@@ -9,18 +9,13 @@
 #include <string.h>
 
 #include "cmsis.h"
-#include "Driver_MPC.h"
 #include "secure_utilities.h"
 #include "arm_acle.h"
-#include "target_cfg.h"
 #include "tfm_svc.h"
 #include "tfm_secure_api.h"
 #include "region_defs.h"
 #include "tfm_api.h"
 
-/* Import MPC driver */
-extern ARM_DRIVER_MPC Driver_SRAM1_MPC;
-
 /* This SVC handler is called if veneer is running in thread mode */
 extern void tfm_core_partition_request_svc_handler(
         uint32_t *svc_args, uint32_t *lr_ptr);
@@ -108,39 +103,6 @@
 #error "Unsupported ARM Architecture."
 #endif
 
-
-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 */
-    LOG_MSG("Oops... MPC fault!!!");
-    while (1) {
-        ;
-    }
-}
-
-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*/
-    LOG_MSG("Oops... PPC fault!!!");
-    while (1) {
-        ;
-    }
-}
-
 #if defined(__ARM_ARCH_8M_MAIN__)
 __attribute__((naked)) void SVC_Handler(void)
 {
@@ -224,3 +186,10 @@
 
     return TFM_ERROR_GENERIC;
 }
+
+void tfm_access_violation_handler(void)
+{
+    while (1) {
+        ;
+    }
+}
diff --git a/secure_fw/core/tfm_platform_api.h b/secure_fw/core/tfm_platform_api.h
new file mode 100644
index 0000000..26abd41
--- /dev/null
+++ b/secure_fw/core/tfm_platform_api.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_PLATFORM_API_H__
+#define __TFM_PLATFORM_API_H__
+
+/**
+ * \brief Should be called in case of access violation.
+ *
+ * There might be platform specific means, by which it is possible on a
+ * subsystem to detect access violation. For example a platform can have a
+ * Peripheral Protection Controller, to detect unauthorised accesses to
+ * peripheral registers. Setting up the protection, and handling the violation
+ * is implemented in platform specific code. However TF-M should be able to
+ * decide how to proceed if a violation happens. So to notify TF-M, platform
+ * code have to call this function, if a violation happens.
+ */
+void tfm_access_violation_handler(void);
+
+#endif /* __TFM_PLATFORM_API_H__ */
diff --git a/secure_fw/services/audit_logging/manifest.yaml b/secure_fw/services/audit_logging/manifest.yaml
index dbcfd61..fa16238 100644
--- a/secure_fw/services/audit_logging/manifest.yaml
+++ b/secure_fw/services/audit_logging/manifest.yaml
@@ -17,11 +17,8 @@
   "heap_size": "0x0400",
   "mmio_regions" : [
     {
-      "name": "UART1",
-      "base": "UART1_BASE_S",
-      "size": "0xFFF",
+      "name": "TFM_PERIPHERAL_UART1",
       "permission": "READ-WRITE",
-      "ppc_config": "PPC_SP_APB_PPC_EXP1, CMSDK_UART1_APB_PPC_POS",
       "conditional": "LOG_UART_REDIRECTION"
     }
   ],
diff --git a/secure_fw/services/tfm_partition_list.inc b/secure_fw/services/tfm_partition_list.inc
index 223ddce..c5ad1b8 100644
--- a/secure_fw/services/tfm_partition_list.inc
+++ b/secure_fw/services/tfm_partition_list.inc
@@ -18,18 +18,14 @@
 PARTITION_DECLARE(TFM_SP_AUDIT_LOG, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);
 PARTITION_ADD_INIT_FUNC(TFM_SP_AUDIT_LOG, log_core_init);
 #ifdef LOG_UART_REDIRECTION
-PARTITION_ADD_PERIPHERAL(TFM_SP_AUDIT_LOG, UART1_BASE_S,
-    UART1_BASE_S + 0xFFF,
-    PPC_SP_APB_PPC_EXP1, CMSDK_UART1_APB_PPC_POS);
+PARTITION_ADD_PERIPHERAL(TFM_SP_AUDIT_LOG, TFM_PERIPHERAL_UART1);
 #endif /* LOG_UART_REDIRECTION */
 
 #ifdef TFM_PARTITION_TEST_CORE
 /******** TFM_SP_CORE_TEST ********/
 PARTITION_DECLARE(TFM_SP_CORE_TEST, SPM_PART_FLAG_SECURE);
 PARTITION_ADD_INIT_FUNC(TFM_SP_CORE_TEST, core_test_init);
-PARTITION_ADD_PERIPHERAL(TFM_SP_CORE_TEST, MPS2_IO_FPGAIO_BASE_S,
-    MPS2_IO_FPGAIO_BASE_S + 0xFFF,
-    PPC_SP_APB_PPC_EXP2, CMSDK_FPGA_IO_PPC_POS);
+PARTITION_ADD_PERIPHERAL(TFM_SP_CORE_TEST, TFM_PERIPHERAL_FPGA_IO);
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #ifdef TFM_PARTITION_TEST_CORE
diff --git a/secure_fw/services/tfm_partition_list.inc.template b/secure_fw/services/tfm_partition_list.inc.template
index 930ae86..7cc1993 100644
--- a/secure_fw/services/tfm_partition_list.inc.template
+++ b/secure_fw/services/tfm_partition_list.inc.template
@@ -24,10 +24,8 @@
 @!GENERATOR_CONDITIONAL_START!@ @@manifest.mmio_regions.conditional@@

 #ifdef @@manifest.mmio_regions.conditional@@

 @!GENERATOR_CONDITIONAL_END!@

-@!GENERATOR_CONDITIONAL_START!@ @@manifest.mmio_regions.base@@

-PARTITION_ADD_PERIPHERAL(@@manifest.tfm_partition_name@@, @@manifest.mmio_regions.base@@,

-    @@manifest.mmio_regions.base@@ + @@manifest.mmio_regions.size@@,

-    @@manifest.mmio_regions.ppc_config@@);

+@!GENERATOR_CONDITIONAL_START!@ @@manifest.mmio_regions.name@@

+PARTITION_ADD_PERIPHERAL(@@manifest.tfm_partition_name@@, @@manifest.mmio_regions.name@@);

 @!GENERATOR_CONDITIONAL_END!@

 @!GENERATOR_CONDITIONAL_START!@ @@manifest.mmio_regions.conditional@@

 #endif /* @@manifest.mmio_regions.conditional@@ */

diff --git a/secure_fw/spm/CMakeLists.inc b/secure_fw/spm/CMakeLists.inc
index e3f05f6..be6bdf8 100644
--- a/secure_fw/spm/CMakeLists.inc
+++ b/secure_fw/spm/CMakeLists.inc
@@ -24,9 +24,7 @@
 	message(FATAL_ERROR "Please set TFM_ROOT_DIR before including this file.")
 endif()
 
-set (SS_SPM_C_SRC "${SS_SPM_DIR}/mpu_armv8m_drv.c"
-		"${SS_SPM_DIR}/spm_api.c"
-	)
+set (SS_SPM_C_SRC "${SS_SPM_DIR}/spm_api.c")
 
 
 #Append all our source files to global lists.
diff --git a/secure_fw/spm/spm_api.c b/secure_fw/spm/spm_api.c
index fd25dc3..91d30e0 100644
--- a/secure_fw/spm/spm_api.c
+++ b/secure_fw/spm/spm_api.c
@@ -14,28 +14,14 @@
 #include "spm_db_setup.h"
 #include "tfm_internal.h"
 #include "tfm_api.h"
-#include "mpu_armv8m_drv.h"
-#include "region_defs.h"
 #include "secure_fw/core/tfm_core.h"
 #include "platform_retarget.h"
-#include "target_cfg.h"
+#include "tfm_peripherals_def.h"
 #include "spm_partition_defs.h"
 
 
 struct spm_partition_db_t g_spm_partition_db = {0,};
 
-#define MPU_REGION_VENEERS           0
-#define MPU_REGION_TFM_UNPRIV_CODE   1
-#define MPU_REGION_TFM_UNPRIV_DATA   2
-#define MPU_REGION_NS_DATA           3
-#define PARTITION_REGION_RO          4
-#define PARTITION_REGION_RW_STACK    5
-#define PARTITION_REGION_PERIPH      6
-#define PARTITION_REGION_SHARE       7
-
-/* This should move to platform retarget */
-struct mpu_armv8m_dev_t dev_mpu_s = { MPU_BASE };
-
 typedef enum {
     TFM_INIT_FAILURE,
 } sp_error_type_t;
@@ -46,7 +32,7 @@
  * returned.
  */
 static void tfm_spm_partition_err_handler(
-    struct tfm_spm_partition_desc_t *partition,
+    struct spm_partition_desc_t *partition,
     sp_error_type_t err_type,
     int32_t err_code)
 {
@@ -82,7 +68,7 @@
 
 enum spm_err_t tfm_spm_db_init(void)
 {
-    struct tfm_spm_partition_desc_t *part_ptr;
+    struct spm_partition_desc_t *part_ptr;
 
     memset (&g_spm_partition_db, 0, sizeof(g_spm_partition_db));
 
@@ -108,12 +94,12 @@
     part_ptr->static_data.partition_flags = 0;
 
 #if TFM_LVL != 1
-    part_ptr->static_data.stack_bottom = (uint32_t)Stack_Mem;
-    part_ptr->static_data.stack_top = (uint32_t)Stack_top;
+    part_ptr->memory_data.stack_bottom = (uint32_t)Stack_Mem;
+    part_ptr->memory_data.stack_top = (uint32_t)Stack_top;
     /* Since RW, ZI and stack are configured as one MPU region, configure
      * RW start address to Stack_Mem to get RW access to stack
      */
-    part_ptr->static_data.rw_start = (uint32_t)Stack_Mem;
+    part_ptr->memory_data.rw_start = (uint32_t)Stack_Mem;
 #endif
 
     part_ptr->runtime_data.partition_state = SPM_PARTITION_STATE_UNINIT;
@@ -139,129 +125,9 @@
     return SPM_ERR_OK;
 }
 
-#if TFM_LVL != 1
-REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Base);
-REGION_DECLARE(Image$$, TFM_UNPRIV_CODE, $$RO$$Limit);
-REGION_DECLARE(Image$$, TFM_UNPRIV_RO_DATA, $$RW$$Base);
-REGION_DECLARE(Image$$, TFM_UNPRIV_RO_DATA, $$ZI$$Limit);
-REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
-REGION_DECLARE(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);
-
-enum spm_err_t tfm_spm_mpu_init(void)
-{
-    mpu_armv8m_clean(&dev_mpu_s);
-
-    struct mpu_armv8m_region_cfg_t region_cfg;
-
-    /* Veneer region */
-    region_cfg.region_nr = MPU_REGION_VENEERS;
-    region_cfg.region_base = CMSE_VENEER_REGION_START;
-    region_cfg.region_limit = CMSE_VENEER_REGION_LIMIT;
-    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {
-        return SPM_ERR_INVALID_CONFIG;
-    }
-
-    /* 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.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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {
-        return SPM_ERR_INVALID_CONFIG;
-    }
-
-    /* TFM Core unprivileged data region */
-    region_cfg.region_nr = MPU_REGION_TFM_UNPRIV_DATA;
-    region_cfg.region_base =
-        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_RO_DATA, $$RW$$Base);
-    region_cfg.region_limit =
-        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_RO_DATA, $$ZI$$Limit);
-    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_NEVER;
-    if (mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {
-        return SPM_ERR_INVALID_CONFIG;
-    }
-
-    /* TFM Core unprivileged non-secure data region */
-    region_cfg.region_nr = MPU_REGION_NS_DATA;
-    region_cfg.region_base = NS_DATA_START;
-    region_cfg.region_limit = NS_DATA_LIMIT;
-    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {
-        return SPM_ERR_INVALID_CONFIG;
-    }
-
-    mpu_armv8m_enable(&dev_mpu_s, 1, 1);
-
-    return SPM_ERR_OK;
-}
-
-/**
- * Set share region to which the partition needs access
- */
-static enum spm_err_t tfm_spm_set_share_region(
-            enum tfm_buffer_share_region_e share)
-{
-    enum spm_err_t res = SPM_ERR_INVALID_CONFIG;
-    uint32_t scratch_base =
-        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Base);
-    uint32_t scratch_limit =
-        (uint32_t)&REGION_NAME(Image$$, TFM_UNPRIV_SCRATCH, $$ZI$$Limit);
-
-    mpu_armv8m_disable(&dev_mpu_s);
-
-    if (share == TFM_BUFFER_SHARE_DISABLE) {
-        mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_SHARE);
-    } else {
-        struct mpu_armv8m_region_cfg_t region_cfg;
-
-        region_cfg.region_nr = PARTITION_REGION_SHARE;
-        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;
-        switch (share) {
-        case TFM_BUFFER_SHARE_SCRATCH:
-            /* Use scratch area for SP-to-SP data sharing */
-            region_cfg.region_base = scratch_base;
-            region_cfg.region_limit = scratch_limit;
-            res = SPM_ERR_OK;
-            break;
-        case TFM_BUFFER_SHARE_NS_CODE:
-            region_cfg.region_base = NS_CODE_START;
-            region_cfg.region_limit = NS_CODE_LIMIT;
-            /* Only allow read access to NS code region and keep
-             * exec.never attribute
-             */
-            region_cfg.attr_access = MPU_ARMV8M_AP_RO_PRIV_UNPRIV;
-            res = SPM_ERR_OK;
-            break;
-        default:
-            res = SPM_ERR_INVALID_CONFIG;
-            break;
-        }
-        if (res == SPM_ERR_OK) {
-            mpu_armv8m_region_enable(&dev_mpu_s, &region_cfg);
-        }
-    }
-    mpu_armv8m_enable(&dev_mpu_s, 1, 1);
-
-    return res;
-}
-#endif
-
 enum spm_err_t tfm_spm_partition_init(void)
 {
-    struct tfm_spm_partition_desc_t *part;
+    struct spm_partition_desc_t *part;
     struct tfm_sfn_req_s desc, *desc_ptr = &desc;
     int32_t args[4] = {0};
     int32_t fail_cnt = 0;
@@ -270,10 +136,7 @@
     /* Call the init function for each partition */
     for (idx = 0; idx < g_spm_partition_db.partition_count; ++idx) {
         part = &g_spm_partition_db.partitions[idx];
-        if (part->platform_data.periph_start) {
-            ppc_configure_to_secure(part->platform_data.periph_ppc_bank,
-                    part->platform_data.periph_ppc_loc);
-        }
+        tfm_spm_hal_configure_default_isolation(part->platform_data);
         if (part->static_data.partition_init == NULL) {
             tfm_spm_partition_set_state(idx, SPM_PARTITION_STATE_IDLE);
             tfm_spm_partition_set_caller_partition_idx(idx,
@@ -314,71 +177,16 @@
 #if TFM_LVL != 1
 enum spm_err_t tfm_spm_partition_sandbox_config(uint32_t partition_idx)
 {
-    /* This function takes a partition id and enables the
-     * SPM partition for that partition
-     */
-
-    struct tfm_spm_partition_desc_t *part;
-    struct mpu_armv8m_region_cfg_t region_cfg;
-
+    struct spm_partition_desc_t *part;
     if (!g_spm_partition_db.is_init) {
         return SPM_ERR_PARTITION_DB_NOT_INIT;
     }
 
-    /*brute force id*/
     part = &g_spm_partition_db.partitions[partition_idx];
 
-    mpu_armv8m_disable(&dev_mpu_s);
+    return tfm_spm_hal_partition_sandbox_config(&(part->memory_data),
+                                                part->platform_data);
 
-    /* Configure Regions */
-
-    if (part->static_data.ro_start) {
-        /* RO region*/
-        region_cfg.region_nr = PARTITION_REGION_RO;
-        region_cfg.region_base = part->static_data.ro_start;
-        region_cfg.region_limit = part->static_data.ro_limit;
-        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_armv8m_region_enable(&dev_mpu_s, &region_cfg)
-            != MPU_ARMV8M_OK) {
-            return SPM_ERR_INVALID_CONFIG;
-        }
-    }
-
-    /* RW, ZI and stack as one region*/
-    region_cfg.region_nr = PARTITION_REGION_RW_STACK;
-    region_cfg.region_base = part->static_data.rw_start;
-    region_cfg.region_limit = part->static_data.stack_top;
-    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_armv8m_region_enable(&dev_mpu_s, &region_cfg) != MPU_ARMV8M_OK) {
-        return SPM_ERR_INVALID_CONFIG;
-    }
-
-    if (part->platform_data.periph_start) {
-        /* Peripheral */
-        region_cfg.region_nr = PARTITION_REGION_PERIPH;
-        region_cfg.region_base = part->platform_data.periph_start;
-        region_cfg.region_limit = part->platform_data.periph_limit;
-        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_armv8m_region_enable(&dev_mpu_s, &region_cfg)
-            != MPU_ARMV8M_OK) {
-            return SPM_ERR_INVALID_CONFIG;
-        }
-
-        ppc_en_secure_unpriv(part->platform_data.periph_ppc_bank,
-                             part->platform_data.periph_ppc_loc);
-    }
-
-    mpu_armv8m_enable(&dev_mpu_s, 1, 1);
-
-    return SPM_ERR_OK;
 }
 
 enum spm_err_t tfm_spm_partition_sandbox_deconfig(uint32_t partition_idx)
@@ -387,35 +195,23 @@
      * SPM partition for that partition
      */
 
-    struct tfm_spm_partition_desc_t *part;
+    struct spm_partition_desc_t *part;
 
     part = &g_spm_partition_db.partitions[partition_idx];
 
-    if (part->platform_data.periph_start) {
-        /* Peripheral */
-        ppc_clr_secure_unpriv(part->platform_data.periph_ppc_bank,
-                              part->platform_data.periph_ppc_loc);
-    }
-
-    mpu_armv8m_disable(&dev_mpu_s);
-    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_RO);
-    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_RW_STACK);
-    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_PERIPH);
-    mpu_armv8m_region_disable(&dev_mpu_s, PARTITION_REGION_SHARE);
-    mpu_armv8m_enable(&dev_mpu_s, 1, 1);
-
-    return SPM_ERR_OK;
+    return tfm_spm_hal_partition_sandbox_deconfig(&(part->memory_data),
+                                                  part->platform_data);
 }
 
 uint32_t tfm_spm_partition_get_stack_bottom(uint32_t partition_idx)
 {
     return g_spm_partition_db.partitions[partition_idx].
-            static_data.stack_bottom;
+            memory_data.stack_bottom;
 }
 
 uint32_t tfm_spm_partition_get_stack_top(uint32_t partition_idx)
 {
-    return g_spm_partition_db.partitions[partition_idx].static_data.stack_top;
+    return g_spm_partition_db.partitions[partition_idx].memory_data.stack_top;
 }
 
 void tfm_spm_partition_set_stack(uint32_t partition_idx, uint32_t stack_ptr)
@@ -485,7 +281,7 @@
 
 #if TFM_LVL != 1
     /* Only need to set configuration on levels higher than 1 */
-    ret = tfm_spm_set_share_region(share);
+    ret = tfm_spm_hal_set_share_region(share);
 #endif
 
     if (ret == SPM_ERR_OK) {
@@ -501,7 +297,7 @@
 
 void tfm_spm_partition_cleanup_context(uint32_t partition_idx)
 {
-    struct tfm_spm_partition_desc_t *partition =
+    struct spm_partition_desc_t *partition =
             &(g_spm_partition_db.partitions[partition_idx]);
     partition->runtime_data.caller_partition_idx = SPM_INVALID_PARTITION_IDX;
     partition->runtime_data.orig_psp = 0;
diff --git a/secure_fw/spm/spm_api.h b/secure_fw/spm/spm_api.h
index 5e15044..7743d45 100644
--- a/secure_fw/spm/spm_api.h
+++ b/secure_fw/spm/spm_api.h
@@ -233,13 +233,6 @@
 enum spm_err_t tfm_spm_db_init(void);
 
 /**
- * \brief Apply default MPU configuration for execution
- *
- * \return Error code \ref spm_err_t
- */
-enum spm_err_t tfm_spm_mpu_init(void);
-
-/**
  * \brief Execute partition init function
  *
  * \return Error code \ref spm_err_t
diff --git a/secure_fw/spm/spm_db.h b/secure_fw/spm/spm_db.h
index d267f6d..4b3b413 100644
--- a/secure_fw/spm/spm_db.h
+++ b/secure_fw/spm/spm_db.h
@@ -18,18 +18,6 @@
 struct spm_partition_static_data_t {
     uint32_t partition_id;
     uint32_t partition_flags;
-#if TFM_LVL != 1
-    uint32_t code_start;
-    uint32_t code_limit;
-    uint32_t ro_start;
-    uint32_t ro_limit;
-    uint32_t rw_start;
-    uint32_t rw_limit;
-    uint32_t zi_start;
-    uint32_t zi_limit;
-    uint32_t stack_bottom;
-    uint32_t stack_top;
-#endif
     sp_init_function partition_init;
 };
 
@@ -37,10 +25,24 @@
  * Holds the fields that define a partition for SPM. The fields are further
  * divided to structures, to keep the related fields close to each other.
  */
-struct tfm_spm_partition_desc_t {
+struct spm_partition_desc_t {
     struct spm_partition_static_data_t static_data;
     struct spm_partition_runtime_data_t runtime_data;
-    struct tfm_spm_partition_platform_data_t platform_data;
+    struct tfm_spm_partition_platform_data_t *platform_data;
+#if TFM_LVL != 1
+    struct tfm_spm_partition_memory_data_t memory_data;
+#endif
 };
 
+/* Macros to pick linker symbols and allow to form the partition data base */
+#define REGION(a, b, c) a##b##c
+#define REGION_NAME(a, b, c) REGION(a, b, c)
+#if TFM_LVL == 1
+#define REGION_DECLARE(a, b, c)
+#else
+#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)
+#define PART_REGION_ADDR(partition, region) \
+    (uint32_t)&REGION_NAME(Image$$, partition, region)
+#endif
+
 #endif /* __SPM_DB_H__ */
diff --git a/secure_fw/spm/spm_db_setup.h b/secure_fw/spm/spm_db_setup.h
index 4862798..d36f8cf 100644
--- a/secure_fw/spm/spm_db_setup.h
+++ b/secure_fw/spm/spm_db_setup.h
@@ -12,10 +12,10 @@
 #include "spm_db.h"
 
 /**
- * \brief Return the index of a partition.
+ * \brief Get the index of a partition.
  *
- * Returns the index of a partition in the partition db based on the partition
- * ID provided as a parameter.
+ * Gets the index of a partition in the partition db based on the partition ID
+ * provided as a parameter.
  *
  * \param[in] partition_id    The ID of the partition
  *
@@ -28,32 +28,20 @@
     uint32_t is_init;
     uint32_t partition_count;
     uint32_t running_partition_idx;
-    struct tfm_spm_partition_desc_t partitions[SPM_MAX_PARTITIONS];
+    struct spm_partition_desc_t partitions[SPM_MAX_PARTITIONS];
 };
 
-/* Macros to pick linker symbols and allow to form the partition data base */
-#define REGION(a, b, c) a##b##c
-#define REGION_NAME(a, b, c) REGION(a, b, c)
-#if TFM_LVL == 1
-#define REGION_DECLARE(a, b, c)
-#else
-#define REGION_DECLARE(a, b, c) extern uint32_t REGION_NAME(a, b, c)
-#define PART_REGION_ADDR(partition, region) \
-    (uint32_t)&REGION_NAME(Image$$, partition, region)
-#endif
-
-
-#if TFM_LVL == 1
 #define PARTITION_INIT_STATIC_DATA(data, partition, flags) \
     do {                                                   \
         data.partition_id    = partition##_ID;             \
         data.partition_flags = flags;                      \
     } while (0)
+
+#if TFM_LVL == 1
+#define PARTITION_INIT_MEMORY_DATA(data, partition)
 #else
-#define PARTITION_INIT_STATIC_DATA(data, partition, flags)                     \
+#define PARTITION_INIT_MEMORY_DATA(data, partition)                            \
     do {                                                                       \
-        data.partition_id    = partition##_ID;                                 \
-        data.partition_flags = flags;                                          \
         data.code_start      = PART_REGION_ADDR(partition, $$Base);            \
         data.code_limit      = PART_REGION_ADDR(partition, $$Limit);           \
         data.ro_start        = PART_REGION_ADDR(partition, $$RO$$Base);        \
@@ -67,6 +55,7 @@
     } while (0)
 #endif
 
+
 #if TFM_LVL == 1
 #define PARTITION_INIT_RUNTIME_DATA(data, partition)            \
     do {                                                        \
@@ -93,7 +82,7 @@
         REGION_DECLARE(Image$$, partition, _DATA$$ZI$$Limit);                \
         REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Base);                \
         REGION_DECLARE(Image$$, partition, _STACK$$ZI$$Limit);               \
-        struct tfm_spm_partition_desc_t *part_ptr;                           \
+        struct spm_partition_desc_t *part_ptr;                               \
         if (g_spm_partition_db.partition_count >= SPM_MAX_PARTITIONS) {      \
             return SPM_ERR_INVALID_CONFIG;                                   \
         }                                                                    \
@@ -101,6 +90,7 @@
             g_spm_partition_db.partition_count]);                            \
         PARTITION_INIT_STATIC_DATA(part_ptr->static_data, partition, flags); \
         PARTITION_INIT_RUNTIME_DATA(part_ptr->runtime_data, partition);      \
+        PARTITION_INIT_MEMORY_DATA(part_ptr->memory_data, partition);        \
         ++g_spm_partition_db.partition_count;                                \
     } while (0)
 
@@ -108,20 +98,17 @@
     do {                                                              \
         extern int32_t init_func(void);                               \
         uint32_t partition_idx = get_partition_idx(partition##_ID);   \
-        struct tfm_spm_partition_desc_t *part_ptr =                   \
+        struct spm_partition_desc_t *part_ptr =                       \
             &(g_spm_partition_db.partitions[partition_idx]);          \
         part_ptr->static_data.partition_init = init_func;             \
     } while (0)
 
-#define PARTITION_ADD_PERIPHERAL(partition, start, limit, bank, loc)   \
+#define PARTITION_ADD_PERIPHERAL(partition, peripheral)               \
     do {                                                               \
         uint32_t partition_idx = get_partition_idx(partition##_ID);    \
-        struct tfm_spm_partition_desc_t *part_ptr =                    \
+        struct spm_partition_desc_t *part_ptr =                        \
             &(g_spm_partition_db.partitions[partition_idx]);           \
-        part_ptr->platform_data.periph_start = start;                  \
-        part_ptr->platform_data.periph_limit = limit;                  \
-        part_ptr->platform_data.periph_ppc_bank = bank;                \
-        part_ptr->platform_data.periph_ppc_loc = loc;                  \
+        part_ptr->platform_data = peripheral;                          \
     } while (0)
 
 #endif /* __SPM_DB_SETUP_H__ */
diff --git a/test/test_services/tfm_core_test/manifest.yaml b/test/test_services/tfm_core_test/manifest.yaml
index ae4b133..7a62855 100644
--- a/test/test_services/tfm_core_test/manifest.yaml
+++ b/test/test_services/tfm_core_test/manifest.yaml
@@ -16,10 +16,7 @@
   "heap_size": "0x0400",
   "mmio_regions": [
     {
-      "name": "GPIO",
-      "base": "MPS2_IO_FPGAIO_BASE_S",
-      "size": "0xFFF",
-      "ppc_config": "PPC_SP_APB_PPC_EXP2, CMSDK_FPGA_IO_PPC_POS",
+      "name": "TFM_PERIPHERAL_FPGA_IO",
       "permission": "READ-WRITE"
     }
   ],