handle.rs 1.4 KB

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