diff --git a/Cargo.toml b/Cargo.toml index 80babe5..2b4742c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ authors = ["Philipp Oppermann "] crate-type = ["staticlib"] [features] +use_apic = [] test = [] qemu_auto_exit = [] diff --git a/src/arch/x86_64/driver/console.rs b/src/arch/x86_64/driver/console.rs index 1d088cc..5ec13ad 100644 --- a/src/arch/x86_64/driver/console.rs +++ b/src/arch/x86_64/driver/console.rs @@ -1,6 +1,8 @@ pub fn init() { - use consts::irq::IRQ_KBD; + use consts::irq::{IRQ_KBD, IRQ_COM1}; // TODO set irq handler // 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); } \ No newline at end of file diff --git a/src/arch/x86_64/driver/pic.rs b/src/arch/x86_64/driver/pic.rs index 6241c40..f597cdf 100644 --- a/src/arch/x86_64/driver/pic.rs +++ b/src/arch/x86_64/driver/pic.rs @@ -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 { cmd: Pio, data: Pio, diff --git a/src/interrupts/irq.rs b/src/interrupts/irq.rs index 0d246c4..282efa7 100644 --- a/src/interrupts/irq.rs +++ b/src/interrupts/irq.rs @@ -9,7 +9,7 @@ pub extern "x86-interrupt" fn breakpoint_handler( pub extern "x86-interrupt" fn double_fault_handler( 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 {} } @@ -18,4 +18,28 @@ pub extern "x86-interrupt" fn page_fault_handler( { println!("\nEXCEPTION: PAGE FAULT\n{:#?}\n{:#?}", stack_frame, error_code); 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); } \ No newline at end of file diff --git a/src/interrupts/mod.rs b/src/interrupts/mod.rs index d292184..165ad80 100644 --- a/src/interrupts/mod.rs +++ b/src/interrupts/mod.rs @@ -10,9 +10,13 @@ mod irq; lazy_static! { static ref IDT: Idt = { use self::irq::*; + use consts::irq::*; let mut idt = Idt::new(); 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 { idt.double_fault.set_handler_fn(double_fault_handler) .set_stack_index(DOUBLE_FAULT_IST_INDEX as u16); diff --git a/src/lib.rs b/src/lib.rs index 417ddb4..d1a49fe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -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"); debug!("{:?}", acpi); - arch::driver::pic::disable(); - - memory_controller.map_page_identity(acpi.lapic_addr as usize); // LAPIC - memory_controller.map_page_identity(0xFEC00000); // IOAPIC - arch::driver::apic::init(acpi.lapic_addr, acpi.ioapic_id); - + 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 + arch::driver::apic::init(acpi.lapic_addr, acpi.ioapic_id); + } else { + arch::driver::pic::init(); + } + unsafe{ x86_64::instructions::interrupts::enable(); } + loop{} test_end!(); }