cortex_ar/
asm.rs

1//! Simple assembly routines
2
3use core::sync::atomic::{compiler_fence, Ordering};
4
5/// Data Memory Barrier
6///
7/// Ensures that all explicit memory accesses that appear in program order before the `DMB`
8/// instruction are observed before any explicit memory accesses that appear in program order
9/// after the `DMB` instruction.
10#[inline]
11pub fn dmb() {
12    compiler_fence(Ordering::SeqCst);
13    unsafe {
14        core::arch::asm!("dmb", options(nostack, preserves_flags));
15    }
16    compiler_fence(Ordering::SeqCst);
17}
18
19/// Data Synchronization Barrier
20///
21/// Acts as a special kind of memory barrier. No instruction in program order after this instruction
22/// can execute until this instruction completes. This instruction completes only when both:
23///
24///  * any explicit memory access made before this instruction is complete
25///  * all cache and branch predictor maintenance operations before this instruction complete
26#[inline]
27pub fn dsb() {
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#[inline]
40pub fn isb() {
41    compiler_fence(Ordering::SeqCst);
42    unsafe {
43        core::arch::asm!("isb", options(nostack, preserves_flags));
44    }
45    compiler_fence(Ordering::SeqCst);
46}
47
48/// Emit an NOP instruction
49#[inline]
50pub fn nop() {
51    unsafe { core::arch::asm!("nop", options(nomem, nostack, preserves_flags)) }
52}
53
54/// Emit an WFI instruction
55#[inline]
56pub fn wfi() {
57    unsafe { core::arch::asm!("wfi", options(nomem, nostack, preserves_flags)) }
58}
59
60/// Emit an WFE instruction
61#[inline]
62pub fn wfe() {
63    unsafe { core::arch::asm!("wfe", options(nomem, nostack, preserves_flags)) }
64}
65
66/// Emit an SEV instruction
67#[inline]
68pub fn sev() {
69    unsafe {
70        core::arch::asm!("sev");
71    }
72}
73
74/// Which core are we?
75///
76/// Return the bottom 24-bits of the MPIDR
77#[inline]
78pub fn core_id() -> u32 {
79    let r: u32;
80    unsafe {
81        core::arch::asm!("MRC p15, 0, {}, c0, c0, 5", out(reg) r, options(nomem, nostack, preserves_flags));
82    }
83    r & 0x00FF_FFFF
84}