handle.rs 1.4 KB

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