11.1-4"Smctr": Control Transfer Records — Registers & Access

Part II Linux boot: optional Vol. II (Privileged) pp. 97–103 · ~4 min read

  • control transfer records

Full instruction tracing drowns in its own bandwidth; CTR instead keeps the last 16–256 control transfers in on-chip storage — enough for Linux perf’s LBR-style sampling and AutoFDO, at near-zero overhead. It’s a circular FIFO of (source PC, target PC, metadata) records behind the indirect-CSR window; Smctr/Ssctr require S-mode and Sscsrind.

The control register

mctrctl (0x34E) — Figure 10

Custom6360WPRI5948jump filters4740trap filters3932WPRI3113LCOFIFRZ12BPFRZ11WPRI10MTE/STE98RASEMU7WPRI63M / S / U20
WPRI/RO WLRL WARL RW
Click a field for semantics, reset state, and the minimal-implementation note.

sctrctl (0x14E) is the same register minus M/MTE (read-only 0 there); vsctrctl substitutes when V=1 — a guest manages its own filters without traps, while its enables can’t affect V=0 recording.

Depth, status, entries

The bookkeeping registers
Contents & rules
sctrdepth (0x15F)DEPTH[2:0] WARL: 16/32/64/128/256 entries (support is implementation-specific). VS access ALWAYS raises virtual-instruction
sctrstatus (0x14F)WRPTR[7:0] (next physical write slot; wraps at depth; excess bits RO-0) + FROZEN[31]
Entries via siselect 0x200-0x2FFLogical entry N (0 = youngest): sireg = ctrsource (PC[63:1] + V valid bit), sireg2 = ctrtarget (PC[63:1] + MISP mispredict bit; not-taken branch records the fall-through PC), sireg3 = ctrdata (TYPE[3:0], CCV[15], CC[31:16] compressed cycle count). sireg4-6 read zero; entries ≥ depth read zero. All MXLEN-wide (immune to XLEN switching truncation)
SCTRCLR (SYSTEM, func12 0x104)Zeroes ALL entries across every depth, plus the cycle counter and CCV. Illegal-instruction in U, virtual-instruction in VU — the context-isolation wipe
Dotted-underlined cells have explanations — click one.

Access control

mstateen0.CTR (bit 54) gates every CTR CSR, the entry window, and SCTRCLR below M-mode (illegal-instruction); hstateen0.CTR does the same for VS (virtual-instruction). Crucially, recording continues regardless — the stateen bits guard the register interface, not the recorder, enabling the lazy-virtualization pattern: trap the guest’s first CTR touch, then start context-switching CTR state for that guest only.

Hardware Designer Notes

The storage bill: depth × (2 × MXLEN + 32) bits of SRAM plus an 8-bit WRPTR — a 16-entry RV64 buffer is ~264 bytes. The write port sits at retirement where source/target/type are already known. The behavioral rules that make records trustworthy are the next page.

Minimal Linux-boot hart MUST

  • Implement M/S/U and BPFRZ fields in the control registers (LCOFIFRZ with Sscofpmf); everything else may be RO-0
  • Keep entry registers MXLEN-wide with zero-extension of narrow writes
  • Make SCTRCLR wipe all physical entries, not just those below the current depth

MAY simplify / trap-and-emulate

  • Support a single depth value (e.g. 16) — DEPTH is WARL
  • Omit MISP, cycle counting, all filters, and RASEMU — each is independently optional
  • Skip CTR entirely on a Linux-boot v1: it needs Sscsrind anyway and only perf tooling misses it

Check yourself — CTR registers

1.How does software read the youngest recorded transfer?

2.Why does VS-mode access to sctrdepth ALWAYS raise virtual-instruction, even with all stateen bits set?

3.With mstateen0.CTR=0, S-mode runs with recording enabled. What still happens?

4.What does SCTRCLR guarantee?

4 questions