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/docs/user_guides/services/core_test_services_integration_guide.rst b/docs/user_guides/services/core_test_services_integration_guide.rst
index a8f6b8c..c3f213f 100644
--- a/docs/user_guides/services/core_test_services_integration_guide.rst
+++ b/docs/user_guides/services/core_test_services_integration_guide.rst
@@ -54,6 +54,44 @@
or all of the functions, by returning the values expected by the test cases,
without actually executing the action expected by the test.
+******************
+IRQ handling tests
+******************
+
+The IRQ handling test currently tests the following scenarios:
+
+- NS code execution is interrupted by a secure IRQ (``IRQ_TEST_SCENARIO_1``)
+- S code execution is interrupted by a secure IRQ, The handler is not the
+ interrupted service (``IRQ_TEST_SCENARIO_2``)
+- 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 following test services participate in the test execution:
+
+- ``TFM_IRQ_TEST_1`` has the role of the interrupted partition with the IRQ
+ handler
+- ``TFM_SP_CORE_TEST_2`` has the role of the interrupted partition without the
+ IRQ handler
+
+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``
+
+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.
+
--------------
*Copyright (c) 2019, Arm Limited. All rights reserved.*
\ No newline at end of file
diff --git a/interface/include/tfm_veneers.h b/interface/include/tfm_veneers.h
index 71bc9e8..92856b3 100644
--- a/interface/include/tfm_veneers.h
+++ b/interface/include/tfm_veneers.h
@@ -100,6 +100,8 @@
psa_status_t tfm_spm_core_test_2_sfn_invert_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_spm_core_test_2_check_caller_client_id_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
psa_status_t tfm_spm_core_test_2_get_every_second_byte_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_spm_core_test_2_prepare_test_scenario_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+psa_status_t tfm_spm_core_test_2_execute_test_scenario_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
#endif /* TFM_PARTITION_TEST_CORE */
#ifdef TFM_PARTITION_TEST_SECURE_SERVICES
@@ -115,6 +117,12 @@
/******** TFM_SP_IPC_CLIENT_TEST ********/
#endif /* TFM_PARTITION_TEST_CORE_IPC */
+#ifdef TFM_PARTITION_TEST_CORE
+/******** TFM_IRQ_TEST_1 ********/
+psa_status_t tfm_spm_irq_test_1_prepare_test_scenario_veneer(psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);
+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_PARTITION_TEST_CORE */
+
#ifdef __cplusplus
}
#endif
diff --git a/platform/ext/common/armclang/tfm_common_s.sct b/platform/ext/common/armclang/tfm_common_s.sct
index 27f539b..24bdbae 100644
--- a/platform/ext/common/armclang/tfm_common_s.sct
+++ b/platform/ext/common/armclang/tfm_common_s.sct
@@ -136,6 +136,14 @@
}
#endif /* TFM_PARTITION_TEST_CORE_IPC */
+#ifdef TFM_PARTITION_TEST_CORE
+ TFM_IRQ_TEST_1 +0 ALIGN 32 {
+ *tfm_irq_test_service_1.* (+RO)
+ *timer_cmsdk* (+RO)
+ *(TFM_IRQ_TEST_1_ATTR_FN)
+ }
+#endif /* TFM_PARTITION_TEST_CORE */
+
/*
* This empty, zero long execution region is here to mark the end address
* of APP RoT code.
@@ -343,6 +351,20 @@
#endif
#endif /* TFM_PARTITION_TEST_CORE_IPC */
+#ifdef TFM_PARTITION_TEST_CORE
+ TFM_IRQ_TEST_1_DATA +0 ALIGN 32 {
+ *tfm_irq_test_service_1.* (+RW +ZI)
+ *timer_cmsdk* (+RW +ZI)
+ *(TFM_IRQ_TEST_1_ATTR_RW)
+ *(TFM_IRQ_TEST_1_ATTR_ZI)
+ }
+
+#if defined (TFM_PSA_API) || (TFM_LVL != 1)
+ TFM_IRQ_TEST_1_STACK +0 ALIGN 128 EMPTY 0x0400 {
+ }
+#endif
+#endif /* TFM_PARTITION_TEST_CORE */
+
/*
* This empty, zero long execution region is here to mark the end address
* of APP 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 b287726..c17135a 100644
--- a/platform/ext/common/gcc/tfm_common_s.ld
+++ b/platform/ext/common/gcc/tfm_common_s.ld
@@ -113,6 +113,11 @@
LONG (ADDR(.TFM_SP_IPC_CLIENT_TEST_DATA))
LONG (SIZEOF(.TFM_SP_IPC_CLIENT_TEST_DATA))
#endif /* TFM_PARTITION_TEST_CORE_IPC */
+#ifdef TFM_PARTITION_TEST_CORE
+ LONG (LOADADDR(.TFM_IRQ_TEST_1_DATA))
+ LONG (ADDR(.TFM_IRQ_TEST_1_DATA))
+ LONG (SIZEOF(.TFM_IRQ_TEST_1_DATA))
+#endif /* TFM_PARTITION_TEST_CORE */
__copy_table_end__ = .;
} > FLASH
@@ -204,6 +209,14 @@
LONG (SIZEOF(.TFM_SP_IPC_CLIENT_TEST_STACK))
#endif
#endif /* TFM_PARTITION_TEST_CORE_IPC */
+#ifdef TFM_PARTITION_TEST_CORE
+ LONG (ADDR(.TFM_IRQ_TEST_1_BSS))
+ LONG (SIZEOF(.TFM_IRQ_TEST_1_BSS))
+#if defined(TFM_PSA_API) || (TFM_LVL != 1)
+ LONG (ADDR(.TFM_IRQ_TEST_1_STACK))
+ LONG (SIZEOF(.TFM_IRQ_TEST_1_STACK))
+#endif
+#endif /* TFM_PARTITION_TEST_CORE */
#if !defined(TFM_PSA_API)
LONG (ADDR(.TFM_UNPRIV_SCRATCH))
LONG (SIZEOF(.TFM_UNPRIV_SCRATCH))
@@ -398,6 +411,22 @@
Image$$TFM_SP_IPC_CLIENT_TEST$$Limit = ADDR(.TFM_SP_IPC_CLIENT_TEST) + SIZEOF(.TFM_SP_IPC_CLIENT_TEST);
#endif /* TFM_PARTITION_TEST_CORE_IPC */
+#ifdef TFM_PARTITION_TEST_CORE
+ .TFM_IRQ_TEST_1 : ALIGN(32)
+ {
+ *tfm_irq_test_service_1.*(.text*)
+ *tfm_irq_test_service_1.*(.rodata*)
+ *timer_cmsdk*(.text*)
+ *timer_cmsdk*(.rodata*)
+ *(TFM_IRQ_TEST_1_ATTR_FN)
+ . = ALIGN(32);
+ } > FLASH
+ Image$$TFM_IRQ_TEST_1$$RO$$Base = ADDR(.TFM_IRQ_TEST_1);
+ Image$$TFM_IRQ_TEST_1$$RO$$Limit = ADDR(.TFM_IRQ_TEST_1) + SIZEOF(.TFM_IRQ_TEST_1);
+ Image$$TFM_IRQ_TEST_1$$Base = ADDR(.TFM_IRQ_TEST_1);
+ Image$$TFM_IRQ_TEST_1$$Limit = ADDR(.TFM_IRQ_TEST_1) + SIZEOF(.TFM_IRQ_TEST_1);
+#endif /* TFM_PARTITION_TEST_CORE */
+
/**** APPLICATION RoT RO part (CODE + RODATA) end here */
Image$$TFM_APP_CODE_END$$Base = .;
@@ -893,6 +922,42 @@
#endif /* TFM_PARTITION_TEST_CORE_IPC */
+#ifdef TFM_PARTITION_TEST_CORE
+ .TFM_IRQ_TEST_1_DATA : ALIGN(32)
+ {
+ *tfm_irq_test_service_1.*(.data*)
+ *timer_cmsdk*(.data*)
+ *(TFM_IRQ_TEST_1_ATTR_RW)
+ . = ALIGN(32);
+ } > RAM AT> FLASH
+ Image$$TFM_IRQ_TEST_1_DATA$$RW$$Base = ADDR(.TFM_IRQ_TEST_1_DATA);
+ Image$$TFM_IRQ_TEST_1_DATA$$RW$$Limit = ADDR(.TFM_IRQ_TEST_1_DATA) + SIZEOF(.TFM_IRQ_TEST_1_DATA);
+
+ .TFM_IRQ_TEST_1_BSS : ALIGN(32)
+ {
+ start_of_TFM_IRQ_TEST_1 = .;
+ *tfm_irq_test_service_1.*(.bss*)
+ *tfm_irq_test_service_1.*(COMMON)
+ *timer_cmsdk*(.bss*)
+ *timer_cmsdk*(COMMON)
+ *(TFM_IRQ_TEST_1_ATTR_ZI)
+ . += (. - start_of_TFM_IRQ_TEST_1) ? 0 : 4;
+ . = ALIGN(32);
+ } > RAM AT> RAM
+ Image$$TFM_IRQ_TEST_1_DATA$$ZI$$Base = ADDR(.TFM_IRQ_TEST_1_BSS);
+ Image$$TFM_IRQ_TEST_1_DATA$$ZI$$Limit = ADDR(.TFM_IRQ_TEST_1_BSS) + SIZEOF(.TFM_IRQ_TEST_1_BSS);
+
+#if defined (TFM_PSA_API) || (TFM_LVL != 1)
+ .TFM_IRQ_TEST_1_STACK : ALIGN(128)
+ {
+ . += 0x0400;
+ } > RAM
+ Image$$TFM_IRQ_TEST_1_STACK$$ZI$$Base = ADDR(.TFM_IRQ_TEST_1_STACK);
+ Image$$TFM_IRQ_TEST_1_STACK$$ZI$$Limit = ADDR(.TFM_IRQ_TEST_1_STACK) + SIZEOF(.TFM_IRQ_TEST_1_STACK);
+#endif
+
+#endif /* TFM_PARTITION_TEST_CORE */
+
/**** APPLICATION RoT DATA end here */
Image$$TFM_APP_RW_STACK_END$$Base = .;
diff --git a/platform/ext/target/mps2/an519/armclang/startup_cmsdk_mps2_an519_s.s b/platform/ext/target/mps2/an519/armclang/startup_cmsdk_mps2_an519_s.s
index 363d83e..2bcbb67 100644
--- a/platform/ext/target/mps2/an519/armclang/startup_cmsdk_mps2_an519_s.s
+++ b/platform/ext/target/mps2/an519/armclang/startup_cmsdk_mps2_an519_s.s
@@ -58,7 +58,7 @@
DCD NONSEC_WATCHDOG_RESET_Handler ; - 0 Non-Secure Watchdog Reset Handler
DCD NONSEC_WATCHDOG_Handler ; - 1 Non-Secure Watchdog Handler
DCD S32K_TIMER_Handler ; - 2 S32K Timer Handler
- DCD TIMER0_Handler ; - 3 TIMER 0 Handler
+ DCD TFM_TIMER0_IRQ_Handler ; - 3 TIMER 0 Handler
DCD TIMER1_Handler ; - 4 TIMER 1 Handler
DCD DUALTIMER_Handler ; - 5 Dual Timer Handler
DCD 0 ; Reserved - 6
@@ -219,7 +219,7 @@
EXPORT NONSEC_WATCHDOG_RESET_Handler [WEAK] ; - 0 Non-Secure Watchdog Reset Handler
EXPORT NONSEC_WATCHDOG_Handler [WEAK] ; - 1 Non-Secure Watchdog Handler
EXPORT S32K_TIMER_Handler [WEAK] ; - 2 S32K Timer Handler
- EXPORT TIMER0_Handler [WEAK] ; - 3 TIMER 0 Handler
+ EXPORT TFM_TIMER0_IRQ_Handler [WEAK] ; - 3 TIMER 0 Handler
EXPORT TIMER1_Handler [WEAK] ; - 4 TIMER 1 Handler
EXPORT DUALTIMER_Handler [WEAK] ; - 5 Dual Timer Handler
; External Interrupts
@@ -292,7 +292,7 @@
NONSEC_WATCHDOG_RESET_Handler ; - 0 Non-Secure Watchdog Reset Handler
NONSEC_WATCHDOG_Handler ; - 1 Non-Secure Watchdog Handler
S32K_TIMER_Handler ; - 2 S32K Timer Handler
-TIMER0_Handler ; - 3 TIMER 0 Handler
+TFM_TIMER0_IRQ_Handler ; - 3 TIMER 0 Handler
TIMER1_Handler ; - 4 TIMER 1 Handler
DUALTIMER_Handler ; - 5 Dual Timer Handler
; External Interrupts
diff --git a/platform/ext/target/mps2/an519/gcc/startup_cmsdk_mps2_an519_s.S b/platform/ext/target/mps2/an519/gcc/startup_cmsdk_mps2_an519_s.S
index fefc1cc..e7302b1 100644
--- a/platform/ext/target/mps2/an519/gcc/startup_cmsdk_mps2_an519_s.S
+++ b/platform/ext/target/mps2/an519/gcc/startup_cmsdk_mps2_an519_s.S
@@ -47,7 +47,7 @@
.long NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */
.long NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */
.long S32K_TIMER_Handler /* 2: S32K Timer Handler */
- .long TIMER0_Handler /* 3: TIMER 0 Handler */
+ .long TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */
.long TIMER1_Handler /* 4: TIMER 1 Handler */
.long DUALTIMER_Handler /* 5: Dual Timer Handler */
.long 0 /* 6: Reserved */
@@ -344,7 +344,7 @@
def_irq_handler NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */
def_irq_handler NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */
def_irq_handler S32K_TIMER_Handler /* 2: S32K Timer Handler */
- def_irq_handler TIMER0_Handler /* 3: TIMER 0 Handler */
+ def_irq_handler TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */
def_irq_handler TIMER1_Handler /* 4: TIMER 1 Handler */
def_irq_handler DUALTIMER_Handler /* 5: Dual Timer Handler */
def_irq_handler MPC_Handler /* 9 MPC Combined (Secure) Handler */
diff --git a/platform/ext/target/mps2/an519/retarget/platform_retarget_dev.c b/platform/ext/target/mps2/an519/retarget/platform_retarget_dev.c
index 1540586..2e48657 100644
--- a/platform/ext/target/mps2/an519/retarget/platform_retarget_dev.c
+++ b/platform/ext/target/mps2/an519/retarget/platform_retarget_dev.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018 ARM Limited
+ * Copyright (c) 2016-2019 Arm Limited
*
* Licensed under the Apache License Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
#include "platform_retarget_dev.h"
#include "platform_retarget.h"
#include "system_cmsdk_mps2_an519.h"
+#include "platform/include/tfm_plat_defs.h"
/* ARM UART driver structures */
#ifdef ARM_UART0_S
@@ -300,12 +301,16 @@
/* CMSDK Timer driver structures */
#ifdef CMSDK_TIMER0_S
-static const struct cmsdk_timer_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S = {
- .base = CMSDK_TIMER0_BASE_S};
-static struct cmsdk_timer_dev_data_t CMSDK_TIMER0_DEV_DATA_S = {
- .is_initialized = 0};
-struct cmsdk_timer_dev_t CMSDK_TIMER0_DEV_S = {&(CMSDK_TIMER0_DEV_CFG_S),
- &(CMSDK_TIMER0_DEV_DATA_S)};
+static const struct cmsdk_timer_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S
+ TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {.base = CMSDK_TIMER0_BASE_S};
+static struct cmsdk_timer_dev_data_t CMSDK_TIMER0_DEV_DATA_S
+ TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {.is_initialized = 0};
+
+struct cmsdk_timer_dev_t CMSDK_TIMER0_DEV_S
+ TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {&(CMSDK_TIMER0_DEV_CFG_S), &(CMSDK_TIMER0_DEV_DATA_S)};
#endif
#ifdef CMSDK_TIMER0_NS
static const struct cmsdk_timer_dev_cfg_t CMSDK_TIMER0_DEV_CFG_NS = {
diff --git a/platform/ext/target/mps2/an521/armclang/startup_cmsdk_mps2_an521_s.s b/platform/ext/target/mps2/an521/armclang/startup_cmsdk_mps2_an521_s.s
index 0ee9e00..f969533 100644
--- a/platform/ext/target/mps2/an521/armclang/startup_cmsdk_mps2_an521_s.s
+++ b/platform/ext/target/mps2/an521/armclang/startup_cmsdk_mps2_an521_s.s
@@ -55,7 +55,7 @@
DCD NONSEC_WATCHDOG_RESET_Handler ; - 0 Non-Secure Watchdog Reset Handler
DCD NONSEC_WATCHDOG_Handler ; - 1 Non-Secure Watchdog Handler
DCD S32K_TIMER_Handler ; - 2 S32K Timer Handler
- DCD TIMER0_Handler ; - 3 TIMER 0 Handler
+ DCD TFM_TIMER0_IRQ_Handler ; - 3 TIMER 0 Handler
DCD TIMER1_Handler ; - 4 TIMER 1 Handler
DCD DUALTIMER_Handler ; - 5 Dual Timer Handler
DCD 0 ; Reserved - 6
@@ -238,7 +238,7 @@
EXPORT NONSEC_WATCHDOG_RESET_Handler [WEAK] ; - 0 Non-Secure Watchdog Reset Handler
EXPORT NONSEC_WATCHDOG_Handler [WEAK] ; - 1 Non-Secure Watchdog Handler
EXPORT S32K_TIMER_Handler [WEAK] ; - 2 S32K Timer Handler
- EXPORT TIMER0_Handler [WEAK] ; - 3 TIMER 0 Handler
+ EXPORT TFM_TIMER0_IRQ_Handler [WEAK] ; - 3 TIMER 0 Handler
EXPORT TIMER1_Handler [WEAK] ; - 4 TIMER 1 Handler
EXPORT DUALTIMER_Handler [WEAK] ; - 5 Dual Timer Handler
; External Interrupts
@@ -311,7 +311,7 @@
NONSEC_WATCHDOG_RESET_Handler ; - 0 Non-Secure Watchdog Reset Handler
NONSEC_WATCHDOG_Handler ; - 1 Non-Secure Watchdog Handler
S32K_TIMER_Handler ; - 2 S32K Timer Handler
-TIMER0_Handler ; - 3 TIMER 0 Handler
+TFM_TIMER0_IRQ_Handler ; - 3 TIMER 0 Handler
TIMER1_Handler ; - 4 TIMER 1 Handler
DUALTIMER_Handler ; - 5 Dual Timer Handler
; External Interrupts
diff --git a/platform/ext/target/mps2/an521/gcc/startup_cmsdk_mps2_an521_s.S b/platform/ext/target/mps2/an521/gcc/startup_cmsdk_mps2_an521_s.S
index 07fd8f8..ccac392 100644
--- a/platform/ext/target/mps2/an521/gcc/startup_cmsdk_mps2_an521_s.S
+++ b/platform/ext/target/mps2/an521/gcc/startup_cmsdk_mps2_an521_s.S
@@ -47,7 +47,7 @@
.long NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */
.long NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */
.long S32K_TIMER_Handler /* 2: S32K Timer Handler */
- .long TIMER0_Handler /* 3: TIMER 0 Handler */
+ .long TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */
.long TIMER1_Handler /* 4: TIMER 1 Handler */
.long DUALTIMER_Handler /* 5: Dual Timer Handler */
.long MHU0_Handler /* 6: Message Handling Unit 0 */
@@ -310,7 +310,7 @@
def_irq_handler NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */
def_irq_handler NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */
def_irq_handler S32K_TIMER_Handler /* 2: S32K Timer Handler */
- def_irq_handler TIMER0_Handler /* 3: TIMER 0 Handler */
+ def_irq_handler TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */
def_irq_handler TIMER1_Handler /* 4: TIMER 1 Handler */
def_irq_handler DUALTIMER_Handler /* 5: Dual Timer Handler */
def_irq_handler MHU0_Handler /* 6: Message Handling Unit 0 */
diff --git a/platform/ext/target/mps2/an521/retarget/platform_retarget_dev.c b/platform/ext/target/mps2/an521/retarget/platform_retarget_dev.c
index a7c70da..a281960 100644
--- a/platform/ext/target/mps2/an521/retarget/platform_retarget_dev.c
+++ b/platform/ext/target/mps2/an521/retarget/platform_retarget_dev.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2016-2018 ARM Limited
+ * Copyright (c) 2016-2019 Arm Limited
*
* Licensed under the Apache License Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
#include "platform_retarget_dev.h"
#include "platform_retarget.h"
#include "system_cmsdk_mps2_an521.h"
+#include "platform/include/tfm_plat_defs.h"
/* ARM UART driver structures */
#ifdef ARM_UART0_S
@@ -300,12 +301,16 @@
/* CMSDK Timer driver structures */
#ifdef CMSDK_TIMER0_S
-static const struct cmsdk_timer_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S = {
- .base = CMSDK_TIMER0_BASE_S};
-static struct cmsdk_timer_dev_data_t CMSDK_TIMER0_DEV_DATA_S = {
- .is_initialized = 0};
-struct cmsdk_timer_dev_t CMSDK_TIMER0_DEV_S = {&(CMSDK_TIMER0_DEV_CFG_S),
- &(CMSDK_TIMER0_DEV_DATA_S)};
+static const struct cmsdk_timer_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S
+ TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {.base = CMSDK_TIMER0_BASE_S};
+static struct cmsdk_timer_dev_data_t CMSDK_TIMER0_DEV_DATA_S
+ TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {.is_initialized = 0};
+
+struct cmsdk_timer_dev_t CMSDK_TIMER0_DEV_S
+ TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {&(CMSDK_TIMER0_DEV_CFG_S), &(CMSDK_TIMER0_DEV_DATA_S)};
#endif
#ifdef CMSDK_TIMER0_NS
static const struct cmsdk_timer_dev_cfg_t CMSDK_TIMER0_DEV_CFG_NS = {
diff --git a/platform/ext/target/mps3/an524/device/source/armclang/startup_cmsdk_mps3_an524_s.s b/platform/ext/target/mps3/an524/device/source/armclang/startup_cmsdk_mps3_an524_s.s
index 84d4d9d..ff9a8d3 100644
--- a/platform/ext/target/mps3/an524/device/source/armclang/startup_cmsdk_mps3_an524_s.s
+++ b/platform/ext/target/mps3/an524/device/source/armclang/startup_cmsdk_mps3_an524_s.s
@@ -56,7 +56,7 @@
DCD NONSEC_WATCHDOG_RESET_Handler ; 0 Non-Secure Watchdog Reset Handler
DCD NONSEC_WATCHDOG_Handler ; 1 Non-Secure Watchdog Handler
DCD S32K_TIMER_Handler ; 2 S32K Timer Handler
- DCD TIMER0_Handler ; 3 TIMER 0 Handler
+ DCD TFM_TIMER0_IRQ_Handler ; 3 TIMER 0 Handler
DCD TIMER1_Handler ; 4 TIMER 1 Handler
DCD DUALTIMER_Handler ; 5 Dual Timer Handler
DCD 0 ; 6 Reserved
@@ -289,7 +289,7 @@
; Reset Handler
EXPORT NONSEC_WATCHDOG_Handler [WEAK] ; 1 Non-Secure Watchdog Handler
EXPORT S32K_TIMER_Handler [WEAK] ; 2 S32K Timer Handler
- EXPORT TIMER0_Handler [WEAK] ; 3 TIMER 0 Handler
+ EXPORT TFM_TIMER0_IRQ_Handler [WEAK] ; 3 TIMER 0 Handler
EXPORT TIMER1_Handler [WEAK] ; 4 TIMER 1 Handler
EXPORT DUALTIMER_Handler [WEAK] ; 5 Dual Timer Handler
EXPORT MHU0_Handler [WEAK] ; 6 Message Handling Unit 0
@@ -405,7 +405,7 @@
NONSEC_WATCHDOG_RESET_Handler ; 0 Non-Secure Watchdog Reset Handler
NONSEC_WATCHDOG_Handler ; 1 Non-Secure Watchdog Handler
S32K_TIMER_Handler ; 2 S32K Timer Handler
-TIMER0_Handler ; 3 TIMER 0 Handler
+TFM_TIMER0_IRQ_Handler ; 3 TIMER 0 Handler
TIMER1_Handler ; 4 TIMER 1 Handler
DUALTIMER_Handler ; 5 Dual Timer Handler
MHU0_Handler ; 6 Message Handling Unit 0
diff --git a/platform/ext/target/mps3/an524/device/source/device_definition.c b/platform/ext/target/mps3/an524/device/source/device_definition.c
index 3f1e81e..7c86c3a 100644
--- a/platform/ext/target/mps3/an524/device/source/device_definition.c
+++ b/platform/ext/target/mps3/an524/device/source/device_definition.c
@@ -25,6 +25,7 @@
#include "device_definition.h"
#include "platform_base_address.h"
+#include "platform/include/tfm_plat_defs.h"
/* UART CMSDK driver structures */
#ifdef UART0_CMSDK_S
@@ -342,16 +343,19 @@
/* CMSDK Timer driver structures */
#ifdef CMSDK_TIMER0_S
-static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S = {
- .base = CMSDK_TIMER0_BASE_S
-};
-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)
-};
+static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S
+ TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_IRQ_TEST_1") = {
+ .base = CMSDK_TIMER0_BASE_S
+ };
+static struct timer_cmsdk_dev_data_t CMSDK_TIMER0_DEV_DATA_S
+ TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_IRQ_TEST_1") = {
+ .is_initialized = 0
+ };
+struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV_S
+ TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_IRQ_TEST_1") = {
+ &(CMSDK_TIMER0_DEV_CFG_S),
+ &(CMSDK_TIMER0_DEV_DATA_S)
+ };
#endif
#ifdef CMSDK_TIMER0_NS
static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_NS = {
diff --git a/platform/ext/target/mps3/an524/device/source/gcc/startup_cmsdk_mps3_an524_s.S b/platform/ext/target/mps3/an524/device/source/gcc/startup_cmsdk_mps3_an524_s.S
index d7be1ab..6e6c976 100644
--- a/platform/ext/target/mps3/an524/device/source/gcc/startup_cmsdk_mps3_an524_s.S
+++ b/platform/ext/target/mps3/an524/device/source/gcc/startup_cmsdk_mps3_an524_s.S
@@ -48,7 +48,7 @@
.long NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */
.long NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */
.long S32K_TIMER_Handler /* 2: S32K Timer Handler */
- .long TIMER0_Handler /* 3: TIMER 0 Handler */
+ .long TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */
.long TIMER1_Handler /* 4: TIMER 1 Handler */
.long DUALTIMER_Handler /* 5: Dual Timer Handler */
.long MHU0_Handler /* 6: Message Handling Unit 0 */
@@ -343,7 +343,7 @@
def_irq_handler NONSEC_WATCHDOG_RESET_Handler /* 0: Non-Secure Watchdog Reset Handler */
def_irq_handler NONSEC_WATCHDOG_Handler /* 1: Non-Secure Watchdog Handler */
def_irq_handler S32K_TIMER_Handler /* 2: S32K Timer Handler */
- def_irq_handler TIMER0_Handler /* 3: TIMER 0 Handler */
+ def_irq_handler TFM_TIMER0_IRQ_Handler /* 3: TIMER 0 Handler */
def_irq_handler TIMER1_Handler /* 4: TIMER 1 Handler */
def_irq_handler DUALTIMER_Handler /* 5: Dual Timer Handler */
def_irq_handler MHU0_Handler /* 6: Message Handling Unit 0 */
diff --git a/platform/ext/target/musca_a/Device/Source/armclang/startup_cmsdk_musca_s.s b/platform/ext/target/musca_a/Device/Source/armclang/startup_cmsdk_musca_s.s
index 263a0ae..547544a 100644
--- a/platform/ext/target/musca_a/Device/Source/armclang/startup_cmsdk_musca_s.s
+++ b/platform/ext/target/musca_a/Device/Source/armclang/startup_cmsdk_musca_s.s
@@ -56,8 +56,8 @@
DCD NS_WATCHDOG_RESET_IRQHandler ; 0: Non-Secure Watchdog Reset Request Interrupt
DCD NS_WATCHDOG_IRQHandler ; 1: Non-Secure Watchdog Interrupt
DCD S32K_TIMER_IRQHandler ; 2: S32K Timer Interrupt
- DCD TIMER0_Handler ; 3: CMSDK Timer 0 Interrupt
- DCD TIMER1_Handler ; 4: CMSDK Timer 1 Interrupt
+ DCD TFM_TIMER0_IRQ_Handler ; 3: CMSDK Timer 0 Interrupt
+ DCD TIMER1_IRQHandler ; 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
@@ -178,8 +178,8 @@
Default_Handler NS_WATCHDOG_RESET_IRQHandler
Default_Handler NS_WATCHDOG_IRQHandler
Default_Handler S32K_TIMER_IRQHandler
- Default_Handler TIMER0_Handler
- Default_Handler TIMER1_Handler
+ Default_Handler TFM_TIMER0_IRQ_Handler
+ Default_Handler TIMER1_IRQHandler
Default_Handler DUALTIMER_IRQHandler
Default_Handler MHU0_IRQHandler
Default_Handler MHU1_IRQHandler
diff --git a/platform/ext/target/musca_a/Device/Source/device_definition.c b/platform/ext/target/musca_a/Device/Source/device_definition.c
index 5b93b46..f65425b 100644
--- a/platform/ext/target/musca_a/Device/Source/device_definition.c
+++ b/platform/ext/target/musca_a/Device/Source/device_definition.c
@@ -395,12 +395,15 @@
/* CMSDK Timers driver structures */
#ifdef CMSDK_TIMER0_S
-static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S = {
- .base = MUSCA_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)};
+static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S
+ TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {.base = MUSCA_CMSDK_TIMER0_S_BASE};
+static struct timer_cmsdk_dev_data_t CMSDK_TIMER0_DEV_DATA_S
+ TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {.is_initialized = 0};
+struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV_S
+ TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {&(CMSDK_TIMER0_DEV_CFG_S), &(CMSDK_TIMER0_DEV_DATA_S)};
#endif
#ifdef CMSDK_TIMER0_NS
static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_NS = {
diff --git a/platform/ext/target/musca_a/Device/Source/gcc/startup_cmsdk_musca_s.S b/platform/ext/target/musca_a/Device/Source/gcc/startup_cmsdk_musca_s.S
index 37ed397..f3b5d91 100644
--- a/platform/ext/target/musca_a/Device/Source/gcc/startup_cmsdk_musca_s.S
+++ b/platform/ext/target/musca_a/Device/Source/gcc/startup_cmsdk_musca_s.S
@@ -45,8 +45,8 @@
.long NS_WATCHDOG_RESET_IRQHandler /* 0: Non-Secure Watchdog Reset Request Interrupt */
.long NS_WATCHDOG_IRQHandler /* 1: Non-Secure Watchdog Interrupt */
.long S32K_TIMER_IRQHandler /* 2: S32K Timer Interrupt */
- .long TIMER0_Handler /* 3: CMSDK Timer 0 Interrupt */
- .long TIMER1_Handler /* 4: CMSDK Timer 1 Interrupt */
+ .long TFM_TIMER0_IRQ_Handler /* 3: CMSDK Timer 0 Interrupt */
+ .long TIMER1_IRQHandler /* 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 */
@@ -290,8 +290,8 @@
def_irq_handler NS_WATCHDOG_RESET_IRQHandler /* 0: Non-Secure Watchdog Reset Request Interrupt */
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_Handler /* 3: CMSDK Timer 0 Interrupt */
- def_irq_handler TIMER1_Handler /* 4: CMSDK Timer 1 Interrupt */
+ def_irq_handler TFM_TIMER0_IRQ_Handler /* 3: CMSDK Timer 0 Interrupt */
+ def_irq_handler TIMER1_IRQHandler /* 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_s.s b/platform/ext/target/musca_b1/Device/Source/armclang/startup_cmsdk_musca_s.s
index f558489..fe00a7f 100644
--- a/platform/ext/target/musca_b1/Device/Source/armclang/startup_cmsdk_musca_s.s
+++ b/platform/ext/target/musca_b1/Device/Source/armclang/startup_cmsdk_musca_s.s
@@ -56,8 +56,8 @@
DCD NS_WATCHDOG_RESET_IRQHandler ; 0: Non-Secure Watchdog Reset Request Interrupt
DCD NS_WATCHDOG_IRQHandler ; 1: Non-Secure Watchdog Interrupt
DCD S32K_TIMER_IRQHandler ; 2: S32K Timer Interrupt
- DCD TIMER0_Handler ; 3: CMSDK Timer 0 Interrupt
- DCD TIMER1_Handler ; 4: CMSDK Timer 1 Interrupt
+ DCD TFM_TIMER0_IRQ_Handler ; 3: CMSDK Timer 0 Interrupt
+ DCD TIMER1_IRQHandler ; 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
@@ -178,8 +178,8 @@
Default_Handler NS_WATCHDOG_RESET_IRQHandler
Default_Handler NS_WATCHDOG_IRQHandler
Default_Handler S32K_TIMER_IRQHandler
- Default_Handler TIMER0_Handler
- Default_Handler TIMER1_Handler
+ Default_Handler TFM_TIMER0_IRQ_Handler
+ Default_Handler TIMER1_IRQHandler
Default_Handler DUALTIMER_IRQHandler
Default_Handler MHU0_IRQHandler
Default_Handler MHU1_IRQHandler
diff --git a/platform/ext/target/musca_b1/Device/Source/device_definition.c b/platform/ext/target/musca_b1/Device/Source/device_definition.c
index b942d29..c392f1c 100644
--- a/platform/ext/target/musca_b1/Device/Source/device_definition.c
+++ b/platform/ext/target/musca_b1/Device/Source/device_definition.c
@@ -369,12 +369,15 @@
/** CMSDK Timers driver structures */
#ifdef CMSDK_TIMER0_S
-static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S = {
- .base = MUSCA_B1_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)};
+static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_S
+ TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {.base = MUSCA_B1_CMSDK_TIMER0_S_BASE};
+static struct timer_cmsdk_dev_data_t CMSDK_TIMER0_DEV_DATA_S
+ TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {.is_initialized = 0};
+struct timer_cmsdk_dev_t CMSDK_TIMER0_DEV_S
+ TFM_LINK_SET_RW_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
+ = {&(CMSDK_TIMER0_DEV_CFG_S), &(CMSDK_TIMER0_DEV_DATA_S)};
#endif
#ifdef CMSDK_TIMER0_NS
static const struct timer_cmsdk_dev_cfg_t CMSDK_TIMER0_DEV_CFG_NS = {
diff --git a/platform/ext/target/musca_b1/Device/Source/gcc/startup_cmsdk_musca_s.S b/platform/ext/target/musca_b1/Device/Source/gcc/startup_cmsdk_musca_s.S
index 37ed397..f3b5d91 100644
--- a/platform/ext/target/musca_b1/Device/Source/gcc/startup_cmsdk_musca_s.S
+++ b/platform/ext/target/musca_b1/Device/Source/gcc/startup_cmsdk_musca_s.S
@@ -45,8 +45,8 @@
.long NS_WATCHDOG_RESET_IRQHandler /* 0: Non-Secure Watchdog Reset Request Interrupt */
.long NS_WATCHDOG_IRQHandler /* 1: Non-Secure Watchdog Interrupt */
.long S32K_TIMER_IRQHandler /* 2: S32K Timer Interrupt */
- .long TIMER0_Handler /* 3: CMSDK Timer 0 Interrupt */
- .long TIMER1_Handler /* 4: CMSDK Timer 1 Interrupt */
+ .long TFM_TIMER0_IRQ_Handler /* 3: CMSDK Timer 0 Interrupt */
+ .long TIMER1_IRQHandler /* 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 */
@@ -290,8 +290,8 @@
def_irq_handler NS_WATCHDOG_RESET_IRQHandler /* 0: Non-Secure Watchdog Reset Request Interrupt */
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_Handler /* 3: CMSDK Timer 0 Interrupt */
- def_irq_handler TIMER1_Handler /* 4: CMSDK Timer 1 Interrupt */
+ def_irq_handler TFM_TIMER0_IRQ_Handler /* 3: CMSDK Timer 0 Interrupt */
+ def_irq_handler TIMER1_IRQHandler /* 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/include/tfm_plat_test.h b/platform/include/tfm_plat_test.h
index c3d7317..513134d 100644
--- a/platform/include/tfm_plat_test.h
+++ b/platform/include/tfm_plat_test.h
@@ -54,11 +54,13 @@
* the timer should be long enough so that the test service can go to the state
* where it starts waiting for the interrupt.
*/
+TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
void tfm_plat_test_secure_timer_start(void);
/**
* \brief Stops the Secure timer and clears the timer interrupt.
*/
+TFM_LINK_SET_RO_IN_PARTITION_SECTION("TFM_IRQ_TEST_1")
void tfm_plat_test_secure_timer_stop(void);
/**
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__ */
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 9953613..945e925 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -46,9 +46,11 @@
if (CORE_TEST_INTERACTIVE OR CORE_TEST_POSITIVE)
set(ENABLE_CORE_TESTS True)
set(ENABLE_CORE_TESTS_2 True)
+ set(ENABLE_IRQ_TEST_SERVICES True)
else()
set(ENABLE_CORE_TESTS False)
set(ENABLE_CORE_TESTS_2 False)
+ set(ENABLE_IRQ_TEST_SERVICES False)
endif()
set(ENABLE_SECURE_STORAGE_SERVICE_TESTS TRUE)
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 320b8fb..08f11a4 100644
--- a/test/suites/core/non_secure/core_ns_positive_testsuite.c
+++ b/test/suites/core/non_secure/core_ns_positive_testsuite.c
@@ -40,6 +40,7 @@
static void tfm_core_test_spm_request(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 struct test_t core_tests[] = {
CORE_TEST_DESCRIPTION(CORE_TEST_ID_NS_THREAD, tfm_core_test_ns_thread,
@@ -52,6 +53,11 @@
CORE_TEST_DESCRIPTION(CORE_TEST_ID_MEMORY_PERMISSIONS,
tfm_core_test_permissions,
"Test secure service memory access permissions"),
+#endif /* TFM_PSA_API */
+CORE_TEST_DESCRIPTION(CORE_TEST_ID_SECURE_IRQ,
+ tfm_core_test_secure_irq,
+ "Test secure irq"),
+#ifndef TFM_PSA_API
CORE_TEST_DESCRIPTION(CORE_TEST_ID_MPU_ACCESS, tfm_core_test_mpu_access,
"Test secure service MPU accesses"),
#endif /* TFM_PSA_API */
@@ -420,6 +426,129 @@
ret->val = TEST_PASSED;
}
+static int32_t execute_test_scenario_ns(
+ enum irq_test_scenario_t test_scenario,
+ struct irq_test_execution_data_t *execution_data)
+{
+
+ switch (test_scenario) {
+ case IRQ_TEST_SCENARIO_NONE:
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ case IRQ_TEST_SCENARIO_1:
+ if (execution_data->timer0_triggered) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+ while (!execution_data->timer0_triggered) {
+ ;
+ }
+ break;
+ case IRQ_TEST_SCENARIO_2:
+ case IRQ_TEST_SCENARIO_3:
+ case IRQ_TEST_SCENARIO_4:
+ /* nothing to be done here */
+ break;
+ default:
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ return CORE_TEST_ERRNO_SUCCESS;
+}
+
+static int32_t tfm_core_test_secure_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;
+ uint32_t scenario = test_scenario;
+
+ psa_invec in_vec[] = {
+ {&scenario, sizeof(uint32_t)},
+ {&execution_data_address,
+ sizeof(struct irq_test_execution_data_t *)} };
+ int32_t err;
+
+#ifdef TFM_PSA_API
+ err = psa_test_common(SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SID,
+ SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_MIN_VER,
+ in_vec, 2, NULL, 0);
+#else
+ err = tfm_spm_irq_test_1_prepare_test_scenario_veneer(in_vec, 2, NULL, 0);
+#endif
+ if (err != CORE_TEST_ERRNO_SUCCESS) {
+ return err;
+ }
+
+#ifdef TFM_PSA_API
+ err = psa_test_common(SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SID,
+ SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_MIN_VER,
+ in_vec, 2, NULL, 0);
+#else
+ err = tfm_spm_core_test_2_prepare_test_scenario_veneer(in_vec, 2, NULL, 0);
+#endif
+ 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,
+ in_vec, 2, NULL, 0);
+#else
+ err = tfm_spm_irq_test_1_execute_test_scenario_veneer(in_vec, 1, NULL, 0);
+#endif
+ if (err != CORE_TEST_ERRNO_SUCCESS) {
+ return err;
+ }
+
+#ifdef TFM_PSA_API
+ err = psa_test_common(SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SID,
+ SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_MIN_VER,
+ in_vec, 2, NULL, 0);
+#else
+ err = tfm_spm_core_test_2_execute_test_scenario_veneer(in_vec, 1, NULL, 0);
+#endif
+ if (err != CORE_TEST_ERRNO_SUCCESS) {
+ return err;
+ }
+
+ err = execute_test_scenario_ns(test_scenario, &execution_data);
+ if (err != CORE_TEST_ERRNO_SUCCESS) {
+ return err;
+ }
+
+ return CORE_TEST_ERRNO_SUCCESS;
+}
+
+static void tfm_core_test_secure_irq(struct test_result_t *ret)
+{
+ int32_t err;
+
+ err = tfm_core_test_secure_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);
+ 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);
+ 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);
+ if (err != CORE_TEST_ERRNO_SUCCESS) {
+ TEST_FAIL("Failed to execute IRQ test scenario 4.");
+ return;
+ }
+
+ ret->val = TEST_PASSED;
+}
/*
* \brief Tests whether the initialisation of the service was successful.
diff --git a/test/test_services/CMakeLists.inc b/test/test_services/CMakeLists.inc
index d591ce6..cbfc572 100644
--- a/test/test_services/CMakeLists.inc
+++ b/test/test_services/CMakeLists.inc
@@ -38,6 +38,13 @@
list(APPEND ALL_SRC_C_S "${CORE_TEST_DIR}/tfm_core_test_2/tfm_ss_core_test_2.c")
endif()
+if (NOT DEFINED ENABLE_IRQ_TEST_SERVICES)
+ message(FATAL_ERROR "Incomplete build configuration: ENABLE_IRQ_TEST_SERVICES is undefined. ")
+elseif(ENABLE_IRQ_TEST_SERVICES)
+ list(APPEND ALL_SRC_C_S
+ "${CORE_TEST_DIR}/tfm_irq_test_service_1/tfm_irq_test_service_1.c")
+endif()
+
if (NOT DEFINED TFM_PARTITION_TEST_SECURE_SERVICES)
message(FATAL_ERROR "Incomplete build configuration: TFM_PARTITION_TEST_SECURE_SERVICES is undefined. ")
elseif (TFM_PARTITION_TEST_SECURE_SERVICES)
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 3a36619..c7a3ae1 100644
--- a/test/test_services/tfm_core_test/core_test_defs.h
+++ b/test/test_services/tfm_core_test/core_test_defs.h
@@ -15,6 +15,7 @@
#include <inttypes.h>
#include <limits.h>
#include "tfm_api.h"
+#include "secure_fw/core/tfm_core.h"
/* These definitions are used in symbols, only digits are permitted */
#define CORE_TEST_ID_NS_THREAD 1001
@@ -31,6 +32,7 @@
#define CORE_TEST_ID_SPM_REQUEST 1014
#define CORE_TEST_ID_IOVEC_SANITIZATION 1015
#define CORE_TEST_ID_OUTVEC_WRITE 1016
+#define CORE_TEST_ID_SECURE_IRQ 1017
#define CORE_TEST_ID_BLOCK 2001
#define SPM_CORE_TEST_INIT_SUCCESS_SID 0x00002100
@@ -64,10 +66,31 @@
#define SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SID 0x00002201
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SID 0x00002202
#define SPM_CORE_TEST_2_INVERT_SID 0x00002203
+#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SID 0x00002204
+#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SID 0x00002205
#define SPM_CORE_TEST_2_SLAVE_SERVICE_MIN_VER 0x0001
#define SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_MIN_VER 0x0001
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_MIN_VER 0x0001
#define SPM_CORE_TEST_2_INVERT_MIN_VER 0x0001
+#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_MIN_VER 0x0001
+#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_MIN_VER 0x0001
+
+#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SID 0x00002300
+#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SID 0x00002301
+#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_MIN_VER 0x0001
+#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_MIN_VER 0x0001
+
+enum irq_test_scenario_t {
+ IRQ_TEST_SCENARIO_NONE,
+ IRQ_TEST_SCENARIO_1,
+ IRQ_TEST_SCENARIO_2,
+ IRQ_TEST_SCENARIO_3,
+ IRQ_TEST_SCENARIO_4,
+};
+
+struct irq_test_execution_data_t {
+ volatile int32_t timer0_triggered;
+};
/* Use lower 16 bits in return value for error code, upper 16 for line number
* in test service
diff --git a/test/test_services/tfm_core_test_2/manifest.yaml b/test/test_services/tfm_core_test_2/manifest.yaml
index c388912..2bef0cc 100644
--- a/test/test_services/tfm_core_test_2/manifest.yaml
+++ b/test/test_services/tfm_core_test_2/manifest.yaml
@@ -41,6 +41,20 @@
"non_secure_clients": true,
"minor_version": 1,
"minor_policy": "STRICT"
+ },
+ {
+ "name": "TFM_CORE_TEST_2_SFN_PREPARE_TEST_SCENARIO",
+ "signal": "SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ {
+ "name": "TFM_CORE_TEST_2_SFN_EXECUTE_TEST_SCENARIO",
+ "signal": "SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "STRICT"
}
],
"linker_pattern": {
@@ -81,5 +95,21 @@
"minor_version": 1,
"minor_policy": "STRICT"
},
+ {
+ "name": "SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO",
+ "sid": "0x00002204",
+ "signal": "SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SIGNAL",
+ "non_secure_clients": "true",
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ {
+ "name": "SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO",
+ "sid": "0x00002205",
+ "signal": "SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SIGNAL",
+ "non_secure_clients": "true",
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
]
}
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 a6192a1..4f93fc8 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
@@ -29,6 +29,10 @@
static int32_t* invalid_addresses [] = {(int32_t*)0x0, (int32_t*)0xFFF12000};
+/* structures for secure IRQ testing */
+static enum irq_test_scenario_t current_scenario = IRQ_TEST_SCENARIO_NONE;
+static struct irq_test_execution_data_t *current_execution_data;
+
psa_status_t spm_core_test_2_slave_service(struct psa_invec *in_vec,
size_t in_len,
struct psa_outvec *out_vec,
@@ -179,7 +183,7 @@
uint32_t *out_ptr;
int32_t *res_ptr;
- if (in_len != 1 || out_len != 2) {
+ if ((in_len != 1) || (out_len != 2)) {
return CORE_TEST_ERRNO_INVALID_PARAMETER;
}
@@ -197,6 +201,88 @@
return spm_core_test_2_sfn_invert_internal(in_ptr, out_ptr, res_ptr, len);
}
+static psa_status_t spm_core_test_2_prepare_test_scenario_internal(
+ enum irq_test_scenario_t irq_test_scenario,
+ struct irq_test_execution_data_t *execution_data)
+{
+ current_scenario = irq_test_scenario;
+ current_execution_data = execution_data;
+
+ switch (irq_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:
+ /* No action is necessary*/
+ break;
+ default:
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ return CORE_TEST_ERRNO_SUCCESS;
+}
+
+psa_status_t spm_core_test_2_prepare_test_scenario(
+ struct psa_invec *in_vec, size_t in_len,
+ struct psa_outvec *out_vec, size_t out_size)
+{
+ if ((in_len != 2) ||
+ (in_vec[0].len != sizeof(uint32_t)) ||
+ (in_vec[1].len != sizeof(struct irq_test_execution_data_t *))) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ enum irq_test_scenario_t irq_test_scenario =
+ (enum irq_test_scenario_t) *(uint32_t *)in_vec[0].base;
+
+ struct irq_test_execution_data_t *execution_data =
+ *(struct irq_test_execution_data_t **)in_vec[1].base;
+
+ return spm_core_test_2_prepare_test_scenario_internal(irq_test_scenario,
+ execution_data);
+}
+
+static psa_status_t spm_core_test_2_execute_test_scenario_internal(
+ enum irq_test_scenario_t irq_test_scenario)
+{
+ switch (irq_test_scenario) {
+ case IRQ_TEST_SCENARIO_NONE:
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ case IRQ_TEST_SCENARIO_1:
+ /* No action is necessary*/
+ break;
+ case IRQ_TEST_SCENARIO_2:
+ if (current_execution_data->timer0_triggered) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+ while (!current_execution_data->timer0_triggered) {
+ ;
+ }
+ break;
+ case IRQ_TEST_SCENARIO_3:
+ case IRQ_TEST_SCENARIO_4:
+ /* No action is necessary*/
+ break;
+ default:
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ return CORE_TEST_ERRNO_SUCCESS;
+}
+
+psa_status_t spm_core_test_2_execute_test_scenario(
+ struct psa_invec *in_vec, size_t in_len,
+ struct psa_outvec *out_vec, size_t out_size)
+{
+ enum irq_test_scenario_t irq_test_scenario =
+ (enum irq_test_scenario_t) *(uint32_t *)in_vec[0].base;
+
+ return spm_core_test_2_execute_test_scenario_internal(irq_test_scenario);
+}
+
+
#ifdef TFM_PSA_API
typedef psa_status_t (*core_test_2_func_t)(psa_msg_t *msg);
@@ -307,6 +393,49 @@
return ret;
}
+psa_status_t spm_core_test_2_wrap_prepare_test_scenario(psa_msg_t *msg)
+{
+ uint32_t irq_test_scenario;
+ struct irq_test_execution_data_t *execution_data;
+ size_t num;
+
+ if ((msg->in_size[0] != sizeof(uint32_t)) ||
+ (msg->in_size[1] != sizeof(struct irq_test_execution_data_t*))) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ num = psa_read(msg->handle, 0, &irq_test_scenario, sizeof(uint32_t));
+ if (num != msg->in_size[0]) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ num = psa_read(msg->handle, 1, &execution_data, sizeof(
+ struct irq_test_execution_data_t*));
+ if (num != msg->in_size[1]) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ return spm_core_test_2_prepare_test_scenario_internal(irq_test_scenario,
+ execution_data);
+}
+
+psa_status_t spm_core_test_2_wrap_execute_test_scenario(psa_msg_t *msg)
+{
+ uint32_t irq_test_scenario;
+ size_t num;
+
+ if (msg->in_size[0] != sizeof(uint32_t)) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ num = psa_read(msg->handle, 0, &irq_test_scenario, sizeof(uint32_t));
+ if (num != msg->in_size[0]) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ return spm_core_test_2_execute_test_scenario_internal(irq_test_scenario);
+}
+
#endif
/* FIXME: Add a testcase to test that a failed init makes the secure partition
@@ -334,6 +463,14 @@
} else if (signals & SPM_CORE_TEST_2_INVERT_SIGNAL) {
core_test_2_signal_handle(SPM_CORE_TEST_2_INVERT_SIGNAL,
spm_core_test_2_wrap_sfn_invert);
+ } else if (signals & SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SIGNAL) {
+ core_test_2_signal_handle(
+ SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SIGNAL,
+ spm_core_test_2_wrap_prepare_test_scenario);
+ } else if (signals & SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SIGNAL) {
+ core_test_2_signal_handle(
+ SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SIGNAL,
+ spm_core_test_2_wrap_execute_test_scenario);
} else {
; /* do nothing */
}
diff --git a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h
index ae9c1db..e95c72b 100644
--- a/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h
+++ b/test/test_services/tfm_core_test_2/tfm_ss_core_test_2_signal.h
@@ -15,6 +15,9 @@
#define SPM_CORE_TEST_2_CHECK_CALLER_CLIENT_ID_SIGNAL (1 << (1 + 4))
#define SPM_CORE_TEST_2_GET_EVERY_SECOND_BYTE_SIGNAL (1 << (2 + 4))
#define SPM_CORE_TEST_2_INVERT_SIGNAL (1 << (3 + 4))
+#define SPM_CORE_TEST_2_PREPARE_TEST_SCENARIO_SIGNAL (1 << (4 + 4))
+#define SPM_CORE_TEST_2_EXECUTE_TEST_SCENARIO_SIGNAL (1 << (5 + 4))
+
#endif /* TFM_PSA_API */
#endif /* __TFM_CORE_TEST_2_SIGNAL_H__ */
diff --git a/test/test_services/tfm_irq_test_service_1/manifest.yaml b/test/test_services/tfm_irq_test_service_1/manifest.yaml
new file mode 100644
index 0000000..5c0d83d
--- /dev/null
+++ b/test/test_services/tfm_irq_test_service_1/manifest.yaml
@@ -0,0 +1,76 @@
+#-------------------------------------------------------------------------------
+# Copyright (c) 2019, Arm Limited. All rights reserved.
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#
+#-------------------------------------------------------------------------------
+
+{
+ "name": "TFM_IRQ_TEST_1",
+ "type": "APPLICATION-ROT",
+ "priority": "NORMAL",
+ "id": "0x0000010B",
+ "entry_point": "tfm_irq_test_1_init",
+ "tfm_partition_ipc": true,
+ "stack_size": "0x0400",
+ "heap_size": "0x0400",
+ "mmio_regions": [
+ {
+ "name": "TFM_PERIPHERAL_TIMER0",
+ "permission": "READ-WRITE"
+ }
+ ],
+ "tfm_init_symbol": "tfm_irq_test_1_init",
+ "secure_functions": [
+ {
+ "name": "SPM_IRQ_TEST_1_PREPARE_TEST_SCENARIO",
+ "signal": "SPM_IRQ_TEST_1_PREPARE_TEST_SCENARIO",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ {
+ "name": "SPM_IRQ_TEST_1_EXECUTE_TEST_SCENARIO",
+ "signal": "SPM_IRQ_TEST_1_EXECUTE_TEST_SCENARIO",
+ "non_secure_clients": true,
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ }
+ ],
+ "irqs": [
+ {
+ "line_name": "TFM_TIMER0_IRQ",
+ "signal": "SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ",
+ "tfm_irq_priority": 64,
+ }
+ ],
+ "source_files": [
+ "./tfm_irq_test_service_1.c",
+ "*timer_cmsdk.c",
+ "*timer_cmsdk_drv.c",
+ ],
+ "linker_pattern": {
+ "object_list": [
+ "*tfm_irq_test_service_1.*",
+ "*timer_cmsdk*",
+ ]
+ },
+ "services": [
+ {
+ "name": "SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO",
+ "sid": "0x00002300",
+ "signal": "SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SIGNAL",
+ "non_secure_clients": "true",
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ {
+ "name": "SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO",
+ "sid": "0x00002301",
+ "signal": "SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SIGNAL",
+ "non_secure_clients": "true",
+ "minor_version": 1,
+ "minor_policy": "STRICT"
+ },
+ ]
+}
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
new file mode 100644
index 0000000..334e4dc
--- /dev/null
+++ b/test/test_services/tfm_irq_test_service_1/tfm_irq_test_service_1.c
@@ -0,0 +1,393 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <stddef.h>
+#include "tfm_api.h"
+#include "tfm_veneers.h"
+#include "secure_fw/core/secure_utilities.h"
+#include "secure_fw/core/tfm_secure_api.h"
+#include "secure_fw/include/tfm_spm_services_api.h"
+#include "spm_partition_defs.h"
+#include "test/test_services/tfm_core_test/core_test_defs.h"
+#include "psa_service.h"
+#include "tfm_irq_test_service_1_signal.h"
+#include "tfm_irq_signal_defs.h"
+#include "tfm_plat_test.h"
+
+static enum irq_test_scenario_t current_scenario = IRQ_TEST_SCENARIO_NONE;
+static struct irq_test_execution_data_t *current_execution_data;
+
+#ifdef TFM_PSA_API
+static psa_handle_t execute_msg_handle = -1;
+#endif
+
+/**
+ * \brief unrecoverable error during test execution.
+ *
+ * Called from places, where error code would be very difficult, or impossible
+ * to return.
+ */
+static void halt_test_execution(void)
+{
+ while (1) {
+ ; /* Test fail */
+ }
+}
+
+/**
+ * \brief Stop the timer, and disable and clear interrupts
+ */
+static void stop_timer(void)
+{
+ tfm_plat_test_secure_timer_stop();
+}
+
+uint32_t spm_irq_test_1_prepare_test_scenario_internal(
+ enum irq_test_scenario_t irq_test_scenario,
+ struct irq_test_execution_data_t *execution_data)
+{
+ current_scenario = irq_test_scenario;
+ current_execution_data = execution_data;
+
+ current_execution_data->timer0_triggered = 0;
+
+ switch (irq_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:
+ tfm_plat_test_secure_timer_start();
+ break;
+ default:
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ return CORE_TEST_ERRNO_SUCCESS;
+}
+
+uint32_t spm_irq_test_1_execute_test_scenario(
+ struct psa_invec *in_vec, size_t in_len,
+ struct psa_outvec *out_vec, size_t out_len)
+{
+ enum irq_test_scenario_t irq_test_scenario =
+ (enum irq_test_scenario_t) *(uint32_t *)in_vec[0].base;
+ psa_signal_t signals = 0;
+
+ if (irq_test_scenario != current_scenario) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ switch (irq_test_scenario) {
+ case IRQ_TEST_SCENARIO_NONE:
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ case IRQ_TEST_SCENARIO_1:
+ case IRQ_TEST_SCENARIO_2:
+ /* nothing to do*/
+ break;
+ case IRQ_TEST_SCENARIO_3:
+ if (current_execution_data->timer0_triggered) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+ while (!current_execution_data->timer0_triggered) {
+ /* Wait for the timer to be triggered */
+ ;
+ }
+ break;
+ case IRQ_TEST_SCENARIO_4:
+ if (current_execution_data->timer0_triggered) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+ while ((signals & SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ) == 0) {
+ signals = psa_wait(SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ,
+ PSA_BLOCK);
+ }
+ if (!current_execution_data->timer0_triggered) {
+ return CORE_TEST_ERRNO_TEST_FAULT;
+ }
+ psa_eoi(SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ);
+ break;
+ default:
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ return CORE_TEST_ERRNO_SUCCESS;
+}
+
+uint32_t spm_irq_test_1_prepare_test_scenario(
+ struct psa_invec *in_vec, size_t in_len,
+ struct psa_outvec *out_vec, size_t out_len)
+{
+ enum irq_test_scenario_t irq_test_scenario;
+ struct irq_test_execution_data_t *execution_data;
+
+ if ((in_len != 2) || (out_len != 0)) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ if ((in_vec[0].len != sizeof(uint32_t)) ||
+ (in_vec[1].len != sizeof(struct irq_test_execution_data_t *))) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ irq_test_scenario =
+ (enum irq_test_scenario_t) *(uint32_t *)in_vec[0].base;
+
+ execution_data =
+ *(struct irq_test_execution_data_t **)in_vec[1].base;
+
+ return spm_irq_test_1_prepare_test_scenario_internal(irq_test_scenario,
+ execution_data);
+}
+
+#ifndef TFM_PSA_API
+
+void SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ_isr(void)
+{
+ stop_timer();
+
+ if ((current_execution_data == NULL) ||
+ (current_execution_data->timer0_triggered != 0)) {
+ halt_test_execution();
+ }
+
+ current_execution_data->timer0_triggered = 1;
+
+ switch (current_scenario) {
+ case IRQ_TEST_SCENARIO_NONE:
+ halt_test_execution();
+ break;
+ case IRQ_TEST_SCENARIO_1:
+ case IRQ_TEST_SCENARIO_2:
+ case IRQ_TEST_SCENARIO_3:
+ psa_eoi(SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ);
+ break;
+ case IRQ_TEST_SCENARIO_4:
+ /* nothing to do*/
+ break;
+ default:
+ halt_test_execution();
+ break;
+ }
+
+ __asm("DSB");
+}
+
+#else /* TFM_PSA_API */
+
+typedef psa_status_t (*irq_test_1_func_t)(psa_msg_t *msg);
+
+static void spm_irq_test_1_signal_handle(psa_signal_t signal,
+ irq_test_1_func_t pfn)
+{
+ psa_msg_t msg;
+ psa_status_t status;
+
+ status = psa_get(signal, &msg);
+ if (status) {
+ return;
+ }
+
+ switch (msg.type) {
+ case PSA_IPC_CONNECT:
+ psa_reply(msg.handle, PSA_SUCCESS);
+ break;
+ case PSA_IPC_CALL:
+ status = pfn(&msg);
+ psa_reply(msg.handle, status);
+ break;
+ case PSA_IPC_DISCONNECT:
+ psa_reply(msg.handle, PSA_SUCCESS);
+ break;
+ default:
+ break;
+ }
+}
+
+void TIMER_0_isr_ipc(void)
+{
+ current_execution_data->timer0_triggered = 1;
+
+ tfm_plat_test_secure_timer_stop();
+
+ switch (current_scenario) {
+ case IRQ_TEST_SCENARIO_NONE:
+ halt_test_execution();
+ break;
+ case IRQ_TEST_SCENARIO_1:
+ case IRQ_TEST_SCENARIO_2:
+ psa_eoi(SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ);
+ break;
+ case IRQ_TEST_SCENARIO_3:
+ /* execute_msg_handle have to be valid at this point */
+ if (execute_msg_handle <= 0) {
+ halt_test_execution();
+ }
+ /* reply to the execute message, to unblock NS side */
+ psa_reply(execute_msg_handle, CORE_TEST_ERRNO_SUCCESS);
+ execute_msg_handle = -1;
+ psa_eoi(SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ);
+ break;
+ case IRQ_TEST_SCENARIO_4:
+ /* This case should never be executed as in this scenario the 'execute
+ * function does the psa wait, and calls psa_eoi immediately'. So when
+ * execution gets to the psa_wait in the main loop, the IRQ signal is
+ * unset.
+ */
+ halt_test_execution();
+ break;
+ default:
+ halt_test_execution();
+ break;
+ }
+}
+
+static psa_status_t spm_irq_test_1_wrap_prepare_test_scenario(psa_msg_t *msg)
+{
+ uint32_t irq_test_scenario;
+ struct irq_test_execution_data_t *execution_data;
+ size_t num;
+
+ if ((msg->in_size[0] != sizeof(uint32_t)) ||
+ (msg->in_size[1] != sizeof(struct irq_test_execution_data_t *))) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+
+ num = psa_read(msg->handle, 0, &irq_test_scenario, sizeof(uint32_t));
+ if (num != msg->in_size[0]) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ num = psa_read(msg->handle, 1, &execution_data,
+ sizeof(struct irq_test_execution_data_t *));
+ if (num != msg->in_size[1]) {
+ return CORE_TEST_ERRNO_INVALID_PARAMETER;
+ }
+
+ return spm_irq_test_1_prepare_test_scenario_internal(irq_test_scenario,
+ execution_data);
+}
+
+static void spm_irq_test_1_execute_test_scenario_ipc_call(psa_msg_t *msg)
+{
+ size_t num;
+ uint32_t irq_test_scenario;
+ psa_signal_t signals = 0;
+
+ num = psa_read(msg->handle, 0, &irq_test_scenario, sizeof(uint32_t));
+ if ((num != msg->in_size[0]) ||
+ (irq_test_scenario != current_scenario)) {
+ psa_reply(msg->handle, CORE_TEST_ERRNO_INVALID_PARAMETER);
+ return;
+ }
+
+ switch (irq_test_scenario) {
+ case IRQ_TEST_SCENARIO_NONE:
+ psa_reply(msg->handle, CORE_TEST_ERRNO_INVALID_PARAMETER);
+ return;
+ case IRQ_TEST_SCENARIO_1:
+ case IRQ_TEST_SCENARIO_2:
+ /* nothing to do, return success */
+ psa_reply(msg->handle, CORE_TEST_ERRNO_SUCCESS);
+ return;
+ case IRQ_TEST_SCENARIO_3:
+ if (current_execution_data->timer0_triggered) {
+ psa_reply(msg->handle, CORE_TEST_ERRNO_TEST_FAULT);
+ return;
+ }
+ /* We need the ISR to be able to run. So we do a wait to let
+ * it run and set timer0_triggered. This message will be replied
+ * from the ISR, so the NS side remains blocked for now. To be able
+ * to reply, we also save the handle of the message.
+ */
+ if (execute_msg_handle > 0) {
+ /* execute_msg_handle should be uninitialised at this point */
+ psa_reply(msg->handle, CORE_TEST_ERRNO_TEST_FAULT);
+ return;
+ }
+ execute_msg_handle = msg->handle;
+ while (!(signals & SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ)) {
+ signals = psa_wait(SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ,
+ PSA_BLOCK);
+ }
+ return;
+ case IRQ_TEST_SCENARIO_4:
+ while (!(signals & SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ)) {
+ signals = psa_wait(SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ,
+ PSA_BLOCK);
+ }
+ /* There is no need to call the ISR in this scenario, so we can
+ * clear the IRQ signal
+ */
+ stop_timer();
+ psa_eoi(SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ);
+ psa_reply(msg->handle, CORE_TEST_ERRNO_SUCCESS);
+ break;
+ default:
+ psa_reply(msg->handle, CORE_TEST_ERRNO_INVALID_PARAMETER);
+ return;
+ }
+}
+
+static void spm_irq_test_1_execute_test_scenario_ipc(psa_signal_t signal)
+{
+ psa_msg_t msg;
+ psa_status_t status;
+
+ status = psa_get(signal, &msg);
+ if (status) {
+ return;
+ }
+
+ if (signal != SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SIGNAL) {
+ psa_reply(msg.handle, CORE_TEST_ERRNO_INVALID_PARAMETER);
+ }
+
+ switch (msg.type) {
+ case PSA_IPC_CONNECT:
+ psa_reply(msg.handle, PSA_SUCCESS);
+ break;
+ case PSA_IPC_CALL:
+ spm_irq_test_1_execute_test_scenario_ipc_call(&msg);
+ break;
+ case PSA_IPC_DISCONNECT:
+ psa_reply(msg.handle, PSA_SUCCESS);
+ break;
+ default:
+ break;
+ }
+}
+#endif /* TFM_PSA_API */
+
+int32_t tfm_irq_test_1_init(void)
+{
+ tfm_enable_irq(SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ);
+#ifdef TFM_PSA_API
+ psa_signal_t signals = 0;
+
+ while (1) {
+ signals = psa_wait(PSA_WAIT_ANY, PSA_BLOCK);
+ if (signals & SPM_CORE_IRQ_TEST_1_SIGNAL_TIMER_0_IRQ) {
+ TIMER_0_isr_ipc();
+ } else if (signals & SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SIGNAL) {
+ spm_irq_test_1_signal_handle(
+ SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SIGNAL,
+ spm_irq_test_1_wrap_prepare_test_scenario);
+ } else if (signals & SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SIGNAL) {
+ spm_irq_test_1_execute_test_scenario_ipc(
+ SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SIGNAL);
+ } else {
+ ; /* do nothing */
+ }
+ }
+#endif /* TFM_PSA_API */
+
+ return TFM_SUCCESS;
+}
+
diff --git a/test/test_services/tfm_irq_test_service_1/tfm_irq_test_service_1_signal.h b/test/test_services/tfm_irq_test_service_1/tfm_irq_test_service_1_signal.h
new file mode 100644
index 0000000..c6b13ab
--- /dev/null
+++ b/test/test_services/tfm_irq_test_service_1/tfm_irq_test_service_1_signal.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2019, Arm Limited. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#ifndef __TFM_IRQ_TEST_1_SERVICE_SIGNAL_H__
+#define __TFM_IRQ_TEST_1_SERVICE_SIGNAL_H__
+
+/* FixMe: hardcode it for the tool cannot support now */
+#ifdef TFM_PSA_API
+
+#define SPM_CORE_IRQ_TEST_1_PREPARE_TEST_SCENARIO_SIGNAL (1U << (4 + 4))
+#define SPM_CORE_IRQ_TEST_1_EXECUTE_TEST_SCENARIO_SIGNAL (1U << (5 + 4))
+
+#endif /* TFM_PSA_API */
+
+#endif /* __TFM_IRQ_TEST_1_SERVICE_SIGNAL_H__ */
diff --git a/tools/tfm_manifest_list.yaml b/tools/tfm_manifest_list.yaml
index b55a0e9..599810b 100644
--- a/tools/tfm_manifest_list.yaml
+++ b/tools/tfm_manifest_list.yaml
@@ -107,6 +107,16 @@
"conditional": "TFM_PARTITION_TEST_CORE_IPC",
"version_major": 0,
"version_minor": 1
+ },
+ {
+ "name": "TFM IRQ Test Service 1",
+ "short_name": "TFM_IRQ_Test_1",
+ "manifest": "test/test_services/tfm_irq_test_service_1/manifest.yaml",
+ "tfm_extensions": true,
+ "tfm_partition_ipc": true,
+ "conditional": "TFM_PARTITION_TEST_CORE",
+ "version_major": 0,
+ "version_minor": 1
}
]
}