xref: /DragonOS/kernel/src/arch/x86_64/driver/apic/mod.rs (revision 70a4e5550a9fb49b537092287c3ddc36448c5b78)
1*70a4e555SLoGin use core::sync::atomic::Ordering;
2*70a4e555SLoGin 
3*70a4e555SLoGin use atomic_enum::atomic_enum;
4*70a4e555SLoGin use x86::{apic::Icr, msr::IA32_APIC_BASE};
5*70a4e555SLoGin 
6*70a4e555SLoGin use crate::{
7*70a4e555SLoGin     arch::{
8*70a4e555SLoGin         driver::apic::{ioapic::ioapic_init, x2apic::X2Apic, xapic::XApic},
9*70a4e555SLoGin         io::PortIOArch,
10*70a4e555SLoGin         CurrentPortIOArch,
11*70a4e555SLoGin     },
12*70a4e555SLoGin     kdebug, kinfo,
13*70a4e555SLoGin     mm::PhysAddr,
14*70a4e555SLoGin     smp::core::smp_get_processor_id,
15*70a4e555SLoGin     syscall::SystemError,
16*70a4e555SLoGin };
17*70a4e555SLoGin 
18*70a4e555SLoGin use self::{
19*70a4e555SLoGin     apic_timer::LocalApicTimerMode,
20*70a4e555SLoGin     xapic::{current_xapic_instance, XApicOffset},
21*70a4e555SLoGin };
22*70a4e555SLoGin 
23*70a4e555SLoGin pub mod apic_timer;
24*70a4e555SLoGin mod c_adapter;
25*70a4e555SLoGin pub mod ioapic;
26*70a4e555SLoGin pub mod x2apic;
27*70a4e555SLoGin pub mod xapic;
28*70a4e555SLoGin 
29*70a4e555SLoGin /// 当前启用的APIC类型
30*70a4e555SLoGin #[atomic_enum]
31*70a4e555SLoGin #[derive(PartialEq, Eq)]
32*70a4e555SLoGin pub enum LocalApicEnableType {
33*70a4e555SLoGin     XApic,
34*70a4e555SLoGin     X2Apic,
35*70a4e555SLoGin }
36*70a4e555SLoGin 
37*70a4e555SLoGin static LOCAL_APIC_ENABLE_TYPE: AtomicLocalApicEnableType =
38*70a4e555SLoGin     AtomicLocalApicEnableType::new(LocalApicEnableType::XApic);
39*70a4e555SLoGin 
40*70a4e555SLoGin pub trait LocalAPIC {
41*70a4e555SLoGin     /// @brief 判断当前处理器是否支持这个类型的apic
42*70a4e555SLoGin     ///
43*70a4e555SLoGin     /// @return true 当前处理器支持这个类型的apic
44*70a4e555SLoGin     /// @return false 当前处理器不支持这个类型的apic
45*70a4e555SLoGin     fn support() -> bool;
46*70a4e555SLoGin 
47*70a4e555SLoGin     /// @brief 为当前处理器初始化local apic
48*70a4e555SLoGin     ///
49*70a4e555SLoGin     /// @return true 初始化成功
50*70a4e555SLoGin     /// @return false 初始化失败
51*70a4e555SLoGin     fn init_current_cpu(&mut self) -> bool;
52*70a4e555SLoGin 
53*70a4e555SLoGin     /// @brief 发送EOI信号(End of interrupt)
54*70a4e555SLoGin     fn send_eoi(&self);
55*70a4e555SLoGin 
56*70a4e555SLoGin     /// @brief 获取APIC版本号
57*70a4e555SLoGin     fn version(&self) -> u8;
58*70a4e555SLoGin 
59*70a4e555SLoGin     /// @brief 判断当前处理器是否支持EOI广播抑制
60*70a4e555SLoGin     fn support_eoi_broadcast_suppression(&self) -> bool;
61*70a4e555SLoGin 
62*70a4e555SLoGin     /// 获取最多支持的LVT寄存器数量
63*70a4e555SLoGin     fn max_lvt_entry(&self) -> u8;
64*70a4e555SLoGin 
65*70a4e555SLoGin     /// @brief 获取当前处理器的APIC ID
66*70a4e555SLoGin     fn id(&self) -> u32;
67*70a4e555SLoGin 
68*70a4e555SLoGin     /// @brief 设置LVT寄存器
69*70a4e555SLoGin     ///
70*70a4e555SLoGin     /// @param register 寄存器
71*70a4e555SLoGin     /// @param lvt 要被设置成的值
72*70a4e555SLoGin     fn set_lvt(&mut self, lvt: LVT);
73*70a4e555SLoGin 
74*70a4e555SLoGin     /// 读取LVT寄存器
75*70a4e555SLoGin     fn read_lvt(&self, reg: LVTRegister) -> LVT;
76*70a4e555SLoGin 
77*70a4e555SLoGin     fn mask_all_lvt(&mut self);
78*70a4e555SLoGin 
79*70a4e555SLoGin     /// 写入ICR寄存器
80*70a4e555SLoGin     fn write_icr(&self, icr: Icr);
81*70a4e555SLoGin }
82*70a4e555SLoGin 
83*70a4e555SLoGin /// @brief 所有LVT寄存器的枚举类型
84*70a4e555SLoGin #[allow(dead_code)]
85*70a4e555SLoGin #[repr(u32)]
86*70a4e555SLoGin #[derive(Debug, Clone, Copy)]
87*70a4e555SLoGin pub enum LVTRegister {
88*70a4e555SLoGin     /// CMCI寄存器
89*70a4e555SLoGin     ///
90*70a4e555SLoGin     /// 如果支持CMCI功能,那么,当修正的机器错误超过阈值时,Local APIC通过CMCI寄存器的配置,
91*70a4e555SLoGin     /// 向处理器核心投递中断消息
92*70a4e555SLoGin     CMCI = 0x82f,
93*70a4e555SLoGin     /// 定时器寄存器
94*70a4e555SLoGin     ///
95*70a4e555SLoGin     /// 当APIC定时器产生中断信号时,Local APIC通过定时器寄存器的设置,向处理器投递中断消息
96*70a4e555SLoGin     Timer = 0x832,
97*70a4e555SLoGin     /// 温度传感器寄存器
98*70a4e555SLoGin     ///
99*70a4e555SLoGin     /// 当处理器内部的温度传感器产生中断请求信号时,Local APIC会通过温度传感器寄存器的设置,
100*70a4e555SLoGin     /// 向处理器投递中断消息。
101*70a4e555SLoGin     Thermal = 0x833,
102*70a4e555SLoGin     /// 性能监控计数器寄存器
103*70a4e555SLoGin     ///
104*70a4e555SLoGin     /// 当性能检测计数器寄存器溢出,产生中断请求时,Local APIC将会根据这个寄存器的配置,
105*70a4e555SLoGin     /// 向处理器投递中断消息
106*70a4e555SLoGin     PerformanceMonitor = 0x834,
107*70a4e555SLoGin     /// 当处理器的LINT0引脚接收到中断请求信号时,Local APIC会根据这个寄存器的配置,
108*70a4e555SLoGin     /// 向处理器投递中断消息
109*70a4e555SLoGin     LINT0 = 0x835,
110*70a4e555SLoGin     /// 当处理器的LINT0引脚接收到中断请求信号时,Local APIC会根据这个寄存器的配置,
111*70a4e555SLoGin     /// 向处理器投递中断消息
112*70a4e555SLoGin     LINT1 = 0x836,
113*70a4e555SLoGin     /// 错误寄存器
114*70a4e555SLoGin     ///
115*70a4e555SLoGin     /// 当APIC检测到内部错误而产生中断请求信号时,它将会通过错误寄存器的设置,向处理器投递中断消息
116*70a4e555SLoGin     ErrorReg = 0x837,
117*70a4e555SLoGin }
118*70a4e555SLoGin 
119*70a4e555SLoGin impl Into<u32> for LVTRegister {
120*70a4e555SLoGin     fn into(self) -> u32 {
121*70a4e555SLoGin         self as u32
122*70a4e555SLoGin     }
123*70a4e555SLoGin }
124*70a4e555SLoGin 
125*70a4e555SLoGin #[derive(Debug)]
126*70a4e555SLoGin pub struct LVT {
127*70a4e555SLoGin     register: LVTRegister,
128*70a4e555SLoGin     data: u32,
129*70a4e555SLoGin }
130*70a4e555SLoGin 
131*70a4e555SLoGin impl LVT {
132*70a4e555SLoGin     /// 当第16位为1时,表示屏蔽中断
133*70a4e555SLoGin     pub const MASKED: u32 = 1 << 16;
134*70a4e555SLoGin 
135*70a4e555SLoGin     pub fn new(register: LVTRegister, data: u32) -> Option<Self> {
136*70a4e555SLoGin         // vector: u8, mode: DeliveryMode, status: DeliveryStatus
137*70a4e555SLoGin         let mut result = Self { register, data: 0 };
138*70a4e555SLoGin         result.set_vector((data & 0xFF) as u8);
139*70a4e555SLoGin         match result.register {
140*70a4e555SLoGin             LVTRegister::Timer | LVTRegister::ErrorReg => {}
141*70a4e555SLoGin             _ => {
142*70a4e555SLoGin                 result
143*70a4e555SLoGin                     .set_delivery_mode(DeliveryMode::try_from(((data >> 8) & 0b111) as u8).ok()?)
144*70a4e555SLoGin                     .ok()?;
145*70a4e555SLoGin             }
146*70a4e555SLoGin         }
147*70a4e555SLoGin 
148*70a4e555SLoGin         if let LVTRegister::LINT0 | LVTRegister::LINT1 = result.register {
149*70a4e555SLoGin             result.set_interrupt_input_pin_polarity((data & (1 << 13)) == 0);
150*70a4e555SLoGin 
151*70a4e555SLoGin             if data & (1 << 15) != 0 {
152*70a4e555SLoGin                 result.set_trigger_mode(TriggerMode::Level).ok()?;
153*70a4e555SLoGin             } else {
154*70a4e555SLoGin                 result.set_trigger_mode(TriggerMode::Edge).ok()?;
155*70a4e555SLoGin             }
156*70a4e555SLoGin         }
157*70a4e555SLoGin         result.set_mask((data & (1 << 16)) != 0);
158*70a4e555SLoGin 
159*70a4e555SLoGin         if let LVTRegister::Timer = result.register {
160*70a4e555SLoGin             result
161*70a4e555SLoGin                 .set_timer_mode(LocalApicTimerMode::try_from(((data >> 17) & 0b11) as u8).ok()?)
162*70a4e555SLoGin                 .ok()?;
163*70a4e555SLoGin         }
164*70a4e555SLoGin 
165*70a4e555SLoGin         return Some(result);
166*70a4e555SLoGin     }
167*70a4e555SLoGin 
168*70a4e555SLoGin     /// 获取LVT寄存器的原始值
169*70a4e555SLoGin     #[allow(dead_code)]
170*70a4e555SLoGin     pub fn data(&self) -> u32 {
171*70a4e555SLoGin         return self.data;
172*70a4e555SLoGin     }
173*70a4e555SLoGin 
174*70a4e555SLoGin     pub fn register(&self) -> LVTRegister {
175*70a4e555SLoGin         return self.register;
176*70a4e555SLoGin     }
177*70a4e555SLoGin 
178*70a4e555SLoGin     pub fn set_vector(&mut self, vector: u8) {
179*70a4e555SLoGin         self.data &= !((1 << 8) - 1);
180*70a4e555SLoGin         self.data |= vector as u32;
181*70a4e555SLoGin     }
182*70a4e555SLoGin 
183*70a4e555SLoGin     /// 获取中断向量号
184*70a4e555SLoGin     #[allow(dead_code)]
185*70a4e555SLoGin     pub fn vector(&self) -> u8 {
186*70a4e555SLoGin         return (self.data & 0xFF) as u8;
187*70a4e555SLoGin     }
188*70a4e555SLoGin 
189*70a4e555SLoGin     /// 设置中断投递模式
190*70a4e555SLoGin     ///
191*70a4e555SLoGin     /// Timer、ErrorReg寄存器不支持这个功能
192*70a4e555SLoGin     ///
193*70a4e555SLoGin     /// ## 参数
194*70a4e555SLoGin     ///
195*70a4e555SLoGin     /// - `mode`:投递模式
196*70a4e555SLoGin     pub fn set_delivery_mode(&mut self, mode: DeliveryMode) -> Result<(), SystemError> {
197*70a4e555SLoGin         match self.register {
198*70a4e555SLoGin             LVTRegister::Timer | LVTRegister::ErrorReg => {
199*70a4e555SLoGin                 return Err(SystemError::EINVAL);
200*70a4e555SLoGin             }
201*70a4e555SLoGin             _ => {}
202*70a4e555SLoGin         }
203*70a4e555SLoGin 
204*70a4e555SLoGin         self.data &= 0xFFFF_F8FF;
205*70a4e555SLoGin         self.data |= ((mode as u32) & 0x7) << 8;
206*70a4e555SLoGin         return Ok(());
207*70a4e555SLoGin     }
208*70a4e555SLoGin 
209*70a4e555SLoGin     /// 获取中断投递模式
210*70a4e555SLoGin     /// Timer、ErrorReg寄存器不支持这个功能
211*70a4e555SLoGin     #[allow(dead_code)]
212*70a4e555SLoGin     pub fn delivery_mode(&self) -> Option<DeliveryMode> {
213*70a4e555SLoGin         if let LVTRegister::Timer | LVTRegister::ErrorReg = self.register {
214*70a4e555SLoGin             return None;
215*70a4e555SLoGin         }
216*70a4e555SLoGin         return DeliveryMode::try_from(((self.data >> 8) & 0b111) as u8).ok();
217*70a4e555SLoGin     }
218*70a4e555SLoGin 
219*70a4e555SLoGin     /// Get the delivery status of the interrupt
220*70a4e555SLoGin     #[allow(dead_code)]
221*70a4e555SLoGin     pub fn delivery_status(&self) -> DeliveryStatus {
222*70a4e555SLoGin         return DeliveryStatus::from(self.data);
223*70a4e555SLoGin     }
224*70a4e555SLoGin 
225*70a4e555SLoGin     /// 设置中断输入引脚的极性
226*70a4e555SLoGin     ///
227*70a4e555SLoGin     /// ## 参数
228*70a4e555SLoGin     ///
229*70a4e555SLoGin     /// - `high`:true表示高电平有效,false表示低电平有效
230*70a4e555SLoGin     pub fn set_interrupt_input_pin_polarity(&mut self, high: bool) {
231*70a4e555SLoGin         self.data &= 0xFFFF_DFFF;
232*70a4e555SLoGin         // 0表示高电平有效,1表示低电平有效
233*70a4e555SLoGin         if !high {
234*70a4e555SLoGin             self.data |= 1 << 13;
235*70a4e555SLoGin         }
236*70a4e555SLoGin     }
237*70a4e555SLoGin 
238*70a4e555SLoGin     /// 获取中断输入引脚的极性
239*70a4e555SLoGin     ///
240*70a4e555SLoGin     /// true表示高电平有效,false表示低电平有效
241*70a4e555SLoGin     #[allow(dead_code)]
242*70a4e555SLoGin     pub fn interrupt_input_pin_polarity(&self) -> bool {
243*70a4e555SLoGin         return (self.data & (1 << 13)) == 0;
244*70a4e555SLoGin     }
245*70a4e555SLoGin 
246*70a4e555SLoGin     /// 设置中断输入引脚的触发模式
247*70a4e555SLoGin     ///
248*70a4e555SLoGin     /// 只有LINT0和LINT1寄存器支持这个功能
249*70a4e555SLoGin     ///
250*70a4e555SLoGin     /// ## 参数
251*70a4e555SLoGin     ///
252*70a4e555SLoGin     /// - `trigger_mode`:触发模式
253*70a4e555SLoGin     pub fn set_trigger_mode(&mut self, trigger_mode: TriggerMode) -> Result<(), SystemError> {
254*70a4e555SLoGin         match self.register {
255*70a4e555SLoGin             LVTRegister::LINT0 | LVTRegister::LINT1 => {
256*70a4e555SLoGin                 self.data &= 0xFFFF_7FFF;
257*70a4e555SLoGin                 if trigger_mode == TriggerMode::Level {
258*70a4e555SLoGin                     self.data |= 1 << 15;
259*70a4e555SLoGin                 }
260*70a4e555SLoGin                 return Ok(());
261*70a4e555SLoGin             }
262*70a4e555SLoGin             _ => {
263*70a4e555SLoGin                 return Err(SystemError::EINVAL);
264*70a4e555SLoGin             }
265*70a4e555SLoGin         }
266*70a4e555SLoGin     }
267*70a4e555SLoGin 
268*70a4e555SLoGin     /// 获取中断输入引脚的触发模式
269*70a4e555SLoGin     ///
270*70a4e555SLoGin     /// 只有LINT0和LINT1寄存器支持这个功能
271*70a4e555SLoGin     #[allow(dead_code)]
272*70a4e555SLoGin     pub fn trigger_mode(&self) -> Option<TriggerMode> {
273*70a4e555SLoGin         match self.register {
274*70a4e555SLoGin             LVTRegister::LINT0 | LVTRegister::LINT1 => {
275*70a4e555SLoGin                 if self.data & (1 << 15) != 0 {
276*70a4e555SLoGin                     return Some(TriggerMode::Level);
277*70a4e555SLoGin                 } else {
278*70a4e555SLoGin                     return Some(TriggerMode::Edge);
279*70a4e555SLoGin                 }
280*70a4e555SLoGin             }
281*70a4e555SLoGin             _ => {
282*70a4e555SLoGin                 return None;
283*70a4e555SLoGin             }
284*70a4e555SLoGin         }
285*70a4e555SLoGin     }
286*70a4e555SLoGin 
287*70a4e555SLoGin     /// 设置是否屏蔽中断
288*70a4e555SLoGin     ///
289*70a4e555SLoGin     /// ## 参数
290*70a4e555SLoGin     ///
291*70a4e555SLoGin     /// - `mask`:true表示屏蔽中断,false表示不屏蔽中断
292*70a4e555SLoGin     pub fn set_mask(&mut self, mask: bool) {
293*70a4e555SLoGin         self.data &= 0xFFFE_FFFF;
294*70a4e555SLoGin         if mask {
295*70a4e555SLoGin             self.data |= 1 << 16;
296*70a4e555SLoGin         }
297*70a4e555SLoGin     }
298*70a4e555SLoGin 
299*70a4e555SLoGin     /// Check if the interrupt is masked
300*70a4e555SLoGin     ///
301*70a4e555SLoGin     /// true表示屏蔽中断,false表示不屏蔽中断
302*70a4e555SLoGin     #[allow(dead_code)]
303*70a4e555SLoGin     pub fn mask(&self) -> bool {
304*70a4e555SLoGin         return (self.data & (1 << 16)) != 0;
305*70a4e555SLoGin     }
306*70a4e555SLoGin 
307*70a4e555SLoGin     /// 设置定时器模式
308*70a4e555SLoGin     pub fn set_timer_mode(&mut self, mode: LocalApicTimerMode) -> Result<(), SystemError> {
309*70a4e555SLoGin         match self.register {
310*70a4e555SLoGin             LVTRegister::Timer => {
311*70a4e555SLoGin                 self.data &= 0xFFF9_FFFF;
312*70a4e555SLoGin                 match mode {
313*70a4e555SLoGin                     LocalApicTimerMode::Oneshot => {
314*70a4e555SLoGin                         self.data |= 0b00 << 17;
315*70a4e555SLoGin                     }
316*70a4e555SLoGin                     LocalApicTimerMode::Periodic => {
317*70a4e555SLoGin                         self.data |= 0b01 << 17;
318*70a4e555SLoGin                     }
319*70a4e555SLoGin                     LocalApicTimerMode::Deadline => {
320*70a4e555SLoGin                         self.data |= 0b10 << 17;
321*70a4e555SLoGin                     }
322*70a4e555SLoGin                 }
323*70a4e555SLoGin                 return Ok(());
324*70a4e555SLoGin             }
325*70a4e555SLoGin             _ => {
326*70a4e555SLoGin                 return Err(SystemError::EINVAL);
327*70a4e555SLoGin             }
328*70a4e555SLoGin         }
329*70a4e555SLoGin     }
330*70a4e555SLoGin 
331*70a4e555SLoGin     /// 获取定时器模式
332*70a4e555SLoGin     #[allow(dead_code)]
333*70a4e555SLoGin     pub fn timer_mode(&self) -> Option<LocalApicTimerMode> {
334*70a4e555SLoGin         if let LVTRegister::Timer = self.register {
335*70a4e555SLoGin             let mode = (self.data >> 17) & 0b11;
336*70a4e555SLoGin             match mode {
337*70a4e555SLoGin                 0b00 => {
338*70a4e555SLoGin                     return Some(LocalApicTimerMode::Oneshot);
339*70a4e555SLoGin                 }
340*70a4e555SLoGin                 0b01 => {
341*70a4e555SLoGin                     return Some(LocalApicTimerMode::Periodic);
342*70a4e555SLoGin                 }
343*70a4e555SLoGin                 0b10 => {
344*70a4e555SLoGin                     return Some(LocalApicTimerMode::Deadline);
345*70a4e555SLoGin                 }
346*70a4e555SLoGin                 _ => {
347*70a4e555SLoGin                     return None;
348*70a4e555SLoGin                 }
349*70a4e555SLoGin             }
350*70a4e555SLoGin         }
351*70a4e555SLoGin         return None;
352*70a4e555SLoGin     }
353*70a4e555SLoGin }
354*70a4e555SLoGin 
355*70a4e555SLoGin /// @brief
356*70a4e555SLoGin #[allow(dead_code)]
357*70a4e555SLoGin #[derive(Debug, PartialEq)]
358*70a4e555SLoGin pub enum DeliveryMode {
359*70a4e555SLoGin     /// 由LVT寄存器的向量号区域指定中断向量号
360*70a4e555SLoGin     Fixed = 0b000,
361*70a4e555SLoGin     /// 通过处理器的SMI信号线,向处理器投递SMI中断请求。
362*70a4e555SLoGin     /// 由于兼容性的原因,使用此投递模式时,LVT的中断向量号区域必须设置为0。
363*70a4e555SLoGin     SMI = 0b010,
364*70a4e555SLoGin     /// 向处理器投递不可屏蔽中断,并忽略向量号区域
365*70a4e555SLoGin     NMI = 0b100,
366*70a4e555SLoGin     /// 向处理器投递INIT中断请求,处理器会执行初始化的过程。
367*70a4e555SLoGin     /// 由于兼容性的原因,使用此投递模式时,LVT的中断向量号区域必须设置为0。
368*70a4e555SLoGin     /// CMCI、温度传感器、性能监控计数器等寄存器均不支持INIT投递模式
369*70a4e555SLoGin     INIT = 0b101,
370*70a4e555SLoGin 
371*70a4e555SLoGin     /// 向目标处理器投递Start-Up IPI。
372*70a4e555SLoGin     ///
373*70a4e555SLoGin     /// 这个向量通常由多核引导模块调用(请参阅Intel开发手册Volume3 Section 8.4,
374*70a4e555SLoGin     /// Multiple-Processor (MP) Initialization)。
375*70a4e555SLoGin     /// 如果源APIC无法投递这个IPI,它不会自动重发。如果Start-Up IPI未成功投递,
376*70a4e555SLoGin     /// 则交由软件决定是否在必要时重新投递SIPI
377*70a4e555SLoGin     StartUp = 0b110,
378*70a4e555SLoGin 
379*70a4e555SLoGin     /// ExtINT模式可以将类8259A中断控制器产生的中断请求投递到处理器,并接收类
380*70a4e555SLoGin     /// 8259A中断控制器提供的中断向量号。
381*70a4e555SLoGin     /// CMCI、温度传感器、性能监控计数器等寄存器均不支持ExtINT投递模式
382*70a4e555SLoGin     ExtINT = 0b111,
383*70a4e555SLoGin }
384*70a4e555SLoGin 
385*70a4e555SLoGin impl TryFrom<u8> for DeliveryMode {
386*70a4e555SLoGin     type Error = SystemError;
387*70a4e555SLoGin 
388*70a4e555SLoGin     fn try_from(value: u8) -> Result<Self, Self::Error> {
389*70a4e555SLoGin         match value {
390*70a4e555SLoGin             0b000 => {
391*70a4e555SLoGin                 return Ok(DeliveryMode::Fixed);
392*70a4e555SLoGin             }
393*70a4e555SLoGin             0b010 => {
394*70a4e555SLoGin                 return Ok(DeliveryMode::SMI);
395*70a4e555SLoGin             }
396*70a4e555SLoGin             0b100 => {
397*70a4e555SLoGin                 return Ok(DeliveryMode::NMI);
398*70a4e555SLoGin             }
399*70a4e555SLoGin             0b101 => {
400*70a4e555SLoGin                 return Ok(DeliveryMode::INIT);
401*70a4e555SLoGin             }
402*70a4e555SLoGin             0b110 => {
403*70a4e555SLoGin                 return Ok(DeliveryMode::StartUp);
404*70a4e555SLoGin             }
405*70a4e555SLoGin             0b111 => {
406*70a4e555SLoGin                 return Ok(DeliveryMode::ExtINT);
407*70a4e555SLoGin             }
408*70a4e555SLoGin             _ => {
409*70a4e555SLoGin                 return Err(SystemError::EINVAL);
410*70a4e555SLoGin             }
411*70a4e555SLoGin         }
412*70a4e555SLoGin     }
413*70a4e555SLoGin }
414*70a4e555SLoGin 
415*70a4e555SLoGin /// @brief 投递状态
416*70a4e555SLoGin #[derive(Debug)]
417*70a4e555SLoGin #[allow(dead_code)]
418*70a4e555SLoGin pub enum DeliveryStatus {
419*70a4e555SLoGin     /// 空闲态。
420*70a4e555SLoGin     /// 此状态表明,当前中断源未产生中断,或者产生的中断已经投递到处理器,并被处理器处理。
421*70a4e555SLoGin     Idle = 0,
422*70a4e555SLoGin     /// 发送挂起状态。
423*70a4e555SLoGin     /// 此状态表明,中断源产生的请求已经投递至处理器,但尚未被处理器处理。
424*70a4e555SLoGin     SendPending = 1,
425*70a4e555SLoGin }
426*70a4e555SLoGin 
427*70a4e555SLoGin impl DeliveryStatus {
428*70a4e555SLoGin     pub fn from(data: u32) -> Self {
429*70a4e555SLoGin         if data & (1 << 12) == 0 {
430*70a4e555SLoGin             return DeliveryStatus::Idle;
431*70a4e555SLoGin         } else {
432*70a4e555SLoGin             return DeliveryStatus::SendPending;
433*70a4e555SLoGin         }
434*70a4e555SLoGin     }
435*70a4e555SLoGin }
436*70a4e555SLoGin 
437*70a4e555SLoGin /// IPI Trigger Mode
438*70a4e555SLoGin #[derive(Debug, Eq, PartialEq)]
439*70a4e555SLoGin #[repr(u64)]
440*70a4e555SLoGin pub enum TriggerMode {
441*70a4e555SLoGin     Edge = 0,
442*70a4e555SLoGin     Level = 1,
443*70a4e555SLoGin }
444*70a4e555SLoGin 
445*70a4e555SLoGin #[derive(Debug)]
446*70a4e555SLoGin pub struct CurrentApic;
447*70a4e555SLoGin 
448*70a4e555SLoGin impl CurrentApic {
449*70a4e555SLoGin     /// x2apic是否启用
450*70a4e555SLoGin     pub fn x2apic_enabled(&self) -> bool {
451*70a4e555SLoGin         return LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic;
452*70a4e555SLoGin     }
453*70a4e555SLoGin 
454*70a4e555SLoGin     pub(self) unsafe fn write_xapic_register(&self, reg: XApicOffset, value: u32) {
455*70a4e555SLoGin         current_xapic_instance().borrow_mut().as_mut().map(|xapic| {
456*70a4e555SLoGin             xapic.write(reg, value);
457*70a4e555SLoGin         });
458*70a4e555SLoGin     }
459*70a4e555SLoGin 
460*70a4e555SLoGin     /// 屏蔽类8259A芯片
461*70a4e555SLoGin     unsafe fn mask8259a(&self) {
462*70a4e555SLoGin         CurrentPortIOArch::out8(0x21, 0xff);
463*70a4e555SLoGin         CurrentPortIOArch::out8(0xa1, 0xff);
464*70a4e555SLoGin 
465*70a4e555SLoGin         // 写入8259A pic的EOI位
466*70a4e555SLoGin         CurrentPortIOArch::out8(0x20, 0x20);
467*70a4e555SLoGin         CurrentPortIOArch::out8(0xa0, 0x20);
468*70a4e555SLoGin 
469*70a4e555SLoGin         kdebug!("8259A Masked.");
470*70a4e555SLoGin 
471*70a4e555SLoGin         // enable IMCR
472*70a4e555SLoGin         CurrentPortIOArch::out8(0x22, 0x70);
473*70a4e555SLoGin         CurrentPortIOArch::out8(0x23, 0x01);
474*70a4e555SLoGin     }
475*70a4e555SLoGin }
476*70a4e555SLoGin 
477*70a4e555SLoGin impl LocalAPIC for CurrentApic {
478*70a4e555SLoGin     fn support() -> bool {
479*70a4e555SLoGin         true
480*70a4e555SLoGin     }
481*70a4e555SLoGin 
482*70a4e555SLoGin     fn init_current_cpu(&mut self) -> bool {
483*70a4e555SLoGin         let cpu_id = smp_get_processor_id();
484*70a4e555SLoGin         if cpu_id == 0 {
485*70a4e555SLoGin             unsafe {
486*70a4e555SLoGin                 self.mask8259a();
487*70a4e555SLoGin             }
488*70a4e555SLoGin         }
489*70a4e555SLoGin         kinfo!("Initializing apic for cpu {}", cpu_id);
490*70a4e555SLoGin         if X2Apic::support() && X2Apic.init_current_cpu() {
491*70a4e555SLoGin             if cpu_id == 0 {
492*70a4e555SLoGin                 LOCAL_APIC_ENABLE_TYPE.store(LocalApicEnableType::X2Apic, Ordering::SeqCst);
493*70a4e555SLoGin             }
494*70a4e555SLoGin             kinfo!("x2APIC initialized for cpu {}", cpu_id);
495*70a4e555SLoGin         } else {
496*70a4e555SLoGin             kinfo!("x2APIC not supported or failed to initialize, fallback to xAPIC.");
497*70a4e555SLoGin             if cpu_id == 0 {
498*70a4e555SLoGin                 LOCAL_APIC_ENABLE_TYPE.store(LocalApicEnableType::XApic, Ordering::SeqCst);
499*70a4e555SLoGin             }
500*70a4e555SLoGin             let apic_base =
501*70a4e555SLoGin                 PhysAddr::new(unsafe { x86::msr::rdmsr(IA32_APIC_BASE) as usize & 0xFFFF_0000 });
502*70a4e555SLoGin             let xapic_instance = unsafe { XApic::new(apic_base) };
503*70a4e555SLoGin 
504*70a4e555SLoGin             let mut cur = current_xapic_instance().borrow_mut();
505*70a4e555SLoGin             if cur.is_none() {
506*70a4e555SLoGin                 *cur = Some(xapic_instance);
507*70a4e555SLoGin             } else {
508*70a4e555SLoGin                 panic!("xapic instance already initialized.");
509*70a4e555SLoGin             }
510*70a4e555SLoGin 
511*70a4e555SLoGin             if let Some(xapic) = cur.as_mut() {
512*70a4e555SLoGin                 xapic.init_current_cpu();
513*70a4e555SLoGin             }
514*70a4e555SLoGin 
515*70a4e555SLoGin             kinfo!("xAPIC initialized for cpu {}", cpu_id);
516*70a4e555SLoGin         }
517*70a4e555SLoGin         if cpu_id == 0 {
518*70a4e555SLoGin             ioapic_init();
519*70a4e555SLoGin         }
520*70a4e555SLoGin         kinfo!("Apic initialized.");
521*70a4e555SLoGin         return true;
522*70a4e555SLoGin     }
523*70a4e555SLoGin 
524*70a4e555SLoGin     fn send_eoi(&self) {
525*70a4e555SLoGin         if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
526*70a4e555SLoGin             X2Apic.send_eoi();
527*70a4e555SLoGin         } else {
528*70a4e555SLoGin             current_xapic_instance().borrow().as_ref().map(|xapic| {
529*70a4e555SLoGin                 xapic.send_eoi();
530*70a4e555SLoGin             });
531*70a4e555SLoGin         }
532*70a4e555SLoGin     }
533*70a4e555SLoGin 
534*70a4e555SLoGin     fn version(&self) -> u8 {
535*70a4e555SLoGin         if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
536*70a4e555SLoGin             return X2Apic.version();
537*70a4e555SLoGin         } else {
538*70a4e555SLoGin             return current_xapic_instance()
539*70a4e555SLoGin                 .borrow()
540*70a4e555SLoGin                 .as_ref()
541*70a4e555SLoGin                 .map(|xapic| xapic.version())
542*70a4e555SLoGin                 .unwrap_or(0);
543*70a4e555SLoGin         }
544*70a4e555SLoGin     }
545*70a4e555SLoGin 
546*70a4e555SLoGin     fn support_eoi_broadcast_suppression(&self) -> bool {
547*70a4e555SLoGin         if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
548*70a4e555SLoGin             return X2Apic.support_eoi_broadcast_suppression();
549*70a4e555SLoGin         } else {
550*70a4e555SLoGin             return current_xapic_instance()
551*70a4e555SLoGin                 .borrow()
552*70a4e555SLoGin                 .as_ref()
553*70a4e555SLoGin                 .map(|xapic| xapic.support_eoi_broadcast_suppression())
554*70a4e555SLoGin                 .unwrap_or(false);
555*70a4e555SLoGin         }
556*70a4e555SLoGin     }
557*70a4e555SLoGin 
558*70a4e555SLoGin     fn max_lvt_entry(&self) -> u8 {
559*70a4e555SLoGin         if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
560*70a4e555SLoGin             return X2Apic.max_lvt_entry();
561*70a4e555SLoGin         } else {
562*70a4e555SLoGin             return current_xapic_instance()
563*70a4e555SLoGin                 .borrow()
564*70a4e555SLoGin                 .as_ref()
565*70a4e555SLoGin                 .map(|xapic| xapic.max_lvt_entry())
566*70a4e555SLoGin                 .unwrap_or(0);
567*70a4e555SLoGin         }
568*70a4e555SLoGin     }
569*70a4e555SLoGin 
570*70a4e555SLoGin     fn id(&self) -> u32 {
571*70a4e555SLoGin         if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
572*70a4e555SLoGin             return X2Apic.id();
573*70a4e555SLoGin         } else {
574*70a4e555SLoGin             return current_xapic_instance()
575*70a4e555SLoGin                 .borrow()
576*70a4e555SLoGin                 .as_ref()
577*70a4e555SLoGin                 .map(|xapic| xapic.id())
578*70a4e555SLoGin                 .unwrap_or(0);
579*70a4e555SLoGin         }
580*70a4e555SLoGin     }
581*70a4e555SLoGin 
582*70a4e555SLoGin     fn set_lvt(&mut self, lvt: LVT) {
583*70a4e555SLoGin         if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
584*70a4e555SLoGin             X2Apic.set_lvt(lvt);
585*70a4e555SLoGin         } else {
586*70a4e555SLoGin             current_xapic_instance().borrow_mut().as_mut().map(|xapic| {
587*70a4e555SLoGin                 xapic.set_lvt(lvt);
588*70a4e555SLoGin             });
589*70a4e555SLoGin         }
590*70a4e555SLoGin     }
591*70a4e555SLoGin 
592*70a4e555SLoGin     fn read_lvt(&self, reg: LVTRegister) -> LVT {
593*70a4e555SLoGin         if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
594*70a4e555SLoGin             return X2Apic.read_lvt(reg);
595*70a4e555SLoGin         } else {
596*70a4e555SLoGin             return current_xapic_instance()
597*70a4e555SLoGin                 .borrow()
598*70a4e555SLoGin                 .as_ref()
599*70a4e555SLoGin                 .map(|xapic| xapic.read_lvt(reg))
600*70a4e555SLoGin                 .expect("xapic instance not initialized.");
601*70a4e555SLoGin         }
602*70a4e555SLoGin     }
603*70a4e555SLoGin 
604*70a4e555SLoGin     fn mask_all_lvt(&mut self) {
605*70a4e555SLoGin         if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
606*70a4e555SLoGin             X2Apic.mask_all_lvt();
607*70a4e555SLoGin         } else {
608*70a4e555SLoGin             current_xapic_instance().borrow_mut().as_mut().map(|xapic| {
609*70a4e555SLoGin                 xapic.mask_all_lvt();
610*70a4e555SLoGin             });
611*70a4e555SLoGin         }
612*70a4e555SLoGin     }
613*70a4e555SLoGin 
614*70a4e555SLoGin     fn write_icr(&self, icr: Icr) {
615*70a4e555SLoGin         if LOCAL_APIC_ENABLE_TYPE.load(Ordering::SeqCst) == LocalApicEnableType::X2Apic {
616*70a4e555SLoGin             X2Apic.write_icr(icr);
617*70a4e555SLoGin         } else {
618*70a4e555SLoGin             current_xapic_instance().borrow().as_ref().map(|xapic| {
619*70a4e555SLoGin                 xapic.write_icr(icr);
620*70a4e555SLoGin             });
621*70a4e555SLoGin         }
622*70a4e555SLoGin     }
623*70a4e555SLoGin }
624