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