PlatformSP: Add Platform service

TF-M Platform service is a trusted service which allows secure
partitions and non-secure applications to interact with some
platform-specific components. There are a number of features which
requires some interaction with platform-specific components which
are at the same time essential for the security of the system.
Therefore, those components need to be handled by a secure partition
which is part of the trusted compute base.

This patch adds the Platform service which provides the system reset
as a first function.

Change-Id: I68253328db22a45fb6a3d6820dd85b1e24ea96f0
Signed-off-by: Marc Moreno <marc.morenoberengue@arm.com>
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index b02a2af..8b49abb 100755
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -46,6 +46,7 @@
 	"${INTERFACE_DIR}/src/tfm_sst_api.c"
 	"${INTERFACE_DIR}/src/tfm_audit_api.c"
 	"${INTERFACE_DIR}/src/tfm_crypto_api.c"
+	"${INTERFACE_DIR}/src/tfm_platform_api.c"
 	"${INTERFACE_DIR}/src/tfm_nspm_svc_handler.c"
 	"${INTERFACE_DIR}/src/tfm_nspm_api.c"
 	"${INTERFACE_DIR}/src/tfm_ns_lock_rtx.c"
diff --git a/docs/user_guides/services/tfm_platform_integration_guide.md b/docs/user_guides/services/tfm_platform_integration_guide.md
new file mode 100644
index 0000000..b6630ec
--- /dev/null
+++ b/docs/user_guides/services/tfm_platform_integration_guide.md
@@ -0,0 +1,65 @@
+# TF-M Platform Service Integration Guide
+
+## Introduction
+
+TF-M Platform service is a trusted service which allows secure partitions and
+non-secure applications to interact with some platform-specific components.
+There are a number of features which requires some interaction with
+platform-specific components which are at the same time essential for the
+security of the system.
+Therefore, those components need to be handled by a secure partition which is
+part of the trusted compute base.
+
+These platform-specific components include system reset, power management,
+Debug, GPIO, etc.
+
+## TF-M Platform interfaces
+
+The TF-M interfaces for the Platform service are located in
+`interface/include/`.
+The TF-M Platform service source files are located in
+`secure_fw/services/platform`.
+
+## TF-M Platform service
+
+The Platform service exposes the following interfaces:
+ - `enum tfm_platform_err_t tfm_platform_system_reset(void)`
+
+The Platform service interfaces and types are defined and documented in
+`interface/include/tfm_platform_api.h`
+
+ - `platform_sp.h/c` : These files define and implement functionalities related
+   to the platform service;
+ - `tfm_platform_secure_api.c` : This file implements `tfm_platform_api.h`
+ functions to be called from the secure partitions. This is the entry point when
+ the secure partitions request an action to the Platform service
+ (e.g system reset).
+
+## Platform HAL system reset
+
+The Platform service service relies on a platform-specific implementation to
+perform some functionalities (e.g. system reset). The platform-specific
+implementation of those APIs will be located in the platform service code
+section (TF-M level 3 isolation) in order to protect it from a direct call from
+other secure partitions.
+
+For API specification, please check:
+`platform/include/tfm_platform_system.h`
+
+An implementation is provided in all the supported platforms. Please,
+check  `platform/ext/target/<SPECIFIC_TARGET_FOLDER>/tfm_platform_system.c`
+
+The API **must** be implemented by the system integrators for their targets.
+
+## Current Service Limitations
+
+The system reset functionality is only supported in isolation level 1.
+Currently, the mechanism by which PRoT services should run in privileged mode in
+level 3, it is not in place due to an ongoing work in TF-M Core. So, the
+NVIC_SystemReset call performed by the service, it is expected to generate a
+memory fault when it tries to access the SCB->AIRCR register in level 3
+isolation.
+
+--------------
+
+*Copyright (c) 2018, Arm Limited. All rights reserved.*
diff --git a/interface/include/tfm_platform_api.h b/interface/include/tfm_platform_api.h
new file mode 100644
index 0000000..1c3069e
--- /dev/null
+++ b/interface/include/tfm_platform_api.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_PLATFORM_API__
+#define __TFM_PLATFORM_API__
+
+#include <limits.h>
+#include "tfm_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief TFM secure partition platform API version
+ */
+#define TFM_PLATFORM_API_VERSION_MAJOR (0)
+#define TFM_PLATFORM_API_VERSION_MINOR (1)
+
+/* The return value is shared with the TF-M partition status value.
+ * The Platform return codes shouldn't overlap with predefined TFM status
+ * values.
+ */
+#define TFM_PLATFORM_ERR_OFFSET (TFM_PARTITION_SPECIFIC_ERROR_MIN)
+
+/*!
+ * \enum tfm_platform_err_t
+ *
+ * \brief Platform service error types
+ *
+ */
+enum tfm_platform_err_t {
+    TFM_PLATFORM_ERR_SUCCESS = 0,
+    TFM_PLATFORM_ERR_SYSTEM_ERROR = TFM_PLATFORM_ERR_OFFSET,
+
+    /* Following entry is only to ensure the error code of int size */
+    TFM_PLATFORM_ERR_FORCE_INT_SIZE = INT_MAX
+};
+
+/*!
+ * \brief Resets the system.
+ *
+ * \return Returns values as specified by the \ref tfm_platform_err_t
+ */
+enum tfm_platform_err_t tfm_platform_system_reset(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_PLATFORM_API__ */
diff --git a/interface/include/tfm_platform_veneers.h b/interface/include/tfm_platform_veneers.h
new file mode 100644
index 0000000..313927e
--- /dev/null
+++ b/interface/include/tfm_platform_veneers.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_PLATFORM_VENEERS_H__
+#define __TFM_PLATFORM_VENEERS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "tfm_platform_api.h"
+
+/*!
+ * \brief Resets the system.
+ *
+ * \return Returns values as specified by the \ref tfm_platform_err_t
+ */
+enum tfm_platform_err_t tfm_platform_veneer_system_reset(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_PLATFORM_VENEERS_H__ */
diff --git a/interface/src/tfm_platform_api.c b/interface/src/tfm_platform_api.c
new file mode 100644
index 0000000..b4e1162
--- /dev/null
+++ b/interface/src/tfm_platform_api.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_platform_api.h"
+#include "tfm_platform_veneers.h"
+#include "tfm_ns_lock.h"
+
+enum tfm_platform_err_t tfm_platform_system_reset(void)
+{
+    return tfm_ns_lock_dispatch((veneer_fn)tfm_platform_veneer_system_reset,
+                                0,
+                                0,
+                                0,
+                                0);
+}
diff --git a/platform/ext/Mps2AN519.cmake b/platform/ext/Mps2AN519.cmake
index d8d06cb..0a0741e 100644
--- a/platform/ext/Mps2AN519.cmake
+++ b/platform/ext/Mps2AN519.cmake
@@ -116,6 +116,7 @@
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/mps2/an519/target_cfg.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")
+  list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an519/tfm_platform_system.c")
   embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
 endif()
 
diff --git a/platform/ext/Mps2AN521.cmake b/platform/ext/Mps2AN521.cmake
index 451a36d..a95b472 100644
--- a/platform/ext/Mps2AN521.cmake
+++ b/platform/ext/Mps2AN521.cmake
@@ -117,6 +117,7 @@
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/mps2/an521/target_cfg.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")
+  list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/mps2/an521/tfm_platform_system.c")
   embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
 endif()
 
diff --git a/platform/ext/musca_a.cmake b/platform/ext/musca_a.cmake
index 4201cd6..ccd5073 100755
--- a/platform/ext/musca_a.cmake
+++ b/platform/ext/musca_a.cmake
@@ -120,6 +120,7 @@
   list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/musca_a/target_cfg.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")
+  list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_a/tfm_platform_system.c")
   embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
 endif()
 
diff --git a/platform/ext/musca_b1.cmake b/platform/ext/musca_b1.cmake
index e29802b..c34782a 100755
--- a/platform/ext/musca_b1.cmake
+++ b/platform/ext/musca_b1.cmake
@@ -116,6 +116,7 @@
     list(APPEND ALL_SRC_C "${PLATFORM_DIR}/target/musca_b1/target_cfg.c")
     list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_b1/spm_hal.c")
     list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_b1/Native_Driver/mpu_armv8m_drv.c")
+    list(APPEND ALL_SRC_C_S "${PLATFORM_DIR}/target/musca_b1/tfm_platform_system.c")
     embedded_include_directories(PATH "${PLATFORM_DIR}/common" ABSOLUTE)
 endif()
 
diff --git a/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct b/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
index c4e1ad2..a399414 100644
--- a/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
+++ b/platform/ext/target/mps2/an519/armclang/mps2_an519_s.sct
@@ -65,6 +65,11 @@
         *(TFM_SP_CRYPTO_ATTR_FN)
     }
 
+    TFM_SP_PLATFORM +0 ALIGN 32 {
+        *tfm_platform* (+RO)
+        *(TFM_SP_PLATFORM_ATTR_FN)
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST +0 ALIGN 32 {
         *tfm_ss_core_test.* (+RO)
@@ -131,6 +136,13 @@
     TFM_SP_CRYPTO_STACK +0 ALIGN 128 EMPTY 0x2000 {
     }
 
+    TFM_SP_PLATFORM_DATA +0 ALIGN 32 {
+        *tfm_platform* (+RW +ZI)
+    }
+
+    TFM_SP_PLATFORM_STACK +0 ALIGN 128 EMPTY 0x0400 {
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
         tfm_ss_core_test.o (+RW +ZI)
diff --git a/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld b/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld
index 42ebba0..649fc8c 100644
--- a/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld
+++ b/platform/ext/target/mps2/an519/gcc/mps2_an519_s.ld
@@ -100,6 +100,9 @@
         LONG (LOADADDR(.TFM_SP_CRYPTO_DATA))
         LONG (ADDR(.TFM_SP_CRYPTO_DATA))
         LONG (SIZEOF(.TFM_SP_CRYPTO_DATA))
+        LONG (LOADADDR(.TFM_SP_PLATFORM_DATA))
+        LONG (ADDR(.TFM_SP_PLATFORM_DATA))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_DATA))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
         LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -142,6 +145,10 @@
         LONG (SIZEOF(.TFM_SP_CRYPTO_BSS))
         LONG (ADDR(.TFM_SP_CRYPTO_STACK))
         LONG (SIZEOF(.TFM_SP_CRYPTO_STACK))
+        LONG (ADDR(.TFM_SP_PLATFORM_BSS))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_BSS))
+        LONG (ADDR(.TFM_SP_PLATFORM_STACK))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_STACK))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
         LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -225,6 +232,18 @@
     Image$$TFM_SP_CRYPTO$$Base = ADDR(.TFM_SP_CRYPTO);
     Image$$TFM_SP_CRYPTO$$Limit = ADDR(.TFM_SP_CRYPTO) + SIZEOF(.TFM_SP_CRYPTO);
 
+    .TFM_SP_PLATFORM : ALIGN(32)
+    {
+        *tfm_platform*:*(.text*)
+        *tfm_platform*:*(.rodata*)
+        *(TFM_SP_PLATFORM_ATTR_FN)
+        . = ALIGN(32);
+    } > FLASH
+    Image$$TFM_SP_PLATFORM$$RO$$Base = ADDR(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$RO$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$Base = ADDR(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST : ALIGN(32)
     {
@@ -459,6 +478,30 @@
     Image$$TFM_SP_CRYPTO_STACK$$ZI$$Base = ADDR(.TFM_SP_CRYPTO_STACK);
     Image$$TFM_SP_CRYPTO_STACK$$ZI$$Limit = ADDR(.TFM_SP_CRYPTO_STACK) + SIZEOF(.TFM_SP_CRYPTO_STACK);
 
+    .TFM_SP_PLATFORM_DATA : ALIGN(32)
+    {
+        *tfm_platform*:*(.data*)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_DATA$$RW$$Base = ADDR(.TFM_SP_PLATFORM_DATA);
+    Image$$TFM_SP_PLATFORM_DATA$$RW$$Limit = ADDR(.TFM_SP_PLATFORM_DATA) + SIZEOF(.TFM_SP_PLATFORM_DATA);
+
+    .TFM_SP_PLATFORM_BSS : ALIGN(32)
+    {
+        *tfm_platform*:*(.bss*)
+        *tfm_platform*:*(COMMON)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_DATA$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_BSS);
+    Image$$TFM_SP_PLATFORM_DATA$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_BSS) + SIZEOF(.TFM_SP_PLATFORM_BSS);
+
+    .TFM_SP_PLATFORM_STACK : ALIGN(128)
+    {
+        . += 0x0400;
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_STACK$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_STACK);
+    Image$$TFM_SP_PLATFORM_STACK$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_STACK) + SIZEOF(.TFM_SP_PLATFORM_STACK);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST_DATA : ALIGN(32)
     {
diff --git a/platform/ext/target/mps2/an519/target_cfg.c b/platform/ext/target/mps2/an519/target_cfg.c
index f43f621..7370513 100755
--- a/platform/ext/target/mps2/an519/target_cfg.c
+++ b/platform/ext/target/mps2/an519/target_cfg.c
@@ -72,6 +72,14 @@
 #define PERIPHERALS_BASE_NS_START (0x40000000)
 #define PERIPHERALS_BASE_NS_END   (0x4FFFFFFF)
 
+/* Enable system reset request for CPU 0 */
+#define ENABLE_CPU0_SYSTEM_RESET_REQUEST (1U << 4U)
+
+/* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
+ * otherwise the processor ignores the write.
+ */
+#define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
+
 struct tfm_spm_partition_platform_data_t tfm_peripheral_std_uart = {
         UART0_BASE_NS,
         UART0_BASE_NS + 0xFFF,
@@ -100,6 +108,22 @@
      */
 }
 
+void system_reset_cfg(void)
+{
+    struct sysctrl_t *sysctrl = (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
+    uint32_t reg_value = SCB->AIRCR;
+
+    /* Enable system reset request for CPU 0, to be triggered via
+     * NVIC_SystemReset function.
+     */
+    sysctrl->resetmask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST;
+
+    /* Enable system reset request for the secure world only */
+    reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
+
+    SCB->AIRCR = reg_value;
+}
+
 /*----------------- NVIC interrupt target state to NS configuration ----------*/
 void nvic_interrupt_target_state_cfg()
 {
diff --git a/platform/ext/target/mps2/an519/tfm_platform_system.c b/platform/ext/target/mps2/an519/tfm_platform_system.c
new file mode 100644
index 0000000..1e8a9ab
--- /dev/null
+++ b/platform/ext/target/mps2/an519/tfm_platform_system.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "platform/include/tfm_platform_system.h"
+#include "cmsis.h"
+
+void tfm_platform_hal_system_reset(void)
+{
+    /* Reset the system */
+    NVIC_SystemReset();
+}
+
diff --git a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
index cea2ba1..a399414 100644
--- a/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
+++ b/platform/ext/target/mps2/an521/armclang/mps2_an521_s.sct
@@ -65,6 +65,11 @@
         *(TFM_SP_CRYPTO_ATTR_FN)
     }
 
+    TFM_SP_PLATFORM +0 ALIGN 32 {
+        *tfm_platform* (+RO)
+        *(TFM_SP_PLATFORM_ATTR_FN)
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST +0 ALIGN 32 {
         *tfm_ss_core_test.* (+RO)
@@ -131,6 +136,12 @@
     TFM_SP_CRYPTO_STACK +0 ALIGN 128 EMPTY 0x2000 {
     }
 
+    TFM_SP_PLATFORM_DATA +0 ALIGN 32 {
+        *tfm_platform* (+RW +ZI)
+    }
+
+    TFM_SP_PLATFORM_STACK +0 ALIGN 128 EMPTY 0x0400 {
+    }
 
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
diff --git a/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld b/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
index c91e649..05fbee3 100644
--- a/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
+++ b/platform/ext/target/mps2/an521/gcc/mps2_an521_s.ld
@@ -100,6 +100,9 @@
         LONG (LOADADDR(.TFM_SP_CRYPTO_DATA))
         LONG (ADDR(.TFM_SP_CRYPTO_DATA))
         LONG (SIZEOF(.TFM_SP_CRYPTO_DATA))
+        LONG (LOADADDR(.TFM_SP_PLATFORM_DATA))
+        LONG (ADDR(.TFM_SP_PLATFORM_DATA))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_DATA))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
         LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -142,6 +145,10 @@
         LONG (SIZEOF(.TFM_SP_CRYPTO_BSS))
         LONG (ADDR(.TFM_SP_CRYPTO_STACK))
         LONG (SIZEOF(.TFM_SP_CRYPTO_STACK))
+        LONG (ADDR(.TFM_SP_PLATFORM_BSS))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_BSS))
+        LONG (ADDR(.TFM_SP_PLATFORM_STACK))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_STACK))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
         LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -225,6 +232,18 @@
     Image$$TFM_SP_CRYPTO$$Base = ADDR(.TFM_SP_CRYPTO);
     Image$$TFM_SP_CRYPTO$$Limit = ADDR(.TFM_SP_CRYPTO) + SIZEOF(.TFM_SP_CRYPTO);
 
+    .TFM_SP_PLATFORM : ALIGN(32)
+    {
+        *tfm_platform*:*(.text*)
+        *tfm_platform*:*(.rodata*)
+        *(TFM_SP_PLATFORM_ATTR_FN)
+        . = ALIGN(32);
+    } > FLASH
+    Image$$TFM_SP_PLATFORM$$RO$$Base = ADDR(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$RO$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$Base = ADDR(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST : ALIGN(32)
     {
@@ -459,6 +478,30 @@
     Image$$TFM_SP_CRYPTO_STACK$$ZI$$Base = ADDR(.TFM_SP_CRYPTO_STACK);
     Image$$TFM_SP_CRYPTO_STACK$$ZI$$Limit = ADDR(.TFM_SP_CRYPTO_STACK) + SIZEOF(.TFM_SP_CRYPTO_STACK);
 
+    .TFM_SP_PLATFORM_DATA : ALIGN(32)
+    {
+        *tfm_platform*:*(.data*)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_DATA$$RW$$Base = ADDR(.TFM_SP_PLATFORM_DATA);
+    Image$$TFM_SP_PLATFORM_DATA$$RW$$Limit = ADDR(.TFM_SP_PLATFORM_DATA) + SIZEOF(.TFM_SP_PLATFORM_DATA);
+
+    .TFM_SP_PLATFORM_BSS : ALIGN(32)
+    {
+        *tfm_platform*:*(.bss*)
+        *tfm_platform*:*(COMMON)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_DATA$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_BSS);
+    Image$$TFM_SP_PLATFORM_DATA$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_BSS) + SIZEOF(.TFM_SP_PLATFORM_BSS);
+
+    .TFM_SP_PLATFORM_STACK : ALIGN(128)
+    {
+        . += 0x0400;
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_STACK$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_STACK);
+    Image$$TFM_SP_PLATFORM_STACK$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_STACK) + SIZEOF(.TFM_SP_PLATFORM_STACK);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST_DATA : ALIGN(32)
     {
diff --git a/platform/ext/target/mps2/an521/target_cfg.c b/platform/ext/target/mps2/an521/target_cfg.c
index 65ae802..98fe3c9 100755
--- a/platform/ext/target/mps2/an521/target_cfg.c
+++ b/platform/ext/target/mps2/an521/target_cfg.c
@@ -72,6 +72,14 @@
 #define PERIPHERALS_BASE_NS_START (0x40000000)
 #define PERIPHERALS_BASE_NS_END   (0x4FFFFFFF)
 
+/* Enable system reset request for CPU 0 */
+#define ENABLE_CPU0_SYSTEM_RESET_REQUEST (1U << 4U)
+
+/* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
+ * otherwise the processor ignores the write.
+ */
+#define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
+
 struct tfm_spm_partition_platform_data_t tfm_peripheral_std_uart = {
         UART0_BASE_NS,
         UART0_BASE_NS + 0xFFF,
@@ -102,6 +110,22 @@
                   | SCB_SHCSR_SECUREFAULTENA_Msk;
 }
 
+void system_reset_cfg(void)
+{
+    struct sysctrl_t *sysctrl = (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
+    uint32_t reg_value = SCB->AIRCR;
+
+    /* Enable system reset request for CPU 0, to be triggered via
+     * NVIC_SystemReset function.
+     */
+    sysctrl->resetmask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST;
+
+    /* Enable system reset request only to the secure world */
+    reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
+
+    SCB->AIRCR = reg_value;
+}
+
 /*----------------- NVIC interrupt target state to NS configuration ----------*/
 void nvic_interrupt_target_state_cfg()
 {
diff --git a/platform/ext/target/mps2/an521/tfm_platform_system.c b/platform/ext/target/mps2/an521/tfm_platform_system.c
new file mode 100644
index 0000000..1e8a9ab
--- /dev/null
+++ b/platform/ext/target/mps2/an521/tfm_platform_system.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "platform/include/tfm_platform_system.h"
+#include "cmsis.h"
+
+void tfm_platform_hal_system_reset(void)
+{
+    /* Reset the system */
+    NVIC_SystemReset();
+}
+
diff --git a/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct b/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
index ad77287..2552c76 100755
--- a/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
+++ b/platform/ext/target/musca_a/Device/Source/armclang/musca_s.sct
@@ -65,6 +65,11 @@
         *(TFM_SP_CRYPTO_ATTR_FN)
     }
 
+    TFM_SP_PLATFORM +0 ALIGN 32 {
+        *tfm_platform* (+RO)
+        *(TFM_SP_PLATFORM_ATTR_FN)
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST +0 ALIGN 32 {
         *tfm_ss_core_test.* (+RO)
@@ -131,6 +136,13 @@
     TFM_SP_CRYPTO_STACK +0 ALIGN 128 EMPTY 0x2000 {
     }
 
+    TFM_SP_PLATFORM_DATA +0 ALIGN 32 {
+        *tfm_platform* (+RW +ZI)
+    }
+
+    TFM_SP_PLATFORM_STACK +0 ALIGN 128 EMPTY 0x0400 {
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
         tfm_ss_core_test.o (+RW +ZI)
diff --git a/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld b/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld
index e686d66..156247c 100644
--- a/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld
+++ b/platform/ext/target/musca_a/Device/Source/gcc/musca_s.ld
@@ -100,6 +100,9 @@
         LONG (LOADADDR(.TFM_SP_CRYPTO_DATA))
         LONG (ADDR(.TFM_SP_CRYPTO_DATA))
         LONG (SIZEOF(.TFM_SP_CRYPTO_DATA))
+        LONG (LOADADDR(.TFM_SP_PLATFORM_DATA))
+        LONG (ADDR(.TFM_SP_PLATFORM_DATA))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_DATA))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
         LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -142,6 +145,10 @@
         LONG (SIZEOF(.TFM_SP_CRYPTO_BSS))
         LONG (ADDR(.TFM_SP_CRYPTO_STACK))
         LONG (SIZEOF(.TFM_SP_CRYPTO_STACK))
+        LONG (ADDR(.TFM_SP_PLATFORM_BSS))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_BSS))
+        LONG (ADDR(.TFM_SP_PLATFORM_STACK))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_STACK))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
         LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -225,6 +232,18 @@
     Image$$TFM_SP_CRYPTO$$Base = ADDR(.TFM_SP_CRYPTO);
     Image$$TFM_SP_CRYPTO$$Limit = ADDR(.TFM_SP_CRYPTO) + SIZEOF(.TFM_SP_CRYPTO);
 
+    .TFM_SP_PLATFORM : ALIGN(32)
+    {
+        *tfm_platform*:*(.text*)
+        *tfm_platform*:*(.rodata*)
+        *(TFM_SP_PLATFORM_ATTR_FN)
+        . = ALIGN(32);
+    } > FLASH
+    Image$$TFM_SP_PLATFORM$$RO$$Base = ADDR(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$RO$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$Base = ADDR(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST : ALIGN(32)
     {
@@ -459,6 +478,30 @@
     Image$$TFM_SP_CRYPTO_STACK$$ZI$$Base = ADDR(.TFM_SP_CRYPTO_STACK);
     Image$$TFM_SP_CRYPTO_STACK$$ZI$$Limit = ADDR(.TFM_SP_CRYPTO_STACK) + SIZEOF(.TFM_SP_CRYPTO_STACK);
 
+    .TFM_SP_PLATFORM_DATA : ALIGN(32)
+    {
+        *tfm_platform*:*(.data*)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_DATA$$RW$$Base = ADDR(.TFM_SP_PLATFORM_DATA);
+    Image$$TFM_SP_PLATFORM_DATA$$RW$$Limit = ADDR(.TFM_SP_PLATFORM_DATA) + SIZEOF(.TFM_SP_PLATFORM_DATA);
+
+    .TFM_SP_PLATFORM_BSS : ALIGN(32)
+    {
+        *tfm_platform*:*(.bss*)
+        *tfm_platform*:*(COMMON)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_DATA$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_BSS);
+    Image$$TFM_SP_PLATFORM_DATA$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_BSS) + SIZEOF(.TFM_SP_PLATFORM_BSS);
+
+    .TFM_SP_PLATFORM_STACK : ALIGN(128)
+    {
+        . += 0x0400;
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_STACK$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_STACK);
+    Image$$TFM_SP_PLATFORM_STACK$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_STACK) + SIZEOF(.TFM_SP_PLATFORM_STACK);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST_DATA : ALIGN(32)
     {
diff --git a/platform/ext/target/musca_a/target_cfg.c b/platform/ext/target/musca_a/target_cfg.c
index ed2a5a3..0e02ac2 100755
--- a/platform/ext/target/musca_a/target_cfg.c
+++ b/platform/ext/target/musca_a/target_cfg.c
@@ -63,6 +63,14 @@
 #define PERIPHERALS_BASE_NS_START (0x40000000)
 #define PERIPHERALS_BASE_NS_END   (0x4FFFFFFF)
 
+/* Enable system reset request for CPU 0 */
+#define ENABLE_CPU0_SYSTEM_RESET_REQUEST (1U << 4U)
+
+/* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
+ * otherwise the processor ignores the write.
+ */
+#define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
+
 struct tfm_spm_partition_platform_data_t tfm_peripheral_std_uart = {
         MUSCA_UART1_NS_BASE,
         MUSCA_UART1_NS_BASE + 0xFFF,
@@ -79,6 +87,22 @@
                   | SCB_SHCSR_SECUREFAULTENA_Msk;
 }
 
+void system_reset_cfg(void)
+{
+    struct sysctrl_t *sysctrl = (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
+    uint32_t reg_value = SCB->AIRCR;
+
+    /* Enable system reset request for CPU 0, to be triggered via
+     * NVIC_SystemReset function.
+     */
+    sysctrl->resetmask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST;
+
+    /* Enable system reset request only to the secure world */
+    reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
+
+    SCB->AIRCR = reg_value;
+}
+
 /*----------------- NVIC interrupt target state to NS configuration ----------*/
 void nvic_interrupt_target_state_cfg()
 {
@@ -239,6 +263,7 @@
     spctrl->apbnsppc0 |= (1U << CMSDK_DTIMER_APB_PPC_POS);
     spctrl->apbnsppc0 |= (1U << CMSDK_MHU0_APB_PPC_POS);
     spctrl->apbnsppc0 |= (1U << CMSDK_MHU1_APB_PPC_POS);
+
     /* Grant non-secure access to S32K Timer in PPC1*/
     spctrl->apbnsppc1 |= (1U << CMSDK_S32K_TIMER_PPC_POS);
 
diff --git a/platform/ext/target/musca_a/tfm_platform_system.c b/platform/ext/target/musca_a/tfm_platform_system.c
new file mode 100644
index 0000000..1e8a9ab
--- /dev/null
+++ b/platform/ext/target/musca_a/tfm_platform_system.c
@@ -0,0 +1,16 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "platform/include/tfm_platform_system.h"
+#include "cmsis.h"
+
+void tfm_platform_hal_system_reset(void)
+{
+    /* Reset the system */
+    NVIC_SystemReset();
+}
+
diff --git a/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct b/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct
index c5a2082..5af3a77 100644
--- a/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct
+++ b/platform/ext/target/musca_b1/Device/Source/armclang/musca_s.sct
@@ -65,6 +65,11 @@
         *(TFM_SP_CRYPTO_ATTR_FN)
     }
 
+    TFM_SP_PLATFORM +0 ALIGN 32 {
+        *tfm_platform* (+RO)
+        *(TFM_SP_PLATFORM_ATTR_FN)
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST +0 ALIGN 32 {
         *tfm_ss_core_test.* (+RO)
@@ -131,6 +136,13 @@
     TFM_SP_CRYPTO_STACK +0 ALIGN 128 EMPTY 0x2000 {
     }
 
+    TFM_SP_PLATFORM_DATA +0 ALIGN 32 {
+        *tfm_platform* (+RW +ZI)
+    }
+
+    TFM_SP_PLATFORM_STACK +0 ALIGN 128 EMPTY 0x0400 {
+    }
+
 #ifdef TFM_PARTITION_TEST_CORE
     TFM_SP_CORE_TEST_DATA +0 ALIGN 32 {
         tfm_ss_core_test.o (+RW +ZI)
diff --git a/platform/ext/target/musca_b1/Device/Source/gcc/musca_s.ld b/platform/ext/target/musca_b1/Device/Source/gcc/musca_s.ld
index fa4f950..2545230 100644
--- a/platform/ext/target/musca_b1/Device/Source/gcc/musca_s.ld
+++ b/platform/ext/target/musca_b1/Device/Source/gcc/musca_s.ld
@@ -100,6 +100,9 @@
         LONG (LOADADDR(.TFM_SP_CRYPTO_DATA))
         LONG (ADDR(.TFM_SP_CRYPTO_DATA))
         LONG (SIZEOF(.TFM_SP_CRYPTO_DATA))
+        LONG (LOADADDR(.TFM_SP_PLATFORM_DATA))
+        LONG (ADDR(.TFM_SP_PLATFORM_DATA))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_DATA))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (LOADADDR(.TFM_SP_CORE_TEST_DATA))
         LONG (ADDR(.TFM_SP_CORE_TEST_DATA))
@@ -142,6 +145,10 @@
         LONG (SIZEOF(.TFM_SP_CRYPTO_BSS))
         LONG (ADDR(.TFM_SP_CRYPTO_STACK))
         LONG (SIZEOF(.TFM_SP_CRYPTO_STACK))
+        LONG (ADDR(.TFM_SP_PLATFORM_BSS))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_BSS))
+        LONG (ADDR(.TFM_SP_PLATFORM_STACK))
+        LONG (SIZEOF(.TFM_SP_PLATFORM_STACK))
 #ifdef TFM_PARTITION_TEST_CORE
         LONG (ADDR(.TFM_SP_CORE_TEST_BSS))
         LONG (SIZEOF(.TFM_SP_CORE_TEST_BSS))
@@ -225,6 +232,18 @@
     Image$$TFM_SP_CRYPTO$$Base = ADDR(.TFM_SP_CRYPTO);
     Image$$TFM_SP_CRYPTO$$Limit = ADDR(.TFM_SP_CRYPTO) + SIZEOF(.TFM_SP_CRYPTO);
 
+    .TFM_SP_PLATFORM : ALIGN(32)
+    {
+        *tfm_platform*:*(.text*)
+        *tfm_platform*:*(.rodata*)
+        *(TFM_SP_PLATFORM_ATTR_FN)
+        . = ALIGN(32);
+    } > FLASH
+    Image$$TFM_SP_PLATFORM$$RO$$Base = ADDR(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$RO$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$Base = ADDR(.TFM_SP_PLATFORM);
+    Image$$TFM_SP_PLATFORM$$Limit = ADDR(.TFM_SP_PLATFORM) + SIZEOF(.TFM_SP_PLATFORM);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST : ALIGN(32)
     {
@@ -459,6 +478,30 @@
     Image$$TFM_SP_CRYPTO_STACK$$ZI$$Base = ADDR(.TFM_SP_CRYPTO_STACK);
     Image$$TFM_SP_CRYPTO_STACK$$ZI$$Limit = ADDR(.TFM_SP_CRYPTO_STACK) + SIZEOF(.TFM_SP_CRYPTO_STACK);
 
+    .TFM_SP_PLATFORM_DATA : ALIGN(32)
+    {
+        *tfm_platform*:*(.data*)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_DATA$$RW$$Base = ADDR(.TFM_SP_PLATFORM_DATA);
+    Image$$TFM_SP_PLATFORM_DATA$$RW$$Limit = ADDR(.TFM_SP_PLATFORM_DATA) + SIZEOF(.TFM_SP_PLATFORM_DATA);
+
+    .TFM_SP_PLATFORM_BSS : ALIGN(32)
+    {
+        *tfm_platform*:*(.bss*)
+        *tfm_platform*:*(COMMON)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_DATA$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_BSS);
+    Image$$TFM_SP_PLATFORM_DATA$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_BSS) + SIZEOF(.TFM_SP_PLATFORM_BSS);
+
+    .TFM_SP_PLATFORM_STACK : ALIGN(128)
+    {
+        . += 0x0400;
+    } > RAM AT> FLASH
+    Image$$TFM_SP_PLATFORM_STACK$$ZI$$Base = ADDR(.TFM_SP_PLATFORM_STACK);
+    Image$$TFM_SP_PLATFORM_STACK$$ZI$$Limit = ADDR(.TFM_SP_PLATFORM_STACK) + SIZEOF(.TFM_SP_PLATFORM_STACK);
+
 #ifdef TFM_PARTITION_TEST_CORE
     .TFM_SP_CORE_TEST_DATA : ALIGN(32)
     {
diff --git a/platform/ext/target/musca_b1/target_cfg.c b/platform/ext/target/musca_b1/target_cfg.c
index f2a60e2..58584c9 100644
--- a/platform/ext/target/musca_b1/target_cfg.c
+++ b/platform/ext/target/musca_b1/target_cfg.c
@@ -74,6 +74,14 @@
 #define PERIPHERALS_BASE_NS_START (0x40000000)
 #define PERIPHERALS_BASE_NS_END   (0x4FFFFFFF)
 
+/* Enable system reset request for CPU 0 */
+#define ENABLE_CPU0_SYSTEM_RESET_REQUEST (1U << 4U)
+
+/* To write into AIRCR register, 0x5FA value must be write to the VECTKEY field,
+ * otherwise the processor ignores the write.
+ */
+#define SCB_AIRCR_WRITE_MASK ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos))
+
 struct tfm_spm_partition_platform_data_t tfm_peripheral_std_uart = {
         MUSCA_B1_UART1_NS_BASE,
         MUSCA_B1_UART1_NS_BASE + 0xFFF,
@@ -90,6 +98,22 @@
                   | SCB_SHCSR_SECUREFAULTENA_Msk;
 }
 
+void system_reset_cfg(void)
+{
+    struct sysctrl_t *sysctrl = (struct sysctrl_t *)CMSDK_SYSCTRL_BASE_S;
+    uint32_t reg_value = SCB->AIRCR;
+
+    /* Enable system reset request for CPU 0, to be triggered via
+     * NVIC_SystemReset function.
+     */
+    sysctrl->resetmask |= ENABLE_CPU0_SYSTEM_RESET_REQUEST;
+
+    /* Enable system reset request only to the secure world */
+    reg_value |= (uint32_t)(SCB_AIRCR_WRITE_MASK | SCB_AIRCR_SYSRESETREQS_Msk);
+
+    SCB->AIRCR = reg_value;
+}
+
 /*----------------- NVIC interrupt target state to NS configuration ----------*/
 void nvic_interrupt_target_state_cfg()
 {
diff --git a/platform/ext/target/musca_b1/tfm_platform_system.c b/platform/ext/target/musca_b1/tfm_platform_system.c
new file mode 100644
index 0000000..2f9d4b4
--- /dev/null
+++ b/platform/ext/target/musca_b1/tfm_platform_system.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "platform/include/tfm_platform_system.h"
+#include "cmsis.h"
+
+void tfm_platform_hal_system_reset(void)
+{
+    /* FIXME: This functionality will be implemented later for Musca B1. */
+}
+
diff --git a/platform/include/tfm_plat_crypto_keys.h b/platform/include/tfm_plat_crypto_keys.h
index dc2b076..9682cc9 100644
--- a/platform/include/tfm_plat_crypto_keys.h
+++ b/platform/include/tfm_plat_crypto_keys.h
@@ -25,7 +25,7 @@
  * \param[out] key   Buf to store the key in
  * \param[in]  size  Size of the buffer
  *
- * \return Returns error code specified in \ref tfm_plat_errno_t
+ * \return Returns error code specified in \ref tfm_plat_err_t
  */
 enum tfm_plat_err_t tfm_plat_get_crypto_huk(uint8_t *key, uint32_t size);
 
diff --git a/platform/include/tfm_plat_defs.h b/platform/include/tfm_plat_defs.h
index 5b6d169..66747ee 100644
--- a/platform/include/tfm_plat_defs.h
+++ b/platform/include/tfm_plat_defs.h
@@ -23,4 +23,16 @@
     TFM_PLAT_ERR_FORCE_INT_SIZE = INT_MAX
 };
 
+/*!
+ * \def TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION(TFM_PARTITION_NAME)
+ *
+ * \brief This macro provides a mechanism to place a function code in a specific
+ *        secure partition at linker time in TF-M Level 3.
+ *
+ * \param[in] TFM_PARTITION_NAME  TF-M partition name assigned in the manifest
+ *                                file "tfm_partition_name" field.
+ */
+#define TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION(TFM_PARTITION_NAME) \
+                __attribute__((section(TFM_PARTITION_NAME"_ATTR_FN")))
+
 #endif /* __TFM_PLAT_DEFS_H__ */
diff --git a/platform/include/tfm_platform_system.h b/platform/include/tfm_platform_system.h
new file mode 100644
index 0000000..d0e5683
--- /dev/null
+++ b/platform/include/tfm_platform_system.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_PLATFORM_SYSTEM_H__
+#define __TFM_PLATFORM_SYSTEM_H__
+/**
+ * \note The interfaces defined in this file must be implemented for each
+ *       target.
+ */
+
+#include "tfm_plat_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Resets the system.
+ *
+ * \details Requests a system reset to reset the MCU.
+ */
+TFM_LINK_SET_OBJECT_IN_PARTITION_SECTION("TFM_SP_PLATFORM")
+void tfm_platform_hal_system_reset(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_PLATFORM_SYSTEM_H__ */
diff --git a/platform/include/tfm_spm_hal.h b/platform/include/tfm_spm_hal.h
index 7c6a1d1..d3505b8 100644
--- a/platform/include/tfm_spm_hal.h
+++ b/platform/include/tfm_spm_hal.h
@@ -94,6 +94,11 @@
 void enable_fault_handlers(void);

 

 /**

+ * \brief Configures the system reset request properties
+ */
+void system_reset_cfg(void);
+
+/**
  * \brief Configures all external interrupts to target the

  *        NS state, apart for the ones associated to secure

  *        peripherals (plus MPC and PPC)

diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index 03bdc3e..785bc74 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -124,6 +124,7 @@
 	add_dependencies(${EXE_NAME} tfm_crypto)
 	add_dependencies(${EXE_NAME} tfm_storage)
 	add_dependencies(${EXE_NAME} tfm_audit)
+	add_dependencies(${EXE_NAME} tfm_platform)
 	add_dependencies(${EXE_NAME} tfm_secure_tests)
 
 	#Set macro definitions for the project.
@@ -133,14 +134,14 @@
 		#The test service veneers may not be referenced in the secure binary so the
 		#veneer objects are explicitly loaded from the secure tests library.
 		if(${COMPILER} STREQUAL "ARMCLANG")
-			target_link_libraries(${EXE_NAME} tfm_crypto tfm_storage tfm_audit $<TARGET_LINKER_FILE:tfm_secure_tests>\(*veneers.o\) tfm_secure_tests)
+			target_link_libraries(${EXE_NAME} tfm_crypto tfm_storage tfm_audit tfm_platform $<TARGET_LINKER_FILE:tfm_secure_tests>\(*veneers.o\) tfm_secure_tests)
 		elseif(${COMPILER} STREQUAL "GNUARM")
-			target_link_libraries(${EXE_NAME} tfm_secure_tests tfm_crypto tfm_storage tfm_audit)
+			target_link_libraries(${EXE_NAME} tfm_secure_tests tfm_crypto tfm_storage tfm_audit tfm_platform)
 		else()
 			message(FATAL_ERROR "unknown compiler" )
 		endif()
 	else()
-		target_link_libraries(${EXE_NAME} tfm_crypto tfm_storage tfm_audit)
+		target_link_libraries(${EXE_NAME} tfm_crypto tfm_storage tfm_audit tfm_platform)
 	endif()
 
 
@@ -247,6 +248,9 @@
 #Add the audit logging library target
 add_subdirectory(${SECURE_FW_DIR}/services/audit_logging)
 
+#Add the platform service library target
+add_subdirectory(${SECURE_FW_DIR}/services/platform)
+
 if (LINK_TO_BOTH_MEMORY_REGION)
 	#Link to primary memory region
 	set_up_secure_fw_build(S_TARGET      ${PROJECT_NAME}
diff --git a/secure_fw/core/tfm_core.c b/secure_fw/core/tfm_core.c
index 9d0cc40..4066f3a 100644
--- a/secure_fw/core/tfm_core.c
+++ b/secure_fw/core/tfm_core.c
@@ -119,6 +119,9 @@
     /* Enables fault handlers */
     enable_fault_handlers();
 
+    /* Configures the system reset request properties */
+    system_reset_cfg();
+
     /* Configure the debug configuration registers */
     configure_debug_registers();
 
@@ -132,6 +135,7 @@
 #endif
 
     tfm_spm_hal_init_isolation_hw();
+
     configure_ns_code();
 
     /* Configures all interrupts to retarget NS state, except for
diff --git a/secure_fw/ns_callable/CMakeLists.inc b/secure_fw/ns_callable/CMakeLists.inc
index 1a4a521..afba7d5 100644
--- a/secure_fw/ns_callable/CMakeLists.inc
+++ b/secure_fw/ns_callable/CMakeLists.inc
@@ -25,7 +25,8 @@
 
 set (SS_NS_CALLABLE_C_SRC "${CMAKE_CURRENT_LIST_DIR}/tfm_sst_veneers.c"
                           "${CMAKE_CURRENT_LIST_DIR}/tfm_audit_veneers.c"
-                          "${CMAKE_CURRENT_LIST_DIR}/tfm_crypto_veneers.c")
+                          "${CMAKE_CURRENT_LIST_DIR}/tfm_crypto_veneers.c"
+                          "${CMAKE_CURRENT_LIST_DIR}/tfm_platform_veneers.c")
 
 #Append all our source files to global lists.
 list(APPEND ALL_SRC_C ${SS_NS_CALLABLE_C_SRC})
diff --git a/secure_fw/ns_callable/tfm_platform_veneers.c b/secure_fw/ns_callable/tfm_platform_veneers.c
new file mode 100644
index 0000000..c2515fe
--- /dev/null
+++ b/secure_fw/ns_callable/tfm_platform_veneers.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_platform_veneers.h"
+#include "secure_fw/services/platform/platform_sp.h"
+#include "tfm_secure_api.h"
+#include "tfm_api.h"
+#include "spm_partition_defs.h"
+
+__tfm_secure_gateway_attributes__
+enum tfm_platform_err_t tfm_platform_veneer_system_reset(void)
+{
+    TFM_CORE_SFN_REQUEST(TFM_SP_PLATFORM_ID,
+                         platform_sp_system_reset,
+                         0, 0, 0, 0);
+}
diff --git a/secure_fw/services/platform/CMakeLists.inc b/secure_fw/services/platform/CMakeLists.inc
new file mode 100644
index 0000000..e79aa5e
--- /dev/null
+++ b/secure_fw/services/platform/CMakeLists.inc
@@ -0,0 +1,51 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+#Definitions to compile the "Platform" module.
+#This file assumes it will be included from a project specific cmakefile, and
+#will not create a library or executable.
+#Inputs:
+#	MBEDTLS_INSTALL_DIR - directory where mbedtls headers and libraries can be found.
+#	TFM_ROOT_DIR	    - root directory of the TF-M repository.
+#Outputs:
+#	Will modify include directories to make the source compile.
+#	ALL_SRC_C: C source files to be compiled will be added to this list. This shall be added to your add_executable or add_library command.
+#	ALL_SRC_CXX: C++ source files to be compiled will be added to this list. This shall be added to your add_executable or add_library command.
+#	ALL_SRC_ASM: assembly source files to be compiled will be added to this list. This shall be added to your add_executable or add_library command.
+#	Include directories will be modified by using the include_directories() commands as needed.
+
+#Get the current directory where this file is located.
+set(PLATFORM_SERVICE_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+#Check input variables
+if (NOT DEFINED ENABLE_PLATFORM_SERVICE)
+	message(FATAL_ERROR "Incomplete build configuration: ENABLE_PLATFORM_SERVICE is undefined. ")
+endif()
+
+if (ENABLE_PLATFORM_SERVICE)
+	if (NOT DEFINED TFM_ROOT_DIR)
+		message(FATAL_ERROR "Please set TFM_ROOT_DIR before including this file.")
+	endif()
+
+	set (PLATFORM_SERVICE_C_SRC
+		"${PLATFORM_SERVICE_DIR}/platform_sp.c"
+		"${PLATFORM_SERVICE_DIR}/tfm_platform_secure_api.c")
+
+	#Append all our source files to global lists.
+	list(APPEND ALL_SRC_C ${PLATFORM_SERVICE_C_SRC})
+	unset(PLATFORM_SERVICE_C_SRC)
+
+	#Setting include directories
+	embedded_include_directories(PATH ${TFM_ROOT_DIR} ABSOLUTE)
+	embedded_include_directories(PATH ${TFM_ROOT_DIR}/interface/include ABSOLUTE)
+	embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/spm ABSOLUTE)
+	embedded_include_directories(PATH ${TFM_ROOT_DIR}/secure_fw/core ABSOLUTE)
+	embedded_include_directories(PATH ${TFM_ROOT_DIR}/platform/ext/common ABSOLUTE)
+
+else()
+	message(FATAL_ERROR "Build system currently doesn't support selectively disabling of a service.")
+endif()
diff --git a/secure_fw/services/platform/CMakeLists.txt b/secure_fw/services/platform/CMakeLists.txt
new file mode 100644
index 0000000..b2ae183
--- /dev/null
+++ b/secure_fw/services/platform/CMakeLists.txt
@@ -0,0 +1,41 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+cmake_minimum_required(VERSION 3.7)
+
+#Tell cmake where our modules can be found
+list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/../../../cmake)
+
+#Include common stuff to control cmake.
+include("Common/BuildSys")
+
+#Start an embedded project.
+embedded_project_start(CONFIG "${CMAKE_CURRENT_LIST_DIR}/../../../ConfigDefault.cmake")
+project(tfm_platform LANGUAGES ASM C)
+embedded_project_fixup()
+
+###Some project global settings
+set (PLATFORM_SP_DIR "${CMAKE_CURRENT_LIST_DIR}")
+get_filename_component(TFM_ROOT_DIR "${PLATFORM_SP_DIR}/../../.." ABSOLUTE)
+
+###Get the definition of what files we need to build
+set (ENABLE_PLATFORM_SERVICE ON)
+include(CMakeLists.inc)
+
+if (NOT DEFINED TFM_LVL)
+	message(FATAL_ERROR "Incomplete build configuration: TFM_LVL is undefined. ")
+endif()
+
+#Specify what we build (for the platform service, build as a static library)
+add_library(tfm_platform STATIC ${ALL_SRC_ASM} ${ALL_SRC_C})
+embedded_set_target_compile_defines(TARGET tfm_platform LANGUAGE C DEFINES __ARM_FEATURE_CMSE=3 __thumb2__ TFM_LVL=${TFM_LVL})
+
+#Set common compiler and linker flags
+config_setting_shared_compiler_flags(tfm_platform)
+config_setting_shared_linker_flags(tfm_platform)
+
+embedded_project_end(tfm_platform)
diff --git a/secure_fw/services/platform/manifest.yaml b/secure_fw/services/platform/manifest.yaml
new file mode 100644
index 0000000..8688ed6
--- /dev/null
+++ b/secure_fw/services/platform/manifest.yaml
@@ -0,0 +1,37 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2018, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+{
+  "name": "SP_PLATFORM",
+  "type": "TRUSTED",
+  "tfm_partition_name": "TFM_SP_PLATFORM",
+  "tfm_trusted": true,
+  "priority": "NORMAL",
+  "id": "0x00000102",
+  "entry_point": "main",
+  "stack_size": "0x0400",
+  "heap_size": "0x0400",
+  "tfm_init_symbol": "platform_sp_init",
+  "secure_functions": [
+    {
+      "sfid": "TFM_SP_PLATFORM_SYSTEM_RESET_SFID",
+      "signal": "TFM_SP_PLATFORM_SYSTEM_RESET",
+      "tfm_symbol": "platform_sp_system_reset",
+      "non_secure_clients": true,
+      "minor_version": 1,
+      "minor_policy": "strict"
+    }
+  ],
+  "source_files": [
+    "platform_sp.c",
+  ],
+  "tfm_linker_pattern": {
+    "library_list": [
+      "*tfm_platform*"
+    ]
+  }
+}
diff --git a/secure_fw/services/platform/platform_sp.c b/secure_fw/services/platform/platform_sp.c
new file mode 100644
index 0000000..e5c22b5
--- /dev/null
+++ b/secure_fw/services/platform/platform_sp.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "platform_sp.h"
+
+#include "platform/include/tfm_platform_system.h"
+#include "secure_fw/core/tfm_secure_api.h"
+#include "secure_fw/include/tfm_spm_services_api.h"
+
+enum tfm_platform_err_t platform_sp_init(void)
+{
+    /* Nothing to be done */
+
+    return TFM_PLATFORM_ERR_SUCCESS;
+}
+
+enum tfm_platform_err_t platform_sp_system_reset(void)
+{
+    /* Check if SPM allows the system reset */
+
+    if (tfm_spm_request_reset_vote() != 0) {
+        return TFM_PLATFORM_ERR_SYSTEM_ERROR;
+    }
+
+    /* FIXME: The system reset functionality is only supported in isolation
+     *        level 1.
+     *        Currently, the mechanism by which PRoT services should run in
+     *        privileged mode in level 3, it is not in place due to an ongoing
+     *        work in TF-M Core. So, the NVIC_SystemReset call performed by the
+     *        service, it is expected to generate a memory fault when it tries
+     *        to access the SCB->AIRCR register in level 3 isolation.
+     */
+
+    tfm_platform_hal_system_reset();
+
+    return TFM_PLATFORM_ERR_SUCCESS;
+}
diff --git a/secure_fw/services/platform/platform_sp.h b/secure_fw/services/platform/platform_sp.h
new file mode 100644
index 0000000..118eb08
--- /dev/null
+++ b/secure_fw/services/platform/platform_sp.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __PLATFORM_SP_H__
+#define __PLATFORM_SP_H__
+
+#include "tfm_platform_api.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*!
+ * \brief Initializes the secure partition.
+ *
+ * \return Returns values as specified by the \ref tfm_platform_err_t
+ */
+enum tfm_platform_err_t platform_sp_init(void);
+
+/*!
+ * \brief Resets the system.
+ *
+ * \return Returns values as specified by the \ref tfm_platform_err_t
+ */
+enum tfm_platform_err_t platform_sp_system_reset(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PLATFORM_SP_H__ */
diff --git a/secure_fw/services/platform/tfm_platform_secure_api.c b/secure_fw/services/platform/tfm_platform_secure_api.c
new file mode 100644
index 0000000..4fa31f0
--- /dev/null
+++ b/secure_fw/services/platform/tfm_platform_secure_api.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2018, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_platform_api.h"
+#include "tfm_platform_veneers.h"
+
+__attribute__((section("SFN")))
+enum tfm_platform_err_t tfm_platform_system_reset(void)
+{
+    return tfm_platform_veneer_system_reset();
+}
diff --git a/secure_fw/services/tfm_partition_defs.inc b/secure_fw/services/tfm_partition_defs.inc
index e06ba4e..1ef4cf0 100644
--- a/secure_fw/services/tfm_partition_defs.inc
+++ b/secure_fw/services/tfm_partition_defs.inc
@@ -16,22 +16,24 @@
 
 #define TFM_SP_CRYPTO_ID (TFM_SP_BASE + 2)
 
+#define TFM_SP_PLATFORM_ID (TFM_SP_BASE + 3)
+
 #ifdef TFM_PARTITION_TEST_CORE
-#define TFM_SP_CORE_TEST_ID (TFM_SP_BASE + 3)
+#define TFM_SP_CORE_TEST_ID (TFM_SP_BASE + 4)
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #ifdef TFM_PARTITION_TEST_CORE
-#define TFM_SP_CORE_TEST_2_ID (TFM_SP_BASE + 4)
+#define TFM_SP_CORE_TEST_2_ID (TFM_SP_BASE + 5)
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #ifdef TFM_PARTITION_TEST_SST
-#define TFM_SP_SST_TEST_PARTITION_ID (TFM_SP_BASE + 5)
+#define TFM_SP_SST_TEST_PARTITION_ID (TFM_SP_BASE + 6)
 #endif /* TFM_PARTITION_TEST_SST */
 
 #ifdef TFM_PARTITION_TEST_SECURE_SERVICES
-#define TFM_SP_SECURE_TEST_PARTITION_ID (TFM_SP_BASE + 6)
+#define TFM_SP_SECURE_TEST_PARTITION_ID (TFM_SP_BASE + 7)
 #endif /* TFM_PARTITION_TEST_SECURE_SERVICES */
 
-#define TFM_MAX_USER_PARTITIONS (7)
+#define TFM_MAX_USER_PARTITIONS (8)
 
 #endif /* __TFM_PARTITION_DEFS_INC__ */
diff --git a/secure_fw/services/tfm_partition_list.inc b/secure_fw/services/tfm_partition_list.inc
index f3fe5f4..8be6ef9 100644
--- a/secure_fw/services/tfm_partition_list.inc
+++ b/secure_fw/services/tfm_partition_list.inc
@@ -25,6 +25,10 @@
 PARTITION_DECLARE(TFM_SP_CRYPTO, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);
 PARTITION_ADD_INIT_FUNC(TFM_SP_CRYPTO, tfm_crypto_init);
 
+/******** TFM_SP_PLATFORM ********/
+PARTITION_DECLARE(TFM_SP_PLATFORM, SPM_PART_FLAG_SECURE | SPM_PART_FLAG_TRUSTED);
+PARTITION_ADD_INIT_FUNC(TFM_SP_PLATFORM, platform_sp_init);
+
 #ifdef TFM_PARTITION_TEST_CORE
 /******** TFM_SP_CORE_TEST ********/
 PARTITION_DECLARE(TFM_SP_CORE_TEST, SPM_PART_FLAG_SECURE);
diff --git a/secure_fw/services/tfm_sfid_list.inc b/secure_fw/services/tfm_sfid_list.inc
index d62e8ff..f2656df 100644
--- a/secure_fw/services/tfm_sfid_list.inc
+++ b/secure_fw/services/tfm_sfid_list.inc
@@ -46,6 +46,9 @@
     {tfm_crypto_hash_verify, TFM_CRYPTO_HASH_VERIFY_SFID},
     {tfm_crypto_hash_abort, TFM_CRYPTO_HASH_ABORT_SFID},
 
+    /******** TFM_SP_PLATFORM ********/
+    {platform_sp_system_reset, TFM_SP_PLATFORM_SYSTEM_RESET_SFID},
+
 #ifdef TFM_PARTITION_TEST_CORE
     /******** TFM_SP_CORE_TEST ********/
     {spm_core_test_sfn, TFM_CORE_TEST_SFN_SFID},
diff --git a/tools/tfm_manifest_list.yaml b/tools/tfm_manifest_list.yaml
index e4eb5fc..4363fc3 100644
--- a/tools/tfm_manifest_list.yaml
+++ b/tools/tfm_manifest_list.yaml
@@ -36,6 +36,14 @@
       "version_minor": 1

     },

     {

+      "name": "TFM Platform Service",
+      "short_name": "TFM_SP_Platform",
+      "manifest": "secure_fw/services/platform/manifest.yaml",
+      "tfm_extensions": true,
+      "version_major": 0,
+      "version_minor": 1
+    },
+    {
       "name": "TFM Core Test Service",

       "short_name": "TFM_Core_Test",

       "manifest": "test/test_services/tfm_core_test/manifest.yaml",