irqdesc.rs 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049
  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. pub fn per_cpu_dev_id(&self) -> Option<&Arc<DeviceId>> {
  609. self.per_cpu_dev_id.as_ref().map(|v| v.get())
  610. }
  611. #[allow(dead_code)]
  612. pub fn per_cpu_dev_id_mut(&mut self) -> Option<&mut Arc<DeviceId>> {
  613. self.per_cpu_dev_id.as_mut().map(|v| v.get_mut())
  614. }
  615. pub fn handler(&self) -> Option<&'static dyn IrqHandler> {
  616. self.handler
  617. }
  618. pub fn set_handler(&mut self, handler: Option<&'static dyn IrqHandler>) {
  619. self.handler = handler;
  620. }
  621. pub fn thread_fn(&self) -> Option<&'static dyn IrqHandler> {
  622. self.thread_fn
  623. }
  624. pub fn thread(&self) -> Option<Arc<ProcessControlBlock>> {
  625. self.thread.clone()
  626. }
  627. pub fn set_thread(&mut self, thread: Option<Arc<ProcessControlBlock>>) {
  628. self.thread = thread;
  629. }
  630. #[allow(dead_code)]
  631. pub fn thread_flags(&self) -> &ThreadedHandlerFlags {
  632. &self.thread_flags
  633. }
  634. pub fn thread_flags_mut(&mut self) -> &mut ThreadedHandlerFlags {
  635. &mut self.thread_flags
  636. }
  637. pub fn secondary(&self) -> Option<Arc<IrqAction>> {
  638. self.secondary.clone()
  639. }
  640. #[allow(dead_code)]
  641. pub fn irq(&self) -> IrqNumber {
  642. self.irq
  643. }
  644. #[allow(dead_code)]
  645. pub fn set_irq(&mut self, irq: IrqNumber) {
  646. self.irq = irq;
  647. }
  648. pub fn flags(&self) -> &IrqHandleFlags {
  649. &self.flags
  650. }
  651. pub fn flags_mut(&mut self) -> &mut IrqHandleFlags {
  652. &mut self.flags
  653. }
  654. pub fn name(&self) -> &String {
  655. &self.name
  656. }
  657. }
  658. bitflags! {
  659. /// 这些标志由线程处理程序使用
  660. pub struct ThreadedHandlerFlags: u32 {
  661. /// IRQTF_RUNTHREAD - 表示应运行中断处理程序线程
  662. const IRQTF_RUNTHREAD = 1 << 0;
  663. /// IRQTF_WARNED - 已打印警告 "IRQ_WAKE_THREAD w/o thread_fn"
  664. const IRQTF_WARNED = 1 << 1;
  665. /// IRQTF_AFFINITY - 请求irq线程调整亲和性
  666. const IRQTF_AFFINITY = 1 << 2;
  667. /// IRQTF_FORCED_THREAD - irq操作被强制线程化
  668. const IRQTF_FORCED_THREAD = 1 << 3;
  669. /// IRQTF_READY - 表示irq线程已准备就绪
  670. const IRQTF_READY = 1 << 4;
  671. }
  672. }
  673. /// Implements the `ThreadedHandlerFlags` structure.
  674. impl ThreadedHandlerFlags {
  675. /// 在 `ThreadedHandlerFlags` 结构中测试并设置特定的位。
  676. ///
  677. /// # 参数
  678. ///
  679. /// * `bit` - 要测试并设置的位。
  680. ///
  681. /// # 返回
  682. ///
  683. /// 如果操作前该位已被设置,则返回 `true`,否则返回 `false`。
  684. pub fn test_and_set_bit(&mut self, bit: ThreadedHandlerFlags) -> bool {
  685. let res = (self.bits & bit.bits) != 0;
  686. self.bits |= bit.bits;
  687. return res;
  688. }
  689. }
  690. // 定义IrqFlags位标志
  691. bitflags! {
  692. /// 这些标志仅由内核在中断处理例程中使用。
  693. #[allow(clippy::bad_bit_mask)]
  694. pub struct IrqHandleFlags: u32 {
  695. const IRQF_TRIGGER_NONE = IrqLineStatus::IRQ_TYPE_NONE.bits();
  696. const IRQF_TRIGGER_RISING = IrqLineStatus::IRQ_TYPE_EDGE_RISING.bits();
  697. const IRQF_TRIGGER_FALLING = IrqLineStatus::IRQ_TYPE_EDGE_FALLING.bits();
  698. const IRQF_TRIGGER_HIGH = IrqLineStatus::IRQ_TYPE_LEVEL_HIGH.bits();
  699. const IRQF_TRIGGER_LOW = IrqLineStatus::IRQ_TYPE_LEVEL_LOW.bits();
  700. const IRQF_TRIGGER_MASK = Self::IRQF_TRIGGER_HIGH.bits | Self::IRQF_TRIGGER_LOW.bits | Self::IRQF_TRIGGER_RISING.bits | Self::IRQF_TRIGGER_FALLING.bits;
  701. /// IRQF_SHARED - 允许多个设备共享中断
  702. const IRQF_SHARED = 0x00000080;
  703. /// IRQF_PROBE_SHARED - 当预期出现共享不匹配时,由调用者设置
  704. const IRQF_PROBE_SHARED = 0x00000100;
  705. /// IRQF_TIMER - 标记此中断为定时器中断
  706. const __IRQF_TIMER = 0x00000200;
  707. /// IRQF_PERCPU - 中断是每个CPU的
  708. const IRQF_PERCPU = 0x00000400;
  709. /// IRQF_NOBALANCING - 将此中断从中断平衡中排除
  710. const IRQF_NOBALANCING = 0x00000800;
  711. /// IRQF_IRQPOLL - 中断用于轮询(出于性能原因,只有在共享中断中首次注册的中断会被考虑)
  712. const IRQF_IRQPOLL = 0x00001000;
  713. /// IRQF_ONESHOT - 在硬中断处理程序完成后,不会重新启用中断。由需要在运行线程处理程序之前保持中断线路禁用的线程中断使用。
  714. const IRQF_ONESHOT = 0x00002000;
  715. /// IRQF_NO_SUSPEND - 在挂起期间不禁用此IRQ。不能保证此中断会从挂起状态唤醒系统。
  716. const IRQF_NO_SUSPEND = 0x00004000;
  717. /// IRQF_FORCE_RESUME - 即使设置了IRQF_NO_SUSPEND,也强制在恢复时启用它
  718. const IRQF_FORCE_RESUME = 0x00008000;
  719. /// IRQF_NO_THREAD - 中断不能被线程化
  720. const IRQF_NO_THREAD = 0x00010000;
  721. /// IRQF_EARLY_RESUME - 在syscore而不是在设备恢复时间早期恢复IRQ。
  722. const IRQF_EARLY_RESUME = 0x00020000;
  723. /// IRQF_COND_SUSPEND - 如果IRQ与NO_SUSPEND用户共享,则在挂起中断后执行此中断处理程序。对于系统唤醒设备用户,需要在他们的中断处理程序中实现唤醒检测。
  724. const IRQF_COND_SUSPEND = 0x00040000;
  725. /// IRQF_NO_AUTOEN - 当用户请求时,不会自动启用IRQ或NMI。用户稍后会通过enable_irq()或enable_nmi()显式启用它。
  726. const IRQF_NO_AUTOEN = 0x00080000;
  727. /// IRQF_NO_DEBUG - 从IPI和类似处理程序的逃逸检测中排除,取决于IRQF_PERCPU。
  728. const IRQF_NO_DEBUG = 0x00100000;
  729. const IRQF_TIMER = Self::__IRQF_TIMER.bits | Self::IRQF_NO_SUSPEND.bits | Self::IRQF_NO_THREAD.bits;
  730. }
  731. }
  732. impl IrqHandleFlags {
  733. /// 检查是否指定了触发类型
  734. #[inline(always)]
  735. pub fn trigger_type_specified(&self) -> bool {
  736. (self.bits & Self::IRQF_TRIGGER_MASK.bits) != 0
  737. }
  738. /// 插入触发类型
  739. pub fn insert_trigger_type(&mut self, trigger: IrqLineStatus) {
  740. self.bits |= trigger.trigger_bits() & IrqHandleFlags::IRQF_TRIGGER_MASK.bits;
  741. }
  742. #[allow(dead_code)]
  743. pub fn remove_trigger_type(&mut self, trigger: IrqLineStatus) {
  744. self.bits &= !(trigger.trigger_bits() & IrqHandleFlags::IRQF_TRIGGER_MASK.bits);
  745. }
  746. pub fn trigger_type(&self) -> IrqLineStatus {
  747. IrqLineStatus::from_bits_truncate(self.bits & IrqHandleFlags::IRQF_TRIGGER_MASK.bits)
  748. }
  749. }
  750. #[inline(never)]
  751. pub(super) fn early_irq_init() -> Result<(), SystemError> {
  752. let irqcnt = CurrentIrqArch::probe_total_irq_num();
  753. let mut manager = IrqDescManager::new();
  754. for i in 0..irqcnt {
  755. let irq_desc = IrqDesc::new(IrqNumber::new(i), None, IrqStatus::empty());
  756. manager.insert(IrqNumber::new(i), irq_desc);
  757. }
  758. unsafe {
  759. IRQ_DESC_MANAGER = Some(manager);
  760. }
  761. return CurrentIrqArch::arch_early_irq_init();
  762. }
  763. static mut IRQ_DESC_MANAGER: Option<IrqDescManager> = None;
  764. /// 获取中断描述符管理器的引用
  765. #[inline(always)]
  766. pub fn irq_desc_manager() -> &'static IrqDescManager {
  767. return unsafe { IRQ_DESC_MANAGER.as_ref().unwrap() };
  768. }
  769. pub struct IrqDescManager {
  770. irq_descs: BTreeMap<IrqNumber, Arc<IrqDesc>>,
  771. }
  772. impl IrqDescManager {
  773. fn new() -> Self {
  774. IrqDescManager {
  775. irq_descs: BTreeMap::new(),
  776. }
  777. }
  778. /// 查找中断描述符
  779. pub fn lookup(&self, irq: IrqNumber) -> Option<Arc<IrqDesc>> {
  780. self.irq_descs.get(&irq).cloned()
  781. }
  782. /// 查找中断描述符并锁定总线(没有对irqdesc进行加锁)
  783. #[allow(dead_code)]
  784. pub fn lookup_and_lock_bus(
  785. &self,
  786. irq: IrqNumber,
  787. check_global: bool,
  788. check_percpu: bool,
  789. ) -> Option<Arc<IrqDesc>> {
  790. self.do_lookup_and_lock(irq, true, check_global, check_percpu)
  791. }
  792. fn do_lookup_and_lock(
  793. &self,
  794. irq: IrqNumber,
  795. lock_bus: bool,
  796. check_global: bool,
  797. check_percpu: bool,
  798. ) -> Option<Arc<IrqDesc>> {
  799. let desc = self.lookup(irq)?;
  800. if check_global || check_percpu {
  801. if check_percpu && !desc.inner().line_status().is_per_cpu_devid() {
  802. return None;
  803. }
  804. if check_global && desc.inner().line_status().is_per_cpu_devid() {
  805. return None;
  806. }
  807. }
  808. if lock_bus {
  809. desc.chip_bus_lock();
  810. }
  811. return Some(desc);
  812. }
  813. fn insert(&mut self, irq: IrqNumber, desc: Arc<IrqDesc>) {
  814. self.irq_descs.insert(irq, desc);
  815. }
  816. /// 释放中断描述符
  817. #[allow(dead_code)]
  818. fn free_desc(&mut self, irq: IrqNumber) {
  819. if let Some(desc) = self.irq_descs.get(&irq) {
  820. irq_sysfs_del(desc);
  821. self.irq_descs.remove(&irq);
  822. }
  823. }
  824. /// 迭代中断描述符
  825. pub fn iter_descs(&self) -> btree_map::Iter<'_, IrqNumber, Arc<IrqDesc>> {
  826. self.irq_descs.iter()
  827. }
  828. /// 设置指定irq的可用cpu为所有cpu
  829. #[allow(dead_code)]
  830. pub fn set_percpu_devid_all(&self, irq: IrqNumber) -> Result<(), SystemError> {
  831. self.set_percpu_devid(irq, None)
  832. }
  833. /// 设置指定irq的可用cpu
  834. ///
  835. /// 如果affinity为None,则表示设置为所有cpu
  836. pub fn set_percpu_devid(
  837. &self,
  838. irq: IrqNumber,
  839. affinity: Option<&CpuMask>,
  840. ) -> Result<(), SystemError> {
  841. let desc = self.lookup(irq).ok_or(SystemError::EINVAL)?;
  842. let mut desc_inner = desc.inner();
  843. if desc_inner.percpu_enabled().is_some() {
  844. return Err(SystemError::EINVAL);
  845. }
  846. *desc_inner.percpu_enabled_mut() = Some(CpuMask::new());
  847. if let Some(affinity) = affinity {
  848. desc_inner.percpu_affinity_mut().replace(affinity.clone());
  849. } else {
  850. desc_inner
  851. .percpu_affinity_mut()
  852. .replace(smp_cpu_manager().possible_cpus().clone());
  853. }
  854. drop(desc_inner);
  855. desc.set_percpu_devid_flags();
  856. return Ok(());
  857. }
  858. }
  859. pub struct GenericIrqHandler;
  860. #[allow(dead_code)]
  861. impl GenericIrqHandler {
  862. /// `handle_domain_irq` - 调用属于某个中断域的硬件中断的处理程序
  863. ///
  864. /// # 参数
  865. ///
  866. /// * `domain`: 执行查找的域
  867. /// * `hwirq`: 要转换为逻辑中断的硬件中断号
  868. ///
  869. /// # 返回
  870. ///
  871. /// 成功时返回 `Ok(())`,如果转换失败则返回 `Err(SystemError)`
  872. ///
  873. /// 此函数必须在初始化了中断寄存器的中断上下文中调用
  874. ///
  875. /// 参考 https://code.dragonos.org.cn/xref/linux-6.6.21/kernel/irq/irqdesc.c?fi=generic_handle_domain_irq#726
  876. pub fn handle_domain_irq(
  877. domain: Arc<IrqDomain>,
  878. hwirq: HardwareIrqNumber,
  879. trap_frame: &mut TrapFrame,
  880. ) -> Result<(), SystemError> {
  881. let (irq_desc, _) =
  882. irq_domain_manager().resolve_irq_mapping(Some(domain.clone()), hwirq)?;
  883. irq_desc.handler().unwrap().handle(&irq_desc, trap_frame);
  884. return Ok(());
  885. }
  886. }