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