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