Test: Add NS IRQ test
Change-Id: I6b480a796b0e577f0eeedb2132c651bd4b8a63d3
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
diff --git a/docs/user_guides/services/core_test_services_integration_guide.rst b/docs/user_guides/services/core_test_services_integration_guide.rst
index c3f213f..fbd985a 100644
--- a/docs/user_guides/services/core_test_services_integration_guide.rst
+++ b/docs/user_guides/services/core_test_services_integration_guide.rst
@@ -66,8 +66,10 @@
- S code execution is interrupted by a secure IRQ, The handler is the
interrupted service (``IRQ_TEST_SCENARIO_3``)
- S code waits for an interrupt (calling ``psa_wait()``), the handler is in
- the service that is waiting, ``psa_eoi()`` is called after ``psa_wait()`` returns
- (``IRQ_TEST_SCENARIO_4``)
+ the service that is waiting, ``psa_eoi()`` is called after ``psa_wait()``
+ returns (``IRQ_TEST_SCENARIO_4``)
+- S code waits for a non-secure interrupt to be triggered
+ (``IRQ_TEST_SCENARIO_5``)
The following test services participate in the test execution:
@@ -79,18 +81,24 @@
All the test executions are initiated from the NS positive test suite. For each
scenario the non-secure testcase calls the following secure functions in order:
-1. prepare_test_scenario for ``TFM_IRQ_TEST_1``
-2. prepare_test_scenario for ``TFM_SP_CORE_TEST_2``
-3. execute_test_scenario for ``TFM_IRQ_TEST_1``
-4. execute_test_scenario for ``TFM_SP_CORE_TEST_2``
+#. prepare_test_scenario for ``TFM_IRQ_TEST_1``
+#. prepare_test_scenario for ``TFM_SP_CORE_TEST_2``
+#. prepare_test_scenario_ns
+#. execute_test_scenario for ``TFM_IRQ_TEST_1``
+#. execute_test_scenario for ``TFM_SP_CORE_TEST_2``
+#. execute_test_scenario_ns
-During these steps, the ``TFM_IRQ_TEST_1`` sets up a timer with a convenient
-init value, and depending on the scenario, one of the services, or the NS code
-enters a busy wait waiting for the timer interrupt to be raised. In case of
-``IRQ_TEST_SCENARIO_3``, when ``PSA API`` is used, the execute_test_scenario
-request of the NS code is only replied when the IRQ is handled, so no explicit
-busy wait is required. In all the other cases, handling of the irq is signalled
-to the waiting party by setting a variable in a non-secure memory location.
+For scenarios 1-4 during the steps above the ``TFM_IRQ_TEST_1`` sets up a timer
+with a convenient init value, and depending on the scenario, one of the
+services, or the NS code enters a busy wait waiting for the timer interrupt to
+be raised. In case of ``IRQ_TEST_SCENARIO_3``, when ``PSA API`` is used, the
+execute_test_scenario request of the NS code is only replied when the IRQ is
+handled, so no explicit busy wait is required. In all the other cases, handling
+of the irq is signalled to the waiting party by setting a variable in a
+non-secure memory location.
+
+For scenario 5 a Non-secure timer is set up and ``TFM_SP_CORE_TEST_2`` waits for
+it to be triggered
--------------
diff --git a/platform/ext/target/musca_a/Device/Source/armclang/startup_cmsdk_musca_ns.s b/platform/ext/target/musca_a/Device/Source/armclang/startup_cmsdk_musca_ns.s
index 5740902..e949f4b 100644
--- a/platform/ext/target/musca_a/Device/Source/armclang/startup_cmsdk_musca_ns.s
+++ b/platform/ext/target/musca_a/Device/Source/armclang/startup_cmsdk_musca_ns.s
@@ -57,7 +57,7 @@
DCD NS_WATCHDOG_IRQHandler ; 1: Non-Secure Watchdog Interrupt
DCD S32K_TIMER_IRQHandler ; 2: S32K Timer Interrupt
DCD TIMER0_IRQHandler ; 3: CMSDK Timer 0 Interrupt
- DCD TIMER1_IRQHandler ; 4: CMSDK Timer 1 Interrupt
+ DCD TIMER1_Handler ; 4: CMSDK Timer 1 Interrupt
DCD DUALTIMER_IRQHandler ; 5: CMSDK Dual Timer Interrupt
DCD MHU0_IRQHandler ; 6: Message Handling Unit 0 Interrupt
DCD MHU1_IRQHandler ; 7: Message Handling Unit 1 Interrupt
@@ -175,7 +175,7 @@
Default_Handler NS_WATCHDOG_IRQHandler
Default_Handler S32K_TIMER_IRQHandler
Default_Handler TIMER0_IRQHandler
- Default_Handler TIMER1_IRQHandler
+ Default_Handler TIMER1_Handler
Default_Handler DUALTIMER_IRQHandler
Default_Handler MHU0_IRQHandler
Default_Handler MHU1_IRQHandler
diff --git a/platform/ext/target/musca_a/Device/Source/gcc/startup_cmsdk_musca_ns.S b/platform/ext/target/musca_a/Device/Source/gcc/startup_cmsdk_musca_ns.S
index 9a69d8b..05d56bb 100644
--- a/platform/ext/target/musca_a/Device/Source/gcc/startup_cmsdk_musca_ns.S
+++ b/platform/ext/target/musca_a/Device/Source/gcc/startup_cmsdk_musca_ns.S
@@ -46,7 +46,7 @@
.long NS_WATCHDOG_IRQHandler /* 1: Non-Secure Watchdog Interrupt */
.long S32K_TIMER_IRQHandler /* 2: S32K Timer Interrupt */
.long TIMER0_IRQHandler /* 3: CMSDK Timer 0 Interrupt */
- .long TIMER1_IRQHandler /* 4: CMSDK Timer 1 Interrupt */
+ .long TIMER1_Handler /* 4: CMSDK Timer 1 Interrupt */
.long DUALTIMER_IRQHandler /* 5: CMSDK Dual Timer Interrupt */
.long MHU0_IRQHandler /* 6: Message Handling Unit 0 Interrupt */
.long MHU1_IRQHandler /* 7: Message Handling Unit 1 Interrupt */
@@ -288,7 +288,7 @@
def_irq_handler NS_WATCHDOG_IRQHandler /* 1: Non-Secure Watchdog Interrupt */
def_irq_handler S32K_TIMER_IRQHandler /* 2: S32K Timer Interrupt */
def_irq_handler TIMER0_IRQHandler /* 3: CMSDK Timer 0 Interrupt */
- def_irq_handler TIMER1_IRQHandler /* 4: CMSDK Timer 1 Interrupt */
+ def_irq_handler TIMER1_Handler /* 4: CMSDK Timer 1 Interrupt */
def_irq_handler DUALTIMER_IRQHandler /* 5: CMSDK Dual Timer Interrupt */
def_irq_handler MHU0_IRQHandler /* 6: Message Handling Unit 0 Interrupt */
def_irq_handler MHU1_IRQHandler /* 7: Message Handling Unit 1 Interrupt */
diff --git a/platform/ext/target/musca_b1/Device/Source/armclang/startup_cmsdk_musca_ns.s b/platform/ext/target/musca_b1/Device/Source/armclang/startup_cmsdk_musca_ns.s
index 1789c5a..f3ed841 100644
--- a/platform/ext/target/musca_b1/Device/Source/armclang/startup_cmsdk_musca_ns.s
+++ b/platform/ext/target/musca_b1/Device/Source/armclang/startup_cmsdk_musca_ns.s
@@ -57,7 +57,7 @@
DCD NS_WATCHDOG_IRQHandler ; 1: Non-Secure Watchdog Interrupt
DCD S32K_TIMER_IRQHandler ; 2: S32K Timer Interrupt
DCD TIMER0_IRQHandler ; 3: CMSDK Timer 0 Interrupt
- DCD TIMER1_IRQHandler ; 4: CMSDK Timer 1 Interrupt
+ DCD TIMER1_Handler ; 4: CMSDK Timer 1 Interrupt
DCD DUALTIMER_IRQHandler ; 5: CMSDK Dual Timer Interrupt
DCD MHU0_IRQHandler ; 6: Message Handling Unit 0 Interrupt
DCD MHU1_IRQHandler ; 7: Message Handling Unit 1 Interrupt
@@ -175,7 +175,7 @@
Default_Handler NS_WATCHDOG_IRQHandler
Default_Handler S32K_TIMER_IRQHandler
Default_Handler TIMER0_IRQHandler
- Default_Handler TIMER1_IRQHandler
+ Default_Handler TIMER1_Handler
Default_Handler DUALTIMER_IRQHandler
Default_Handler MHU0_IRQHandler
Default_Handler MHU1_IRQHandler
diff --git a/platform/ext/target/musca_b1/Device/Source/gcc/startup_cmsdk_musca_ns.S b/platform/ext/target/musca_b1/Device/Source/gcc/startup_cmsdk_musca_ns.S
index 9a69d8b..05d56bb 100644
--- a/platform/ext/target/musca_b1/Device/Source/gcc/startup_cmsdk_musca_ns.S
+++ b/platform/ext/target/musca_b1/Device/Source/gcc/startup_cmsdk_musca_ns.S
@@ -46,7 +46,7 @@
.long NS_WATCHDOG_IRQHandler /* 1: Non-Secure Watchdog Interrupt */
.long S32K_TIMER_IRQHandler /* 2: S32K Timer Interrupt */
.long TIMER0_IRQHandler /* 3: CMSDK Timer 0 Interrupt */
- .long TIMER1_IRQHandler /* 4: CMSDK Timer 1 Interrupt */
+ .long TIMER1_Handler /* 4: CMSDK Timer 1 Interrupt */
.long DUALTIMER_IRQHandler /* 5: CMSDK Dual Timer Interrupt */
.long MHU0_IRQHandler /* 6: Message Handling Unit 0 Interrupt */
.long MHU1_IRQHandler /* 7: Message Handling Unit 1 Interrupt */
@@ -288,7 +288,7 @@
def_irq_handler NS_WATCHDOG_IRQHandler /* 1: Non-Secure Watchdog Interrupt */
def_irq_handler S32K_TIMER_IRQHandler /* 2: S32K Timer Interrupt */
def_irq_handler TIMER0_IRQHandler /* 3: CMSDK Timer 0 Interrupt */
- def_irq_handler TIMER1_IRQHandler /* 4: CMSDK Timer 1 Interrupt */
+ def_irq_handler TIMER1_Handler /* 4: CMSDK Timer 1 Interrupt */
def_irq_handler DUALTIMER_IRQHandler /* 5: CMSDK Dual Timer Interrupt */
def_irq_handler MHU0_IRQHandler /* 6: Message Handling Unit 0 Interrupt */
def_irq_handler MHU1_IRQHandler /* 7: Message Handling Unit 1 Interrupt */
diff --git a/test/suites/core/non_secure/core_ns_positive_testsuite.c b/test/suites/core/non_secure/core_ns_positive_testsuite.c
index caf16d6..d359cd2 100644
--- a/test/suites/core/non_secure/core_ns_positive_testsuite.c
+++ b/test/suites/core/non_secure/core_ns_positive_testsuite.c
@@ -5,17 +5,19 @@
*
*/
+#include <stdio.h>
+#include <string.h>
+
#include "core_ns_tests.h"
#include "tfm_api.h"
+#include "tfm_plat_test.h"
#include "test/suites/core/non_secure/core_test_api.h"
#include "test/test_services/tfm_core_test/core_test_defs.h"
+#include "platform_irq.h"
#ifndef TFM_PSA_API
#include "tfm_veneers.h"
#endif /* TFM_PSA_API */
-#include <stdio.h>
-#include <string.h>
-
/* Define test suite for core tests */
/* List of tests */
@@ -40,7 +42,10 @@
static void tfm_core_test_peripheral_access(struct test_result_t *ret);
static void tfm_core_test_iovec_sanitization(struct test_result_t *ret);
static void tfm_core_test_outvec_write(struct test_result_t *ret);
-static void tfm_core_test_secure_irq(struct test_result_t *ret);
+static void tfm_core_test_irq(struct test_result_t *ret);
+
+static enum irq_test_scenario_t executing_irq_test_scenario = IRQ_TEST_SCENARIO_NONE;
+static struct irq_test_execution_data_t irq_test_execution_data = {0};
static struct test_t core_tests[] = {
CORE_TEST_DESCRIPTION(CORE_TEST_ID_NS_THREAD, tfm_core_test_ns_thread,
@@ -55,7 +60,7 @@
"Test secure service memory access permissions"),
#endif /* TFM_PSA_API */
CORE_TEST_DESCRIPTION(CORE_TEST_ID_SECURE_IRQ,
- tfm_core_test_secure_irq,
+ tfm_core_test_irq,
"Test secure irq"),
#ifndef TFM_PSA_API
CORE_TEST_DESCRIPTION(CORE_TEST_ID_MPU_ACCESS, tfm_core_test_mpu_access,
@@ -426,6 +431,31 @@
ret->val = TEST_PASSED;
}
+static int32_t prepare_test_scenario_ns(
+ enum irq_test_scenario_t test_scenario,
+ struct irq_test_execution_data_t *execution_data)
+{
+ executing_irq_test_scenario = test_scenario;
+ switch (test_scenario) {
+ case IRQ_TEST_SCENARIO_NONE:
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ case IRQ_TEST_SCENARIO_1:
+ case IRQ_TEST_SCENARIO_2:
+ case IRQ_TEST_SCENARIO_3:
+ case IRQ_TEST_SCENARIO_4:
+ /* nothing to be done here */
+ break;
+ case IRQ_TEST_SCENARIO_5:
+ execution_data->timer1_triggered = 0;
+ tfm_plat_test_non_secure_timer_start();
+ break;
+ default:
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ return CORE_TEST_ERRNO_SUCCESS;
+}
+
static int32_t execute_test_scenario_ns(
enum irq_test_scenario_t test_scenario,
struct irq_test_execution_data_t *execution_data)
@@ -445,6 +475,7 @@
case IRQ_TEST_SCENARIO_2:
case IRQ_TEST_SCENARIO_3:
case IRQ_TEST_SCENARIO_4:
+ case IRQ_TEST_SCENARIO_5:
/* nothing to be done here */
break;
default:
@@ -454,11 +485,33 @@
return CORE_TEST_ERRNO_SUCCESS;
}
-static int32_t tfm_core_test_secure_irq_scenario(
+void TIMER1_Handler (void)
+{
+ tfm_plat_test_non_secure_timer_stop();
+
+ switch (executing_irq_test_scenario) {
+ case IRQ_TEST_SCENARIO_NONE:
+ case IRQ_TEST_SCENARIO_1:
+ case IRQ_TEST_SCENARIO_2:
+ case IRQ_TEST_SCENARIO_3:
+ case IRQ_TEST_SCENARIO_4:
+ while (1) {}
+ /* shouldn't happen */
+ break;
+ case IRQ_TEST_SCENARIO_5:
+ irq_test_execution_data.timer1_triggered = 1;
+ break;
+ default:
+ while (1) {}
+ /* shouldn't happen */
+ break;
+ }
+}
+
+static int32_t tfm_core_test_irq_scenario(
enum irq_test_scenario_t test_scenario)
{
- struct irq_test_execution_data_t execution_data = {0};
- struct irq_test_execution_data_t *execution_data_address = &execution_data;
+ struct irq_test_execution_data_t *execution_data_address = &irq_test_execution_data;
uint32_t scenario = test_scenario;
psa_invec in_vec[] = {
@@ -489,6 +542,11 @@
return err;
}
+ err = prepare_test_scenario_ns(test_scenario, &irq_test_execution_data);
+ if (err != CORE_TEST_ERRNO_SUCCESS) {
+ return err;
+ }
+
#ifdef TFM_PSA_API
err = psa_test_common(SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SID,
SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_MIN_VER,
@@ -511,7 +569,7 @@
return err;
}
- err = execute_test_scenario_ns(test_scenario, &execution_data);
+ err = execute_test_scenario_ns(test_scenario, &irq_test_execution_data);
if (err != CORE_TEST_ERRNO_SUCCESS) {
return err;
}
@@ -519,34 +577,42 @@
return CORE_TEST_ERRNO_SUCCESS;
}
-static void tfm_core_test_secure_irq(struct test_result_t *ret)
+static void tfm_core_test_irq(struct test_result_t *ret)
{
int32_t err;
- err = tfm_core_test_secure_irq_scenario(IRQ_TEST_SCENARIO_1);
+ NVIC_EnableIRQ(4);
+
+ err = tfm_core_test_irq_scenario(IRQ_TEST_SCENARIO_1);
if (err != CORE_TEST_ERRNO_SUCCESS) {
TEST_FAIL("Failed to execute IRQ test scenario 1.");
return;
}
- err = tfm_core_test_secure_irq_scenario(IRQ_TEST_SCENARIO_2);
+ err = tfm_core_test_irq_scenario(IRQ_TEST_SCENARIO_2);
if (err != CORE_TEST_ERRNO_SUCCESS) {
TEST_FAIL("Failed to execute IRQ test scenario 2.");
return;
}
- err = tfm_core_test_secure_irq_scenario(IRQ_TEST_SCENARIO_3);
+ err = tfm_core_test_irq_scenario(IRQ_TEST_SCENARIO_3);
if (err != CORE_TEST_ERRNO_SUCCESS) {
TEST_FAIL("Failed to execute IRQ test scenario 3.");
return;
}
- err = tfm_core_test_secure_irq_scenario(IRQ_TEST_SCENARIO_4);
+ err = tfm_core_test_irq_scenario(IRQ_TEST_SCENARIO_4);
if (err != CORE_TEST_ERRNO_SUCCESS) {
TEST_FAIL("Failed to execute IRQ test scenario 4.");
return;
}
+ err = tfm_core_test_irq_scenario(IRQ_TEST_SCENARIO_5);
+ if (err != CORE_TEST_ERRNO_SUCCESS) {
+ TEST_FAIL("Failed to execute IRQ test scenario 5.");
+ return;
+ }
+
ret->val = TEST_PASSED;
}
diff --git a/test/test_services/tfm_core_test/core_test_defs.h b/test/test_services/tfm_core_test/core_test_defs.h
index 48c9c08..6b8729b 100644
--- a/test/test_services/tfm_core_test/core_test_defs.h
+++ b/test/test_services/tfm_core_test/core_test_defs.h
@@ -86,10 +86,12 @@
IRQ_TEST_SCENARIO_2,
IRQ_TEST_SCENARIO_3,
IRQ_TEST_SCENARIO_4,
+ IRQ_TEST_SCENARIO_5,
};
struct irq_test_execution_data_t {
volatile int32_t timer0_triggered;
+ volatile int32_t timer1_triggered;
};
/* Use lower 16 bits in return value for error code, upper 16 for line number
diff --git a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c
index 1d3e2bf..7fa0210 100644
--- a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c
+++ b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2.c
@@ -219,6 +219,7 @@
case IRQ_TEST_SCENARIO_2:
case IRQ_TEST_SCENARIO_3:
case IRQ_TEST_SCENARIO_4:
+ case IRQ_TEST_SCENARIO_5:
/* No action is necessary*/
break;
default:
@@ -269,6 +270,14 @@
case IRQ_TEST_SCENARIO_4:
/* No action is necessary*/
break;
+ case IRQ_TEST_SCENARIO_5:
+ if (current_execution_data->timer1_triggered) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+ while (!current_execution_data->timer1_triggered) {
+ ;
+ }
+ break;
default:
return CORE_TEST_ERRNO_INVALID_PARAMETER;
}
diff --git a/test/test_services/tfm_irq_test_service_1/tfm_irq_test_service_1.c b/test/test_services/tfm_irq_test_service_1/tfm_irq_test_service_1.c
index 334e4dc..373e6dc 100644
--- a/test/test_services/tfm_irq_test_service_1/tfm_irq_test_service_1.c
+++ b/test/test_services/tfm_irq_test_service_1/tfm_irq_test_service_1.c
@@ -64,6 +64,9 @@
case IRQ_TEST_SCENARIO_4:
tfm_plat_test_secure_timer_start();
break;
+ case IRQ_TEST_SCENARIO_5:
+ /* Do nothing */
+ break;
default:
return CORE_TEST_ERRNO_INVALID_PARAMETER;
}
@@ -112,6 +115,9 @@
}
psa_eoi(SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ);
break;
+ case IRQ_TEST_SCENARIO_5:
+ /* nothing to do*/
+ break;
default:
return CORE_TEST_ERRNO_INVALID_PARAMETER;
}
@@ -170,6 +176,10 @@
case IRQ_TEST_SCENARIO_4:
/* nothing to do*/
break;
+ case IRQ_TEST_SCENARIO_5:
+ halt_test_execution();
+ /* No secure interrups are used in this scenario */
+ break;
default:
halt_test_execution();
break;
@@ -241,6 +251,10 @@
*/
halt_test_execution();
break;
+ case IRQ_TEST_SCENARIO_5:
+ /* No secure interrups are used in this scenario */
+ halt_test_execution();
+ break;
default:
halt_test_execution();
break;
@@ -293,6 +307,7 @@
return;
case IRQ_TEST_SCENARIO_1:
case IRQ_TEST_SCENARIO_2:
+ case IRQ_TEST_SCENARIO_5:
/* nothing to do, return success */
psa_reply(msg->handle, CORE_TEST_ERRNO_SUCCESS);
return;