6.1"Zicsr": CSR Instructions

Part I Linux boot: required Vol. I (Unprivileged) pp. 47–50 · ~5 min read

  • csr
  • csr side effect
  • csr access ordering

Every hart carries a separate address space of 4096 CSRs — 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:

csr3120rs1 / uimm1915funct31412rd117SYSTEM60CSRRx
Click a field for its role.
  • 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:

Read/write conditions (Table 7)
Operand conditionReads CSRWrites CSR
CSRRW / CSRRWIrd = x0NoYes
CSRRW / CSRRWIrd ≠ x0YesYes
CSRRS/C, CSRRS/CIrs1 = x0 or uimm = 0Yes — alwaysNo
CSRRS/C, CSRRS/CIrs1 ≠ x0 (any value) / uimm ≠ 0YesYes
Dotted-underlined cells have explanations — click one.

Side effects vs indirect effects

A side effect 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 , 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…

4 questions