From afc95d5c2541c27c762091ad38fdffabe355db5a Mon Sep 17 00:00:00 2001 From: YJwu2023 Date: Tue, 3 Oct 2023 12:09:29 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84pci=E4=B8=AD=E6=96=AD?= =?UTF-8?q?=E7=9A=84=E8=AE=BE=E8=AE=A1=20(#392)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 完善pci中断的设计 --- kernel/src/driver/pci/pci.rs | 6 ++-- kernel/src/driver/pci/pci_irq.rs | 39 +++++++++++++++++++---- kernel/src/driver/virtio/transport_pci.rs | 23 ++++++------- kernel/src/net/net_core.rs | 2 +- 4 files changed, 46 insertions(+), 24 deletions(-) diff --git a/kernel/src/driver/pci/pci.rs b/kernel/src/driver/pci/pci.rs index 97c78b25..4c8cd567 100644 --- a/kernel/src/driver/pci/pci.rs +++ b/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); } diff --git a/kernel/src/driver/pci/pci_irq.rs b/kernel/src/driver/pci/pci_irq.rs index 50e8d294..84b28a09 100644 --- a/kernel/src/driver/pci/pci_irq.rs +++ b/kernel/src/driver/pci/pci_irq.rs @@ -23,11 +23,13 @@ struct MsixEntry { msg_data: Volatile, vector_control: Volatile, } + /// Pending表的一项 #[repr(C)] struct PendingEntry { entry: Volatile, } + /// 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, // 中断的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, // 中断的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, + ) -> 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::(); 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); diff --git a/kernel/src/driver/virtio/transport_pci.rs b/kernel/src/driver/virtio/transport_pci.rs index 5f83460a..79a58e71 100644 --- a/kernel/src/driver/virtio/transport_pci.rs +++ b/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); diff --git a/kernel/src/net/net_core.rs b/kernel/src/net/net_core.rs index ae28be88..9c51b433 100644 --- a/kernel/src/net/net_core.rs +++ b/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