Support timer IRQ from PIC

master
WangRunji 7 years ago
parent 8af7220d25
commit 156034c3d1

@ -7,6 +7,7 @@ authors = ["Philipp Oppermann <dev@phil-opp.com>"]
crate-type = ["staticlib"] crate-type = ["staticlib"]
[features] [features]
use_apic = []
test = [] test = []
qemu_auto_exit = [] qemu_auto_exit = []

@ -1,6 +1,8 @@
pub fn init() { pub fn init() {
use consts::irq::IRQ_KBD; use consts::irq::{IRQ_KBD, IRQ_COM1};
// TODO set irq handler // TODO set irq handler
// super::pic::enable_irq(IRQ_KBD); // super::pic::enable_irq(IRQ_KBD);
super::apic::IOAPIC.lock().enable(IRQ_KBD, 0); let mut ioapic = super::apic::IOAPIC.lock();
ioapic.enable(IRQ_KBD, 0);
ioapic.enable(IRQ_COM1, 0);
} }

@ -55,6 +55,14 @@ pub fn enable_irq(irq: u8)
} }
} }
pub fn ack(irq: u8) {
assert!(irq < 16);
MASTER.lock().ack();
if irq >= 8 {
SLAVE.lock().ack();
}
}
struct Pic { struct Pic {
cmd: Pio<u8>, cmd: Pio<u8>,
data: Pio<u8>, data: Pio<u8>,

@ -9,7 +9,7 @@ pub extern "x86-interrupt" fn breakpoint_handler(
pub extern "x86-interrupt" fn double_fault_handler( pub extern "x86-interrupt" fn double_fault_handler(
stack_frame: &mut ExceptionStackFrame, _error_code: u64) stack_frame: &mut ExceptionStackFrame, _error_code: u64)
{ {
println!("\nEXCEPTION: DOUBLE FAULT\n{:#?}", stack_frame); println!("\nEXCEPTION: DOUBLE FAULT\n{:#?}\nErrorCode: {:#x}", stack_frame, _error_code);
loop {} loop {}
} }
@ -18,4 +18,28 @@ pub extern "x86-interrupt" fn page_fault_handler(
{ {
println!("\nEXCEPTION: PAGE FAULT\n{:#?}\n{:#?}", stack_frame, error_code); println!("\nEXCEPTION: PAGE FAULT\n{:#?}\n{:#?}", stack_frame, error_code);
loop {} loop {}
}
use arch::driver::pic;
use consts::irq::*;
pub extern "x86-interrupt" fn keyboard_handler(
stack_frame: &mut ExceptionStackFrame)
{
println!("\nInterupt: Keyboard \n{:#?}", stack_frame);
pic::ack(IRQ_KBD);
}
pub extern "x86-interrupt" fn serial_handler(
stack_frame: &mut ExceptionStackFrame)
{
println!("\nInterupt: Serial \n{:#?}", stack_frame);
pic::ack(IRQ_COM1);
}
pub extern "x86-interrupt" fn timer_handler(
stack_frame: &mut ExceptionStackFrame)
{
println!("\nInterupt: Timer \n{:#?}", stack_frame);
pic::ack(IRQ_TIMER);
} }

@ -10,9 +10,13 @@ mod irq;
lazy_static! { lazy_static! {
static ref IDT: Idt = { static ref IDT: Idt = {
use self::irq::*; use self::irq::*;
use consts::irq::*;
let mut idt = Idt::new(); let mut idt = Idt::new();
idt.breakpoint.set_handler_fn(breakpoint_handler); idt.breakpoint.set_handler_fn(breakpoint_handler);
idt.page_fault.set_handler_fn(page_fault_handler); idt.page_fault.set_handler_fn(page_fault_handler);
idt[(T_IRQ0 + IRQ_COM1) as usize].set_handler_fn(serial_handler);
idt[(T_IRQ0 + IRQ_KBD) as usize].set_handler_fn(keyboard_handler);
idt[(T_IRQ0 + IRQ_TIMER) as usize].set_handler_fn(timer_handler);
unsafe { unsafe {
idt.double_fault.set_handler_fn(double_fault_handler) idt.double_fault.set_handler_fn(double_fault_handler)
.set_stack_index(DOUBLE_FAULT_IST_INDEX as u16); .set_stack_index(DOUBLE_FAULT_IST_INDEX as u16);

@ -76,12 +76,17 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) {
let acpi = arch::driver::acpi::init().expect("Failed to init ACPI"); let acpi = arch::driver::acpi::init().expect("Failed to init ACPI");
debug!("{:?}", acpi); debug!("{:?}", acpi);
arch::driver::pic::disable(); if cfg!(feature = "use_apic") {
arch::driver::pic::disable();
memory_controller.map_page_identity(acpi.lapic_addr as usize); // LAPIC
memory_controller.map_page_identity(0xFEC00000); // IOAPIC memory_controller.map_page_identity(acpi.lapic_addr as usize); // LAPIC
arch::driver::apic::init(acpi.lapic_addr, acpi.ioapic_id); memory_controller.map_page_identity(0xFEC00000); // IOAPIC
arch::driver::apic::init(acpi.lapic_addr, acpi.ioapic_id);
} else {
arch::driver::pic::init();
}
unsafe{ x86_64::instructions::interrupts::enable(); }
loop{}
test_end!(); test_end!();
} }

Loading…
Cancel
Save