hal::dma
DMA reachability — the one fact a driver needs before pointing an engine at a buffer.
A DMA engine reaches only certain address ranges: on the ESP32 that is
internal DRAM (0x3FFAE000..0x40000000), on a Cortex-M it is a different
SRAM window, and external PSRAM or flash-mapped memory is off-limits to
both. A driver that starts a transfer into an unreachable buffer gets
silence or garbage, not a fault — so the check has to happen first.
[DmaReach] is that check, behind a trait so the rule lives with the SoC
and a portable driver does not hard-code one chip’s memory map. It is the
first of the hal seams the second-architecture plan calls for
(doc/plan-arm32.md, Phase 1.1).
Structs
Section titled “Structs”DmaHandle
Section titled “DmaHandle”struct DmaHandle { /* private fields */ }A handle to a DMA-safe buffer the broker handed out.
Lives here, not in the kernel, so a driver and api can name it without
naming the kernel; the kernel’s broker builds it with [DmaHandle::new]
and re-exports the type from dma_broker.
It carries the buffer’s already-resolved address rather than an offset: the pool base is a linker symbol only the kernel can see, so the kernel does the arithmetic once, at allocation, and every reader here just reads the answer.
Implements: Clone, Copy, Debug
DmaTransferId
Section titled “DmaTransferId”struct DmaTransferId(/* private */);Identifies one transfer, from the broker’s begin to its await_transfer.
Lives here rather than in the kernel so a driver — and api — can name it
without naming the kernel; the kernel re-exports it from dma_broker.
Implements: Clone, Copy, Debug, Eq, PartialEq, StructuralPartialEq
DmaError
Section titled “DmaError”enum DmaError { PoolExhausted, NotOwner, Timeout,}Why the kernel’s DMA broker refused or lost a transfer.
Defined here rather than in the kernel so a driver can name it without
naming the kernel; the kernel re-exports it from dma_broker.
Implements: Clone, Copy, Debug, Display, Eq, From, PartialEq, StructuralPartialEq
Traits
Section titled “Traits”DmaReach
Section titled “DmaReach”trait DmaReach: Send + Sync { fn reachable(&self, addr: u32, len: u32) -> bool}Whether a byte range is reachable by this SoC’s DMA engines.
Functions
Section titled “Functions”range_within
Section titled “range_within”const fn range_within(addr: u32, len: u32, low: u32, high: u32) -> boolWhether every byte of [addr, addr + len) lies within [low, high).
The shared building block for [DmaReach::reachable] impls whose reachable
memory is a single contiguous window: only low/high differ per chip.
len == 0 is vacuously within; a range whose last byte would overflow
u32 is rejected rather than wrapped.