Test: Add SST test partition

Adds an SST test partition, which can be used to call the
sst_system_prepare() function from the SST test partition's
context.

Change-Id: Ib07a88e5f05fc181da2b9276279e57618fb059e4
Signed-off-by: Jamie Fox <jamie.fox@arm.com>
diff --git a/CommonConfig.cmake b/CommonConfig.cmake
index 0e83118..d159c4c 100644
--- a/CommonConfig.cmake
+++ b/CommonConfig.cmake
@@ -139,6 +139,7 @@
 set (CORE_TEST_INTERACTIVE OFF)
 set (REFERENCE_PLATFORM OFF)
 set (TFM_PARTITION_TEST_SECURE_SERVICES OFF)
+set (TFM_PARTITION_TEST_SST OFF)
 set (SERVICES_TEST_ENABLED OFF)
 set (TEST_FRAMEWORK_S  OFF)
 set (TEST_FRAMEWORK_NS OFF)
@@ -344,6 +345,13 @@
 	endif()
 endif()
 
+# The SST NV counter tests depend on the SST test partition to call
+# sst_system_prepare().
+if (SST_TEST_NV_COUNTERS)
+	set(TFM_PARTITION_TEST_SST ON)
+	add_definitions(-DTFM_PARTITION_TEST_SST)
+endif()
+
 #Default TF-M internal trusted storage flags.
 #These flags values can be overwritten by setting them in platform/ext/<TARGET_NAME>.cmake
 #Documentation about these flags can be found in the TF-M ITS integration guide
diff --git a/interface/include/psa_manifest/pid.h b/interface/include/psa_manifest/pid.h
index 42eeab3..0ff494e 100644
--- a/interface/include/psa_manifest/pid.h
+++ b/interface/include/psa_manifest/pid.h
@@ -26,8 +26,9 @@
 #define TFM_SP_IPC_SERVICE_TEST                                        (265)
 #define TFM_SP_IPC_CLIENT_TEST                                         (266)
 #define TFM_IRQ_TEST_1                                                 (267)
+#define TFM_SP_SST_TEST                                                (268)
 
-#define TFM_MAX_USER_PARTITIONS                                        (12)
+#define TFM_MAX_USER_PARTITIONS                                        (13)
 
 #ifdef __cplusplus
 }
diff --git a/interface/include/psa_manifest/sid.h b/interface/include/psa_manifest/sid.h
index b35bf2d..baa02c2 100644
--- a/interface/include/psa_manifest/sid.h
+++ b/interface/include/psa_manifest/sid.h
@@ -118,6 +118,10 @@
 #define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SID              (0x0000F0A1U)
 #define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_VERSION          (1U)
 
+/******** TFM_SP_SST_TEST ********/
+#define TFM_SST_TEST_PREPARE_SID                                   (0x0000F0C0U)
+#define TFM_SST_TEST_PREPARE_VERSION                               (1U)
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/interface/include/tfm_veneers.h b/interface/include/tfm_veneers.h
index 5b0e2bf..b0b4867 100644
--- a/interface/include/tfm_veneers.h
+++ b/interface/include/tfm_veneers.h
@@ -131,6 +131,11 @@
 psa_status_t tfm_spm_irq_test_1_execute_test_scenario_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+/******** TFM_SP_SST_TEST ********/
+psa_status_t tfm_tfm_sst_test_prepare_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+#endif /* TFM_PARTITION_TEST_SST */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/platform/ext/common/armclang/tfm_common_s.sct b/platform/ext/common/armclang/tfm_common_s.sct
index 832d83a..36dc5af 100644
--- a/platform/ext/common/armclang/tfm_common_s.sct
+++ b/platform/ext/common/armclang/tfm_common_s.sct
@@ -112,6 +112,13 @@
     }
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
+#ifdef TFM_PARTITION_TEST_SST
+    TFM_SP_SST_TEST_LINKER +0 ALIGN 32 {
+        *tfm_sst_test_service.* (+RO)
+        *(TFM_SP_SST_TEST_ATTR_FN)
+    }
+#endif /* TFM_PARTITION_TEST_SST */
+
     /*
      * This empty, zero long execution region is here to mark the end address
      * of PSA RoT code.
@@ -411,6 +418,19 @@
 #endif
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
+#ifdef TFM_PARTITION_TEST_SST
+    TFM_SP_SST_TEST_LINKER_DATA +0 ALIGN 32 {
+        *tfm_sst_test_service.* (+RW +ZI)
+        *(TFM_SP_SST_TEST_ATTR_RW)
+        *(TFM_SP_SST_TEST_ATTR_ZI)
+    }
+
+#if defined (TFM_PSA_API)
+    TFM_SP_SST_TEST_LINKER_STACK +0 ALIGN 128 EMPTY 0x400 {
+    }
+#endif
+#endif /* TFM_PARTITION_TEST_SST */
+
     /*
      * This empty, zero long execution region is here to mark the end address
      * of PSA RoT RW and Stack.
diff --git a/platform/ext/common/gcc/tfm_common_s.ld b/platform/ext/common/gcc/tfm_common_s.ld
index 81091a1..df4d29c 100644
--- a/platform/ext/common/gcc/tfm_common_s.ld
+++ b/platform/ext/common/gcc/tfm_common_s.ld
@@ -116,6 +116,11 @@
         LONG (ADDR(.TFM_IRQ_TEST_1_LINKER_DATA))
         LONG (SIZEOF(.TFM_IRQ_TEST_1_LINKER_DATA))
 #endif /* TFM_ENABLE_IRQ_TEST */
+#ifdef TFM_PARTITION_TEST_SST
+        LONG (LOADADDR(.TFM_SP_SST_TEST_LINKER_DATA))
+        LONG (ADDR(.TFM_SP_SST_TEST_LINKER_DATA))
+        LONG (SIZEOF(.TFM_SP_SST_TEST_LINKER_DATA))
+#endif /* TFM_PARTITION_TEST_SST */
 #if defined (S_RAM_CODE_START)
         LONG (LOADADDR(.TFM_RAM_CODE))
         LONG (ADDR(.TFM_RAM_CODE))
@@ -221,6 +226,14 @@
         LONG (SIZEOF(.TFM_IRQ_TEST_1_LINKER_STACK))
 #endif
 #endif /* TFM_ENABLE_IRQ_TEST */
+#ifdef TFM_PARTITION_TEST_SST
+        LONG (ADDR(.TFM_SP_SST_TEST_LINKER_BSS))
+        LONG (SIZEOF(.TFM_SP_SST_TEST_LINKER_BSS))
+#if defined(TFM_PSA_API)
+        LONG (ADDR(.TFM_SP_SST_TEST_LINKER_STACK))
+        LONG (SIZEOF(.TFM_SP_SST_TEST_LINKER_STACK))
+#endif
+#endif /* TFM_PARTITION_TEST_SST */
         __zero_table_end__ = .;
     } > FLASH
 
@@ -387,6 +400,20 @@
     Image$$TFM_SP_IPC_SERVICE_TEST_LINKER$$Limit = ADDR(.TFM_SP_IPC_SERVICE_TEST_LINKER) + SIZEOF(.TFM_SP_IPC_SERVICE_TEST_LINKER);
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
+#ifdef TFM_PARTITION_TEST_SST
+    .TFM_SP_SST_TEST_LINKER : ALIGN(32)
+    {
+        *tfm_sst_test_service.*(.text*)
+        *tfm_sst_test_service.*(.rodata*)
+        *(TFM_SP_SST_TEST_LD_ATTR_FN)
+        . = ALIGN(32);
+    } > FLASH
+    Image$$TFM_SP_SST_TEST_LINKER$$RO$$Base = ADDR(.TFM_SP_SST_TEST_LINKER);
+    Image$$TFM_SP_SST_TEST_LINKER$$RO$$Limit = ADDR(.TFM_SP_SST_TEST_LINKER) + SIZEOF(.TFM_SP_SST_TEST_LINKER);
+    Image$$TFM_SP_SST_TEST_LINKER$$Base = ADDR(.TFM_SP_SST_TEST_LINKER);
+    Image$$TFM_SP_SST_TEST_LINKER$$Limit = ADDR(.TFM_SP_SST_TEST_LINKER) + SIZEOF(.TFM_SP_SST_TEST_LINKER);
+#endif /* TFM_PARTITION_TEST_SST */
+
     /**** PSA RoT RO part (CODE + RODATA) end here */
     Image$$TFM_PSA_CODE_END$$Base = .;
 
@@ -1072,6 +1099,39 @@
 
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
+#ifdef TFM_PARTITION_TEST_SST
+    .TFM_SP_SST_TEST_LINKER_DATA : ALIGN(32)
+    {
+        *tfm_sst_test_service.*(.data*)
+        *(TFM_SP_SST_TEST_ATTR_RW)
+        . = ALIGN(32);
+    } > RAM AT> FLASH
+    Image$$TFM_SP_SST_TEST_LINKER_DATA$$RW$$Base = ADDR(.TFM_SP_SST_TEST_LINKER_DATA);
+    Image$$TFM_SP_SST_TEST_LINKER_DATA$$RW$$Limit = ADDR(.TFM_SP_SST_TEST_LINKER_DATA) + SIZEOF(.TFM_SP_SST_TEST_LINKER_DATA);
+
+    .TFM_SP_SST_TEST_LINKER_BSS : ALIGN(32)
+    {
+        start_of_TFM_SP_SST_TEST_LINKER = .;
+        *tfm_sst_test_service.*(.bss*)
+        *tfm_sst_test_service.*(COMMON)
+        *(TFM_SP_SST_TEST_ATTR_ZI)
+        . += (. - start_of_TFM_SP_SST_TEST_LINKER) ? 0 : 4;
+        . = ALIGN(32);
+    } > RAM AT> RAM
+    Image$$TFM_SP_SST_TEST_LINKER_DATA$$ZI$$Base = ADDR(.TFM_SP_SST_TEST_LINKER_BSS);
+    Image$$TFM_SP_SST_TEST_LINKER_DATA$$ZI$$Limit = ADDR(.TFM_SP_SST_TEST_LINKER_BSS) + SIZEOF(.TFM_SP_SST_TEST_LINKER_BSS);
+
+#if defined (TFM_PSA_API)
+    .TFM_SP_SST_TEST_LINKER_STACK : ALIGN(128)
+    {
+        . += 0x400;
+    } > RAM
+    Image$$TFM_SP_SST_TEST_LINKER_STACK$$ZI$$Base = ADDR(.TFM_SP_SST_TEST_LINKER_STACK);
+    Image$$TFM_SP_SST_TEST_LINKER_STACK$$ZI$$Limit = ADDR(.TFM_SP_SST_TEST_LINKER_STACK) + SIZEOF(.TFM_SP_SST_TEST_LINKER_STACK);
+#endif
+
+#endif /* TFM_PARTITION_TEST_SST */
+
     /**** PSA RoT DATA end here */
     Image$$TFM_PSA_RW_STACK_END$$Base = .;
 
diff --git a/secure_fw/CMakeLists.txt b/secure_fw/CMakeLists.txt
index 6a56a05..6cc8d6c 100644
--- a/secure_fw/CMakeLists.txt
+++ b/secure_fw/CMakeLists.txt
@@ -222,6 +222,12 @@
 		embedded_set_target_link_defines(TARGET ${EXE_NAME} DEFINES "TFM_PARTITION_TEST_SECURE_SERVICES")
 	endif()
 
+	if (NOT DEFINED TFM_PARTITION_TEST_SST)
+		message(FATAL_ERROR "Incomplete build configuration: TFM_PARTITION_TEST_SST is undefined.")
+	elseif (TFM_PARTITION_TEST_SST)
+		embedded_set_target_link_defines(TARGET ${EXE_NAME} DEFINES "TFM_PARTITION_TEST_SST")
+	endif()
+
 	if (NOT DEFINED TEST_FRAMEWORK_S)
 		message(FATAL_ERROR "Incomplete build configuration: TEST_FRAMEWORK_S is undefined.")
 	elseif (TEST_FRAMEWORK_S)
diff --git a/secure_fw/core/ipc/tfm_secure_irq_handlers_ipc.inc b/secure_fw/core/ipc/tfm_secure_irq_handlers_ipc.inc
index 2451b22..e600056 100644
--- a/secure_fw/core/ipc/tfm_secure_irq_handlers_ipc.inc
+++ b/secure_fw/core/ipc/tfm_secure_irq_handlers_ipc.inc
@@ -19,6 +19,7 @@
 #include "test/test_services/tfm_ipc_service/psa_manifest/tfm_ipc_service_partition.h"
 #include "test/test_services/tfm_ipc_client/psa_manifest/tfm_ipc_client_partition.h"
 #include "test/test_services/tfm_irq_test_service_1/psa_manifest/tfm_irq_test_service_1.h"
+#include "test/test_services/tfm_sst_test_service/psa_manifest/tfm_sst_test_service.h"
 #include "cmsis_compiler.h"
 
 /* Definitions of the signals of the IRQs (if any) */
diff --git a/secure_fw/core/tfm_secure_irq_handlers.inc b/secure_fw/core/tfm_secure_irq_handlers.inc
index 4c60c38..9b78b95 100644
--- a/secure_fw/core/tfm_secure_irq_handlers.inc
+++ b/secure_fw/core/tfm_secure_irq_handlers.inc
@@ -19,6 +19,7 @@
 #include "test/test_services/tfm_ipc_service/psa_manifest/tfm_ipc_service_partition.h"
 #include "test/test_services/tfm_ipc_client/psa_manifest/tfm_ipc_client_partition.h"
 #include "test/test_services/tfm_irq_test_service_1/psa_manifest/tfm_irq_test_service_1.h"
+#include "test/test_services/tfm_sst_test_service/psa_manifest/tfm_sst_test_service.h"
 #include "psa_manifest/pid.h"
 
 /* Definitions of the signals of the IRQs */
diff --git a/secure_fw/ns_callable/tfm_veneers.c b/secure_fw/ns_callable/tfm_veneers.c
index 8f527e2..bc7ee6f 100644
--- a/secure_fw/ns_callable/tfm_veneers.c
+++ b/secure_fw/ns_callable/tfm_veneers.c
@@ -125,6 +125,11 @@
 psa_status_t spm_irq_test_1_execute_test_scenario(psa_invec *, size_t, psa_outvec *, size_t);
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+/******** TFM_SP_SST_TEST ********/
+psa_status_t tfm_sst_test_prepare(psa_invec *, size_t, psa_outvec *, size_t);
+#endif /* TFM_PARTITION_TEST_SST */
+
 
 #define TFM_VENEER_FUNCTION(partition_name, sfn_name) \
     __tfm_secure_gateway_attributes__ \
@@ -253,3 +258,8 @@
 TFM_VENEER_FUNCTION(TFM_IRQ_TEST_1, spm_irq_test_1_execute_test_scenario)
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+/******** TFM_SP_SST_TEST ********/
+TFM_VENEER_FUNCTION(TFM_SP_SST_TEST, tfm_sst_test_prepare)
+#endif /* TFM_PARTITION_TEST_SST */
+
diff --git a/secure_fw/services/tfm_service_list.inc b/secure_fw/services/tfm_service_list.inc
index afbb59c..9767f85 100644
--- a/secure_fw/services/tfm_service_list.inc
+++ b/secure_fw/services/tfm_service_list.inc
@@ -22,6 +22,7 @@
 #include "test/test_services/tfm_ipc_service/psa_manifest/tfm_ipc_service_partition.h"
 #include "test/test_services/tfm_ipc_client/psa_manifest/tfm_ipc_client_partition.h"
 #include "test/test_services/tfm_irq_test_service_1/psa_manifest/tfm_irq_test_service_1.h"
+#include "test/test_services/tfm_sst_test_service/psa_manifest/tfm_sst_test_service.h"
 
 const struct tfm_spm_service_db_t service_db[] =
 {
@@ -435,6 +436,19 @@
     },
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+    /******** TFM_SP_SST_TEST ********/
+    {
+        .name = "TFM_SST_TEST_PREPARE",
+        .partition_id = TFM_SP_SST_TEST,
+        .signal = TFM_SST_TEST_PREPARE_SIGNAL,
+        .sid = 0x0000F0C0,
+        .non_secure_client = false,
+        .version = 1,
+        .version_policy = TFM_VERSION_POLICY_STRICT
+    },
+#endif /* TFM_PARTITION_TEST_SST */
+
 };
 
 /**************************************************************************/
@@ -768,6 +782,17 @@
     },
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+    /******** TFM_SP_SST_TEST ********/
+    {
+        .service_db = NULL,
+        .partition = NULL,
+        .handle_list = {0},
+        .msg_queue = {0},
+        .list = {0},
+    },
+#endif /* TFM_PARTITION_TEST_SST */
+
 };
 
 #endif /* __TFM_SERVICE_LIST_INC__ */
diff --git a/secure_fw/spm/tfm_spm_db.inc b/secure_fw/spm/tfm_spm_db.inc
index 2ac6176..6302cd3 100644
--- a/secure_fw/spm/tfm_spm_db.inc
+++ b/secure_fw/spm/tfm_spm_db.inc
@@ -55,6 +55,10 @@
 #define TFM_PARTITION_TFM_IRQ_TEST_1_IRQ_COUNT 1
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+#define TFM_PARTITION_TFM_SP_SST_TEST_IRQ_COUNT 0
+#endif /* TFM_PARTITION_TEST_SST */
+
 /**************************************************************************/
 /** Declarations of partition init functions */
 /**************************************************************************/
@@ -102,6 +106,10 @@
 extern void tfm_irq_test_1_init(void);
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+extern void tfm_sst_test_init(void);
+#endif /* TFM_PARTITION_TEST_SST */
+
 /**************************************************************************/
 /** Memory region declarations */
 /**************************************************************************/
@@ -257,6 +265,19 @@
 REGION_DECLARE(Image$$, TFM_IRQ_TEST_1_LINKER, _STACK$$ZI$$Limit);
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+REGION_DECLARE(Image$$, TFM_SP_SST_TEST_LINKER, $$Base);
+REGION_DECLARE(Image$$, TFM_SP_SST_TEST_LINKER, $$Limit);
+REGION_DECLARE(Image$$, TFM_SP_SST_TEST_LINKER, $$RO$$Base);
+REGION_DECLARE(Image$$, TFM_SP_SST_TEST_LINKER, $$RO$$Limit);
+REGION_DECLARE(Image$$, TFM_SP_SST_TEST_LINKER, _DATA$$RW$$Base);
+REGION_DECLARE(Image$$, TFM_SP_SST_TEST_LINKER, _DATA$$RW$$Limit);
+REGION_DECLARE(Image$$, TFM_SP_SST_TEST_LINKER, _DATA$$ZI$$Base);
+REGION_DECLARE(Image$$, TFM_SP_SST_TEST_LINKER, _DATA$$ZI$$Limit);
+REGION_DECLARE(Image$$, TFM_SP_SST_TEST_LINKER, _STACK$$ZI$$Base);
+REGION_DECLARE(Image$$, TFM_SP_SST_TEST_LINKER, _STACK$$ZI$$Limit);
+#endif /* TFM_PARTITION_TEST_SST */
+
 #endif /* defined(TFM_PSA_API) */
 
 #ifndef TFM_PSA_API
@@ -378,6 +399,15 @@
         )) / sizeof(uint32_t)];
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+static uint32_t ctx_stack_TFM_SP_SST_TEST[
+        (sizeof(struct interrupted_ctx_stack_frame_t) +
+            (TFM_PARTITION_TFM_SP_SST_TEST_IRQ_COUNT) * (
+                sizeof(struct interrupted_ctx_stack_frame_t) +
+                sizeof(struct handler_ctx_stack_frame_t)
+        )) / sizeof(uint32_t)];
+#endif /* TFM_PARTITION_TEST_SST */
+
 
 uint32_t *ctx_stack_list[] =
 {
@@ -411,6 +441,9 @@
 #ifdef TFM_ENABLE_IRQ_TEST
     ctx_stack_TFM_IRQ_TEST_1,
 #endif /* TFM_ENABLE_IRQ_TEST */
+#ifdef TFM_PARTITION_TEST_SST
+    ctx_stack_TFM_SP_SST_TEST,
+#endif /* TFM_PARTITION_TEST_SST */
 };
 #endif /* !defined(TFM_PSA_API) */
 
@@ -604,6 +637,20 @@
     },
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+    {
+#ifdef TFM_PSA_API
+        .psa_framework_version = 0x0100,
+#endif /* defined(TFM_PSA_API) */
+        .partition_id         = TFM_SP_SST_TEST,
+        .partition_flags      = SPM_PART_FLAG_IPC
+                              | SPM_PART_FLAG_PSA_ROT | SPM_PART_FLAG_APP_ROT
+                              ,
+        .partition_priority   = TFM_PRIORITY(NORMAL),
+        .partition_init       = tfm_sst_test_init,
+    },
+#endif /* TFM_PARTITION_TEST_SST */
+
 };
 
 /**************************************************************************/
@@ -665,6 +712,10 @@
     TFM_PERIPHERAL_TIMER0,
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+    NULL,
+#endif /* TFM_PARTITION_TEST_SST */
+
 };
 
 /**************************************************************************/
@@ -850,6 +901,21 @@
     },
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+#ifdef TFM_PARTITION_TEST_SST
+    {
+        .code_start           = PART_REGION_ADDR(TFM_SP_SST_TEST_LINKER, $$Base),
+        .code_limit           = PART_REGION_ADDR(TFM_SP_SST_TEST_LINKER, $$Limit),
+        .ro_start             = PART_REGION_ADDR(TFM_SP_SST_TEST_LINKER, $$RO$$Base),
+        .ro_limit             = PART_REGION_ADDR(TFM_SP_SST_TEST_LINKER, $$RO$$Limit),
+        .rw_start             = PART_REGION_ADDR(TFM_SP_SST_TEST_LINKER, _DATA$$RW$$Base),
+        .rw_limit             = PART_REGION_ADDR(TFM_SP_SST_TEST_LINKER, _DATA$$RW$$Limit),
+        .zi_start             = PART_REGION_ADDR(TFM_SP_SST_TEST_LINKER, _DATA$$ZI$$Base),
+        .zi_limit             = PART_REGION_ADDR(TFM_SP_SST_TEST_LINKER, _DATA$$ZI$$Limit),
+        .stack_bottom         = PART_REGION_ADDR(TFM_SP_SST_TEST_LINKER, _STACK$$ZI$$Base),
+        .stack_top            = PART_REGION_ADDR(TFM_SP_SST_TEST_LINKER, _STACK$$ZI$$Limit),
+    },
+#endif /* TFM_PARTITION_TEST_SST */
+
 };
 #endif /* defined(TFM_PSA_API) */
 
@@ -1011,6 +1077,19 @@
     },
 #endif /* TFM_ENABLE_IRQ_TEST */
 
+    /* -----------------------------------------------------------------------*/
+    /* - Partition DB record for TFM_SP_SST_TEST */
+    /* -----------------------------------------------------------------------*/
+#ifdef TFM_PARTITION_TEST_SST
+    {
+    /* Runtime data */
+        .runtime_data             = {},
+        .static_data              = NULL,
+        .platform_data            = NULL,
+
+    },
+#endif /* TFM_PARTITION_TEST_SST */
+
 };
 
 struct spm_partition_db_t g_spm_partition_db = {
diff --git a/test/suites/sst/secure/sst_rollback_protection_testsuite.c b/test/suites/sst/secure/sst_rollback_protection_testsuite.c
index 3194b91..de96fdb 100644
--- a/test/suites/sst/secure/sst_rollback_protection_testsuite.c
+++ b/test/suites/sst/secure/sst_rollback_protection_testsuite.c
@@ -15,11 +15,11 @@
 #include "tfm_memory_utils.h"
 #include "s_test_helpers.h"
 
-/* This include is required to expose the sst_system_prepare function to
- * simulate a reboot in the system by calling sst_system_prepare().
+/* This include is required to expose the sst_system_prepare function, via the
+ * tfm_sst_test_system_prepare API, to simulate a reboot in the system.
  * sst_system_prepare is called when the SST service is initialized.
  */
-#include "secure_fw/services/secure_storage/sst_object_system.h"
+#include "test/test_services/tfm_sst_test_service/tfm_sst_test_service_api.h"
 
 #include "test/framework/test_framework_helpers.h"
 
@@ -184,7 +184,7 @@
      * Prepare should not fail as the NV counters has the same values and
      * the SST area authentication is aligned with those values.
      */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_SUCCESS) {
         TEST_FAIL("AM prepare should not fail");
         return;
@@ -258,7 +258,7 @@
      * Prepare should fail as the SST area version does not match the
      * NV counters values.
      */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_ERROR_OPERATION_FAILED) {
         TEST_FAIL("SST system prepare should fail as version is old");
         return;
@@ -294,7 +294,7 @@
     }
 
     /* Calls sst_system_prepare to mark the SST area as a valid image */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_SUCCESS) {
         TEST_FAIL("SST system prepare should not fail");
         return;
@@ -348,7 +348,7 @@
      * Prepare should not fail as the SST area version match NV counters 1 and
      * 2 values.
      */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_SUCCESS) {
         TEST_FAIL("SST system prepare should not fail");
         return;
@@ -417,7 +417,7 @@
      * Prepare should not fail as the SST area version match the NV counter 2
      * and 3 values.
      */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_SUCCESS) {
         TEST_FAIL("SST system prepare should not fail");
         return;
@@ -491,7 +491,7 @@
      *
      * Prepare should not fail as the SST area version match the NV counter 1.
      */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_SUCCESS) {
         TEST_FAIL("SST system prepare should not fail");
         return;
@@ -568,7 +568,7 @@
      *
      * Prepare should not fail as the SST area version match the NV counter 1.
      */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_SUCCESS) {
         TEST_FAIL("SST system prepare should not fail");
         return;
@@ -638,7 +638,7 @@
      * Prepare should fail as the SST area version match the NV counter 2 and
      * the other counters are different.
      */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_ERROR_OPERATION_FAILED) {
         TEST_FAIL("SST system prepare should fail");
         return;
@@ -668,7 +668,7 @@
     }
 
     /* Calls sst_system_prepare to mark the SST area as a valid image */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_SUCCESS) {
         TEST_FAIL("SST system prepare should not fail");
         return;
@@ -730,7 +730,7 @@
      * Prepare should fail as the SST area version match the NV counter 2 and
      * the other counters are different.
      */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_ERROR_OPERATION_FAILED) {
         TEST_FAIL("AM prepare should fail");
         return;
@@ -766,7 +766,7 @@
     }
 
     /* Calls sst_system_prepare to mark the SST area as a valid image */
-    status = sst_system_prepare();
+    status = tfm_sst_test_system_prepare();
     if (status != PSA_PS_SUCCESS) {
         TEST_FAIL("SST system prepare should not fail");
         return;
diff --git a/test/test_services/CMakeLists.inc b/test/test_services/CMakeLists.inc
index 33d66e9..6523292 100644
--- a/test/test_services/CMakeLists.inc
+++ b/test/test_services/CMakeLists.inc
@@ -61,6 +61,13 @@
 		)
 endif()
 
+if (NOT DEFINED TFM_PARTITION_TEST_SST)
+	message(FATAL_ERROR "Incomplete build configuration: TFM_PARTITION_TEST_SST is undefined.")
+elseif (TFM_PARTITION_TEST_SST)
+	list(APPEND ALL_SRC_C_S "${CORE_TEST_DIR}/tfm_sst_test_service/tfm_sst_test_service.c"
+		"${CORE_TEST_DIR}/tfm_sst_test_service/tfm_sst_test_service_api.c")
+endif()
+
 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}/platform/include ABSOLUTE)
diff --git a/test/test_services/tfm_sst_test_service/psa_manifest/tfm_sst_test_service.h b/test/test_services/tfm_sst_test_service/psa_manifest/tfm_sst_test_service.h
new file mode 100644
index 0000000..d7f1a70
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/psa_manifest/tfm_sst_test_service.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*********** WARNING: This is an auto-generated file. Do not edit! ***********/
+
+#ifndef __PSA_MANIFEST_TFM_SST_TEST_SERVICE_H__
+#define __PSA_MANIFEST_TFM_SST_TEST_SERVICE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TFM_SST_TEST_PREPARE_SIGNAL                             (1U << (0 + 4))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __PSA_MANIFEST_TFM_SST_TEST_SERVICE_H__ */
diff --git a/test/test_services/tfm_sst_test_service/tfm_sst_test_service.c b/test/test_services/tfm_sst_test_service/tfm_sst_test_service.c
new file mode 100644
index 0000000..bd29085
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/tfm_sst_test_service.c
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifdef TFM_PSA_API
+#include "psa/service.h"
+#include "psa_manifest/tfm_sst_test_service.h"
+#else
+#include "psa/client.h"
+#endif
+
+#include "secure_fw/services/secure_storage/sst_object_system.h"
+
+psa_status_t tfm_sst_test_prepare(psa_invec *in_vec, size_t in_len,
+                                  psa_outvec *out_vec, size_t out_len)
+{
+    (void)in_vec;
+    (void)in_len;
+    (void)out_vec;
+    (void)out_len;
+
+    return sst_system_prepare();
+}
+
+psa_status_t tfm_sst_test_init(void)
+{
+#ifdef TFM_PSA_API
+    psa_msg_t msg;
+
+    while (1) {
+        (void)psa_wait(TFM_SST_TEST_PREPARE_SIGNAL, PSA_BLOCK);
+        (void)psa_get(TFM_SST_TEST_PREPARE_SIGNAL, &msg);
+        switch (msg.type) {
+        case PSA_IPC_CONNECT:
+        case PSA_IPC_DISCONNECT:
+            psa_reply(msg.handle, PSA_SUCCESS);
+            break;
+        case PSA_IPC_CALL:
+            psa_reply(msg.handle, sst_system_prepare());
+            break;
+        }
+    }
+#endif
+    return PSA_SUCCESS;
+}
diff --git a/test/test_services/tfm_sst_test_service/tfm_sst_test_service.yaml b/test/test_services/tfm_sst_test_service/tfm_sst_test_service.yaml
new file mode 100644
index 0000000..b69d0c6
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/tfm_sst_test_service.yaml
@@ -0,0 +1,39 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+{
+  "psa_framework_version": 1.0,
+  "name": "TFM_SP_SST_TEST",
+  "type": "PSA-ROT",
+  "priority": "NORMAL",
+  "entry_point": "tfm_sst_test_init",
+  "stack_size": "0x400",
+  "heap_size": "0",
+  "secure_functions": [
+    {
+      "name": "TFM_SST_TEST_PREPARE",
+      "signal": "TFM_SST_TEST_PREPARE",
+      "non_secure_clients": false,
+      "version": 1,
+      "version_policy": "STRICT"
+    },
+  ],
+  "services": [
+    {
+      "name": "TFM_SST_TEST_PREPARE",
+      "sid": "0x0000F0C0",
+      "non_secure_clients": false,
+      "version": 1,
+      "version_policy": "STRICT"
+    }
+  ],
+  "linker_pattern": {
+    "object_list": [
+      "*tfm_sst_test_service.*",
+    ]
+  }
+}
diff --git a/test/test_services/tfm_sst_test_service/tfm_sst_test_service_api.c b/test/test_services/tfm_sst_test_service/tfm_sst_test_service_api.c
new file mode 100644
index 0000000..a50b490
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/tfm_sst_test_service_api.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "tfm_sst_test_service_api.h"
+
+#ifdef TFM_PSA_API
+#include "psa/client.h"
+#include "psa_manifest/sid.h"
+#else
+#include "tfm_veneers.h"
+#endif
+
+__attribute__((section("SFN")))
+psa_status_t tfm_sst_test_system_prepare(void)
+{
+#ifdef TFM_PSA_API
+    psa_handle_t handle;
+    psa_status_t status;
+
+    handle = psa_connect(TFM_SST_TEST_PREPARE_SID,
+                         TFM_SST_TEST_PREPARE_VERSION);
+    if (!PSA_HANDLE_IS_VALID(handle)) {
+        return PSA_ERROR_GENERIC_ERROR;
+    }
+
+    status = psa_call(handle, PSA_IPC_CALL, NULL, 0, NULL, 0);
+    psa_close(handle);
+
+    return status;
+#else
+    return tfm_tfm_sst_test_prepare_veneer(NULL, 0, NULL, 0);
+#endif
+}
diff --git a/test/test_services/tfm_sst_test_service/tfm_sst_test_service_api.h b/test/test_services/tfm_sst_test_service/tfm_sst_test_service_api.h
new file mode 100644
index 0000000..5fb558a
--- /dev/null
+++ b/test/test_services/tfm_sst_test_service/tfm_sst_test_service_api.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_SST_TEST_SERVICE_API_H__
+#define __TFM_SST_TEST_SERVICE_API_H__
+
+#include "psa/error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * \brief Requests the SST Test Service to call sst_system_prepare().
+ *
+ * \return Returns error code as specified in \ref psa_status_t
+ */
+psa_status_t tfm_sst_test_system_prepare(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TFM_SST_TEST_SERVICE_API_H__ */
diff --git a/tools/tfm_manifest_list.yaml b/tools/tfm_manifest_list.yaml
index c9432c7..b982d20 100644
--- a/tools/tfm_manifest_list.yaml
+++ b/tools/tfm_manifest_list.yaml
@@ -138,6 +138,17 @@
       "version_major": 0,
       "version_minor": 1,
       "pid": 267
+    },
+    {
+      "name": "TF-M SST Test Service",
+      "short_name": "TFM_SP_SST_TEST",
+      "manifest": "test/test_services/tfm_sst_test_service/tfm_sst_test_service.yaml",
+      "tfm_extensions": true,
+      "tfm_partition_ipc": true,
+      "conditional": "TFM_PARTITION_TEST_SST",
+      "version_major": 0,
+      "version_minor": 1,
+      "pid": 268
     }
   ]
 }