1 // © 2021 Qualcomm Innovation Center, Inc. All rights reserved.
2 //
3 // SPDX-License-Identifier: BSD-3-Clause
4 
5 // Macros to enable or disable interrupts.
6 
7 // Enable all aborts and interrupts, with a full compiler barrier. Self-hosted
8 // debug is left disabled.
9 #define asm_interrupt_enable() __asm__ volatile("msr daifclr, 0x7" ::: "memory")
10 
11 // Enable all aborts and interrupts, with a compiler release fence. Self-hosted
12 // debug is left disabled.
13 //
14 // The argument should be a pointer to a flag that has previously been read to
15 // decide whether to enable interrupts. The pointer will not be dereferenced by
16 // this macro.
17 #define asm_interrupt_enable_release(flag_ptr)                                 \
18 	do {                                                                   \
19 		atomic_signal_fence(memory_order_release);                     \
20 		__asm__ volatile("msr daifclr, 0x7" : "+m"(*(flag_ptr)));      \
21 	} while ((_Bool)0)
22 
23 // Disable all aborts and interrupts, with a full compiler barrier.
24 #define asm_interrupt_disable()                                                \
25 	__asm__ volatile("msr daifset, 0x7" ::: "memory")
26 
27 // Disable all aborts and interrupts, with a compiler acquire fence.
28 //
29 // The argument should be a pointer to a flag that will be written (by the
30 // caller) after this macro completes to record the fact that we have
31 // disabled interrupts. The pointer will not be dereferenced by this macro.
32 //
33 // Warning: the flag must not be CPU-local if this configuration allows context
34 // switches in interrupt handlers! If it is, use asm_interrupt_disable() (with
35 // a full barrier) and ensure that the CPU ID is determined _after_ disabling
36 // interrupts. A thread-local flag is ok, however.
37 #define asm_interrupt_disable_acquire(flag_ptr)                                \
38 	do {                                                                   \
39 		__asm__ volatile("msr daifset, 0x7" ::"m"(*(flag_ptr)));       \
40 		atomic_signal_fence(memory_order_acquire);                     \
41 	} while ((_Bool)0)
42