Browse Source

完善pci中断的设计 (#392)

* 完善pci中断的设计
YJwu2023 1 year ago
parent
commit
afc95d5c25

+ 3 - 3
kernel/src/driver/pci/pci.rs

@@ -1335,7 +1335,7 @@ impl Display for PciStandardDeviceBar {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
         write!(
             f,
-            "\r\nBar0:{}\r\n Bar1:{}\r\n Bar2:{}\r\n Bar3:{}\r\nBar4:{}\r\nBar5:{}",
+            "\r\nBar0:{}\r\nBar1:{}\r\nBar2:{}\r\nBar3:{}\r\nBar4:{}\r\nBar5:{}",
             self.bar0, self.bar1, self.bar2, self.bar3, self.bar4, self.bar5
         )
     }
@@ -1411,7 +1411,7 @@ pub fn pci_bar_init(
                     .create_mmio(size_want)
                     .map_err(|_| PciError::CreateMmioError)?;
                 space_guard = Arc::new(tmp);
-                kdebug!("Pci bar init: mmio space: {space_guard:?}, paddr={paddr:?}, size_want={size_want}");
+                //kdebug!("Pci bar init: mmio space: {space_guard:?}, paddr={paddr:?}, size_want={size_want}");
                 assert!(
                     space_guard.map_phys(paddr, size_want).is_ok(),
                     "pci_bar_init: map_phys failed"
@@ -1447,7 +1447,7 @@ pub fn pci_bar_init(
             _ => {}
         }
     }
-    kdebug!("pci_device_bar:{}", device_bar);
+    //kdebug!("pci_device_bar:{}", device_bar);
     return Ok(device_bar);
 }
 

+ 33 - 6
kernel/src/driver/pci/pci_irq.rs

@@ -23,11 +23,13 @@ struct MsixEntry {
     msg_data: Volatile<u32>,
     vector_control: Volatile<u32>,
 }
+
 /// Pending表的一项
 #[repr(C)]
 struct PendingEntry {
     entry: Volatile<u64>,
 }
+
 /// PCI设备中断错误
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum PciIrqError {
@@ -44,6 +46,7 @@ pub enum PciIrqError {
     MaskNotSupported,
     IrqNotInited,
 }
+
 /// PCI设备的中断类型
 #[derive(Copy, Clone, Debug)]
 pub enum IrqType {
@@ -64,21 +67,42 @@ pub enum IrqType {
     Legacy,
     Unused,
 }
+
 // PCI设备install中断时需要传递的参数
 #[derive(Clone, Debug)]
 pub struct IrqMsg {
     pub irq_common_message: IrqCommonMsg,
     pub irq_specific_message: IrqSpecificMsg,
 }
+
 // PCI设备install中断时需要传递的共同参数
 #[derive(Clone, Debug)]
 pub struct IrqCommonMsg {
-    pub irq_index: u16,     //要install的中断号在PCI设备中的irq_vector的index
-    pub irq_name: CString,  //中断名字
-    pub irq_parameter: u16, //中断额外参数,可传入中断处理函数
-    pub irq_hander: unsafe extern "C" fn(irq_num: ul, parameter: ul, regs: *mut pt_regs), // 中断处理函数
-    pub irq_ack: Option<unsafe extern "C" fn(irq_num: ul)>, // 中断的ack,可为None,若为None则中断处理中会正常通知中断结束,不为None则调用传入的函数进行回复
+    irq_index: u16,     //要install的中断号在PCI设备中的irq_vector的index
+    irq_name: CString,  //中断名字
+    irq_parameter: u16, //中断额外参数,可传入中断处理函数
+    irq_hander: unsafe extern "C" fn(irq_num: ul, parameter: ul, regs: *mut pt_regs), // 中断处理函数
+    irq_ack: Option<unsafe extern "C" fn(irq_num: ul)>, // 中断的ack,可为None,若为None则中断处理中会正常通知中断结束,不为None则调用传入的函数进行回复
 }
+
+impl IrqCommonMsg {
+    pub fn init_from(
+        irq_index: u16,
+        irq_name: &str,
+        irq_parameter: u16,
+        irq_hander: unsafe extern "C" fn(irq_num: ul, parameter: ul, regs: *mut pt_regs),
+        irq_ack: Option<unsafe extern "C" fn(irq_num: ul)>,
+    ) -> Self {
+        IrqCommonMsg {
+            irq_index,
+            irq_name: CString::new(irq_name).expect("CString::new failed"),
+            irq_parameter,
+            irq_hander,
+            irq_ack,
+        }
+    }
+}
+
 // PCI设备install中断时需要传递的特有参数,Msi代表MSI与MSIX
 #[derive(Clone, Debug)]
 pub enum IrqSpecificMsg {
@@ -96,6 +120,7 @@ impl IrqSpecificMsg {
         }
     }
 }
+
 // 申请中断的触发模式,MSI默认为边沿触发
 #[derive(Copy, Clone, Debug)]
 pub enum TriggerMode {
@@ -103,6 +128,7 @@ pub enum TriggerMode {
     AssertHigh,
     AssertLow,
 }
+
 bitflags! {
     /// 设备中断类型,使用bitflag使得中断类型的选择更多元化
     pub struct IRQ: u8{
@@ -112,6 +138,7 @@ bitflags! {
         const PCI_IRQ_ALL_TYPES=IRQ::PCI_IRQ_LEGACY.bits|IRQ::PCI_IRQ_MSI.bits|IRQ::PCI_IRQ_MSIX.bits;
     }
 }
+
 /// PciDeviceStructure的子trait,使用继承以直接使用PciDeviceStructure里的接口
 pub trait PciInterrupt: PciDeviceStructure {
     /// @brief PCI设备调用该函数选择中断类型
@@ -510,7 +537,7 @@ pub trait PciInterrupt: PciDeviceStructure {
                         + msix_table_offset as usize
                         + msg.irq_common_message.irq_index as usize * size_of::<MsixEntry>();
                     let msix_entry = NonNull::new(vaddr.data() as *mut MsixEntry).unwrap();
-                    kdebug!("msg_data: {:?}, msix_addr: {:?}", msg_data, msg_address);
+                    // 这里的操作并不适用于所有架构,需要再优化,msg_upper_data并不一定为0
                     unsafe {
                         volwrite!(msix_entry, vector_control, 0);
                         volwrite!(msix_entry, msg_data, msg_data);

+ 9 - 14
kernel/src/driver/virtio/transport_pci.rs

@@ -7,13 +7,11 @@ use crate::driver::pci::pci::{
 
 use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqMsg, IrqSpecificMsg, PciInterrupt, IRQ};
 use crate::include::bindings::bindings::pt_regs;
-
 use crate::libs::volatile::{
     volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
 };
 use crate::mm::VirtAddr;
 use crate::net::net_core::poll_ifaces_try_lock_onetime;
-use alloc::ffi::CString;
 use core::{
     fmt::{self, Display, Formatter},
     mem::{align_of, size_of},
@@ -62,7 +60,7 @@ const VIRTIO_PCI_CAP_DEVICE_CFG: u8 = 4;
 const VIRTIO_RECV_VECTOR: u16 = 56;
 /// Virtio设备接收中断的设备号的表项号
 const VIRTIO_RECV_VECTOR_INDEX: u16 = 0;
-// 接收的queue
+// 接收的queue
 const QUEUE_RECEIVE: u16 = 0;
 ///@brief device id 转换为设备类型
 ///@param pci_device_id,device_id
@@ -136,17 +134,13 @@ impl PciTransport {
             .expect("IRQ init failed");
         // 中断相关信息
         let msg = IrqMsg {
-            irq_common_message: IrqCommonMsg {
-                irq_index: 0,
-                irq_name: CString::new(
-                    "Virtio_Recv_
-                IRQ",
-                )
-                .expect("CString::new failed"),
-                irq_parameter: 0,
-                irq_hander: virtio_irq_hander,
-                irq_ack: None,
-            },
+            irq_common_message: IrqCommonMsg::init_from(
+                0,
+                "Virtio_Recv_IRQ",
+                0,
+                virtio_irq_hander,
+                None,
+            ),
             irq_specific_message: IrqSpecificMsg::msi_default(),
         };
         standard_device.irq_install(msg)?;
@@ -314,6 +308,7 @@ impl Transport for PciTransport {
             volwrite!(self.common_cfg, queue_desc, descriptors as u64);
             volwrite!(self.common_cfg, queue_driver, driver_area as u64);
             volwrite!(self.common_cfg, queue_device, device_area as u64);
+            // 这里设置队列中断对应的中断项
             if queue == QUEUE_RECEIVE {
                 volwrite!(self.common_cfg, queue_msix_vector, VIRTIO_RECV_VECTOR_INDEX);
                 let vector = volread!(self.common_cfg, queue_msix_vector);

+ 1 - 1
kernel/src/net/net_core.rs

@@ -162,7 +162,7 @@ pub fn poll_ifaces_try_lock(times: u16) -> Result<(), SystemError> {
     return Err(SystemError::EAGAIN_OR_EWOULDBLOCK);
 }
 
-/// 对ifaces进行轮询。
+/// 对ifaces进行轮询,最多对SOCKET_SET尝试一次加锁
 ///
 /// @return 轮询成功,返回Ok(())
 /// @return 加锁超时,返回SystemError::EAGAIN_OR_EWOULDBLOCK