Every hart carries a separate address space of 4096 CSRs csr Control and Status Register: one of a separate 4096-entry per-hart address space (csr specifier = instruction bits 31:20), accessed only via the atomic read-modify-write Zicsr instructions (CSRRW/S/C and immediate forms). defined in ch. I·6 — open in glossary — the interface through which the entire privileged architecture (Volume II), the counters, and floating-point status are controlled. Zicsr defines the six instructions that access them. All six are atomic read-modify-writes of a single CSR, encoded under SYSTEM with the CSR specifier in bits 31:20:
- CSRRW — atomic swap: rd ← old CSR, CSR ← rs1.
- CSRRS — read + set the bits marked in rs1 (where writable).
- CSRRC — read + clear the bits marked in rs1 (where writable).
- CSRRWI / CSRRSI / CSRRCI — same, with a zero-extended
uimm[4:0]in place of rs1.
Table 7: when is it a read, when is it a write?
The x0 special cases are not cosmetic — they decide whether side effects fire, and whether an access to a read-only CSR traps:
| Operand condition | Reads CSR | Writes CSR | |
|---|---|---|---|
| CSRRW / CSRRWI | rd = x0 | No | Yes |
| CSRRW / CSRRWI | rd ≠ x0 | Yes | Yes |
| CSRRS/C, CSRRS/CI | rs1 = x0 or uimm = 0 | Yes — always | No |
| CSRRS/C, CSRRS/CI | rs1 ≠ x0 (any value) / uimm ≠ 0 | Yes | Yes |
Side effects vs indirect effects
A side effect csr side effect A consequence of a CSR read/write not determined solely by the CSR's value (spec example: read turns a light on). Standard CSRs have NO read side effects; write side effects are possible in principle. A trap caused by the value a write installed is an INDIRECT effect, not a side effect. defined in ch. I·6 — open in glossary is a consequence not determined solely by the CSR’s value (the spec’s example: a read that turns on a light bulb). An indirect effect is a consequence of the value itself — a trap that fires because a write created a triggering CSR combination is not a side effect. The practical state of the world: standard CSRs have no read side effects, currently no field-write side effects (and defining them is discouraged) — so whether a standard CSR access has side effects is decidable from the opcode alone.
Counters add one precise rule: an explicit read of instret returns the
value before the instruction; an explicit write suppresses and
overrides the implicit increment — the next instruction reads exactly
the written value.
6.1.1 Access ordering
Locally, a hart observes its own CSR accesses — explicit and implicit —
in program order, with side-effect consequences fully visible to the next
instruction and never visible early.
Globally csr access ordering A hart observes its own CSR accesses in program order (side effects visible to the next instruction). Globally, CSR accesses are weakly ordered under RVWMO and unordered vs memory accesses; FENCE covers them with CSR read = device input (I), CSR write = device output (O).
defined in ch. I·6 — open in glossary
, the CSR space behaves like
a weakly ordered memory-mapped I/O region: CSR accesses may be observed
out of order by other harts/devices and are unordered against explicit
memory accesses (absent syntactic dependencies or Memory-Ordering PMA
rules). The FENCE hook: CSR reads are device input (I), CSR writes are
device output (O). This matters exactly for the CSRs the outside world
can see — time, cycle, mip/sip (interrupt pending state) — while
private ones like fcsr reorder freely. Platforms may additionally
declare specific CSRs strongly ordered.
Hardware Designer Notes
In a simple in-order core, treat CSR instructions as serializing: drain the pipeline, perform the RMW, redirect fetch. That single decision discharges the program-order observation rule, the implicit-access ordering, and the next-instruction-sees-side-effects rule at once — optimize later, if profiling ever cares. The dangerous corner is Table 7: privilege/read-only trap checks (Vol II ch. 2 defines the address conventions) must consult the does-it-write bit, and that bit comes from specifier comparison, not operand value.
Minimal Linux-boot hart MUST
- Implement the Table 7 suppression matrix on the register SPECIFIER, not the value — CSRRS rd, ro_csr, x0 must not trap; CSRRS rd, ro_csr, t1 must, even if t1==0
- Zero-extend CSR reads to XLEN; make the CSR RMW atomic within the hart
- Counter CSRs: explicit write beats the same-instruction implicit increment; explicit read returns the pre-instruction value
- Route CSR reads/writes into the FENCE I/O sets
MAY simplify / trap-and-emulate
- Serialize the pipeline on every CSR instruction — the simple, safe default (CSR ops are rare)
- Decode side-effect-freedom from the opcode alone for standard CSRs (no read side effects exist)
Check yourself — CSR instructions
1.CSRRS x5, mstatus, x0 executes with x5 ≠ x0. mstatus is read-write. What happens to mstatus?
2.CSRRS t0, somecsr, t1 executes where t1 happens to contain 0. Which side effects fire?
3.An instruction writes 100 to instret. Ignoring the write, instret would have incremented to 42. What does the NEXT instruction read?
4.Hart A writes a device doorbell via MMIO, then reads the 'time' CSR. To guarantee the MMIO write is ordered before the CSR read as devices observe it, software must…