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