|
1 | 1 | //! misa register
|
2 | 2 |
|
3 |
| -use core::num::NonZeroUsize; |
4 |
| - |
5 |
| -/// misa register |
6 |
| -#[derive(Clone, Copy, Debug)] |
7 |
| -pub struct Misa { |
8 |
| - bits: NonZeroUsize, |
| 3 | +#[cfg(target_arch = "riscv32")] |
| 4 | +read_only_csr! { |
| 5 | + /// `misa` register |
| 6 | + Misa: 0x301, |
| 7 | + mask: 0xc3ff_ffff, |
| 8 | + sentinel: 0, |
9 | 9 | }
|
10 | 10 |
|
11 |
| -/// Base integer ISA width |
12 |
| -#[derive(Copy, Clone, Debug, Eq, PartialEq)] |
13 |
| -pub enum XLEN { |
14 |
| - XLEN32 = 1, |
15 |
| - XLEN64 = 2, |
16 |
| - XLEN128 = 3, |
| 11 | +#[cfg(not(target_arch = "riscv32"))] |
| 12 | +read_only_csr! { |
| 13 | + /// `misa` register |
| 14 | + Misa: 0x301, |
| 15 | + mask: 0xc000_0000_03ff_ffff, |
| 16 | + sentinel: 0, |
17 | 17 | }
|
18 | 18 |
|
19 |
| -impl XLEN { |
20 |
| - /// Converts a number into an ISA width |
21 |
| - pub(crate) fn from(value: u8) -> Self { |
22 |
| - match value { |
23 |
| - 1 => XLEN::XLEN32, |
24 |
| - 2 => XLEN::XLEN64, |
25 |
| - 3 => XLEN::XLEN128, |
26 |
| - _ => unreachable!(), |
27 |
| - } |
| 19 | +csr_field_enum! { |
| 20 | + /// Base integer ISA width |
| 21 | + XLEN { |
| 22 | + default: XLEN32, |
| 23 | + XLEN32 = 1, |
| 24 | + XLEN64 = 2, |
| 25 | + XLEN128 = 3, |
28 | 26 | }
|
29 | 27 | }
|
30 | 28 |
|
31 |
| -impl Misa { |
32 |
| - /// Returns the contents of the register as raw bits |
33 |
| - #[inline] |
34 |
| - pub fn bits(&self) -> usize { |
35 |
| - self.bits.get() |
36 |
| - } |
| 29 | +#[cfg(target_arch = "riscv32")] |
| 30 | +read_only_csr_field! { |
| 31 | + Misa, |
| 32 | + /// Effective xlen in M-mode (i.e., `MXLEN`). |
| 33 | + mxl, |
| 34 | + XLEN: [30:31], |
| 35 | +} |
37 | 36 |
|
| 37 | +#[cfg(not(target_arch = "riscv32"))] |
| 38 | +read_only_csr_field! { |
| 39 | + Misa, |
38 | 40 | /// Effective xlen in M-mode (i.e., `MXLEN`).
|
39 |
| - #[inline] |
40 |
| - pub fn mxl(&self) -> XLEN { |
41 |
| - let value = (self.bits() >> (usize::BITS - 2)) as u8; |
42 |
| - XLEN::from(value) |
43 |
| - } |
| 41 | + mxl, |
| 42 | + XLEN: [62:63], |
| 43 | +} |
44 | 44 |
|
| 45 | +impl Misa { |
45 | 46 | /// Returns true when a given extension is implemented.
|
46 | 47 | ///
|
47 | 48 | /// # Example
|
48 | 49 | ///
|
49 | 50 | /// ```no_run
|
50 |
| - /// let misa = unsafe { riscv::register::misa::read() }.unwrap(); |
| 51 | + /// let misa = unsafe { riscv::register::misa::try_read() }.unwrap(); |
51 | 52 | /// assert!(misa.has_extension('A')); // panics if atomic extension is not implemented
|
52 | 53 | /// ```
|
53 | 54 | #[inline]
|
54 | 55 | pub fn has_extension(&self, extension: char) -> bool {
|
55 |
| - let bit = extension as u8 - 65; |
| 56 | + let bit = ext_char_to_bit(extension); |
56 | 57 | if bit > 25 {
|
57 | 58 | return false;
|
58 | 59 | }
|
59 | 60 | self.bits() & (1 << bit) == (1 << bit)
|
60 | 61 | }
|
61 | 62 | }
|
62 | 63 |
|
63 |
| -read_csr!(0x301); |
64 |
| - |
65 |
| -/// Reads the CSR |
66 | 64 | #[inline]
|
67 |
| -pub fn read() -> Option<Misa> { |
68 |
| - let r = unsafe { _read() }; |
69 |
| - // When misa is hardwired to zero it means that the misa csr |
70 |
| - // isn't implemented. |
71 |
| - NonZeroUsize::new(r).map(|bits| Misa { bits }) |
| 65 | +const fn ext_char_to_bit(extension: char) -> u8 { |
| 66 | + (extension as u8).saturating_sub(b'A') |
72 | 67 | }
|
0 commit comments