The privileged architecture requires Zicsr, and this chapter maps its 4096-entry address space. The design principle: access rights are encoded in the address itself, so the privilege check is pure address decode.
The fault rules, exhaustively:
| Result | |
|---|---|
| Non-existent CSR | Reserved — in practice, illegal-instruction |
| Insufficient privilege | Illegal-instruction (or virtual-instruction under H) |
| Write to a read-only CSR (csr[11:10]=11) | Illegal-instruction |
| Write to read-only BITS of a RW CSR | Those bits ignore the write — no trap |
| M-mode access to 0x7B0-0x7BF | Should raise illegal-instruction — those are debug-mode-only (0x7A0-0x7AF triggers are M-visible) |
| Permitted lower-priv access, intercepted | A higher mode MAY trap it transparently |
Table 3’s range allocation in brief: U-level 0x000/0x400/0xC00 blocks, S-level 0x100/0x500/0x900/0xD00, hypervisor 0x200/0x600/0xA00/0xE00, machine 0x300/0x700/0xB00/0xF00 — each with standard and custom sub-ranges (custom blocks like 0x800-0x8FF and 0x7C0-0x7FF are permanently safe for your own CSRs).
Hardware Designer Notes
Your CSR file’s address decoder is now fully specified: a ROM/CAM of implemented addresses, two privilege comparators, and the write-intent bit. Everything else in Part II populates the entries.
Minimal Linux-boot hart MUST
- Implement the privilege check as address decode: mode ≥ csr[9:8], and reject writes when csr[11:10]=11 — using the does-it-write bit from the u06 Table 7 logic
- Trap M-mode access to 0x7B0-0x7BF; keep 0x7A0-0x7AF for triggers
- Store counters once, expose twice (0xC00-class URO, 0xB00-class MRW)
MAY simplify / trap-and-emulate
- Put custom CSRs only in the custom ranges (0x7C0-0x7FF, 0x800-, 0xBC0-, 0xFC0-…) — they are never reclaimed by standard extensions
- Add transparent interception of lower-priv CSR accesses if you build virtualization hooks
Check yourself — CSR address conventions
1.S-mode code executes csrw mstatus, t0 (address 0x300). What happens and why, purely from the address bits?
2.Why do the counters exist at TWO addresses (cycle 0xC00 URO, mcycle 0xB00 MRW)?
3.Machine mode reads CSR 0x7B0 (a debug-mode CSR). What should happen?