@@ -159,6 +159,73 @@ bitflags! {
159159 }
160160}
161161
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+
162229#[ cfg( all( feature = "instructions" , target_arch = "x86_64" ) ) ]
163230mod x86_64 {
164231 use super :: * ;
@@ -496,4 +563,50 @@ mod x86_64 {
496563 }
497564 }
498565 }
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+ }
499612}
0 commit comments