sstatus.rs 2.9 KB

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