aarch32_cpu/
asmv7.rs

1//! Simple assembly routines for ARMv7
2
3/// Data Memory Barrier
4///
5/// Ensures that all explicit memory accesses that appear in program order before the `DMB`
6/// instruction are observed before any explicit memory accesses that appear in program order
7/// after the `DMB` instruction.
8#[cfg_attr(not(feature = "check-asm"), inline)]
9pub fn dmb() {
10    use core::sync::atomic::{compiler_fence, Ordering};
11    compiler_fence(Ordering::SeqCst);
12    unsafe {
13        core::arch::asm!("dmb", options(nostack, preserves_flags));
14    }
15    compiler_fence(Ordering::SeqCst);
16}
17
18/// Data Synchronization Barrier
19///
20/// Acts as a special kind of memory barrier. No instruction in program order after this instruction
21/// can execute until this instruction completes. This instruction completes only when both:
22///
23///  * any explicit memory access made before this instruction is complete
24///  * all cache and branch predictor maintenance operations before this instruction complete
25#[cfg_attr(not(feature = "check-asm"), inline)]
26pub fn dsb() {
27    use core::sync::atomic::{compiler_fence, Ordering};
28    compiler_fence(Ordering::SeqCst);
29    unsafe {
30        core::arch::asm!("dsb", options(nostack, preserves_flags));
31    }
32    compiler_fence(Ordering::SeqCst);
33}
34
35/// Instruction Synchronization Barrier
36///
37/// Flushes the pipeline in the processor, so that all instructions following the `ISB` are fetched
38/// from cache or memory, after the instruction has been completed.
39#[cfg_attr(not(feature = "check-asm"), inline)]
40pub fn isb() {
41    use core::sync::atomic::{compiler_fence, Ordering};
42    compiler_fence(Ordering::SeqCst);
43    unsafe {
44        core::arch::asm!("isb", options(nostack, preserves_flags));
45    }
46    compiler_fence(Ordering::SeqCst);
47}
48
49/// Emit an NOP instruction
50#[cfg_attr(not(feature = "check-asm"), inline)]
51pub fn nop() {
52    unsafe { core::arch::asm!("nop", options(nomem, nostack, preserves_flags)) }
53}
54
55/// Emit an WFI instruction
56#[cfg_attr(not(feature = "check-asm"), inline)]
57pub fn wfi() {
58    unsafe { core::arch::asm!("wfi", options(nomem, nostack, preserves_flags)) }
59}
60
61/// Emit an WFE instruction
62#[cfg_attr(not(feature = "check-asm"), inline)]
63pub fn wfe() {
64    unsafe { core::arch::asm!("wfe", options(nomem, nostack, preserves_flags)) }
65}
66
67/// Emit an SEV instruction
68#[cfg_attr(not(feature = "check-asm"), inline)]
69pub fn sev() {
70    unsafe {
71        core::arch::asm!("sev");
72    }
73}
74
75/// Mask IRQ
76#[cfg_attr(not(feature = "check-asm"), inline)]
77pub fn irq_disable() {
78    unsafe {
79        core::arch::asm!("cpsid i");
80    }
81}
82
83/// Unmask IRQ
84#[cfg_attr(not(feature = "check-asm"), inline)]
85pub fn irq_enable() {
86    unsafe {
87        core::arch::asm!("cpsie i");
88    }
89}
90
91/// Which core are we?
92///
93/// Return the bottom 24-bits of the MPIDR
94#[cfg_attr(not(feature = "check-asm"), inline)]
95pub fn core_id() -> u32 {
96    let r: u32;
97    unsafe {
98        core::arch::asm!("MRC p15, 0, {}, c0, c0, 5", out(reg) r, options(nomem, nostack, preserves_flags));
99    }
100    r & 0x00FF_FFFF
101}