aphrodite/arch/x86_asmp/interrupts.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
//! Provides interrupt-related functions
#![cfg(any(target_arch = "x86"))]
use core::arch::asm;
/// Returns whether interrupts are enabled or not.
pub fn interrupts_enabled() -> bool {
let flags: u32;
unsafe {
asm!(
"pushf",
"pop {0:e}", out(reg) flags
)
}
(flags & (1 << 9)) == 0
}
/// Disables interrupts.
pub fn disable_interrupts() {
unsafe {
asm!("cli")
}
}
/// Disables interrupts and returns the value of them.
pub fn pop_irq() -> u32 {
let flags: u32;
unsafe {
asm!(
"pushf",
"cli",
"pop {0:e}", out(reg) flags
)
}
flags
}
/// Restores interrupts after a [pop_irq] call.
pub fn restore_irq(flags: u32) {
unsafe {
asm!(
"push {0:e}", in(reg) flags
);
asm!(
"popf"
);
}
}
/// The IDTR. Used internally in [load_idt].
#[repr(C)]
struct IDTR {
base: *const u8,
size: usize
}
/// Loads an interrupt descriptor table.
pub fn load_idt(base: *const u8, size: usize) {
let idtr = IDTR {
base,
size
};
unsafe {
asm!(
"lidt {}", in(reg) &idtr
)
}
}