xref: /DragonOS/kernel/src/arch/x86_64/driver/apic/lapic_vector.rs (revision b5b571e02693d91eb6918d3b7561e088c3e7ee81)
1e2841179SLoGin use core::intrinsics::unlikely;
2e2841179SLoGin 
3e2841179SLoGin use alloc::{string::ToString, sync::Arc};
4e2841179SLoGin use intertrait::CastFrom;
5e2841179SLoGin use system_error::SystemError;
6e2841179SLoGin 
7e2841179SLoGin use crate::{
8e2841179SLoGin     arch::{
9e2841179SLoGin         driver::apic::{
10e2841179SLoGin             apic_timer::{local_apic_timer_irq_desc_init, APIC_TIMER_IRQ_NUM},
11e2841179SLoGin             ioapic::ioapic_init,
12e2841179SLoGin         },
13e2841179SLoGin         interrupt::{
14e2841179SLoGin             entry::arch_setup_interrupt_gate,
15e2841179SLoGin             ipi::{arch_ipi_handler_init, send_ipi, IPI_NUM_FLUSH_TLB, IPI_NUM_KICK_CPU},
16e2841179SLoGin             msi::{X86MsiAddrHi, X86MsiAddrLoNormal, X86MsiDataNormal, X86_MSI_BASE_ADDRESS_LOW},
17e2841179SLoGin         },
18e2841179SLoGin     },
19e2841179SLoGin     driver::open_firmware::device_node::DeviceNode,
20e2841179SLoGin     exception::{
21e2841179SLoGin         ipi::{IpiKind, IpiTarget},
22e2841179SLoGin         irqchip::{IrqChip, IrqChipData, IrqChipFlags},
23e2841179SLoGin         irqdata::IrqData,
24e2841179SLoGin         irqdomain::{irq_domain_manager, IrqDomain, IrqDomainBusToken, IrqDomainOps},
25e2841179SLoGin         msi::MsiMsg,
26e2841179SLoGin         HardwareIrqNumber, IrqNumber,
27e2841179SLoGin     },
28e2841179SLoGin     kwarn,
29e2841179SLoGin     libs::spinlock::{SpinLock, SpinLockGuard},
30e2841179SLoGin     smp::{core::smp_get_processor_id, cpu::ProcessorId},
31e2841179SLoGin };
32e2841179SLoGin 
33e2841179SLoGin use super::{hw_irq::HardwareIrqConfig, CurrentApic, LocalAPIC};
34e2841179SLoGin 
35e2841179SLoGin static mut LOCAL_APIC_CHIP: Option<Arc<LocalApicChip>> = None;
36e2841179SLoGin 
37e2841179SLoGin pub fn local_apic_chip() -> &'static Arc<LocalApicChip> {
38e2841179SLoGin     unsafe { LOCAL_APIC_CHIP.as_ref().unwrap() }
39e2841179SLoGin }
40e2841179SLoGin 
41e2841179SLoGin #[derive(Debug)]
42e2841179SLoGin pub struct LocalApicChip {
43e2841179SLoGin     inner: SpinLock<InnerIrqChip>,
44e2841179SLoGin }
45e2841179SLoGin 
46e2841179SLoGin impl LocalApicChip {
47e2841179SLoGin     pub fn new() -> Self {
48e2841179SLoGin         Self {
49e2841179SLoGin             inner: SpinLock::new(InnerIrqChip {
50e2841179SLoGin                 flags: IrqChipFlags::empty(),
51e2841179SLoGin             }),
52e2841179SLoGin         }
53e2841179SLoGin     }
54e2841179SLoGin }
55e2841179SLoGin 
56e2841179SLoGin impl IrqChip for LocalApicChip {
57e2841179SLoGin     fn name(&self) -> &'static str {
58e2841179SLoGin         "APIC"
59e2841179SLoGin     }
60e2841179SLoGin 
61e2841179SLoGin     fn can_set_flow_type(&self) -> bool {
62e2841179SLoGin         false
63e2841179SLoGin     }
64e2841179SLoGin 
65e2841179SLoGin     fn irq_disable(&self, _irq: &Arc<IrqData>) {}
66e2841179SLoGin 
67e2841179SLoGin     fn irq_ack(&self, _irq: &Arc<IrqData>) {
68e2841179SLoGin         CurrentApic.send_eoi();
69e2841179SLoGin     }
70e2841179SLoGin 
71e2841179SLoGin     fn can_set_affinity(&self) -> bool {
72e2841179SLoGin         false
73e2841179SLoGin     }
74e2841179SLoGin 
75e2841179SLoGin     fn can_mask_ack(&self) -> bool {
76e2841179SLoGin         false
77e2841179SLoGin     }
78e2841179SLoGin 
79e2841179SLoGin     fn irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
80e2841179SLoGin         // 这里临时处理,后续需要修改
81e2841179SLoGin         return Ok(());
82e2841179SLoGin     }
83e2841179SLoGin 
84e2841179SLoGin     fn irq_unmask(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
85e2841179SLoGin         Ok(())
86e2841179SLoGin     }
87e2841179SLoGin 
88e2841179SLoGin     fn irq_compose_msi_msg(&self, irq: &Arc<IrqData>, msg: &mut MsiMsg) {
89e2841179SLoGin         let chip_data = irq.chip_info_read_irqsave().chip_data().unwrap();
90e2841179SLoGin         let apicd = chip_data.ref_any().downcast_ref::<ApicChipData>().unwrap();
91e2841179SLoGin         let cfg = &apicd.inner().hw_irq_cfg;
92e2841179SLoGin         irq_msi_compose_msg(cfg, msg, false);
93e2841179SLoGin     }
94e2841179SLoGin 
95e2841179SLoGin     fn retrigger(&self, irq: &Arc<IrqData>) -> Result<(), SystemError> {
96e2841179SLoGin         let chip_data = irq
97e2841179SLoGin             .chip_info_read_irqsave()
98e2841179SLoGin             .chip_data()
99e2841179SLoGin             .ok_or(SystemError::EINVAL)?;
100e2841179SLoGin         let apicd = chip_data
101e2841179SLoGin             .ref_any()
102e2841179SLoGin             .downcast_ref::<ApicChipData>()
103e2841179SLoGin             .ok_or(SystemError::EINVAL)?;
104e2841179SLoGin         let inner = apicd.inner();
105e2841179SLoGin 
106e2841179SLoGin         send_ipi(
107e2841179SLoGin             IpiKind::SpecVector(inner.vector),
108e2841179SLoGin             IpiTarget::Specified(inner.cpu),
109e2841179SLoGin         );
110e2841179SLoGin 
111e2841179SLoGin         Ok(())
112e2841179SLoGin     }
113e2841179SLoGin 
114e2841179SLoGin     fn flags(&self) -> IrqChipFlags {
115e2841179SLoGin         self.inner.lock_irqsave().flags
116e2841179SLoGin     }
117e2841179SLoGin }
118e2841179SLoGin 
119e2841179SLoGin #[derive(Debug)]
120e2841179SLoGin struct InnerIrqChip {
121e2841179SLoGin     flags: IrqChipFlags,
122e2841179SLoGin }
123e2841179SLoGin 
124e2841179SLoGin #[derive(Debug)]
125e2841179SLoGin struct ApicChipData {
126e2841179SLoGin     inner: SpinLock<InnerApicChipData>,
127e2841179SLoGin }
128e2841179SLoGin 
129e2841179SLoGin impl ApicChipData {
130e2841179SLoGin     #[allow(dead_code)]
131e2841179SLoGin     pub fn new(
132e2841179SLoGin         hw_irq_cfg: HardwareIrqConfig,
133e2841179SLoGin         irq: IrqNumber,
134e2841179SLoGin         vector: HardwareIrqNumber,
135e2841179SLoGin         cpu: ProcessorId,
136e2841179SLoGin     ) -> Self {
137e2841179SLoGin         Self {
138e2841179SLoGin             inner: SpinLock::new(InnerApicChipData {
139e2841179SLoGin                 hw_irq_cfg,
140e2841179SLoGin                 irq,
141e2841179SLoGin                 vector,
142e2841179SLoGin                 prev_vector: None,
143e2841179SLoGin                 cpu,
144e2841179SLoGin                 prev_cpu: None,
145e2841179SLoGin                 status: ApicChipStatus::empty(),
146e2841179SLoGin             }),
147e2841179SLoGin         }
148e2841179SLoGin     }
149e2841179SLoGin 
150e2841179SLoGin     pub fn inner(&self) -> SpinLockGuard<InnerApicChipData> {
151e2841179SLoGin         self.inner.lock_irqsave()
152e2841179SLoGin     }
153e2841179SLoGin }
154e2841179SLoGin 
155e2841179SLoGin #[allow(dead_code)]
156e2841179SLoGin #[derive(Debug)]
157e2841179SLoGin struct InnerApicChipData {
158e2841179SLoGin     hw_irq_cfg: HardwareIrqConfig,
159e2841179SLoGin     irq: IrqNumber,
160e2841179SLoGin     vector: HardwareIrqNumber,
161e2841179SLoGin     prev_vector: Option<HardwareIrqNumber>,
162e2841179SLoGin     cpu: ProcessorId,
163e2841179SLoGin     prev_cpu: Option<ProcessorId>,
164e2841179SLoGin     status: ApicChipStatus,
165e2841179SLoGin }
166e2841179SLoGin 
167e2841179SLoGin impl IrqChipData for ApicChipData {
168e2841179SLoGin     fn as_any_ref(&self) -> &dyn core::any::Any {
169e2841179SLoGin         self
170e2841179SLoGin     }
171e2841179SLoGin }
172e2841179SLoGin 
173e2841179SLoGin bitflags! {
174e2841179SLoGin     pub struct ApicChipStatus: u32 {
175e2841179SLoGin         const MOVE_IN_PROGRESS = 1 << 0;
176e2841179SLoGin         const IS_MANAGED = 1 << 1;
177e2841179SLoGin         const CAN_RESERVE = 1 << 2;
178e2841179SLoGin         const HAS_RESERVED = 1 << 3;
179e2841179SLoGin     }
180e2841179SLoGin }
181e2841179SLoGin 
182e2841179SLoGin pub(super) fn irq_msi_compose_msg(cfg: &HardwareIrqConfig, msg: &mut MsiMsg, dmar: bool) {
183e2841179SLoGin     *msg = MsiMsg::new_zeroed();
184e2841179SLoGin 
185e2841179SLoGin     let arch_data = X86MsiDataNormal::new()
186e2841179SLoGin         .with_delivery_mode(x86::apic::DeliveryMode::Fixed as u8)
187e2841179SLoGin         .with_vector((cfg.vector.data() & 0xff) as u8);
188e2841179SLoGin     let mut address_lo = X86MsiAddrLoNormal::new()
189e2841179SLoGin         .with_base_address(X86_MSI_BASE_ADDRESS_LOW)
190e2841179SLoGin         .with_dest_mode_logical(false)
191e2841179SLoGin         .with_destid_0_7(cfg.apic_id.data() & 0xff);
192e2841179SLoGin 
193e2841179SLoGin     let mut address_hi = X86MsiAddrHi::new();
194e2841179SLoGin 
195e2841179SLoGin     /*
196e2841179SLoGin      * 只有IOMMU本身可以使用将目标APIC ID放入地址的高位的技术。
197e2841179SLoGin      * 任何其他尝试这样做的东西都只是在写内存,并且需要IR来
198e2841179SLoGin      * 寻址不能在正常的32位地址范围内0xFFExxxxx寻址的APIC。
199e2841179SLoGin      * 这通常是8位,但一些虚拟化程序允许在位5-11使用扩展的目的地ID字段,
200e2841179SLoGin      * 总共支持15位的APIC ID。
201e2841179SLoGin      */
202e2841179SLoGin     if dmar {
203e2841179SLoGin         address_hi.set_destid_8_31(cfg.apic_id.data() >> 8);
204e2841179SLoGin     } else if cfg.apic_id.data() < 0x8000 {
205e2841179SLoGin         // todo: 判断vmx是否支持 extended destination mode
206e2841179SLoGin         // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/apic.c?fi=__irq_msi_compose_msg#2580
207e2841179SLoGin         address_lo.set_virt_destid_8_14(cfg.apic_id.data() >> 8);
208*b5b571e0SLoGin     } else if unlikely(cfg.apic_id.data() > 0xff) {
209e2841179SLoGin         kwarn!(
210e2841179SLoGin             "irq_msi_compose_msg: Invalid APIC ID: {}",
211e2841179SLoGin             cfg.apic_id.data()
212e2841179SLoGin         );
213e2841179SLoGin     }
214*b5b571e0SLoGin 
215e2841179SLoGin     msg.address_hi = address_hi.into();
216e2841179SLoGin     msg.address_lo = address_lo.into();
217e2841179SLoGin     msg.data = arch_data.into();
218e2841179SLoGin }
219e2841179SLoGin 
220e2841179SLoGin static mut X86_VECTOR_DOMAIN: Option<Arc<IrqDomain>> = None;
221e2841179SLoGin 
222e2841179SLoGin #[inline(always)]
223e2841179SLoGin #[allow(dead_code)]
224e2841179SLoGin pub fn x86_vector_domain() -> &'static Arc<IrqDomain> {
225e2841179SLoGin     unsafe { X86_VECTOR_DOMAIN.as_ref().unwrap() }
226e2841179SLoGin }
227e2841179SLoGin 
228e2841179SLoGin #[inline(never)]
229e2841179SLoGin pub fn arch_early_irq_init() -> Result<(), SystemError> {
230e2841179SLoGin     let vec_domain = irq_domain_manager()
231e2841179SLoGin         .create_and_add(
232e2841179SLoGin             "VECTOR".to_string(),
233e2841179SLoGin             &X86VectorDomainOps,
234e2841179SLoGin             IrqNumber::new(32),
235e2841179SLoGin             HardwareIrqNumber::new(32),
236e2841179SLoGin             223,
237e2841179SLoGin         )
238e2841179SLoGin         .ok_or(SystemError::ENOMEM)?;
239e2841179SLoGin     irq_domain_manager().set_default_domain(vec_domain.clone());
240e2841179SLoGin     unsafe { X86_VECTOR_DOMAIN = Some(vec_domain) };
241e2841179SLoGin 
242e2841179SLoGin     let apic_chip = Arc::new(LocalApicChip::new());
243e2841179SLoGin 
244e2841179SLoGin     unsafe { LOCAL_APIC_CHIP = Some(apic_chip) };
245e2841179SLoGin 
246e2841179SLoGin     // todo: add vector matrix
247e2841179SLoGin     // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/vector.c#803
248e2841179SLoGin     kwarn!("arch_early_irq_init: todo: add vector matrix");
249e2841179SLoGin 
250e2841179SLoGin     local_apic_timer_irq_desc_init();
251e2841179SLoGin     arch_ipi_handler_init();
252e2841179SLoGin     CurrentApic.init_current_cpu();
253e2841179SLoGin     if smp_get_processor_id().data() == 0 {
254e2841179SLoGin         unsafe { arch_setup_interrupt_gate() };
255e2841179SLoGin         ioapic_init(&[APIC_TIMER_IRQ_NUM, IPI_NUM_KICK_CPU, IPI_NUM_FLUSH_TLB]);
256e2841179SLoGin     }
257e2841179SLoGin     return Ok(());
258e2841179SLoGin }
259e2841179SLoGin 
260e2841179SLoGin /// x86的中断域操作
261e2841179SLoGin ///
262e2841179SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/vector.c#693
263e2841179SLoGin #[derive(Debug)]
264e2841179SLoGin struct X86VectorDomainOps;
265e2841179SLoGin 
266e2841179SLoGin impl IrqDomainOps for X86VectorDomainOps {
267e2841179SLoGin     fn match_node(
268e2841179SLoGin         &self,
269e2841179SLoGin         _irq_domain: &Arc<IrqDomain>,
270e2841179SLoGin         _device_node: &Arc<DeviceNode>,
271e2841179SLoGin         _bus_token: IrqDomainBusToken,
272e2841179SLoGin     ) -> bool {
273e2841179SLoGin         todo!()
274e2841179SLoGin     }
275e2841179SLoGin 
276e2841179SLoGin     fn map(
277e2841179SLoGin         &self,
278e2841179SLoGin         _irq_domain: &Arc<IrqDomain>,
279e2841179SLoGin         _hwirq: HardwareIrqNumber,
280e2841179SLoGin         _virq: IrqNumber,
281e2841179SLoGin     ) -> Result<(), SystemError> {
282e2841179SLoGin         Err(SystemError::ENOSYS)
283e2841179SLoGin     }
284e2841179SLoGin 
285e2841179SLoGin     fn unmap(&self, _irq_domain: &Arc<IrqDomain>, _virq: IrqNumber) {
286e2841179SLoGin         todo!()
287e2841179SLoGin     }
288e2841179SLoGin }
289