xref: /DragonOS/kernel/src/exception/irqdesc.rs (revision 3bc96fa4a9c01d91cddeb152fe78d6408351c29f)
1*3bc96fa4SLoGin use core::{any::Any, fmt::Debug};
2*3bc96fa4SLoGin 
3*3bc96fa4SLoGin use alloc::{
4*3bc96fa4SLoGin     collections::BTreeMap,
5*3bc96fa4SLoGin     string::String,
6*3bc96fa4SLoGin     sync::{Arc, Weak},
7*3bc96fa4SLoGin     vec::Vec,
8*3bc96fa4SLoGin };
9*3bc96fa4SLoGin use system_error::SystemError;
10*3bc96fa4SLoGin 
11*3bc96fa4SLoGin use crate::{
12*3bc96fa4SLoGin     arch::CurrentIrqArch,
13*3bc96fa4SLoGin     driver::base::{
14*3bc96fa4SLoGin         device::DeviceId,
15*3bc96fa4SLoGin         kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
16*3bc96fa4SLoGin         kset::KSet,
17*3bc96fa4SLoGin     },
18*3bc96fa4SLoGin     filesystem::kernfs::KernFSInode,
19*3bc96fa4SLoGin     libs::{
20*3bc96fa4SLoGin         rwlock::{RwLockReadGuard, RwLockWriteGuard},
21*3bc96fa4SLoGin         spinlock::{SpinLock, SpinLockGuard},
22*3bc96fa4SLoGin     },
23*3bc96fa4SLoGin     process::ProcessControlBlock,
24*3bc96fa4SLoGin };
25*3bc96fa4SLoGin 
26*3bc96fa4SLoGin use super::{
27*3bc96fa4SLoGin     dummychip::no_irq_chip,
28*3bc96fa4SLoGin     handle::bad_irq_handler,
29*3bc96fa4SLoGin     irqdata::{IrqCommonData, IrqData, IrqStatus},
30*3bc96fa4SLoGin     sysfs::IrqKObjType,
31*3bc96fa4SLoGin     HardwareIrqNumber, InterruptArch, IrqNumber,
32*3bc96fa4SLoGin };
33*3bc96fa4SLoGin 
34*3bc96fa4SLoGin /// 中断流处理程序
35*3bc96fa4SLoGin pub trait IrqFlowHandler: Debug + Send + Sync {
36*3bc96fa4SLoGin     fn handle(&self, irq_desc: &Arc<IrqDesc>);
37*3bc96fa4SLoGin }
38*3bc96fa4SLoGin 
39*3bc96fa4SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdesc.h#55
40*3bc96fa4SLoGin #[derive(Debug)]
41*3bc96fa4SLoGin pub struct IrqDesc {
42*3bc96fa4SLoGin     inner: SpinLock<InnerIrqDesc>,
43*3bc96fa4SLoGin 
44*3bc96fa4SLoGin     handler: SpinLock<Option<&'static dyn IrqFlowHandler>>,
45*3bc96fa4SLoGin 
46*3bc96fa4SLoGin     kobj_state: LockedKObjectState,
47*3bc96fa4SLoGin }
48*3bc96fa4SLoGin 
49*3bc96fa4SLoGin impl IrqDesc {
50*3bc96fa4SLoGin     #[inline(never)]
51*3bc96fa4SLoGin     pub fn new(irq: IrqNumber, name: Option<String>, irqd_flags: IrqStatus) -> Arc<Self> {
52*3bc96fa4SLoGin         // 初始化的过程参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#392
53*3bc96fa4SLoGin         let common_data = Arc::new(IrqCommonData::new());
54*3bc96fa4SLoGin         let irq_data = Arc::new(IrqData::new(
55*3bc96fa4SLoGin             irq,
56*3bc96fa4SLoGin             HardwareIrqNumber::new(irq.data()),
57*3bc96fa4SLoGin             common_data.clone(),
58*3bc96fa4SLoGin             no_irq_chip(),
59*3bc96fa4SLoGin         ));
60*3bc96fa4SLoGin 
61*3bc96fa4SLoGin         irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
62*3bc96fa4SLoGin         common_data.irqd_set(IrqStatus::IRQD_IRQ_MASKED);
63*3bc96fa4SLoGin 
64*3bc96fa4SLoGin         let irq_desc = IrqDesc {
65*3bc96fa4SLoGin             inner: SpinLock::new(InnerIrqDesc {
66*3bc96fa4SLoGin                 common_data,
67*3bc96fa4SLoGin                 irq_data,
68*3bc96fa4SLoGin                 actions: Vec::new(),
69*3bc96fa4SLoGin                 name,
70*3bc96fa4SLoGin                 parent_irq: None,
71*3bc96fa4SLoGin                 depth: 1,
72*3bc96fa4SLoGin                 wake_depth: 0,
73*3bc96fa4SLoGin                 kern_inode: None,
74*3bc96fa4SLoGin                 kset: None,
75*3bc96fa4SLoGin                 parent_kobj: None,
76*3bc96fa4SLoGin             }),
77*3bc96fa4SLoGin             handler: SpinLock::new(None),
78*3bc96fa4SLoGin             kobj_state: LockedKObjectState::new(Some(KObjectState::INITIALIZED)),
79*3bc96fa4SLoGin         };
80*3bc96fa4SLoGin 
81*3bc96fa4SLoGin         irq_desc.set_handler(bad_irq_handler());
82*3bc96fa4SLoGin         irq_desc.inner().irq_data.irqd_set(irqd_flags);
83*3bc96fa4SLoGin 
84*3bc96fa4SLoGin         return Arc::new(irq_desc);
85*3bc96fa4SLoGin     }
86*3bc96fa4SLoGin 
87*3bc96fa4SLoGin     pub fn set_handler(&self, handler: &'static dyn IrqFlowHandler) {
88*3bc96fa4SLoGin         let mut guard = self.handler.lock_irqsave();
89*3bc96fa4SLoGin         *guard = Some(handler);
90*3bc96fa4SLoGin     }
91*3bc96fa4SLoGin 
92*3bc96fa4SLoGin     fn inner(&self) -> SpinLockGuard<InnerIrqDesc> {
93*3bc96fa4SLoGin         self.inner.lock_irqsave()
94*3bc96fa4SLoGin     }
95*3bc96fa4SLoGin 
96*3bc96fa4SLoGin     pub fn irq(&self) -> IrqNumber {
97*3bc96fa4SLoGin         self.inner().irq_data.irq()
98*3bc96fa4SLoGin     }
99*3bc96fa4SLoGin }
100*3bc96fa4SLoGin 
101*3bc96fa4SLoGin #[allow(dead_code)]
102*3bc96fa4SLoGin #[derive(Debug)]
103*3bc96fa4SLoGin struct InnerIrqDesc {
104*3bc96fa4SLoGin     /// per irq and chip data passed down to chip functions
105*3bc96fa4SLoGin     common_data: Arc<IrqCommonData>,
106*3bc96fa4SLoGin     irq_data: Arc<IrqData>,
107*3bc96fa4SLoGin     actions: Vec<Arc<IrqAction>>,
108*3bc96fa4SLoGin     name: Option<String>,
109*3bc96fa4SLoGin     parent_irq: Option<IrqNumber>,
110*3bc96fa4SLoGin     /// nested irq disables
111*3bc96fa4SLoGin     depth: u32,
112*3bc96fa4SLoGin     /// nested wake enables
113*3bc96fa4SLoGin     wake_depth: u32,
114*3bc96fa4SLoGin 
115*3bc96fa4SLoGin     kern_inode: Option<Arc<KernFSInode>>,
116*3bc96fa4SLoGin     kset: Option<Arc<KSet>>,
117*3bc96fa4SLoGin     parent_kobj: Option<Weak<dyn KObject>>,
118*3bc96fa4SLoGin }
119*3bc96fa4SLoGin 
120*3bc96fa4SLoGin impl KObject for IrqDesc {
121*3bc96fa4SLoGin     fn as_any_ref(&self) -> &dyn Any {
122*3bc96fa4SLoGin         self
123*3bc96fa4SLoGin     }
124*3bc96fa4SLoGin 
125*3bc96fa4SLoGin     fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
126*3bc96fa4SLoGin         self.inner().kern_inode = inode;
127*3bc96fa4SLoGin     }
128*3bc96fa4SLoGin 
129*3bc96fa4SLoGin     fn inode(&self) -> Option<Arc<KernFSInode>> {
130*3bc96fa4SLoGin         self.inner().kern_inode.clone()
131*3bc96fa4SLoGin     }
132*3bc96fa4SLoGin 
133*3bc96fa4SLoGin     fn parent(&self) -> Option<Weak<dyn KObject>> {
134*3bc96fa4SLoGin         self.inner().parent_kobj.clone()
135*3bc96fa4SLoGin     }
136*3bc96fa4SLoGin 
137*3bc96fa4SLoGin     fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
138*3bc96fa4SLoGin         self.inner().parent_kobj = parent;
139*3bc96fa4SLoGin     }
140*3bc96fa4SLoGin 
141*3bc96fa4SLoGin     fn kset(&self) -> Option<Arc<KSet>> {
142*3bc96fa4SLoGin         self.inner().kset.clone()
143*3bc96fa4SLoGin     }
144*3bc96fa4SLoGin 
145*3bc96fa4SLoGin     fn set_kset(&self, kset: Option<Arc<KSet>>) {
146*3bc96fa4SLoGin         self.inner().kset = kset;
147*3bc96fa4SLoGin     }
148*3bc96fa4SLoGin 
149*3bc96fa4SLoGin     fn kobj_type(&self) -> Option<&'static dyn KObjType> {
150*3bc96fa4SLoGin         Some(&IrqKObjType)
151*3bc96fa4SLoGin     }
152*3bc96fa4SLoGin 
153*3bc96fa4SLoGin     fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {}
154*3bc96fa4SLoGin 
155*3bc96fa4SLoGin     fn name(&self) -> String {
156*3bc96fa4SLoGin         self.inner().name.clone().unwrap_or_else(|| format!(""))
157*3bc96fa4SLoGin     }
158*3bc96fa4SLoGin 
159*3bc96fa4SLoGin     fn set_name(&self, _name: String) {}
160*3bc96fa4SLoGin 
161*3bc96fa4SLoGin     fn kobj_state(&self) -> RwLockReadGuard<KObjectState> {
162*3bc96fa4SLoGin         self.kobj_state.read()
163*3bc96fa4SLoGin     }
164*3bc96fa4SLoGin 
165*3bc96fa4SLoGin     fn kobj_state_mut(&self) -> RwLockWriteGuard<KObjectState> {
166*3bc96fa4SLoGin         self.kobj_state.write()
167*3bc96fa4SLoGin     }
168*3bc96fa4SLoGin 
169*3bc96fa4SLoGin     fn set_kobj_state(&self, state: KObjectState) {
170*3bc96fa4SLoGin         *self.kobj_state_mut() = state;
171*3bc96fa4SLoGin     }
172*3bc96fa4SLoGin }
173*3bc96fa4SLoGin 
174*3bc96fa4SLoGin /// 每个中断的响应动作的描述符
175*3bc96fa4SLoGin /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/interrupt.h#118
176*3bc96fa4SLoGin #[allow(dead_code)]
177*3bc96fa4SLoGin #[derive(Debug)]
178*3bc96fa4SLoGin pub struct IrqAction {
179*3bc96fa4SLoGin     inner: SpinLock<InnerIrqAction>,
180*3bc96fa4SLoGin }
181*3bc96fa4SLoGin 
182*3bc96fa4SLoGin impl IrqAction {
183*3bc96fa4SLoGin     #[allow(dead_code)]
184*3bc96fa4SLoGin     pub fn new(
185*3bc96fa4SLoGin         irq: IrqNumber,
186*3bc96fa4SLoGin         name: String,
187*3bc96fa4SLoGin         handler: Option<&'static dyn IrqFlowHandler>,
188*3bc96fa4SLoGin     ) -> Arc<Self> {
189*3bc96fa4SLoGin         let action = IrqAction {
190*3bc96fa4SLoGin             inner: SpinLock::new(InnerIrqAction {
191*3bc96fa4SLoGin                 dev_id: None,
192*3bc96fa4SLoGin                 handler,
193*3bc96fa4SLoGin                 thread_fn: None,
194*3bc96fa4SLoGin                 thread: None,
195*3bc96fa4SLoGin                 secondary: None,
196*3bc96fa4SLoGin                 irq,
197*3bc96fa4SLoGin                 flags: IrqHandleFlags::empty(),
198*3bc96fa4SLoGin                 name,
199*3bc96fa4SLoGin             }),
200*3bc96fa4SLoGin         };
201*3bc96fa4SLoGin 
202*3bc96fa4SLoGin         return Arc::new(action);
203*3bc96fa4SLoGin     }
204*3bc96fa4SLoGin }
205*3bc96fa4SLoGin 
206*3bc96fa4SLoGin #[allow(dead_code)]
207*3bc96fa4SLoGin #[derive(Debug)]
208*3bc96fa4SLoGin struct InnerIrqAction {
209*3bc96fa4SLoGin     /// cookie to identify the device
210*3bc96fa4SLoGin     dev_id: Option<DeviceId>,
211*3bc96fa4SLoGin     /// 中断处理程序
212*3bc96fa4SLoGin     handler: Option<&'static dyn IrqFlowHandler>,
213*3bc96fa4SLoGin     /// interrupt handler function for threaded interrupts
214*3bc96fa4SLoGin     thread_fn: Option<&'static dyn IrqFlowHandler>,
215*3bc96fa4SLoGin     /// thread pointer for threaded interrupts
216*3bc96fa4SLoGin     thread: Option<Arc<ProcessControlBlock>>,
217*3bc96fa4SLoGin     /// pointer to secondary irqaction (force threading)
218*3bc96fa4SLoGin     secondary: Option<Arc<IrqAction>>,
219*3bc96fa4SLoGin     /// 中断号
220*3bc96fa4SLoGin     irq: IrqNumber,
221*3bc96fa4SLoGin     flags: IrqHandleFlags,
222*3bc96fa4SLoGin     /// name of the device
223*3bc96fa4SLoGin     name: String,
224*3bc96fa4SLoGin }
225*3bc96fa4SLoGin 
226*3bc96fa4SLoGin // 定义IrqFlags位标志
227*3bc96fa4SLoGin bitflags! {
228*3bc96fa4SLoGin     /// 这些标志仅由内核在中断处理例程中使用。
229*3bc96fa4SLoGin     pub struct IrqHandleFlags: u32 {
230*3bc96fa4SLoGin         /// IRQF_SHARED - 允许多个设备共享中断
231*3bc96fa4SLoGin         const IRQF_SHARED = 0x00000080;
232*3bc96fa4SLoGin         /// IRQF_PROBE_SHARED - 当预期出现共享不匹配时,由调用者设置
233*3bc96fa4SLoGin         const IRQF_PROBE_SHARED = 0x00000100;
234*3bc96fa4SLoGin         /// IRQF_TIMER - 标记此中断为定时器中断
235*3bc96fa4SLoGin         const __IRQF_TIMER = 0x00000200;
236*3bc96fa4SLoGin         /// IRQF_PERCPU - 中断是每个CPU的
237*3bc96fa4SLoGin         const IRQF_PERCPU = 0x00000400;
238*3bc96fa4SLoGin         /// IRQF_NOBALANCING - 将此中断从中断平衡中排除
239*3bc96fa4SLoGin         const IRQF_NOBALANCING = 0x00000800;
240*3bc96fa4SLoGin         /// IRQF_IRQPOLL - 中断用于轮询(出于性能原因,只有在共享中断中首次注册的中断会被考虑)
241*3bc96fa4SLoGin         const IRQF_IRQPOLL = 0x00001000;
242*3bc96fa4SLoGin         /// IRQF_ONESHOT - 在硬中断处理程序完成后,不会重新启用中断。由需要在运行线程处理程序之前保持中断线路禁用的线程中断使用。
243*3bc96fa4SLoGin         const IRQF_ONESHOT = 0x00002000;
244*3bc96fa4SLoGin         /// IRQF_NO_SUSPEND - 在挂起期间不禁用此IRQ。不能保证此中断会从挂起状态唤醒系统。
245*3bc96fa4SLoGin         const IRQF_NO_SUSPEND = 0x00004000;
246*3bc96fa4SLoGin         /// IRQF_FORCE_RESUME - 即使设置了IRQF_NO_SUSPEND,也强制在恢复时启用它
247*3bc96fa4SLoGin         const IRQF_FORCE_RESUME = 0x00008000;
248*3bc96fa4SLoGin         /// IRQF_NO_THREAD - 中断不能被线程化
249*3bc96fa4SLoGin         const IRQF_NO_THREAD = 0x00010000;
250*3bc96fa4SLoGin         /// IRQF_EARLY_RESUME - 在syscore而不是在设备恢复时间早期恢复IRQ。
251*3bc96fa4SLoGin         const IRQF_EARLY_RESUME = 0x00020000;
252*3bc96fa4SLoGin         /// IRQF_COND_SUSPEND - 如果IRQ与NO_SUSPEND用户共享,则在挂起中断后执行此中断处理程序。对于系统唤醒设备用户,需要在他们的中断处理程序中实现唤醒检测。
253*3bc96fa4SLoGin         const IRQF_COND_SUSPEND = 0x00040000;
254*3bc96fa4SLoGin         /// IRQF_NO_AUTOEN - 当用户请求时,不会自动启用IRQ或NMI。用户稍后会通过enable_irq()或enable_nmi()显式启用它。
255*3bc96fa4SLoGin         const IRQF_NO_AUTOEN = 0x00080000;
256*3bc96fa4SLoGin         /// IRQF_NO_DEBUG - 从IPI和类似处理程序的逃逸检测中排除,取决于IRQF_PERCPU。
257*3bc96fa4SLoGin         const IRQF_NO_DEBUG = 0x00100000;
258*3bc96fa4SLoGin         const IRQF_TIMER = Self::__IRQF_TIMER.bits | Self::IRQF_NO_SUSPEND.bits | Self::IRQF_NO_THREAD.bits;
259*3bc96fa4SLoGin     }
260*3bc96fa4SLoGin }
261*3bc96fa4SLoGin 
262*3bc96fa4SLoGin #[inline(never)]
263*3bc96fa4SLoGin pub(super) fn early_irq_init() -> Result<(), SystemError> {
264*3bc96fa4SLoGin     let irqcnt = CurrentIrqArch::probe_total_irq_num();
265*3bc96fa4SLoGin     let mut manager = IrqDescManager::new();
266*3bc96fa4SLoGin     for i in 0..irqcnt {
267*3bc96fa4SLoGin         let irq_desc = IrqDesc::new(IrqNumber::new(i), None, IrqStatus::empty());
268*3bc96fa4SLoGin         manager.insert(IrqNumber::new(i), irq_desc);
269*3bc96fa4SLoGin     }
270*3bc96fa4SLoGin 
271*3bc96fa4SLoGin     return CurrentIrqArch::arch_early_irq_init();
272*3bc96fa4SLoGin }
273*3bc96fa4SLoGin 
274*3bc96fa4SLoGin pub(super) struct IrqDescManager {
275*3bc96fa4SLoGin     irq_descs: BTreeMap<IrqNumber, Arc<IrqDesc>>,
276*3bc96fa4SLoGin }
277*3bc96fa4SLoGin 
278*3bc96fa4SLoGin impl IrqDescManager {
279*3bc96fa4SLoGin     fn new() -> Self {
280*3bc96fa4SLoGin         IrqDescManager {
281*3bc96fa4SLoGin             irq_descs: BTreeMap::new(),
282*3bc96fa4SLoGin         }
283*3bc96fa4SLoGin     }
284*3bc96fa4SLoGin 
285*3bc96fa4SLoGin     /// 查找中断描述符
286*3bc96fa4SLoGin     #[allow(dead_code)]
287*3bc96fa4SLoGin     pub fn lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>> {
288*3bc96fa4SLoGin         self.irq_descs.get(&irq).map(|desc| desc.clone())
289*3bc96fa4SLoGin     }
290*3bc96fa4SLoGin 
291*3bc96fa4SLoGin     fn insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>) {
292*3bc96fa4SLoGin         self.irq_descs.insert(irq, desc);
293*3bc96fa4SLoGin     }
294*3bc96fa4SLoGin }
295