1 use core::{
2 cell::RefCell,
3 hint::spin_loop,
4 ptr::{read_volatile, write_volatile},
5 };
6
7 use log::{debug, error, info};
8
9 use crate::{
10 mm::{
11 mmio_buddy::{mmio_pool, MMIOSpaceGuard},
12 percpu::PerCpu,
13 PhysAddr, VirtAddr,
14 },
15 smp::core::smp_get_processor_id,
16 };
17
18 use super::{hw_irq::ApicId, LVTRegister, LocalAPIC, LVT};
19
20 /// per-cpu的xAPIC的MMIO空间起始地址
21 static mut XAPIC_INSTANCES: [RefCell<Option<XApic>>; PerCpu::MAX_CPU_NUM as usize] =
22 [const { RefCell::new(None) }; PerCpu::MAX_CPU_NUM as usize];
23
24 #[inline(always)]
current_xapic_instance() -> &'static RefCell<Option<XApic>>25 pub(super) fn current_xapic_instance() -> &'static RefCell<Option<XApic>> {
26 unsafe { &XAPIC_INSTANCES.as_ref()[smp_get_processor_id().data() as usize] }
27 }
28
29 /// TODO:统一变量
30 /// @brief local APIC 寄存器地址偏移量
31 #[derive(Debug)]
32 #[allow(dead_code)]
33 #[allow(non_camel_case_types)]
34 #[repr(u32)]
35 pub enum XApicOffset {
36 // 定义各个寄存器的地址偏移量
37 LOCAL_APIC_OFFSET_Local_APIC_ID = 0x20,
38 LOCAL_APIC_OFFSET_Local_APIC_Version = 0x30,
39 LOCAL_APIC_OFFSET_Local_APIC_TPR = 0x80,
40 LOCAL_APIC_OFFSET_Local_APIC_APR = 0x90,
41 LOCAL_APIC_OFFSET_Local_APIC_PPR = 0xa0,
42 LOCAL_APIC_OFFSET_Local_APIC_EOI = 0xb0,
43 LOCAL_APIC_OFFSET_Local_APIC_RRD = 0xc0,
44 LOCAL_APIC_OFFSET_Local_APIC_LDR = 0xd0,
45 LOCAL_APIC_OFFSET_Local_APIC_DFR = 0xe0,
46 LOCAL_APIC_OFFSET_Local_APIC_SVR = 0xf0,
47
48 LOCAL_APIC_OFFSET_Local_APIC_ISR_31_0 = 0x100, // In-Service Register
49 LOCAL_APIC_OFFSET_Local_APIC_ISR_63_32 = 0x110,
50 LOCAL_APIC_OFFSET_Local_APIC_ISR_95_64 = 0x120,
51 LOCAL_APIC_OFFSET_Local_APIC_ISR_127_96 = 0x130,
52 LOCAL_APIC_OFFSET_Local_APIC_ISR_159_128 = 0x140,
53 LOCAL_APIC_OFFSET_Local_APIC_ISR_191_160 = 0x150,
54 LOCAL_APIC_OFFSET_Local_APIC_ISR_223_192 = 0x160,
55 LOCAL_APIC_OFFSET_Local_APIC_ISR_255_224 = 0x170,
56
57 LOCAL_APIC_OFFSET_Local_APIC_TMR_31_0 = 0x180, // Trigger Mode Register
58 LOCAL_APIC_OFFSET_Local_APIC_TMR_63_32 = 0x190,
59 LOCAL_APIC_OFFSET_Local_APIC_TMR_95_64 = 0x1a0,
60 LOCAL_APIC_OFFSET_Local_APIC_TMR_127_96 = 0x1b0,
61 LOCAL_APIC_OFFSET_Local_APIC_TMR_159_128 = 0x1c0,
62 LOCAL_APIC_OFFSET_Local_APIC_TMR_191_160 = 0x1d0,
63 LOCAL_APIC_OFFSET_Local_APIC_TMR_223_192 = 0x1e0,
64 LOCAL_APIC_OFFSET_Local_APIC_TMR_255_224 = 0x1f0,
65
66 LOCAL_APIC_OFFSET_Local_APIC_IRR_31_0 = 0x200, // Interrupt Request Register
67 LOCAL_APIC_OFFSET_Local_APIC_IRR_63_32 = 0x210,
68 LOCAL_APIC_OFFSET_Local_APIC_IRR_95_64 = 0x220,
69 LOCAL_APIC_OFFSET_Local_APIC_IRR_127_96 = 0x230,
70 LOCAL_APIC_OFFSET_Local_APIC_IRR_159_128 = 0x240,
71 LOCAL_APIC_OFFSET_Local_APIC_IRR_191_160 = 0x250,
72 LOCAL_APIC_OFFSET_Local_APIC_IRR_223_192 = 0x260,
73 LOCAL_APIC_OFFSET_Local_APIC_IRR_255_224 = 0x270,
74
75 LOCAL_APIC_OFFSET_Local_APIC_ESR = 0x280, // Error Status Register
76
77 LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI = 0x2f0, // Corrected Machine Check Interrupt Register
78
79 LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0 = 0x300, // Interrupt Command Register
80 LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32 = 0x310,
81
82 LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER = 0x320,
83 LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL = 0x330,
84 LOCAL_APIC_OFFSET_Local_APIC_LVT_PERFORMANCE_MONITOR = 0x340,
85 LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT0 = 0x350,
86 LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT1 = 0x360,
87 LOCAL_APIC_OFFSET_Local_APIC_LVT_ERROR = 0x370,
88 // 初始计数寄存器(定时器专用)
89 LOCAL_APIC_OFFSET_Local_APIC_INITIAL_COUNT_REG = 0x380,
90 // 当前计数寄存器(定时器专用)
91 LOCAL_APIC_OFFSET_Local_APIC_CURRENT_COUNT_REG = 0x390,
92 LOCAL_APIC_OFFSET_Local_APIC_CLKDIV = 0x3e0,
93 }
94
95 impl From<XApicOffset> for u32 {
from(val: XApicOffset) -> Self96 fn from(val: XApicOffset) -> Self {
97 val as u32
98 }
99 }
100
101 impl From<LVTRegister> for XApicOffset {
from(lvt: LVTRegister) -> Self102 fn from(lvt: LVTRegister) -> Self {
103 match lvt {
104 LVTRegister::Timer => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER,
105 LVTRegister::Thermal => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_THERMAL,
106 LVTRegister::PerformanceMonitor => {
107 XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_PERFORMANCE_MONITOR
108 }
109 LVTRegister::LINT0 => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT0,
110 LVTRegister::LINT1 => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_LINT1,
111 LVTRegister::ErrorReg => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_ERROR,
112 LVTRegister::CMCI => XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_CMCI,
113 }
114 }
115 }
116
117 #[derive(Debug)]
118 #[allow(dead_code)]
119 pub struct XApic {
120 /// 当前xAPIC的寄存器映射的虚拟地址。注意,每个CPU都有自己的xAPIC,所以这个地址是每个CPU都不一样的。
121 apic_vaddr: VirtAddr,
122 /// `apic_vaddr`与映射的空间起始位置之间的偏移量
123 offset: usize,
124 map_guard: MMIOSpaceGuard,
125 xapic_base: PhysAddr,
126 }
127
128 impl XApic {
129 /// 读取指定寄存器的值
130 #[allow(dead_code)]
read(&self, reg: XApicOffset) -> u32131 pub unsafe fn read(&self, reg: XApicOffset) -> u32 {
132 read_volatile((self.apic_vaddr.data() + reg as usize) as *const u32)
133 }
134
135 /// 将指定的值写入寄存器
136 #[allow(dead_code)]
write(&self, reg: XApicOffset, value: u32)137 pub unsafe fn write(&self, reg: XApicOffset, value: u32) {
138 write_volatile(
139 (self.apic_vaddr.data() + (reg as u32) as usize) as *mut u32,
140 value,
141 );
142 self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ID); // 等待写操作完成,通过读取进行同步
143 }
144 }
145
146 impl XApic {
147 /// 创建新的XAPIC实例
148 ///
149 /// ## 参数
150 ///
151 /// - `xapic_base` - 当前核心的xAPIC的寄存器的物理地址
new(xapic_base: PhysAddr) -> Self152 pub unsafe fn new(xapic_base: PhysAddr) -> Self {
153 let offset = xapic_base.data() & 0xffff;
154 let paddr = PhysAddr::new(xapic_base.data() & !0xffff);
155 let g = mmio_pool()
156 .create_mmio(4096)
157 .expect("Fail to create MMIO for XAPIC");
158 g.map_phys(paddr, 4096).expect("Fail to map MMIO for XAPIC");
159 let addr = g.vaddr() + offset;
160
161 debug!(
162 "XAPIC: {:#x} -> {:#x}, offset={offset}",
163 xapic_base.data(),
164 addr.data()
165 );
166
167 let r = Self {
168 apic_vaddr: addr,
169 offset,
170 map_guard: g,
171 xapic_base,
172 };
173
174 return r;
175 }
176 }
177
178 #[allow(dead_code)]
179 const X1: u32 = 0x0000000B; // 将除数设置为1,即不除频率
180 #[allow(dead_code)]
181 const PERIODIC: u32 = 0x00020000; // 周期性模式
182 #[allow(dead_code)]
183 const ENABLE: u32 = 0x00000100; // 单元使能
184 #[allow(dead_code)]
185 const MASKED: u32 = 0x00010000; // 中断屏蔽
186 const LEVEL: u32 = 0x00008000; // 电平触发
187 const BCAST: u32 = 0x00080000; // 发送到所有APIC,包括自己
188 const DELIVS: u32 = 0x00001000; // 传递状态
189 const INIT: u32 = 0x00000500; // INIT/RESET
190
191 //中断请求
192 #[allow(dead_code)]
193 const T_IRQ0: u32 = 32; // IRQ 0 对应于 T_IRQ 中断
194 #[allow(dead_code)]
195 const IRQ_TIMER: u32 = 0;
196 #[allow(dead_code)]
197 const IRQ_KBD: u32 = 1;
198 #[allow(dead_code)]
199 const IRQ_COM1: u32 = 4;
200 #[allow(dead_code)]
201 const IRQ_IDE: u32 = 14;
202 #[allow(dead_code)]
203 const IRQ_ERROR: u32 = 19;
204 #[allow(dead_code)]
205 const IRQ_SPURIOUS: u32 = 31;
206
207 impl LocalAPIC for XApic {
208 /// @brief 判断处理器是否支持apic
support() -> bool209 fn support() -> bool {
210 return x86::cpuid::CpuId::new()
211 .get_feature_info()
212 .expect("Fail to get CPU feature.")
213 .has_apic();
214 }
215
216 /// @return true -> 函数运行成功
init_current_cpu(&mut self) -> bool217 fn init_current_cpu(&mut self) -> bool {
218 unsafe {
219 // enable xapic
220 x86::msr::wrmsr(x86::msr::APIC_BASE, (self.xapic_base.data() | 0x800) as u64);
221 let val = x86::msr::rdmsr(x86::msr::APIC_BASE);
222 if val & 0x800 != 0x800 {
223 error!("xAPIC enable failed: APIC_BASE & 0x800 != 0x800");
224 return false;
225 }
226 // 设置 Spurious Interrupt Vector Register
227 let val = self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR);
228
229 self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR, val | ENABLE);
230
231 let val = self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_SVR);
232 if val & ENABLE == 0 {
233 error!("xAPIC software enable failed.");
234
235 return false;
236 } else {
237 info!("xAPIC software enabled.");
238 }
239
240 if val & 0x1000 != 0 {
241 info!("xAPIC EOI broadcast suppression enabled.");
242 }
243
244 self.mask_all_lvt();
245
246 // 清除错误状态寄存器(需要连续写入两次)
247 self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ESR, 0);
248 self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ESR, 0);
249
250 // 确认任何未完成的中断
251 self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_EOI, 0);
252
253 // 发送 Init Level De-Assert 信号以同步仲裁ID
254 self.write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32, 0);
255 self.write(
256 XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0,
257 BCAST | INIT | LEVEL,
258 );
259 while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) & DELIVS != 0 {
260 spin_loop();
261 }
262 }
263
264 true
265 }
266
267 /// 发送 EOI(End Of Interrupt)
send_eoi(&self)268 fn send_eoi(&self) {
269 unsafe {
270 let s = self as *const Self as *mut Self;
271 (*s).write(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_EOI, 0);
272 }
273 }
274
275 /// 获取版本号
version(&self) -> u8276 fn version(&self) -> u8 {
277 unsafe { (self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version) & 0xff) as u8 }
278 }
279
support_eoi_broadcast_suppression(&self) -> bool280 fn support_eoi_broadcast_suppression(&self) -> bool {
281 unsafe { ((self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version) >> 24) & 1) == 1 }
282 }
283
max_lvt_entry(&self) -> u8284 fn max_lvt_entry(&self) -> u8 {
285 unsafe {
286 ((self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_Version) >> 16) & 0xff) as u8 + 1
287 }
288 }
289
290 /// 获取ID
id(&self) -> ApicId291 fn id(&self) -> ApicId {
292 unsafe { ApicId::new(self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ID) >> 24) }
293 }
294
295 /// 设置LVT寄存器的值
set_lvt(&mut self, lvt: LVT)296 fn set_lvt(&mut self, lvt: LVT) {
297 unsafe {
298 self.write(lvt.register().into(), lvt.data);
299 }
300 }
301
read_lvt(&self, reg: LVTRegister) -> LVT302 fn read_lvt(&self, reg: LVTRegister) -> LVT {
303 unsafe {
304 LVT::new(
305 reg,
306 self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_LVT_TIMER),
307 )
308 .unwrap()
309 }
310 }
311
mask_all_lvt(&mut self)312 fn mask_all_lvt(&mut self) {
313 // self.set_lvt(LVT::new(LVTRegister::CMCI, LVT::MASKED).unwrap());
314 self.set_lvt(LVT::new(LVTRegister::Timer, LVT::MASKED).unwrap());
315 self.set_lvt(LVT::new(LVTRegister::Thermal, LVT::MASKED).unwrap());
316 self.set_lvt(LVT::new(LVTRegister::PerformanceMonitor, LVT::MASKED).unwrap());
317 self.set_lvt(LVT::new(LVTRegister::LINT0, LVT::MASKED).unwrap());
318 self.set_lvt(LVT::new(LVTRegister::LINT1, LVT::MASKED).unwrap());
319 self.set_lvt(LVT::new(LVTRegister::ErrorReg, LVT::MASKED).unwrap());
320 }
321
write_icr(&self, icr: x86::apic::Icr)322 fn write_icr(&self, icr: x86::apic::Icr) {
323 unsafe {
324 // Wait for any previous send to finish
325 while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) & DELIVS != 0 {
326 spin_loop();
327 }
328
329 self.write(
330 XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_63_32,
331 icr.upper(),
332 );
333 self.write(
334 XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0,
335 icr.lower(),
336 );
337
338 // Wait for send to finish
339 while self.read(XApicOffset::LOCAL_APIC_OFFSET_Local_APIC_ICR_31_0) & DELIVS != 0 {
340 spin_loop();
341 }
342 }
343 }
344 }
345