Test: Add testcases for IRQ handling

This patch contains a test cases exercising the secure IRQ handling
feature of TF-M.

Details of the change:
 * Add documentation on the tests
 * Create new service which handles timer0 interrupts
 * Link timer0 driver structures to IRQ test service
 * Implement the testcases in the positive test suite, the new IRQ test
   service and in TFM_SP_CORE_TEST_2

Change-Id: If7e3d1b57eac4de9ff6e01f0b04efd04bc443545
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/secure_fw/core/ipc/include/tfm_spm_signal_defs.h b/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
index 523b6b1..a508691 100644
--- a/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
+++ b/secure_fw/core/ipc/include/tfm_spm_signal_defs.h
@@ -15,5 +15,6 @@
 #include "secure_fw/services/secure_storage/tfm_sst_signal.h"
 #include "secure_fw/services/initial_attestation/tfm_attest_signal.h"
 #include "test/test_services/tfm_ipc_client/tfm_ipc_client_partition.h"
+#include "test/test_services/tfm_irq_test_service_1/tfm_irq_test_service_1_signal.h"
 
 #endif /* __TFM_SPM_SIGNAL_DEFS_H__ */
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 42a6086..7303a66 100644
--- a/secure_fw/core/ipc/tfm_secure_irq_handlers_ipc.inc
+++ b/secure_fw/core/ipc/tfm_secure_irq_handlers_ipc.inc
@@ -12,9 +12,25 @@
 
 /* Definitions of the signals of the IRQs (if any) */
 const struct tfm_core_irq_signal_data_t tfm_core_irq_signals[] = {
+#ifdef TFM_PARTITION_TEST_CORE
+    { TFM_IRQ_TEST_1_ID, SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ, TFM_TIMER0_IRQ, 64 },
+#endif /* TFM_PARTITION_TEST_CORE */
 };
 
 const size_t tfm_core_irq_signals_count = sizeof(tfm_core_irq_signals) /
                                           sizeof(*tfm_core_irq_signals);
 
 /* Definitions of privileged IRQ handlers (if any) */
+#ifdef TFM_PARTITION_TEST_CORE
+void TFM_TIMER0_IRQ_Handler(void)
+{
+    __disable_irq();
+    /* It is OK to call tfm_irq_handler directly from here, as we are already
+     * in handler mode, and we will not be pre-empted as we disabled interrupts
+     */
+    tfm_irq_handler(TFM_IRQ_TEST_1_ID, SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ, TFM_TIMER0_IRQ);
+    __enable_irq();
+}
+
+#endif /* TFM_PARTITION_TEST_CORE */
+
diff --git a/secure_fw/core/tfm_irq_signal_defs.h b/secure_fw/core/tfm_irq_signal_defs.h
index e851776..2327a28 100644
--- a/secure_fw/core/tfm_irq_signal_defs.h
+++ b/secure_fw/core/tfm_irq_signal_defs.h
@@ -7,5 +7,6 @@
 #ifndef __TFM_IRQ_SIGNAL_DEFS_H__
 #define __TFM_IRQ_SIGNAL_DEFS_H__
 
+#define SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ              (1U << (27 + 4))
 
 #endif /* __TFM_IRQ_SIGNAL_DEFS_H__ */
diff --git a/secure_fw/core/tfm_secure_irq_handlers.inc b/secure_fw/core/tfm_secure_irq_handlers.inc
index 5ff583a..01e6e1e 100644
--- a/secure_fw/core/tfm_secure_irq_handlers.inc
+++ b/secure_fw/core/tfm_secure_irq_handlers.inc
@@ -11,6 +11,9 @@
 
 /* Definitions of the signals of the IRQs */
 const struct tfm_core_irq_signal_data_t tfm_core_irq_signals[] = {
+#ifdef TFM_PARTITION_TEST_CORE
+    { TFM_IRQ_TEST_1_ID, SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ, TFM_TIMER0_IRQ, 64 },
+#endif /* TFM_PARTITION_TEST_CORE */
 };
 
 const size_t tfm_core_irq_signals_count = sizeof(tfm_core_irq_signals) /
@@ -22,5 +25,20 @@
                                   uint32_t irq_line);
 
 /* Forward declarations of unpriv IRQ handlers*/
+#ifdef TFM_PARTITION_TEST_CORE
+extern void SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ_isr(void);
+#endif /* TFM_PARTITION_TEST_CORE */
+
 
 /* Definitions of privileged IRQ handlers */
+#ifdef TFM_PARTITION_TEST_CORE
+void TFM_TIMER0_IRQ_Handler(void)
+{
+    priv_irq_handler_main(TFM_IRQ_TEST_1_ID,
+                          (uint32_t)SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ_isr,
+                          SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ,
+                          TFM_TIMER0_IRQ);
+}
+
+#endif /* TFM_PARTITION_TEST_CORE */
+
diff --git a/secure_fw/ns_callable/tfm_veneers.c b/secure_fw/ns_callable/tfm_veneers.c
index 2ba8a2c..023ce36 100644
--- a/secure_fw/ns_callable/tfm_veneers.c
+++ b/secure_fw/ns_callable/tfm_veneers.c
@@ -94,6 +94,8 @@
 psa_status_t spm_core_test_2_sfn_invert(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t spm_core_test_2_check_caller_client_id(psa_invec *, size_t, psa_outvec *, size_t);
 psa_status_t spm_core_test_2_get_every_second_byte(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t spm_core_test_2_prepare_test_scenario(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t spm_core_test_2_execute_test_scenario(psa_invec *, size_t, psa_outvec *, size_t);
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #ifdef TFM_PARTITION_TEST_SECURE_SERVICES
@@ -109,6 +111,12 @@
 /******** TFM_SP_IPC_CLIENT_TEST ********/
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
+#ifdef TFM_PARTITION_TEST_CORE
+/******** TFM_IRQ_TEST_1 ********/
+psa_status_t spm_irq_test_1_prepare_test_scenario(psa_invec *, size_t, psa_outvec *, size_t);
+psa_status_t spm_irq_test_1_execute_test_scenario(psa_invec *, size_t, psa_outvec *, size_t);
+#endif /* TFM_PARTITION_TEST_CORE */
+
 
 #define TFM_VENEER_FUNCTION(partition_name, sfn_name) \
     __tfm_secure_gateway_attributes__ \
@@ -206,6 +214,8 @@
 TFM_VENEER_FUNCTION(TFM_SP_CORE_TEST_2, spm_core_test_2_sfn_invert)
 TFM_VENEER_FUNCTION(TFM_SP_CORE_TEST_2, spm_core_test_2_check_caller_client_id)
 TFM_VENEER_FUNCTION(TFM_SP_CORE_TEST_2, spm_core_test_2_get_every_second_byte)
+TFM_VENEER_FUNCTION(TFM_SP_CORE_TEST_2, spm_core_test_2_prepare_test_scenario)
+TFM_VENEER_FUNCTION(TFM_SP_CORE_TEST_2, spm_core_test_2_execute_test_scenario)
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #ifdef TFM_PARTITION_TEST_SECURE_SERVICES
@@ -221,3 +231,9 @@
 /******** TFM_SP_IPC_CLIENT_TEST ********/
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
+#ifdef TFM_PARTITION_TEST_CORE
+/******** TFM_IRQ_TEST_1 ********/
+TFM_VENEER_FUNCTION(TFM_IRQ_TEST_1, spm_irq_test_1_prepare_test_scenario)
+TFM_VENEER_FUNCTION(TFM_IRQ_TEST_1, spm_irq_test_1_execute_test_scenario)
+#endif /* TFM_PARTITION_TEST_CORE */
+
diff --git a/secure_fw/services/tfm_partition_defs.inc b/secure_fw/services/tfm_partition_defs.inc
index 19e459d..bf195a3 100644
--- a/secure_fw/services/tfm_partition_defs.inc
+++ b/secure_fw/services/tfm_partition_defs.inc
@@ -44,6 +44,10 @@
 #define TFM_SP_IPC_CLIENT_TEST_ID (TFM_SP_BASE + 9)
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
-#define TFM_MAX_USER_PARTITIONS (10)
+#ifdef TFM_PARTITION_TEST_CORE
+#define TFM_IRQ_TEST_1_ID (TFM_SP_BASE + 10)
+#endif /* TFM_PARTITION_TEST_CORE */
+
+#define TFM_MAX_USER_PARTITIONS (11)
 
 #endif /* __TFM_PARTITION_DEFS_INC__ */
diff --git a/secure_fw/services/tfm_partition_list.inc b/secure_fw/services/tfm_partition_list.inc
index 90344e2..41f50e1 100644
--- a/secure_fw/services/tfm_partition_list.inc
+++ b/secure_fw/services/tfm_partition_list.inc
@@ -99,4 +99,14 @@
 PARTITION_ADD_INIT_FUNC(TFM_SP_IPC_CLIENT_TEST, ipc_client_test_main);
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
+#ifdef TFM_PARTITION_TEST_CORE
+/******** TFM_IRQ_TEST_1 ********/
+#define TFM_PARTITION_TFM_IRQ_TEST_1_IRQ_COUNT 1
+PARTITION_DECLARE(TFM_IRQ_TEST_1, 0
+    | SPM_PART_FLAG_IPC
+    , "APPLICATION-ROT", TFM_IRQ_TEST_1_ID, NORMAL);
+PARTITION_ADD_INIT_FUNC(TFM_IRQ_TEST_1, tfm_irq_test_1_init);
+PARTITION_ADD_PERIPHERAL(TFM_IRQ_TEST_1, TFM_PERIPHERAL_TIMER0);
+#endif /* TFM_PARTITION_TEST_CORE */
+
 #endif /* __TFM_PARTITION_LIST_INC__ */
diff --git a/secure_fw/services/tfm_service_list.inc b/secure_fw/services/tfm_service_list.inc
index f3bf254..d408bf5 100644
--- a/secure_fw/services/tfm_service_list.inc
+++ b/secure_fw/services/tfm_service_list.inc
@@ -249,6 +249,24 @@
         1,
         TFM_VERSION_POLICY_STRICT
 },
+{
+        "SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO",
+        TFM_SP_CORE_TEST_2_ID,
+        SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SIGNAL,
+        0x00002204,
+        true,
+        1,
+        TFM_VERSION_POLICY_STRICT
+},
+{
+        "SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO",
+        TFM_SP_CORE_TEST_2_ID,
+        SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SIGNAL,
+        0x00002205,
+        true,
+        1,
+        TFM_VERSION_POLICY_STRICT
+},
 #endif /* TFM_PARTITION_TEST_CORE */
 
 #ifdef TFM_PARTITION_TEST_SECURE_SERVICES
@@ -353,4 +371,26 @@
 },
 #endif /* TFM_PARTITION_TEST_CORE_IPC */
 
+#ifdef TFM_PARTITION_TEST_CORE
+/******** TFM_IRQ_TEST_1 ********/
+{
+        "SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO",
+        TFM_IRQ_TEST_1_ID,
+        SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SIGNAL,
+        0x00002300,
+        true,
+        1,
+        TFM_VERSION_POLICY_STRICT
+},
+{
+        "SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO",
+        TFM_IRQ_TEST_1_ID,
+        SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SIGNAL,
+        0x00002301,
+        true,
+        1,
+        TFM_VERSION_POLICY_STRICT
+},
+#endif /* TFM_PARTITION_TEST_CORE */
+
 #endif /* __TFM_SERVICE_LIST_INC__ */