Skip to content

[rv_core_ibex] Add u-mode performance counters and mcounteren#30135

Merged
nasahlpa merged 3 commits into
lowRISC:masterfrom
SamuelRiedel:mcounteren
Jun 17, 2026
Merged

[rv_core_ibex] Add u-mode performance counters and mcounteren#30135
nasahlpa merged 3 commits into
lowRISC:masterfrom
SamuelRiedel:mcounteren

Conversation

@SamuelRiedel

@SamuelRiedel SamuelRiedel commented May 18, 2026

Copy link
Copy Markdown
Contributor
  • Update Ibex to contain the u-mode performance counter aliases
  • Ibex also implements the mcounteren CSR to control which u-mode counters are accessible
  • The mcounteren CSR can be locked through an input signal to prevent modifying it even in m-mode
  • Add a mcounteren_writable register in rv_core_ibex driving the above signal. This register is lockable with the mcounteren_writable_regwen register.

ToDo:

  • Add sofware test to ensure the newly added registers are writable, lockable, and correctly lock the mcounteren register in Ibex
  • Use consistent MuBi encoding between Ibex and OT.
  • Update Ibex once Add mcounteren register ibex#2403 is merged

The test will run in the nightly CI. I activated it temporarily also in the PR's CI and the run can be found here.

@SamuelRiedel SamuelRiedel force-pushed the mcounteren branch 2 times, most recently from 3baeac4 to a204ac4 Compare May 29, 2026 16:22
@SamuelRiedel SamuelRiedel marked this pull request as ready for review May 29, 2026 16:22
@SamuelRiedel SamuelRiedel requested review from a team as code owners May 29, 2026 16:22
@SamuelRiedel SamuelRiedel requested review from gautschimi, rswarbrick and timothytrippel and removed request for a team May 29, 2026 16:22

@gautschimi gautschimi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks all good.

changes in this PR are approved. But the vendor-in commit needs to be updated once the ibex PR has been merged.

edit: commit messages could be a bit longer:)

edit: and the CI jobs need to be fixed

@rswarbrick rswarbrick left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the "Add missing rvfi ports" commit be squashed with the vendoring update? Otherwise, I think we have a (slightly) broken intermediate state of the repository?

Comment thread sw/device/tests/rv_core_ibex_mcounteren_writable_test.c Outdated
@SamuelRiedel

Copy link
Copy Markdown
Contributor Author

Should the "Add missing rvfi ports" commit be squashed with the vendoring update? Otherwise, I think we have a (slightly) broken intermediate state of the repository?

Yes good point. I will squash the two once we merge the Ibex PR and I vendor in Ibex from the main branch.

@SamuelRiedel SamuelRiedel added the CI:Rerun Rerun failed CI jobs label Jun 12, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Jun 12, 2026
@SamuelRiedel SamuelRiedel added the CI:Rerun Rerun failed CI jobs label Jun 12, 2026
@github-actions github-actions Bot removed the CI:Rerun Rerun failed CI jobs label Jun 12, 2026
@SamuelRiedel

Copy link
Copy Markdown
Contributor Author

I pulled in the Ibex changes from upstream, squashed the commits and extended the commit messages a bit. So this is ready to go from my side.

Comment thread hw/ip_templates/rv_core_ibex/rtl/rv_core_ibex.sv.tpl

@marnovandermaas marnovandermaas left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one minor improvement to the test but otherwise looks good to me.

Comment thread sw/device/tests/rv_core_ibex_mcounteren_writable_test.c
Comment thread sw/device/tests/rv_core_ibex_mcounteren_writable_test.c
@SamuelRiedel SamuelRiedel force-pushed the mcounteren branch 2 times, most recently from fe0d5f5 to 8b41d27 Compare June 16, 2026 12:59
@marnovandermaas

Copy link
Copy Markdown
Contributor

CHANGE AUTHORIZED: hw/top_earlgrey/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson
CHANGE AUTHORIZED: hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv
CHANGE AUTHORIZED: hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv
CHANGE AUTHORIZED: hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_core.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_id_stage.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_lockstep.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_top.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_top_tracing.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_tracer.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_wb_stage.sv

@andreaskurth andreaskurth left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with only two small suggestions. Thanks @SamuelRiedel!

ibex_pkg::ibex_mubi_t mcounteren_writable_ibex;
assign mcounteren_writable_mubi4 = prim_mubi_pkg::mubi4_t'(reg2hw.mcounteren_writable.q);
// Convert the mubi4 to ibex_mubi. They are both four bit, but with different encodings.
// This conversion should be a simple wire crossing.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this isn't true because there's no bit permutation that maps one pair to the other, so it's a genuine re-encoding, not a rewiring. I don't think this is a problem and the implementation is correct, but suggest rephrasing the comment.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should map well by swapping the lower two bits; at least the True/False values match. Nevertheless, this might not hold true generally if the values change, nor is it particularly relevant, so I removed this line of the comment.

Comment thread sw/device/tests/BUILD
srcs = ["rv_core_ibex_mcounteren_writable_test.c"],
exec_env = EARLGREY_TEST_ENVS,
deps = [
"//hw/top_earlgrey/sw/autogen:top_earlgrey",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the C file #includes hw/top/rv_core_ibex_regs.h, I suggest you add //hw/top:rv_core_ibex_c_regs. The test seems to build, so this gets transitively pulled in already, but it's cleaner to have the depencency explicit.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, I added this.

@andreaskurth

Copy link
Copy Markdown
Contributor

CHANGE AUTHORIZED: hw/top_earlgrey/ip_autogen/rv_core_ibex/data/rv_core_ibex.hjson
CHANGE AUTHORIZED: hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex.sv
CHANGE AUTHORIZED: hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_cfg_reg_top.sv
CHANGE AUTHORIZED: hw/top_earlgrey/ip_autogen/rv_core_ibex/rtl/rv_core_ibex_reg_pkg.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_core.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_cs_registers.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_id_stage.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_lockstep.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_pkg.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_top.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_top_tracing.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_tracer.sv
CHANGE AUTHORIZED: hw/vendor/lowrisc_ibex/rtl/ibex_wb_stage.sv

Agreed new feature for Ibex.

This register allows locking/unlocking the mcounteren CSR in Ibex to
control which performance counters are available in U-mode.

Signed-off-by: Samuel Riedel <sriedel@lowrisc.org>
Update code from upstream repository
https://github.com/lowRISC/ibex.git to revision
aae4809aea170fc605bdaa64a70a13efd2408829

* [dv] Check u-mode counter alias the correct m-mode counter (Samuel
  Riedel)
* [formal] Exclude u-mode counters from formal verification (Samuel
  Riedel)
* [doc] Document the newly added performance counters (Samuel Riedel)
* [dv] Add directed test for mcounteren lock signal (Samuel Riedel)
* [dv] Add `mcounteren` directed test (Samuel Riedel)
* [dv] Fix ordering in `directed_testlist.yml` (Samuel Riedel)
* [dv] Implement Ibex-specific mcounteren behavior in cosim (Samuel
  Riedel)
* [rtl] Add input to lock mcounteren (Samuel Riedel)
* [rtl] Add unpriviledged counter/timers (Samuel Riedel)
* [rtl] Add register for `mcounteren` (Samuel Riedel)
* [rtl] Fix incrementing `minstret` after setting it (Samuel Riedel)
* [rtl] Fix speculative increment of `minstret` (Samuel Riedel)
* [syn] Fix scripts for new vendored lowrisc_ip (Harry Callahan)
* [syn] Add nix devShell for example synthesis flow (Harry Callahan)
* [dv] Fixup explicit static lifetime on initializer by seperating
  decl from assign. (Harry Callahan)
* [vendor/google_riscv-dv] Add VCS -Xcflags to suppress build warnings
  (Harry Callahan)
* [vendor/google_riscv-dv] use env bash and non-absolute bash paths
  (Harry Callahan)
* [rtl] Explicitly define mapping to `prim_generic` for linter targets
  (Samuel Riedel)
* [rtl] Fix prim_generic mapping in ibex_top (Samuel Riedel)
* [rtl] Move prim_generic dependency to ibex_top (Samuel Riedel)
* [doc] Ibex Concierge updated (Marno van der Maas)

Signed-off-by: Samuel Riedel <sriedel@lowrisc.org>
Software test to verify that the `mcounteren_writable` can be set and
cleared and locked. This test also verifies that it locks the
`mcounteren` CSR in Ibex

Signed-off-by: Samuel Riedel <sriedel@lowrisc.org>
]
},

{ name: "MCOUNTEREN_WRITABLE_REGWEN",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As discussed offline, OK for me to have this as a single-bit value and not a mubi. To change the MCOUNTEREN value below, an attacker would need to fault it to be unlocked and also have SW access to write to it.

@nasahlpa

Copy link
Copy Markdown
Contributor

Merging as the timeout in the CW340 ROM Tests is a known issue that is not related to this PR.

@nasahlpa nasahlpa added this pull request to the merge queue Jun 17, 2026
Merged via the queue into lowRISC:master with commit 5428a5a Jun 17, 2026
42 of 43 checks passed
@SamuelRiedel SamuelRiedel deleted the mcounteren branch June 19, 2026 06:18
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.

6 participants