A driver reports an access that traps, and several different faults look identical from the core: an unmapped address, a secure denial, a reserved slot and an unmapped register offset all arrive as a bus error. Guessing wastes the afternoon; reading the response code against the map takes a minute. This lesson turns the error table into a diagnostic drill.
The drill has three steps. First, classify by response: DECERR means no slave claimed the address, so look for the map holes H1, H2 and H4. SLVERR means something below the interconnect answered no: a security refusal, a reserved APB slot (H3), or an unmapped register offset inside a slave. SLVERR is therefore not proof that the address is a real register. Second, localise by level: a refusal from inside the APB window points at the slot check or the APB default slave, a refusal on SRAM1 points at the interconnect filter. Third, reproduce from both states: the same access from secure and non-secure, and from CPU and SBR where both can reach, splits attribute bugs from wiring bugs. The table below is the whole drill on NanoSoC addresses.
# not-run: NanoSoC denial diagnosis table, NanoSoC teaching values
0x2001_0000 non-secure .... SLVERR from interconnect filter: secure-only region.
0x4000_6000 non-secure .... SLVERR via PSLVERR: secure-only RSTPWR slot.
0x4000_7000 either state ... SLVERR via PSLVERR: H3 reserved, APB default slave.
0x4000_0014 either state ... SLVERR via PSLVERR: DMA offset 0x14 is unmapped (0x14 to 0xFF).
0x4000_0100 either state ... completes, no error: alias of the DMA at 0x4000_0000.
0x5000_0000 either state ... DECERR: hole H4, no select, interconnect default.
SBR job from SRAM1, NS set . SBR STATUS.ERR on beat zero: master attribute.
Same job, NS cleared ..... completes: attribute fixed, wiring proved good.The fault handler logs address, response code and security state, so field returns carry the diagnosis.
The diagnosis table above, or its equivalent, is in the integration specification with the responder named per row.
No production software treats a denial as a retryable error: denials are deterministic and retrying hides attacks.
Sweep the denial table from software during bring-up: one access per row, confirming each code from each state. If a row that should deny instead hangs, the error path is broken, not the policy: check the default slave, the denied-burst responder and the bridge error propagation before touching any filter. If a row that should allow denies, read the filter attribute and the master sideband at the filter inputs; the mismatch is visible there. Do not read SLVERR as mapped: confirm the offset against the register map, because three different causes share the code.
Correct behaviour: H3 is reserved and the APB default slave answers PSLVERR, which the bridge turns into SLVERR. The fix for the driver is to stop going there, not to relax any filter.