use core::fmt;
#[derive(Debug)]
pub struct InterruptDescription {
pub vector: u8,
pub mnemonic: &'static str,
pub description: &'static str,
pub irqtype: &'static str,
pub source: &'static str
}
impl fmt::Display for InterruptDescription {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} ({}, vec={}) {}", self.mnemonic, self.irqtype, self.vector, self.description)
}
}
pub static EXCEPTIONS: [InterruptDescription; 15] = [
InterruptDescription{ vector: 0, mnemonic: "#DE", description: "Divide Error", irqtype: "Fault", source: "DIV and IDIV instructions." },
InterruptDescription{ vector: 1, mnemonic: "#DB", description: "RESERVED", irqtype: "Fault/ Trap", source: "For Intel use only." },
InterruptDescription{ vector: 2, mnemonic: "NMI", description: "Interrupt", irqtype: "Interrupt", source: "Nonmaskable external interrupt." },
InterruptDescription{ vector: 3, mnemonic: "#BP", description: "Breakpoint", irqtype: "Trap", source: "INT 3 instruction." },
InterruptDescription{ vector: 4, mnemonic: "#OF", description: "Overflow", irqtype: "Trap", source: "INTO instruction." },
InterruptDescription{ vector: 5, mnemonic: "#BR", description: "BOUND Range Exceeded", irqtype: "Fault", source: "BOUND instruction." },
InterruptDescription{ vector: 6, mnemonic: "#UD", description: "Invalid Opcode (Undefined Opcode)", irqtype: "Fault", source: "UD2 instruction or reserved opcode." },
InterruptDescription{ vector: 7, mnemonic: "#NM", description: "Device Not Available (No Math Coprocessor)", irqtype: "Fault", source: "Floating-point or WAIT/FWAIT instruction." },
InterruptDescription{ vector: 8, mnemonic: "#DF", description: "Double Fault", irqtype: "Abort", source: "Any instruction that can generate an exception, an NMI, or an INTR." },
InterruptDescription{ vector: 9, mnemonic: "" , description: "Coprocessor Segment Overrun", irqtype: "Fault", source: "Floating-point instruction." },
InterruptDescription{ vector: 10, mnemonic: "#TS", description: "Invalid TSS", irqtype: "Fault", source: "Task switch or TSS access." },
InterruptDescription{ vector: 11, mnemonic: "#NP", description: "Segment Not Present", irqtype: "Fault", source: "Loading segment registers or accessing system segments." },
InterruptDescription{ vector: 12, mnemonic: "#SS", description: "Stack-Segment Fault", irqtype: "Fault", source: "Stack operations and SS register loads." },
InterruptDescription{ vector: 13, mnemonic: "#GP", description: "General Protection", irqtype: "Fault", source: "Any memory reference and other protection checks." },
InterruptDescription{ vector: 14, mnemonic: "#PF", description: "Page Fault", irqtype: "Fault", source: "Any memory reference." }
];
pub unsafe fn enable() {
asm!("sti");
}
pub unsafe fn disable() {
asm!("cli");
}
#[macro_export]
macro_rules! int {
( $x:expr ) => {
{
asm!("int $0" :: "N" ($x));
}
};
}
#[derive(Debug, Clone, Copy)]
#[repr(C, packed)]
pub struct IdtEntry {
pub base_lo: u16,
pub sel: u16,
pub res0: u8,
pub flags: u8,
pub base_hi: u64,
pub res1: u16
}
bitflags!{
flags PageFaultError: u32 {
const PFAULT_ERROR_P = 0b0001,
const PFAULT_ERROR_WR = 0b0010,
const PFAULT_ERROR_US = 0b0100,
const PFAULT_ERROR_RSVD = 0b1000,
const PFAULT_ERROR_ID = 0b1000,
}
}
impl fmt::Debug for PageFaultError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
let p = match self.contains(PFAULT_ERROR_P) {
false => "The fault was caused by a non-present page.",
true => "The fault was caused by a page-level protection violation."
};
let wr = match self.contains(PFAULT_ERROR_WR) {
false => "The access causing the fault was a read.",
true => "The access causing the fault was a write."
};
let us = match self.contains(PFAULT_ERROR_US) {
false => "The access causing the fault originated when the processor was executing in supervisor mode.",
true => "The access causing the fault originated when the processor was executing in user mode."
};
let rsvd = match self.contains(PFAULT_ERROR_RSVD) {
false => "The fault was not caused by reserved bit violation.",
true => "The fault was caused by reserved bits set to 1 in a page directory."
};
let id = match self.contains(PFAULT_ERROR_ID) {
false => "The fault was not caused by an instruction fetch.",
true => "The fault was caused by an instruction fetch."
};
write!(f, "{}\n{}\n{}\n{}\n{}", p, wr, us, rsvd, id)
}
}