1e2841179SLoGin use core::intrinsics::unlikely;
2e2841179SLoGin
3e2841179SLoGin use alloc::{string::ToString, sync::Arc};
4e2841179SLoGin use intertrait::CastFrom;
52eab6dd7S曾俊 use log::warn;
6e2841179SLoGin use system_error::SystemError;
7e2841179SLoGin
8e2841179SLoGin use crate::{
9e2841179SLoGin arch::{
10e2841179SLoGin driver::apic::{
11e2841179SLoGin apic_timer::{local_apic_timer_irq_desc_init, APIC_TIMER_IRQ_NUM},
12e2841179SLoGin ioapic::ioapic_init,
13e2841179SLoGin },
14e2841179SLoGin interrupt::{
15e2841179SLoGin entry::arch_setup_interrupt_gate,
16e2841179SLoGin ipi::{arch_ipi_handler_init, send_ipi, IPI_NUM_FLUSH_TLB, IPI_NUM_KICK_CPU},
17e2841179SLoGin msi::{X86MsiAddrHi, X86MsiAddrLoNormal, X86MsiDataNormal, X86_MSI_BASE_ADDRESS_LOW},
18e2841179SLoGin },
19e2841179SLoGin },
20e2841179SLoGin driver::open_firmware::device_node::DeviceNode,
21e2841179SLoGin exception::{
22e2841179SLoGin ipi::{IpiKind, IpiTarget},
23e2841179SLoGin irqchip::{IrqChip, IrqChipData, IrqChipFlags},
24e2841179SLoGin irqdata::IrqData,
25e2841179SLoGin irqdomain::{irq_domain_manager, IrqDomain, IrqDomainBusToken, IrqDomainOps},
26e2841179SLoGin msi::MsiMsg,
27e2841179SLoGin HardwareIrqNumber, IrqNumber,
28e2841179SLoGin },
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
local_apic_chip() -> &'static Arc<LocalApicChip>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 {
new() -> Self47e2841179SLoGin 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 {
name(&self) -> &'static str57e2841179SLoGin fn name(&self) -> &'static str {
58e2841179SLoGin "APIC"
59e2841179SLoGin }
60e2841179SLoGin
can_set_flow_type(&self) -> bool61e2841179SLoGin fn can_set_flow_type(&self) -> bool {
62e2841179SLoGin false
63e2841179SLoGin }
64e2841179SLoGin
irq_disable(&self, _irq: &Arc<IrqData>)65e2841179SLoGin fn irq_disable(&self, _irq: &Arc<IrqData>) {}
66e2841179SLoGin
irq_ack(&self, _irq: &Arc<IrqData>)67e2841179SLoGin fn irq_ack(&self, _irq: &Arc<IrqData>) {
68e2841179SLoGin CurrentApic.send_eoi();
69e2841179SLoGin }
70e2841179SLoGin
can_set_affinity(&self) -> bool71e2841179SLoGin fn can_set_affinity(&self) -> bool {
72e2841179SLoGin false
73e2841179SLoGin }
74e2841179SLoGin
can_mask_ack(&self) -> bool75e2841179SLoGin fn can_mask_ack(&self) -> bool {
76e2841179SLoGin false
77e2841179SLoGin }
78e2841179SLoGin
irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError>79e2841179SLoGin fn irq_enable(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
80e2841179SLoGin // 这里临时处理,后续需要修改
81e2841179SLoGin return Ok(());
82e2841179SLoGin }
83e2841179SLoGin
irq_unmask(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError>84e2841179SLoGin fn irq_unmask(&self, _irq: &Arc<IrqData>) -> Result<(), SystemError> {
85e2841179SLoGin Ok(())
86e2841179SLoGin }
87e2841179SLoGin
irq_compose_msi_msg(&self, irq: &Arc<IrqData>, msg: &mut MsiMsg)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
retrigger(&self, irq: &Arc<IrqData>) -> Result<(), SystemError>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
flags(&self) -> IrqChipFlags114e2841179SLoGin 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)]
new( hw_irq_cfg: HardwareIrqConfig, irq: IrqNumber, vector: HardwareIrqNumber, cpu: ProcessorId, ) -> Self131e2841179SLoGin 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
inner(&self) -> SpinLockGuard<InnerApicChipData>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 {
as_any_ref(&self) -> &dyn core::any::Any168e2841179SLoGin 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
182*bd70d2d1SLoGin #[allow(dead_code)]
irq_msi_compose_msg(cfg: &HardwareIrqConfig, msg: &mut MsiMsg, dmar: bool)183e2841179SLoGin pub(super) fn irq_msi_compose_msg(cfg: &HardwareIrqConfig, msg: &mut MsiMsg, dmar: bool) {
184e2841179SLoGin *msg = MsiMsg::new_zeroed();
185e2841179SLoGin
186e2841179SLoGin let arch_data = X86MsiDataNormal::new()
187e2841179SLoGin .with_delivery_mode(x86::apic::DeliveryMode::Fixed as u8)
188e2841179SLoGin .with_vector((cfg.vector.data() & 0xff) as u8);
189e2841179SLoGin let mut address_lo = X86MsiAddrLoNormal::new()
190e2841179SLoGin .with_base_address(X86_MSI_BASE_ADDRESS_LOW)
191e2841179SLoGin .with_dest_mode_logical(false)
192e2841179SLoGin .with_destid_0_7(cfg.apic_id.data() & 0xff);
193e2841179SLoGin
194e2841179SLoGin let mut address_hi = X86MsiAddrHi::new();
195e2841179SLoGin
196e2841179SLoGin /*
197e2841179SLoGin * 只有IOMMU本身可以使用将目标APIC ID放入地址的高位的技术。
198e2841179SLoGin * 任何其他尝试这样做的东西都只是在写内存,并且需要IR来
199e2841179SLoGin * 寻址不能在正常的32位地址范围内0xFFExxxxx寻址的APIC。
200e2841179SLoGin * 这通常是8位,但一些虚拟化程序允许在位5-11使用扩展的目的地ID字段,
201e2841179SLoGin * 总共支持15位的APIC ID。
202e2841179SLoGin */
203e2841179SLoGin if dmar {
204e2841179SLoGin address_hi.set_destid_8_31(cfg.apic_id.data() >> 8);
205e2841179SLoGin } else if cfg.apic_id.data() < 0x8000 {
206e2841179SLoGin // todo: 判断vmx是否支持 extended destination mode
207e2841179SLoGin // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/apic.c?fi=__irq_msi_compose_msg#2580
208e2841179SLoGin address_lo.set_virt_destid_8_14(cfg.apic_id.data() >> 8);
209b5b571e0SLoGin } else if unlikely(cfg.apic_id.data() > 0xff) {
2102eab6dd7S曾俊 warn!(
211e2841179SLoGin "irq_msi_compose_msg: Invalid APIC ID: {}",
212e2841179SLoGin cfg.apic_id.data()
213e2841179SLoGin );
214e2841179SLoGin }
215b5b571e0SLoGin
216e2841179SLoGin msg.address_hi = address_hi.into();
217e2841179SLoGin msg.address_lo = address_lo.into();
218e2841179SLoGin msg.data = arch_data.into();
219e2841179SLoGin }
220e2841179SLoGin
221e2841179SLoGin static mut X86_VECTOR_DOMAIN: Option<Arc<IrqDomain>> = None;
222e2841179SLoGin
223e2841179SLoGin #[inline(always)]
224e2841179SLoGin #[allow(dead_code)]
x86_vector_domain() -> &'static Arc<IrqDomain>225e2841179SLoGin pub fn x86_vector_domain() -> &'static Arc<IrqDomain> {
226e2841179SLoGin unsafe { X86_VECTOR_DOMAIN.as_ref().unwrap() }
227e2841179SLoGin }
228e2841179SLoGin
229e2841179SLoGin #[inline(never)]
arch_early_irq_init() -> Result<(), SystemError>230e2841179SLoGin pub fn arch_early_irq_init() -> Result<(), SystemError> {
2310102d69fSLoGin const IRQ_SIZE: u32 = 223;
232e2841179SLoGin let vec_domain = irq_domain_manager()
233e2841179SLoGin .create_and_add(
234e2841179SLoGin "VECTOR".to_string(),
235e2841179SLoGin &X86VectorDomainOps,
236e2841179SLoGin IrqNumber::new(32),
237e2841179SLoGin HardwareIrqNumber::new(32),
2380102d69fSLoGin IRQ_SIZE,
239e2841179SLoGin )
240e2841179SLoGin .ok_or(SystemError::ENOMEM)?;
241e2841179SLoGin irq_domain_manager().set_default_domain(vec_domain.clone());
2420102d69fSLoGin irq_domain_manager().domain_associate_many(
2430102d69fSLoGin &vec_domain,
2440102d69fSLoGin IrqNumber::new(0),
2450102d69fSLoGin HardwareIrqNumber::new(0),
2460102d69fSLoGin IRQ_SIZE,
2470102d69fSLoGin );
248e2841179SLoGin unsafe { X86_VECTOR_DOMAIN = Some(vec_domain) };
249e2841179SLoGin
250e2841179SLoGin let apic_chip = Arc::new(LocalApicChip::new());
251e2841179SLoGin
252e2841179SLoGin unsafe { LOCAL_APIC_CHIP = Some(apic_chip) };
253e2841179SLoGin
254e2841179SLoGin // todo: add vector matrix
255e2841179SLoGin // 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/vector.c#803
2562eab6dd7S曾俊 warn!("arch_early_irq_init: todo: add vector matrix");
257e2841179SLoGin
258e2841179SLoGin local_apic_timer_irq_desc_init();
259e2841179SLoGin arch_ipi_handler_init();
260e2841179SLoGin CurrentApic.init_current_cpu();
261e2841179SLoGin if smp_get_processor_id().data() == 0 {
262e2841179SLoGin unsafe { arch_setup_interrupt_gate() };
263e2841179SLoGin ioapic_init(&[APIC_TIMER_IRQ_NUM, IPI_NUM_KICK_CPU, IPI_NUM_FLUSH_TLB]);
264e2841179SLoGin }
265e2841179SLoGin return Ok(());
266e2841179SLoGin }
267e2841179SLoGin
268e2841179SLoGin /// x86的中断域操作
269e2841179SLoGin ///
270e2841179SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/arch/x86/kernel/apic/vector.c#693
271e2841179SLoGin #[derive(Debug)]
272e2841179SLoGin struct X86VectorDomainOps;
273e2841179SLoGin
274e2841179SLoGin impl IrqDomainOps for X86VectorDomainOps {
match_node( &self, _irq_domain: &Arc<IrqDomain>, _device_node: &Arc<DeviceNode>, _bus_token: IrqDomainBusToken, ) -> bool275e2841179SLoGin fn match_node(
276e2841179SLoGin &self,
277e2841179SLoGin _irq_domain: &Arc<IrqDomain>,
278e2841179SLoGin _device_node: &Arc<DeviceNode>,
279e2841179SLoGin _bus_token: IrqDomainBusToken,
280e2841179SLoGin ) -> bool {
281e2841179SLoGin todo!()
282e2841179SLoGin }
283e2841179SLoGin
map( &self, _irq_domain: &Arc<IrqDomain>, _hwirq: HardwareIrqNumber, _virq: IrqNumber, ) -> Result<(), SystemError>284e2841179SLoGin fn map(
285e2841179SLoGin &self,
286e2841179SLoGin _irq_domain: &Arc<IrqDomain>,
287e2841179SLoGin _hwirq: HardwareIrqNumber,
288e2841179SLoGin _virq: IrqNumber,
289e2841179SLoGin ) -> Result<(), SystemError> {
290e2841179SLoGin Err(SystemError::ENOSYS)
291e2841179SLoGin }
292e2841179SLoGin
unmap(&self, _irq_domain: &Arc<IrqDomain>, _virq: IrqNumber)293e2841179SLoGin fn unmap(&self, _irq_domain: &Arc<IrqDomain>, _virq: IrqNumber) {
294e2841179SLoGin todo!()
295e2841179SLoGin }
296e2841179SLoGin }
297