xref: /DragonOS/kernel/src/exception/irqdesc.rs (revision d2b28acb4d1f160779b25d76afca49ed60ad5d48)
1 use core::{any::Any, fmt::Debug};
2 
3 use alloc::{
4     collections::{btree_map, BTreeMap},
5     string::{String, ToString},
6     sync::{Arc, Weak},
7     vec::Vec,
8 };
9 use system_error::SystemError;
10 
11 use crate::{
12     arch::CurrentIrqArch,
13     driver::base::{
14         device::DeviceId,
15         kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
16         kset::KSet,
17     },
18     filesystem::kernfs::KernFSInode,
19     libs::{
20         rwlock::{RwLockReadGuard, RwLockWriteGuard},
21         spinlock::{SpinLock, SpinLockGuard},
22     },
23     process::ProcessControlBlock,
24 };
25 
26 use super::{
27     dummychip::no_irq_chip,
28     handle::bad_irq_handler,
29     irqdata::{IrqCommonData, IrqData, IrqStatus},
30     sysfs::{irq_sysfs_del, IrqKObjType},
31     HardwareIrqNumber, InterruptArch, IrqNumber,
32 };
33 
34 /// 中断流处理程序
35 pub trait IrqFlowHandler: Debug + Send + Sync {
36     fn handle(&self, irq_desc: &Arc<IrqDesc>);
37 }
38 
39 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdesc.h#55
40 #[derive(Debug)]
41 pub struct IrqDesc {
42     inner: SpinLock<InnerIrqDesc>,
43 
44     handler: SpinLock<Option<&'static dyn IrqFlowHandler>>,
45 
46     kobj_state: LockedKObjectState,
47 }
48 
49 impl IrqDesc {
50     #[inline(never)]
51     pub fn new(irq: IrqNumber, name: Option<String>, irqd_flags: IrqStatus) -> Arc<Self> {
52         // 初始化的过程参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#392
53         let common_data = Arc::new(IrqCommonData::new());
54         let irq_data = Arc::new(IrqData::new(
55             irq,
56             HardwareIrqNumber::new(irq.data()),
57             common_data.clone(),
58             no_irq_chip(),
59         ));
60 
61         irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
62         common_data.irqd_set(IrqStatus::IRQD_IRQ_MASKED);
63 
64         let irq_desc = IrqDesc {
65             inner: SpinLock::new(InnerIrqDesc {
66                 common_data,
67                 irq_data,
68                 desc_internal_state: IrqDescState::empty(),
69                 actions: Vec::new(),
70                 name,
71                 parent_irq: None,
72                 depth: 1,
73                 wake_depth: 0,
74                 kern_inode: None,
75                 kset: None,
76                 parent_kobj: None,
77             }),
78             handler: SpinLock::new(None),
79             kobj_state: LockedKObjectState::new(Some(KObjectState::INITIALIZED)),
80         };
81 
82         irq_desc.set_handler(bad_irq_handler());
83         irq_desc.inner().irq_data.irqd_set(irqd_flags);
84 
85         return Arc::new(irq_desc);
86     }
87 
88     pub fn set_handler(&self, handler: &'static dyn IrqFlowHandler) {
89         let mut guard = self.handler.lock_irqsave();
90         *guard = Some(handler);
91     }
92 
93     fn inner(&self) -> SpinLockGuard<InnerIrqDesc> {
94         self.inner.lock_irqsave()
95     }
96 
97     pub fn actions(&self) -> Vec<Arc<IrqAction>> {
98         self.inner().actions.clone()
99     }
100 
101     pub fn irq(&self) -> IrqNumber {
102         self.inner().irq_data.irq()
103     }
104 
105     pub fn hardware_irq(&self) -> HardwareIrqNumber {
106         self.inner().irq_data.hardware_irq()
107     }
108 
109     pub fn irq_data(&self) -> Arc<IrqData> {
110         self.inner().irq_data.clone()
111     }
112 
113     /// 标记当前irq描述符已经被添加到sysfs
114     pub fn mark_in_sysfs(&self) {
115         self.inner()
116             .desc_internal_state
117             .insert(IrqDescState::IRQS_SYSFS);
118     }
119 
120     pub fn mark_not_in_sysfs(&self) {
121         self.inner()
122             .desc_internal_state
123             .remove(IrqDescState::IRQS_SYSFS);
124     }
125 
126     /// 判断当前描述符是否已经添加到了sysfs
127     pub fn in_sysfs(&self) -> bool {
128         self.inner()
129             .desc_internal_state
130             .contains(IrqDescState::IRQS_SYSFS)
131     }
132 
133     pub fn name(&self) -> Option<String> {
134         self.inner().name.clone()
135     }
136 }
137 
138 #[allow(dead_code)]
139 #[derive(Debug)]
140 struct InnerIrqDesc {
141     /// per irq and chip data passed down to chip functions
142     common_data: Arc<IrqCommonData>,
143     irq_data: Arc<IrqData>,
144     actions: Vec<Arc<IrqAction>>,
145     name: Option<String>,
146     parent_irq: Option<IrqNumber>,
147     /// nested irq disables
148     depth: u32,
149     /// nested wake enables
150     wake_depth: u32,
151     desc_internal_state: IrqDescState,
152 
153     kern_inode: Option<Arc<KernFSInode>>,
154     kset: Option<Arc<KSet>>,
155     parent_kobj: Option<Weak<dyn KObject>>,
156 }
157 
158 impl KObject for IrqDesc {
159     fn as_any_ref(&self) -> &dyn Any {
160         self
161     }
162 
163     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
164         self.inner().kern_inode = inode;
165     }
166 
167     fn inode(&self) -> Option<Arc<KernFSInode>> {
168         self.inner().kern_inode.clone()
169     }
170 
171     fn parent(&self) -> Option<Weak<dyn KObject>> {
172         self.inner().parent_kobj.clone()
173     }
174 
175     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
176         self.inner().parent_kobj = parent;
177     }
178 
179     fn kset(&self) -> Option<Arc<KSet>> {
180         self.inner().kset.clone()
181     }
182 
183     fn set_kset(&self, kset: Option<Arc<KSet>>) {
184         self.inner().kset = kset;
185     }
186 
187     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
188         Some(&IrqKObjType)
189     }
190 
191     fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {}
192 
193     fn name(&self) -> String {
194         self.inner().irq_data.irq().data().to_string()
195     }
196 
197     fn set_name(&self, _name: String) {}
198 
199     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
200         self.kobj_state.read()
201     }
202 
203     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
204         self.kobj_state.write()
205     }
206 
207     fn set_kobj_state(&self, state: KObjectState) {
208         *self.kobj_state_mut() = state;
209     }
210 }
211 
212 bitflags! {
213     /// Bit masks for desc->desc_internal_state
214     struct IrqDescState: u32 {
215         /// autodetection in progress
216         const IRQS_AUTODETECT = 0x00000001;
217         /// was disabled due to spurious interrupt detection
218         const IRQS_SPURIOUS_DISABLED = 0x00000002;
219         /// polling in progress
220         const IRQS_POLL_INPROGRESS = 0x00000008;
221         /// irq is not unmasked in primary handler
222         const IRQS_ONESHOT = 0x00000020;
223         /// irq is replayed
224         const IRQS_REPLAY = 0x00000040;
225         /// irq is waiting
226         const IRQS_WAITING = 0x00000080;
227         /// irq is pending and replayed later
228         const IRQS_PENDING = 0x00000200;
229         /// irq is suspended
230         const IRQS_SUSPENDED = 0x00000800;
231         /// irq line is used to deliver NMIs
232         const IRQS_NMI = 0x00002000;
233         /// descriptor has been added to sysfs
234         const IRQS_SYSFS = 0x00004000;
235     }
236 }
237 
238 /// 每个中断的响应动作的描述符
239 /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/interrupt.h#118
240 #[allow(dead_code)]
241 #[derive(Debug)]
242 pub struct IrqAction {
243     inner: SpinLock<InnerIrqAction>,
244 }
245 
246 impl IrqAction {
247     #[allow(dead_code)]
248     pub fn new(
249         irq: IrqNumber,
250         name: String,
251         handler: Option<&'static dyn IrqFlowHandler>,
252     ) -> Arc<Self> {
253         let action = IrqAction {
254             inner: SpinLock::new(InnerIrqAction {
255                 dev_id: None,
256                 handler,
257                 thread_fn: None,
258                 thread: None,
259                 secondary: None,
260                 irq,
261                 flags: IrqHandleFlags::empty(),
262                 name,
263             }),
264         };
265 
266         return Arc::new(action);
267     }
268 
269     pub fn name(&self) -> String {
270         self.inner().name.clone()
271     }
272 
273     fn inner(&self) -> SpinLockGuard<InnerIrqAction> {
274         self.inner.lock_irqsave()
275     }
276 }
277 
278 #[allow(dead_code)]
279 #[derive(Debug)]
280 struct InnerIrqAction {
281     /// cookie to identify the device
282     dev_id: Option<DeviceId>,
283     /// 中断处理程序
284     handler: Option<&'static dyn IrqFlowHandler>,
285     /// interrupt handler function for threaded interrupts
286     thread_fn: Option<&'static dyn IrqFlowHandler>,
287     /// thread pointer for threaded interrupts
288     thread: Option<Arc<ProcessControlBlock>>,
289     /// pointer to secondary irqaction (force threading)
290     secondary: Option<Arc<IrqAction>>,
291     /// 中断号
292     irq: IrqNumber,
293     flags: IrqHandleFlags,
294     /// name of the device
295     name: String,
296 }
297 
298 // 定义IrqFlags位标志
299 bitflags! {
300     /// 这些标志仅由内核在中断处理例程中使用。
301     pub struct IrqHandleFlags: u32 {
302         /// IRQF_SHARED - 允许多个设备共享中断
303         const IRQF_SHARED = 0x00000080;
304         /// IRQF_PROBE_SHARED - 当预期出现共享不匹配时,由调用者设置
305         const IRQF_PROBE_SHARED = 0x00000100;
306         /// IRQF_TIMER - 标记此中断为定时器中断
307         const __IRQF_TIMER = 0x00000200;
308         /// IRQF_PERCPU - 中断是每个CPU的
309         const IRQF_PERCPU = 0x00000400;
310         /// IRQF_NOBALANCING - 将此中断从中断平衡中排除
311         const IRQF_NOBALANCING = 0x00000800;
312         /// IRQF_IRQPOLL - 中断用于轮询(出于性能原因,只有在共享中断中首次注册的中断会被考虑)
313         const IRQF_IRQPOLL = 0x00001000;
314         /// IRQF_ONESHOT - 在硬中断处理程序完成后,不会重新启用中断。由需要在运行线程处理程序之前保持中断线路禁用的线程中断使用。
315         const IRQF_ONESHOT = 0x00002000;
316         /// IRQF_NO_SUSPEND - 在挂起期间不禁用此IRQ。不能保证此中断会从挂起状态唤醒系统。
317         const IRQF_NO_SUSPEND = 0x00004000;
318         /// IRQF_FORCE_RESUME - 即使设置了IRQF_NO_SUSPEND,也强制在恢复时启用它
319         const IRQF_FORCE_RESUME = 0x00008000;
320         /// IRQF_NO_THREAD - 中断不能被线程化
321         const IRQF_NO_THREAD = 0x00010000;
322         /// IRQF_EARLY_RESUME - 在syscore而不是在设备恢复时间早期恢复IRQ。
323         const IRQF_EARLY_RESUME = 0x00020000;
324         /// IRQF_COND_SUSPEND - 如果IRQ与NO_SUSPEND用户共享,则在挂起中断后执行此中断处理程序。对于系统唤醒设备用户,需要在他们的中断处理程序中实现唤醒检测。
325         const IRQF_COND_SUSPEND = 0x00040000;
326         /// IRQF_NO_AUTOEN - 当用户请求时,不会自动启用IRQ或NMI。用户稍后会通过enable_irq()或enable_nmi()显式启用它。
327         const IRQF_NO_AUTOEN = 0x00080000;
328         /// IRQF_NO_DEBUG - 从IPI和类似处理程序的逃逸检测中排除,取决于IRQF_PERCPU。
329         const IRQF_NO_DEBUG = 0x00100000;
330         const IRQF_TIMER = Self::__IRQF_TIMER.bits | Self::IRQF_NO_SUSPEND.bits | Self::IRQF_NO_THREAD.bits;
331     }
332 }
333 
334 #[inline(never)]
335 pub(super) fn early_irq_init() -> Result<(), SystemError> {
336     let irqcnt = CurrentIrqArch::probe_total_irq_num();
337     let mut manager = IrqDescManager::new();
338     for i in 0..irqcnt {
339         let irq_desc = IrqDesc::new(IrqNumber::new(i), None, IrqStatus::empty());
340         manager.insert(IrqNumber::new(i), irq_desc);
341     }
342 
343     unsafe {
344         IRQ_DESC_MANAGER = Some(manager);
345     }
346 
347     return CurrentIrqArch::arch_early_irq_init();
348 }
349 
350 static mut IRQ_DESC_MANAGER: Option<IrqDescManager> = None;
351 
352 /// 获取中断描述符管理器的引用
353 #[inline(always)]
354 pub(super) fn irq_desc_manager() -> &'static IrqDescManager {
355     return unsafe { IRQ_DESC_MANAGER.as_ref().unwrap() };
356 }
357 
358 pub(super) struct IrqDescManager {
359     irq_descs: BTreeMap<IrqNumber, Arc<IrqDesc>>,
360 }
361 
362 impl IrqDescManager {
363     fn new() -> Self {
364         IrqDescManager {
365             irq_descs: BTreeMap::new(),
366         }
367     }
368 
369     /// 查找中断描述符
370     #[allow(dead_code)]
371     pub fn lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>> {
372         self.irq_descs.get(&irq).map(|desc| desc.clone())
373     }
374 
375     fn insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>) {
376         self.irq_descs.insert(irq, desc);
377     }
378 
379     /// 释放中断描述符
380     #[allow(dead_code)]
381     fn free_desc(&mut self, irq: IrqNumber) {
382         if let Some(desc) = self.irq_descs.get(&irq) {
383             irq_sysfs_del(desc);
384             self.irq_descs.remove(&irq);
385         }
386     }
387 
388     /// 迭代中断描述符
389     pub fn iter_descs(&self) -> btree_map::Iter<'_, IrqNumber, Arc<IrqDesc>> {
390         self.irq_descs.iter()
391     }
392 }
393