2016-09-01 01:45:21 +02:00
|
|
|
//! Interrupt instructions
|
|
|
|
|
2016-09-02 20:27:45 +02:00
|
|
|
use core::mem;
|
|
|
|
|
|
|
|
use paging::{ActivePageTable, VirtualAddress};
|
|
|
|
|
2016-09-01 01:45:21 +02:00
|
|
|
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;
|
2016-09-02 22:47:56 +02:00
|
|
|
asm!("" : "={rbp}"(rbp) : : : "intel", "volatile");
|
2016-09-01 01:45:21 +02:00
|
|
|
|
|
|
|
println!("TRACE: {:>016X}", rbp);
|
|
|
|
//Maximum 64 frames
|
2016-09-02 20:27:45 +02:00
|
|
|
let active_table = ActivePageTable::new();
|
2016-09-01 01:45:21 +02:00
|
|
|
for _frame in 0..64 {
|
2016-09-08 23:45:26 +02:00
|
|
|
if let Some(rip_rbp) = rbp.checked_add(mem::size_of::<usize>()) {
|
|
|
|
if active_table.translate(VirtualAddress::new(rbp)).is_some() && active_table.translate(VirtualAddress::new(rip_rbp)).is_some() {
|
|
|
|
let rip = *(rip_rbp as *const usize);
|
|
|
|
if rip == 0 {
|
|
|
|
println!(" {:>016X}: EMPTY RETURN", rbp);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
println!(" {:>016X}: {:>016X}", rbp, rip);
|
|
|
|
rbp = *(rbp as *const usize);
|
|
|
|
} else {
|
|
|
|
println!(" {:>016X}: GUARD PAGE", rbp);
|
|
|
|
break;
|
|
|
|
}
|
2016-09-02 20:27:45 +02:00
|
|
|
} else {
|
2016-09-08 23:45:26 +02:00
|
|
|
println!(" {:>016X}: RBP OVERFLOW", rbp);
|
2016-09-01 01:45:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|