FPU: Added interrupts for FPU test purposes

Using timer interrupt to test FPU registers protection is not
efficient and direct. This patch involves dedicated test interrupts
respectively for NS and S, which get triggered by software (STIR)
instead of a timer. This change is applied on AN521 and Musca-S1
platforms.

Signed-off-by: Jianliang Shen <jianliang.shen@arm.com>
Change-Id: I3ce92e837fe62f94ce6fd068efedc547c5f6f3c3
diff --git a/platform/CMakeLists.txt b/platform/CMakeLists.txt
index 89bd2a6..d003040 100755
--- a/platform/CMakeLists.txt
+++ b/platform/CMakeLists.txt
@@ -65,6 +65,7 @@
         $<$<OR:$<AND:$<BOOL:${PLATFORM_DEFAULT_NV_COUNTERS}>,$<BOOL:${TFM_PARTITION_PROTECTED_STORAGE}>>,$<BOOL:${PLATFORM_DEFAULT_OTP}>>:ext/common/template/flash_otp_nv_counters_backend.c>
         $<$<BOOL:${PLATFORM_DEFAULT_OTP}>:ext/common/template/otp_flash.c>
         $<$<BOOL:${PLATFORM_DEFAULT_PROVISIONING}>:ext/common/provisioning.c>
+        $<$<OR:$<BOOL:${TEST_S_FPU}>,$<BOOL:${TEST_NS_FPU}>>:${CMAKE_SOURCE_DIR}/platform/ext/common/test_interrupt.c>
 )
 
 # If this is not added to the tfm_s it will not correctly override the weak
diff --git a/platform/ext/common/test_interrupt.c b/platform/ext/common/test_interrupt.c
new file mode 100644
index 0000000..5a49f9c
--- /dev/null
+++ b/platform/ext/common/test_interrupt.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "test_interrupt.h"
+
+#if defined(TEST_NS_FPU) || defined(TEST_S_FPU)
+__attribute__((naked)) void TFM_FPU_S_TEST_Handler(void)
+{
+    __asm volatile(
+        "mov       r0, #0x000000E0         \n"
+        "vmov      s0, r0                  \n"
+        "mov       r0, #0x000000E1         \n"
+        "vmov      s1, r0                  \n"
+        "mov       r0, #0x000000E2         \n"
+        "vmov      s2, r0                  \n"
+        "mov       r0, #0x000000E3         \n"
+        "vmov      s3, r0                  \n"
+        "mov       r0, #0x000000E4         \n"
+        "vmov      s4, r0                  \n"
+        "mov       r0, #0x000000E5         \n"
+        "vmov      s5, r0                  \n"
+        "mov       r0, #0x000000E6         \n"
+        "vmov      s6, r0                  \n"
+        "mov       r0, #0x000000E7         \n"
+        "vmov      s7, r0                  \n"
+        "mov       r0, #0x000000E8         \n"
+        "vmov      s8, r0                  \n"
+        "mov       r0, #0x000000E9         \n"
+        "vmov      s9, r0                  \n"
+        "mov       r0, #0x000000EA         \n"
+        "vmov      s10, r0                 \n"
+        "mov       r0, #0x000000EB         \n"
+        "vmov      s11, r0                 \n"
+        "mov       r0, #0x000000EC         \n"
+        "vmov      s12, r0                 \n"
+        "mov       r0, #0x000000ED         \n"
+        "vmov      s13, r0                 \n"
+        "mov       r0, #0x000000EE         \n"
+        "vmov      s14, r0                 \n"
+        "mov       r0, #0x000000EF         \n"
+        "vmov      s15, r0                 \n"
+        "mov       r0, #0x000000F0         \n"
+        "vmov      s16, r0                 \n"
+        "mov       r0, #0x000000F1         \n"
+        "vmov      s17, r0                 \n"
+        "mov       r0, #0x000000F2         \n"
+        "vmov      s18, r0                 \n"
+        "mov       r0, #0x000000F3         \n"
+        "vmov      s19, r0                 \n"
+        "mov       r0, #0x000000F4         \n"
+        "vmov      s20, r0                 \n"
+        "mov       r0, #0x000000F5         \n"
+        "vmov      s21, r0                 \n"
+        "mov       r0, #0x000000F6         \n"
+        "vmov      s22, r0                 \n"
+        "mov       r0, #0x000000F7         \n"
+        "vmov      s23, r0                 \n"
+        "mov       r0, #0x000000F8         \n"
+        "vmov      s24, r0                 \n"
+        "mov       r0, #0x000000F9         \n"
+        "vmov      s25, r0                 \n"
+        "mov       r0, #0x000000FA         \n"
+        "vmov      s26, r0                 \n"
+        "mov       r0, #0x000000FB         \n"
+        "vmov      s27, r0                 \n"
+        "mov       r0, #0x000000FC         \n"
+        "vmov      s28, r0                 \n"
+        "mov       r0, #0x000000FD         \n"
+        "vmov      s29, r0                 \n"
+        "mov       r0, #0x000000FE         \n"
+        "vmov      s30, r0                 \n"
+        "mov       r0, #0x000000FF         \n"
+        "vmov      s31, r0                 \n"
+        "bx        lr                      \n"
+    );
+}
+#endif
+
+#ifdef TEST_NS_FPU
+__attribute__((used)) static uint32_t is_non_zero(uint32_t *p, uint32_t n)
+{
+
+    while(n && p[n - 1] == 0) {
+        n--;
+    }
+    return n;
+}
+
+__attribute__((naked)) void TFM_FPU_NS_TEST_Handler(void)
+{
+    __asm volatile(
+        /*
+        * If LR.BIT[6] equals 1, the interrupt is triggerred by secure thread.
+        */
+        "ands      r0, lr, #0x40           \n"
+        "cmp       r0, 0x40                \n"
+        "bne       change_regs             \n"
+        "push      {r7, lr}                \n"
+        "vpush     {s0-s15}                \n"
+        "vpush     {s16-s31}               \n"
+        "mov       r0, sp                  \n"
+        "mov       r1, #32                 \n"
+        "bl        is_non_zero             \n"
+        "vpop      {s16-s31}               \n"
+        "vpop      {s0-s15}                \n"
+        "pop       {r7, lr}                \n"
+        "cmp       r0, #0                  \n"
+        "bne       panic                   \n"
+    "change_regs:                          \n"
+        "mov       r0, #0x000000E0         \n"
+        "vmov      s0, r0                  \n"
+        "mov       r0, #0x000000E1         \n"
+        "vmov      s1, r0                  \n"
+        "mov       r0, #0x000000E2         \n"
+        "vmov      s2, r0                  \n"
+        "mov       r0, #0x000000E3         \n"
+        "vmov      s3, r0                  \n"
+        "mov       r0, #0x000000E4         \n"
+        "vmov      s4, r0                  \n"
+        "mov       r0, #0x000000E5         \n"
+        "vmov      s5, r0                  \n"
+        "mov       r0, #0x000000E6         \n"
+        "vmov      s6, r0                  \n"
+        "mov       r0, #0x000000E7         \n"
+        "vmov      s7, r0                  \n"
+        "mov       r0, #0x000000E8         \n"
+        "vmov      s8, r0                  \n"
+        "mov       r0, #0x000000E9         \n"
+        "vmov      s9, r0                  \n"
+        "mov       r0, #0x000000EA         \n"
+        "vmov      s10, r0                 \n"
+        "mov       r0, #0x000000EB         \n"
+        "vmov      s11, r0                 \n"
+        "mov       r0, #0x000000EC         \n"
+        "vmov      s12, r0                 \n"
+        "mov       r0, #0x000000ED         \n"
+        "vmov      s13, r0                 \n"
+        "mov       r0, #0x000000EE         \n"
+        "vmov      s14, r0                 \n"
+        "mov       r0, #0x000000EF         \n"
+        "vmov      s15, r0                 \n"
+        "mov       r0, #0x000000F0         \n"
+        "vmov      s16, r0                 \n"
+        "mov       r0, #0x000000F1         \n"
+        "vmov      s17, r0                 \n"
+        "mov       r0, #0x000000F2         \n"
+        "vmov      s18, r0                 \n"
+        "mov       r0, #0x000000F3         \n"
+        "vmov      s19, r0                 \n"
+        "mov       r0, #0x000000F4         \n"
+        "vmov      s20, r0                 \n"
+        "mov       r0, #0x000000F5         \n"
+        "vmov      s21, r0                 \n"
+        "mov       r0, #0x000000F6         \n"
+        "vmov      s22, r0                 \n"
+        "mov       r0, #0x000000F7         \n"
+        "vmov      s23, r0                 \n"
+        "mov       r0, #0x000000F8         \n"
+        "vmov      s24, r0                 \n"
+        "mov       r0, #0x000000F9         \n"
+        "vmov      s25, r0                 \n"
+        "mov       r0, #0x000000FA         \n"
+        "vmov      s26, r0                 \n"
+        "mov       r0, #0x000000FB         \n"
+        "vmov      s27, r0                 \n"
+        "mov       r0, #0x000000FC         \n"
+        "vmov      s28, r0                 \n"
+        "mov       r0, #0x000000FD         \n"
+        "vmov      s29, r0                 \n"
+        "mov       r0, #0x000000FE         \n"
+        "vmov      s30, r0                 \n"
+        "mov       r0, #0x000000FF         \n"
+        "vmov      s31, r0                 \n"
+        "bx        lr                      \n"
+    "panic:                                \n"
+        "b         .                       \n"
+    );
+}
+#endif
diff --git a/platform/ext/common/test_interrupt.h b/platform/ext/common/test_interrupt.h
new file mode 100644
index 0000000..5c4477c
--- /dev/null
+++ b/platform/ext/common/test_interrupt.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TEST_INTERRUPT_H__
+#define __TEST_INTERRUPT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#if defined(TEST_NS_FPU) || defined(TEST_S_FPU)
+/* Change FP caller and callee registers. */
+void TFM_FPU_S_TEST_Handler(void);
+#endif
+
+#ifdef TEST_NS_FPU
+/*
+ * Change FP caller and callee registers. For interrupt triggerred by secure
+ * thread, all FP registers should be checked whether cleared.
+ */
+void TFM_FPU_NS_TEST_Handler(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TEST_INTERRUPT_H__ */
diff --git a/platform/ext/target/arm/mps3/an552/CMakeLists.txt b/platform/ext/target/arm/mps3/an552/CMakeLists.txt
index fb7729c..f4a1a4d 100644
--- a/platform/ext/target/arm/mps3/an552/CMakeLists.txt
+++ b/platform/ext/target/arm/mps3/an552/CMakeLists.txt
@@ -106,7 +106,7 @@
         native_drivers/syscounter_armv8-m_cntrl_drv.c
         native_drivers/uart_cmsdk_drv.c
         spm_hal.c
-        $<$<AND:$<BOOL:${TFM_PSA_API}>,$<NOT:$<BOOL:${TEST_NS_FPU}>>>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_interrupts.c>
+        $<$<BOOL:${TFM_PSA_API}>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_interrupts.c>
         target_cfg.c
         tfm_peripherals_def.c
         tfm_hal_isolation.c
@@ -121,20 +121,6 @@
         # SLIH test Partition and FLIH test Partition access the timer as ARoT Partitions.
         # Put the driver to SPRT so that both SLIH and FLIH tests can access it.
         $<$<OR:$<BOOL:${TEST_NS_SLIH_IRQ}>,$<BOOL:${TEST_NS_FLIH_IRQ}>>:${CMAKE_CURRENT_SOURCE_DIR}/native_drivers/systimer_armv8-m_drv.c>
-
-        # FPU client test partition access the timer as ARoT Partitions.
-        # Put the driver to SPRT so that FPU tests can access it.
-        $<$<BOOL:${TEST_NS_FPU}>:${CMAKE_CURRENT_SOURCE_DIR}/native_drivers/systimer_armv8-m_drv.c>
-        $<$<BOOL:${TEST_NS_FPU}>:${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c>
-)
-
-# Adding new defined handler function to the library where the weak handler
-# funtion symbol are, to override weak handler funtion.
-# Otherwise the weak handler funtion cannot be replaced by the new defined
-# hanlder function which symbol is in another library.
-target_sources(tfm_s
-    PRIVATE
-        $<$<BOOL:${TEST_NS_FPU}>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_interrupts.c>
 )
 
 target_link_libraries(platform_s
@@ -151,6 +137,7 @@
 target_compile_definitions(platform_s
     PUBLIC
         $<$<BOOL:${TEST_NS_FPU}>:TEST_NS_FPU>
+        $<$<BOOL:${TEST_S_FPU}>:TEST_S_FPU>
 )
 
 #========================= Platform Non-Secure ================================#
@@ -163,6 +150,8 @@
         device/source/system_core_init.c
         native_drivers/uart_cmsdk_drv.c
         native_drivers/systimer_armv8-m_drv.c
+    INTERFACE
+        $<$<BOOL:${TEST_NS_FPU}>:${CMAKE_CURRENT_SOURCE_DIR}/device/source/an552_ns_init.c>
 )
 
 target_include_directories(platform_ns
@@ -178,15 +167,7 @@
         device/source/armclang
         native_drivers
         partition
-)
-
-# Adding new defined handler function to the library where the weak handler
-# funtion symbol are, to override weak handler funtion.
-# Otherwise the weak handler funtion cannot be replaced by the new defined
-# hanlder function which symbol is in another library.
-target_sources(tfm_ns
-    PRIVATE
-        $<$<BOOL:${TEST_NS_FPU}>:${CMAKE_CURRENT_SOURCE_DIR}/ns_fp_test_interrupt.c>
+        ${CMAKE_SOURCE_DIR}/platform/ext/cmsis
 )
 
 #========================= Platform BL2 =======================================#
diff --git a/platform/ext/target/arm/mps3/an552/device/source/an552_ns_init.c b/platform/ext/target/arm/mps3/an552/device/source/an552_ns_init.c
new file mode 100644
index 0000000..1e7587c
--- /dev/null
+++ b/platform/ext/target/arm/mps3/an552/device/source/an552_ns_init.c
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2022, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include "cmsis.h"
+#include "tfm_peripherals_def.h"
+#include "uart_stdout.h"
+#include "Driver_USART.h"
+#include "test_interrupt.h"
+
+int32_t tfm_ns_platform_init (void)
+{
+    /* Register FPU non-secure test interrupt handler */
+    NVIC_SetVector(TFM_FPU_NS_TEST_IRQ, (uint32_t)TFM_FPU_NS_TEST_Handler);
+
+    /* Enable FPU non-secure test interrupt */
+    NVIC_EnableIRQ(TFM_FPU_NS_TEST_IRQ);
+
+    stdio_init();
+
+    return ARM_DRIVER_OK;
+}
diff --git a/platform/ext/target/arm/mps3/an552/device/source/device_definition.c b/platform/ext/target/arm/mps3/an552/device/source/device_definition.c
index 3badf99..ae67c5a 100644
--- a/platform/ext/target/arm/mps3/an552/device/source/device_definition.c
+++ b/platform/ext/target/arm/mps3/an552/device/source/device_definition.c
@@ -450,25 +450,6 @@
 
 /* System timers */
 #ifdef SYSTIMER0_ARMV8_M_S
-#ifdef TEST_NS_FPU
-static const struct systimer_armv8_m_dev_cfg_t SYSTIMER0_ARMV8_M_DEV_CFG_S
-TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-= {
-    .base = SYSTIMER0_ARMV8_M_BASE_S,
-    .default_freq_hz = SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ
-};
-static struct systimer_armv8_m_dev_data_t SYSTIMER0_ARMV8_M_DEV_DATA_S
-TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-= {
-    .is_initialized = false
-};
-struct systimer_armv8_m_dev_t SYSTIMER0_ARMV8_M_DEV_S
-TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-= {
-    &(SYSTIMER0_ARMV8_M_DEV_CFG_S),
-    &(SYSTIMER0_ARMV8_M_DEV_DATA_S)
-};
-#else
 static const struct systimer_armv8_m_dev_cfg_t SYSTIMER0_ARMV8_M_DEV_CFG_S
 #ifdef TEST_NS_SLIH_IRQ
     TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_SLIH_TEST", "APP-ROT")
@@ -498,7 +479,6 @@
     &(SYSTIMER0_ARMV8_M_DEV_CFG_S),
     &(SYSTIMER0_ARMV8_M_DEV_DATA_S)
 };
-#endif /* TEST_NS_FPU */
 #endif
 
 #ifdef SYSTIMER0_ARMV8_M_NS
@@ -534,25 +514,6 @@
 #endif
 
 #ifdef SYSTIMER1_ARMV8_M_NS
-#ifdef TEST_NS_FPU
-static const struct systimer_armv8_m_dev_cfg_t SYSTIMER1_ARMV8_M_DEV_CFG_NS
-TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-= {
-    .base = SYSTIMER1_ARMV8_M_BASE_NS,
-    .default_freq_hz = SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ
-};
-static struct systimer_armv8_m_dev_data_t SYSTIMER1_ARMV8_M_DEV_DATA_NS
-TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-= {
-    .is_initialized = false
-};
-struct systimer_armv8_m_dev_t SYSTIMER1_ARMV8_M_DEV_NS
-TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-= {
-    &(SYSTIMER1_ARMV8_M_DEV_CFG_NS),
-    &(SYSTIMER1_ARMV8_M_DEV_DATA_NS)
-};
-#else
 static const struct systimer_armv8_m_dev_cfg_t
 SYSTIMER1_ARMV8_M_DEV_CFG_NS = {
     .base = SYSTIMER1_ARMV8_M_BASE_NS,
@@ -566,7 +527,6 @@
     &(SYSTIMER1_ARMV8_M_DEV_CFG_NS),
     &(SYSTIMER1_ARMV8_M_DEV_DATA_NS)
 };
-#endif /* TEST_NS_FPU */
 #endif
 
 #ifdef SYSTIMER2_ARMV8_M_S
diff --git a/platform/ext/target/arm/mps3/an552/ns_fp_test_interrupt.c b/platform/ext/target/arm/mps3/an552/ns_fp_test_interrupt.c
deleted file mode 100644
index 06d97c7..0000000
--- a/platform/ext/target/arm/mps3/an552/ns_fp_test_interrupt.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-
-#include <stdbool.h>
-#include "device_definition.h"
-#include "systimer_armv8-m_drv.h"
-
-#define NR_FP_REG                               (32U)
-#define REL_VALUE_FP_REGS_INVALIDATED           (0xDEADBEEF)
-#define REL_VALUE_FP_REGS_NOT_INVALIDATED       (0xBEEFDEAD)
-
-void non_secure_timer_set_reload_value(uint32_t value)
-{
-    systimer_armv8_m_set_autoinc_reload(&SYSTIMER1_ARMV8_M_DEV_NS, value);
-}
-
-void non_secure_timer_stop(void)
-{
-    systimer_armv8_m_uninit(&SYSTIMER1_ARMV8_M_DEV_NS);
-    systimer_armv8_m_clear_autoinc_interrupt(&SYSTIMER1_ARMV8_M_DEV_NS);
-    systimer_armv8_m_disable_timer(&SYSTIMER1_ARMV8_M_DEV_NS);
-}
-
-/*
- * Check whether FP registers are invalidated.
- * Return:
- *   True - FP registers are invalidated
- *   False - FP registers are not invalidated
- */
-#if defined (__GNUC__)
-__attribute__((noinline))
-#endif
-bool is_fp_regs_invalidated(void)
-{
-    static uint32_t fp_buffer[NR_FP_REG] = {0};
-    uint32_t i;
-
-    /* Dump FP data from FP registers to buffer */
-    __asm volatile(
-        "vstm      %0, {S0-S31}            \n"
-        :
-        :"r"(fp_buffer)
-        :"memory"
-    );
-
-    for(i = 0; i < NR_FP_REG; i++) {
-        if (fp_buffer[i] != 0){
-            return false;
-        }
-    }
-    return true;
-}
-
-void TIMER1_Handler()
-{
-    /* Check whether FP regs is invalidated */
-    if (is_fp_regs_invalidated()) {
-        non_secure_timer_set_reload_value(REL_VALUE_FP_REGS_INVALIDATED);
-    } else {
-        non_secure_timer_set_reload_value(REL_VALUE_FP_REGS_NOT_INVALIDATED);
-    }
-
-    non_secure_timer_stop();
-}
diff --git a/platform/ext/target/arm/mps3/an552/plat_test.c b/platform/ext/target/arm/mps3/an552/plat_test.c
index c22528a..ac12b89 100644
--- a/platform/ext/target/arm/mps3/an552/plat_test.c
+++ b/platform/ext/target/arm/mps3/an552/plat_test.c
@@ -9,22 +9,14 @@
 #include "systimer_armv8-m_drv.h"
 #include "tfm_plat_test.h"
 #include "device_definition.h"
-#include "tfm_peripherals_def.h"
 
-#ifdef TEST_NS_FPU
-/* Interrupt interval is set to 1 s */
-#define TIMER0_RELOAD_VALUE          (SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ)
-#define TIMER1_RELOAD_VALUE          (SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ)
-#else
 /* Interrupt interval is set to 1 ms */
-#define TIMER0_RELOAD_VALUE          (SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ / 1000)
-#define TIMER1_RELOAD_VALUE          (SYSTIMER1_ARMV8M_DEFAULT_FREQ_HZ / 1000)
-#endif
+#define TIMER_RELOAD_VALUE          (SYSTIMER0_ARMV8M_DEFAULT_FREQ_HZ / 1000)
 
 void tfm_plat_test_secure_timer_start(void)
 {
     systimer_armv8_m_init(&SYSTIMER0_ARMV8_M_DEV_S);
-    systimer_armv8_m_set_autoinc_reload(&SYSTIMER0_ARMV8_M_DEV_S, TIMER0_RELOAD_VALUE);
+    systimer_armv8_m_set_autoinc_reload(&SYSTIMER0_ARMV8_M_DEV_S, TIMER_RELOAD_VALUE);
     systimer_armv8_m_enable_autoinc(&SYSTIMER0_ARMV8_M_DEV_S);
     systimer_armv8_m_enable_interrupt(&SYSTIMER0_ARMV8_M_DEV_S);
 }
@@ -39,39 +31,3 @@
     systimer_armv8_m_uninit(&SYSTIMER0_ARMV8_M_DEV_S);
     systimer_armv8_m_clear_autoinc_interrupt(&SYSTIMER0_ARMV8_M_DEV_S);
 }
-
-void tfm_plat_test_secure_timer_set_reload_value(uint32_t value)
-{
-    systimer_armv8_m_set_autoinc_reload(&SYSTIMER0_ARMV8_M_DEV_S, value);
-}
-
-uint32_t tfm_plat_test_secure_timer_get_reload_value(void)
-{
-    return systimer_armv8_m_get_autoinc_reload(&SYSTIMER0_ARMV8_M_DEV_S);
-}
-
-void tfm_plat_test_secure_timer_nvic_configure(void)
-{
-    NVIC_SetPriority(TFM_TIMER0_IRQ, DEFAULT_IRQ_PRIORITY);
-    NVIC_ClearTargetState(TFM_TIMER0_IRQ);
-    NVIC_EnableIRQ(TFM_TIMER0_IRQ);
-}
-
-void tfm_plat_test_non_secure_timer_start(void)
-{
-    systimer_armv8_m_init(&SYSTIMER1_ARMV8_M_DEV_NS);
-    systimer_armv8_m_set_autoinc_reload(&SYSTIMER1_ARMV8_M_DEV_NS, TIMER1_RELOAD_VALUE);
-    systimer_armv8_m_enable_autoinc(&SYSTIMER1_ARMV8_M_DEV_NS);
-    systimer_armv8_m_enable_interrupt(&SYSTIMER1_ARMV8_M_DEV_NS);
-}
-
-uint32_t tfm_plat_test_non_secure_timer_get_reload_value(void)
-{
-    return systimer_armv8_m_get_autoinc_reload(&SYSTIMER1_ARMV8_M_DEV_NS);
-}
-
-void tfm_plat_test_non_secure_timer_nvic_configure(void)
-{
-    NVIC_SetPriority(TFM_TIMER1_IRQ, 1);
-    NVIC_EnableIRQ(TFM_TIMER1_IRQ);
-}
diff --git a/platform/ext/target/arm/mps3/an552/target_cfg.c b/platform/ext/target/arm/mps3/an552/target_cfg.c
index b599ace..c80ad5c 100644
--- a/platform/ext/target/arm/mps3/an552/target_cfg.c
+++ b/platform/ext/target/arm/mps3/an552/target_cfg.c
@@ -421,13 +421,6 @@
     err |= Driver_PPC_SSE300_PERIPH0.ConfigSecurity(
                                         WATCHDOG_PERIPH_PPC0_POS_MASK,
                                         PPC_SSE300_NONSECURE_CONFIG);
-#ifdef TEST_NS_FPU
-    /* Grant un-privileged access for TIMER1 in NS domain */
-    err |= Driver_PPC_SSE300_PERIPH0.ConfigPrivilege(
-                                        SYSTEM_TIMER1_PERIPH_PPC0_POS_MASK,
-                                        PPC_SSE300_NONSECURE_CONFIG,
-                                        PPC_SSE300_PRIV_AND_NONPRIV_CONFIG);
-#endif
 
     /* Grant non-secure access to peripherals on PERIPH1 */
     err |= Driver_PPC_SSE300_PERIPH1.Initialize();
diff --git a/platform/ext/target/arm/mps3/an552/tfm_hal_platform.c b/platform/ext/target/arm/mps3/an552/tfm_hal_platform.c
index 97aed64..0eec442 100644
--- a/platform/ext/target/arm/mps3/an552/tfm_hal_platform.c
+++ b/platform/ext/target/arm/mps3/an552/tfm_hal_platform.c
@@ -11,8 +11,8 @@
 #include "tfm_peripherals_def.h"
 #include "uart_stdout.h"
 #include "device_definition.h"
-#if (CONFIG_TFM_FP == 2) && (TEST_NS_FPU == 1)
-#include "tfm_plat_test.h"
+#if defined(TEST_NS_FPU) || defined(TEST_S_FPU)
+#include "test_interrupt.h"
 #endif
 
 /* Get address of memory regions to configure MPU */
@@ -59,12 +59,20 @@
         return TFM_HAL_ERROR_GENERIC;
     }
 
-#if (CONFIG_TFM_FP == 2) && (TEST_NS_FPU == 1)
-    /* Configure secure timer */
-    tfm_plat_test_secure_timer_nvic_configure();
+#if defined(TEST_S_FPU) || defined(TEST_NS_FPU)
+    /* Set IRQn in secure mode */
+    NVIC_ClearTargetState(TFM_FPU_S_TEST_IRQ);
 
-    /* Configure non-secure timer */
-    tfm_plat_test_non_secure_timer_nvic_configure();
+    /* Register FPU secure test interrupt handler */
+    NVIC_SetVector(TFM_FPU_S_TEST_IRQ, (uint32_t)TFM_FPU_S_TEST_Handler);
+
+    /* Enable FPU secure test interrupt */
+    NVIC_EnableIRQ(TFM_FPU_S_TEST_IRQ);
+#endif
+
+#if defined(TEST_NS_FPU)
+    /* Set IRQn in non-secure mode */
+    NVIC_SetTargetState(TFM_FPU_NS_TEST_IRQ);
 #endif
 
     return TFM_HAL_SUCCESS;
diff --git a/platform/ext/target/arm/mps3/an552/tfm_interrupts.c b/platform/ext/target/arm/mps3/an552/tfm_interrupts.c
index d787a27..db56b52 100644
--- a/platform/ext/target/arm/mps3/an552/tfm_interrupts.c
+++ b/platform/ext/target/arm/mps3/an552/tfm_interrupts.c
@@ -16,26 +16,12 @@
 #include "tfm_plat_test.h"
 #include "device_definition.h"
 
-#ifdef TEST_NS_FPU
-#define REL_VALUE_NS_THREAD_INTERRUPTED           (0xDEADBEEF)
-#endif
-
 static struct irq_t timer0_irq = {0};
 
-#ifdef TEST_NS_FPU
-__attribute__((naked)) void TFM_TIMER0_IRQ_Handler(void)
-{
-    __asm volatile(
-        "   mov    r0, lr                              \n"
-        "   b      TIMER0_IRQHandler_C                 \n"
-    );
-}
-#else
 void TFM_TIMER0_IRQ_Handler(void)
 {
     spm_handle_interrupt(timer0_irq.p_pt, timer0_irq.p_ildi);
 }
-#endif
 
 enum tfm_hal_status_t tfm_timer0_irq_init(void *p_pt,
                                           struct irq_load_info_t *p_ildi)
@@ -49,101 +35,3 @@
 
     return TFM_HAL_SUCCESS;
 }
-
-#ifdef TEST_NS_FPU
-/**
- * Change FP registers.
- */
-__attribute__((naked)) static void change_fp_regs_in_secure_handler(void)
-{
-    __asm volatile(
-        "mov       r0, #0xE0000000         \n"
-        "vmov      s0, r0                  \n"
-        "mov       r0, #0xE1000000         \n"
-        "vmov      s1, r0                  \n"
-        "mov       r0, #0xE2000000         \n"
-        "vmov      s2, r0                  \n"
-        "mov       r0, #0xE3000000         \n"
-        "vmov      s3, r0                  \n"
-        "mov       r0, #0xE4000000         \n"
-        "vmov      s4, r0                  \n"
-        "mov       r0, #0xE5000000         \n"
-        "vmov      s5, r0                  \n"
-        "mov       r0, #0xE6000000         \n"
-        "vmov      s6, r0                  \n"
-        "mov       r0, #0xE7000000         \n"
-        "vmov      s7, r0                  \n"
-        "mov       r0, #0xE8000000         \n"
-        "vmov      s8, r0                  \n"
-        "mov       r0, #0xE9000000         \n"
-        "vmov      s9, r0                  \n"
-        "mov       r0, #0xEA000000         \n"
-        "vmov      s10, r0                 \n"
-        "mov       r0, #0xEB000000         \n"
-        "vmov      s11, r0                 \n"
-        "mov       r0, #0xEC000000         \n"
-        "vmov      s12, r0                 \n"
-        "mov       r0, #0xED000000         \n"
-        "vmov      s13, r0                 \n"
-        "mov       r0, #0xEE000000         \n"
-        "vmov      s14, r0                 \n"
-        "mov       r0, #0xEF000000         \n"
-        "vmov      s15, r0                 \n"
-        "mov       r0, #0xF0000000         \n"
-        "vmov      s16, r0                 \n"
-        "mov       r0, #0xF1000000         \n"
-        "vmov      s17, r0                 \n"
-        "mov       r0, #0xF2000000         \n"
-        "vmov      s18, r0                 \n"
-        "mov       r0, #0xF3000000         \n"
-        "vmov      s19, r0                 \n"
-        "mov       r0, #0xF4000000         \n"
-        "vmov      s20, r0                 \n"
-        "mov       r0, #0xF5000000         \n"
-        "vmov      s21, r0                 \n"
-        "mov       r0, #0xF6000000         \n"
-        "vmov      s22, r0                 \n"
-        "mov       r0, #0xF7000000         \n"
-        "vmov      s23, r0                 \n"
-        "mov       r0, #0xF8000000         \n"
-        "vmov      s24, r0                 \n"
-        "mov       r0, #0xF9000000         \n"
-        "vmov      s25, r0                 \n"
-        "mov       r0, #0xFA000000         \n"
-        "vmov      s26, r0                 \n"
-        "mov       r0, #0xFB000000         \n"
-        "vmov      s27, r0                 \n"
-        "mov       r0, #0xFC000000         \n"
-        "vmov      s28, r0                 \n"
-        "mov       r0, #0xFD000000         \n"
-        "vmov      s29, r0                 \n"
-        "mov       r0, #0xFE000000         \n"
-        "vmov      s30, r0                 \n"
-        "mov       r0, #0xFF000000         \n"
-        "vmov      s31, r0                 \n"
-
-        "bx        lr                      \n"
-    );
-}
-
-/**
- * Subroutine of secure timer0 handler function, to check whether non-secure
- * thread are interrupted by secure exception by LR register.
- */
-void TIMER0_IRQHandler_C(uint32_t lr)
-{
-    /*
-     * Check whether no-secure thread is interrupted by this exception.
-     * EXC_RETURN bit[6], indicates whether a Secure or Non-secure stack is
-     * used to restore stack frame on exception return.
-     */
-    if ((lr & EXC_RETURN_SECURE_STACK) == 0){
-        change_fp_regs_in_secure_handler();
-        tfm_plat_test_secure_timer_stop();
-        tfm_plat_test_secure_timer_set_reload_value(
-                                            REL_VALUE_NS_THREAD_INTERRUPTED);
-    } else {
-        systimer_armv8_m_clear_autoinc_interrupt(&SYSTIMER0_ARMV8_M_DEV_S);
-    }
-}
-#endif
diff --git a/platform/ext/target/arm/mps3/an552/tfm_peripherals_def.c b/platform/ext/target/arm/mps3/an552/tfm_peripherals_def.c
index d7c162d..8eb1767 100644
--- a/platform/ext/target/arm/mps3/an552/tfm_peripherals_def.c
+++ b/platform/ext/target/arm/mps3/an552/tfm_peripherals_def.c
@@ -86,17 +86,10 @@
 };
 
 struct platform_data_t tfm_peripheral_timer1 = {
-#if (CONFIG_TFM_FP == 2) && (TEST_NS_FPU == 1)
-        SYSTIMER1_ARMV8_M_BASE_NS,
-        SYSTIMER1_ARMV8_M_BASE_NS + 0xFFF,
-        PPC_SP_DO_NOT_CONFIGURE,
-        -1
-#else
         SYSTIMER1_ARMV8_M_BASE_S,
         SYSTIMER1_ARMV8_M_BASE_S + 0xFFF,
         PPC_SP_PERIPH0,
         SYSTEM_TIMER1_PERIPH_PPC0_POS_MASK
-#endif
 };
 
 struct platform_data_t tfm_peripheral_timer2 = {
diff --git a/platform/ext/target/arm/mps3/an552/tfm_peripherals_def.h b/platform/ext/target/arm/mps3/an552/tfm_peripherals_def.h
index c7385c0..66a8443 100644
--- a/platform/ext/target/arm/mps3/an552/tfm_peripherals_def.h
+++ b/platform/ext/target/arm/mps3/an552/tfm_peripherals_def.h
@@ -25,6 +25,9 @@
 #define TFM_TIMER0_IRQ           (TIMER0_IRQn)
 #define TFM_TIMER1_IRQ           (TIMER1_IRQn)
 
+#define TFM_FPU_S_TEST_IRQ       (GPIO0_0_IRQn)
+#define TFM_FPU_NS_TEST_IRQ      (GPIO0_1_IRQn)
+
 extern struct platform_data_t tfm_peripheral_gpio0;
 extern struct platform_data_t tfm_peripheral_gpio1;
 extern struct platform_data_t tfm_peripheral_gpio2;
diff --git a/platform/ext/target/arm/musca_s1/CMakeLists.txt b/platform/ext/target/arm/musca_s1/CMakeLists.txt
index 3313354..9e7d774 100644
--- a/platform/ext/target/arm/musca_s1/CMakeLists.txt
+++ b/platform/ext/target/arm/musca_s1/CMakeLists.txt
@@ -106,43 +106,27 @@
         Native_Driver/qspi_ip6514e_drv.c
         Native_Driver/cache_drv.c
         spm_hal.c
-        $<$<AND:$<BOOL:${TFM_PSA_API}>,$<NOT:$<BOOL:${TEST_NS_FPU}>>>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_interrupts.c>
+        $<$<BOOL:${TFM_PSA_API}>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_interrupts.c>
         tfm_hal_isolation.c
         tfm_hal_platform.c
         target_cfg.c
-        $<$<NOT:$<BOOL:${TEST_NS_FPU}>>:${CMAKE_CURRENT_SOURCE_DIR}/Native_Driver/timer_cmsdk_drv.c>
+        ${CMAKE_CURRENT_SOURCE_DIR}/Native_Driver/timer_cmsdk_drv.c
         Libraries/mt25ql_flash_lib.c
         ${CMAKE_SOURCE_DIR}/platform/ext/common/tfm_hal_nvic.c
-        $<$<NOT:$<BOOL:${TEST_NS_FPU}>>:${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c>
+        ${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c
         $<$<BOOL:${TFM_PARTITION_PLATFORM}>:${CMAKE_CURRENT_SOURCE_DIR}/services/src/tfm_platform_system.c>
 )
 
-# Adding new defined handler function to the library where the weak handler
-# funtion symbol are, to override weak handler funtion.
-# Otherwise the weak handler funtion cannot be replaced by the new defined
-# hanlder function which symbol is in another library.
-target_sources(tfm_s
-    PRIVATE
-        $<$<AND:$<BOOL:${TFM_PSA_API}>,$<BOOL:${TEST_NS_FPU}>>:${CMAKE_CURRENT_SOURCE_DIR}/tfm_interrupts.c>
-)
-
 target_compile_options(platform_s
     PUBLIC
         ${COMPILER_CMSE_FLAG}
 )
 
-target_sources(tfm_sprt
-    PRIVATE
-        # FPU client test partition access the timer as ARoT Partitions.
-        # Put the driver to SPRT so that FPU tests can access it.
-        $<$<BOOL:${TEST_NS_FPU}>:${CMAKE_CURRENT_SOURCE_DIR}/Native_Driver/timer_cmsdk_drv.c>
-        $<$<BOOL:${TEST_NS_FPU}>:${CMAKE_CURRENT_SOURCE_DIR}/plat_test.c>
-)
-
 # To configure S and NS timer in S side for FP interrupt test
 target_compile_definitions(platform_s
     PUBLIC
         $<$<BOOL:${TEST_NS_FPU}>:TEST_NS_FPU>
+        $<$<BOOL:${TEST_S_FPU}>:TEST_S_FPU>
 )
 
 #========================= Platform Non-Secure ================================#
@@ -170,15 +154,6 @@
         ${CMAKE_SOURCE_DIR}/platform/ext/cmsis
 )
 
-# Adding new defined handler function to the library where the weak handler
-# funtion symbol are, to override weak handler funtion.
-# Otherwise the weak handler funtion cannot be replaced by the new defined
-# hanlder function which symbol is in another library.
-target_sources(tfm_ns
-    PRIVATE
-        $<$<BOOL:${TEST_NS_FPU}>:${CMAKE_CURRENT_SOURCE_DIR}/ns_fp_test_interrupt.c>
-)
-
 #========================= Platform BL2 =======================================#
 
 if(BL2)
diff --git a/platform/ext/target/arm/musca_s1/Device/Include/platform_irq.h b/platform/ext/target/arm/musca_s1/Device/Include/platform_irq.h
index 886f037..a63df07 100644
--- a/platform/ext/target/arm/musca_s1/Device/Include/platform_irq.h
+++ b/platform/ext/target/arm/musca_s1/Device/Include/platform_irq.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019 Arm Limited. All rights reserved.
+ * Copyright (c) 2019-2022 Arm Limited. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -124,6 +124,8 @@
   PWM_1_IRQn                =   74, /*  PWM1 interrupt                      */
   PWM_2_IRQn                =   75, /*  PWM2 interrupt                      */
   IOMUX_IRQn                =   76, /*  IOMUX interrupt                     */
+  TFM_FPU_S_TEST_IRQn       =   77, /*  TFM FPU Secure Test Interrupt       */
+  TFM_FPU_NS_TEST_IRQn      =   78, /*  TFM FPU Non-Secure Test Interrupt   */
 } IRQn_Type;
 
 #ifdef __cplusplus
diff --git a/platform/ext/target/arm/musca_s1/Device/Source/device_definition.c b/platform/ext/target/arm/musca_s1/Device/Source/device_definition.c
index fe831d7..1d903a8 100644
--- a/platform/ext/target/arm/musca_s1/Device/Source/device_definition.c
+++ b/platform/ext/target/arm/musca_s1/Device/Source/device_definition.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2017-2022 Arm Limited. All rights reserved.
+ * Copyright (c) 2017-2021 Arm Limited. All rights reserved.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,7 +26,6 @@
 #include "device_cfg.h"
 #include "device_definition.h"
 #include "platform_base_address.h"
-#include "tfm_plat_defs.h"
 
 /* ======= Peripheral configuration structure definitions ======= */
 
@@ -309,24 +308,12 @@
 
 /* CMSDK Timers driver structures */
 #ifdef CMSDK_TIMER0_S
-#ifdef TEST_NS_FPU
-static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S
-    TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-    = {.base = MUSCA_S1_CMSDK_TIMER0_S_BASE};
-static struct timer_cmsdk_dev_data_t CMSDK_TIMER0_DEV_DATA_S
-    TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-    = {.is_initialized = 0};
-struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV_S
-    TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-    = {&(CMSDK_TIMER0_DEV_CFG_S), &(CMSDK_TIMER0_DEV_DATA_S)};
-#else
 static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S = {
     .base = MUSCA_S1_CMSDK_TIMER0_S_BASE};
 static struct timer_cmsdk_dev_data_t CMSDK_TIMER0_DEV_DATA_S = {
     .is_initialized = 0};
 struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV_S = {&(CMSDK_TIMER0_DEV_CFG_S),
                                                &(CMSDK_TIMER0_DEV_DATA_S)};
-#endif /* TEST_NS_FPU */
 #endif
 #ifdef CMSDK_TIMER0_NS
 static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_NS = {
@@ -346,24 +333,12 @@
                                                &(CMSDK_TIMER1_DEV_DATA_S)};
 #endif
 #ifdef CMSDK_TIMER1_NS
-#ifdef TEST_NS_FPU
-static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER1_DEV_CFG_NS
-    TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-    = {.base = MUSCA_S1_CMSDK_TIMER1_NS_BASE};
-static struct timer_cmsdk_dev_data_t CMSDK_TIMER1_DEV_DATA_NS
-    TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-    = {.is_initialized = 0};
-struct timer_cmsdk_dev_t CMSDK_TIMER1_DEV_NS
-    TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-    = {&(CMSDK_TIMER1_DEV_CFG_NS), &(CMSDK_TIMER1_DEV_DATA_NS)};
-#else
 static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER1_DEV_CFG_NS = {
     .base = MUSCA_S1_CMSDK_TIMER1_NS_BASE};
 static struct timer_cmsdk_dev_data_t CMSDK_TIMER1_DEV_DATA_NS = {
     .is_initialized = 0};
 struct timer_cmsdk_dev_t CMSDK_TIMER1_DEV_NS = {&(CMSDK_TIMER1_DEV_CFG_NS),
                                                 &(CMSDK_TIMER1_DEV_DATA_NS)};
-#endif /* TEST_NS_FPU */
 #endif
 
 /* CMSDK Dualtimer driver structures */
diff --git a/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_bl2.S b/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_bl2.S
index 21f729b..932a80d 100644
--- a/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_bl2.S
+++ b/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_bl2.S
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2009-2019 Arm Limited. All rights reserved.
+; * Copyright (c) 2009-2022 Arm Limited. All rights reserved.
 ; *
 ; * Licensed under the Apache License, Version 2.0 (the "License");
 ; * you may not use this file except in compliance with the License.
@@ -121,6 +121,8 @@
     .long    PWM_1_IRQHandler                /* 74: PWM1 interrupt */
     .long    PWM_2_IRQHandler                /* 75: PWM2 interrupt */
     .long    IOMUX_IRQHandler                /* 76: IOMUX interrupt */
+    .long    TFM_FPU_S_TEST_Handler          /* 77: TFM FPU Secure Test Interrupt */
+    .long    TFM_FPU_NS_TEST_Handler         /* 78: TFM FPU Non-Secure Test Interrupt */
 
     .size    __Vectors, . - __Vectors
 
@@ -360,5 +362,7 @@
     def_irq_handler     PWM_1_IRQHandler                /* 74: PWM1 interrupt */
     def_irq_handler     PWM_2_IRQHandler                /* 75: PWM2 interrupt */
     def_irq_handler     IOMUX_IRQHandler                /* 76: IOMUX interrupt */
+    def_irq_handler     TFM_FPU_S_TEST_Handler          /* 77: TFM FPU Secure Test Interrupt */
+    def_irq_handler     TFM_FPU_NS_TEST_Handler         /* 78: TFM FPU Non-Secure Test Interrupt */
 
     .end
diff --git a/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_ns.S b/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_ns.S
index bc45037..1218555 100644
--- a/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_ns.S
+++ b/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_ns.S
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2009-2020 Arm Limited. All rights reserved.
+; * Copyright (c) 2009-2022 Arm Limited. All rights reserved.
 ; *
 ; * Licensed under the Apache License, Version 2.0 (the "License");
 ; * you may not use this file except in compliance with the License.
@@ -121,6 +121,8 @@
     .long    PWM_1_IRQHandler                /* 74: PWM1 interrupt */
     .long    PWM_2_IRQHandler                /* 75: PWM2 interrupt */
     .long    IOMUX_IRQHandler                /* 76: IOMUX interrupt */
+    .long    TFM_FPU_S_TEST_Handler          /* 77: TFM FPU Secure Test Interrupt */
+    .long    TFM_FPU_NS_TEST_Handler         /* 78: TFM FPU Non-Secure Test Interrupt */
 
     .size    __Vectors, . - __Vectors
 
@@ -351,5 +353,7 @@
     def_irq_handler     PWM_1_IRQHandler                /* 74: PWM1 interrupt */
     def_irq_handler     PWM_2_IRQHandler                /* 75: PWM2 interrupt */
     def_irq_handler     IOMUX_IRQHandler                /* 76: IOMUX interrupt */
+    def_irq_handler     TFM_FPU_S_TEST_Handler          /* 77: TFM FPU Secure Test Interrupt */
+    def_irq_handler     TFM_FPU_NS_TEST_Handler         /* 78: TFM FPU Non-Secure Test Interrupt */
 
     .end
diff --git a/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_s.S b/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_s.S
index aad6e6e..ae10ee0 100644
--- a/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_s.S
+++ b/platform/ext/target/arm/musca_s1/Device/Source/gcc/startup_cmsdk_musca_s.S
@@ -1,5 +1,5 @@
 ;/*
-; * Copyright (c) 2009-2021 Arm Limited. All rights reserved.
+; * Copyright (c) 2009-2022 Arm Limited. All rights reserved.
 ; *
 ; * Licensed under the Apache License, Version 2.0 (the "License");
 ; * you may not use this file except in compliance with the License.
@@ -123,6 +123,8 @@
     .long    PWM_1_IRQHandler                /* 74: PWM1 interrupt */
     .long    PWM_2_IRQHandler                /* 75: PWM2 interrupt */
     .long    IOMUX_IRQHandler                /* 76: IOMUX interrupt */
+    .long    TFM_FPU_S_TEST_Handler          /* 77: TFM FPU Secure Test Interrupt */
+    .long    TFM_FPU_NS_TEST_Handler         /* 78: TFM FPU Non-Secure Test Interrupt */
 
     .size    __Vectors, . - __Vectors
 
@@ -355,5 +357,7 @@
     def_irq_handler     PWM_1_IRQHandler                /* 74: PWM1 interrupt */
     def_irq_handler     PWM_2_IRQHandler                /* 75: PWM2 interrupt */
     def_irq_handler     IOMUX_IRQHandler                /* 76: IOMUX interrupt */
+    def_irq_handler     TFM_FPU_S_TEST_Handler          /* 77: TFM FPU Secure Test Interrupt */
+    def_irq_handler     TFM_FPU_NS_TEST_Handler         /* 78: TFM FPU Non-Secure Test Interrupt */
 
     .end
diff --git a/platform/ext/target/arm/musca_s1/mmio_defs.h b/platform/ext/target/arm/musca_s1/mmio_defs.h
index 3a9f392..1572bd8 100644
--- a/platform/ext/target/arm/musca_s1/mmio_defs.h
+++ b/platform/ext/target/arm/musca_s1/mmio_defs.h
@@ -24,9 +24,6 @@
 /* Allowed named MMIO of this platform */
 const uintptr_t partition_named_mmio_list[] = {
     (uintptr_t)TFM_PERIPHERAL_TIMER0,
-#ifdef TEST_NS_FPU
-    (uintptr_t)TFM_PERIPHERAL_TIMER1,
-#endif
     (uintptr_t)TFM_PERIPHERAL_STD_UART,
 #ifdef PSA_API_TEST_IPC
     (uintptr_t)FF_TEST_UART_REGION,
diff --git a/platform/ext/target/arm/musca_s1/ns_fp_test_interrupt.c b/platform/ext/target/arm/musca_s1/ns_fp_test_interrupt.c
deleted file mode 100644
index 18a107c..0000000
--- a/platform/ext/target/arm/musca_s1/ns_fp_test_interrupt.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (c) 2022, Arm Limited. All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- *
- */
-
-
-#include <stdbool.h>
-#include "device_definition.h"
-
-#define NR_FP_REG                               (32U)
-#define REL_VALUE_FP_REGS_INVALIDATED           (0xDEADBEEF)
-#define REL_VALUE_FP_REGS_NOT_INVALIDATED       (0xBEEFDEAD)
-
-void non_secure_timer_set_reload_value(uint32_t value)
-{
-    timer_cmsdk_set_reload_value(&CMSDK_TIMER1_DEV_NS, value);
-}
-
-void non_secure_timer_stop(void)
-{
-    timer_cmsdk_disable(&CMSDK_TIMER1_DEV_NS);
-    timer_cmsdk_disable_interrupt(&CMSDK_TIMER1_DEV_NS);
-    timer_cmsdk_clear_interrupt(&CMSDK_TIMER1_DEV_NS);
-}
-
-/*
- * Check whether FP registers are invalidated.
- * Return:
- *   True - FP registers are invalidated
- *   False - FP registers are not invalidated
- */
-#if defined (__GNUC__)
-__attribute__((noinline))
-#endif
-bool is_fp_regs_invalidated(void)
-{
-    static uint32_t fp_buffer[NR_FP_REG] = {0};
-    uint32_t i;
-
-    /* Dump FP data from FP registers to buffer */
-    __asm volatile(
-        "vstm      %0, {S0-S31}            \n"
-        :
-        :"r"(fp_buffer)
-        :"memory"
-    );
-
-    for(i = 0; i < NR_FP_REG; i++) {
-        if (fp_buffer[i] != 0){
-            return false;
-        }
-    }
-    return true;
-}
-
-void TIMER1_Handler()
-{
-    /* Check whether FP regs is invalidated */
-    if (is_fp_regs_invalidated()) {
-        non_secure_timer_set_reload_value(REL_VALUE_FP_REGS_INVALIDATED);
-    } else {
-        non_secure_timer_set_reload_value(REL_VALUE_FP_REGS_NOT_INVALIDATED);
-    }
-
-    non_secure_timer_stop();
-}
diff --git a/platform/ext/target/arm/musca_s1/plat_test.c b/platform/ext/target/arm/musca_s1/plat_test.c
index aad27d3..02d7a66 100644
--- a/platform/ext/target/arm/musca_s1/plat_test.c
+++ b/platform/ext/target/arm/musca_s1/plat_test.c
@@ -9,8 +9,6 @@
 #include "tfm_plat_defs.h"
 #include "tfm_plat_test.h"
 #include "device_definition.h"
-#include "cmsis.h"
-#include "tfm_peripherals_def.h"
 
 #define TIMER_RELOAD_VALUE          (16*1024*1024)
 
@@ -31,23 +29,6 @@
     timer_cmsdk_clear_interrupt(&CMSDK_TIMER0_DEV_S);
 }
 
-void tfm_plat_test_secure_timer_set_reload_value(uint32_t value)
-{
-    timer_cmsdk_set_reload_value(&CMSDK_TIMER0_DEV_S, value);
-}
-
-uint32_t tfm_plat_test_secure_timer_get_reload_value(void)
-{
-    return timer_cmsdk_get_reload_value(&CMSDK_TIMER0_DEV_S);
-}
-
-void tfm_plat_test_secure_timer_nvic_configure(void)
-{
-    NVIC_SetPriority(TFM_TIMER0_IRQ, DEFAULT_IRQ_PRIORITY);
-    NVIC_ClearTargetState(TFM_TIMER0_IRQ);
-    NVIC_EnableIRQ(TFM_TIMER0_IRQ);
-}
-
 void tfm_plat_test_non_secure_timer_start(void)
 {
     if (!timer_cmsdk_is_initialized(&CMSDK_TIMER1_DEV_NS)) {
@@ -58,13 +39,9 @@
     timer_cmsdk_enable_interrupt(&CMSDK_TIMER1_DEV_NS);
 }
 
-uint32_t tfm_plat_test_non_secure_timer_get_reload_value(void)
+void tfm_plat_test_non_secure_timer_stop(void)
 {
-    return timer_cmsdk_get_reload_value(&CMSDK_TIMER1_DEV_NS);
-}
-
-void tfm_plat_test_non_secure_timer_nvic_configure(void)
-{
-    NVIC_SetPriority(TFM_TIMER1_IRQ, 1);
-    NVIC_EnableIRQ(TFM_TIMER1_IRQ);
+    timer_cmsdk_disable(&CMSDK_TIMER1_DEV_NS);
+    timer_cmsdk_disable_interrupt(&CMSDK_TIMER1_DEV_NS);
+    timer_cmsdk_clear_interrupt(&CMSDK_TIMER1_DEV_NS);
 }
diff --git a/platform/ext/target/arm/musca_s1/target_cfg.c b/platform/ext/target/arm/musca_s1/target_cfg.c
index 0aba73b..7557d69 100644
--- a/platform/ext/target/arm/musca_s1/target_cfg.c
+++ b/platform/ext/target/arm/musca_s1/target_cfg.c
@@ -126,13 +126,6 @@
         CMSDK_TIMER0_APB_PPC_POS
 };
 
-struct platform_data_t tfm_peripheral_timer1 = {
-        MUSCA_S1_CMSDK_TIMER1_NS_BASE,
-        MUSCA_S1_CMSDK_DUALTIMER_NS_BASE - 1,
-        PPC_SP_DO_NOT_CONFIGURE,
-        -1
-};
-
 #ifdef PSA_API_TEST_IPC
 
 /* Below data structure are only used for PSA FF tests, and this pattern is
@@ -521,27 +514,15 @@
     if (ret != ARM_DRIVER_OK) {
         return ret;
     }
-#ifdef TEST_NS_FPU
-    ret = Driver_APB_PPC0.ConfigPeriph(CMSDK_TIMER0_APB_PPC_POS,
-                                 ARM_PPC_SECURE_ONLY,
-                                 ARM_PPC_PRIV_AND_NONPRIV);
-#else
     ret = Driver_APB_PPC0.ConfigPeriph(CMSDK_TIMER0_APB_PPC_POS,
                                  ARM_PPC_NONSECURE_ONLY,
                                  ARM_PPC_PRIV_ONLY);
-#endif
     if (ret != ARM_DRIVER_OK) {
         return ret;
     }
-#ifdef TEST_NS_FPU
-    ret = Driver_APB_PPC0.ConfigPeriph(CMSDK_TIMER1_APB_PPC_POS,
-                                 ARM_PPC_NONSECURE_ONLY,
-                                 ARM_PPC_PRIV_AND_NONPRIV);
-#else
     ret = Driver_APB_PPC0.ConfigPeriph(CMSDK_TIMER1_APB_PPC_POS,
                                  ARM_PPC_NONSECURE_ONLY,
                                  ARM_PPC_PRIV_ONLY);
-#endif
     if (ret != ARM_DRIVER_OK) {
         return ret;
     }
diff --git a/platform/ext/target/arm/musca_s1/tfm_hal_platform.c b/platform/ext/target/arm/musca_s1/tfm_hal_platform.c
index 6ebfe3e..c25ea5d 100644
--- a/platform/ext/target/arm/musca_s1/tfm_hal_platform.c
+++ b/platform/ext/target/arm/musca_s1/tfm_hal_platform.c
@@ -13,8 +13,8 @@
 #include "tfm_hal_platform.h"
 #include "tfm_plat_defs.h"
 #include "uart_stdout.h"
-#if (CONFIG_TFM_FP == 2) && (TEST_NS_FPU == 1)
-#include "tfm_plat_test.h"
+#if defined(TEST_NS_FPU) || defined(TEST_S_FPU)
+#include "test_interrupt.h"
 #endif
 
 extern const struct memory_region_limits memory_regions;
@@ -55,18 +55,20 @@
         return TFM_HAL_ERROR_GENERIC;
     }
 
-#if (CONFIG_TFM_FP == 2) && (TEST_NS_FPU == 1)
-    /* Configure secure timer */
-    tfm_plat_test_secure_timer_nvic_configure();
-    if (!timer_cmsdk_is_initialized(&CMSDK_TIMER0_DEV_S)) {
-        timer_cmsdk_init(&CMSDK_TIMER0_DEV_S);
-    }
+#if defined(TEST_S_FPU) || defined(TEST_NS_FPU)
+    /* Enable FPU secure test interrupt */
+    NVIC_EnableIRQ(TFM_FPU_S_TEST_IRQ);
 
-    /* Configure non-secure timer */
-    tfm_plat_test_non_secure_timer_nvic_configure();
-    if (!timer_cmsdk_is_initialized(&CMSDK_TIMER1_DEV_NS)) {
-        timer_cmsdk_init(&CMSDK_TIMER1_DEV_NS);
-    }
+    /* Set IRQn in secure mode */
+    NVIC_ClearTargetState(TFM_FPU_S_TEST_IRQ);
+#endif
+
+#if defined(TEST_NS_FPU)
+    NVIC_EnableIRQ(TFM_FPU_NS_TEST_IRQ);
+
+    /* Set IRQn in non-secure mode */
+    NVIC_SetTargetState(TFM_FPU_NS_TEST_IRQ);
+
 #endif
 
     return TFM_HAL_SUCCESS;
diff --git a/platform/ext/target/arm/musca_s1/tfm_interrupts.c b/platform/ext/target/arm/musca_s1/tfm_interrupts.c
index 80d54d5..8dc86bf 100644
--- a/platform/ext/target/arm/musca_s1/tfm_interrupts.c
+++ b/platform/ext/target/arm/musca_s1/tfm_interrupts.c
@@ -13,28 +13,13 @@
 #include "tfm_peripherals_def.h"
 #include "ffm/interrupt.h"
 #include "load/interrupt_defs.h"
-#include "tfm_plat_test.h"
-
-#ifdef TEST_NS_FPU
-#define REL_VALUE_NS_THREAD_INTERRUPTED           (0xDEADBEEF)
-#endif
 
 static struct irq_t timer0_irq = {0};
 
-#ifdef TEST_NS_FPU
-__attribute__((naked)) void TFM_TIMER0_IRQ_Handler(void)
-{
-    __asm volatile(
-        "   mov    r0, lr                              \n"
-        "   b      TIMER0_IRQHandler_C                 \n"
-    );
-}
-#else
 void TFM_TIMER0_IRQ_Handler(void)
 {
     spm_handle_interrupt(timer0_irq.p_pt, timer0_irq.p_ildi);
 }
-#endif
 
 enum tfm_hal_status_t tfm_timer0_irq_init(void *p_pt,
                                           struct irq_load_info_t *p_ildi)
@@ -72,101 +57,3 @@
 }
 
 #endif
-
-#ifdef TEST_NS_FPU
-/**
- * Change FP registers.
- */
-__attribute__((naked)) static void change_fp_regs_in_secure_handler(void)
-{
-    __asm volatile(
-        "push      {r4, lr}                \n"
-
-        "mov       r0, #0xE0000000         \n"
-        "vmov      s0, r0                  \n"
-        "mov       r0, #0xE1000000         \n"
-        "vmov      s1, r0                  \n"
-        "mov       r0, #0xE2000000         \n"
-        "vmov      s2, r0                  \n"
-        "mov       r0, #0xE3000000         \n"
-        "vmov      s3, r0                  \n"
-        "mov       r0, #0xE4000000         \n"
-        "vmov      s4, r0                  \n"
-        "mov       r0, #0xE5000000         \n"
-        "vmov      s5, r0                  \n"
-        "mov       r0, #0xE6000000         \n"
-        "vmov      s6, r0                  \n"
-        "mov       r0, #0xE7000000         \n"
-        "vmov      s7, r0                  \n"
-        "mov       r0, #0xE8000000         \n"
-        "vmov      s8, r0                  \n"
-        "mov       r0, #0xE9000000         \n"
-        "vmov      s9, r0                  \n"
-        "mov       r0, #0xEA000000         \n"
-        "vmov      s10, r0                 \n"
-        "mov       r0, #0xEB000000         \n"
-        "vmov      s11, r0                 \n"
-        "mov       r0, #0xEC000000         \n"
-        "vmov      s12, r0                 \n"
-        "mov       r0, #0xED000000         \n"
-        "vmov      s13, r0                 \n"
-        "mov       r0, #0xEE000000         \n"
-        "vmov      s14, r0                 \n"
-        "mov       r0, #0xEF000000         \n"
-        "vmov      s15, r0                 \n"
-        "mov       r0, #0xF0000000         \n"
-        "vmov      s16, r0                 \n"
-        "mov       r0, #0xF1000000         \n"
-        "vmov      s17, r0                 \n"
-        "mov       r0, #0xF2000000         \n"
-        "vmov      s18, r0                 \n"
-        "mov       r0, #0xF3000000         \n"
-        "vmov      s19, r0                 \n"
-        "mov       r0, #0xF4000000         \n"
-        "vmov      s20, r0                 \n"
-        "mov       r0, #0xF5000000         \n"
-        "vmov      s21, r0                 \n"
-        "mov       r0, #0xF6000000         \n"
-        "vmov      s22, r0                 \n"
-        "mov       r0, #0xF7000000         \n"
-        "vmov      s23, r0                 \n"
-        "mov       r0, #0xF8000000         \n"
-        "vmov      s24, r0                 \n"
-        "mov       r0, #0xF9000000         \n"
-        "vmov      s25, r0                 \n"
-        "mov       r0, #0xFA000000         \n"
-        "vmov      s26, r0                 \n"
-        "mov       r0, #0xFB000000         \n"
-        "vmov      s27, r0                 \n"
-        "mov       r0, #0xFC000000         \n"
-        "vmov      s28, r0                 \n"
-        "mov       r0, #0xFD000000         \n"
-        "vmov      s29, r0                 \n"
-        "mov       r0, #0xFE000000         \n"
-        "vmov      s30, r0                 \n"
-        "mov       r0, #0xFF000000         \n"
-        "vmov      s31, r0                 \n"
-
-        "pop       {r4, pc}                \n"
-    );
-}
-
-/**
- * Subroutine of secure timer0 handler function, to check whether non-secure
- * thread are interrupted by secure exception by LR register.
- */
-void TIMER0_IRQHandler_C(uint32_t lr)
-{
-    /*
-     * Check whether no-secure thread is interrupted by this exception.
-     * EXC_RETURN bit[6], indicates whether a Secure or Non-secure stack is
-     * used to restore stack frame on exception return.
-     */
-    if ((lr & EXC_RETURN_SECURE_STACK) == 0){
-        change_fp_regs_in_secure_handler();
-        tfm_plat_test_secure_timer_set_reload_value(
-                                            REL_VALUE_NS_THREAD_INTERRUPTED);
-        tfm_plat_test_secure_timer_stop();
-    }
-}
-#endif
diff --git a/platform/ext/target/arm/musca_s1/tfm_peripherals_def.h b/platform/ext/target/arm/musca_s1/tfm_peripherals_def.h
index d5e175f..03ca7c2 100644
--- a/platform/ext/target/arm/musca_s1/tfm_peripherals_def.h
+++ b/platform/ext/target/arm/musca_s1/tfm_peripherals_def.h
@@ -25,6 +25,8 @@
 #define TFM_TIMER1_IRQ           (TIMER1_IRQn)
 #define FF_TEST_UART_IRQ         (UART1_Tx_IRQn)
 #define FF_TEST_UART_IRQ_Handler UARTTX1_Handler
+#define TFM_FPU_S_TEST_IRQ       (TFM_FPU_S_TEST_IRQn)
+#define TFM_FPU_NS_TEST_IRQ      (TFM_FPU_NS_TEST_IRQn)
 
 struct platform_data_t;
 
diff --git a/platform/include/tfm_plat_test.h b/platform/include/tfm_plat_test.h
index e18f10e..ca72d9c 100644
--- a/platform/include/tfm_plat_test.h
+++ b/platform/include/tfm_plat_test.h
@@ -22,8 +22,6 @@
 TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_SLIH_TEST", "APP-ROT")
 #elif defined(TEST_NS_FLIH_IRQ)
 TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FLIH_TEST", "APP-ROT")
-#elif defined(TEST_NS_FPU)
-TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
 #endif
 void tfm_plat_test_secure_timer_start(void);
 
@@ -49,24 +47,6 @@
 void tfm_plat_test_secure_timer_stop(void);
 
 /**
- * \brief Set secure timer reload value.
- */
-void tfm_plat_test_secure_timer_set_reload_value(uint32_t value);
-
-/**
- * \brief Get secure timer reload value.
- */
-#if defined(TEST_NS_FPU)
-TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-#endif
-uint32_t tfm_plat_test_secure_timer_get_reload_value(void);
-
-/**
- * \brief Set NVIC interrupt priority and enablement for the Secure timer.
- */
-void tfm_plat_test_secure_timer_nvic_configure(void);
-
-/**
  * \brief starts Non-secure timer
  *
  * Configures a timer to start counting, and generate a timer interrupt after a
@@ -74,30 +54,12 @@
  * the timer should be long enough so that the test service can go to the state
  * where it starts waiting for the interrupt.
  */
-#if defined(TEST_NS_FPU)
-TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-#endif
 void tfm_plat_test_non_secure_timer_start(void);
 
 /**
  * \brief Stops the non-Secure timer and clears the timer interrupt.
  */
-#if defined(TEST_NS_FPU)
-TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-#endif
 void tfm_plat_test_non_secure_timer_stop(void);
 
-/**
- * \brief Get non-secure timer reload value.
- */
-#if defined(TEST_NS_FPU)
-TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_SP_FPU_SERVICE_TEST", "APP-ROT")
-#endif
-uint32_t tfm_plat_test_non_secure_timer_get_reload_value(void);
-
-/**
- * \brief Set NVIC interrupt priority and enablement for the non-Secure timer.
- */
-void tfm_plat_test_non_secure_timer_nvic_configure(void);
 
 #endif /* __TFM_PLAT_TEST_H__ */
diff --git a/platform/ns/CMakeLists.txt b/platform/ns/CMakeLists.txt
index aab3796..6fffa7f 100755
--- a/platform/ns/CMakeLists.txt
+++ b/platform/ns/CMakeLists.txt
@@ -21,6 +21,8 @@
     PRIVATE
         $<$<BOOL:${PLATFORM_DEFAULT_UART_STDOUT}>:${CMAKE_CURRENT_SOURCE_DIR}/../ext/common/uart_stdout.c>
         $<$<AND:$<NOT:$<BOOL:${SYMMETRIC_INITIAL_ATTESTATION}>>,$<BOOL:${TEST_NS_ATTESTATION}>>:${CMAKE_CURRENT_SOURCE_DIR}/../ext/common/template/tfm_initial_attest_pub_key.c>
+    PUBLIC
+        $<$<OR:$<BOOL:${TEST_S_FPU}>,$<BOOL:${TEST_NS_FPU}>>:${CMAKE_SOURCE_DIR}/platform/ext/common/test_interrupt.c>
 )
 
 target_link_libraries(platform_ns