|
1 | 1 | #[allow(unused)] |
2 | 2 | use crate::interrupts::apic; |
| 3 | +use crate::interrupts::apic::registry::{IrqContext, IRQ_REGISTRY}; |
| 4 | +use crate::interrupts::idt::IRQ_BASE; |
3 | 5 | use crate::panic::{ExceptionInfo, EXCEPTION_INFO}; |
4 | 6 | use crate::serial_println; |
5 | 7 | use x86_64::{ |
@@ -150,42 +152,70 @@ pub extern "x86-interrupt" fn machine_check_handler(stack_frame: InterruptStackF |
150 | 152 | panic!("CRITICAL: MACHINE CHECK"); |
151 | 153 | } |
152 | 154 |
|
153 | | -pub extern "x86-interrupt" fn timer_interrupt_handler(_stack_frame: InterruptStackFrame) { |
154 | | - // APIC Timer interrupt |
155 | | - // For now just EOI |
| 155 | +pub extern "x86-interrupt" fn timer_interrupt_handler(stack_frame: InterruptStackFrame) { |
| 156 | + let context = IrqContext { |
| 157 | + vector: crate::interrupts::apic::TIMER_VECTOR, |
| 158 | + irq_number: None, // APIC timer is not a standard ISA IRQ |
| 159 | + stack_frame: &stack_frame, |
| 160 | + error_code: None, |
| 161 | + }; |
| 162 | + |
| 163 | + if let Some(mut registry) = IRQ_REGISTRY.try_lock() { |
| 164 | + registry.handle(context); |
| 165 | + } |
| 166 | + |
156 | 167 | apic::end_of_interrupt(); |
157 | 168 | } |
158 | 169 |
|
159 | | -macro_rules! pic_interrupt_handler { |
| 170 | +macro_rules! ioapic_interrupt_handler { |
160 | 171 | ($name:ident, $irq_number:expr) => { |
161 | 172 | #[allow(unused_variables)] |
162 | 173 | pub extern "x86-interrupt" fn $name(stack_frame: InterruptStackFrame) { |
163 | | - if $irq_number == 1 { |
164 | | - let mut port = x86_64::instructions::port::Port::<u8>::new(0x60); |
165 | | - let scancode = unsafe { port.read() }; |
166 | | - crate::drivers::input::keyboard::KEYBOARD.handle_scancode(scancode); |
167 | | - } else { |
168 | | - serial_println!("IRQ {} received!", $irq_number); |
| 174 | + let vector = IRQ_BASE + $irq_number; |
| 175 | + let context = IrqContext { |
| 176 | + vector, |
| 177 | + irq_number: Some($irq_number), |
| 178 | + stack_frame: &stack_frame, |
| 179 | + error_code: None, |
| 180 | + }; |
| 181 | + |
| 182 | + let mut handled = false; |
| 183 | + if let Some(mut registry) = IRQ_REGISTRY.try_lock() { |
| 184 | + if let crate::interrupts::apic::registry::IrqResult::Handled = |
| 185 | + registry.handle(context) |
| 186 | + { |
| 187 | + handled = true; |
| 188 | + } |
| 189 | + } |
| 190 | + |
| 191 | + if !handled { |
| 192 | + if $irq_number == 1 { |
| 193 | + let mut port = x86_64::instructions::port::Port::<u8>::new(0x60); |
| 194 | + let scancode = unsafe { port.read() }; |
| 195 | + crate::drivers::input::keyboard::KEYBOARD.handle_scancode(scancode); |
| 196 | + } else { |
| 197 | + serial_println!("IRQ {} received!", $irq_number); |
| 198 | + } |
169 | 199 | } |
170 | 200 |
|
171 | 201 | apic::end_of_interrupt(); |
172 | 202 | } |
173 | 203 | }; |
174 | 204 | } |
175 | 205 | // 为所有 16 个 IRQ 定义处理函数 |
176 | | -pic_interrupt_handler!(pic_interrupt_handler_0, 0); // Timer Interrupt |
177 | | -pic_interrupt_handler!(pic_interrupt_handler_1, 1); // Keyboard Interrupt |
178 | | -pic_interrupt_handler!(pic_interrupt_handler_2, 2); // Cascade to PIC2 |
179 | | -pic_interrupt_handler!(pic_interrupt_handler_3, 3); // Serial COM2 |
180 | | -pic_interrupt_handler!(pic_interrupt_handler_4, 4); // Serial COM1 |
181 | | -pic_interrupt_handler!(pic_interrupt_handler_5, 5); // Parallel Port LPT2 / Sound Card |
182 | | -pic_interrupt_handler!(pic_interrupt_handler_6, 6); // Floppy Disk Controller |
183 | | -pic_interrupt_handler!(pic_interrupt_handler_7, 7); // Parallel Port LPT1 / Fake Interrupt |
184 | | -pic_interrupt_handler!(pic_interrupt_handler_8, 8); // RTC Real Time Clock |
185 | | -pic_interrupt_handler!(pic_interrupt_handler_9, 9); // Redirect IRQ2 |
186 | | -pic_interrupt_handler!(pic_interrupt_handler_10, 10); // Freed / SCSI / Netcard |
187 | | -pic_interrupt_handler!(pic_interrupt_handler_11, 11); // Freed / SCSI / Netcard |
188 | | -pic_interrupt_handler!(pic_interrupt_handler_12, 12); // PS/2 mouse |
189 | | -pic_interrupt_handler!(pic_interrupt_handler_13, 13); // FPU / MPU |
190 | | -pic_interrupt_handler!(pic_interrupt_handler_14, 14); // Primary IDE |
191 | | -pic_interrupt_handler!(pic_interrupt_handler_15, 15); // Secondary IDE |
| 206 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_0, 0); // Timer Interrupt |
| 207 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_1, 1); // Keyboard Interrupt |
| 208 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_2, 2); // Cascade to PIC2 |
| 209 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_3, 3); // Serial COM2 |
| 210 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_4, 4); // Serial COM1 |
| 211 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_5, 5); // Parallel Port LPT2 / Sound Card |
| 212 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_6, 6); // Floppy Disk Controller |
| 213 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_7, 7); // Parallel Port LPT1 / Fake Interrupt |
| 214 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_8, 8); // RTC Real Time Clock |
| 215 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_9, 9); // Redirect IRQ2 |
| 216 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_10, 10); // Freed / SCSI / Netcard |
| 217 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_11, 11); // Freed / SCSI / Netcard |
| 218 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_12, 12); // PS/2 mouse |
| 219 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_13, 13); // FPU / MPU |
| 220 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_14, 14); // Primary IDE |
| 221 | +ioapic_interrupt_handler!(ioapic_interrupt_handler_15, 15); // Secondary IDE |
0 commit comments