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
        )
    }
}