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