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