hal_arm/
asm.rs

1#[cfg(not(feature = "host"))]
2#[macro_export]
3macro_rules! __macro_nop {
4    () => {
5        unsafe { core::arch::asm!("nop", options(nomem, nostack, preserves_flags)) };
6    };
7}
8
9#[cfg(feature = "host")]
10#[macro_export]
11macro_rules! __macro_nop {
12    () => {{}};
13}
14
15// This prefixing is a little cursed but necessary to avoid name conflicts, because #[macro_export] exports macros at the top level.
16pub use crate::__macro_nop as nop;
17
18/// Macro for doing a system call.
19#[cfg(not(feature = "host"))]
20#[macro_export]
21macro_rules! __macro_syscall {
22    ($num:expr) => {
23        {
24            use core::arch::asm;
25            let ret: isize;
26            unsafe {
27                asm!(
28                    "svc {num}",
29                    lateout("r0") ret,
30                    num = const $num,
31                    clobber_abi("C")
32                );
33            }
34            ret
35        }
36    };
37    ($num:expr, $arg0:expr) => {
38        {
39            use core::arch::asm;
40            let ret: isize;
41            unsafe {
42                asm!(
43                    "svc {num}",
44                    inlateout("r0") $arg0 => ret,
45                    num = const $num,
46                    clobber_abi("C")
47                );
48            }
49            ret
50        }
51    };
52    ($num:expr, $arg0:expr, $arg1:expr) => {
53        {
54            use core::arch::asm;
55            let ret: isize;
56            unsafe {
57                asm!(
58                    "svc {num}",
59                    inlateout("r0") $arg0 => ret,
60                    in("r1") $arg1,
61                    num = const $num,
62                    clobber_abi("C")
63                );
64            }
65            ret
66        }
67    };
68    ($num:expr, $arg0:expr, $arg1:expr, $arg2:expr) => {
69        {
70            use core::arch::asm;
71            let ret: isize;
72            unsafe {
73                asm!(
74                    "svc {num}",
75                    inlateout("r0") $arg0 => ret,
76                    in("r1") $arg1,
77                    in("r2") $arg2,
78                    num = const $num,
79                    clobber_abi("C")
80                );
81            }
82            ret
83        }
84    };
85    ($num:expr, $arg0:expr, $arg1:expr, $arg2:expr, $arg3:expr) => {
86        {
87            use core::arch::asm;
88            let ret: isize;
89            unsafe {
90                asm!(
91                    "svc {num}",
92                    inlateout("r0") $arg0 => ret,
93                    in("r1") $arg1,
94                    in("r2") $arg2,
95                    in("r3") $arg3,
96                    num = const $num,
97                    clobber_abi("C")
98                );
99            }
100            ret
101        }
102    };
103}
104
105#[cfg(feature = "host")]
106#[macro_export]
107macro_rules! __macro_syscall {
108    ($num:expr) => {{ 0isize }};
109    ($num:expr, $arg0:expr) => {{ 0isize }};
110    ($num:expr, $arg0:expr, $arg1:expr) => {{ 0isize }};
111    ($num:expr, $arg0:expr, $arg1:expr, $arg2:expr) => {{ 0isize }};
112    ($num:expr, $arg0:expr, $arg1:expr, $arg2:expr, $arg3:expr) => {{ 0isize }};
113}
114
115pub use crate::__macro_syscall as syscall;
116
117#[cfg(not(feature = "host"))]
118#[inline(always)]
119pub fn disable_irq_save() -> usize {
120    use core::arch::asm;
121
122    let old: usize;
123
124    unsafe {
125        asm!(
126            "mrs {old}, primask",
127            "cpsid i",
128            "isb",
129            old = out(reg) old,
130            options(nostack, preserves_flags)
131        );
132    }
133    old
134}
135
136#[cfg(feature = "host")]
137#[inline(always)]
138pub fn disable_irq_save() -> usize {
139    0
140}
141
142#[cfg(not(feature = "host"))]
143#[inline(always)]
144pub fn are_interrupts_enabled() -> bool {
145    use core::arch::asm;
146
147    let primask: u32;
148    unsafe {
149        asm!("mrs {}, primask", out(reg) primask, options(nomem, nostack, preserves_flags));
150    }
151    primask == 0
152}
153
154#[cfg(feature = "host")]
155#[inline(always)]
156pub fn are_interrupts_enabled() -> bool {
157    true
158}
159
160#[cfg(not(feature = "host"))]
161#[inline(always)]
162pub fn enable_irq_restr(state: usize) {
163    use core::arch::asm;
164
165    unsafe {
166        asm!(
167            "dsb",
168            "msr primask, {state}",
169            "isb",
170            state = in(reg) state,
171            options(nostack, preserves_flags)
172        );
173    }
174}
175
176#[cfg(feature = "host")]
177#[inline(always)]
178pub fn enable_irq_restr(state: usize) {}
179
180#[cfg(not(feature = "host"))]
181#[macro_export]
182macro_rules! __macro_startup_trampoline {
183    () => {{
184        use core::arch::naked_asm;
185        naked_asm!("ldr r1,=__stack_top", "mov sp, r1", "b bootstrap")
186    }};
187}
188
189#[cfg(feature = "host")]
190#[macro_export]
191macro_rules! __macro_startup_trampoline {
192    () => {{
193        use core::arch::naked_asm;
194        naked_asm!("")
195    }};
196}
197
198pub use crate::__macro_startup_trampoline as startup_trampoline;
199
200#[cfg(not(feature = "host"))]
201#[macro_export]
202macro_rules! __macro_delay {
203    ($cycles:expr) => {{
204        for _ in 0..$cycles {
205            $crate::asm::nop!();
206        }
207    }};
208}
209
210#[cfg(feature = "host")]
211#[macro_export]
212macro_rules! __macro_delay {
213    ($cycles:expr) => {{}};
214}
215
216pub use crate::__macro_delay as delay;
217
218#[cfg(not(feature = "host"))]
219#[macro_export]
220macro_rules! __macro_fault_do_not_use_under_any_circumstances {
221    () => {{
222        use core::arch::asm;
223        use core::sync::atomic::compiler_fence;
224        compiler_fence(core::sync::atomic::Ordering::SeqCst);
225        asm!("udf #0", options(nomem, nostack, preserves_flags));
226        compiler_fence(core::sync::atomic::Ordering::SeqCst);
227    }};
228}
229
230#[cfg(feature = "host")]
231#[macro_export]
232macro_rules! __macro_fault_do_not_use_under_any_circumstances {
233    () => {{}};
234}
235
236pub use crate::__macro_fault_do_not_use_under_any_circumstances as fault_do_not_use_under_any_circumstances;