From 3b792baf5b16bd2a1469acc0694a985aeb645b17 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Sun, 15 Apr 2018 01:01:44 +0800 Subject: [PATCH] ACK for APIC IRQ --- Makefile | 1 + src/arch/x86_64/driver/apic/lapic.c | 8 ++++++++ src/arch/x86_64/driver/apic/lapic.rs | 7 +++++++ src/arch/x86_64/driver/apic/mod.rs | 1 + src/arch/x86_64/driver/interrupt.rs | 9 +++++++++ src/arch/x86_64/driver/mod.rs | 3 ++- src/interrupts/irq.rs | 12 ++++++++---- src/lib.rs | 2 +- 8 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 src/arch/x86_64/driver/interrupt.rs diff --git a/Makefile b/Makefile index 559e148..350677b 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ assembly_source_files := $(wildcard $(boot_src)/*.asm) assembly_object_files := $(patsubst $(boot_src)/%.asm, \ build/arch/$(arch)/boot/%.o, $(assembly_source_files)) qemu_opts := -cdrom $(iso) -smp 2 -serial mon:stdio +features := use_apic ifdef travis test := 1 diff --git a/src/arch/x86_64/driver/apic/lapic.c b/src/arch/x86_64/driver/apic/lapic.c index d4655fc..f0eecfb 100644 --- a/src/arch/x86_64/driver/apic/lapic.c +++ b/src/arch/x86_64/driver/apic/lapic.c @@ -97,4 +97,12 @@ lapicinit(void) // Enable interrupts on the APIC (but not on the processor). lapicw(TPR, 0); +} + +// Acknowledge interrupt. +void +lapiceoi(void) +{ + if(lapic) + lapicw(EOI, 0); } \ No newline at end of file diff --git a/src/arch/x86_64/driver/apic/lapic.rs b/src/arch/x86_64/driver/apic/lapic.rs index 0e05a68..b7b0ebb 100644 --- a/src/arch/x86_64/driver/apic/lapic.rs +++ b/src/arch/x86_64/driver/apic/lapic.rs @@ -1,6 +1,7 @@ extern { static mut lapic: *const (); fn lapicinit(); // must set `lapic` first + fn lapiceoi(); // ack } pub fn init(lapic_addr: *const ()) { @@ -10,4 +11,10 @@ pub fn init(lapic_addr: *const ()) { lapicinit(); } debug!("lapic: init end"); +} + +pub fn ack(_irq: u8) { + unsafe { + lapiceoi(); + } } \ No newline at end of file diff --git a/src/arch/x86_64/driver/apic/mod.rs b/src/arch/x86_64/driver/apic/mod.rs index a6c9ff3..27b0f35 100644 --- a/src/arch/x86_64/driver/apic/mod.rs +++ b/src/arch/x86_64/driver/apic/mod.rs @@ -1,4 +1,5 @@ pub use self::ioapic::IOAPIC; +pub use self::lapic::ack; mod lapic; mod ioapic; diff --git a/src/arch/x86_64/driver/interrupt.rs b/src/arch/x86_64/driver/interrupt.rs new file mode 100644 index 0000000..3b1e404 --- /dev/null +++ b/src/arch/x86_64/driver/interrupt.rs @@ -0,0 +1,9 @@ +use x86_64; + +pub fn enable() { + unsafe{ x86_64::instructions::interrupts::enable(); } +} + +pub fn disable() { + unsafe{ x86_64::instructions::interrupts::disable(); } +} \ No newline at end of file diff --git a/src/arch/x86_64/driver/mod.rs b/src/arch/x86_64/driver/mod.rs index 5a93241..02e8e4b 100644 --- a/src/arch/x86_64/driver/mod.rs +++ b/src/arch/x86_64/driver/mod.rs @@ -4,4 +4,5 @@ pub mod apic; pub mod mp; pub mod serial; pub mod pic; -pub mod console; \ No newline at end of file +pub mod console; +pub mod interrupt; \ No newline at end of file diff --git a/src/interrupts/irq.rs b/src/interrupts/irq.rs index 282efa7..90f71ad 100644 --- a/src/interrupts/irq.rs +++ b/src/interrupts/irq.rs @@ -20,26 +20,30 @@ pub extern "x86-interrupt" fn page_fault_handler( loop {} } -use arch::driver::pic; +#[cfg(feature = "use_apic")] +use arch::driver::apic::ack; +#[cfg(not(feature = "use_apic"))] +use arch::driver::pic::ack; + use consts::irq::*; pub extern "x86-interrupt" fn keyboard_handler( stack_frame: &mut ExceptionStackFrame) { println!("\nInterupt: Keyboard \n{:#?}", stack_frame); - pic::ack(IRQ_KBD); + ack(IRQ_KBD); } pub extern "x86-interrupt" fn serial_handler( stack_frame: &mut ExceptionStackFrame) { println!("\nInterupt: Serial \n{:#?}", stack_frame); - pic::ack(IRQ_COM1); + ack(IRQ_COM1); } pub extern "x86-interrupt" fn timer_handler( stack_frame: &mut ExceptionStackFrame) { println!("\nInterupt: Timer \n{:#?}", stack_frame); - pic::ack(IRQ_TIMER); + ack(IRQ_TIMER); } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index d1a49fe..daf50df 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -85,7 +85,7 @@ pub extern "C" fn rust_main(multiboot_information_address: usize) { } else { arch::driver::pic::init(); } - unsafe{ x86_64::instructions::interrupts::enable(); } + arch::driver::interrupt::enable(); loop{} test_end!(); }