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