sstatus.rs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //! sstatus register
  2. pub use super::mstatus::FS;
  3. use bit_field::BitField;
  4. use core::mem::size_of;
  5. /// Supervisor Status Register
  6. #[derive(Clone, Copy, Debug)]
  7. pub struct Sstatus {
  8. bits: usize,
  9. }
  10. /// Supervisor Previous Privilege Mode
  11. #[derive(Copy, Clone, Debug, Eq, PartialEq)]
  12. pub enum SPP {
  13. Supervisor = 1,
  14. User = 0,
  15. }
  16. impl Sstatus {
  17. /// User Interrupt Enable
  18. #[inline]
  19. pub fn uie(&self) -> bool {
  20. self.bits.get_bit(0)
  21. }
  22. /// Supervisor Interrupt Enable
  23. #[inline]
  24. pub fn sie(&self) -> bool {
  25. self.bits.get_bit(1)
  26. }
  27. /// User Previous Interrupt Enable
  28. #[inline]
  29. pub fn upie(&self) -> bool {
  30. self.bits.get_bit(4)
  31. }
  32. /// Supervisor Previous Interrupt Enable
  33. #[inline]
  34. pub fn spie(&self) -> bool {
  35. self.bits.get_bit(5)
  36. }
  37. /// Supervisor Previous Privilege Mode
  38. #[inline]
  39. pub fn spp(&self) -> SPP {
  40. match self.bits.get_bit(8) {
  41. true => SPP::Supervisor,
  42. false => SPP::User,
  43. }
  44. }
  45. /// The status of the floating-point unit
  46. #[inline]
  47. pub fn fs(&self) -> FS {
  48. match self.bits.get_bits(13..15) {
  49. 0 => FS::Off,
  50. 1 => FS::Initial,
  51. 2 => FS::Clean,
  52. 3 => FS::Dirty,
  53. _ => unreachable!(),
  54. }
  55. }
  56. /// The status of additional user-mode extensions
  57. /// and associated state
  58. #[inline]
  59. pub fn xs(&self) -> FS {
  60. match self.bits.get_bits(15..17) {
  61. 0 => FS::Off,
  62. 1 => FS::Initial,
  63. 2 => FS::Clean,
  64. 3 => FS::Dirty,
  65. _ => unreachable!(),
  66. }
  67. }
  68. /// Permit Supervisor User Memory access
  69. #[inline]
  70. pub fn sum(&self) -> bool {
  71. self.bits.get_bit(18)
  72. }
  73. /// Make eXecutable Readable
  74. #[inline]
  75. pub fn mxr(&self) -> bool {
  76. self.bits.get_bit(19)
  77. }
  78. /// Whether either the FS field or XS field
  79. /// signals the presence of some dirty state
  80. #[inline]
  81. pub fn sd(&self) -> bool {
  82. self.bits.get_bit(size_of::<usize>() * 8 - 1)
  83. }
  84. }
  85. read_csr_as!(Sstatus, 0x100);
  86. write_csr!(0x100);
  87. set!(0x100);
  88. clear!(0x100);
  89. set_clear_csr!(
  90. /// User Interrupt Enable
  91. , set_uie, clear_uie, 1 << 0);
  92. set_clear_csr!(
  93. /// Supervisor Interrupt Enable
  94. , set_sie, clear_sie, 1 << 1);
  95. set_csr!(
  96. /// User Previous Interrupt Enable
  97. , set_upie, 1 << 4);
  98. set_csr!(
  99. /// Supervisor Previous Interrupt Enable
  100. , set_spie, 1 << 5);
  101. set_clear_csr!(
  102. /// Permit Supervisor User Memory access
  103. , set_sum, clear_sum, 1 << 18);
  104. set_clear_csr!(
  105. /// Make eXecutable Readable
  106. , set_mxr, clear_mxr, 1 << 19);
  107. /// Supervisor Previous Privilege Mode
  108. #[inline]
  109. pub unsafe fn set_spp(spp: SPP) {
  110. match spp {
  111. SPP::Supervisor => _set(1 << 8),
  112. SPP::User => _clear(1 << 8),
  113. }
  114. }
  115. /// The status of the floating-point unit
  116. #[inline]
  117. pub unsafe fn set_fs(fs: FS) {
  118. let mut value = _read();
  119. value.set_bits(13..15, fs as usize);
  120. _write(value);
  121. }