⚠️ VeridianOS Kernel Documentation - This is low-level kernel code. All functions are unsafe unless explicitly marked otherwise. no_std

veridian_kernel/arch/
barriers.rs

1//! Architecture-independent memory barrier abstractions.
2//!
3//! Centralizes memory barrier/fence operations so that non-arch code does not
4//! need scattered `#[cfg(target_arch)]` blocks with inline assembly.
5//!
6//! # Barrier types
7//!
8//! * [`memory_fence`] -- full read/write fence (strongest).
9//! * [`data_sync_barrier`] -- data synchronization barrier with instruction
10//!   synchronization on AArch64; equivalent to a full fence on other
11//!   architectures.
12//! * [`instruction_sync_barrier`] -- instruction stream synchronization
13//!   (AArch64 ISB, RISC-V FENCE.I, x86_64 no-op because of strong ordering).
14
15/// Full memory fence -- all reads and writes issued before this barrier are
16/// globally visible before any reads or writes issued after it.
17///
18/// * **x86_64**: `core::sync::atomic::fence(SeqCst)` -- MFENCE semantics.
19/// * **AArch64**: `dsb sy` -- Data Synchronization Barrier (full system).
20/// * **RISC-V**: `fence rw, rw` -- read/write ordering fence.
21#[inline(always)]
22pub fn memory_fence() {
23    #[cfg(target_arch = "x86_64")]
24    {
25        core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
26    }
27
28    #[cfg(target_arch = "aarch64")]
29    {
30        // SAFETY: `dsb sy` is a data synchronization barrier that ensures all
31        // preceding memory accesses are complete before subsequent ones begin.
32        // No side effects beyond ordering.
33        unsafe {
34            core::arch::asm!("dsb sy", options(nostack, nomem, preserves_flags));
35        }
36    }
37
38    #[cfg(target_arch = "riscv64")]
39    {
40        // SAFETY: `fence rw, rw` ensures all prior reads and writes are ordered
41        // before subsequent reads and writes. Standard RISC-V fence instruction.
42        unsafe {
43            core::arch::asm!("fence rw, rw", options(nostack, nomem, preserves_flags));
44        }
45    }
46}
47
48/// Data synchronization barrier with instruction synchronization.
49///
50/// On AArch64 this issues `dsb sy` followed by `isb`, which is the standard
51/// pattern used when a data store must be visible before instruction fetch
52/// proceeds (e.g., writing to a pointer that will be dereferenced
53/// immediately after).
54///
55/// On other architectures this is equivalent to [`memory_fence`] because
56/// their memory models already guarantee the necessary ordering.
57///
58/// * **x86_64**: `core::sync::atomic::fence(SeqCst)`.
59/// * **AArch64**: `dsb sy` + `isb`.
60/// * **RISC-V**: `fence rw, rw`.
61#[inline(always)]
62pub fn data_sync_barrier() {
63    #[cfg(target_arch = "x86_64")]
64    {
65        core::sync::atomic::fence(core::sync::atomic::Ordering::SeqCst);
66    }
67
68    #[cfg(target_arch = "aarch64")]
69    {
70        // SAFETY: `dsb sy` ensures all data accesses are complete; `isb`
71        // flushes the instruction pipeline so subsequent instructions see
72        // the updated data. Standard AArch64 barrier pair.
73        unsafe {
74            core::arch::asm!("dsb sy", "isb", options(nostack, nomem, preserves_flags));
75        }
76    }
77
78    #[cfg(target_arch = "riscv64")]
79    {
80        // SAFETY: `fence rw, rw` is the RISC-V full read/write ordering fence.
81        unsafe {
82            core::arch::asm!("fence rw, rw", options(nostack, nomem, preserves_flags));
83        }
84    }
85}
86
87/// Instruction synchronization barrier.
88///
89/// Ensures that all preceding instructions have completed and the instruction
90/// pipeline is flushed before subsequent instructions execute.  This is
91/// primarily needed on AArch64 and RISC-V after modifying code pages or
92/// after a data barrier that affects instruction fetch.
93///
94/// * **x86_64**: no-op -- x86_64's strong ordering model and unified cache make
95///   an explicit instruction barrier unnecessary in most scenarios.
96/// * **AArch64**: `isb` -- Instruction Synchronization Barrier.
97/// * **RISC-V**: `fence.i` -- Instruction fence.
98#[inline(always)]
99pub fn instruction_sync_barrier() {
100    #[cfg(target_arch = "x86_64")]
101    {
102        // x86_64 has a strongly ordered memory model; no explicit ISB needed.
103    }
104
105    #[cfg(target_arch = "aarch64")]
106    {
107        // SAFETY: `isb` flushes the instruction pipeline. No side effects
108        // beyond pipeline synchronization.
109        unsafe {
110            core::arch::asm!("isb", options(nostack, nomem, preserves_flags));
111        }
112    }
113
114    #[cfg(target_arch = "riscv64")]
115    {
116        // SAFETY: `fence.i` synchronizes the instruction and data streams.
117        // Required after modifying code in memory. No memory side effects.
118        unsafe {
119            core::arch::asm!("fence.i", options(nostack, nomem));
120        }
121    }
122}