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