Skip to content

SmpCluster: add mstatush, required by OpenSBI >= 1.6 on RV32 - #480

Merged
Dolu1990 merged 1 commit into
SpinalHDL:masterfrom
rvodden:smp-cluster-mstatush
Sep 24, 2026
Merged

Dolu1990 merged 1 commit into
SpinalHDL:masterfrom
rvodden:smp-cluster-mstatush

Conversation

@rvodden

@rvodden rvodden commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

#468 added MstatushPlugin but nothing instantiates it, so every SMP cluster still lacks CSR 0x310.

RV32 OpenSBI 1.6 and later clear MSTATUSH_MDT unconditionally in the trap entry and restore paths. CLEAR_MDT in firmware/fw_base.S, which expands to csrc CSR_MSTATUSH, t0 with no runtime guard. On a core without the CSR the first trap takes an illegal instruction exception inside the trap handler, before a console exists to report it. That is what keeps linux-on-litex-vexriscv pinned to the litex-hub OpenSBI fork at 1.3.1.

Verified by generating a cluster netlist and testing for the CSR decode: the plugin registers an anonymous U(0, 32 bits), so no signal carries the name and grep mstatush gives a false negative -- grep -c "12'h310" is the test.

SpinalHDL#468 added MstatushPlugin but nothing instantiates it, so every SMP cluster
still lacks CSR 0x310.

RV32 OpenSBI 1.6 and later clear MSTATUSH_MDT unconditionally in the trap entry
and restore paths -- CLEAR_MDT in firmware/fw_base.S, which expands to
`csrc CSR_MSTATUSH, t0` with no runtime guard. On a core without the CSR the
first trap takes an illegal instruction exception inside the trap handler,
before a console exists to report it. That is what keeps
linux-on-litex-vexriscv pinned to the litex-hub OpenSBI fork at 1.3.1.

Gated on a parameter defaulting to true and added the way FpuPlugin is, so an
existing configuration can opt out. readOnly = false so the write is accepted
and discarded: readOnly = true happens to tolerate the csrc OpenSBI uses,
because csrc asserts CSR_READ_OPCODE, but a csrw to the same CSR would still
trap, which is too fragile a distinction to depend on.

Verified by generating a cluster netlist and testing for the CSR decode: the
plugin registers an anonymous U(0, 32 bits), so no signal carries the name and
`grep mstatush` gives a false negative -- `grep -c "12'h310"` is the test.
@Dolu1990

Copy link
Copy Markdown
Member

Thanks ^^

@Dolu1990

Copy link
Copy Markdown
Member

Are you sure about the readOnly = false ?
Some software may assume mstatush feature are functionnal as they would be writable.

@rvodden

rvodden commented Aug 16, 2026

Copy link
Copy Markdown
Contributor Author

I'm pretty sure it is correct. The spec says it's a read/write register:

For RV32 only, mstatush is a 32-bit read/write register formatted as shown in Figure 8. Bits 30:4 of mstatush generally contain the same fields found in bits 62:36 of mstatus for RV64. Fields SD, SXL, and UXL do not exist in mstatush.

and the address encoding also implies read/write: bits [11:10] of 0x310 are 00.

Also, OpenSBI writes to mstatush which would mean it would trap if it was read only:

https://github.com/riscv-software-src/opensbi/blob/master/lib/sbi/sbi_hart.c#L87

if (misa_extension('H'))
		csr_write(CSR_HSTATUS, 0);

As I understand it, feature detection works by writing to the register and then checking that the value holds. The plugin discards the written value, and every field reads back zero, which is the correct answer for MBE/SBE (VexRiscv is little-endian), MPV/GVA (no H) and MDT/MPELP (no Smdbltrp/Zicfilp).

I'm happy to take your steer though. Would you prefer it selectable through a parameter?

@rvodden

rvodden commented Aug 27, 2026

Copy link
Copy Markdown
Contributor Author

Hey @Dolu1990, I just noticed a slight subtlety with this. pythondata-cpu-vexriscv-smp is currently pointed at the dev branch of this repo, and is using a couple of the features in that branch (--reset-vector and --jtag-tap).

What's your approach here? Do you periodically merge dev into master? If so, should this PR be raised against dev? If dev is just a relic then I'll happily raise a PR to repoint the litex repo onto master. That will be loads easier if those two options are also merged, I'm similarly happy to raise that if you don't want to merge all of dev.

Thanks loads for your help.

@rvodden

rvodden commented Sep 24, 2026

Copy link
Copy Markdown
Contributor Author

Hey @Dolu1990 did you have an opinion on the above? I've got some time this weekend and will be more than happy to make any changes you'd like!

@Dolu1990
Dolu1990 merged commit baf7dc8 into SpinalHDL:master Sep 24, 2026
1 check passed
@Dolu1990

Copy link
Copy Markdown
Member

I'm pretty sure it is correct. The spec says it's a read/write register:

Ahhh yes you are right ^^

@Dolu1990

Copy link
Copy Markdown
Member

Hi ^^

What's your approach here? Do you periodically merge dev into master?

Yes that is the normal flow.
If you want i can cherry pick this PR into dev aswell

If so, should this PR be raised against dev?

Yes normaly, but that is not too bad ^^

Hey @Dolu1990 did you have an opinion on the above? I've got some time this weekend and will be more than happy to make any changes you'd like!

Do not hesitate to ping when i'm so unreactive XD
Sorry

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants