mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 02:46:47 +00:00
parent
876cb89ecf
commit
afc95d5c25
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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_id,device_id
|
///@param pci_device_id,device_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);
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user