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