1 use alloc::sync::Arc; 2 use system_error::SystemError; 3 4 #[cfg(target_arch = "x86_64")] 5 use crate::arch::driver::apic::{CurrentApic, LocalAPIC}; 6 7 use crate::{ 8 arch::MMArch, 9 mm::MemoryManagementArch, 10 sched::{SchedMode, __schedule}, 11 smp::cpu::ProcessorId, 12 }; 13 14 use super::{ 15 irqdata::IrqHandlerData, 16 irqdesc::{IrqHandler, IrqReturn}, 17 HardwareIrqNumber, IrqNumber, 18 }; 19 20 #[allow(dead_code)] 21 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 22 pub enum IpiKind { 23 KickCpu, 24 FlushTLB, 25 /// 指定中断向量号 26 SpecVector(HardwareIrqNumber), 27 } 28 29 /// IPI投递目标 30 #[derive(Debug, Copy, Clone, Eq, PartialEq)] 31 #[allow(dead_code)] 32 pub enum IpiTarget { 33 /// 当前CPU 34 Current, 35 /// 所有CPU 36 All, 37 /// 除了当前CPU以外的所有CPU 38 Other, 39 /// 指定的CPU 40 Specified(ProcessorId), 41 } 42 43 /// 处理跨核心CPU唤醒的IPI 44 #[derive(Debug)] 45 pub struct KickCpuIpiHandler; 46 47 impl IrqHandler for KickCpuIpiHandler { 48 fn handle( 49 &self, 50 _irq: IrqNumber, 51 _static_data: Option<&dyn IrqHandlerData>, 52 _dynamic_data: Option<Arc<dyn IrqHandlerData>>, 53 ) -> Result<IrqReturn, SystemError> { 54 #[cfg(target_arch = "x86_64")] 55 CurrentApic.send_eoi(); 56 57 // 被其他cpu kick时应该是抢占调度 58 __schedule(SchedMode::SM_PREEMPT); 59 Ok(IrqReturn::Handled) 60 } 61 } 62 63 /// 处理TLB刷新的IPI 64 #[derive(Debug)] 65 pub struct FlushTLBIpiHandler; 66 67 impl IrqHandler for FlushTLBIpiHandler { 68 fn handle( 69 &self, 70 _irq: IrqNumber, 71 _static_data: Option<&dyn IrqHandlerData>, 72 _dynamic_data: Option<Arc<dyn IrqHandlerData>>, 73 ) -> Result<IrqReturn, SystemError> { 74 unsafe { MMArch::invalidate_all() }; 75 76 Ok(IrqReturn::Handled) 77 } 78 } 79