Handle timer interrupts
This commit is contained in:
parent
d8df82cdad
commit
880e840ac5
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -8,6 +8,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"bootloader",
|
||||
"lazy_static",
|
||||
"pic8259",
|
||||
"spin",
|
||||
"volatile 0.2.7",
|
||||
"x86_64",
|
||||
|
@ -40,6 +41,15 @@ dependencies = [
|
|||
"spin",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pic8259"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24ec21f514e2e16e94649f1d041ca4a7069b512c037ac156360652a775e6229d"
|
||||
dependencies = [
|
||||
"x86_64",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
|
|
|
@ -10,6 +10,7 @@ bootloader = "0.9.8"
|
|||
volatile = "0.2.6"
|
||||
spin = "0.5.2"
|
||||
x86_64 = "0.14.2"
|
||||
pic8259 = "0.10.1"
|
||||
|
||||
[dependencies.lazy_static]
|
||||
version = "1.0"
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
use x86_64::structures::idt::{InterruptDescriptorTable, InterruptStackFrame};
|
||||
use crate::println;
|
||||
use crate::print;
|
||||
use lazy_static::lazy_static;
|
||||
use crate::gdt;
|
||||
use pic8259::ChainedPics;
|
||||
use spin::Mutex;
|
||||
|
||||
lazy_static! {
|
||||
static ref IDT: InterruptDescriptorTable = {
|
||||
|
@ -11,12 +14,16 @@ lazy_static! {
|
|||
idt.double_fault.set_handler_fn(double_fault_handler)
|
||||
.set_stack_index(gdt::DOUBLE_FAULT_IST_INDEX);
|
||||
}
|
||||
idt[InterruptIndex::Timer.as_usize()]
|
||||
.set_handler_fn(timer_interrupt_handler);
|
||||
idt
|
||||
};
|
||||
}
|
||||
|
||||
pub fn init_idt() {
|
||||
pub fn init() {
|
||||
IDT.load();
|
||||
unsafe { PICS.lock().initialize() };
|
||||
x86_64::instructions::interrupts::enable();
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
||||
|
@ -26,3 +33,32 @@ extern "x86-interrupt" fn breakpoint_handler(stack_frame: InterruptStackFrame) {
|
|||
extern "x86-interrupt" fn double_fault_handler(stack_frame: InterruptStackFrame, _error_code: u64) -> ! {
|
||||
panic!("EXCEPTION : DOUBLE FAULT\n{:#?}", stack_frame);
|
||||
}
|
||||
|
||||
extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) {
|
||||
print!(".");
|
||||
|
||||
unsafe {
|
||||
PICS.lock().notify_end_of_interrupt(InterruptIndex::Timer.as_u8());
|
||||
}
|
||||
}
|
||||
|
||||
pub const PIC_1_OFFSET: u8 = 32;
|
||||
pub const PIC_2_OFFSET: u8 = PIC_1_OFFSET + 8;
|
||||
|
||||
pub static PICS: Mutex<ChainedPics> = Mutex::new(unsafe { ChainedPics::new(PIC_1_OFFSET, PIC_2_OFFSET) });
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[repr(u8)]
|
||||
pub enum InterruptIndex {
|
||||
Timer = PIC_1_OFFSET
|
||||
}
|
||||
|
||||
impl InterruptIndex {
|
||||
fn as_u8(self) -> u8 {
|
||||
self as u8
|
||||
}
|
||||
|
||||
fn as_usize(self) -> usize {
|
||||
usize::from(self.as_u8())
|
||||
}
|
||||
}
|
||||
|
|
12
src/main.rs
12
src/main.rs
|
@ -21,7 +21,7 @@ fn panic(info: &PanicInfo) -> ! {
|
|||
|
||||
fn init() {
|
||||
gdt::init_gdt();
|
||||
interrupts::init_idt();
|
||||
interrupts::init();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
@ -32,17 +32,13 @@ pub extern "C" fn _start() {
|
|||
|
||||
x86_64::instructions::interrupts::int3();
|
||||
|
||||
fn stack_overflow() {
|
||||
stack_overflow();
|
||||
}
|
||||
|
||||
stack_overflow();
|
||||
|
||||
#[cfg(test)]
|
||||
test_main();
|
||||
|
||||
println!("It did not crash!");
|
||||
loop {}
|
||||
loop {
|
||||
x86_64::instructions::hlt();
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -142,5 +142,12 @@ macro_rules! println {
|
|||
#[doc(hidden)]
|
||||
pub fn _print(args: fmt::Arguments) {
|
||||
use core::fmt::Write;
|
||||
WRITER.lock().write_fmt(args).unwrap();
|
||||
}
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
interrupts::without_interrupts(|| {
|
||||
WRITER.lock().write_fmt(args).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue