完善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 {
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);
}

View File

@ -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);

View File

@ -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_iddevice_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);

View File

@ -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