Skip to content

Commit 7ae7da5

Browse files
authored
Merge pull request #547 from Freax13/feature/cr8
implement functions for accessing CR8
2 parents cbd39d6 + c9bfc08 commit 7ae7da5

File tree

1 file changed

+113
-0
lines changed

1 file changed

+113
-0
lines changed

src/registers/control.rs

+113
Original file line numberDiff line numberDiff line change
@@ -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"))]
163230
mod 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

Comments
 (0)