irqdesc.rs 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
  1. use core::{
  2. any::Any,
  3. fmt::Debug,
  4. sync::atomic::{AtomicI64, Ordering},
  5. };
  6. use alloc::{
  7. collections::{btree_map, BTreeMap},
  8. string::{String, ToString},
  9. sync::{Arc, Weak},
  10. vec::Vec,
  11. };
  12. use system_error::SystemError;
  13. use crate::{
  14. arch::{interrupt::TrapFrame, CurrentIrqArch},
  15. driver::base::{
  16. device::DeviceId,
  17. kobject::{KObjType, KObject, KObjectState, LockedKObjectState},
  18. kset::KSet,
  19. },
  20. filesystem::kernfs::KernFSInode,
  21. libs::{
  22. cpumask::CpuMask,
  23. mutex::{Mutex, MutexGuard},
  24. rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard},
  25. spinlock::{SpinLock, SpinLockGuard},
  26. },
  27. mm::percpu::PerCpuVar,
  28. process::ProcessControlBlock,
  29. sched::completion::Completion,
  30. smp::cpu::smp_cpu_manager,
  31. };
  32. use super::{
  33. dummychip::no_irq_chip,
  34. handle::bad_irq_handler,
  35. irqchip::IrqChip,
  36. irqdata::{IrqCommonData, IrqData, IrqHandlerData, IrqLineStatus, IrqStatus},
  37. irqdomain::{irq_domain_manager, IrqDomain},
  38. sysfs::{irq_sysfs_del, IrqKObjType},
  39. HardwareIrqNumber, InterruptArch, IrqNumber,
  40. };
  41. /// 中断流处理程序
  42. pub trait IrqFlowHandler: Debug + Send + Sync + Any {
  43. fn handle(&self, irq_desc: &Arc<IrqDesc>, trap_frame: &mut TrapFrame);
  44. }
  45. /// 中断处理程序
  46. pub trait IrqHandler: Debug + Send + Sync + Any {
  47. fn handle(
  48. &self,
  49. irq: IrqNumber,
  50. static_data: Option<&dyn IrqHandlerData>,
  51. dynamic_data: Option<Arc<dyn IrqHandlerData>>,
  52. ) -> Result<IrqReturn, SystemError>;
  53. }
  54. /// 中断处理函数返回值
  55. ///
  56. /// 用于指示中断处理函数是否处理了中断
  57. #[derive(Debug, Clone, Copy, PartialEq, Eq)]
  58. pub enum IrqReturn {
  59. /// 中断未被处理
  60. NotHandled,
  61. /// 中断已被处理
  62. Handled,
  63. /// 中断已被处理,并且需要唤醒中断线程
  64. WakeThread,
  65. }
  66. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/irqdesc.h#55
  67. #[derive(Debug)]
  68. pub struct IrqDesc {
  69. inner: SpinLock<InnerIrqDesc>,
  70. handler: RwLock<Option<&'static dyn IrqFlowHandler>>,
  71. /// 一个用于串行化 request_irq()和free_irq() 的互斥锁
  72. request_mutex: Mutex<()>,
  73. kobj_state: LockedKObjectState,
  74. /// 当前描述符内正在运行的中断线程数
  75. threads_active: AtomicI64,
  76. }
  77. impl IrqDesc {
  78. #[inline(never)]
  79. pub fn new(irq: IrqNumber, name: Option<String>, irqd_flags: IrqStatus) -> Arc<Self> {
  80. // 初始化的过程参考 https://code.dragonos.org.cn/xref/linux-6.1.9/kernel/irq/irqdesc.c#392
  81. let common_data = Arc::new(IrqCommonData::new());
  82. let irq_data = Arc::new(IrqData::new(
  83. irq,
  84. HardwareIrqNumber::new(irq.data()),
  85. common_data.clone(),
  86. no_irq_chip(),
  87. ));
  88. irq_data.irqd_set(IrqStatus::IRQD_IRQ_DISABLED);
  89. common_data.insert_status(IrqStatus::IRQD_IRQ_MASKED);
  90. let irq_desc = IrqDesc {
  91. inner: SpinLock::new(InnerIrqDesc {
  92. percpu_affinity: None,
  93. percpu_enabled: None,
  94. common_data,
  95. irq_data,
  96. desc_internal_state: IrqDescState::empty(),
  97. line_status: IrqLineStatus::empty(),
  98. actions: Vec::new(),
  99. name,
  100. parent_irq: None,
  101. depth: 1,
  102. wake_depth: 0,
  103. kern_inode: None,
  104. kset: None,
  105. parent_kobj: None,
  106. threads_oneshot: 0,
  107. }),
  108. request_mutex: Mutex::new(()),
  109. handler: RwLock::new(None),
  110. kobj_state: LockedKObjectState::new(Some(KObjectState::INITIALIZED)),
  111. threads_active: AtomicI64::new(0),
  112. };
  113. let irq_desc = Arc::new(irq_desc);
  114. irq_desc.irq_data().set_irq_desc(Arc::downgrade(&irq_desc));
  115. irq_desc.set_handler(bad_irq_handler());
  116. irq_desc.inner().irq_data.irqd_set(irqd_flags);
  117. return irq_desc;
  118. }
  119. /// 返回当前活跃的中断线程数量
  120. #[allow(dead_code)]
  121. pub fn threads_active(&self) -> i64 {
  122. self.threads_active.load(Ordering::SeqCst)
  123. }
  124. /// 增加当前活跃的中断线程数量, 返回增加前的值
  125. pub fn inc_threads_active(&self) -> i64 {
  126. self.threads_active.fetch_add(1, Ordering::SeqCst)
  127. }
  128. /// 减少当前活跃的中断线程数量, 返回减少前的值
  129. #[allow(dead_code)]
  130. pub fn dec_threads_active(&self) -> i64 {
  131. self.threads_active.fetch_sub(1, Ordering::SeqCst)
  132. }
  133. pub fn set_handler(&self, handler: &'static dyn IrqFlowHandler) {
  134. self.chip_bus_lock();
  135. let mut guard = self.handler.write_irqsave();
  136. *guard = Some(handler);
  137. self.chip_bus_sync_unlock();
  138. }
  139. /// 设置中断处理程序(不对desc->inner)
  140. ///
  141. ///
  142. /// ## Safety
  143. ///
  144. /// 需要保证irq_data和chip是当前irqdesc的
  145. pub fn set_handler_no_lock_inner(
  146. &self,
  147. handler: &'static dyn IrqFlowHandler,
  148. irq_data: &Arc<IrqData>,
  149. chip: &Arc<dyn IrqChip>,
  150. ) {
  151. chip.irq_bus_lock(irq_data).ok();
  152. let mut guard = self.handler.write_irqsave();
  153. *guard = Some(handler);
  154. chip.irq_bus_sync_unlock(irq_data).ok();
  155. }
  156. pub fn handler(&self) -> Option<&'static dyn IrqFlowHandler> {
  157. let guard = self.handler.read_irqsave();
  158. *guard
  159. }
  160. pub fn inner(&self) -> SpinLockGuard<'_, InnerIrqDesc> {
  161. self.inner.lock_irqsave()
  162. }
  163. pub fn actions(&self) -> Vec<Arc<IrqAction>> {
  164. self.inner().actions.clone()
  165. }
  166. /// 对中断请求过程加锁
  167. pub fn request_mutex_lock(&self) -> MutexGuard<'_, ()> {
  168. self.request_mutex.lock()
  169. }
  170. pub fn irq(&self) -> IrqNumber {
  171. self.inner().irq_data.irq()
  172. }
  173. pub fn hardware_irq(&self) -> HardwareIrqNumber {
  174. self.inner().irq_data.hardware_irq()
  175. }
  176. pub fn irq_data(&self) -> Arc<IrqData> {
  177. self.inner().irq_data.clone()
  178. }
  179. /// 标记当前irq描述符已经被添加到sysfs
  180. pub fn mark_in_sysfs(&self) {
  181. self.inner()
  182. .desc_internal_state
  183. .insert(IrqDescState::IRQS_SYSFS);
  184. }
  185. pub fn mark_not_in_sysfs(&self) {
  186. self.inner()
  187. .desc_internal_state
  188. .remove(IrqDescState::IRQS_SYSFS);
  189. }
  190. /// 判断当前描述符是否已经添加到了sysfs
  191. pub fn in_sysfs(&self) -> bool {
  192. self.inner()
  193. .desc_internal_state
  194. .contains(IrqDescState::IRQS_SYSFS)
  195. }
  196. pub fn name(&self) -> Option<String> {
  197. self.inner().name.clone()
  198. }
  199. pub fn can_request(&self) -> bool {
  200. self.inner().can_request()
  201. }
  202. #[allow(dead_code)]
  203. pub fn set_norequest(&self) {
  204. self.inner().set_norequest();
  205. }
  206. #[allow(dead_code)]
  207. pub fn clear_norequest(&self) {
  208. self.inner().clear_norequest();
  209. }
  210. pub fn nested_thread(&self) -> bool {
  211. self.inner().nested_thread()
  212. }
  213. /// 中断是否可以线程化
  214. pub fn can_thread(&self) -> bool {
  215. !self
  216. .inner()
  217. .line_status
  218. .contains(IrqLineStatus::IRQ_NOTHREAD)
  219. }
  220. pub fn chip_bus_lock(&self) {
  221. let irq_data = self.inner().irq_data.clone();
  222. irq_data
  223. .chip_info_read_irqsave()
  224. .chip()
  225. .irq_bus_lock(&irq_data)
  226. .ok();
  227. }
  228. /// 同步释放低速总线锁
  229. ///
  230. /// ## 锁
  231. ///
  232. /// 进入此函数时,必须持有低速总线锁,并且desc的inner锁和irqdata的inner锁
  233. /// 必须已经释放。否则将死锁。
  234. pub fn chip_bus_sync_unlock(&self) {
  235. let irq_data = self.inner().irq_data.clone();
  236. irq_data
  237. .chip_info_write_irqsave()
  238. .chip()
  239. .irq_bus_sync_unlock(&irq_data)
  240. .ok();
  241. }
  242. pub fn set_percpu_devid_flags(&self) {
  243. self.modify_status(
  244. IrqLineStatus::empty(),
  245. IrqLineStatus::IRQ_NOAUTOEN
  246. | IrqLineStatus::IRQ_PER_CPU
  247. | IrqLineStatus::IRQ_NOTHREAD
  248. | IrqLineStatus::IRQ_NOPROBE
  249. | IrqLineStatus::IRQ_PER_CPU_DEVID,
  250. );
  251. }
  252. #[allow(dead_code)]
  253. pub fn set_probe(&self) {
  254. self.modify_status(IrqLineStatus::IRQ_NOPROBE, IrqLineStatus::empty());
  255. }
  256. #[allow(dead_code)]
  257. pub fn set_noprobe(&self) {
  258. self.modify_status(IrqLineStatus::empty(), IrqLineStatus::IRQ_NOPROBE);
  259. }
  260. pub fn modify_status(&self, clear: IrqLineStatus, set: IrqLineStatus) {
  261. let mut desc_guard = self.inner();
  262. desc_guard.line_status.remove(clear);
  263. desc_guard.line_status.insert(set);
  264. let mut trigger = desc_guard.common_data().trigger_type();
  265. desc_guard.common_data().clear_status(
  266. IrqStatus::IRQD_NO_BALANCING
  267. | IrqStatus::IRQD_PER_CPU
  268. | IrqStatus::IRQD_TRIGGER_MASK
  269. | IrqStatus::IRQD_LEVEL
  270. | IrqStatus::IRQD_MOVE_PCNTXT,
  271. );
  272. if desc_guard
  273. .line_status
  274. .contains(IrqLineStatus::IRQ_NO_BALANCING)
  275. {
  276. desc_guard
  277. .common_data()
  278. .insert_status(IrqStatus::IRQD_NO_BALANCING);
  279. }
  280. if desc_guard.line_status.contains(IrqLineStatus::IRQ_PER_CPU) {
  281. desc_guard
  282. .common_data()
  283. .insert_status(IrqStatus::IRQD_PER_CPU);
  284. }
  285. if desc_guard
  286. .line_status
  287. .contains(IrqLineStatus::IRQ_MOVE_PCNTXT)
  288. {
  289. desc_guard
  290. .common_data()
  291. .insert_status(IrqStatus::IRQD_MOVE_PCNTXT);
  292. }
  293. if desc_guard.line_status.is_level_type() {
  294. desc_guard
  295. .common_data()
  296. .insert_status(IrqStatus::IRQD_LEVEL);
  297. }
  298. let tmp = desc_guard.line_status.trigger_type();
  299. if tmp != IrqLineStatus::IRQ_TYPE_NONE {
  300. trigger = tmp;
  301. }
  302. desc_guard.common_data().set_trigger_type(trigger);
  303. }
  304. }
  305. #[allow(dead_code)]
  306. #[derive(Debug)]
  307. pub struct InnerIrqDesc {
  308. /// per irq and chip data passed down to chip functions
  309. common_data: Arc<IrqCommonData>,
  310. irq_data: Arc<IrqData>,
  311. actions: Vec<Arc<IrqAction>>,
  312. name: Option<String>,
  313. parent_irq: Option<IrqNumber>,
  314. /// nested irq disables
  315. depth: u32,
  316. /// nested wake enables
  317. wake_depth: u32,
  318. desc_internal_state: IrqDescState,
  319. /// 中断线的状态
  320. line_status: IrqLineStatus,
  321. kern_inode: Option<Arc<KernFSInode>>,
  322. kset: Option<Arc<KSet>>,
  323. parent_kobj: Option<Weak<dyn KObject>>,
  324. /// per-cpu enabled mask
  325. percpu_enabled: Option<CpuMask>,
  326. /// per-cpu affinity
  327. percpu_affinity: Option<CpuMask>,
  328. // wait_for_threads: EventWaitQueue
  329. /// bitfield to handle shared oneshot threads
  330. threads_oneshot: u64,
  331. }
  332. impl InnerIrqDesc {
  333. pub fn name(&self) -> Option<&String> {
  334. self.name.as_ref()
  335. }
  336. #[allow(dead_code)]
  337. pub fn set_name(&mut self, name: Option<String>) {
  338. self.name = name;
  339. }
  340. pub fn can_request(&self) -> bool {
  341. !self.line_status.contains(IrqLineStatus::IRQ_NOREQUEST)
  342. }
  343. #[allow(dead_code)]
  344. pub fn set_norequest(&mut self) {
  345. self.line_status.insert(IrqLineStatus::IRQ_NOREQUEST);
  346. }
  347. #[allow(dead_code)]
  348. pub fn clear_norequest(&mut self) {
  349. self.line_status.remove(IrqLineStatus::IRQ_NOREQUEST);
  350. }
  351. #[allow(dead_code)]
  352. pub fn set_noprobe(&mut self) {
  353. self.line_status.insert(IrqLineStatus::IRQ_NOPROBE);
  354. }
  355. #[allow(dead_code)]
  356. pub fn clear_noprobe(&mut self) {
  357. self.line_status.remove(IrqLineStatus::IRQ_NOPROBE);
  358. }
  359. pub fn set_nothread(&mut self) {
  360. self.line_status.insert(IrqLineStatus::IRQ_NOTHREAD);
  361. }
  362. #[allow(dead_code)]
  363. pub fn clear_nothread(&mut self) {
  364. self.line_status.remove(IrqLineStatus::IRQ_NOTHREAD);
  365. }
  366. pub fn nested_thread(&self) -> bool {
  367. self.line_status.contains(IrqLineStatus::IRQ_NESTED_THREAD)
  368. }
  369. pub fn line_status_set_per_cpu(&mut self) {
  370. self.line_status.insert(IrqLineStatus::IRQ_PER_CPU);
  371. }
  372. #[allow(dead_code)]
  373. pub fn line_status_clear_per_cpu(&mut self) {
  374. self.line_status.remove(IrqLineStatus::IRQ_PER_CPU);
  375. }
  376. #[allow(dead_code)]
  377. pub fn line_status(&self) -> &IrqLineStatus {
  378. &self.line_status
  379. }
  380. pub fn line_status_set_no_debug(&mut self) {
  381. self.line_status.insert(IrqLineStatus::IRQ_NO_BALANCING);
  382. }
  383. #[allow(dead_code)]
  384. pub fn line_status_clear_no_debug(&mut self) {
  385. self.line_status.remove(IrqLineStatus::IRQ_NO_BALANCING);
  386. }
  387. pub fn can_autoenable(&self) -> bool {
  388. !self.line_status.contains(IrqLineStatus::IRQ_NOAUTOEN)
  389. }
  390. #[allow(dead_code)]
  391. pub fn can_thread(&self) -> bool {
  392. !self.line_status.contains(IrqLineStatus::IRQ_NOTHREAD)
  393. }
  394. pub fn threads_oneshot(&self) -> u64 {
  395. self.threads_oneshot
  396. }
  397. /// 中断是否可以设置CPU亲和性
  398. pub fn can_set_affinity(&self) -> bool {
  399. if !self.common_data.status().can_balance()
  400. || !self
  401. .irq_data()
  402. .chip_info_read_irqsave()
  403. .chip()
  404. .can_set_affinity()
  405. {
  406. return false;
  407. }
  408. return true;
  409. }
  410. pub fn actions(&self) -> &Vec<Arc<IrqAction>> {
  411. &self.actions
  412. }
  413. pub fn add_action(&mut self, action: Arc<IrqAction>) {
  414. self.actions.push(action);
  415. }
  416. pub fn clear_actions(&mut self) {
  417. self.actions.clear();
  418. }
  419. #[allow(dead_code)]
  420. pub fn remove_action(&mut self, action: &Arc<IrqAction>) {
  421. self.actions.retain(|a| !Arc::ptr_eq(a, action));
  422. }
  423. pub fn internal_state(&self) -> &IrqDescState {
  424. &self.desc_internal_state
  425. }
  426. pub(super) fn internal_state_mut(&mut self) -> &mut IrqDescState {
  427. &mut self.desc_internal_state
  428. }
  429. pub fn irq_data(&self) -> &Arc<IrqData> {
  430. &self.irq_data
  431. }
  432. pub fn common_data(&self) -> &Arc<IrqCommonData> {
  433. &self.common_data
  434. }
  435. #[allow(dead_code)]
  436. pub fn depth(&self) -> u32 {
  437. self.depth
  438. }
  439. #[allow(dead_code)]
  440. pub fn wake_depth(&self) -> u32 {
  441. self.wake_depth
  442. }
  443. #[allow(dead_code)]
  444. pub fn set_depth(&mut self, depth: u32) {
  445. self.depth = depth;
  446. }
  447. pub fn set_trigger_type(&mut self, trigger: IrqLineStatus) {
  448. self.line_status.remove(IrqLineStatus::IRQ_TYPE_SENSE_MASK);
  449. self.line_status
  450. .insert(trigger & IrqLineStatus::IRQ_TYPE_SENSE_MASK);
  451. }
  452. pub fn clear_level(&mut self) {
  453. self.line_status.remove(IrqLineStatus::IRQ_LEVEL);
  454. }
  455. pub fn set_level(&mut self) {
  456. self.line_status.insert(IrqLineStatus::IRQ_LEVEL);
  457. }
  458. pub fn percpu_enabled(&self) -> &Option<CpuMask> {
  459. &self.percpu_enabled
  460. }
  461. pub fn percpu_enabled_mut(&mut self) -> &mut Option<CpuMask> {
  462. &mut self.percpu_enabled
  463. }
  464. #[allow(dead_code)]
  465. pub fn percpu_affinity(&self) -> &Option<CpuMask> {
  466. &self.percpu_affinity
  467. }
  468. pub fn percpu_affinity_mut(&mut self) -> &mut Option<CpuMask> {
  469. &mut self.percpu_affinity
  470. }
  471. }
  472. impl KObject for IrqDesc {
  473. fn as_any_ref(&self) -> &dyn Any {
  474. self
  475. }
  476. fn set_inode(&self, inode: Option<Arc<KernFSInode>>) {
  477. self.inner().kern_inode = inode;
  478. }
  479. fn inode(&self) -> Option<Arc<KernFSInode>> {
  480. self.inner().kern_inode.clone()
  481. }
  482. fn parent(&self) -> Option<Weak<dyn KObject>> {
  483. self.inner().parent_kobj.clone()
  484. }
  485. fn set_parent(&self, parent: Option<Weak<dyn KObject>>) {
  486. self.inner().parent_kobj = parent;
  487. }
  488. fn kset(&self) -> Option<Arc<KSet>> {
  489. self.inner().kset.clone()
  490. }
  491. fn set_kset(&self, kset: Option<Arc<KSet>>) {
  492. self.inner().kset = kset;
  493. }
  494. fn kobj_type(&self) -> Option<&'static dyn KObjType> {
  495. Some(&IrqKObjType)
  496. }
  497. fn set_kobj_type(&self, _ktype: Option<&'static dyn KObjType>) {}
  498. fn name(&self) -> String {
  499. self.inner().irq_data.irq().data().to_string()
  500. }
  501. fn set_name(&self, _name: String) {}
  502. fn kobj_state(&self) -> RwLockReadGuard<'_, KObjectState> {
  503. self.kobj_state.read()
  504. }
  505. fn kobj_state_mut(&self) -> RwLockWriteGuard<'_, KObjectState> {
  506. self.kobj_state.write()
  507. }
  508. fn set_kobj_state(&self, state: KObjectState) {
  509. *self.kobj_state_mut() = state;
  510. }
  511. }
  512. bitflags! {
  513. /// Bit masks for desc->desc_internal_state
  514. pub struct IrqDescState: u32 {
  515. /// autodetection in progress
  516. const IRQS_AUTODETECT = 0x00000001;
  517. /// was disabled due to spurious interrupt detection
  518. const IRQS_SPURIOUS_DISABLED = 0x00000002;
  519. /// polling in progress
  520. const IRQS_POLL_INPROGRESS = 0x00000008;
  521. /// irq is not unmasked in primary handler
  522. const IRQS_ONESHOT = 0x00000020;
  523. /// irq is replayed
  524. const IRQS_REPLAY = 0x00000040;
  525. /// irq is waiting
  526. const IRQS_WAITING = 0x00000080;
  527. /// irq is pending and replayed later
  528. const IRQS_PENDING = 0x00000200;
  529. /// irq is suspended
  530. const IRQS_SUSPENDED = 0x00000800;
  531. /// irq line is used to deliver NMIs
  532. const IRQS_NMI = 0x00002000;
  533. /// descriptor has been added to sysfs
  534. const IRQS_SYSFS = 0x00004000;
  535. }
  536. }
  537. /// 每个中断的响应动作的描述符
  538. /// 参考 https://code.dragonos.org.cn/xref/linux-6.1.9/include/linux/interrupt.h#118
  539. #[allow(dead_code)]
  540. #[derive(Debug)]
  541. pub struct IrqAction {
  542. inner: SpinLock<InnerIrqAction>,
  543. /// 用于等待线程被创建的完成量
  544. thread_completion: Completion,
  545. }
  546. impl IrqAction {
  547. #[allow(dead_code)]
  548. pub fn new(
  549. irq: IrqNumber,
  550. name: String,
  551. handler: Option<&'static dyn IrqHandler>,
  552. thread_fn: Option<&'static dyn IrqHandler>,
  553. ) -> Arc<Self> {
  554. let action: IrqAction = IrqAction {
  555. inner: SpinLock::new(InnerIrqAction {
  556. dev_id: None,
  557. per_cpu_dev_id: None,
  558. handler,
  559. thread_fn,
  560. thread: None,
  561. secondary: None,
  562. irq,
  563. flags: IrqHandleFlags::empty(),
  564. name,
  565. thread_flags: ThreadedHandlerFlags::empty(),
  566. }),
  567. thread_completion: Completion::new(),
  568. };
  569. return Arc::new(action);
  570. }
  571. pub fn inner(&self) -> SpinLockGuard<'_, InnerIrqAction> {
  572. self.inner.lock_irqsave()
  573. }
  574. pub fn thread_completion(&self) -> &Completion {
  575. &self.thread_completion
  576. }
  577. }
  578. #[allow(dead_code)]
  579. #[derive(Debug)]
  580. pub struct InnerIrqAction {
  581. /// cookie to identify the device
  582. dev_id: Option<Arc<DeviceId>>,
  583. /// cookie to identify the device (per cpu)
  584. per_cpu_dev_id: Option<PerCpuVar<Arc<DeviceId>>>,
  585. /// 中断处理程序
  586. handler: Option<&'static dyn IrqHandler>,
  587. /// interrupt handler function for threaded interrupts
  588. thread_fn: Option<&'static dyn IrqHandler>,
  589. /// thread pointer for threaded interrupts
  590. thread: Option<Arc<ProcessControlBlock>>,
  591. /// pointer to secondary irqaction (force threading)
  592. secondary: Option<Arc<IrqAction>>,
  593. /// 中断号
  594. irq: IrqNumber,
  595. flags: IrqHandleFlags,
  596. /// 中断线程的标志
  597. thread_flags: ThreadedHandlerFlags,
  598. /// name of the device
  599. name: String,
  600. }
  601. impl InnerIrqAction {
  602. pub fn dev_id(&self) -> &Option<Arc<DeviceId>> {
  603. &self.dev_id
  604. }
  605. pub fn dev_id_mut(&mut self) -> &mut Option<Arc<DeviceId>> {
  606. &mut self.dev_id
  607. }
  608. #[allow(dead_code)]
  609. pub fn per_cpu_dev_id(&self) -> Option<&Arc<DeviceId>> {
  610. self.per_cpu_dev_id.as_ref().map(|v| v.get())
  611. }
  612. #[allow(dead_code)]
  613. pub fn per_cpu_dev_id_mut(&mut self) -> Option<&mut Arc<DeviceId>> {
  614. self.per_cpu_dev_id.as_mut().map(|v| v.get_mut())
  615. }
  616. pub fn handler(&self) -> Option<&'static dyn IrqHandler> {
  617. self.handler
  618. }
  619. pub fn set_handler(&mut self, handler: Option<&'static dyn IrqHandler>) {
  620. self.handler = handler;
  621. }
  622. pub fn thread_fn(&self) -> Option<&'static dyn IrqHandler> {
  623. self.thread_fn
  624. }
  625. pub fn thread(&self) -> Option<Arc<ProcessControlBlock>> {
  626. self.thread.clone()
  627. }
  628. pub fn set_thread(&mut self, thread: Option<Arc<ProcessControlBlock>>) {
  629. self.thread = thread;
  630. }
  631. #[allow(dead_code)]
  632. pub fn thread_flags(&self) -> &ThreadedHandlerFlags {
  633. &self.thread_flags
  634. }
  635. pub fn thread_flags_mut(&mut self) -> &mut ThreadedHandlerFlags {
  636. &mut self.thread_flags
  637. }
  638. pub fn secondary(&self) -> Option<Arc<IrqAction>> {
  639. self.secondary.clone()
  640. }
  641. #[allow(dead_code)]
  642. pub fn irq(&self) -> IrqNumber {
  643. self.irq
  644. }
  645. #[allow(dead_code)]
  646. pub fn set_irq(&mut self, irq: IrqNumber) {
  647. self.irq = irq;
  648. }
  649. pub fn flags(&self) -> &IrqHandleFlags {
  650. &self.flags
  651. }
  652. pub fn flags_mut(&mut self) -> &mut IrqHandleFlags {
  653. &mut self.flags
  654. }
  655. pub fn name(&self) -> &String {
  656. &self.name
  657. }
  658. }
  659. bitflags! {
  660. /// 这些标志由线程处理程序使用
  661. pub struct ThreadedHandlerFlags: u32 {
  662. /// IRQTF_RUNTHREAD - 表示应运行中断处理程序线程
  663. const IRQTF_RUNTHREAD = 1 << 0;
  664. /// IRQTF_WARNED - 已打印警告 "IRQ_WAKE_THREAD w/o thread_fn"
  665. const IRQTF_WARNED = 1 << 1;
  666. /// IRQTF_AFFINITY - 请求irq线程调整亲和性
  667. const IRQTF_AFFINITY = 1 << 2;
  668. /// IRQTF_FORCED_THREAD - irq操作被强制线程化
  669. const IRQTF_FORCED_THREAD = 1 << 3;
  670. /// IRQTF_READY - 表示irq线程已准备就绪
  671. const IRQTF_READY = 1 << 4;
  672. }
  673. }
  674. /// Implements the `ThreadedHandlerFlags` structure.
  675. impl ThreadedHandlerFlags {
  676. /// 在 `ThreadedHandlerFlags` 结构中测试并设置特定的位。
  677. ///
  678. /// # 参数
  679. ///
  680. /// * `bit` - 要测试并设置的位。
  681. ///
  682. /// # 返回
  683. ///
  684. /// 如果操作前该位已被设置,则返回 `true`,否则返回 `false`。
  685. pub fn test_and_set_bit(&mut self, bit: ThreadedHandlerFlags) -> bool {
  686. let res = (self.bits & bit.bits) != 0;
  687. self.bits |= bit.bits;
  688. return res;
  689. }
  690. }
  691. // 定义IrqFlags位标志
  692. bitflags! {
  693. /// 这些标志仅由内核在中断处理例程中使用。
  694. #[allow(clippy::bad_bit_mask)]
  695. pub struct IrqHandleFlags: u32 {
  696. const IRQF_TRIGGER_NONE = IrqLineStatus::IRQ_TYPE_NONE.bits();
  697. const IRQF_TRIGGER_RISING = IrqLineStatus::IRQ_TYPE_EDGE_RISING.bits();
  698. const IRQF_TRIGGER_FALLING = IrqLineStatus::IRQ_TYPE_EDGE_FALLING.bits();
  699. const IRQF_TRIGGER_HIGH = IrqLineStatus::IRQ_TYPE_LEVEL_HIGH.bits();
  700. const IRQF_TRIGGER_LOW = IrqLineStatus::IRQ_TYPE_LEVEL_LOW.bits();
  701. const IRQF_TRIGGER_MASK = Self::IRQF_TRIGGER_HIGH.bits | Self::IRQF_TRIGGER_LOW.bits | Self::IRQF_TRIGGER_RISING.bits | Self::IRQF_TRIGGER_FALLING.bits;
  702. /// IRQF_SHARED - 允许多个设备共享中断
  703. const IRQF_SHARED = 0x00000080;
  704. /// IRQF_PROBE_SHARED - 当预期出现共享不匹配时,由调用者设置
  705. const IRQF_PROBE_SHARED = 0x00000100;
  706. /// IRQF_TIMER - 标记此中断为定时器中断
  707. const __IRQF_TIMER = 0x00000200;
  708. /// IRQF_PERCPU - 中断是每个CPU的
  709. const IRQF_PERCPU = 0x00000400;
  710. /// IRQF_NOBALANCING - 将此中断从中断平衡中排除
  711. const IRQF_NOBALANCING = 0x00000800;
  712. /// IRQF_IRQPOLL - 中断用于轮询(出于性能原因,只有在共享中断中首次注册的中断会被考虑)
  713. const IRQF_IRQPOLL = 0x00001000;
  714. /// IRQF_ONESHOT - 在硬中断处理程序完成后,不会重新启用中断。由需要在运行线程处理程序之前保持中断线路禁用的线程中断使用。
  715. const IRQF_ONESHOT = 0x00002000;
  716. /// IRQF_NO_SUSPEND - 在挂起期间不禁用此IRQ。不能保证此中断会从挂起状态唤醒系统。
  717. const IRQF_NO_SUSPEND = 0x00004000;
  718. /// IRQF_FORCE_RESUME - 即使设置了IRQF_NO_SUSPEND,也强制在恢复时启用它
  719. const IRQF_FORCE_RESUME = 0x00008000;
  720. /// IRQF_NO_THREAD - 中断不能被线程化
  721. const IRQF_NO_THREAD = 0x00010000;
  722. /// IRQF_EARLY_RESUME - 在syscore而不是在设备恢复时间早期恢复IRQ。
  723. const IRQF_EARLY_RESUME = 0x00020000;
  724. /// IRQF_COND_SUSPEND - 如果IRQ与NO_SUSPEND用户共享,则在挂起中断后执行此中断处理程序。对于系统唤醒设备用户,需要在他们的中断处理程序中实现唤醒检测。
  725. const IRQF_COND_SUSPEND = 0x00040000;
  726. /// IRQF_NO_AUTOEN - 当用户请求时,不会自动启用IRQ或NMI。用户稍后会通过enable_irq()或enable_nmi()显式启用它。
  727. const IRQF_NO_AUTOEN = 0x00080000;
  728. /// IRQF_NO_DEBUG - 从IPI和类似处理程序的逃逸检测中排除,取决于IRQF_PERCPU。
  729. const IRQF_NO_DEBUG = 0x00100000;
  730. const IRQF_TIMER = Self::__IRQF_TIMER.bits | Self::IRQF_NO_SUSPEND.bits | Self::IRQF_NO_THREAD.bits;
  731. }
  732. }
  733. impl IrqHandleFlags {
  734. /// 检查是否指定了触发类型
  735. #[inline(always)]
  736. pub fn trigger_type_specified(&self) -> bool {
  737. (self.bits & Self::IRQF_TRIGGER_MASK.bits) != 0
  738. }
  739. /// 插入触发类型
  740. pub fn insert_trigger_type(&mut self, trigger: IrqLineStatus) {
  741. self.bits |= trigger.trigger_bits() & IrqHandleFlags::IRQF_TRIGGER_MASK.bits;
  742. }
  743. #[allow(dead_code)]
  744. pub fn remove_trigger_type(&mut self, trigger: IrqLineStatus) {
  745. self.bits &= !(trigger.trigger_bits() & IrqHandleFlags::IRQF_TRIGGER_MASK.bits);
  746. }
  747. pub fn trigger_type(&self) -> IrqLineStatus {
  748. IrqLineStatus::from_bits_truncate(self.bits & IrqHandleFlags::IRQF_TRIGGER_MASK.bits)
  749. }
  750. }
  751. #[inline(never)]
  752. pub(super) fn early_irq_init() -> Result<(), SystemError> {
  753. let irqcnt = CurrentIrqArch::probe_total_irq_num();
  754. let mut manager = IrqDescManager::new();
  755. for i in 0..irqcnt {
  756. let irq_desc = IrqDesc::new(IrqNumber::new(i), None, IrqStatus::empty());
  757. manager.insert(IrqNumber::new(i), irq_desc);
  758. }
  759. unsafe {
  760. IRQ_DESC_MANAGER = Some(manager);
  761. }
  762. return CurrentIrqArch::arch_early_irq_init();
  763. }
  764. static mut IRQ_DESC_MANAGER: Option<IrqDescManager> = None;
  765. /// 获取中断描述符管理器的引用
  766. #[inline(always)]
  767. pub fn irq_desc_manager() -> &'static IrqDescManager {
  768. return unsafe { IRQ_DESC_MANAGER.as_ref().unwrap() };
  769. }
  770. pub struct IrqDescManager {
  771. irq_descs: BTreeMap<IrqNumber, Arc<IrqDesc>>,
  772. }
  773. impl IrqDescManager {
  774. fn new() -> Self {
  775. IrqDescManager {
  776. irq_descs: BTreeMap::new(),
  777. }
  778. }
  779. /// 查找中断描述符
  780. pub fn lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>> {
  781. self.irq_descs.get(&irq).cloned()
  782. }
  783. /// 查找中断描述符并锁定总线(没有对irqdesc进行加锁)
  784. #[allow(dead_code)]
  785. pub fn lookup_and_lock_bus(
  786. &self,
  787. irq: IrqNumber,
  788. check_global: bool,
  789. check_percpu: bool,
  790. ) -> Option<Arc<IrqDesc>> {
  791. self.do_lookup_and_lock(irq, true, check_global, check_percpu)
  792. }
  793. fn do_lookup_and_lock(
  794. &self,
  795. irq: IrqNumber,
  796. lock_bus: bool,
  797. check_global: bool,
  798. check_percpu: bool,
  799. ) -> Option<Arc<IrqDesc>> {
  800. let desc = self.lookup(irq)?;
  801. if check_global || check_percpu {
  802. if check_percpu && !desc.inner().line_status().is_per_cpu_devid() {
  803. return None;
  804. }
  805. if check_global && desc.inner().line_status().is_per_cpu_devid() {
  806. return None;
  807. }
  808. }
  809. if lock_bus {
  810. desc.chip_bus_lock();
  811. }
  812. return Some(desc);
  813. }
  814. fn insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>) {
  815. self.irq_descs.insert(irq, desc);
  816. }
  817. /// 释放中断描述符
  818. #[allow(dead_code)]
  819. fn free_desc(&mut self, irq: IrqNumber) {
  820. if let Some(desc) = self.irq_descs.get(&irq) {
  821. irq_sysfs_del(desc);
  822. self.irq_descs.remove(&irq);
  823. }
  824. }
  825. /// 迭代中断描述符
  826. pub fn iter_descs(&self) -> btree_map::Iter<'_, IrqNumber, Arc<IrqDesc>> {
  827. self.irq_descs.iter()
  828. }
  829. /// 设置指定irq的可用cpu为所有cpu
  830. #[allow(dead_code)]
  831. pub fn set_percpu_devid_all(&self, irq: IrqNumber) -> Result<(), SystemError> {
  832. self.set_percpu_devid(irq, None)
  833. }
  834. /// 设置指定irq的可用cpu
  835. ///
  836. /// 如果affinity为None,则表示设置为所有cpu
  837. pub fn set_percpu_devid(
  838. &self,
  839. irq: IrqNumber,
  840. affinity: Option<&CpuMask>,
  841. ) -> Result<(), SystemError> {
  842. let desc = self.lookup(irq).ok_or(SystemError::EINVAL)?;
  843. let mut desc_inner = desc.inner();
  844. if desc_inner.percpu_enabled().is_some() {
  845. return Err(SystemError::EINVAL);
  846. }
  847. *desc_inner.percpu_enabled_mut() = Some(CpuMask::new());
  848. if let Some(affinity) = affinity {
  849. desc_inner.percpu_affinity_mut().replace(affinity.clone());
  850. } else {
  851. desc_inner
  852. .percpu_affinity_mut()
  853. .replace(smp_cpu_manager().possible_cpus().clone());
  854. }
  855. drop(desc_inner);
  856. desc.set_percpu_devid_flags();
  857. return Ok(());
  858. }
  859. }
  860. pub struct GenericIrqHandler;
  861. #[allow(dead_code)]
  862. impl GenericIrqHandler {
  863. /// `handle_domain_irq` - 调用属于某个中断域的硬件中断的处理程序
  864. ///
  865. /// # 参数
  866. ///
  867. /// * `domain`: 执行查找的域
  868. /// * `hwirq`: 要转换为逻辑中断的硬件中断号
  869. ///
  870. /// # 返回
  871. ///
  872. /// 成功时返回 `Ok(())`,如果转换失败则返回 `Err(SystemError)`
  873. ///
  874. /// 此函数必须在初始化了中断寄存器的中断上下文中调用
  875. ///
  876. /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/irq/irqdesc.c?fi=generic_handle_domain_irq#726
  877. pub fn handle_domain_irq(
  878. domain: Arc<IrqDomain>,
  879. hwirq: HardwareIrqNumber,
  880. trap_frame: &mut TrapFrame,
  881. ) -> Result<(), SystemError> {
  882. let (irq_desc, _) =
  883. irq_domain_manager().resolve_irq_mapping(Some(domain.clone()), hwirq)?;
  884. irq_desc.handler().unwrap().handle(&irq_desc, trap_frame);
  885. return Ok(());
  886. }
  887. }