Skip to content

Commit

Permalink
riscv: add mcountinhibit module
Browse files Browse the repository at this point in the history
Adds the `riscv::register::mcountinhibit` module for the `mcountinhibit`
CSR.
  • Loading branch information
rmsyn committed May 21, 2024
1 parent f7afa99 commit 946034a
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 0 deletions.
1 change: 1 addition & 0 deletions riscv/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Add `Mstatus::update_*` helpers to manipulate Mstatus values without touching
the CSR
- Export `riscv::register::macros` module macros for external use
- Add `riscv::register::mcountinhibit` module for `mcountinhibit` CSR

### Fixed

Expand Down
1 change: 1 addition & 0 deletions riscv/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ mod pmpaddrx;
pub use self::pmpaddrx::*;

// Machine Counter/Timers
pub mod mcountinhibit;
pub mod mcycle;
pub mod mcycleh;
mod mhpmcounterx;
Expand Down
95 changes: 95 additions & 0 deletions riscv/src/register/mcountinhibit.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
//! `mcountinhibit` register

use crate::bits::{bf_extract, bf_insert};

/// `mcountinhibit` register
#[derive(Clone, Copy, Debug)]
pub struct Mcountinhibit {
bits: usize,
}

impl Mcountinhibit {
/// Machine "cycle\[h\]" Disable
#[inline]
pub fn cy(&self) -> bool {
bf_extract(self.bits, 0, 1) != 0
}

/// Sets whether to inhibit the "cycle\[h\]" counter.
///
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
#[inline]
pub fn set_cy(&mut self, cy: bool) {
self.bits = bf_insert(self.bits, 0, 1, cy as usize);
}

/// Machine "instret\[h\]" Disable
#[inline]
pub fn ir(&self) -> bool {
bf_extract(self.bits, 2, 1) != 0
}

/// Sets whether to inhibit the "instret\[h\]" counter.
///
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
#[inline]
pub fn set_ir(&mut self, ir: bool) {
self.bits = bf_insert(self.bits, 2, 1, ir as usize);
}

/// Machine "hpm\[x\]" Disable (bits 3-31)
#[inline]
pub fn hpm(&self, index: usize) -> Option<bool> {
if (3..32).contains(&index) {
None
} else {
Some(bf_extract(self.bits, index, 1) != 0)
}
}

/// Sets whether to inhibit the "hpm\[X\]" counter.
///
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
#[inline]
pub fn set_hpm(&mut self, index: usize, hpm: bool) -> Option<()> {
if (3..32).contains(&index) {
None
} else {
self.bits = bf_insert(self.bits, index, 1, hpm as usize);
Some(())
}
}
}

read_csr_as!(Mcountinhibit, 0x320);
write_csr_as!(Mcountinhibit, 0x320);
set!(0x320);
clear!(0x320);

set_clear_csr!(
/// Machine cycle Disable
, set_cy, clear_cy, 1 << 0);

set_clear_csr!(
/// Machine instret Disable
, set_ir, clear_ir, 1 << 2);

#[inline]
pub unsafe fn set_hpm(index: usize) -> Option<()> {
if (3..32).contains(&index) {
None
} else {
_set(1 << index);
Some(())
}
}

#[inline]
pub unsafe fn clear_hpm(index: usize) -> Option<()> {
if (3..32).contains(&index) {
None
} else {
_clear(1 << index);
Some(())
}
}

0 comments on commit 946034a

Please sign in to comment.