1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/interrupt_util.h>
9
10 #define DURATION 5
11 #define HANDLER_TOKEN 0xDEADBEEF
12
13 /* Long enough to be guaranteed a tick "should have fired" */
14 #define TIMER_DELAY_US (128 * 1000000 / CONFIG_SYS_CLOCK_TICKS_PER_SEC)
15
16 static struct k_timer irqlock_timer;
17 volatile uint32_t handler_result;
18
timer_handler(struct k_timer * timer)19 static void timer_handler(struct k_timer *timer)
20 {
21 ARG_UNUSED(timer);
22 handler_result = HANDLER_TOKEN;
23 printk("timer fired\n");
24 }
25
26 /**
27 * @brief Test interrupt prevention
28 *
29 * @ingroup kernel_interrupt_tests
30 *
31 * This routine tests if the kernel is capable of preventing interruption, by
32 * locking interrupts and busy-waiting to see if the system timer interrupt is
33 * serviced while interrupts are locked; in addition, this test also verifies
34 * that the system timer interrupt is serviced after interrupts are unlocked.
35 */
ZTEST(interrupt_feature,test_prevent_interruption)36 ZTEST(interrupt_feature, test_prevent_interruption)
37 {
38 unsigned int key;
39
40 printk("locking interrupts\n");
41 key = irq_lock();
42
43 handler_result = 0;
44
45 k_timer_init(&irqlock_timer, timer_handler, NULL);
46
47 /* Start the timer and busy-wait for a bit with IRQs locked. The
48 * timer ought to have fired during this time if interrupts weren't
49 * locked -- but since they are, check_lock_new isn't updated.
50 */
51 k_timer_start(&irqlock_timer, K_MSEC(DURATION), K_NO_WAIT);
52 k_busy_wait(TIMER_DELAY_US);
53 zassert_not_equal(handler_result, HANDLER_TOKEN,
54 "timer interrupt was serviced while interrupts are locked");
55
56 printk("unlocking interrupts\n");
57 irq_unlock(key);
58
59 k_busy_wait(TIMER_DELAY_US);
60
61 zassert_equal(handler_result, HANDLER_TOKEN,
62 "timer should have fired");
63
64 k_timer_stop(&irqlock_timer);
65 }
66
67 ZTEST_SUITE(interrupt_feature, NULL, NULL, NULL, NULL, NULL);
68