mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-08 18:26:48 +00:00
parent
876cb89ecf
commit
afc95d5c25
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user