1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#[inline]
pub fn without_interrupts<F, R>(f: F) -> R
where
F: FnOnce() -> R,
{
let flags = read_disable();
let ret = f();
restore(flags);
ret
}
#[inline]
pub(crate) fn read_disable() -> imp::Flags {
if cfg!(target_os = "none") {
let flags = imp::get();
if flags != DISABLE {
imp::set(DISABLE);
}
flags
} else {
DISABLE
}
}
#[inline]
pub(crate) fn restore(flags: imp::Flags) {
if flags != DISABLE && cfg!(target_os = "none") {
imp::set(flags);
}
}
pub(crate) use imp::{AtomicFlags, DISABLE};
#[cfg(target_arch = "x86_64")]
mod imp {
use x86_64::instructions::interrupts;
pub type Flags = bool;
pub type AtomicFlags = core::sync::atomic::AtomicBool;
pub const DISABLE: bool = false;
pub use interrupts::are_enabled as get;
#[inline]
pub fn set(enable: bool) {
if enable {
interrupts::enable();
} else {
interrupts::disable();
}
}
}
#[cfg(target_arch = "aarch64")]
mod imp {
use aarch64_cpu::registers::DAIF;
use tock_registers::interfaces::{Readable, Writeable};
pub type Flags = u64;
pub type AtomicFlags = core::sync::atomic::AtomicU64;
pub const DISABLE: u64 = 0;
#[inline]
pub fn get() -> u64 {
DAIF.get()
}
#[inline]
pub fn set(value: u64) {
DAIF.set(value);
}
}