lapic_vector.rs 7.9 KB

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