Handle timer interrupts

This commit is contained in:
Yash Karandikar 2021-09-16 12:13:36 -05:00
parent d8df82cdad
commit 880e840ac5
5 changed files with 61 additions and 11 deletions

10
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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())
}
}

View file

@ -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)]

View file

@ -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();
});
}