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