74 lines
2.6 KiB
Rust
74 lines
2.6 KiB
Rust
//! DMA memory ownership and non-blocking transfer contracts.
|
|
//!
|
|
//! Board/HAL code proves the memory region, cache policy, and peripheral route.
|
|
//! Runtime code sees only prepared immutable TX ranges and terminal outcomes.
|
|
|
|
#![no_std]
|
|
|
|
/// A borrowed byte range prepared for a device-to-read DMA transfer.
|
|
///
|
|
/// This is a capability rather than a general byte-slice wrapper. It exists
|
|
/// only after a platform-selected policy proves DMA reachability and CPU-to-device
|
|
/// visibility for the selected controller.
|
|
pub struct DmaReadableBuffer<'a> {
|
|
bytes: &'a [u8],
|
|
}
|
|
|
|
impl<'a> DmaReadableBuffer<'a> {
|
|
/// Creates a DMA-read capability after platform-specific validation.
|
|
///
|
|
/// # Safety
|
|
///
|
|
/// - `bytes` is reachable by the selected DMA engine.
|
|
/// - CPU writes to `bytes` are visible before transfer begins.
|
|
/// - `bytes` remains addressable, immovable, and immutable until a terminal
|
|
/// completion or a documented route-halt outcome releases ownership.
|
|
pub const unsafe fn new_unchecked(bytes: &'a [u8]) -> Self {
|
|
Self { bytes }
|
|
}
|
|
|
|
/// Returns the DMA-visible byte range.
|
|
pub const fn bytes(&self) -> &'a [u8] {
|
|
self.bytes
|
|
}
|
|
}
|
|
|
|
/// Prepares CPU-owned bytes for a DMA transmit handoff.
|
|
///
|
|
/// A cache-disabled board validates the RAM range. A cached board must clean
|
|
/// the exact range and issue the required ordering barrier before returning.
|
|
pub trait DmaTxBufferFactory {
|
|
/// Platform-specific preparation failure.
|
|
type Error;
|
|
|
|
/// Validates and prepares a frame for device DMA reads.
|
|
fn prepare<'a>(&mut self, bytes: &'a [u8]) -> Result<DmaReadableBuffer<'a>, Self::Error>;
|
|
}
|
|
|
|
/// Terminal result reported by a DMA transmit interrupt handler.
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
pub enum TxCompletion {
|
|
/// The selected engine has no terminal event pending.
|
|
NotPending,
|
|
/// DMA reached the peripheral data-register endpoint.
|
|
///
|
|
/// This does not prove that the final UART stop bit left the wire.
|
|
Complete,
|
|
/// The engine reported a terminal transfer fault.
|
|
TransferFault,
|
|
/// The route entered a halted state and requires explicit reinitialization.
|
|
Halted,
|
|
}
|
|
|
|
/// Owns one non-blocking DMA-backed transmit route.
|
|
///
|
|
/// The caller retains the prepared range until a terminal completion or fault.
|
|
/// Implementations must not poll for a hardware state transition from this API.
|
|
pub trait DmaTxEngine {
|
|
/// Start-operation failure.
|
|
type StartError;
|
|
|
|
/// Starts one DMA transfer from a prepared readable buffer.
|
|
fn start(&mut self, buffer: DmaReadableBuffer<'_>) -> Result<(), Self::StartError>;
|
|
}
|