pci_irq.rs 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. #![allow(dead_code)]
  2. use core::mem::size_of;
  3. use core::ptr::NonNull;
  4. use alloc::ffi::CString;
  5. use alloc::vec::Vec;
  6. use super::pci::{PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError};
  7. use crate::arch::msi::{ia64_pci_get_arch_msi_message_address, ia64_pci_get_arch_msi_message_data};
  8. use crate::arch::{PciArch, TraitPciArch};
  9. use crate::include::bindings::bindings::{
  10. c_irq_install, c_irq_uninstall, pt_regs, ul, EAGAIN, EINVAL,
  11. };
  12. use crate::libs::volatile::{volread, volwrite, Volatile, VolatileReadable, VolatileWritable};
  13. /// MSIX表的一项
  14. #[repr(C)]
  15. struct MsixEntry {
  16. vector_control: Volatile<u32>,
  17. msg_data: Volatile<u32>,
  18. msg_upper_addr: Volatile<u32>,
  19. msg_addr: Volatile<u32>,
  20. }
  21. /// Pending表的一项
  22. #[repr(C)]
  23. struct PendingEntry {
  24. entry: Volatile<u64>,
  25. }
  26. /// PCI设备中断错误
  27. #[derive(Copy, Clone, Debug, Eq, PartialEq)]
  28. pub enum PciIrqError {
  29. IrqTypeNotSupported,
  30. PciDeviceNotSupportIrq,
  31. IrqTypeUnmatch,
  32. InvalidIrqIndex(u16),
  33. InvalidIrqNum(u16),
  34. IrqNumOccupied(u16),
  35. DeviceIrqOverflow,
  36. MxiIrqNumWrong,
  37. PciBarNotInited,
  38. BarGetVaddrFailed,
  39. MaskNotSupported,
  40. IrqNotInited,
  41. }
  42. /// PCI设备的中断类型
  43. #[derive(Copy, Clone, Debug)]
  44. pub enum IrqType {
  45. Msi {
  46. address_64: bool,
  47. maskable: bool,
  48. irq_max_num: u16,
  49. cap_offset: u8,
  50. },
  51. Msix {
  52. msix_table_bar: u8,
  53. msix_table_offset: u32,
  54. pending_table_bar: u8,
  55. pending_table_offset: u32,
  56. irq_max_num: u16,
  57. cap_offset: u8,
  58. },
  59. Legacy,
  60. Unused,
  61. }
  62. // PCI设备install中断时需要传递的参数
  63. #[derive(Clone, Debug)]
  64. pub struct IrqMsg {
  65. irq_common_message: IrqCommonMsg,
  66. irq_specific_message: IrqSpecificMsg,
  67. }
  68. // PCI设备install中断时需要传递的共同参数
  69. #[derive(Clone, Debug)]
  70. pub struct IrqCommonMsg {
  71. irq_index: u16, //要install的中断号在PCI设备中的irq_vector的index
  72. irq_name: CString, //中断名字
  73. irq_parameter: u16, //中断额外参数,可传入中断处理函数
  74. irq_hander: unsafe extern "C" fn(irq_num: ul, parameter: ul, regs: *mut pt_regs), // 中断处理函数
  75. irq_ack: Option<unsafe extern "C" fn(irq_num: ul)>, // 中断的ack,可为None,若为None则中断处理中会正常通知中断结束,不为None则调用传入的函数进行回复
  76. }
  77. // PCI设备install中断时需要传递的特有参数,Msi代表MSI与MSIX
  78. #[derive(Clone, Debug)]
  79. pub enum IrqSpecificMsg {
  80. Legacy,
  81. Msi {
  82. processor: u16,
  83. trigger_mode: TriggerMode,
  84. },
  85. }
  86. impl IrqSpecificMsg {
  87. fn msi_default() -> Self {
  88. IrqSpecificMsg::Msi {
  89. processor: 0,
  90. trigger_mode: TriggerMode::EdgeTrigger,
  91. }
  92. }
  93. }
  94. // 申请中断的触发模式,MSI默认为边沿触发
  95. #[derive(Copy, Clone, Debug)]
  96. pub enum TriggerMode {
  97. EdgeTrigger,
  98. AssertHigh,
  99. AssertLow,
  100. }
  101. bitflags! {
  102. /// 设备中断类型,使用bitflag使得中断类型的选择更多元化
  103. pub struct IRQ: u8{
  104. const PCI_IRQ_LEGACY = 1 << 0;
  105. const PCI_IRQ_MSI = 1 << 1;
  106. const PCI_IRQ_MSIX = 1 << 2;
  107. const PCI_IRQ_ALL_TYPES=IRQ::PCI_IRQ_LEGACY.bits|IRQ::PCI_IRQ_MSI.bits|IRQ::PCI_IRQ_MSIX.bits;
  108. }
  109. }
  110. /// PciDeviceStructure的子trait,使用继承以直接使用PciDeviceStructure里的接口
  111. pub trait PciInterrupt: PciDeviceStructure {
  112. /// @brief PCI设备调用该函数选择中断类型
  113. /// @param self PCI设备的可变引用
  114. /// @param flag 选择的中断类型(支持多个选择),如PCI_IRQ_ALL_TYPES表示所有中断类型均可,让系统按顺序进行选择
  115. /// @return Option<IrqType> 失败返回None,成功则返回对应中断类型
  116. fn irq_init(&mut self, flag: IRQ) -> Option<IrqType> {
  117. // MSIX中断优先
  118. if flag.contains(IRQ::PCI_IRQ_MSIX) {
  119. if let Some(cap_offset) = self.msix_capability_offset() {
  120. let data =
  121. PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 4);
  122. let irq_max_num = ((data >> 16) & 0x07ff) as u16;
  123. let data =
  124. PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 4);
  125. let msix_table_bar = (data & 0x01) as u8;
  126. let msix_table_offset = data & 0xfffe;
  127. let data =
  128. PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 8);
  129. let pending_table_bar = (data & 0x01) as u8;
  130. let pending_table_offset = data & 0xfffe;
  131. *self.irq_type_mut()? = IrqType::Msix {
  132. msix_table_bar,
  133. msix_table_offset,
  134. pending_table_bar,
  135. pending_table_offset,
  136. irq_max_num,
  137. cap_offset,
  138. };
  139. return Some(IrqType::Msix {
  140. msix_table_bar,
  141. msix_table_offset,
  142. pending_table_bar,
  143. pending_table_offset,
  144. irq_max_num,
  145. cap_offset,
  146. });
  147. }
  148. }
  149. // 其次MSI
  150. if flag.contains(IRQ::PCI_IRQ_MSI) {
  151. if let Some(cap_offset) = self.msi_capability_offset() {
  152. let data =
  153. PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
  154. let message_control = (data >> 16) as u16;
  155. let maskable = (message_control & 0x0100) != 0;
  156. let address_64 = (message_control & 0x0080) != 0;
  157. let irq_max_num = (1 << (((message_control & 0x000e) >> 1) + 1)) as u16;
  158. *self.irq_type_mut()? = IrqType::Msi {
  159. address_64,
  160. maskable,
  161. irq_max_num,
  162. cap_offset,
  163. };
  164. return Some(IrqType::Msi {
  165. address_64,
  166. maskable,
  167. irq_max_num,
  168. cap_offset,
  169. });
  170. }
  171. }
  172. // 最后选择legacy#
  173. if flag.contains(IRQ::PCI_IRQ_LEGACY) {
  174. *self.irq_type_mut()? = IrqType::Legacy;
  175. return Some(IrqType::Legacy);
  176. }
  177. None
  178. }
  179. /// @brief 启动/关闭设备中断
  180. /// @param self PCI设备的可变引用
  181. /// @param enable 开启/关闭
  182. fn irq_enable(&mut self, enable: bool) -> Result<u8, PciError> {
  183. if let Some(irq_type) = self.irq_type_mut() {
  184. match *irq_type {
  185. IrqType::Msix { .. } => {
  186. return self.msix_enable(enable);
  187. }
  188. IrqType::Msi { .. } => {
  189. return self.msi_enable(enable);
  190. }
  191. IrqType::Legacy => {
  192. return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
  193. }
  194. IrqType::Unused => {
  195. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  196. }
  197. }
  198. }
  199. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  200. }
  201. /// @brief 启动/关闭设备MSIX中断
  202. /// @param self PCI设备的可变引用
  203. /// @param enable 开启/关闭
  204. fn msix_enable(&mut self, enable: bool) -> Result<u8, PciError> {
  205. if let Some(irq_type) = self.irq_type_mut() {
  206. match *irq_type {
  207. IrqType::Msix { cap_offset, .. } => {
  208. let mut message =
  209. PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
  210. if enable {
  211. message |= 1 << 31;
  212. } else {
  213. message &= !(1 << 31);
  214. }
  215. PciArch::write_config(
  216. &self.common_header().bus_device_function,
  217. cap_offset,
  218. message,
  219. );
  220. return Ok(0);
  221. }
  222. IrqType::Unused => {
  223. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  224. }
  225. _ => {
  226. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  227. }
  228. }
  229. }
  230. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  231. }
  232. /// @brief 启动/关闭设备MSI中断
  233. /// @param self PCI设备的可变引用
  234. /// @param enable 开启/关闭
  235. fn msi_enable(&mut self, enable: bool) -> Result<u8, PciError> {
  236. if let Some(irq_type) = self.irq_type_mut() {
  237. match *irq_type {
  238. IrqType::Msi { cap_offset, .. } => {
  239. let mut message =
  240. PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
  241. if enable {
  242. message |= 1 << 16;
  243. } else {
  244. message &= !(1 << 16);
  245. }
  246. PciArch::write_config(
  247. &self.common_header().bus_device_function,
  248. cap_offset,
  249. message,
  250. );
  251. return Ok(0);
  252. }
  253. IrqType::Unused => {
  254. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  255. }
  256. _ => {
  257. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  258. }
  259. }
  260. }
  261. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  262. }
  263. /// @brief 获取指定数量的中断号 todo 需要中断重构支持
  264. fn irq_alloc(_num: u16) -> Option<Vec<u16>> {
  265. None
  266. }
  267. /// @brief 进行PCI设备中断的安装
  268. /// @param self PCI设备的可变引用
  269. /// @param msg PCI设备install中断时需要传递的共同参数
  270. /// @return 一切正常返回Ok(0),有错误返回对应错误原因
  271. fn irq_install(&mut self, msg: IrqMsg) -> Result<u8, PciError> {
  272. if let Some(irq_vector) = self.irq_vector_mut() {
  273. if msg.irq_common_message.irq_index as usize > irq_vector.len() {
  274. return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
  275. msg.irq_common_message.irq_index,
  276. )));
  277. }
  278. }
  279. self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断
  280. if let Some(irq_type) = self.irq_type_mut() {
  281. match *irq_type {
  282. IrqType::Msix { .. } => {
  283. return self.msix_install(msg);
  284. }
  285. IrqType::Msi { .. } => {
  286. return self.msi_install(msg);
  287. }
  288. IrqType::Unused => {
  289. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  290. }
  291. _ => {
  292. return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
  293. }
  294. }
  295. }
  296. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  297. }
  298. /// @brief 进行PCI设备中断的安装(MSI)
  299. /// @param self PCI设备的可变引用
  300. /// @param msg PCI设备install中断时需要传递的共同参数
  301. /// @return 一切正常返回Ok(0),有错误返回对应错误原因
  302. fn msi_install(&mut self, msg: IrqMsg) -> Result<u8, PciError> {
  303. if let Some(irq_type) = self.irq_type_mut() {
  304. match *irq_type {
  305. IrqType::Msi {
  306. address_64,
  307. irq_max_num,
  308. cap_offset,
  309. ..
  310. } => {
  311. // 注意:MSI中断分配的中断号必须连续且大小为2的倍数
  312. if self.irq_vector_mut().unwrap().len() > irq_max_num as usize {
  313. return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow));
  314. }
  315. let irq_num =
  316. self.irq_vector_mut().unwrap()[msg.irq_common_message.irq_index as usize];
  317. let common_msg = &msg.irq_common_message;
  318. let result = unsafe {
  319. c_irq_install(
  320. irq_num as u64,
  321. Some(common_msg.irq_hander),
  322. common_msg.irq_parameter as u64,
  323. common_msg.irq_name.as_ptr(),
  324. common_msg.irq_ack,
  325. )
  326. };
  327. match result as u32 {
  328. EINVAL => {
  329. return Err(PciError::PciIrqError(PciIrqError::InvalidIrqNum(irq_num)));
  330. }
  331. EAGAIN => {
  332. return Err(PciError::PciIrqError(PciIrqError::IrqNumOccupied(
  333. irq_num,
  334. )));
  335. }
  336. _ => {}
  337. }
  338. //MSI中断只需配置一次PCI寄存器
  339. if common_msg.irq_index == 0 {
  340. let msg_address = ia64_pci_get_arch_msi_message_address(0);
  341. let trigger = match msg.irq_specific_message {
  342. IrqSpecificMsg::Legacy => {
  343. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  344. }
  345. IrqSpecificMsg::Msi { trigger_mode, .. } => trigger_mode,
  346. };
  347. let msg_data = ia64_pci_get_arch_msi_message_data(irq_num, 0, trigger);
  348. //写入Message Data和Message Address
  349. if address_64 {
  350. PciArch::write_config(
  351. &self.common_header().bus_device_function,
  352. cap_offset + 4,
  353. msg_address,
  354. );
  355. PciArch::write_config(
  356. &self.common_header().bus_device_function,
  357. cap_offset + 8,
  358. 0,
  359. );
  360. PciArch::write_config(
  361. &self.common_header().bus_device_function,
  362. cap_offset + 12,
  363. msg_data,
  364. );
  365. } else {
  366. PciArch::write_config(
  367. &self.common_header().bus_device_function,
  368. cap_offset + 4,
  369. msg_address,
  370. );
  371. PciArch::write_config(
  372. &self.common_header().bus_device_function,
  373. cap_offset + 8,
  374. msg_data,
  375. );
  376. }
  377. let data = PciArch::read_config(
  378. &self.common_header().bus_device_function,
  379. cap_offset,
  380. );
  381. let message_control = (data >> 16) as u16;
  382. match self.irq_vector_mut().unwrap().len() {
  383. 1 => {
  384. let temp = message_control & (!0x0070);
  385. PciArch::write_config(
  386. &self.common_header().bus_device_function,
  387. cap_offset,
  388. (temp as u32) << 16,
  389. );
  390. }
  391. 2 => {
  392. let temp = message_control & (!0x0070);
  393. PciArch::write_config(
  394. &self.common_header().bus_device_function,
  395. cap_offset,
  396. ((temp | (0x0001 << 4)) as u32) << 16,
  397. );
  398. }
  399. 4 => {
  400. let temp = message_control & (!0x0070);
  401. PciArch::write_config(
  402. &self.common_header().bus_device_function,
  403. cap_offset,
  404. ((temp | (0x0002 << 4)) as u32) << 16,
  405. );
  406. }
  407. 8 => {
  408. let temp = message_control & (!0x0070);
  409. PciArch::write_config(
  410. &self.common_header().bus_device_function,
  411. cap_offset,
  412. ((temp | (0x0003 << 4)) as u32) << 16,
  413. );
  414. }
  415. 16 => {
  416. let temp = message_control & (!0x0070);
  417. PciArch::write_config(
  418. &self.common_header().bus_device_function,
  419. cap_offset,
  420. ((temp | (0x0004 << 4)) as u32) << 16,
  421. );
  422. }
  423. 32 => {
  424. let temp = message_control & (!0x0070);
  425. PciArch::write_config(
  426. &self.common_header().bus_device_function,
  427. cap_offset,
  428. ((temp | (0x0005 << 4)) as u32) << 16,
  429. );
  430. }
  431. _ => {
  432. return Err(PciError::PciIrqError(PciIrqError::MxiIrqNumWrong));
  433. }
  434. }
  435. }
  436. return Ok(0);
  437. }
  438. IrqType::Unused => {
  439. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  440. }
  441. _ => {
  442. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  443. }
  444. }
  445. }
  446. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  447. }
  448. /// @brief 进行PCI设备中断的安装(MSIX)
  449. /// @param self PCI设备的可变引用
  450. /// @param msg PCI设备install中断时需要传递的共同参数
  451. /// @return 一切正常返回Ok(0),有错误返回对应错误原因
  452. fn msix_install(&mut self, msg: IrqMsg) -> Result<u8, PciError> {
  453. if let Some(irq_type) = self.irq_type_mut() {
  454. match *irq_type {
  455. IrqType::Msix {
  456. irq_max_num,
  457. msix_table_bar,
  458. msix_table_offset,
  459. ..
  460. } => {
  461. if self.irq_vector_mut().unwrap().len() > irq_max_num as usize {
  462. return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow));
  463. }
  464. let irq_num =
  465. self.irq_vector_mut().unwrap()[msg.irq_common_message.irq_index as usize];
  466. let common_msg = &msg.irq_common_message;
  467. let result = unsafe {
  468. c_irq_install(
  469. irq_num as u64,
  470. Some(common_msg.irq_hander),
  471. common_msg.irq_parameter as u64,
  472. common_msg.irq_name.as_ptr(),
  473. common_msg.irq_ack,
  474. )
  475. };
  476. match result as u32 {
  477. EINVAL => {
  478. return Err(PciError::PciIrqError(PciIrqError::InvalidIrqNum(irq_num)));
  479. }
  480. EAGAIN => {
  481. return Err(PciError::PciIrqError(PciIrqError::IrqNumOccupied(
  482. irq_num,
  483. )));
  484. }
  485. _ => {}
  486. }
  487. let msg_address = ia64_pci_get_arch_msi_message_address(0);
  488. let trigger = match msg.irq_specific_message {
  489. IrqSpecificMsg::Legacy => {
  490. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  491. }
  492. IrqSpecificMsg::Msi { trigger_mode, .. } => trigger_mode,
  493. };
  494. let msg_data = ia64_pci_get_arch_msi_message_data(irq_num, 0, trigger);
  495. //写入Message Data和Message Address
  496. let pcistandardbar = self
  497. .bar()
  498. .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))?;
  499. let msix_bar = pcistandardbar.get_bar(msix_table_bar)?;
  500. let vaddr = msix_bar
  501. .virtual_address()
  502. .ok_or(PciError::PciIrqError(PciIrqError::BarGetVaddrFailed))?
  503. + msix_table_offset as usize
  504. + msg.irq_common_message.irq_index as usize * size_of::<MsixEntry>();
  505. let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap();
  506. unsafe {
  507. volwrite!(msix_entry, vector_control, 0);
  508. volwrite!(msix_entry, msg_data, msg_data);
  509. volwrite!(msix_entry, msg_upper_addr, 0);
  510. volwrite!(msix_entry, msg_addr, msg_address);
  511. }
  512. return Ok(0);
  513. }
  514. IrqType::Unused => {
  515. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  516. }
  517. _ => {
  518. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  519. }
  520. }
  521. }
  522. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  523. }
  524. /// @brief 进行PCI设备中断的卸载
  525. /// @param self PCI设备的可变引用
  526. fn irq_uninstall(&mut self) -> Result<u8, PciError> {
  527. self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断
  528. if let Some(irq_type) = self.irq_type_mut() {
  529. match *irq_type {
  530. IrqType::Msix { .. } => {
  531. return self.msix_uninstall();
  532. }
  533. IrqType::Msi { .. } => {
  534. return self.msi_uninstall();
  535. }
  536. IrqType::Unused => {
  537. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  538. }
  539. _ => {
  540. return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
  541. }
  542. }
  543. }
  544. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  545. }
  546. /// @brief 进行PCI设备中断的卸载(MSI)
  547. /// @param self PCI设备的可变引用
  548. fn msi_uninstall(&mut self) -> Result<u8, PciError> {
  549. if let Some(irq_type) = self.irq_type_mut() {
  550. match *irq_type {
  551. IrqType::Msi {
  552. address_64,
  553. cap_offset,
  554. ..
  555. } => {
  556. for vector in self.irq_vector_mut().unwrap() {
  557. unsafe {
  558. c_irq_uninstall(vector.clone() as u64);
  559. }
  560. }
  561. PciArch::write_config(&self.common_header().bus_device_function, cap_offset, 0);
  562. PciArch::write_config(
  563. &self.common_header().bus_device_function,
  564. cap_offset + 4,
  565. 0,
  566. );
  567. PciArch::write_config(
  568. &self.common_header().bus_device_function,
  569. cap_offset + 8,
  570. 0,
  571. );
  572. if address_64 {
  573. PciArch::write_config(
  574. &self.common_header().bus_device_function,
  575. cap_offset + 12,
  576. 0,
  577. );
  578. }
  579. return Ok(0);
  580. }
  581. IrqType::Unused => {
  582. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  583. }
  584. _ => {
  585. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  586. }
  587. }
  588. }
  589. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  590. }
  591. /// @brief 进行PCI设备中断的卸载(MSIX)
  592. /// @param self PCI设备的可变引用
  593. fn msix_uninstall(&mut self) -> Result<u8, PciError> {
  594. if let Some(irq_type) = self.irq_type_mut() {
  595. match *irq_type {
  596. IrqType::Msix {
  597. irq_max_num,
  598. cap_offset,
  599. msix_table_bar,
  600. msix_table_offset,
  601. ..
  602. } => {
  603. for vector in self.irq_vector_mut().unwrap() {
  604. unsafe {
  605. c_irq_uninstall(vector.clone() as u64);
  606. }
  607. }
  608. PciArch::write_config(&self.common_header().bus_device_function, cap_offset, 0);
  609. let pcistandardbar = self
  610. .bar()
  611. .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
  612. .unwrap();
  613. let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
  614. for index in 0..irq_max_num {
  615. let vaddr = msix_bar
  616. .virtual_address()
  617. .ok_or(PciError::PciIrqError(PciIrqError::BarGetVaddrFailed))
  618. .unwrap()
  619. + msix_table_offset as usize
  620. + index as usize * size_of::<MsixEntry>();
  621. let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap();
  622. unsafe {
  623. volwrite!(msix_entry, vector_control, 0);
  624. volwrite!(msix_entry, msg_data, 0);
  625. volwrite!(msix_entry, msg_upper_addr, 0);
  626. volwrite!(msix_entry, msg_addr, 0);
  627. }
  628. }
  629. return Ok(0);
  630. }
  631. IrqType::Unused => {
  632. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  633. }
  634. _ => {
  635. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  636. }
  637. }
  638. }
  639. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  640. }
  641. /// @brief 屏蔽相应位置的中断
  642. /// @param self PCI设备的可变引用
  643. /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
  644. fn irq_mask(&mut self, irq_index: u16) -> Result<u8, PciError> {
  645. if let Some(irq_type) = self.irq_type_mut() {
  646. match *irq_type {
  647. IrqType::Msix { .. } => {
  648. return self.msix_mask(irq_index);
  649. }
  650. IrqType::Msi { .. } => {
  651. return self.msi_mask(irq_index);
  652. }
  653. IrqType::Unused => {
  654. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  655. }
  656. _ => {
  657. return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
  658. }
  659. }
  660. }
  661. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  662. }
  663. /// @brief 屏蔽相应位置的中断(MSI)
  664. /// @param self PCI设备的可变引用
  665. /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
  666. fn msi_mask(&mut self, irq_index: u16) -> Result<u8, PciError> {
  667. if let Some(irq_type) = self.irq_type_mut() {
  668. match *irq_type {
  669. IrqType::Msi {
  670. maskable,
  671. address_64,
  672. cap_offset,
  673. irq_max_num,
  674. } => {
  675. if irq_index >= irq_max_num {
  676. return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
  677. irq_index,
  678. )));
  679. }
  680. if maskable {
  681. match address_64 {
  682. true => {
  683. let mut mask = PciArch::read_config(
  684. &self.common_header().bus_device_function,
  685. cap_offset + 16,
  686. );
  687. mask |= 1 << irq_index;
  688. PciArch::write_config(
  689. &self.common_header().bus_device_function,
  690. cap_offset,
  691. mask,
  692. );
  693. }
  694. false => {
  695. let mut mask = PciArch::read_config(
  696. &self.common_header().bus_device_function,
  697. cap_offset + 12,
  698. );
  699. mask |= 1 << irq_index;
  700. PciArch::write_config(
  701. &self.common_header().bus_device_function,
  702. cap_offset,
  703. mask,
  704. );
  705. }
  706. }
  707. return Ok(0);
  708. }
  709. return Err(PciError::PciIrqError(PciIrqError::MaskNotSupported));
  710. }
  711. IrqType::Unused => {
  712. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  713. }
  714. _ => {
  715. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  716. }
  717. }
  718. }
  719. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  720. }
  721. /// @brief 屏蔽相应位置的中断(MSIX)
  722. /// @param self PCI设备的可变引用
  723. /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
  724. fn msix_mask(&mut self, irq_index: u16) -> Result<u8, PciError> {
  725. if let Some(irq_type) = self.irq_type_mut() {
  726. match *irq_type {
  727. IrqType::Msix {
  728. irq_max_num,
  729. msix_table_bar,
  730. msix_table_offset,
  731. ..
  732. } => {
  733. if irq_index >= irq_max_num {
  734. return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
  735. irq_index,
  736. )));
  737. }
  738. let pcistandardbar = self
  739. .bar()
  740. .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
  741. .unwrap();
  742. let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
  743. let vaddr = msix_bar.virtual_address().unwrap()
  744. + msix_table_offset as usize
  745. + irq_index as usize * size_of::<MsixEntry>();
  746. let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap();
  747. unsafe {
  748. volwrite!(msix_entry, vector_control, 1);
  749. }
  750. return Ok(0);
  751. }
  752. IrqType::Unused => {
  753. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  754. }
  755. _ => {
  756. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  757. }
  758. }
  759. }
  760. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  761. }
  762. /// @brief 解除屏蔽相应位置的中断
  763. /// @param self PCI设备的可变引用
  764. /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
  765. fn irq_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> {
  766. if let Some(irq_type) = self.irq_type_mut() {
  767. match *irq_type {
  768. IrqType::Msix { .. } => {
  769. return self.msix_unmask(irq_index);
  770. }
  771. IrqType::Msi { .. } => {
  772. return self.msi_unmask(irq_index);
  773. }
  774. IrqType::Unused => {
  775. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  776. }
  777. _ => {
  778. return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
  779. }
  780. }
  781. }
  782. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  783. }
  784. /// @brief 解除屏蔽相应位置的中断(MSI)
  785. /// @param self PCI设备的可变引用
  786. /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
  787. fn msi_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> {
  788. if let Some(irq_type) = self.irq_type_mut() {
  789. match *irq_type {
  790. IrqType::Msi {
  791. maskable,
  792. address_64,
  793. cap_offset,
  794. irq_max_num,
  795. } => {
  796. if irq_index >= irq_max_num {
  797. return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
  798. irq_index,
  799. )));
  800. }
  801. if maskable {
  802. match address_64 {
  803. true => {
  804. let mut mask = PciArch::read_config(
  805. &self.common_header().bus_device_function,
  806. cap_offset + 16,
  807. );
  808. mask &= !(1 << irq_index);
  809. PciArch::write_config(
  810. &self.common_header().bus_device_function,
  811. cap_offset,
  812. mask,
  813. );
  814. }
  815. false => {
  816. let mut mask = PciArch::read_config(
  817. &self.common_header().bus_device_function,
  818. cap_offset + 12,
  819. );
  820. mask &= !(1 << irq_index);
  821. PciArch::write_config(
  822. &self.common_header().bus_device_function,
  823. cap_offset,
  824. mask,
  825. );
  826. }
  827. }
  828. }
  829. return Err(PciError::PciIrqError(PciIrqError::MaskNotSupported));
  830. }
  831. IrqType::Unused => {
  832. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  833. }
  834. _ => {
  835. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  836. }
  837. }
  838. }
  839. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  840. }
  841. /// @brief 解除屏蔽相应位置的中断(MSIX)
  842. /// @param self PCI设备的可变引用
  843. /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
  844. fn msix_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> {
  845. if let Some(irq_type) = self.irq_type_mut() {
  846. match *irq_type {
  847. IrqType::Msix {
  848. irq_max_num,
  849. msix_table_bar,
  850. msix_table_offset,
  851. ..
  852. } => {
  853. if irq_index >= irq_max_num {
  854. return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
  855. irq_index,
  856. )));
  857. }
  858. let pcistandardbar = self
  859. .bar()
  860. .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
  861. .unwrap();
  862. let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
  863. let vaddr = msix_bar.virtual_address().unwrap()
  864. + msix_table_offset as usize
  865. + irq_index as usize * size_of::<MsixEntry>();
  866. let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap();
  867. unsafe {
  868. volwrite!(msix_entry, vector_control, 0);
  869. }
  870. return Ok(0);
  871. }
  872. IrqType::Unused => {
  873. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  874. }
  875. _ => {
  876. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  877. }
  878. }
  879. }
  880. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  881. }
  882. /// @brief 检查被挂起的中断是否在挂起的时候产生了
  883. /// @param self PCI设备的可变引用
  884. /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
  885. /// @return 是否在挂起过程中产生中断(异常情况也返回false)
  886. fn irq_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> {
  887. if let Some(irq_type) = self.irq_type_mut() {
  888. match *irq_type {
  889. IrqType::Msix { .. } => {
  890. return self.msix_check_pending(irq_index);
  891. }
  892. IrqType::Msi { .. } => {
  893. return self.msi_check_pending(irq_index);
  894. }
  895. IrqType::Unused => {
  896. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  897. }
  898. _ => {
  899. return Err(PciError::PciIrqError(PciIrqError::IrqTypeNotSupported));
  900. }
  901. }
  902. }
  903. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  904. }
  905. /// @brief 检查被挂起的中断是否在挂起的时候产生了(MSI)
  906. /// @param self PCI设备的可变引用
  907. /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
  908. /// @return 是否在挂起过程中产生中断(异常情况也返回false)
  909. fn msi_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> {
  910. if let Some(irq_type) = self.irq_type_mut() {
  911. match *irq_type {
  912. IrqType::Msi {
  913. maskable,
  914. address_64,
  915. cap_offset,
  916. irq_max_num,
  917. } => {
  918. if irq_index >= irq_max_num {
  919. return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
  920. irq_index,
  921. )));
  922. }
  923. if maskable {
  924. match address_64 {
  925. true => {
  926. let mut pend = PciArch::read_config(
  927. &self.common_header().bus_device_function,
  928. cap_offset + 20,
  929. );
  930. pend &= 1 << irq_index;
  931. return Ok(pend != 0);
  932. }
  933. false => {
  934. let mut pend = PciArch::read_config(
  935. &self.common_header().bus_device_function,
  936. cap_offset + 16,
  937. );
  938. pend &= 1 << irq_index;
  939. return Ok(pend != 0);
  940. }
  941. }
  942. }
  943. }
  944. IrqType::Unused => {
  945. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  946. }
  947. _ => {
  948. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  949. }
  950. }
  951. }
  952. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  953. }
  954. /// @brief 检查被挂起的中断是否在挂起的时候产生了(MSIX)
  955. /// @param self PCI设备的可变引用
  956. /// @param irq_index 中断的位置(在vec中的index和安装的index相同)
  957. /// @return 是否在挂起过程中产生中断(异常情况也返回false)
  958. fn msix_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> {
  959. if let Some(irq_type) = self.irq_type_mut() {
  960. match *irq_type {
  961. IrqType::Msix {
  962. irq_max_num,
  963. pending_table_bar,
  964. pending_table_offset,
  965. ..
  966. } => {
  967. if irq_index >= irq_max_num {
  968. return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
  969. irq_index,
  970. )));
  971. }
  972. let pcistandardbar = self
  973. .bar()
  974. .ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
  975. .unwrap();
  976. let pending_bar = pcistandardbar.get_bar(pending_table_bar).unwrap();
  977. let vaddr = pending_bar.virtual_address().unwrap()
  978. + pending_table_offset as usize
  979. + (irq_index as usize / 64) * size_of::<PendingEntry>();
  980. let pending_entry = NonNull::new(vaddr.data() as *mut PendingEntry).unwrap();
  981. let pending_entry = unsafe { volread!(pending_entry, entry) };
  982. return Ok(pending_entry & (1 << (irq_index as u64 % 64)) != 0);
  983. }
  984. IrqType::Unused => {
  985. return Err(PciError::PciIrqError(PciIrqError::IrqNotInited));
  986. }
  987. _ => {
  988. return Err(PciError::PciIrqError(PciIrqError::IrqTypeUnmatch));
  989. }
  990. }
  991. }
  992. return Err(PciError::PciIrqError(PciIrqError::PciDeviceNotSupportIrq));
  993. }
  994. }
  995. /// PCI标准设备的msi/msix中断相关函数块
  996. impl PciInterrupt for PciDeviceStructureGeneralDevice {}