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