1e2841179SLoGin use core::intrinsics::likely; 2e2841179SLoGin 3e2841179SLoGin use crate::{ 4e2841179SLoGin arch::{ 5e2841179SLoGin driver::apic::{apic_timer::APIC_TIMER_IRQ_NUM, CurrentApic, LocalAPIC}, 6e2841179SLoGin sched::sched, 7e2841179SLoGin }, 8e2841179SLoGin exception::{irqdesc::irq_desc_manager, softirq::do_softirq, IrqNumber}, 9e2841179SLoGin process::{ 10*b5b571e0SLoGin utils::{current_pcb_flags, current_pcb_preempt_count}, 11e2841179SLoGin ProcessFlags, 12e2841179SLoGin }, 13e2841179SLoGin }; 14e2841179SLoGin 15e2841179SLoGin use super::TrapFrame; 16e2841179SLoGin 17e2841179SLoGin #[no_mangle] 18e2841179SLoGin unsafe extern "C" fn x86_64_do_irq(trap_frame: &mut TrapFrame, vector: u32) { 19e2841179SLoGin // swapgs 20e2841179SLoGin 21*b5b571e0SLoGin if trap_frame.is_from_user() { 22e2841179SLoGin x86_64::registers::segmentation::GS::swap(); 23e2841179SLoGin } 24e2841179SLoGin 25e2841179SLoGin // 由于x86上面,虚拟中断号与物理中断号是一一对应的,所以这里直接使用vector作为中断号来查询irqdesc 26e2841179SLoGin 27e2841179SLoGin let desc = irq_desc_manager().lookup(IrqNumber::new(vector)); 28e2841179SLoGin 29e2841179SLoGin if likely(desc.is_some()) { 30e2841179SLoGin let desc = desc.unwrap(); 31e2841179SLoGin let handler = desc.handler(); 32e2841179SLoGin if likely(handler.is_some()) { 33e2841179SLoGin handler.unwrap().handle(&desc, trap_frame); 34e2841179SLoGin } else { 35e2841179SLoGin CurrentApic.send_eoi(); 36e2841179SLoGin } 37e2841179SLoGin } else { 38e2841179SLoGin CurrentApic.send_eoi(); 39e2841179SLoGin } 40e2841179SLoGin 41e2841179SLoGin do_softirq(); 42e2841179SLoGin 43e2841179SLoGin if current_pcb_preempt_count() > 0 { 44e2841179SLoGin return; 45e2841179SLoGin } 46e2841179SLoGin // 检测当前进程是否可被调度 47e2841179SLoGin if (current_pcb_flags().contains(ProcessFlags::NEED_SCHEDULE)) 48e2841179SLoGin && vector == APIC_TIMER_IRQ_NUM.data() 49e2841179SLoGin { 50e2841179SLoGin sched(); 51e2841179SLoGin } 52e2841179SLoGin } 53