xref: /DragonOS/kernel/src/exception/ipi.rs (revision f0c87a897fe813b7f06bf5a9e93c43ad9519dafd)
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