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