Skip to content

AMBA APB · Module 3

PPROT — The Protection Attributes

PPROT, the APB4 protection attributes — the privileged, secure, and data-vs-instruction bits that carry access-control context down to peripherals, and what a subordinate does with them.

Module 2 told you that PPROT is the attribute the APB4 version added — the bus that lets an access carry "who is asking." That named the feature; this chapter gives you its exact contract: three bits, what each one means, who sets them, and who checks them. PPROT is a three-bit bus that travels with every access and describes the context of the access — privileged or not, secure or not, instruction or data — so a security-aware subordinate can decide whether to allow it. The single idea to carry: PPROT does not change what is read or written; it describes who is doing it and why, and the subordinate is free to act on that context or ignore it entirely.

1. What problem is being solved?

The problem is carrying access-control context down to the peripheral, so a subordinate can refuse an access it should not serve.

A subordinate sees an address, a direction, and data. That is enough to perform the access — but not enough to police it. In a security-aware SoC, a register might be writable only by privileged software, or readable only by the secure world. The address alone cannot express that: the same address may be legitimate from a trusted master and forbidden from an untrusted one. Something must travel with the access describing the requester's rights.

PPROT is that something. It is a three-bit bus, presented alongside PADDR in the address phase, that labels the access:

  • PPROT[0] — privileged vs unprivileged (normal) access.
  • PPROT[1] — non-secure vs secure access (note the inversion below).
  • PPROT[2] — instruction vs data access.

With these three bits riding along, a subordinate that cares can compare the access context against the protection policy of the targeted register and decide to serve it or reject it. A subordinate that does not care simply ignores PPROT. Either way, the access itself — address, direction, data — is unchanged; PPROT only adds context.

2. Why the lifecycle view is not enough

Module 2 named PPROT as the APB4 attribute add — the version-level fact that APB4 introduced a protection bus on top of APB3. That is true, but "APB4 added a protection bus" is a feature label, not a contract. To wire PPROT into a real bridge, or to check it in a real subordinate, you need three things the lifecycle view leaves unstated:

  • The exact meaning of each bit — including the inversion. PPROT[0] is 1 for privileged, PPROT[2] is 1 for instruction. But PPROT[1] is inverted: it is 1 for non-secure and 0 for secure. The version view says "carries security info"; the contract says exactly which polarity, and getting it backwards is a real, exploitable bug.
  • Who sets it, and where it comes from. PPROT is driven by the manager (the bridge), but its value usually originates further upstream — a CPU's privilege/security state, or the AxPROT attributes of an AXI master on a TrustZone-style fabric — and is propagated down through the bridge onto PPROT. The subordinate never drives it; it only samples it.
  • Who checks it, and what rejection looks like. Checking PPROT is optional and the subordinate's choice. A security-aware subordinate compares it against a per-register policy and, on a violation, rejects the access by asserting PSLVERR at completion. A subordinate that does not care leaves PPROT unconnected.

Knowing the role tells you PPROT "carries protection info." Knowing the contract tells you the polarity of each bit, the chain that sets it, and the mechanism that enforces it — which is what you actually need to build secure RTL.

3. The signal's mental model

The model: PPROT is the credential stamped on the access — and the subordinate is the door that may check it.

Think of someone arriving at a secure facility carrying a badge. The badge does not change where they want to go or what they want to do; it states who they are — their clearance level (secure or not), their rank (privileged or not), and their purpose (fetching an instruction or moving data). At the door, a guard who cares reads the badge and decides whether to let them in; an unguarded door lets everyone through. PPROT is the badge, the access is the visitor, and the subordinate is the door — guarded or not, as the designer chose.

Three refinements make the model precise:

  • The badge is stamped upstream, presented at the address phase. The originator's privilege/security/access-type state is captured into PPROT and presented with PADDR in the address phase, held stable through the access — exactly like the other access-defining signals.
  • PPROT[1] reads "non-secure," not "secure." The security bit is asserted when the access is NOT secure. A 0 on PPROT[1] means a secure access; a 1 means non-secure. Always state it as "non-secure when high" so the polarity never slips.
  • The door is optional. PPROT is information, not enforcement. The bus carries the credential, but whether anyone checks it is entirely up to the subordinate. Most peripherals ignore it; the few that guard protected state act on it.
A three-row field table decoding PPROT: bit 0 privilege (0 unprivileged, 1 privileged), bit 1 security inverted (0 secure, 1 non-secure), bit 2 access type (0 data, 1 instruction).
Figure 1 — the three PPROT bits decoded. PPROT[0] is the privilege bit: 0 = unprivileged (normal) access, 1 = privileged. PPROT[1] is the security bit and is inverted: 0 = secure, 1 = non-secure. PPROT[2] is the access-type bit: 0 = data access, 1 = instruction access. The table makes explicit which value of each bit means what, and highlights that bit 1 is asserted when the access is NOT secure — the one polarity engineers most often get wrong.

4. Real SoC / hardware context

In a real chip, PPROT is the tail end of a protection chain that starts at the CPU. A processor running secure, privileged code issues a transaction whose attributes reflect that state. On a TrustZone-style fabric those attributes ride as the AxPROT and security signals of AXI; when the access is bridged down to APB, the bridge maps them onto PPROT and presents it with the address. So the bridge drives PPROT, but it rarely invents the value — it propagates context that originated upstream.

A flow from originator to APB bridge to subordinate: the bridge maps upstream attributes onto PPROT, and a protection-aware subordinate either permits the access or rejects an unauthorized one with PSLVERR, while an indifferent subordinate ignores PPROT.
Figure 2 — how PPROT flows and is used. An originator (CPU or AXI master on a TrustZone-style fabric) issues an access carrying privilege, security, and access-type context. The APB bridge maps that context onto PPROT[2:0] and presents it in the SETUP phase with the address. The subordinate receives it: a protection-aware subordinate checks PPROT against the targeted register's policy — permitting the access (completes normally, PSLVERR low) or rejecting an unauthorized one (e.g. a secure-only register hit with the non-secure bit set), asserting PSLVERR at completion. A subordinate that does not care ignores PPROT entirely.

On the subordinate side, the question is binary: does this peripheral guard protected state or not? Most peripherals — a UART, a timer, a GPIO with no privilege model — simply leave PPROT unconnected and serve every access identically. A peripheral that does hold protected state (a secure key store, a privileged control register) reads PPROT and enforces a policy: it compares the access context against what the targeted register requires and rejects a mismatch.

Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
// Security-aware APB subordinate: reject a non-secure access to a
// secure-only register by asserting PSLVERR at completion.
// Teaching sketch — not a full slave.
// PPROT[0] = privileged (1) vs unprivileged (0)
// PPROT[1] = NON-secure (1) vs secure (0)   <-- note the inversion
// PPROT[2] = instruction (1) vs data (0)
 
logic        sel_secure_reg;   // address decode: target is a secure-only register
logic        non_secure;       // this access is non-secure
logic        access_denied;
 
assign sel_secure_reg = psel && (paddr == SECURE_KEY_REG);
assign non_secure     = pprot[1];                 // PPROT[1] high => NOT secure
assign access_denied  = sel_secure_reg && non_secure;
 
// PSLVERR is sampled at completion (PENABLE & PREADY high). A denied access
// completes the handshake but reports an error instead of acting on the data.
assign pready  = 1'b1;                             // always ready in this sketch
assign pslverr = penable && pready && access_denied;
 
// The register only updates on a permitted write — never when denied.
always_ff @(posedge pclk) begin
  if (psel && penable && pready && pwrite && sel_secure_reg && !access_denied)
    secure_key_reg <= pwdata;
end

Two things to read out of that sketch. First, the violation is expressed through PSLVERR, the same completion-edge status bit APB3 already had — PPROT enforcement reuses the error path rather than inventing a new one. Second, a denied access still completes the handshake normally (the bridge is not left hanging); it simply reports an error and leaves the protected state untouched. Refusing to assert PREADY would be wrong — that stalls the bus, it does not secure the register.

5. Engineering tradeoff table

PPROT is a deliberately thin, optional bus. Each property trades enforcement power for the simplicity APB insists on.

PPROT propertyWhat it gives upWhat it buysWhy it is correct for APB
Three bits onlyRich, fine-grained permission modelsA tiny, cheap attribute busAPB peripherals need coarse context, not an MMU
Descriptive, not enforcingBus-level access blockingA subordinate that may choose to checkEnforcement belongs to the device that owns the state
Optional to checkGuaranteed protection everywhereZero cost for peripherals that do not careMost peripherals hold no protected state
Driven by the manager/bridgeSubordinate-set attributesOne driver, context propagated from upstreamRights originate at the CPU/fabric, not the slave
Rejection via PSLVERRA dedicated security-error channelReuse of the existing completion-edge error bitNo new mechanism; violations ride the error path

The throughline: PPROT carries just enough context for a security-aware subordinate to make an allow/deny decision, and nothing more. It enforces nothing on its own, costs nothing for peripherals that ignore it, and reuses PSLVERR for rejection — keeping APB's protection story as cheap and optional as the rest of the bus.

6. Common RTL / waveform mistakes

7. Interview framing

PPROT is a strong discriminator because a precise answer proves you understand both the bit-level contract and the security model around it, while a vague one ("it's the protection signal") proves neither. Interviewers ask "what does PPROT carry?" or "how would a subordinate enforce security on APB?"

The strong answer states the contract, then the model: PPROT is the APB4 three-bit protection bus, presented with the address — PPROT[0] privileged vs unprivileged, PPROT[1] non-secure (high) vs secure (low, note the inversion), PPROT[2] instruction vs data. Then frame the flow: the bridge drives it, but the value propagates down from the CPU or an AXI/TrustZone-style fabric; the subordinate optionally checks it against a per-register policy and rejects a violation by asserting PSLVERR at completion, while still completing the handshake and leaving protected state untouched. The depth point that lands: PPROT describes, it does not enforce — enforcement is the subordinate's choice, and it reuses the existing error path rather than inventing a new one. Calling out the PPROT[1] inversion unprompted signals you have actually written this RTL.

8. Q&A

9. Practice

  1. Decode the bits. For PPROT = 3'b010, state whether the access is privileged or not, secure or not, and instruction or data — and watch the PPROT[1] inversion.
  2. State the contract. From memory, write the meaning of each PPROT bit including which value of PPROT[1] means non-secure, and explain why the polarity matters in a security check.
  3. Trace the chain. Describe how the security state of a CPU running secure, privileged code reaches a peripheral's PPROT input, naming the role of the AXI fabric and the APB bridge.
  4. Write the check. Sketch the condition a subordinate uses to deny a non-secure write to a secure-only register, and explain why it still asserts PREADY and reports via PSLVERR rather than stalling.
  5. Find the bug. A subordinate treats PPROT[1] high as "secure" and permits those accesses. State exactly what attacks this enables and how to fix the polarity.

10. Key takeaways

  • PPROT is the APB4 three-bit protection bus — presented with the address, carrying the context of the access, not changing the access itself.
  • The bits are PPROT[0] privileged, PPROT[1] non-secure, PPROT[2] instruction — and PPROT[1] is inverted: high means non-secure, low means secure. Getting that polarity wrong inverts a security policy.
  • The manager/bridge drives it; the value propagates from upstream — a CPU's privilege/security state or an AXI master's AxPROT on a TrustZone-style fabric, mapped down onto PPROT.
  • PPROT describes, it does not enforce. Checking it is the subordinate's optional choice; a peripheral with no protected state simply ignores it and stays fully correct.
  • A security-aware subordinate rejects a violation via PSLVERR at completion — completing the handshake while leaving protected state untouched, reusing the existing error path rather than stalling.
  • It is descriptive metadata onlyPPROT never alters address, direction, data, or the byte lanes that PSTRB controls; it only adds the ability to refuse.