summaryrefslogtreecommitdiffstats
path: root/library/stdarch/crates/core_arch/src/arm_shared/barrier
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /library/stdarch/crates/core_arch/src/arm_shared/barrier
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'library/stdarch/crates/core_arch/src/arm_shared/barrier')
-rw-r--r--library/stdarch/crates/core_arch/src/arm_shared/barrier/common.rs14
-rw-r--r--library/stdarch/crates/core_arch/src/arm_shared/barrier/cp15.rs38
-rw-r--r--library/stdarch/crates/core_arch/src/arm_shared/barrier/mod.rs154
-rw-r--r--library/stdarch/crates/core_arch/src/arm_shared/barrier/not_mclass.rs43
-rw-r--r--library/stdarch/crates/core_arch/src/arm_shared/barrier/v8.rs23
5 files changed, 272 insertions, 0 deletions
diff --git a/library/stdarch/crates/core_arch/src/arm_shared/barrier/common.rs b/library/stdarch/crates/core_arch/src/arm_shared/barrier/common.rs
new file mode 100644
index 000000000..0fb35534d
--- /dev/null
+++ b/library/stdarch/crates/core_arch/src/arm_shared/barrier/common.rs
@@ -0,0 +1,14 @@
+//! Access types available on all architectures
+
+/// Full system is the required shareability domain, reads and writes are the
+/// required access types
+pub struct SY;
+
+dmb_dsb!(SY);
+
+impl super::super::sealed::Isb for SY {
+ #[inline(always)]
+ unsafe fn __isb(&self) {
+ super::isb(super::arg::SY)
+ }
+}
diff --git a/library/stdarch/crates/core_arch/src/arm_shared/barrier/cp15.rs b/library/stdarch/crates/core_arch/src/arm_shared/barrier/cp15.rs
new file mode 100644
index 000000000..6faae0fee
--- /dev/null
+++ b/library/stdarch/crates/core_arch/src/arm_shared/barrier/cp15.rs
@@ -0,0 +1,38 @@
+// Reference: ARM11 MPCore Processor Technical Reference Manual (ARM DDI 0360E) Section 3.5 "Summary
+// of CP15 instructions"
+
+use crate::arch::asm;
+
+/// Full system is the required shareability domain, reads and writes are the
+/// required access types
+pub struct SY;
+
+impl super::super::sealed::Dmb for SY {
+ #[inline(always)]
+ unsafe fn __dmb(&self) {
+ asm!(
+ "mcr p15, 0, r0, c7, c10, 5",
+ options(preserves_flags, nostack)
+ )
+ }
+}
+
+impl super::super::sealed::Dsb for SY {
+ #[inline(always)]
+ unsafe fn __dsb(&self) {
+ asm!(
+ "mcr p15, 0, r0, c7, c10, 4",
+ options(preserves_flags, nostack)
+ )
+ }
+}
+
+impl super::super::sealed::Isb for SY {
+ #[inline(always)]
+ unsafe fn __isb(&self) {
+ asm!(
+ "mcr p15, 0, r0, c7, c5, 4",
+ options(preserves_flags, nostack)
+ )
+ }
+}
diff --git a/library/stdarch/crates/core_arch/src/arm_shared/barrier/mod.rs b/library/stdarch/crates/core_arch/src/arm_shared/barrier/mod.rs
new file mode 100644
index 000000000..6ccced00e
--- /dev/null
+++ b/library/stdarch/crates/core_arch/src/arm_shared/barrier/mod.rs
@@ -0,0 +1,154 @@
+// 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<A>(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<A>(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<A>(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;
+}
diff --git a/library/stdarch/crates/core_arch/src/arm_shared/barrier/not_mclass.rs b/library/stdarch/crates/core_arch/src/arm_shared/barrier/not_mclass.rs
new file mode 100644
index 000000000..385e1d528
--- /dev/null
+++ b/library/stdarch/crates/core_arch/src/arm_shared/barrier/not_mclass.rs
@@ -0,0 +1,43 @@
+//! Access types available on v7 and v8 but not on v7(E)-M or v8-M
+
+/// Full system is the required shareability domain, writes are the required
+/// access type
+pub struct ST;
+
+dmb_dsb!(ST);
+
+/// Inner Shareable is the required shareability domain, reads and writes are
+/// the required access types
+pub struct ISH;
+
+dmb_dsb!(ISH);
+
+/// Inner Shareable is the required shareability domain, writes are the required
+/// access type
+pub struct ISHST;
+
+dmb_dsb!(ISHST);
+
+/// Non-shareable is the required shareability domain, reads and writes are the
+/// required access types
+pub struct NSH;
+
+dmb_dsb!(NSH);
+
+/// Non-shareable is the required shareability domain, writes are the required
+/// access type
+pub struct NSHST;
+
+dmb_dsb!(NSHST);
+
+/// Outer Shareable is the required shareability domain, reads and writes are
+/// the required access types
+pub struct OSH;
+
+dmb_dsb!(OSH);
+
+/// Outer Shareable is the required shareability domain, writes are the required
+/// access type
+pub struct OSHST;
+
+dmb_dsb!(OSHST);
diff --git a/library/stdarch/crates/core_arch/src/arm_shared/barrier/v8.rs b/library/stdarch/crates/core_arch/src/arm_shared/barrier/v8.rs
new file mode 100644
index 000000000..db15da805
--- /dev/null
+++ b/library/stdarch/crates/core_arch/src/arm_shared/barrier/v8.rs
@@ -0,0 +1,23 @@
+/// Full system is the required shareability domain, reads are the required
+/// access type
+pub struct LD;
+
+dmb_dsb!(LD);
+
+/// Inner Shareable is the required shareability domain, reads are the required
+/// access type
+pub struct ISHLD;
+
+dmb_dsb!(ISHLD);
+
+/// Non-shareable is the required shareability domain, reads are the required
+/// access type
+pub struct NSHLD;
+
+dmb_dsb!(NSHLD);
+
+/// Outer Shareable is the required shareability domain, reads are the required
+/// access type
+pub struct OSHLD;
+
+dmb_dsb!(OSHLD);