1 /*
2  * Copyright (c) 2016 Linaro Limited
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/sys/printk.h>
9 #include <zephyr/sys/reboot.h>
10 #include <zephyr/sys/barrier.h>
11 #include <cmsis_core.h>
12 #include <zephyr/arch/arm/nmi.h>
13 #include <zephyr/ztest.h>
14 #include <zephyr/tc_util.h>
15 #include <zephyr/cache.h>
16 
17 /* on v8m arch the nmi pend bit is renamed to pend nmi map it to old name */
18 #ifndef SCB_ICSR_NMIPENDSET_Msk
19 #define SCB_ICSR_NMIPENDSET_Msk SCB_ICSR_PENDNMISET_Msk
20 #endif
21 
22 static bool nmi_triggered;
23 
nmi_test_isr(void)24 static void nmi_test_isr(void)
25 {
26 	printk("NMI triggered (test_handler_isr)!\n");
27 	/* ISR triggered correctly: test passed! */
28 	nmi_triggered = true;
29 }
30 
31 /**
32  * @brief Test the behavior of CONFIG_RUNTIME_NMI at runtime.
33  * @addtogroup kernel_interrupt_tests
34  * @ingroup all_tests
35  * @{
36  */
37 
38 
39 /**
40  * @brief test the behavior of CONFIG_RUNTIME_NMI at run time
41  *
42  * @details this test is to validate z_arm_nmi_set_handler() api.
43  * First we configure the NMI isr using z_arm_nmi_set_handler() api.
44  * After wait for some time, and set the  Interrupt Control and
45  * State Register(ICSR) of System control block (SCB).
46  * The registered NMI isr should fire immediately.
47  *
48  * @see z_arm_nmi_set_handler()
49  */
ZTEST(arm_runtime_nmi_fn,test_arm_runtime_nmi)50 ZTEST(arm_runtime_nmi_fn, test_arm_runtime_nmi)
51 {
52 	uint32_t i = 0U;
53 
54 	/* Configure the NMI isr */
55 	z_arm_nmi_set_handler(nmi_test_isr);
56 
57 	for (i = 0U; i < 2; i++) {
58 		printk("Trigger NMI in 2s: %d s\n", i);
59 		k_sleep(K_MSEC(1000));
60 	}
61 
62 	/* Trigger NMI: Should fire immediately */
63 	SCB->ICSR |= SCB_ICSR_NMIPENDSET_Msk;
64 
65 	barrier_dsync_fence_full();
66 	barrier_isync_fence_full();
67 
68 #ifdef ARM_CACHEL1_ARMV7_H
69 	/* Flush Data Cache now if enabled */
70 	if (IS_ENABLED(CONFIG_DCACHE)) {
71 		sys_cache_data_flush_all();
72 	}
73 #endif /* ARM_CACHEL1_ARMV7_H */
74 	zassert_true(nmi_triggered, "Isr not triggered!\n");
75 }
76 /**
77  * @}
78  */
79