Signed-off-by: Boqun Feng <boqun.feng@xxxxxxxxx> --- rust/kernel/sync/atomic/arch.rs | 6 ++++++ rust/kernel/sync/atomic/arch/arm64.rs | 26 ++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 rust/kernel/sync/atomic/arch/arm64.rs diff --git a/rust/kernel/sync/atomic/arch.rs b/rust/kernel/sync/atomic/arch.rs index 3eb5a103a69a..fc280f229237 100644 --- a/rust/kernel/sync/atomic/arch.rs +++ b/rust/kernel/sync/atomic/arch.rs @@ -5,5 +5,11 @@ #[cfg(CONFIG_X86)] pub(crate) use x86::*; +#[cfg(CONFIG_ARM64)] +pub(crate) use arm64::*; + #[cfg(CONFIG_X86)] pub(crate) mod x86; + +#[cfg(CONFIG_ARM64)] +pub(crate) mod arm64; diff --git a/rust/kernel/sync/atomic/arch/arm64.rs b/rust/kernel/sync/atomic/arch/arm64.rs new file mode 100644 index 000000000000..438f37cf7df6 --- /dev/null +++ b/rust/kernel/sync/atomic/arch/arm64.rs @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0 + +//! ARM64 implementation for atomic and barrier primitives. + +use core::arch::asm; +use core::cell::UnsafeCell; + +pub(crate) fn i32_fetch_add_relaxed(v: &UnsafeCell<i32>, i: i32) -> i32 { + let mut result; + unsafe { + asm!( + "prfm pstl1strm, [{v}]", + "1: ldxr {result:w}, [{v}]", + "add {val:w}, {result:w}, {i:w}", + "stxr {tmp:w}, {val:w}, [{v}]", + "cbnz {tmp:w}, 1b", + result = out(reg) result, + tmp = out(reg) _, + val = out(reg) _, + v = in(reg) v.get(), + i = in(reg) i, + ) + } + + result +} -- 2.44.0