Summary
The goal was to configure an AXI DMA controller on a Kria K26 SoC to use physical OCM memory as a DMA target. While the example works for DRAM, mapping OCM memory into the DMA pipeline fails due to unrecognized DMA buffer allocation logic in the driver.
Root Cause
- Invalid DMA buffer registration: The AXI DMA driver’s
axidma_register_bufferAPI expects memory regions compatible with DMA, but OCM lacks required attributes (e.g., DMA coherence, cache alignment). - Driver limitations: The
axidma_dma_get_externalfunction usesdma_buf_getinternally, which may not recognize OCM memory as a valid DMA buffer even if mapped via/dev/mem. - Missing device tree configuration: OCM memory might not be exposed to the DMA subsystem as a shareable DMA pool or coherent memory region.
Why This Happens in Real Systems
- Memory attribute mismatch: DMA operations require memory regions with explicit DMA support (e.g.,
dma_memoryproperties in DT, cache attributes). OCM may lack these unless explicitly configured. - Legacy driver design: The
libaxidmaframework might prioritize simplicity over advanced memory targeting, relying on standard DMA buffers from DRAM. - Hardware constraints: OCM access via AXI DMA may require specific alignment or synchronization mechanisms not handled by the example.
Real-World Impact
- Performance bottlenecks: Using OCM instead of DRAM could reduce throughput due to slower OCM access latencies.
- Design flexibility loss: Forcing DMA to use OCM may complicate scenarios requiring dynamic memory allocation.
- Maintenance overhead: A custom driver would be needed to bypass library limitations, increasing code complexity.
Example or Code (if necessary and relevant)
// Incomplete OCM mapping code (attempted by user)
unsigned int bram_size = OCM_SIZE;
off_t bram_pbase = OCM_BASE;
bram64_vptr = (u64 *)mmap(NULL, bram_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, Bram_pbase);
// AXI DMA registration (failing call)
rc = axidma_register_buffer(axidma_dev, rx_fd, rx_address, rx_size);
This code fails because axidma_register_buffer does not validate OCM memory as a valid DMA target.
How Senior Engineers Fix It
- Modify device tree: Add
dma-memoryproperties to OCM memory region to signal DMA compatibility. - Replace with custom DMA API: Implement a driver that directly configures the AXI DMA controller to target OCM without relying on
libaxidma. - Use coherent memory: Allocate memory via
dma_alloc_coherentinstead of manual/dev/memmmapping for guaranteed DMA support.
Why Juniors Miss It
- Overlooking DMA memory requirements: Juniors may treat all mapped memory as equally valid for DMA, ignoring hardware-specific constraints.
- Relying on abstracted APIs: They might assume
axidma_register_bufferhandles all memory types without verifying underlying implementation. - Ignoring device tree impact: Juniors often miss how DT overrides affect driver behavior, especially for niche memory regions like OCM.