Fill in all exception and IRQ entries. Handle PIT, keyboard IRQs
This commit is contained in:
parent
a9a8c2b340
commit
f784e9a06a
16 changed files with 441 additions and 219 deletions
97
arch/x86_64/src/interrupt/exception.rs
Normal file
97
arch/x86_64/src/interrupt/exception.rs
Normal file
|
@ -0,0 +1,97 @@
|
|||
use super::halt;
|
||||
|
||||
interrupt!(divide_by_zero, {
|
||||
print!("Divide by zero fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt!(debug, {
|
||||
print!("Debug trap\n");
|
||||
});
|
||||
|
||||
interrupt!(non_maskable, {
|
||||
print!("Non-maskable interrupt\n");
|
||||
});
|
||||
|
||||
interrupt!(breakpoint, {
|
||||
print!("Breakpoint trap\n");
|
||||
});
|
||||
|
||||
interrupt!(overflow, {
|
||||
print!("Overflow trap\n");
|
||||
});
|
||||
|
||||
interrupt!(bound_range, {
|
||||
print!("Bound range exceeded fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt!(invalid_opcode, {
|
||||
print!("Invalid opcode fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt!(device_not_available, {
|
||||
print!("Device not available fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt_error!(double_fault, {
|
||||
print!("Double fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt_error!(invalid_tss, {
|
||||
print!("Invalid TSS fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt_error!(segment_not_present, {
|
||||
print!("Segment not present fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt_error!(stack_segment, {
|
||||
print!("Stack segment fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt_error!(protection, {
|
||||
print!("Protection fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt_error!(page, {
|
||||
print!("Page fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt!(fpu, {
|
||||
print!("FPU floating point fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt_error!(alignment_check, {
|
||||
print!("Alignment check fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt!(machine_check, {
|
||||
print!("Machine check fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt!(simd, {
|
||||
print!("SIMD floating point fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt!(virtualization, {
|
||||
print!("Virtualization fault\n");
|
||||
loop { halt(); }
|
||||
});
|
||||
|
||||
interrupt_error!(security, {
|
||||
print!("Security exception\n");
|
||||
loop { halt(); }
|
||||
});
|
98
arch/x86_64/src/interrupt/irq.rs
Normal file
98
arch/x86_64/src/interrupt/irq.rs
Normal file
|
@ -0,0 +1,98 @@
|
|||
use x86::io;
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn master_ack() {
|
||||
io::outb(0x20, 0x20);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
unsafe fn slave_ack() {
|
||||
io::outb(0xA0, 0x20);
|
||||
master_ack();
|
||||
}
|
||||
|
||||
interrupt!(pit, {
|
||||
io::outb(0x43, 0);
|
||||
let low = io::inb(0x40);
|
||||
let high = io::inb(0x40);
|
||||
let count = (high as u16) << 8 | (low as u16);
|
||||
let missed = 5370 - count;
|
||||
master_ack();
|
||||
});
|
||||
|
||||
interrupt!(keyboard, {
|
||||
let data = io::inb(0x60);
|
||||
print!("KEYBOARD {:X}\n", data);
|
||||
master_ack();
|
||||
});
|
||||
|
||||
interrupt!(cascade, {
|
||||
print!("CASCADE\n");
|
||||
master_ack();
|
||||
});
|
||||
|
||||
interrupt!(com2, {
|
||||
print!("COM2\n");
|
||||
master_ack();
|
||||
});
|
||||
|
||||
interrupt!(com1, {
|
||||
print!("COM1\n");
|
||||
master_ack();
|
||||
});
|
||||
|
||||
interrupt!(lpt2, {
|
||||
print!("LPT2\n");
|
||||
master_ack();
|
||||
});
|
||||
|
||||
interrupt!(floppy, {
|
||||
print!("FLOPPY\n");
|
||||
master_ack();
|
||||
});
|
||||
|
||||
interrupt!(lpt1, {
|
||||
print!("LPT1\n");
|
||||
master_ack();
|
||||
});
|
||||
|
||||
interrupt!(rtc, {
|
||||
print!("RTC\n");
|
||||
slave_ack();
|
||||
});
|
||||
|
||||
interrupt!(pci1, {
|
||||
print!("PCI1\n");
|
||||
slave_ack();
|
||||
});
|
||||
|
||||
interrupt!(pci2, {
|
||||
print!("PCI2\n");
|
||||
slave_ack();
|
||||
});
|
||||
|
||||
interrupt!(pci3, {
|
||||
print!("PCI3\n");
|
||||
slave_ack();
|
||||
});
|
||||
|
||||
interrupt!(mouse, {
|
||||
let data = io::inb(0x60);
|
||||
print!("MOUSE {:X}\n", data);
|
||||
slave_ack();
|
||||
});
|
||||
|
||||
interrupt!(fpu, {
|
||||
print!("FPU\n");
|
||||
slave_ack();
|
||||
});
|
||||
|
||||
interrupt!(ata1, {
|
||||
print!("ATA1\n");
|
||||
slave_ack();
|
||||
});
|
||||
|
||||
interrupt!(ata2, {
|
||||
print!("ATA2\n");
|
||||
slave_ack();
|
||||
});
|
57
arch/x86_64/src/interrupt/mod.rs
Normal file
57
arch/x86_64/src/interrupt/mod.rs
Normal file
|
@ -0,0 +1,57 @@
|
|||
//! Interrupt instructions
|
||||
|
||||
pub mod exception;
|
||||
pub mod irq;
|
||||
pub mod syscall;
|
||||
|
||||
/// 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");
|
||||
}
|
||||
|
||||
/// Pause instruction
|
||||
/// Safe because it is similar to a NOP, and has no memory effects
|
||||
#[inline(always)]
|
||||
pub fn pause() {
|
||||
unsafe { asm!("pause" : : : : "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 {
|
||||
let rip = *(rbp as *const usize).offset(1);
|
||||
println!(" {:>016X}: {:>016X}", rbp, rip);
|
||||
if rip == 0 {
|
||||
break;
|
||||
}
|
||||
rbp = *(rbp as *const usize);
|
||||
}
|
||||
}
|
22
arch/x86_64/src/interrupt/syscall.rs
Normal file
22
arch/x86_64/src/interrupt/syscall.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
#[naked]
|
||||
pub unsafe extern fn syscall() {
|
||||
extern {
|
||||
fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> usize;
|
||||
}
|
||||
|
||||
let a;
|
||||
let b;
|
||||
let c;
|
||||
let d;
|
||||
let e;
|
||||
let f;
|
||||
asm!("" : "={rax}"(a), "={rbx}"(b), "={rcx}"(c), "={rdx}"(d), "={rsi}"(e), "={rdi}"(f)
|
||||
: : : "intel", "volatile");
|
||||
|
||||
let a = syscall(a, b, c, d, e, f);
|
||||
|
||||
asm!("" : : "{rax}"(a) : : "intel", "volatile");
|
||||
|
||||
// Pop scratch registers, error code, and return
|
||||
asm!("iretq" : : : : "intel", "volatile");
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue