Skip to content

Commit 7762939

Browse files
committed
Merge branch 'master' into riscv-pac
2 parents 6c75aa0 + 7291ac2 commit 7762939

File tree

10 files changed

+218
-8
lines changed

10 files changed

+218
-8
lines changed

riscv-peripheral/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1111

1212
- `PLIC` now expects interrupt enums to implement the `riscv_pac::ExternalInterruptNumber` trait.
1313

14+
### Fixed
15+
16+
- `clippy` fixes
17+
1418
## [v0.1.0] - 2024-02-15
1519

1620
### Added

riscv-peripheral/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
//! ## Features
44
//!
55
//! - `aclint-hal-async`: enables the [`hal_async::delay::DelayNs`] implementation for the ACLINT peripheral.
6-
//! This feature relies on external functions that must be provided by the user. See [`hal_async::aclint`] for more information.
6+
//! This feature relies on external functions that must be provided by the user. See [`hal_async::aclint`] for more information.
77
88
#![deny(missing_docs)]
99
#![no_std]

riscv-rt/macros/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -483,12 +483,14 @@ fn vectored_interrupt_trap(arch: RiscvArch) -> TokenStream {
483483
core::arch::global_asm!(
484484
".section .trap, \"ax\"
485485
486+
.align 4
486487
.global _start_DefaultHandler_trap
487488
_start_DefaultHandler_trap:
488489
addi sp, sp, -{TRAP_SIZE} * {width} // allocate space for trap frame
489490
{store_start} // store trap partially (only register a0)
490491
la a0, DefaultHandler // load interrupt handler address into a0
491492
493+
.align 4
492494
.global _continue_interrupt_trap
493495
_continue_interrupt_trap:
494496
{store_continue} // store trap partially (all registers except a0)

riscv-semihosting/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
88
### Changed
99

1010
- Made `cfg` variable selection more robust for custom targets
11+
- Fixed debug::exit() on riscv64 QEMU simulation
1112

1213
## [v0.1.0] - 2023-01-18
1314

riscv-semihosting/src/debug.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,10 @@ pub fn exit(status: ExitStatus) {
8989
pub fn report_exception(reason: Exception) {
9090
let code = reason as usize;
9191
unsafe {
92+
#[cfg(target_arch = "riscv64")]
93+
syscall!(REPORT_EXCEPTION, code, 0);
94+
95+
#[cfg(not(target_arch = "riscv64"))]
9296
syscall1!(REPORT_EXCEPTION, code);
9397
}
9498
}

riscv/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1818
- Add `Mstatus::update_*` helpers to manipulate Mstatus values without touching
1919
the CSR
2020
- Export `riscv::register::macros` module macros for external use
21+
- Add `riscv::register::mcountinhibit` module for `mcountinhibit` CSR
22+
- Add `Mcounteren` in-memory update functions
2123

2224
### Changed
2325

@@ -26,6 +28,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
2628
### Fixed
2729

2830
- Fixed `sip::set_ssoft` and `sip::clear_ssoft` using wrong address
31+
- Fixed assignment in `mstatus` unit tests.
2932

3033
## [v0.11.1] - 2024-02-15
3134

riscv/src/interrupt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub mod machine {
6262
/// - Do not call this function inside a critical section.
6363
/// - This method is assumed to be called within an interrupt handler.
6464
/// - Make sure to clear the interrupt flag that caused the interrupt before calling
65-
/// this method. Otherwise, the interrupt will be re-triggered before executing `f`.
65+
/// this method. Otherwise, the interrupt will be re-triggered before executing `f`.
6666
#[inline]
6767
pub unsafe fn nested<F, R>(f: F) -> R
6868
where
@@ -152,7 +152,7 @@ pub mod supervisor {
152152
/// - Do not call this function inside a critical section.
153153
/// - This method is assumed to be called within an interrupt handler.
154154
/// - Make sure to clear the interrupt flag that caused the interrupt before calling
155-
/// this method. Otherwise, the interrupt will be re-triggered before executing `f`.
155+
/// this method. Otherwise, the interrupt will be re-triggered before executing `f`.
156156
#[inline]
157157
pub unsafe fn nested<F, R>(f: F) -> R
158158
where

riscv/src/register.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ mod pmpaddrx;
9595
pub use self::pmpaddrx::*;
9696

9797
// Machine Counter/Timers
98+
pub mod mcountinhibit;
9899
pub mod mcycle;
99100
pub mod mcycleh;
100101
mod mhpmcounterx;

riscv/src/register/mcounteren.rs

Lines changed: 84 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! mcounteren register
22
3+
use crate::bits::{bf_extract, bf_insert};
4+
35
/// mcounteren register
46
#[derive(Clone, Copy, Debug)]
57
pub struct Mcounteren {
@@ -10,31 +12,64 @@ impl Mcounteren {
1012
/// Supervisor "cycle\[h\]" Enable
1113
#[inline]
1214
pub fn cy(&self) -> bool {
13-
self.bits & (1 << 0) != 0
15+
bf_extract(self.bits, 0, 1) != 0
16+
}
17+
18+
/// Sets whether to enable the "cycle\[h\]" counter.
19+
///
20+
/// Only updates the in-memory value, does not modify the `mcounteren` register.
21+
#[inline]
22+
pub fn set_cy(&mut self, cy: bool) {
23+
self.bits = bf_insert(self.bits, 0, 1, cy as usize);
1424
}
1525

1626
/// Supervisor "time\[h\]" Enable
1727
#[inline]
1828
pub fn tm(&self) -> bool {
19-
self.bits & (1 << 1) != 0
29+
bf_extract(self.bits, 1, 1) != 0
30+
}
31+
32+
/// Sets whether to enable "time\[h\]".
33+
///
34+
/// Only updates the in-memory value, does not modify the `mcounteren` register.
35+
#[inline]
36+
pub fn set_tm(&mut self, tm: bool) {
37+
self.bits = bf_insert(self.bits, 1, 1, tm as usize);
2038
}
2139

2240
/// Supervisor "instret\[h\]" Enable
2341
#[inline]
2442
pub fn ir(&self) -> bool {
25-
self.bits & (1 << 2) != 0
43+
bf_extract(self.bits, 2, 1) != 0
44+
}
45+
46+
/// Sets whether to enable the "instret\[h\]" counter.
47+
///
48+
/// Only updates the in-memory value, does not modify the `mcounteren` register.
49+
#[inline]
50+
pub fn set_ir(&mut self, ir: bool) {
51+
self.bits = bf_insert(self.bits, 2, 1, ir as usize);
2652
}
2753

2854
/// Supervisor "hpm\[x\]" Enable (bits 3-31)
2955
#[inline]
3056
pub fn hpm(&self, index: usize) -> bool {
3157
assert!((3..32).contains(&index));
32-
self.bits & (1 << index) != 0
58+
bf_extract(self.bits, index, 1) != 0
59+
}
60+
61+
/// Sets whether to enable the "hpm\[X\]" counter.
62+
///
63+
/// Only updates the in-memory value, does not modify the `mcounteren` register.
64+
#[inline]
65+
pub fn set_hpm(&mut self, index: usize, hpm: bool) {
66+
assert!((3..32).contains(&index));
67+
self.bits = bf_insert(self.bits, index, 1, hpm as usize);
3368
}
3469
}
3570

3671
read_csr_as!(Mcounteren, 0x306);
37-
write_csr!(0x306);
72+
write_csr_as!(Mcounteren, 0x306);
3873
set!(0x306);
3974
clear!(0x306);
4075

@@ -61,3 +96,47 @@ pub unsafe fn clear_hpm(index: usize) {
6196
assert!((3..32).contains(&index));
6297
_clear(1 << index);
6398
}
99+
100+
#[cfg(test)]
101+
mod tests {
102+
use super::*;
103+
104+
#[test]
105+
fn test_mcounteren() {
106+
let mut m = Mcounteren { bits: 0 };
107+
108+
assert!(!m.cy());
109+
110+
m.set_cy(true);
111+
assert!(m.cy());
112+
113+
m.set_cy(false);
114+
assert!(!m.cy());
115+
116+
assert!(!m.tm());
117+
118+
m.set_tm(true);
119+
assert!(m.tm());
120+
121+
m.set_tm(false);
122+
assert!(!m.tm());
123+
124+
assert!(!m.ir());
125+
126+
m.set_ir(true);
127+
assert!(m.ir());
128+
129+
m.set_ir(false);
130+
assert!(!m.ir());
131+
132+
(3..32).for_each(|i| {
133+
assert!(!m.hpm(i));
134+
135+
m.set_hpm(i, true);
136+
assert!(m.hpm(i));
137+
138+
m.set_hpm(i, false);
139+
assert!(!m.hpm(i));
140+
});
141+
}
142+
}

riscv/src/register/mcountinhibit.rs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//! `mcountinhibit` register
2+
3+
use crate::bits::{bf_extract, bf_insert};
4+
5+
/// `mcountinhibit` register
6+
#[derive(Clone, Copy, Debug)]
7+
pub struct Mcountinhibit {
8+
bits: usize,
9+
}
10+
11+
impl Mcountinhibit {
12+
/// Machine "cycle\[h\]" Disable
13+
#[inline]
14+
pub fn cy(&self) -> bool {
15+
bf_extract(self.bits, 0, 1) != 0
16+
}
17+
18+
/// Sets whether to inhibit the "cycle\[h\]" counter.
19+
///
20+
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
21+
#[inline]
22+
pub fn set_cy(&mut self, cy: bool) {
23+
self.bits = bf_insert(self.bits, 0, 1, cy as usize);
24+
}
25+
26+
/// Machine "instret\[h\]" Disable
27+
#[inline]
28+
pub fn ir(&self) -> bool {
29+
bf_extract(self.bits, 2, 1) != 0
30+
}
31+
32+
/// Sets whether to inhibit the "instret\[h\]" counter.
33+
///
34+
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
35+
#[inline]
36+
pub fn set_ir(&mut self, ir: bool) {
37+
self.bits = bf_insert(self.bits, 2, 1, ir as usize);
38+
}
39+
40+
/// Machine "hpm\[x\]" Disable (bits 3-31)
41+
#[inline]
42+
pub fn hpm(&self, index: usize) -> bool {
43+
assert!((3..32).contains(&index));
44+
bf_extract(self.bits, index, 1) != 0
45+
}
46+
47+
/// Sets whether to inhibit the "hpm\[X\]" counter.
48+
///
49+
/// Only updates the in-memory value, does not modify the `mcountinhibit` register.
50+
#[inline]
51+
pub fn set_hpm(&mut self, index: usize, hpm: bool) {
52+
assert!((3..32).contains(&index));
53+
self.bits = bf_insert(self.bits, index, 1, hpm as usize);
54+
}
55+
}
56+
57+
read_csr_as!(Mcountinhibit, 0x320);
58+
write_csr_as!(Mcountinhibit, 0x320);
59+
set!(0x320);
60+
clear!(0x320);
61+
62+
set_clear_csr!(
63+
/// Machine cycle Disable
64+
, set_cy, clear_cy, 1 << 0);
65+
66+
set_clear_csr!(
67+
/// Machine instret Disable
68+
, set_ir, clear_ir, 1 << 2);
69+
70+
#[inline]
71+
pub unsafe fn set_hpm(index: usize) {
72+
assert!((3..32).contains(&index));
73+
_set(1 << index);
74+
}
75+
76+
#[inline]
77+
pub unsafe fn clear_hpm(index: usize) {
78+
assert!((3..32).contains(&index));
79+
_clear(1 << index);
80+
}
81+
82+
#[cfg(test)]
83+
mod tests {
84+
use super::*;
85+
86+
#[test]
87+
fn test_mcountinhibit() {
88+
let mut m = Mcountinhibit { bits: 0 };
89+
90+
assert!(!m.cy());
91+
92+
m.set_cy(true);
93+
assert!(m.cy());
94+
95+
m.set_cy(false);
96+
assert!(!m.cy());
97+
98+
assert!(!m.ir());
99+
100+
m.set_ir(true);
101+
assert!(m.ir());
102+
103+
m.set_ir(false);
104+
assert!(!m.ir());
105+
106+
(3..32).for_each(|i| {
107+
assert!(!m.hpm(i));
108+
109+
m.set_hpm(i, true);
110+
assert!(m.hpm(i));
111+
112+
m.set_hpm(i, false);
113+
assert!(!m.hpm(i));
114+
});
115+
}
116+
}

0 commit comments

Comments
 (0)