The last two PPO rules encode two facts about every real pipeline; then the appendix maps the model onto the world beyond coherent DRAM.
Rule 12: forwarding needs resolved data
A load that returns a store’s value can’t outrun the store’s inputs:
Hart 0
- li t1, 1
- (a) sw t1,0(s0)
- (b) fence w,w
- (c) sw t1,0(s1)
Hart 1
- (d) lw a0,0(s1)
- (e) sw a0,0(s2)
- (f) lw a1,0(s2)
- xor a2,a1,a1
- add s0,s0,a2
- (g) lw a3,0(s0)
Rule 13: stores wait out possible aliases
A store may not become visible while an older load’s address is still
unresolved — they might overlap, and the load must appear to read the
old value (Table 85: the store to x waits until the load lw a2,0(a1)
knows whether a1 == s0). The appendix notes this is nearly a special
case of rule 11: stores must also wait until prior instructions can no
longer fault.
A.4 Beyond main memory
The model as formalized covers coherent main memory. The PMA interface (Vol II) hooks in like this:
| Effect on the model | |
|---|---|
| Main memory vs I/O | The RVWMO axioms apply to main memory; I/O gets the modified PPO below |
| Cacheability | No change to allowed behaviors — non-cacheable may be more restrictive, never weaker |
| Coherence | Non-coherent regions: all three axioms may be violated |
| Idempotency | Governs prefetch legality (side effects); no direct model impact |
I/O ordering replaces the axioms with a PPO variant: same-address I/O accesses order; accesses in the same strongly ordered region order; channel-based ordering (channel 1 = ordered against everything; same nonzero channel = ordered); aq/rl never cross the memory↔I/O boundary. Cross-domain ordering is FENCE’s job, mixing PI/PO/SI/SO with PR/PW/SR/SW:
sd t0, 0(a0) # main-memory buffer write
fence w, o # memory-write before device-output
sd a0, 0(a1) # MMIO doorbell
And the obligation runs deep: if the device reads memory on receiving
the doorbell, it must observe the buffer write — for many
implementations that means the store completes before the MMIO write
issues. RISC-V deliberately has no separate “completion fence”; the
distinction is inferred from the bits. Past a platform boundary (PCIe),
platform rules take over. The Unix Platform requires coherent DMA over
strongly ordered channels — which is why Linux’s dma_rmb/dma_wmb
map to plain fence r,r/fence w,w there.
Hardware Designer Notes
Rules 12/13 cost an out-of-order LSU real bookkeeping (store-to-load forwarding predicates, alias disambiguation); an in-order LSU gets both by construction. The I/O section is where your SoC integration lives: the FENCE W,O → doorbell → device-DMA-read chain is exactly the path every driver exercises, and “the store must complete before the MMIO issues” is the conservatively correct implementation.
Minimal Linux-boot hart MUST
- Hold stores until older loads' addresses resolve (rule 13) — or speculate with airtight repair before visibility
- Order forwarded loads behind the forwarded store's dependencies (rule 12)
- Honor FENCE's I/O bits through the LSU AND the bus interface — W,O may require store completion before MMIO issue
- Give device-visible regions the right PMAs: I/O, non-cacheable, strongly ordered channel for Unix-platform DMA
MAY simplify / trap-and-emulate
- Treat every fence with any I/O bit as FENCE IORW,IORW
- Implement rules 12/13 by simply not launching dependent accesses early — in-order LSUs get them for free
Check yourself — pipeline rules & I/O
1.Rule 12: why can't a load that forwards from store m perform before whatever m's data depends on?
2.Rule 13: a store waits for an OLDER load's unresolved address (possible alias). Which classic hazard is this?
3.To order a main-memory store before an MMIO doorbell write, software issues…
4.What does the memory model promise about non-coherent memory regions (per the coherence PMA)?