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  * @brief test the behavior of CONFIG_RUNTIME_NMI at run time
40  *
41  * @details this test is to validate z_arm_nmi_set_handler() api.
42  * First we configure the NMI isr using z_arm_nmi_set_handler() api.
43  * After wait for some time, and set the  Interrupt Control and
44  * State Register(ICSR) of System control block (SCB).
45  * The registered NMI isr should fire immediately.
46  *
47  * @see z_arm_nmi_set_handler()
48  */
ZTEST(arm_runtime_nmi_fn,test_arm_runtime_nmi)49 ZTEST(arm_runtime_nmi_fn, test_arm_runtime_nmi)
50 {
51 	uint32_t i = 0U;
52 
53 	/* Configure the NMI isr */
54 	z_arm_nmi_set_handler(nmi_test_isr);
55 
56 	for (i = 0U; i < 2; i++) {
57 		printk("Trigger NMI in 2s: %d s\n", i);
58 		k_sleep(K_MSEC(1000));
59 	}
60 
61 	/* Trigger NMI: Should fire immediately */
62 	SCB->ICSR |= SCB_ICSR_NMIPENDSET_Msk;
63 
64 	barrier_dsync_fence_full();
65 	barrier_isync_fence_full();
66 
67 #ifdef ARM_CACHEL1_ARMV7_H
68 	/* Flush Data Cache now if enabled */
69 	if (IS_ENABLED(CONFIG_DCACHE)) {
70 		sys_cache_data_flush_all();
71 	}
72 #endif /* ARM_CACHEL1_ARMV7_H */
73 	zassert_true(nmi_triggered, "Isr not triggered!\n");
74 }
75 /**
76  * @}
77  */
78