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