pci_irq.rs 44 KB

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