4
0

mstatus.rs 4.3 KB

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