DmaFence

Trait DmaFence 

Source
pub unsafe trait DmaFence:
    Debug
    + Send
    + Sync
    + Copy {
    // Required methods
    fn release<T>(self, buf: *mut [T]);
    fn acquire<T>(self, buf: *mut [T]);
}
Expand description

Synchronization primitives for safely sharing memory with DMA peripherals.

An implementation of acquire and release memory fence operations to expose memory reads and writes by Rust and DMA peripherals to each other. These operations are from the perspective of Rust and the Tock kernel: a memory buffer is released to the DMA peripheral, and then after the DMA operation is fully completed, acquired back from the DMA peripheral.

When starting a DMA operation over a buffer prepared from Rust, it is important that the buffer’s current contents are actually observable by the DMA hardware. Similarly, when a DMA operation is finished, we must ensure that Rust can see the latest buffer contents, as written by a DMA peripheral. However, instruction reordering by both the compiler, hardware, and non cache-coherent platforms complicate this story. These optimizations can mean that a write from within Rust may not be visible to a DMA peripheral, or a write performed by a DMA peripheral may not be visible to Rust.

This trait provides acquire and release memory fences that recover these guarantees for DMA buffers in the presence of compiler reordering and, if present on the target platform, hardware reordering or non-coherent caches.

Ordinarily, we’d use the built-in core::sync::atomic::fence for this, but that explicitly cannot be used to establish synchronization among non-atomic accesses. Additionally, certain platforms require platform-specific instructions to synchronize memory: for instance, the RISC-V unprivileged spec (version 20250508) states that “[n]on-coherent DMA may need additional synchronization (such as cache flush or invalidate mechanisms); currently any such extra synchronization will be device-specific” 1. Therefore, Tock uses a DMA-specific trait implemented by its target architecture and platform crates.

§Implementations

Implementations may assume this trait is only used for DMA peripherals, where hardware has access to memory separate from normal load and store instructions executed on the CPU. Implementations do not need to provide any synchronization between loads and stores, for example to support multi-core execution. Implementations must correctly synchronize for all possible DMA operations on the chip.

Implementations may use any chip-specific DMA synchronization features that may exist on a particular microcontroller.

§Safety

This is an unsafe trait, as users of it rely on correct acquire and release implementations to maintain soundness.

Incorrect implementations of this trait can introduce undefined behavior. For example, an incorrect acquire operation could cause DMA-issued writes to memory to be visible to Rust only after a shared or immutable reference to this buffer is made accessible, which effectively violates Rust’s no-alias assumptions.

Required Methods§

Source

fn release<T>(self, buf: *mut [T])

Expose prior writes to in-memory buffers to subsequent DMA operations.

Specifically, this function must ensure that any writes from Rust to the buffer described by ptr and len before this function, are visible to any DMA operations, as long as these operations are initiated by MMIO read or write operations issued after this function returns.

Source

fn acquire<T>(self, buf: *mut [T])

Expose prior writes by DMA peripherals to subsequent memory reads.

Specifically, this function must ensure that any Rust reads of the buffer described by ptr and len, performed after this function returns, reflect all writes made by DMA operations finished before this function ran.

This function must be called after the program has observed that the DMA operation finished, by reading a status field through an MMIO or memory read.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§