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