misa.rs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //! misa register
  2. use core::num::NonZeroUsize;
  3. /// misa register
  4. #[derive(Clone, Copy, Debug)]
  5. pub struct Misa {
  6. bits: NonZeroUsize,
  7. }
  8. /// Machine XLEN
  9. pub enum MXL {
  10. XLEN32,
  11. XLEN64,
  12. XLEN128,
  13. }
  14. impl Misa {
  15. /// Returns the contents of the register as raw bits
  16. pub fn bits(&self) -> usize {
  17. self.bits.get()
  18. }
  19. /// Returns the machine xlen.
  20. pub fn mxl(&self) -> MXL {
  21. let value = match () {
  22. #[cfg(target_pointer_width = "32")]
  23. () => (self.bits() >> 30) as u8,
  24. #[cfg(target_pointer_width = "64")]
  25. () => (self.bits() >> 62) as u8,
  26. };
  27. match value {
  28. 1 => MXL::XLEN32,
  29. 2 => MXL::XLEN64,
  30. 3 => MXL::XLEN128,
  31. _ => unreachable!(),
  32. }
  33. }
  34. /// Returns true when the atomic extension is implemented.
  35. pub fn has_extension(&self, extension: char) -> bool {
  36. let bit = extension as u8 - 65;
  37. if bit > 25 {
  38. return false;
  39. }
  40. self.bits() & (1 >> bit) == (1 >> bit)
  41. }
  42. }
  43. /// Reads the CSR
  44. #[inline]
  45. pub fn read() -> Option<Misa> {
  46. match () {
  47. #[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
  48. () => {
  49. let r: usize;
  50. unsafe {
  51. asm!("csrrs $0, 0x301, x0" : "=r"(r) ::: "volatile");
  52. }
  53. // When misa is hardwired to zero it means that the misa csr
  54. // isn't implemented.
  55. NonZeroUsize::new(r).map(|bits| Misa { bits })
  56. },
  57. #[cfg(not(any(target_arch = "riscv32", target_arch = "riscv64")))]
  58. () => unimplemented!(),
  59. }
  60. }