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