mstatus.rs 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //! mstatus register
  2. // TODO: Virtualization, Memory Privilege and Extension Context Fields
  3. use bit_field::BitField;
  4. /// mstatus register
  5. #[derive(Clone, Copy, Debug)]
  6. pub struct Mstatus {
  7. bits: usize,
  8. }
  9. /// Additional extension state
  10. pub enum XS {
  11. /// All off
  12. AllOff = 0,
  13. /// None dirty or clean, some on
  14. NoneDirtyOrClean = 1,
  15. /// None dirty, some clean
  16. NoneDirtySomeClean = 2,
  17. /// Some dirty
  18. SomeDirty = 3,
  19. }
  20. /// Floating-point extension state
  21. pub enum FS {
  22. Off = 0,
  23. Initial = 1,
  24. Clean = 2,
  25. Dirty = 3,
  26. }
  27. /// Machine Previous Privilege Mode
  28. pub enum MPP {
  29. Machine = 3,
  30. Supervisor = 1,
  31. User = 0,
  32. }
  33. /// Supervisor Previous Privilege Mode
  34. pub enum SPP {
  35. Supervisor = 1,
  36. User = 0,
  37. }
  38. impl Mstatus {
  39. /// User Interrupt Enable
  40. #[inline]
  41. pub fn uie(&self) -> bool {
  42. self.bits.get_bit(0)
  43. }
  44. /// Supervisor Interrupt Enable
  45. #[inline]
  46. pub fn sie(&self) -> bool {
  47. self.bits.get_bit(1)
  48. }
  49. /// Machine Interrupt Enable
  50. #[inline]
  51. pub fn mie(&self) -> bool {
  52. self.bits.get_bit(3)
  53. }
  54. /// User Previous Interrupt Enable
  55. #[inline]
  56. pub fn upie(&self) -> bool {
  57. self.bits.get_bit(4)
  58. }
  59. /// Supervisor Previous Interrupt Enable
  60. #[inline]
  61. pub fn spie(&self) -> bool {
  62. self.bits.get_bit(5)
  63. }
  64. /// User Previous Interrupt Enable
  65. #[inline]
  66. pub fn mpie(&self) -> bool {
  67. self.bits.get_bit(7)
  68. }
  69. /// Supervisor Previous Privilege Mode
  70. #[inline]
  71. pub fn spp(&self) -> SPP {
  72. match self.bits.get_bit(8) {
  73. true => SPP::Supervisor,
  74. false => SPP::User,
  75. }
  76. }
  77. /// Machine Previous Privilege Mode
  78. #[inline]
  79. pub fn mpp(&self) -> MPP {
  80. match self.bits.get_bits(11..13) {
  81. 0b00 => MPP::User,
  82. 0b01 => MPP::Supervisor,
  83. 0b11 => MPP::Machine,
  84. _ => unreachable!(),
  85. }
  86. }
  87. /// Floating-point extension state
  88. ///
  89. /// Encodes the status of the floating-point unit,
  90. /// including the CSR `fcsr` and floating-point data registers `f0–f31`.
  91. #[inline]
  92. pub fn fs(&self) -> FS {
  93. match self.bits.get_bits(13..15) {
  94. 0b00 => FS::Off,
  95. 0b01 => FS::Initial,
  96. 0b10 => FS::Clean,
  97. 0b11 => FS::Dirty,
  98. _ => unreachable!(),
  99. }
  100. }
  101. /// Additional extension state
  102. ///
  103. /// Encodes the status of additional user-mode extensions and associated state.
  104. #[inline]
  105. pub fn xs(&self) -> XS {
  106. match self.bits.get_bits(15..17) {
  107. 0b00 => XS::AllOff,
  108. 0b01 => XS::NoneDirtyOrClean,
  109. 0b10 => XS::NoneDirtySomeClean,
  110. 0b11 => XS::SomeDirty,
  111. _ => unreachable!(),
  112. }
  113. }
  114. }
  115. read_csr_as!(Mstatus, 0x300, __read_mstatus);
  116. write_csr!(0x300, __write_mstatus);
  117. set!(0x300, __set_mstatus);
  118. clear!(0x300, __clear_mstatus);
  119. set_clear_csr!(
  120. /// User Interrupt Enable
  121. , set_uie, clear_uie, 1 << 0);
  122. set_clear_csr!(
  123. /// Supervisor Interrupt Enable
  124. , set_sie, clear_sie, 1 << 1);
  125. set_clear_csr!(
  126. /// Machine Interrupt Enable
  127. , set_mie, clear_mie, 1 << 3);
  128. set_csr!(
  129. /// User Previous Interrupt Enable
  130. , set_upie, 1 << 4);
  131. set_csr!(
  132. /// Supervisor Previous Interrupt Enable
  133. , set_spie, 1 << 5);
  134. set_csr!(
  135. /// Machine Previous Interrupt Enable
  136. , set_mpie, 1 << 7);
  137. /// Supervisor Previous Privilege Mode
  138. #[inline]
  139. pub unsafe fn set_spp(spp: SPP) {
  140. match spp {
  141. SPP::Supervisor => _set(1 << 8),
  142. SPP::User => _clear(1 << 8),
  143. }
  144. }
  145. /// Machine Previous Privilege Mode
  146. #[inline]
  147. pub unsafe fn set_mpp(mpp: MPP) {
  148. let mut value = _read();
  149. value.set_bits(11..13, mpp as usize);
  150. _write(value);
  151. }
  152. /// Floating-point extension state
  153. #[inline]
  154. pub unsafe fn set_fs(fs: FS) {
  155. let mut value = _read();
  156. value.set_bits(13..15, fs as usize);
  157. _write(value);
  158. }