A write buffer in the interconnect speeds up memory writes by accepting them at once and finishing them later. Someone points the same buffer at a peripheral: a write to its "start" register is accepted at once, and the driver's next instruction, which assumes the peripheral has started, runs before the write arrives. The buffer did nothing wrong. It had no way to know that this write, unlike the memory writes, must not be delayed.
Why does a transaction carry information about itself beyond its address and data, and who uses it?
The obvious view is that the target knows what it is, so the address says everything: a memory address may be cached and buffered, a peripheral address may not. But the agents that cache, buffer, reorder, check permissions and prioritise are between the requester and the target. They see the address but not the target's nature, and looking it up in a central table at every hop would be slow and fragile. So the requester, which does know (its page tables and its privilege level tell it), attaches a description to every transaction.
Attribute | Says | Who uses it |
|---|---|---|
Bufferable | The write may be acknowledged before it reaches the target | Write buffers, interconnect: may answer early (lesson 7.4) |
Cacheable / modifiable | The transaction may be cached, merged, split or prefetched | Caches, interconnect: may merge writes or read more than asked |
Allocate hints | Whether a cache should keep the line after a miss | Caches |
Privileged | The requester was running in a privileged mode | Targets and firewalls: protect control registers from user code |
Secure / non-secure | Which security world the requester belongs to | Firewalls and secure memory: block non-secure access to secure regions (Part 14) |
Instruction / data | Whether this is an instruction fetch | Protection units: forbid executing from data regions |
Priority (QoS) | How urgent the request is | Arbiters and memory controllers (Part 8) |
The pattern is always the same: the requester knows something about the request that agents along the path cannot work out from the address, so it says so, and each agent reads only the attributes it cares about.
Device registers must be non-bufferable and non-modifiable. A read that is merged, prefetched or repeated can pop a FIFO or clear a status bit (lesson 5.4); a write that is delayed or merged can start a device at the wrong time.
Memory should be cacheable and bufferable. Marking normal memory as device memory is safe but slow: every access goes all the way to the target.
Security attributes must be set by trusted hardware, not by the software that the check is meant to restrict. Otherwise the check is a suggestion.
Protocol | Attributes |
|---|---|
AXI | AxCACHE (bufferable, modifiable and allocate hints), AxPROT (privileged, secure or non-secure, instruction or data), and from AXI4 AxQOS (a 4-bit priority) and AxREGION. |
APB | PPROT (from APB4): privileged, secure, instruction or data. |
PCI Express | Attribute bits in the packet header, such as Relaxed Ordering and No Snoop, and a traffic class for priority (Part 7). |
The opening story: the peripheral's address range was marked bufferable in the processor's memory attributes, so the interconnect acknowledged the "start" write immediately. The fix was to mark the range as device memory, non-bufferable, so the write was acknowledged only by the peripheral itself. A related bug (illustrative) marked a FIFO's data register as modifiable: the interconnect turned two narrow reads into one wide read, popping two entries, and returned half of the data to nobody.
Reading it pops a byte; an agent allowed to merge, split or prefetch could read it more or fewer times than software asked, losing data.
Every access goes to the target unmerged and unbuffered: correct but slow, with no caching or write buffering.
A transaction carries attributes because agents along the path cannot tell from the address how it may be handled.
Bufferable and modifiable allow early acknowledgement and merging; device registers must allow neither.
Privilege and security attributes must be set by trusted hardware and carried across every bridge.