irqdomain.rs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704
  1. use core::fmt::Debug;
  2. use alloc::{
  3. string::{String, ToString},
  4. sync::{Arc, Weak},
  5. vec::Vec,
  6. };
  7. use hashbrown::HashMap;
  8. use log::{info, warn};
  9. use system_error::SystemError;
  10. use crate::{
  11. driver::{base::device::Device, open_firmware::device_node::DeviceNode},
  12. exception::{irqdata::IrqLineStatus, irqdesc::irq_desc_manager, manage::irq_manager},
  13. libs::{
  14. rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
  15. spinlock::SpinLock,
  16. },
  17. };
  18. use super::{
  19. dummychip::no_irq_chip,
  20. irqchip::{IrqChip, IrqChipData, IrqChipGeneric, IrqGcFlags},
  21. irqdata::{IrqData, IrqHandlerData},
  22. irqdesc::{IrqDesc, IrqFlowHandler},
  23. HardwareIrqNumber, IrqNumber,
  24. };
  25. static mut IRQ_DOMAIN_MANAGER: Option<Arc<IrqDomainManager>> = None;
  26. /// 获取中断域管理器的引用
  27. #[inline(always)]
  28. pub fn irq_domain_manager() -> &'static Arc<IrqDomainManager> {
  29. unsafe { IRQ_DOMAIN_MANAGER.as_ref().unwrap() }
  30. }
  31. pub(super) fn irq_domain_manager_init() {
  32. unsafe {
  33. IRQ_DOMAIN_MANAGER = Some(Arc::new(IrqDomainManager::new()));
  34. }
  35. }
  36. /// 中断域管理器
  37. pub struct IrqDomainManager {
  38. domains: SpinLock<Vec<Arc<IrqDomain>>>,
  39. inner: RwLock<InnerIrqDomainManager>,
  40. }
  41. impl IrqDomainManager {
  42. pub fn new() -> IrqDomainManager {
  43. IrqDomainManager {
  44. domains: SpinLock::new(Vec::new()),
  45. inner: RwLock::new(InnerIrqDomainManager {
  46. default_domain: None,
  47. }),
  48. }
  49. }
  50. /// 创建一个新的线性映射的irqdomain, 并将其添加到irqdomain管理器中
  51. ///
  52. /// 创建的irqdomain,中断号是线性的,即从0开始,依次递增
  53. ///
  54. /// ## 参数
  55. ///
  56. /// - `name` - 中断域的名字
  57. /// - `ops` - 中断域的操作
  58. /// - `irq_size` - 中断号的数量
  59. #[allow(dead_code)]
  60. pub fn create_and_add_linear(
  61. &self,
  62. name: String,
  63. ops: &'static dyn IrqDomainOps,
  64. irq_size: u32,
  65. ) -> Option<Arc<IrqDomain>> {
  66. self.create_and_add(
  67. name,
  68. ops,
  69. IrqNumber::new(0),
  70. HardwareIrqNumber::new(0),
  71. irq_size,
  72. )
  73. }
  74. /// 创建一个新的irqdomain, 并将其添加到irqdomain管理器中
  75. ///
  76. /// ## 参数
  77. ///
  78. /// - `name` - 中断域的名字
  79. /// - `ops` - 中断域的操作
  80. /// - `first_irq` - 起始软件中断号
  81. /// - `first_hwirq` - 起始硬件中断号
  82. /// - `irq_size` - 中断号的数量
  83. ///
  84. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdomain.c?fi=__irq_domain_add#139
  85. pub fn create_and_add(
  86. &self,
  87. name: String,
  88. ops: &'static dyn IrqDomainOps,
  89. first_irq: IrqNumber,
  90. first_hwirq: HardwareIrqNumber,
  91. irq_size: u32,
  92. ) -> Option<Arc<IrqDomain>> {
  93. let domain = IrqDomain::new(
  94. None,
  95. Some(name),
  96. ops,
  97. IrqDomainFlags::NAME_ALLOCATED,
  98. IrqDomainBusToken::Any,
  99. first_irq + irq_size,
  100. first_hwirq + irq_size,
  101. )?;
  102. self.add_domain(domain.clone());
  103. return Some(domain);
  104. }
  105. fn add_domain(&self, domain: Arc<IrqDomain>) {
  106. self.domains.lock_irqsave().push(domain);
  107. }
  108. #[allow(dead_code)]
  109. pub fn remove_domain(&self, domain: &Arc<IrqDomain>) {
  110. let mut domains = self.domains.lock_irqsave();
  111. let index = domains
  112. .iter()
  113. .position(|x| Arc::ptr_eq(x, domain))
  114. .expect("domain not found");
  115. domains.remove(index);
  116. }
  117. /// 获取默认的中断域
  118. #[allow(dead_code)]
  119. pub fn default_domain(&self) -> Option<Arc<IrqDomain>> {
  120. self.inner.read().default_domain.clone()
  121. }
  122. /// 设置默认的中断域
  123. ///
  124. /// 在创建IRQ映射的时候,如果没有指定中断域,就会使用默认的中断域
  125. pub fn set_default_domain(&self, domain: Arc<IrqDomain>) {
  126. self.inner.write_irqsave().default_domain = Some(domain);
  127. }
  128. /// 将指定范围的硬件中断号与软件中断号一一对应的关联起来
  129. ///
  130. /// ## 参数
  131. ///
  132. /// - `domain` - 中断域
  133. /// - `first_irq` - 起始软件中断号
  134. /// - `first_hwirq` - 起始硬件中断号
  135. /// - `count` - 数量
  136. pub fn domain_associate_many(
  137. &self,
  138. domain: &Arc<IrqDomain>,
  139. first_irq: IrqNumber,
  140. first_hwirq: HardwareIrqNumber,
  141. count: u32,
  142. ) {
  143. for i in 0..count {
  144. if let Err(e) = self.domain_associate(domain, first_irq + i, first_hwirq + i) {
  145. warn!("domain associate failed: {:?}, domain '{:?}' didn't like hwirq {} to virq {} mapping.", e, domain.name(), (first_hwirq + i).data(), (first_irq + i).data());
  146. }
  147. }
  148. }
  149. /// 将一个硬件中断号与一个软件中断号关联起来
  150. ///
  151. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdomain.c#562
  152. pub fn domain_associate(
  153. &self,
  154. domain: &Arc<IrqDomain>,
  155. irq: IrqNumber,
  156. hwirq: HardwareIrqNumber,
  157. ) -> Result<(), SystemError> {
  158. if hwirq >= domain.revmap.read_irqsave().hwirq_max {
  159. warn!(
  160. "hwirq {} is out of range for domain {:?}",
  161. hwirq.data(),
  162. domain.name()
  163. );
  164. return Err(SystemError::EINVAL);
  165. }
  166. let irq_data = irq_desc_manager()
  167. .lookup(irq)
  168. .ok_or_else(|| {
  169. warn!("irq_desc not found for irq {}", irq.data());
  170. SystemError::EINVAL
  171. })?
  172. .irq_data();
  173. if irq_data.domain().is_some() {
  174. warn!(
  175. "irq {} is already associated with domain {:?}",
  176. irq.data(),
  177. irq_data.domain().unwrap().name()
  178. );
  179. return Err(SystemError::EINVAL);
  180. }
  181. let mut irq_data_guard = irq_data.inner();
  182. irq_data_guard.set_hwirq(hwirq);
  183. irq_data_guard.set_domain(Some(domain.clone()));
  184. drop(irq_data_guard);
  185. let r = domain.ops.map(domain, hwirq, irq);
  186. if let Err(e) = r {
  187. if e != SystemError::ENOSYS {
  188. if e != SystemError::EPERM {
  189. info!("domain associate failed: {:?}, domain '{:?}' didn't like hwirq {} to virq {} mapping.", e, domain.name(), hwirq.data(), irq.data());
  190. }
  191. let mut irq_data_guard = irq_data.inner();
  192. irq_data_guard.set_domain(None);
  193. irq_data_guard.set_hwirq(HardwareIrqNumber::new(0));
  194. return Err(e);
  195. }
  196. }
  197. if domain.name().is_none() {
  198. let chip = irq_data.chip_info_read_irqsave().chip();
  199. domain.set_name(chip.name().to_string());
  200. }
  201. self.irq_domain_set_mapping(domain, hwirq, irq_data);
  202. irq_manager().irq_clear_status_flags(irq, IrqLineStatus::IRQ_NOREQUEST)?;
  203. return Ok(());
  204. }
  205. fn irq_domain_set_mapping(
  206. &self,
  207. domain: &Arc<IrqDomain>,
  208. hwirq: HardwareIrqNumber,
  209. irq_data: Arc<IrqData>,
  210. ) {
  211. if domain.no_map() {
  212. return;
  213. }
  214. domain.revmap.write_irqsave().insert(hwirq, irq_data);
  215. }
  216. /// 递归调用 domain_ops->activate 以激活中断
  217. ///
  218. /// ## 参数
  219. ///
  220. /// - irq_data: 与中断关联的最外层 irq_data
  221. /// - reserve: 如果为true,则仅预留一个中断向量,而不是分配一个
  222. ///
  223. /// 这是调用 domain_ops->activate 以编程中断控制器的第二步,以便中断实际上可以被传递。
  224. pub fn activate_irq(&self, irq_data: &Arc<IrqData>, reserve: bool) -> Result<(), SystemError> {
  225. let mut r = Ok(());
  226. // debug!(
  227. // "activate_irq: irq_data.common_data().status().is_activated()={}",
  228. // irq_data.common_data().status().is_activated()
  229. // );
  230. if !irq_data.common_data().status().is_activated() {
  231. r = self.do_activate_irq(Some(irq_data.clone()), reserve);
  232. }
  233. if r.is_err() {
  234. irq_data.common_data().status().set_activated();
  235. }
  236. return r;
  237. }
  238. #[inline(never)]
  239. fn do_activate_irq(
  240. &self,
  241. irq_data: Option<Arc<IrqData>>,
  242. reserve: bool,
  243. ) -> Result<(), SystemError> {
  244. let mut r = Ok(());
  245. if let Some(irq_data) = irq_data {
  246. // debug!("do_activate_irq: irq_data={:?}", irq_data);
  247. if let Some(domain) = irq_data.domain() {
  248. // debug!("do_activate_irq: domain={:?}", domain.name());
  249. let parent_data = irq_data.parent_data().and_then(|x| x.upgrade());
  250. if let Some(parent_data) = parent_data.clone() {
  251. r = self.do_activate_irq(Some(parent_data), reserve);
  252. }
  253. if r.is_err() {
  254. let tmpr = domain.ops.activate(&domain, &irq_data, reserve);
  255. if let Err(e) = tmpr {
  256. if e != SystemError::ENOSYS && parent_data.is_some() {
  257. self.do_deactivate_irq(parent_data);
  258. }
  259. }
  260. }
  261. }
  262. }
  263. return r;
  264. }
  265. #[allow(clippy::only_used_in_recursion)]
  266. fn do_deactivate_irq(&self, irq_data: Option<Arc<IrqData>>) {
  267. if let Some(irq_data) = irq_data {
  268. if let Some(domain) = irq_data.domain() {
  269. domain.ops.deactivate(&domain, &irq_data);
  270. let pp = irq_data.parent_data().and_then(|x| x.upgrade());
  271. if pp.is_some() {
  272. self.do_deactivate_irq(pp);
  273. }
  274. }
  275. }
  276. }
  277. /// `irq_domain_set_info` - 在 @domain 中为 @virq 设置完整的数据
  278. ///
  279. /// ## 参数
  280. ///
  281. /// - `domain`: 要匹配的中断域
  282. /// - `virq`: IRQ号
  283. /// - `hwirq`: 硬件中断号
  284. /// - `chip`: 相关的中断芯片
  285. /// - `chip_data`: 相关的中断芯片数据
  286. /// - `handler`: 中断流处理器
  287. /// - `handler_data`: 中断流处理程序数据
  288. /// - `handler_name`: 中断处理程序名称
  289. #[allow(clippy::too_many_arguments)]
  290. #[allow(dead_code)]
  291. pub fn domain_set_info(
  292. &self,
  293. domain: &Arc<IrqDomain>,
  294. virq: IrqNumber,
  295. hwirq: HardwareIrqNumber,
  296. chip: Arc<dyn IrqChip>,
  297. chip_data: Option<Arc<dyn IrqChipData>>,
  298. flow_handler: &'static dyn IrqFlowHandler,
  299. handler_data: Option<Arc<dyn IrqHandlerData>>,
  300. handler_name: Option<String>,
  301. ) {
  302. let r = self.domain_set_hwirq_and_chip(domain, virq, hwirq, Some(chip), chip_data);
  303. if r.is_err() {
  304. return;
  305. }
  306. irq_manager().__irq_set_handler(virq, flow_handler, false, handler_name);
  307. irq_manager().irq_set_handler_data(virq, handler_data).ok();
  308. }
  309. /// `domain_set_hwirq_and_chip` - 在 @domain 中为 @virq 设置 hwirq 和 irqchip
  310. ///
  311. /// ## 参数
  312. ///
  313. /// - `domain`: 要匹配的中断域
  314. /// - `virq`: IRQ号
  315. /// - `hwirq`: hwirq号
  316. /// - `chip`: 相关的中断芯片
  317. /// - `chip_data`: 相关的芯片数据
  318. pub fn domain_set_hwirq_and_chip(
  319. &self,
  320. domain: &Arc<IrqDomain>,
  321. virq: IrqNumber,
  322. hwirq: HardwareIrqNumber,
  323. chip: Option<Arc<dyn IrqChip>>,
  324. chip_data: Option<Arc<dyn IrqChipData>>,
  325. ) -> Result<(), SystemError> {
  326. let irq_data: Arc<IrqData> = self
  327. .domain_get_irq_data(domain, virq)
  328. .ok_or(SystemError::ENOENT)?;
  329. let mut inner = irq_data.inner();
  330. let mut chip_info = irq_data.chip_info_write_irqsave();
  331. inner.set_hwirq(hwirq);
  332. if let Some(chip) = chip {
  333. chip_info.set_chip(Some(chip));
  334. } else {
  335. chip_info.set_chip(Some(no_irq_chip()));
  336. };
  337. chip_info.set_chip_data(chip_data);
  338. return Ok(());
  339. }
  340. /// `irq_domain_get_irq_data` - 获取与 @virq 和 @domain 关联的 irq_data
  341. ///
  342. /// ## 参数
  343. ///
  344. /// - `domain`: 要匹配的域
  345. /// - `virq`: 要获取 irq_data 的IRQ号
  346. pub fn domain_get_irq_data(
  347. &self,
  348. domain: &Arc<IrqDomain>,
  349. virq: IrqNumber,
  350. ) -> Option<Arc<IrqData>> {
  351. let desc = irq_desc_manager().lookup(virq)?;
  352. let mut irq_data = Some(desc.irq_data());
  353. while irq_data.is_some() {
  354. let dt = irq_data.unwrap();
  355. if dt.domain().is_some() && Arc::ptr_eq(dt.domain().as_ref().unwrap(), domain) {
  356. return Some(dt);
  357. }
  358. irq_data = dt.parent_data().and_then(|x| x.upgrade());
  359. }
  360. return None;
  361. }
  362. /// `resolve_irq_mapping` - 从硬件中断号找到中断号。
  363. ///
  364. /// ## 参数
  365. ///
  366. /// - `domain`: 拥有此硬件中断的域
  367. /// - `hwirq`: 该域空间中的硬件中断号
  368. /// - `irq`: 如果需要,可选的指针以返回Linux中断
  369. ///
  370. /// ## 返回
  371. ///
  372. /// 返回一个元组,包含中断描述符和中断号
  373. pub fn resolve_irq_mapping(
  374. &self,
  375. mut domain: Option<Arc<IrqDomain>>,
  376. hwirq: HardwareIrqNumber,
  377. ) -> Result<(Arc<IrqDesc>, IrqNumber), SystemError> {
  378. if domain.is_none() {
  379. domain = Some(self.default_domain().ok_or(SystemError::EINVAL)?);
  380. }
  381. let domain = domain.unwrap();
  382. if domain.no_map() {
  383. if hwirq < domain.revmap_read_irqsave().hwirq_max {
  384. let irq_desc = irq_desc_manager()
  385. .lookup(IrqNumber::new(hwirq.data()))
  386. .ok_or(SystemError::EINVAL)?;
  387. if irq_desc.irq_data().hardware_irq() == hwirq {
  388. let irq = irq_desc.irq_data().irq();
  389. return Ok((irq_desc, irq));
  390. }
  391. }
  392. return Err(SystemError::EINVAL);
  393. }
  394. let revmap = domain.revmap_read_irqsave();
  395. let irq_data = revmap.lookup(hwirq).ok_or(SystemError::EINVAL)?;
  396. let irq_desc = irq_data.irq_desc().unwrap();
  397. return Ok((irq_desc, irq_data.irq()));
  398. }
  399. }
  400. struct InnerIrqDomainManager {
  401. default_domain: Option<Arc<IrqDomain>>,
  402. }
  403. /// 中断域
  404. ///
  405. /// 用于把硬件中断号翻译为软件中断号的映射的对象
  406. ///
  407. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdomain.h#164
  408. #[allow(dead_code)]
  409. #[derive(Debug)]
  410. pub struct IrqDomain {
  411. /// 中断域的名字 (二选一)
  412. name: Option<&'static str>,
  413. allocated_name: SpinLock<Option<String>>,
  414. /// 中断域的操作
  415. ops: &'static dyn IrqDomainOps,
  416. inner: SpinLock<InnerIrqDomain>,
  417. /// 中断号反向映射
  418. revmap: RwLock<IrqDomainRevMap>,
  419. }
  420. #[allow(dead_code)]
  421. #[derive(Debug)]
  422. struct InnerIrqDomain {
  423. /// this field not touched by the core code
  424. host_data: Option<Arc<dyn IrqChipData>>,
  425. /// host per irq_domain flags
  426. flags: IrqDomainFlags,
  427. /// The number of mapped interrupts
  428. mapcount: u32,
  429. bus_token: IrqDomainBusToken,
  430. /// 指向 generic chip 列表的指针。
  431. /// 有一个辅助函数用于为中断控制器驱动程序设置一个或
  432. /// 多个 generic chip,该函数使用此指针并依赖于 generic chip 库。
  433. generic_chip: Option<Arc<IrqDomainChipGeneric>>,
  434. /// Pointer to a device that the domain represent, and that will be
  435. /// used for power management purposes.
  436. device: Option<Arc<dyn Device>>,
  437. /// Pointer to parent irq_domain to support hierarchy irq_domains
  438. parent: Option<Weak<IrqDomain>>,
  439. }
  440. impl IrqDomain {
  441. #[allow(dead_code)]
  442. pub fn new(
  443. name: Option<&'static str>,
  444. allocated_name: Option<String>,
  445. ops: &'static dyn IrqDomainOps,
  446. flags: IrqDomainFlags,
  447. bus_token: IrqDomainBusToken,
  448. irq_max: IrqNumber,
  449. hwirq_max: HardwareIrqNumber,
  450. ) -> Option<Arc<Self>> {
  451. if name.is_none() && allocated_name.is_none() {
  452. return None;
  453. }
  454. let x = IrqDomain {
  455. name,
  456. allocated_name: SpinLock::new(allocated_name),
  457. ops,
  458. inner: SpinLock::new(InnerIrqDomain {
  459. host_data: None,
  460. flags,
  461. mapcount: 0,
  462. bus_token,
  463. generic_chip: None,
  464. device: None,
  465. parent: None,
  466. }),
  467. revmap: RwLock::new(IrqDomainRevMap {
  468. map: HashMap::new(),
  469. hwirq_max,
  470. irq_max,
  471. }),
  472. };
  473. return Some(Arc::new(x));
  474. }
  475. /// 中断域是否不对中断号进行转换
  476. pub fn no_map(&self) -> bool {
  477. self.inner
  478. .lock_irqsave()
  479. .flags
  480. .contains(IrqDomainFlags::NO_MAP)
  481. }
  482. #[allow(dead_code)]
  483. fn revmap_read_irqsave(&self) -> RwLockReadGuard<IrqDomainRevMap> {
  484. self.revmap.read_irqsave()
  485. }
  486. #[allow(dead_code)]
  487. fn revmap_write_irqsave(&self) -> RwLockWriteGuard<IrqDomainRevMap> {
  488. self.revmap.write_irqsave()
  489. }
  490. #[allow(dead_code)]
  491. fn set_hwirq_max(&self, hwirq_max: HardwareIrqNumber) {
  492. self.revmap_write_irqsave().hwirq_max = hwirq_max;
  493. }
  494. pub fn name(&self) -> Option<String> {
  495. if let Some(name) = self.name {
  496. return Some(name.to_string());
  497. }
  498. return self.allocated_name.lock_irqsave().clone();
  499. }
  500. pub fn set_name(&self, name: String) {
  501. *self.allocated_name.lock_irqsave() = Some(name);
  502. }
  503. /// The number of mapped interrupts
  504. #[allow(dead_code)]
  505. pub fn map_count(&self) -> u32 {
  506. self.revmap_read_irqsave().map.len() as u32
  507. }
  508. #[allow(dead_code)]
  509. pub fn host_data(&self) -> Option<Arc<dyn IrqChipData>> {
  510. self.inner.lock_irqsave().host_data.clone()
  511. }
  512. #[allow(dead_code)]
  513. pub fn set_host_data(&self, host_data: Option<Arc<dyn IrqChipData>>) {
  514. self.inner.lock_irqsave().host_data = host_data;
  515. }
  516. }
  517. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdomain.h#190
  518. #[allow(dead_code)]
  519. #[derive(Debug)]
  520. struct IrqDomainRevMap {
  521. map: HashMap<HardwareIrqNumber, Arc<IrqData>>,
  522. hwirq_max: HardwareIrqNumber,
  523. irq_max: IrqNumber,
  524. }
  525. impl IrqDomainRevMap {
  526. fn insert(&mut self, hwirq: HardwareIrqNumber, irq_data: Arc<IrqData>) {
  527. self.map.insert(hwirq, irq_data);
  528. }
  529. #[allow(dead_code)]
  530. fn remove(&mut self, hwirq: HardwareIrqNumber) {
  531. self.map.remove(&hwirq);
  532. }
  533. #[allow(dead_code)]
  534. fn lookup(&self, hwirq: HardwareIrqNumber) -> Option<Arc<IrqData>> {
  535. self.map.get(&hwirq).cloned()
  536. }
  537. }
  538. bitflags! {
  539. pub struct IrqDomainFlags: u32 {
  540. /// Irq domain is hierarchical
  541. const HIERARCHY = (1 << 0);
  542. /// Irq domain name was allocated dynamically
  543. const NAME_ALLOCATED = (1 << 1);
  544. /// Irq domain is an IPI domain with virq per cpu
  545. const IPI_PER_CPU = (1 << 2);
  546. /// Irq domain is an IPI domain with single virq
  547. const IPI_SINGLE = (1 << 3);
  548. /// Irq domain implements MSIs
  549. const MSI = (1 << 4);
  550. /// Irq domain implements MSI remapping
  551. const MSI_REMAP = (1 << 5);
  552. /// Quirk to handle MSI implementations which do not provide masking
  553. const MSI_NOMASK_QUIRK = (1 << 6);
  554. /// Irq domain doesn't translate anything
  555. const NO_MAP = (1 << 7);
  556. /// Flags starting from IRQ_DOMAIN_FLAG_NONCORE are reserved
  557. /// for implementation specific purposes and ignored by the core code
  558. const NONCORE = (1 << 16);
  559. }
  560. }
  561. /// 如果多个域有相同的设备节点,但服务于不同的目的(例如,一个域用于PCI/MSI,另一个用于有线IRQs),
  562. /// 它们可以使用特定于总线的token进行区分。预计大多数域只会携带`DomainBusAny`。
  563. ///
  564. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdomain.h#78
  565. #[allow(dead_code)]
  566. #[derive(Debug, Clone, Copy, PartialEq, Eq)]
  567. pub enum IrqDomainBusToken {
  568. Any = 0,
  569. Wired,
  570. GenericMsi,
  571. PciMsi,
  572. PlatformMsi,
  573. Nexus,
  574. Ipi,
  575. FslMcMsi,
  576. TiSciIntaMsi,
  577. Wakeup,
  578. VmdMsi,
  579. }
  580. /// IrqDomain的操作方法
  581. ///
  582. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdomain.h#107
  583. pub trait IrqDomainOps: Debug + Send + Sync {
  584. /// 匹配一个中断控制器设备节点到一个主机。
  585. #[allow(dead_code)]
  586. fn match_node(
  587. &self,
  588. _irq_domain: &Arc<IrqDomain>,
  589. _device_node: &Arc<DeviceNode>,
  590. _bus_token: IrqDomainBusToken,
  591. ) -> bool {
  592. false
  593. }
  594. /// 创建或更新一个虚拟中断号与一个硬件中断号之间的映射。
  595. /// 对于给定的映射,这只会被调用一次。
  596. ///
  597. /// 如果没有实现这个方法,那么就会返回`ENOSYS`
  598. fn map(
  599. &self,
  600. _irq_domain: &Arc<IrqDomain>,
  601. _hwirq: HardwareIrqNumber,
  602. _virq: IrqNumber,
  603. ) -> Result<(), SystemError> {
  604. Err(SystemError::ENOSYS)
  605. }
  606. /// 删除一个虚拟中断号与一个硬件中断号之间的映射。
  607. #[allow(dead_code)]
  608. fn unmap(&self, irq_domain: &Arc<IrqDomain>, virq: IrqNumber);
  609. fn activate(
  610. &self,
  611. _domain: &Arc<IrqDomain>,
  612. _irq_data: &Arc<IrqData>,
  613. _reserve: bool,
  614. ) -> Result<(), SystemError> {
  615. Err(SystemError::ENOSYS)
  616. }
  617. fn deactivate(&self, _domain: &Arc<IrqDomain>, _irq_data: &Arc<IrqData>) {}
  618. }
  619. #[allow(dead_code)]
  620. #[derive(Debug)]
  621. pub struct IrqDomainChipGeneric {
  622. inner: SpinLock<InnerIrqDomainChipGeneric>,
  623. }
  624. #[allow(dead_code)]
  625. #[derive(Debug)]
  626. struct InnerIrqDomainChipGeneric {
  627. irqs_per_chip: u32,
  628. flags_to_clear: IrqGcFlags,
  629. flags_to_set: IrqGcFlags,
  630. gc_flags: IrqGcFlags,
  631. gc: Vec<Arc<IrqChipGeneric>>,
  632. }