Setup: CPU writes config buffer, kicks DMA to read it. DMA reads zeros. CPU write waveform looks correct. DMA read waveform looks correct. Block VIP passes.
Tag CPU write txn: id=2 addr=0x8000_1000. Tag DMA read txn: id=7 addr=0x8000_1000.
Check CPU write cacheable/shareable attributes on AW channel.
Trace path: CPU -> L2 -> interconnect -> DRAM. DMA path: DRAM direct.
Under the stated non-coherent DMA model, discover that the bridge changes the attribute/domain so the CPU's dirty cache line is not observed by the DMA path.
Apply the platform DMA API's direction-specific ownership/cache-maintenance contract, use a suitable non-cacheable allocation, or provide a correctly configured hardware-coherent path; do not prescribe a generic clean-plus-invalidate sequence.
Outcome: For this defined model, the bridge changed the coherency contract. The repair must align allocation, DMA ownership/cache maintenance and hardware participation with the platform specification.
Lesson: Locally legal handshakes do not establish that two agents observe the same data version; trace the attribute and ownership contract end to end.
Setup: Firmware reads STATUS register, sometimes gets 0xDEADBEEF (reset value) instead of live status. 1 in 50 reads. No bus errors.
Correlate failures with concurrent DMA on same peripheral.
STATUS at 0x1000, NEXT_REG at 0x1004. Firmware uses 32-bit reads.
Bridge to peripheral is 64-bit. Bridge merges adjacent register reads.
When DMA interleaves, bridge issues 64-bit read spanning 0x1000-0x1007.
Upper 32 bits from wrong cycle aliased into STATUS read.
Outcome: Width conversion bridge served wrong 32-bit lane. Fix: peripheral supports byte strobes, bridge config for narrow access.
Lesson: Transaction layer includes access width and byte enables — not just address.