@@ -159,6 +159,73 @@ bitflags! {
159
159
}
160
160
}
161
161
162
+ /// Contains the task priority.
163
+ #[ derive( Debug ) ]
164
+ pub struct Cr8 ;
165
+
166
+ /// A priority class for an interrupt. Loading CR8 with a priority class blocks
167
+ /// all interrupts of that class or lower. Note that 0 is not a priority class,
168
+ /// if CR8 contains 0, all interrupts are enabled regardless of their priority
169
+ /// class.
170
+ #[ derive( Debug ) ]
171
+ pub enum PriorityClass {
172
+ // 0 is not a valid priority class, 1 is the first valid class
173
+ /// Priority class 1
174
+ PriorityClass1 = 1 ,
175
+ /// Priority class 2
176
+ PriorityClass2 ,
177
+ /// Priority class 3
178
+ PriorityClass3 ,
179
+ /// Priority class 4
180
+ PriorityClass4 ,
181
+ /// Priority class 5
182
+ PriorityClass5 ,
183
+ /// Priority class 6
184
+ PriorityClass6 ,
185
+ /// Priority class 7
186
+ PriorityClass7 ,
187
+ /// Priority class 8
188
+ PriorityClass8 ,
189
+ /// Priority class 9
190
+ PriorityClass9 ,
191
+ /// Priority class 10
192
+ PriorityClass10 ,
193
+ /// Priority class 11
194
+ PriorityClass11 ,
195
+ /// Priority class 12
196
+ PriorityClass12 ,
197
+ /// Priority class 13
198
+ PriorityClass13 ,
199
+ /// Priority class 14
200
+ PriorityClass14 ,
201
+ /// Priority class 15
202
+ PriorityClass15 ,
203
+ }
204
+
205
+ impl PriorityClass {
206
+ /// Convert a number into a priority class
207
+ pub const fn new ( priority_class : u8 ) -> Option < Self > {
208
+ Some ( match priority_class {
209
+ 1 => Self :: PriorityClass1 ,
210
+ 2 => Self :: PriorityClass2 ,
211
+ 3 => Self :: PriorityClass3 ,
212
+ 4 => Self :: PriorityClass4 ,
213
+ 5 => Self :: PriorityClass5 ,
214
+ 6 => Self :: PriorityClass6 ,
215
+ 7 => Self :: PriorityClass7 ,
216
+ 8 => Self :: PriorityClass8 ,
217
+ 9 => Self :: PriorityClass9 ,
218
+ 10 => Self :: PriorityClass10 ,
219
+ 11 => Self :: PriorityClass11 ,
220
+ 12 => Self :: PriorityClass12 ,
221
+ 13 => Self :: PriorityClass13 ,
222
+ 14 => Self :: PriorityClass14 ,
223
+ 15 => Self :: PriorityClass15 ,
224
+ _ => return None ,
225
+ } )
226
+ }
227
+ }
228
+
162
229
#[ cfg( all( feature = "instructions" , target_arch = "x86_64" ) ) ]
163
230
mod x86_64 {
164
231
use super :: * ;
@@ -496,4 +563,50 @@ mod x86_64 {
496
563
}
497
564
}
498
565
}
566
+
567
+ impl Cr8 {
568
+ /// Read the current priority class in CR8.
569
+ #[ inline]
570
+ pub fn read ( ) -> Option < PriorityClass > {
571
+ PriorityClass :: new ( Self :: read_raw ( ) as u8 )
572
+ }
573
+
574
+ /// Read the current raw CR8 value.
575
+ #[ inline]
576
+ pub fn read_raw ( ) -> u64 {
577
+ let value: u64 ;
578
+
579
+ unsafe {
580
+ asm ! ( "mov {}, cr8" , out( reg) value, options( nomem, nostack, preserves_flags) ) ;
581
+ }
582
+
583
+ value
584
+ }
585
+
586
+ /// Write the priority class to CR8.
587
+ #[ inline]
588
+ pub fn write ( priority_class : Option < PriorityClass > ) {
589
+ let value = priority_class. map_or ( 0 , |pc| pc as u64 ) ;
590
+ Self :: write_raw ( value) ;
591
+ }
592
+
593
+ /// Write to CR8.
594
+ #[ inline]
595
+ pub fn write_raw ( value : u64 ) {
596
+ unsafe {
597
+ asm ! ( "mov cr8, {}" , in( reg) value, options( nomem, nostack, preserves_flags) ) ;
598
+ }
599
+ }
600
+
601
+ /// Updates the priority class in CR8.
602
+ #[ inline]
603
+ pub fn update < F > ( f : F )
604
+ where
605
+ F : FnOnce ( & mut Option < PriorityClass > ) ,
606
+ {
607
+ let mut priority_class = Self :: read ( ) ;
608
+ f ( & mut priority_class) ;
609
+ Self :: write ( priority_class) ;
610
+ }
611
+ }
499
612
}
0 commit comments