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

* 完善pci中断的设计
This commit is contained in:
YJwu2023 2023-10-03 12:09:29 +08:00 committed by GitHub
parent 876cb89ecf
commit afc95d5c25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 24 deletions

View File

@ -1335,7 +1335,7 @@ impl Display for PciStandardDeviceBar {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
write!( write!(
f, 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 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) .create_mmio(size_want)
.map_err(|_| PciError::CreateMmioError)?; .map_err(|_| PciError::CreateMmioError)?;
space_guard = Arc::new(tmp); 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!( assert!(
space_guard.map_phys(paddr, size_want).is_ok(), space_guard.map_phys(paddr, size_want).is_ok(),
"pci_bar_init: map_phys failed" "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); return Ok(device_bar);
} }

View File

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

View File

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

View File

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