// Reference: Section 7.4 "Hints" of ACLE // CP15 instruction #[cfg(not(any( // v8 target_arch = "aarch64", // v7 target_feature = "v7", // v6-M target_feature = "mclass" )))] mod cp15; #[cfg(not(any( target_arch = "aarch64", target_feature = "v7", target_feature = "mclass" )))] pub use self::cp15::*; // Dedicated instructions #[cfg(any( target_arch = "aarch64", target_feature = "v7", target_feature = "mclass" ))] macro_rules! dmb_dsb { ($A:ident) => { impl super::super::sealed::Dmb for $A { #[inline(always)] unsafe fn __dmb(&self) { super::dmb(super::arg::$A) } } impl super::super::sealed::Dsb for $A { #[inline(always)] unsafe fn __dsb(&self) { super::dsb(super::arg::$A) } } }; } #[cfg(any( target_arch = "aarch64", target_feature = "v7", target_feature = "mclass" ))] mod common; #[cfg(any( target_arch = "aarch64", target_feature = "v7", target_feature = "mclass" ))] pub use self::common::*; #[cfg(any(target_arch = "aarch64", target_feature = "v7",))] mod not_mclass; #[cfg(any(target_arch = "aarch64", target_feature = "v7",))] pub use self::not_mclass::*; #[cfg(target_arch = "aarch64")] mod v8; #[cfg(target_arch = "aarch64")] pub use self::v8::*; /// Generates a DMB (data memory barrier) instruction or equivalent CP15 instruction. /// /// DMB ensures the observed ordering of memory accesses. Memory accesses of the specified type /// issued before the DMB are guaranteed to be observed (in the specified scope) before memory /// accesses issued after the DMB. /// /// For example, DMB should be used between storing data, and updating a flag variable that makes /// that data available to another core. /// /// The __dmb() intrinsic also acts as a compiler memory barrier of the appropriate type. #[inline(always)] pub unsafe fn __dmb(arg: A) where A: super::sealed::Dmb, { arg.__dmb() } /// Generates a DSB (data synchronization barrier) instruction or equivalent CP15 instruction. /// /// DSB ensures the completion of memory accesses. A DSB behaves as the equivalent DMB and has /// additional properties. After a DSB instruction completes, all memory accesses of the specified /// type issued before the DSB are guaranteed to have completed. /// /// The __dsb() intrinsic also acts as a compiler memory barrier of the appropriate type. #[inline(always)] pub unsafe fn __dsb(arg: A) where A: super::sealed::Dsb, { arg.__dsb() } /// Generates an ISB (instruction synchronization barrier) instruction or equivalent CP15 /// instruction. /// /// This instruction flushes the processor pipeline fetch buffers, so that following instructions /// are fetched from cache or memory. /// /// An ISB is needed after some system maintenance operations. An ISB is also needed before /// transferring control to code that has been loaded or modified in memory, for example by an /// overlay mechanism or just-in-time code generator. (Note that if instruction and data caches are /// separate, privileged cache maintenance operations would be needed in order to unify the caches.) /// /// The only supported argument for the __isb() intrinsic is 15, corresponding to the SY (full /// system) scope of the ISB instruction. #[inline(always)] pub unsafe fn __isb(arg: A) where A: super::sealed::Isb, { arg.__isb() } extern "unadjusted" { #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.dmb")] #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.dmb")] fn dmb(_: i32); #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.dsb")] #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.dsb")] fn dsb(_: i32); #[cfg_attr(target_arch = "aarch64", link_name = "llvm.aarch64.isb")] #[cfg_attr(target_arch = "arm", link_name = "llvm.arm.isb")] fn isb(_: i32); } // we put these in a module to prevent weirdness with glob re-exports mod arg { // See Section 7.3 Memory barriers of ACLE pub const SY: i32 = 15; pub const ST: i32 = 14; pub const LD: i32 = 13; pub const ISH: i32 = 11; pub const ISHST: i32 = 10; pub const ISHLD: i32 = 9; pub const NSH: i32 = 7; pub const NSHST: i32 = 6; pub const NSHLD: i32 = 5; pub const OSH: i32 = 3; pub const OSHST: i32 = 2; pub const OSHLD: i32 = 1; }