Skip to content

AMBA AHB · Module 11

Illegal Address Behavior

What happens when an AHB master accesses an illegal address — an unmapped address routes to the default slave's ERROR, a real slave can also ERROR on accesses it can't satisfy; the master aborts and the CPU takes a bus fault. Illegal access is defined behavior: it always completes (no hang) and is reported (no silent corruption).

Chapter 11.3 introduced the default slave; this chapter takes the broader view of illegal address behavior — what counts as an illegal access, how the resulting error propagates from the bus all the way to software, and the governing principle: on AHB, an illegal access is defined behavior, not undefined. An illegal access can be an unmapped address (caught by the default slave's ERROR) or a real slave rejecting an access it can't satisfy (a write to a read-only region, an unsupported transfer size, a protection violation) — both produce the two-cycle ERROR response. The master then aborts the transfer (discards any read data, cancels any pipelined follow-on) and signals the core, which takes a bus-fault exception, running a fault handler that can diagnose the access. So the bus guarantees liveness (the access always completes — no hang) and observability (the error is reported — no silent corruption). This chapter covers the kinds of illegal access, the error-propagation path, and why "defined behavior" is the key property.

1. What Is It?

Illegal address behavior is how the AHB system responds when a master issues an access that can't be legitimately served. Two main cases, both ending in an ERROR response:

  • Unmapped address. HADDR matches no region → the decoder selects the default slave → it returns the two-cycle ERROR (chapter 11.3).
  • Slave can't satisfy it. The addressed real slave rejects the access — e.g. a write to a read-only region, an unsupported transfer size (HSIZE the slave doesn't handle), or a protection violation (an unprivileged access to a privileged register) → that slave returns the two-cycle ERROR.
Three panels: unmapped address (default slave ERROR), slave-can't-satisfy (slave ERROR), and the common handling (master aborts, CPU bus fault).
Figure 1 — kinds of illegal access, all ending in ERROR. Left: an unmapped address (no region matches) → the decoder selects the default slave → two-cycle ERROR. Middle: the addressed slave can't satisfy the access (write to read-only, unsupported size, protection violation) → that slave returns two-cycle ERROR. Right: either way the handling is the same — the master sees HRESP = ERROR, aborts the transfer, and the CPU takes a bus fault. A defined, reported event.

So illegal address behavior is the whole system's defined reaction to a bad access — not just the default slave, but any ERROR-producing situation, and the chain of events it triggers: ERROR response → master abort → CPU fault → fault handler. The unifying point is that all of these are defined: the protocol specifies exactly what happens (a two-cycle ERROR, a master abort, a fault), so there's no undefined behavior, no hang, no silent corruption. The access is rejected cleanly and visibly. So illegal address behavior is the AHB system's defined, observable handling of accesses that can't be served.

2. Why Does It Exist?

Defined illegal-address behavior exists because real systems will issue bad accesses (bugs, wild pointers, attacks, misconfigurations), and the bus must handle them deterministically — completing the access (so the system doesn't hang) and reporting it (so the bug is visible) — rather than hanging or corrupting silently.

The inevitability of bad accesses is the root motivation: in any real system, masters will sometimes access addresses they shouldn't — a software bug dereferences a wild pointer, a DMA descriptor has a corrupted address, a driver uses a stale base address, a security exploit probes memory, or a register is misconfigured. These will happen. So the bus must have a defined behavior for them — leaving it undefined would mean unpredictable, system-specific, often catastrophic results. So defined illegal-address behavior exists because bad accesses are inevitable and the bus needs a deterministic response. So the protocol specifies what happens: the ERROR response and its propagation.

The reason the access must complete (not hang) is liveness (chapter 11.3): if a bad access didn't complete — e.g. an unmapped access asserting no HSEL, no HREADY — the master would hang, freezing the system. So the defined behavior completes the access: the ERROR response (or the default slave's ERROR) drives HREADY high, finishing the transfer, so the master proceeds. So illegal-address behavior exists to guarantee completion — the access ends (with an error), the master moves on, the bus stays live. So liveness is one reason the behavior is defined-to-complete.

The reason the access must be reported (not silently OKAY'd) is observability (chapter 11.3): a silently-succeeded bad access (returning OKAY, garbage data, dropped write) would hide the bug — the system would misbehave with no clue why. So the defined behavior reports the error: HRESP = ERROR → the master/CPU sees it → a fault → diagnosable. So illegal-address behavior exists to surface the bug — making it observable and debuggable. So observability is the second reason. So defined illegal-address behavior exists because bad accesses are inevitable, and the bus must handle them deterministically: completing the access (liveness — no hang) and reporting it (observability — no silent corruption). "Defined behavior" means both the protocol response (two-cycle ERROR) and the system response (master abort, CPU fault) are specified — so a bad access has a known, safe, visible outcome.

3. Mental Model

Model illegal-address behavior as a bank teller handling a malformed request — if you ask for an account that doesn't exist, or try to withdraw from an account you're not authorized for, the teller doesn't freeze (leaving you standing forever) and doesn't silently pretend it worked (handing you nothing while marking it done); instead they hand back a clear "declined: invalid request" slip, and a manager is notified — the transaction is finished, and the problem is on record.

At a bank, you hand the teller a request. Most are valid (legal accesses). But some are malformed: an account number that doesn't exist (an unmapped address), or a withdrawal from an account you're not authorized for (a protection violation / write-to-read-only). A bad teller might freeze — unable to process it, leaving you standing at the window forever (a hang) — or silently pretend it succeeded — taking your slip, doing nothing, and waving you off as if done (silent corruption: you think it worked, it didn't). A good teller (the AHB system) does neither: they hand back a clear "declined: invalid request" slip (the ERROR response) — so the transaction is finished (you're not stuck waiting) — and they notify a manager (the CPU fault / fault handler) — so the problem is on record and can be investigated. The transaction completed (with a decline), and the issue is visible. Predictable, terminating, recorded.

This captures illegal-address behavior: the malformed request = the illegal access; the nonexistent account = an unmapped address; the unauthorized withdrawal = a protection/read-only/size violation; freezing = a hang (what doesn't happen); silently pretending = silent corruption (what doesn't happen); the "declined" slip = the ERROR response (the access completes); notifying the manager = the CPU bus fault and handler (the error is reported). The good teller declines clearly and records the issue — defined, completing, observable.

Watch the master's reaction to an ERROR cycle by cycle:

Master aborts on an illegal-access ERROR

4 cycles
The master issues a NONSEQ transfer to a bad address. The slave drives HRESP = ERROR for two cycles (HREADY low then high). The master cancels its follow-on transfer by driving HTRANS = IDLE during the error, and the transfer completes with the error.ERROR cycle 1 (HREADY low) → master cancels follow-on (HTRANS=IDLE)ERROR cycle 1 (HREADY …ERROR cycle 2 (HREADY high) → transfer completes; master signals coreERROR cycle 2 (HREADY …HCLKHTRANSNONSEQIDLEIDLENONSEQHADDRbad_addrbad_addrbad_addrnextHRESPOKAYERRORERROROKAYHREADYt0t1t2t3
Figure 2 — the master's reaction to an illegal-access ERROR. The master issues a transfer to a bad address (cycle 0, HTRANS = NONSEQ). The selected slave (or default) drives the two-cycle ERROR: HRESP = ERROR with HREADY low (cycle 1), then HRESP = ERROR with HREADY high (cycle 2). Seeing the first ERROR cycle, the master cancels any pipelined follow-on transfer — it drives HTRANS = IDLE (cycle 1) rather than continuing. At cycle 2 the transfer completes with the error; the master discards read data and signals the core (bus fault). The two-cycle ERROR gives the master the cycle it needs to cancel the follow-on.

The model's lesson: the good teller declines clearly and notifies a manager — the request finishes and the problem is on record. In the waveform, the ERROR completes the transfer (no hang) and the master aborts + faults (reported) — defined, terminating, observable.

4. Real Hardware Perspective

In hardware, illegal-address behavior is the standard two-cycle ERROR response (from the default slave or a real slave) plus the master's ERROR-handling logic and the core's fault mechanism — all standard AHB and CPU features, not special cases.

The ERROR-response source can be either the default slave or a real slave. The default slave errors on unmapped addresses (chapter 11.3). A real slave errors when it can't satisfy a legal-address access: it decodes the access (HWRITE, HSIZE, the sub-address, protection bits like HPROT) and, if it can't serve it — a write to a read-only register, a size it doesn't support, an HPROT-indicated privilege it requires but the access lacks — it drives the two-cycle ERROR instead of completing normally. So any slave can be an ERROR source; the default slave is just the one for unmapped addresses. So in hardware, the ERROR can originate from the decoder's default path or from a real slave's reject logic — same two-cycle ERROR protocol either way.

The master's ERROR handling is the standard response logic (chapter 7.x): the master samples HRESP in the data phase. AHB's ERROR is two cycles — first cycle HRESP = ERROR with HREADY low, second cycle HRESP = ERROR with HREADY high — specifically so the master gets a cycle of warning (the first ERROR cycle) to cancel any transfer it had already pipelined (issued the address phase for). On seeing the first ERROR cycle, the master drives HTRANS = IDLE for the would-be-next transfer (canceling it), and on the second cycle the errored transfer completes. The master then discards any read data (it's invalid on an error) and flags the error to the core. So in hardware, the master's ERROR handling uses the two-cycle structure to cleanly abort the errored transfer and cancel the follow-on. (This is the same ERROR handling covered in How the Master Reacts — illegal addresses are one source of that ERROR.)

A four-stage propagation chain: slave drives ERROR, master aborts, CPU takes a bus fault, fault handler diagnoses.
Figure 3 — error propagation from bus to software. The slave (real or default) drives the two-cycle ERROR on HRESP. The master samples HRESP = ERROR, aborts the transfer, and discards read data. The master signals the CPU core, which takes a bus-fault/abort exception. The fault handler runs, often reading a captured fault address and status, so software can diagnose the illegal access. A bad address becomes a clean, attributable software fault — not silent corruption, not a hang. The two-cycle ERROR (HREADY low then high) lets the master cancel any pipelined follow-on.

The core/software side completes the chain: the master (often the CPU's bus interface) signals the error to the core, which takes a bus-fault (or abort) exception. Many cores capture the faulting address and status (a fault-address register, fault-status register) so the handler can report which access faulted. The fault handler can then log it, recover (kill the offending task, reset a subsystem), or halt for debug. So in hardware, the illegal access ends as a CPU exception with diagnostic info — turning the bus-level ERROR into a software-visible, attributable fault. So the whole hardware path is: ERROR source (default or real slave) → master abort (two-cycle handling, cancel follow-on, discard data) → CPU bus fault (with captured address/status) → fault handler. All standard, all defined.

5. System Architecture Perspective

At the system level, defined illegal-address behavior is a robustness and safety feature — it's what lets a system contain and recover from bad accesses, and it's foundational for memory protection, security, and fault-tolerant design.

The containment property is the first system point: a defined ERROR response contains a bad access — it doesn't hang the bus (liveness) and doesn't silently corrupt (observability), so a single bad access can't bring down or silently corrupt the whole system. The access is isolated to a clean fault. So at the system level, defined illegal-address behavior provides fault containment — a bad access is a localized, handled event, not a system-wide catastrophe. This is essential for any system that must keep running despite bugs (most embedded systems) — one errant access faults and is handled, rather than freezing the SoC.

The recovery and fault-tolerance view extends this: because the access faults cleanly (a defined exception with diagnostic info), the system can recover. A fault handler can kill and restart the offending task (in an RTOS), reset a misbehaving peripheral, log the fault for later analysis, or enter a safe state — all because the bad access produced a clean, attributable fault rather than a hang or corruption. So defined illegal-address behavior is the foundation of recoverable fault handling. In safety-critical systems (automotive, medical, aerospace), this is mandatory: the system must detect illegal accesses and respond safely, which requires exactly this defined-error behavior. So at the system level, defined illegal-address behavior enables recovery and is a building block of functional safety.

The protection and security view is the third system point: illegal-address behavior is the enforcement mechanism for memory protection and security. A memory protection unit (MPU) or MMU defines which regions a given context (privileged/unprivileged, secure/non-secure) may access; a violation is enforced by generating an ERROR (a fault) — exactly the illegal-address mechanism. TrustZone-style security similarly faults non-secure accesses to secure regions. So the defined ERROR-and-fault behavior is how protection and security boundaries are enforced at the bus level — a violation becomes a fault. So at the system level, illegal-address behavior is the enforcement substrate for protection and security, not just a bad-pointer catcher. So defined illegal-address behavior is a foundational robustness/safety/security feature: it contains bad accesses (no hang, no silent corruption), enables recovery (clean, attributable faults), and enforces protection/security (violations become faults). It turns "a bad access" from an undefined catastrophe into a managed, observable, recoverable event — which is why "illegal access is defined behavior" is such an important property of a well-designed bus.

6. Engineering Tradeoffs

Illegal-address behavior embodies the defined-error, fault-reporting design.

  • Defined ERROR vs undefined behavior. A defined ERROR response (complete + report) gives liveness and observability at the cost of the ERROR logic (default slave, slave reject logic, master handling). Undefined behavior is "simpler" but catastrophic (hangs, silent corruption). The defined behavior is non-negotiable.
  • Complete-with-error vs hang. Completing the access with an ERROR keeps the bus live; hanging (no response) freezes it. Always complete — the ERROR response drives HREADY high.
  • Report (ERROR) vs hide (OKAY). Reporting via ERROR surfaces the bug (CPU fault); hiding via OKAY causes silent corruption. Always report illegal accesses with ERROR.
  • Fault capture vs bare fault. Capturing the faulting address/status (fault registers) aids diagnosis at a small hardware cost; a bare fault (no info) is cheaper but harder to debug. Most cores capture fault info; safety systems require it.
  • Slave-level reject vs decode-only. Slaves that reject illegal accesses they're addressed for (read-only writes, bad sizes, protection) catch more bugs at the cost of slave reject logic; decode-only (only unmapped errors) is simpler but misses these. Robust slaves implement reject logic.

The throughline: on AHB, illegal address behavior is defined: an illegal access (unmapped → default slave, or a real slave rejecting a write-to-read-only / unsupported-size / protection violation) produces the two-cycle ERROR; the master aborts (cancels the follow-on, discards data) and the CPU takes a bus fault. The access always completes (liveness — no hang) and is always reported (observability — no silent corruption). This containment-with-reporting is the foundation of fault tolerance, recovery, and protection/security enforcement.

7. Industry Example

Trace illegal accesses through a system.

A system has a CPU, an MPU (memory protection unit), and the usual memory map.

  • Wild pointer (unmapped). A bug dereferences an uninitialized pointer → read to an unmapped address. The decoder selects the default slave → two-cycle ERROR. The CPU's load faults; the bus-fault handler reads the captured fault address, logs the faulting address, and (in an RTOS) kills the offending task. The bug is contained and diagnosed.
  • Write to read-only (slave reject). Code accidentally writes to a flash/ROM region that's read-only. The flash controller (the addressed slave) sees HWRITE = 1 to a read-only region and returns the two-cycle ERROR (rather than silently dropping the write or corrupting flash). The CPU faults; software learns of the illegal write. The read-only invariant is enforced.
  • Protection violation (MPU/HPROT). An unprivileged thread tries to access a privileged peripheral. The MPU (or the slave checking HPROT) detects the privilege mismatch and generates an ERROR. The CPU takes a memory-management/bus fault; the OS handles it (e.g. signals the thread, or terminates it). The protection boundary is enforced as a fault.
  • Unsupported size. A master issues a word (32-bit) access to a byte-only register. The slave, not supporting that size, returns ERROR. The master faults; the bug (wrong access size) is surfaced.
  • Recovery. In each case, the fault handler can recover — restart the task, reset the peripheral, log and continue — because the access faulted cleanly with diagnostic info, rather than hanging the bus or silently corrupting state.

The example shows illegal-address behavior across its forms: unmapped (default slave), slave-reject (read-only, size), and protection (MPU/HPROT) — all producing a defined ERROR that becomes a CPU fault, contained and diagnosable, enabling recovery. This is the robustness that defined illegal-address behavior provides: bad accesses become managed faults, not catastrophes.

8. Common Mistakes

9. Interview Insight

Illegal-address behavior is a robustness interview topic — the "defined, not undefined" framing, the complete-and-report properties, and the discard-read-data rule are the signals.

A summary card on illegal address behavior: ERROR sources, master abort and bus fault, and the liveness + observability properties.
Figure 4 — a strong answer in one card: an unmapped address goes to the default slave, a can't-satisfy access is rejected by the slave, both return the two-cycle ERROR; the master samples HRESP = ERROR, aborts and discards read data, and the CPU takes a bus fault; the access always completes (no hang) and is reported (no silent corruption) — liveness plus observability. The senior point: illegal access is defined behavior — an ERROR response that becomes a CPU fault, not undefined.

The answer that lands frames it as defined behavior with two guarantees: "On AHB, an illegal address access is defined behavior, not undefined. There are two cases. An unmapped address routes to the default slave, which returns the two-cycle ERROR response. And a real slave can reject an access it can't satisfy — a write to a read-only region, an unsupported transfer size, or a protection violation — also returning the two-cycle ERROR. Either way, the master samples HRESP = ERROR in the data phase, aborts the transfer, discards any read data — which is invalid on an error — and signals the core, which takes a bus-fault exception, often with the faulting address captured, so software can diagnose it. The two key properties: the access always completes — the ERROR drives HREADY high, so there's no hang (liveness) — and it's always reported — the master and CPU see the error, so there's no silent corruption (observability). This makes illegal accesses contained and recoverable, and it's the enforcement mechanism for memory protection and security — a violation becomes a fault. The two-cycle ERROR structure exists so the master can cancel any pipelined follow-on transfer in the first error cycle." The defined-behavior framing, the complete-and-report properties, and the discard-data rule are the senior signals.

10. Practice Challenge

Reason from illegal-address behavior.

  1. The two cases. Describe the two kinds of illegal access and how each produces an ERROR.
  2. Two guarantees. Explain the completion (liveness) and reporting (observability) properties and why both matter.
  3. Read the waveform. From Figure 2, explain what the master does in the first ERROR cycle and why (the follow-on cancel).
  4. Discard data. Explain why the master must discard the read data on an ERROR and what happens if it doesn't.
  5. Protection. Explain how illegal-address behavior is the enforcement mechanism for an MPU or TrustZone.

11. Key Takeaways

  • Illegal access is defined behavior on AHB, not undefined — a two-cycle ERROR response, a master abort, and a CPU bus fault: a known, safe, observable outcome.
  • Two sources of illegal-access ERROR — an unmapped address (→ default slave) and a real slave rejecting an access it can't satisfy (write to read-only, unsupported size, protection violation).
  • The access always completes (liveness) — the ERROR drives HREADY high, so the master never hangs — and is always reported (observability) — the master/CPU faults, so no silent corruption.
  • The master must discard the read data on ERROR — HRDATA is invalid; committing it would propagate garbage. Report the fault and discard the data together.
  • The two-cycle ERROR lets the master cancel any pipelined follow-on transfer (in the first error cycle) before the transfer completes (second cycle).
  • It's a robustness/safety/security foundation — defined illegal-address behavior provides fault containment, enables recovery (clean attributable faults), and is the enforcement mechanism for memory protection and security (MPU/MMU/TrustZone violations are this mechanism).

12. What Comes Next

You now understand illegal-address behavior — the defined, completing, reported handling of bad accesses, and its role in protection and safety. The next chapters finish Module 11:

  • Sparse Memory Maps (next) — decoding for sparse, non-power-of-two regions (range decode, partial decode, aliasing).
  • Peripheral Selection — how peripherals are selected and addressed on the bus.

To revisit the default slave and the ERROR response this builds on, see The Default Slave, The ERROR Response, and How the Master Reacts.