redox/arch/x86_64/src/interrupt.rs

114 lines
3.1 KiB
Rust

//! Interrupt instructions
/// Clear interrupts
#[inline(always)]
pub unsafe fn disable() {
asm!("cli" : : : : "intel", "volatile");
}
/// Set interrupts
#[inline(always)]
pub unsafe fn enable() {
asm!("sti" : : : : "intel", "volatile");
}
/// Set interrupts and halt
#[inline(always)]
pub unsafe fn enable_and_halt() {
asm!("sti
hlt"
: : : : "intel", "volatile");
}
/// Halt instruction
#[inline(always)]
pub unsafe fn halt() {
asm!("hlt" : : : : "intel", "volatile");
}
/// Get a stack trace
//TODO: Check for stack being mapped before dereferencing
#[inline(never)]
pub unsafe fn stack_trace() {
let mut rbp: usize;
asm!("xchg bx, bx" : "={rbp}"(rbp) : : : "intel", "volatile");
println!("TRACE: {:>016X}", rbp);
//Maximum 64 frames
for _frame in 0..64 {
unsafe {
let rip = *(rbp as *const usize).offset(1);
println!(" {:>016X}: {:>016X}", rbp, rip);
if rip == 0 {
break;
}
rbp = *(rbp as *const usize);
}
}
}
/// x86 External Interrupts (1-16).
pub static EXCEPTIONS: [Descriptor; 21] = [
Descriptor::new("Division error", Kind::Fault),
Descriptor::new("Debug trap", Kind::Trap),
Descriptor::new("Unmaskable interrupt", Kind::Unmaskable),
Descriptor::new("Breakpoint", Kind::Trap),
Descriptor::new("Overflow", Kind::Trap),
Descriptor::new("Out of bound", Kind::Fault),
Descriptor::new("Invalid opcode", Kind::Fault),
Descriptor::new("Device unavailable", Kind::Fault),
Descriptor::new("Double fault", Kind::Fault),
Descriptor::new("Coprocessor segment overrun", Kind::Fault),
Descriptor::new("Invalid TSS", Kind::Fault),
Descriptor::new("Segment not present", Kind::Fault),
Descriptor::new("Stack-segment fault", Kind::Fault),
Descriptor::new("General protection", Kind::Fault),
Descriptor::new("Page fault", Kind::Fault),
Descriptor::new("Reserved", Kind::Reserved),
Descriptor::new("x87 FPU", Kind::Fault),
Descriptor::new("Unaligned memory access", Kind::Fault),
Descriptor::new("Machine check", Kind::Abort),
Descriptor::new("SIMD floating-point", Kind::Fault),
Descriptor::new("Virtualization violation", Kind::Fault),
];
/// An interrupt description.
#[derive(Debug, Copy, Clone)]
pub struct Descriptor {
/// The description of this interrupt.
pub desc: &'static str,
/// The interrupt type.
pub kind: Kind,
}
impl Descriptor {
/// Create a new interrupt description.
pub const fn new(desc: &'static str, kind: Kind) -> Descriptor {
Descriptor {
desc: desc,
kind: kind,
}
}
}
/// The interrupt kind.
#[derive(Debug, Copy, Clone)]
pub enum Kind {
/// A fault.
///
/// This can have multiple sources, but is often a result of a program error of some sort.
Fault,
/// A trap.
///
/// These are often for debugging purposes.
Trap,
/// A deliberate abort.
Abort,
/// An unmaskable interrupt.
///
/// This is a forced interrupt which need to be handled immediately.
Unmaskable,
/// Reserved or deprecated.
Reserved,
}