mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 07:06:47 +00:00
feat(pci): 解决了pci总线子系统中pci结构一致性问题,增加了pci设备的可读属性 (#1009)
--------- Co-authored-by: 黄铭涛 <1037827920@qq.com>
This commit is contained in:
parent
20c58101dd
commit
69715438f2
@ -2,23 +2,22 @@
|
|||||||
pub mod ahci_inode;
|
pub mod ahci_inode;
|
||||||
pub mod ahcidisk;
|
pub mod ahcidisk;
|
||||||
pub mod hba;
|
pub mod hba;
|
||||||
|
|
||||||
use crate::arch::MMArch;
|
use crate::arch::MMArch;
|
||||||
use crate::driver::base::block::manager::block_dev_manager;
|
use crate::driver::base::block::manager::block_dev_manager;
|
||||||
use crate::driver::block::cache::cached_block_device::BlockCache;
|
use crate::driver::block::cache::cached_block_device::BlockCache;
|
||||||
use crate::driver::disk::ahci::ahcidisk::LockedAhciDisk;
|
use crate::driver::disk::ahci::ahcidisk::LockedAhciDisk;
|
||||||
use crate::driver::pci::pci::{
|
use crate::driver::pci::pci::{
|
||||||
get_pci_device_structure_mut, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
|
get_pci_device_structure_mut, PciDeviceLinkedList, PciDeviceStructure, PCI_DEVICE_LINKEDLIST,
|
||||||
};
|
};
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
|
||||||
use crate::driver::disk::ahci::{
|
use crate::driver::disk::ahci::{
|
||||||
hba::HbaMem,
|
hba::HbaMem,
|
||||||
hba::{HbaPort, HbaPortType},
|
hba::{HbaPort, HbaPortType},
|
||||||
};
|
};
|
||||||
use crate::libs::rwlock::RwLockWriteGuard;
|
|
||||||
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
|
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
|
||||||
use crate::mm::{MemoryManagementArch, VirtAddr};
|
use crate::mm::{MemoryManagementArch, VirtAddr};
|
||||||
use alloc::{boxed::Box, collections::LinkedList, vec::Vec};
|
use alloc::{boxed::Box, vec::Vec};
|
||||||
use core::sync::atomic::compiler_fence;
|
use core::sync::atomic::compiler_fence;
|
||||||
use log::debug;
|
use log::debug;
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
@ -36,9 +35,9 @@ pub const HBA_PxIS_TFES: u32 = 1 << 30;
|
|||||||
/// @brief 寻找所有的ahci设备
|
/// @brief 寻找所有的ahci设备
|
||||||
/// @param list 链表的写锁
|
/// @param list 链表的写锁
|
||||||
/// @return Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> 成功则返回包含所有ahci设备结构体的可变引用的链表,失败则返回err
|
/// @return Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> 成功则返回包含所有ahci设备结构体的可变引用的链表,失败则返回err
|
||||||
fn ahci_device_search<'a>(
|
fn ahci_device_search(
|
||||||
list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
|
list: &PciDeviceLinkedList,
|
||||||
) -> Result<Vec<&'a mut Box<dyn PciDeviceStructure>>, SystemError> {
|
) -> Result<Vec<Arc<dyn PciDeviceStructure>>, SystemError> {
|
||||||
let result = get_pci_device_structure_mut(list, AHCI_CLASS, AHCI_SUBCLASS);
|
let result = get_pci_device_structure_mut(list, AHCI_CLASS, AHCI_SUBCLASS);
|
||||||
|
|
||||||
if result.is_empty() {
|
if result.is_empty() {
|
||||||
@ -50,11 +49,11 @@ fn ahci_device_search<'a>(
|
|||||||
|
|
||||||
/// @brief: 初始化 ahci
|
/// @brief: 初始化 ahci
|
||||||
pub fn ahci_init() -> Result<(), SystemError> {
|
pub fn ahci_init() -> Result<(), SystemError> {
|
||||||
let mut list = PCI_DEVICE_LINKEDLIST.write();
|
let list = &*PCI_DEVICE_LINKEDLIST;
|
||||||
let ahci_device = ahci_device_search(&mut list)?;
|
let ahci_device = ahci_device_search(list)?;
|
||||||
|
|
||||||
for device in ahci_device {
|
for device in ahci_device {
|
||||||
let standard_device = device.as_standard_device_mut().unwrap();
|
let standard_device = device.as_standard_device().unwrap();
|
||||||
standard_device.bar_ioremap();
|
standard_device.bar_ioremap();
|
||||||
// 对于每一个ahci控制器分配一块空间
|
// 对于每一个ahci控制器分配一块空间
|
||||||
let ahci_port_base_vaddr =
|
let ahci_port_base_vaddr =
|
||||||
@ -62,6 +61,7 @@ pub fn ahci_init() -> Result<(), SystemError> {
|
|||||||
let virtaddr = standard_device
|
let virtaddr = standard_device
|
||||||
.bar()
|
.bar()
|
||||||
.ok_or(SystemError::EACCES)?
|
.ok_or(SystemError::EACCES)?
|
||||||
|
.read()
|
||||||
.get_bar(5)
|
.get_bar(5)
|
||||||
.or(Err(SystemError::EACCES))?
|
.or(Err(SystemError::EACCES))?
|
||||||
.virtual_address()
|
.virtual_address()
|
||||||
|
@ -1,16 +1,6 @@
|
|||||||
// 参考手册: PCIe* GbE Controllers Open Source Software Developer’s Manual
|
// 参考手册: PCIe* GbE Controllers Open Source Software Developer’s Manual
|
||||||
// Refernce: PCIe* GbE Controllers Open Source Software Developer’s Manual
|
// Refernce: PCIe* GbE Controllers Open Source Software Developer’s Manual
|
||||||
|
|
||||||
use alloc::string::ToString;
|
|
||||||
use alloc::sync::Arc;
|
|
||||||
use alloc::vec::Vec;
|
|
||||||
use core::intrinsics::unlikely;
|
|
||||||
use core::mem::size_of;
|
|
||||||
use core::ptr::NonNull;
|
|
||||||
use core::slice::{from_raw_parts, from_raw_parts_mut};
|
|
||||||
use core::sync::atomic::{compiler_fence, Ordering};
|
|
||||||
use log::{debug, info};
|
|
||||||
|
|
||||||
use super::e1000e_driver::e1000e_driver_init;
|
use super::e1000e_driver::e1000e_driver_init;
|
||||||
use crate::driver::base::device::DeviceId;
|
use crate::driver::base::device::DeviceId;
|
||||||
use crate::driver::net::dma::{dma_alloc, dma_dealloc};
|
use crate::driver::net::dma::{dma_alloc, dma_dealloc};
|
||||||
@ -21,6 +11,15 @@ use crate::driver::pci::pci::{
|
|||||||
};
|
};
|
||||||
use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqSpecificMsg, PciInterrupt, PciIrqMsg, IRQ};
|
use crate::driver::pci::pci_irq::{IrqCommonMsg, IrqSpecificMsg, PciInterrupt, PciIrqMsg, IRQ};
|
||||||
use crate::exception::IrqNumber;
|
use crate::exception::IrqNumber;
|
||||||
|
use alloc::string::ToString;
|
||||||
|
use alloc::sync::Arc;
|
||||||
|
use alloc::vec::Vec;
|
||||||
|
use core::intrinsics::unlikely;
|
||||||
|
use core::mem::size_of;
|
||||||
|
use core::ptr::NonNull;
|
||||||
|
use core::slice::{from_raw_parts, from_raw_parts_mut};
|
||||||
|
use core::sync::atomic::{compiler_fence, Ordering};
|
||||||
|
use log::{debug, info};
|
||||||
|
|
||||||
use crate::libs::volatile::{ReadOnly, Volatile, WriteOnly};
|
use crate::libs::volatile::{ReadOnly, Volatile, WriteOnly};
|
||||||
|
|
||||||
@ -200,14 +199,14 @@ impl E1000EDevice {
|
|||||||
// init the device for PCI standard device struct
|
// init the device for PCI standard device struct
|
||||||
#[allow(unused_assignments)]
|
#[allow(unused_assignments)]
|
||||||
pub fn new(
|
pub fn new(
|
||||||
device: &mut PciDeviceStructureGeneralDevice,
|
device: Arc<PciDeviceStructureGeneralDevice>,
|
||||||
device_id: Arc<DeviceId>,
|
device_id: Arc<DeviceId>,
|
||||||
) -> Result<Self, E1000EPciError> {
|
) -> Result<Self, E1000EPciError> {
|
||||||
// 从BAR0获取我们需要的寄存器
|
// 从BAR0获取我们需要的寄存器
|
||||||
// Build registers sturcts from BAR0
|
// Build registers sturcts from BAR0
|
||||||
device.bar_ioremap().unwrap()?;
|
device.bar_ioremap().unwrap()?;
|
||||||
device.enable_master();
|
device.enable_master();
|
||||||
let bar = device.bar().ok_or(E1000EPciError::BarGetFailed)?;
|
let bar = device.bar().ok_or(E1000EPciError::BarGetFailed)?.read();
|
||||||
let bar0 = bar.get_bar(0)?;
|
let bar0 = bar.get_bar(0)?;
|
||||||
let (address, size) = bar0
|
let (address, size) = bar0
|
||||||
.memory_address_size()
|
.memory_address_size()
|
||||||
@ -226,7 +225,7 @@ impl E1000EDevice {
|
|||||||
// 初始化msi中断
|
// 初始化msi中断
|
||||||
// initialize msi interupt
|
// initialize msi interupt
|
||||||
let irq_vector = device.irq_vector_mut().unwrap();
|
let irq_vector = device.irq_vector_mut().unwrap();
|
||||||
irq_vector.push(E1000E_RECV_VECTOR);
|
irq_vector.write().push(E1000E_RECV_VECTOR);
|
||||||
device.irq_init(IRQ::PCI_IRQ_MSI).expect("IRQ Init Failed");
|
device.irq_init(IRQ::PCI_IRQ_MSI).expect("IRQ Init Failed");
|
||||||
let msg = PciIrqMsg {
|
let msg = PciIrqMsg {
|
||||||
irq_common_message: IrqCommonMsg::init_from(
|
irq_common_message: IrqCommonMsg::init_from(
|
||||||
@ -598,26 +597,32 @@ pub fn e1000e_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn e1000e_probe() -> Result<u64, E1000EPciError> {
|
pub fn e1000e_probe() -> Result<u64, E1000EPciError> {
|
||||||
let mut list = PCI_DEVICE_LINKEDLIST.write();
|
let list = &*PCI_DEVICE_LINKEDLIST;
|
||||||
let result = get_pci_device_structure_mut(&mut list, NETWORK_CLASS, ETHERNET_SUBCLASS);
|
let result = get_pci_device_structure_mut(list, NETWORK_CLASS, ETHERNET_SUBCLASS);
|
||||||
if result.is_empty() {
|
if result.is_empty() {
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
for device in result {
|
for device in result {
|
||||||
let standard_device = device.as_standard_device_mut().unwrap();
|
let standard_device = device.as_standard_device().unwrap();
|
||||||
let header = &standard_device.common_header;
|
if standard_device.common_header.vendor_id == 0x8086 {
|
||||||
if header.vendor_id == 0x8086 {
|
|
||||||
// intel
|
// intel
|
||||||
if E1000E_DEVICE_ID.contains(&header.device_id) {
|
if E1000E_DEVICE_ID.contains(&standard_device.common_header.device_id) {
|
||||||
debug!(
|
debug!(
|
||||||
"Detected e1000e PCI device with device id {:#x}",
|
"Detected e1000e PCI device with device id {:#x}",
|
||||||
header.device_id
|
standard_device.common_header.device_id
|
||||||
);
|
);
|
||||||
|
|
||||||
// todo: 根据pci的path来生成device id
|
// todo: 根据pci的path来生成device id
|
||||||
let e1000e = E1000EDevice::new(
|
let e1000e = E1000EDevice::new(
|
||||||
standard_device,
|
standard_device.clone(),
|
||||||
DeviceId::new(None, Some(format!("e1000e_{}", header.device_id))).unwrap(),
|
DeviceId::new(
|
||||||
|
None,
|
||||||
|
Some(format!(
|
||||||
|
"e1000e_{}",
|
||||||
|
standard_device.common_header.device_id
|
||||||
|
)),
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
)?;
|
)?;
|
||||||
e1000e_driver_init(e1000e);
|
e1000e_driver_init(e1000e);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::device::PciDevice;
|
use super::{device::PciDevice, pci_irq::IrqType};
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct BasicPciReadOnlyAttrs;
|
pub struct BasicPciReadOnlyAttrs;
|
||||||
|
|
||||||
@ -23,7 +23,16 @@ impl AttributeGroup for BasicPciReadOnlyAttrs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn attrs(&self) -> &[&'static dyn Attribute] {
|
fn attrs(&self) -> &[&'static dyn Attribute] {
|
||||||
&[&Vendor, &DeviceID, &SubsystemVendor, &SubsystemDevice]
|
&[
|
||||||
|
&Vendor,
|
||||||
|
&DeviceID,
|
||||||
|
&SubsystemVendor,
|
||||||
|
&SubsystemDevice,
|
||||||
|
&Revision,
|
||||||
|
&Class,
|
||||||
|
&Irq,
|
||||||
|
&Modalias,
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_visible(
|
fn is_visible(
|
||||||
@ -36,7 +45,7 @@ impl AttributeGroup for BasicPciReadOnlyAttrs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Vendor;
|
struct Vendor;
|
||||||
|
|
||||||
impl Attribute for Vendor {
|
impl Attribute for Vendor {
|
||||||
fn mode(&self) -> ModeType {
|
fn mode(&self) -> ModeType {
|
||||||
@ -67,7 +76,7 @@ impl Attribute for Vendor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct DeviceID;
|
struct DeviceID;
|
||||||
|
|
||||||
impl Attribute for DeviceID {
|
impl Attribute for DeviceID {
|
||||||
fn mode(&self) -> ModeType {
|
fn mode(&self) -> ModeType {
|
||||||
@ -98,7 +107,7 @@ impl Attribute for DeviceID {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SubsystemVendor;
|
struct SubsystemVendor;
|
||||||
|
|
||||||
impl Attribute for SubsystemVendor {
|
impl Attribute for SubsystemVendor {
|
||||||
fn mode(&self) -> ModeType {
|
fn mode(&self) -> ModeType {
|
||||||
@ -129,7 +138,7 @@ impl Attribute for SubsystemVendor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct SubsystemDevice;
|
struct SubsystemDevice;
|
||||||
|
|
||||||
impl Attribute for SubsystemDevice {
|
impl Attribute for SubsystemDevice {
|
||||||
fn mode(&self) -> ModeType {
|
fn mode(&self) -> ModeType {
|
||||||
@ -158,3 +167,143 @@ impl Attribute for SubsystemDevice {
|
|||||||
SysFSOpsSupport::ATTR_SHOW
|
SysFSOpsSupport::ATTR_SHOW
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Revision;
|
||||||
|
|
||||||
|
impl Attribute for Revision {
|
||||||
|
fn mode(&self) -> ModeType {
|
||||||
|
SYSFS_ATTR_MODE_RO
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"revision"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||||
|
let dev = _kobj
|
||||||
|
.cast::<dyn PciDevice>()
|
||||||
|
.map_err(|e: Arc<dyn KObject>| {
|
||||||
|
warn!("device:{:?} is not a pci device!", e);
|
||||||
|
SystemError::EINVAL
|
||||||
|
})?;
|
||||||
|
return sysfs_emit_str(_buf, &format!("0x{:02x}", dev.revision()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn support(&self) -> SysFSOpsSupport {
|
||||||
|
SysFSOpsSupport::ATTR_SHOW
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Class;
|
||||||
|
|
||||||
|
impl Attribute for Class {
|
||||||
|
fn mode(&self) -> ModeType {
|
||||||
|
SYSFS_ATTR_MODE_RO
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"class"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||||
|
let dev = _kobj
|
||||||
|
.cast::<dyn PciDevice>()
|
||||||
|
.map_err(|e: Arc<dyn KObject>| {
|
||||||
|
warn!("device:{:?} is not a pci device!", e);
|
||||||
|
SystemError::EINVAL
|
||||||
|
})?;
|
||||||
|
return sysfs_emit_str(_buf, &format!("0x{:06x}", dev.class_code()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn support(&self) -> SysFSOpsSupport {
|
||||||
|
SysFSOpsSupport::ATTR_SHOW
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Irq;
|
||||||
|
|
||||||
|
impl Attribute for Irq {
|
||||||
|
fn mode(&self) -> ModeType {
|
||||||
|
SYSFS_ATTR_MODE_RO
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"irq"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||||
|
let dev = _kobj
|
||||||
|
.cast::<dyn PciDevice>()
|
||||||
|
.map_err(|e: Arc<dyn KObject>| {
|
||||||
|
warn!("device:{:?} is not a pci device!", e);
|
||||||
|
SystemError::EINVAL
|
||||||
|
})?;
|
||||||
|
if let IrqType::Msi { .. } = *dev.irq_type().read() {
|
||||||
|
// 见https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/pci/pci-sysfs.c#55
|
||||||
|
return sysfs_emit_str(_buf, "todo:sry,msi device is unimplemented now");
|
||||||
|
}
|
||||||
|
return sysfs_emit_str(_buf, &format!("{}", dev.irq_line()));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn support(&self) -> SysFSOpsSupport {
|
||||||
|
SysFSOpsSupport::ATTR_SHOW
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct Modalias;
|
||||||
|
|
||||||
|
impl Attribute for Modalias {
|
||||||
|
fn mode(&self) -> ModeType {
|
||||||
|
SYSFS_ATTR_MODE_RO
|
||||||
|
}
|
||||||
|
|
||||||
|
fn name(&self) -> &str {
|
||||||
|
"modalias"
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show(&self, _kobj: Arc<dyn KObject>, _buf: &mut [u8]) -> Result<usize, SystemError> {
|
||||||
|
let dev = _kobj
|
||||||
|
.cast::<dyn PciDevice>()
|
||||||
|
.map_err(|e: Arc<dyn KObject>| {
|
||||||
|
warn!("device:{:?} is not a pci device!", e);
|
||||||
|
SystemError::EINVAL
|
||||||
|
})?;
|
||||||
|
return sysfs_emit_str(
|
||||||
|
_buf,
|
||||||
|
&format!(
|
||||||
|
"pci:v{:08X}d{:08X}sv{:08X}sd{:08X}bc{:02X}sc{:02X}i{:02X}",
|
||||||
|
dev.vendor(),
|
||||||
|
dev.device_id(),
|
||||||
|
dev.subsystem_vendor(),
|
||||||
|
dev.subsystem_device(),
|
||||||
|
dev.class_code(),
|
||||||
|
dev.subclass(),
|
||||||
|
dev.interface_code(),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn store(&self, _kobj: Arc<dyn KObject>, _buf: &[u8]) -> Result<usize, SystemError> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn support(&self) -> SysFSOpsSupport {
|
||||||
|
SysFSOpsSupport::ATTR_SHOW
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -14,13 +14,14 @@ use crate::{
|
|||||||
},
|
},
|
||||||
filesystem::kernfs::KernFSInode,
|
filesystem::kernfs::KernFSInode,
|
||||||
libs::{
|
libs::{
|
||||||
rwlock::RwLockWriteGuard,
|
rwlock::{RwLock, RwLockWriteGuard},
|
||||||
spinlock::{SpinLock, SpinLockGuard},
|
spinlock::{SpinLock, SpinLockGuard},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
dev_id::PciDeviceID,
|
dev_id::PciDeviceID,
|
||||||
|
pci_irq::IrqType,
|
||||||
subsys::{pci_bus, pci_bus_device},
|
subsys::{pci_bus, pci_bus_device},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -83,6 +84,12 @@ pub trait PciDevice: Device {
|
|||||||
fn device_id(&self) -> u16;
|
fn device_id(&self) -> u16;
|
||||||
fn subsystem_vendor(&self) -> u16;
|
fn subsystem_vendor(&self) -> u16;
|
||||||
fn subsystem_device(&self) -> u16;
|
fn subsystem_device(&self) -> u16;
|
||||||
|
fn revision(&self) -> u8;
|
||||||
|
fn class_code(&self) -> u8;
|
||||||
|
fn irq_type(&self) -> &RwLock<IrqType>;
|
||||||
|
fn irq_line(&self) -> u8;
|
||||||
|
fn subclass(&self) -> u8;
|
||||||
|
fn interface_code(&self) -> u8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// #结构功能
|
/// #结构功能
|
||||||
|
@ -16,7 +16,7 @@ use crate::mm::mmio_buddy::{mmio_pool, MMIOSpaceGuard};
|
|||||||
use crate::mm::VirtAddr;
|
use crate::mm::VirtAddr;
|
||||||
|
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::{Arc, Weak};
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use alloc::{boxed::Box, collections::LinkedList};
|
use alloc::{boxed::Box, collections::LinkedList};
|
||||||
use bitflags::bitflags;
|
use bitflags::bitflags;
|
||||||
@ -68,7 +68,7 @@ impl Debug for PciAddr {
|
|||||||
|
|
||||||
/// 添加了读写锁的链表,存储PCI设备结构体
|
/// 添加了读写锁的链表,存储PCI设备结构体
|
||||||
pub struct PciDeviceLinkedList {
|
pub struct PciDeviceLinkedList {
|
||||||
list: RwLock<LinkedList<Box<dyn PciDeviceStructure>>>,
|
list: RwLock<LinkedList<Arc<dyn PciDeviceStructure>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PciDeviceLinkedList {
|
impl PciDeviceLinkedList {
|
||||||
@ -80,12 +80,12 @@ impl PciDeviceLinkedList {
|
|||||||
}
|
}
|
||||||
/// @brief 获取可读的linkedlist(读锁守卫)
|
/// @brief 获取可读的linkedlist(读锁守卫)
|
||||||
/// @return RwLockReadGuard<LinkedList<Box<dyn PciDeviceStructure>>> 读锁守卫
|
/// @return RwLockReadGuard<LinkedList<Box<dyn PciDeviceStructure>>> 读锁守卫
|
||||||
pub fn read(&self) -> RwLockReadGuard<LinkedList<Box<dyn PciDeviceStructure>>> {
|
pub fn read(&self) -> RwLockReadGuard<LinkedList<Arc<dyn PciDeviceStructure>>> {
|
||||||
self.list.read()
|
self.list.read()
|
||||||
}
|
}
|
||||||
/// @brief 获取可写的linkedlist(写锁守卫)
|
/// @brief 获取可写的linkedlist(写锁守卫)
|
||||||
/// @return RwLockWriteGuard<LinkedList<Box<dyn PciDeviceStructure>>> 写锁守卫
|
/// @return RwLockWriteGuard<LinkedList<Box<dyn PciDeviceStructure>>> 写锁守卫
|
||||||
pub fn write(&self) -> RwLockWriteGuard<LinkedList<Box<dyn PciDeviceStructure>>> {
|
pub fn write(&self) -> RwLockWriteGuard<LinkedList<Arc<dyn PciDeviceStructure>>> {
|
||||||
self.list.write()
|
self.list.write()
|
||||||
}
|
}
|
||||||
/// @brief 获取链表中PCI结构体数目
|
/// @brief 获取链表中PCI结构体数目
|
||||||
@ -95,7 +95,7 @@ impl PciDeviceLinkedList {
|
|||||||
list.len()
|
list.len()
|
||||||
}
|
}
|
||||||
/// @brief 添加Pci设备结构体到链表中
|
/// @brief 添加Pci设备结构体到链表中
|
||||||
pub fn add(&self, device: Box<dyn PciDeviceStructure>) {
|
pub fn add(&self, device: Arc<dyn PciDeviceStructure>) {
|
||||||
let mut list = self.list.write();
|
let mut list = self.list.write();
|
||||||
list.push_back(device);
|
list.push_back(device);
|
||||||
}
|
}
|
||||||
@ -113,15 +113,14 @@ impl PciDeviceLinkedList {
|
|||||||
/// ## 返回值
|
/// ## 返回值
|
||||||
///
|
///
|
||||||
/// - 返回匹配的供应商ID的PCI设备结构的引用。
|
/// - 返回匹配的供应商ID的PCI设备结构的引用。
|
||||||
pub fn get_pci_device_structures_mut_by_vendor_id<'a>(
|
pub fn get_pci_device_structures_mut_by_vendor_id(
|
||||||
list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
|
list: &PciDeviceLinkedList,
|
||||||
vendor_id: u16,
|
vendor_id: u16,
|
||||||
) -> Vec<&'a mut Box<(dyn PciDeviceStructure)>> {
|
) -> Vec<Arc<(dyn PciDeviceStructure)>> {
|
||||||
let mut result = Vec::new();
|
let mut result: Vec<Arc<(dyn PciDeviceStructure)>> = Vec::new();
|
||||||
for box_pci_device_structure in list.iter_mut() {
|
for box_pci_device_structure in list.write().iter() {
|
||||||
let common_header = (*box_pci_device_structure).common_header();
|
if box_pci_device_structure.common_header().vendor_id == vendor_id {
|
||||||
if common_header.vendor_id == vendor_id {
|
result.push(box_pci_device_structure.clone());
|
||||||
result.push(box_pci_device_structure);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
@ -140,16 +139,17 @@ pub fn get_pci_device_structures_mut_by_vendor_id<'a>(
|
|||||||
///
|
///
|
||||||
/// ## 返回值
|
/// ## 返回值
|
||||||
/// - 包含链表中所有满足条件的PCI结构体的可变引用的容器。
|
/// - 包含链表中所有满足条件的PCI结构体的可变引用的容器。
|
||||||
pub fn get_pci_device_structure_mut<'a>(
|
pub fn get_pci_device_structure_mut(
|
||||||
list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
|
list: &PciDeviceLinkedList,
|
||||||
class_code: u8,
|
class_code: u8,
|
||||||
subclass: u8,
|
subclass: u8,
|
||||||
) -> Vec<&'a mut Box<(dyn PciDeviceStructure)>> {
|
) -> Vec<Arc<dyn PciDeviceStructure>> {
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
for box_pci_device_structure in list.iter_mut() {
|
for box_pci_device_structure in list.write().iter() {
|
||||||
let common_header = (*box_pci_device_structure).common_header();
|
if (box_pci_device_structure.common_header().class_code == class_code)
|
||||||
if (common_header.class_code == class_code) && (common_header.subclass == subclass) {
|
&& (box_pci_device_structure.common_header().subclass == subclass)
|
||||||
result.push(box_pci_device_structure);
|
{
|
||||||
|
result.push(box_pci_device_structure.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
@ -317,7 +317,7 @@ pub trait PciDeviceStructure: Send + Sync {
|
|||||||
fn header_type(&self) -> HeaderType;
|
fn header_type(&self) -> HeaderType;
|
||||||
/// @brief 当其为standard设备时返回&Pci_Device_Structure_General_Device,其余情况返回None
|
/// @brief 当其为standard设备时返回&Pci_Device_Structure_General_Device,其余情况返回None
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_standard_device(&self) -> Option<&PciDeviceStructureGeneralDevice> {
|
fn as_standard_device(&self) -> Option<Arc<PciDeviceStructureGeneralDevice>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
/// @brief 当其为pci to pci bridge设备时返回&Pci_Device_Structure_Pci_to_Pci_Bridge,其余情况返回None
|
/// @brief 当其为pci to pci bridge设备时返回&Pci_Device_Structure_Pci_to_Pci_Bridge,其余情况返回None
|
||||||
@ -333,21 +333,14 @@ pub trait PciDeviceStructure: Send + Sync {
|
|||||||
/// @brief 获取Pci设备共有的common_header
|
/// @brief 获取Pci设备共有的common_header
|
||||||
/// @return 返回其不可变引用
|
/// @return 返回其不可变引用
|
||||||
fn common_header(&self) -> &PciDeviceStructureHeader;
|
fn common_header(&self) -> &PciDeviceStructureHeader;
|
||||||
/// @brief 当其为standard设备时返回&mut Pci_Device_Structure_General_Device,其余情况返回None
|
|
||||||
#[inline(always)]
|
|
||||||
fn as_standard_device_mut(&mut self) -> Option<&mut PciDeviceStructureGeneralDevice> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
/// @brief 当其为pci to pci bridge设备时返回&mut Pci_Device_Structure_Pci_to_Pci_Bridge,其余情况返回None
|
/// @brief 当其为pci to pci bridge设备时返回&mut Pci_Device_Structure_Pci_to_Pci_Bridge,其余情况返回None
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_pci_to_pci_bridge_device_mut(&mut self) -> Option<&mut PciDeviceStructurePciToPciBridge> {
|
fn as_pci_to_pci_bridge_device_mut(&self) -> Option<&PciDeviceStructurePciToPciBridge> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
/// @brief 当其为pci to cardbus bridge设备时返回&mut Pci_Device_Structure_Pci_to_Cardbus_Bridge,其余情况返回None
|
/// @brief 当其为pci to cardbus bridge设备时返回&mut Pci_Device_Structure_Pci_to_Cardbus_Bridge,其余情况返回None
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_pci_to_carbus_bridge_device_mut(
|
fn as_pci_to_carbus_bridge_device_mut(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> {
|
||||||
&mut self,
|
|
||||||
) -> Option<&mut PciDeviceStructurePciToCardbusBridge> {
|
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
/// @brief 返回迭代器,遍历capabilities
|
/// @brief 返回迭代器,遍历capabilities
|
||||||
@ -358,14 +351,14 @@ pub trait PciDeviceStructure: Send + Sync {
|
|||||||
fn status_command(&self) -> (Status, Command) {
|
fn status_command(&self) -> (Status, Command) {
|
||||||
let common_header = self.common_header();
|
let common_header = self.common_header();
|
||||||
let status = Status::from_bits_truncate(common_header.status);
|
let status = Status::from_bits_truncate(common_header.status);
|
||||||
let command = Command::from_bits_truncate(common_header.command);
|
let command = Command::from_bits_truncate(*common_header.command.read());
|
||||||
(status, command)
|
(status, command)
|
||||||
}
|
}
|
||||||
/// @brief 设置Command寄存器的值
|
/// @brief 设置Command寄存器的值
|
||||||
fn set_command(&mut self, command: Command) {
|
fn set_command(&self, command: Command) {
|
||||||
let common_header = self.common_header_mut();
|
let common_header = self.common_header_mut();
|
||||||
let command = command.bits();
|
let command = command.bits();
|
||||||
common_header.command = command;
|
*common_header.command.write() = command;
|
||||||
pci_root_0().write_config(
|
pci_root_0().write_config(
|
||||||
common_header.bus_device_function,
|
common_header.bus_device_function,
|
||||||
STATUS_COMMAND_OFFSET.into(),
|
STATUS_COMMAND_OFFSET.into(),
|
||||||
@ -374,22 +367,22 @@ pub trait PciDeviceStructure: Send + Sync {
|
|||||||
}
|
}
|
||||||
/// @brief 获取Pci设备共有的common_header
|
/// @brief 获取Pci设备共有的common_header
|
||||||
/// @return 返回其可变引用
|
/// @return 返回其可变引用
|
||||||
fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader;
|
fn common_header_mut(&self) -> &PciDeviceStructureHeader;
|
||||||
|
|
||||||
/// @brief 读取standard设备的bar寄存器,映射后将结果加入结构体的standard_device_bar变量
|
/// @brief 读取standard设备的bar寄存器,映射后将结果加入结构体的standard_device_bar变量
|
||||||
/// @return 只有standard设备才返回成功或者错误,其余返回None
|
/// @return 只有standard设备才返回成功或者错误,其余返回None
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn bar_ioremap(&mut self) -> Option<Result<u8, PciError>> {
|
fn bar_ioremap(&self) -> Option<Result<u8, PciError>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
/// @brief 获取PCI设备的bar寄存器的引用
|
/// @brief 获取PCI设备的bar寄存器的引用
|
||||||
/// @return
|
/// @return
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn bar(&mut self) -> Option<&PciStandardDeviceBar> {
|
fn bar(&self) -> Option<&RwLock<PciStandardDeviceBar>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
/// @brief 通过设置该pci设备的command
|
/// @brief 通过设置该pci设备的command
|
||||||
fn enable_master(&mut self) {
|
fn enable_master(&self) {
|
||||||
self.set_command(Command::IO_SPACE | Command::MEMORY_SPACE | Command::BUS_MASTER);
|
self.set_command(Command::IO_SPACE | Command::MEMORY_SPACE | Command::BUS_MASTER);
|
||||||
}
|
}
|
||||||
/// @brief 寻找设备的msix空间的offset
|
/// @brief 寻找设备的msix空间的offset
|
||||||
@ -411,21 +404,21 @@ pub trait PciDeviceStructure: Send + Sync {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
/// @brief 返回结构体中的irq_type的可变引用
|
/// @brief 返回结构体中的irq_type的可变引用
|
||||||
fn irq_type_mut(&mut self) -> Option<&mut IrqType>;
|
fn irq_type_mut(&self) -> Option<&RwLock<IrqType>>;
|
||||||
/// @brief 返回结构体中的irq_vector的可变引用
|
/// @brief 返回结构体中的irq_vector的可变引用
|
||||||
fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>>;
|
fn irq_vector_mut(&self) -> Option<&RwLock<Vec<IrqNumber>>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pci_Device_Structure_Header PCI设备结构体共有的头部
|
/// Pci_Device_Structure_Header PCI设备结构体共有的头部
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PciDeviceStructureHeader {
|
pub struct PciDeviceStructureHeader {
|
||||||
// ==== busdevicefunction变量表示该结构体所处的位置
|
// ==== busdevicefunction变量表示该结构体所处的位置
|
||||||
pub bus_device_function: BusDeviceFunction,
|
pub bus_device_function: BusDeviceFunction,
|
||||||
pub vendor_id: u16, // 供应商ID 0xffff是一个无效值,在读取访问不存在的设备的配置空间寄存器时返回
|
pub vendor_id: u16, // 供应商ID 0xffff是一个无效值,在读取访问不存在的设备的配置空间寄存器时返回
|
||||||
pub device_id: u16, // 设备ID,标志特定设备
|
pub device_id: u16, // 设备ID,标志特定设备
|
||||||
pub command: u16, // 提供对设备生成和响应pci周期的能力的控制 向该寄存器写入0时,设备与pci总线断开除配置空间访问以外的所有连接
|
pub command: RwLock<u16>, // 提供对设备生成和响应pci周期的能力的控制 向该寄存器写入0时,设备与pci总线断开除配置空间访问以外的所有连接
|
||||||
pub status: u16, // 用于记录pci总线相关时间的状态信息寄存器
|
pub status: u16, // 用于记录pci总线相关时间的状态信息寄存器
|
||||||
pub revision_id: u8, // 修订ID,指定特定设备的修订标志符
|
pub revision_id: u8, // 修订ID,指定特定设备的修订标志符
|
||||||
pub prog_if: u8, // 编程接口字节,一个只读寄存器,指定设备具有的寄存器级别的编程接口(如果有的话)
|
pub prog_if: u8, // 编程接口字节,一个只读寄存器,指定设备具有的寄存器级别的编程接口(如果有的话)
|
||||||
pub subclass: u8, // 子类。指定设备执行的特定功能的只读寄存器
|
pub subclass: u8, // 子类。指定设备执行的特定功能的只读寄存器
|
||||||
pub class_code: u8, // 类代码,一个只读寄存器,指定设备执行的功能类型
|
pub class_code: u8, // 类代码,一个只读寄存器,指定设备执行的功能类型
|
||||||
@ -440,14 +433,14 @@ pub struct PciDeviceStructureHeader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Pci_Device_Structure_General_Device PCI标准设备结构体
|
/// Pci_Device_Structure_General_Device PCI标准设备结构体
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PciDeviceStructureGeneralDevice {
|
pub struct PciDeviceStructureGeneralDevice {
|
||||||
pub common_header: PciDeviceStructureHeader,
|
pub common_header: PciDeviceStructureHeader,
|
||||||
// 中断结构体,包括legacy,msi,msix三种情况
|
// 中断结构体,包括legacy,msi,msix三种情况
|
||||||
pub irq_type: IrqType,
|
pub irq_type: RwLock<IrqType>,
|
||||||
// 使用的中断号的vec集合
|
// 使用的中断号的vec集合
|
||||||
pub irq_vector: Vec<IrqNumber>,
|
pub irq_vector: RwLock<Vec<IrqNumber>>,
|
||||||
pub standard_device_bar: PciStandardDeviceBar,
|
pub standard_device_bar: RwLock<PciStandardDeviceBar>,
|
||||||
pub cardbus_cis_pointer: u32, // 指向卡信息结构,供在 CardBus 和 PCI 之间共享芯片的设备使用。
|
pub cardbus_cis_pointer: u32, // 指向卡信息结构,供在 CardBus 和 PCI 之间共享芯片的设备使用。
|
||||||
pub subsystem_vendor_id: u16,
|
pub subsystem_vendor_id: u16,
|
||||||
pub subsystem_id: u16,
|
pub subsystem_id: u16,
|
||||||
@ -460,6 +453,7 @@ pub struct PciDeviceStructureGeneralDevice {
|
|||||||
pub interrupt_pin: u8, // 指定设备使用的中断引脚。其中值为0x1INTA#、0x2INTB#、0x3INTC#、0x4INTD#,0x0表示设备不使用中断引脚。
|
pub interrupt_pin: u8, // 指定设备使用的中断引脚。其中值为0x1INTA#、0x2INTB#、0x3INTC#、0x4INTD#,0x0表示设备不使用中断引脚。
|
||||||
pub min_grant: u8, // 一个只读寄存器,用于指定设备所需的突发周期长度(以 1/4 微秒为单位)(假设时钟速率为 33 MHz)
|
pub min_grant: u8, // 一个只读寄存器,用于指定设备所需的突发周期长度(以 1/4 微秒为单位)(假设时钟速率为 33 MHz)
|
||||||
pub max_latency: u8, // 一个只读寄存器,指定设备需要多长时间访问一次 PCI 总线(以 1/4 微秒为单位)。
|
pub max_latency: u8, // 一个只读寄存器,指定设备需要多长时间访问一次 PCI 总线(以 1/4 微秒为单位)。
|
||||||
|
pub self_ptr: RwLock<Weak<Self>>,
|
||||||
}
|
}
|
||||||
impl PciDeviceStructure for PciDeviceStructureGeneralDevice {
|
impl PciDeviceStructure for PciDeviceStructureGeneralDevice {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -467,20 +461,16 @@ impl PciDeviceStructure for PciDeviceStructureGeneralDevice {
|
|||||||
HeaderType::Standard
|
HeaderType::Standard
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_standard_device(&self) -> Option<&PciDeviceStructureGeneralDevice> {
|
fn as_standard_device(&self) -> Option<Arc<PciDeviceStructureGeneralDevice>> {
|
||||||
Some(self)
|
self.self_ptr.read().upgrade()
|
||||||
}
|
|
||||||
#[inline(always)]
|
|
||||||
fn as_standard_device_mut(&mut self) -> Option<&mut PciDeviceStructureGeneralDevice> {
|
|
||||||
Some(self)
|
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn common_header(&self) -> &PciDeviceStructureHeader {
|
fn common_header(&self) -> &PciDeviceStructureHeader {
|
||||||
&self.common_header
|
&self.common_header
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader {
|
fn common_header_mut(&self) -> &PciDeviceStructureHeader {
|
||||||
&mut self.common_header
|
&self.common_header
|
||||||
}
|
}
|
||||||
fn capabilities(&self) -> Option<CapabilityIterator> {
|
fn capabilities(&self) -> Option<CapabilityIterator> {
|
||||||
Some(CapabilityIterator {
|
Some(CapabilityIterator {
|
||||||
@ -488,37 +478,37 @@ impl PciDeviceStructure for PciDeviceStructureGeneralDevice {
|
|||||||
next_capability_offset: Some(self.capabilities_pointer),
|
next_capability_offset: Some(self.capabilities_pointer),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn bar_ioremap(&mut self) -> Option<Result<u8, PciError>> {
|
fn bar_ioremap(&self) -> Option<Result<u8, PciError>> {
|
||||||
let common_header = &self.common_header;
|
let common_header = &self.common_header;
|
||||||
match pci_bar_init(common_header.bus_device_function) {
|
match pci_bar_init(common_header.bus_device_function) {
|
||||||
Ok(bar) => {
|
Ok(bar) => {
|
||||||
self.standard_device_bar = bar;
|
*self.standard_device_bar.write() = bar;
|
||||||
Some(Ok(0))
|
Some(Ok(0))
|
||||||
}
|
}
|
||||||
Err(e) => Some(Err(e)),
|
Err(e) => Some(Err(e)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn bar(&mut self) -> Option<&PciStandardDeviceBar> {
|
fn bar(&self) -> Option<&RwLock<PciStandardDeviceBar>> {
|
||||||
Some(&self.standard_device_bar)
|
Some(&self.standard_device_bar)
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn irq_type_mut(&mut self) -> Option<&mut IrqType> {
|
fn irq_type_mut(&self) -> Option<&RwLock<IrqType>> {
|
||||||
Some(&mut self.irq_type)
|
Some(&self.irq_type)
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>> {
|
fn irq_vector_mut(&self) -> Option<&RwLock<Vec<IrqNumber>>> {
|
||||||
Some(&mut self.irq_vector)
|
Some(&self.irq_vector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pci_Device_Structure_Pci_to_Pci_Bridge pci-to-pci桥设备结构体
|
/// Pci_Device_Structure_Pci_to_Pci_Bridge pci-to-pci桥设备结构体
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PciDeviceStructurePciToPciBridge {
|
pub struct PciDeviceStructurePciToPciBridge {
|
||||||
pub common_header: PciDeviceStructureHeader,
|
pub common_header: PciDeviceStructureHeader,
|
||||||
// 中断结构体,包括legacy,msi,msix三种情况
|
// 中断结构体,包括legacy,msi,msix三种情况
|
||||||
pub irq_type: IrqType,
|
pub irq_type: RwLock<IrqType>,
|
||||||
// 使用的中断号的vec集合
|
// 使用的中断号的vec集合
|
||||||
pub irq_vector: Vec<IrqNumber>,
|
pub irq_vector: RwLock<Vec<IrqNumber>>,
|
||||||
pub bar0: u32,
|
pub bar0: u32,
|
||||||
pub bar1: u32,
|
pub bar1: u32,
|
||||||
pub primary_bus_number: u8,
|
pub primary_bus_number: u8,
|
||||||
@ -554,7 +544,7 @@ impl PciDeviceStructure for PciDeviceStructurePciToPciBridge {
|
|||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_pci_to_pci_bridge_device_mut(&mut self) -> Option<&mut PciDeviceStructurePciToPciBridge> {
|
fn as_pci_to_pci_bridge_device_mut(&self) -> Option<&PciDeviceStructurePciToPciBridge> {
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -562,20 +552,20 @@ impl PciDeviceStructure for PciDeviceStructurePciToPciBridge {
|
|||||||
&self.common_header
|
&self.common_header
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader {
|
fn common_header_mut(&self) -> &PciDeviceStructureHeader {
|
||||||
&mut self.common_header
|
&self.common_header
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn irq_type_mut(&mut self) -> Option<&mut IrqType> {
|
fn irq_type_mut(&self) -> Option<&RwLock<IrqType>> {
|
||||||
Some(&mut self.irq_type)
|
Some(&self.irq_type)
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>> {
|
fn irq_vector_mut(&self) -> Option<&RwLock<Vec<IrqNumber>>> {
|
||||||
Some(&mut self.irq_vector)
|
Some(&self.irq_vector)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Pci_Device_Structure_Pci_to_Cardbus_Bridge Pci_to_Cardbus桥设备结构体
|
/// Pci_Device_Structure_Pci_to_Cardbus_Bridge Pci_to_Cardbus桥设备结构体
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PciDeviceStructurePciToCardbusBridge {
|
pub struct PciDeviceStructurePciToCardbusBridge {
|
||||||
pub common_header: PciDeviceStructureHeader,
|
pub common_header: PciDeviceStructureHeader,
|
||||||
pub cardbus_socket_ex_ca_base_address: u32,
|
pub cardbus_socket_ex_ca_base_address: u32,
|
||||||
@ -611,9 +601,7 @@ impl PciDeviceStructure for PciDeviceStructurePciToCardbusBridge {
|
|||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn as_pci_to_carbus_bridge_device_mut(
|
fn as_pci_to_carbus_bridge_device_mut(&self) -> Option<&PciDeviceStructurePciToCardbusBridge> {
|
||||||
&mut self,
|
|
||||||
) -> Option<&mut PciDeviceStructurePciToCardbusBridge> {
|
|
||||||
Some(self)
|
Some(self)
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@ -621,15 +609,15 @@ impl PciDeviceStructure for PciDeviceStructurePciToCardbusBridge {
|
|||||||
&self.common_header
|
&self.common_header
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn common_header_mut(&mut self) -> &mut PciDeviceStructureHeader {
|
fn common_header_mut(&self) -> &PciDeviceStructureHeader {
|
||||||
&mut self.common_header
|
&self.common_header
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn irq_type_mut(&mut self) -> Option<&mut IrqType> {
|
fn irq_type_mut(&self) -> Option<&RwLock<IrqType>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn irq_vector_mut(&mut self) -> Option<&mut Vec<IrqNumber>> {
|
fn irq_vector_mut(&self) -> Option<&RwLock<Vec<IrqNumber>>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -684,14 +672,14 @@ pub fn capabilities_offset(bus_device_function: BusDeviceFunction) -> Option<u8>
|
|||||||
fn pci_read_header(
|
fn pci_read_header(
|
||||||
bus_device_function: BusDeviceFunction,
|
bus_device_function: BusDeviceFunction,
|
||||||
add_to_list: bool,
|
add_to_list: bool,
|
||||||
) -> Result<Box<dyn PciDeviceStructure>, PciError> {
|
) -> Result<Arc<dyn PciDeviceStructure>, PciError> {
|
||||||
// 先读取公共header
|
// 先读取公共header
|
||||||
let result = pci_root_0().read_config(bus_device_function, 0x00);
|
let result = pci_root_0().read_config(bus_device_function, 0x00);
|
||||||
let vendor_id = result as u16;
|
let vendor_id = result as u16;
|
||||||
let device_id = (result >> 16) as u16;
|
let device_id = (result >> 16) as u16;
|
||||||
|
|
||||||
let result = pci_root_0().read_config(bus_device_function, 0x04);
|
let result = pci_root_0().read_config(bus_device_function, 0x04);
|
||||||
let command = result as u16;
|
let command = RwLock::new(result as u16);
|
||||||
let status = (result >> 16) as u16;
|
let status = (result >> 16) as u16;
|
||||||
|
|
||||||
let result = pci_root_0().read_config(bus_device_function, 0x08);
|
let result = pci_root_0().read_config(bus_device_function, 0x08);
|
||||||
@ -727,22 +715,22 @@ fn pci_read_header(
|
|||||||
HeaderType::Standard => {
|
HeaderType::Standard => {
|
||||||
let general_device: PciDeviceStructureGeneralDevice =
|
let general_device: PciDeviceStructureGeneralDevice =
|
||||||
pci_read_general_device_header(header, &bus_device_function);
|
pci_read_general_device_header(header, &bus_device_function);
|
||||||
let box_general_device = Box::new(general_device.clone());
|
let box_general_device = Arc::new(general_device);
|
||||||
let box_general_device_clone = box_general_device.clone();
|
*box_general_device.self_ptr.write() = Arc::downgrade(&box_general_device);
|
||||||
if add_to_list {
|
if add_to_list {
|
||||||
PCI_DEVICE_LINKEDLIST.add(box_general_device);
|
PCI_DEVICE_LINKEDLIST.add(box_general_device.clone());
|
||||||
//这里实际上不应该使用clone,因为raw是用于sysfs的结构,但是实际上pci设备是在PCI_DEVICE_LINKEDLIST链表上的,
|
//这里实际上不应该使用clone,因为raw是用于sysfs的结构,但是实际上pci设备是在PCI_DEVICE_LINKEDLIST链表上的,
|
||||||
//这就导致sysfs呈现的对pci设备的操控接口实际上操控的是pci设备描述符是一个副本
|
//这就导致sysfs呈现的对pci设备的操控接口实际上操控的是pci设备描述符是一个副本
|
||||||
//但是无奈这里没有使用Arc
|
//但是无奈这里没有使用Arc
|
||||||
//todo:修改pci设备描述符在静态链表中存在的方式,并修改这里的clone操作
|
//todo:修改pci设备描述符在静态链表中存在的方式,并修改这里的clone操作
|
||||||
let raw = PciGeneralDevice::from(&general_device);
|
let raw = PciGeneralDevice::from(box_general_device.clone());
|
||||||
let _ = pci_device_manager().device_add(Arc::new(raw));
|
let _ = pci_device_manager().device_add(Arc::new(raw));
|
||||||
}
|
}
|
||||||
Ok(box_general_device_clone)
|
Ok(box_general_device)
|
||||||
}
|
}
|
||||||
HeaderType::PciPciBridge => {
|
HeaderType::PciPciBridge => {
|
||||||
let pci_to_pci_bridge = pci_read_pci_to_pci_bridge_header(header, &bus_device_function);
|
let pci_to_pci_bridge = pci_read_pci_to_pci_bridge_header(header, &bus_device_function);
|
||||||
let box_pci_to_pci_bridge = Box::new(pci_to_pci_bridge);
|
let box_pci_to_pci_bridge = Arc::new(pci_to_pci_bridge);
|
||||||
let box_pci_to_pci_bridge_clone = box_pci_to_pci_bridge.clone();
|
let box_pci_to_pci_bridge_clone = box_pci_to_pci_bridge.clone();
|
||||||
if add_to_list {
|
if add_to_list {
|
||||||
PCI_DEVICE_LINKEDLIST.add(box_pci_to_pci_bridge);
|
PCI_DEVICE_LINKEDLIST.add(box_pci_to_pci_bridge);
|
||||||
@ -752,7 +740,7 @@ fn pci_read_header(
|
|||||||
HeaderType::PciCardbusBridge => {
|
HeaderType::PciCardbusBridge => {
|
||||||
let pci_cardbus_bridge =
|
let pci_cardbus_bridge =
|
||||||
pci_read_pci_to_cardbus_bridge_header(header, &bus_device_function);
|
pci_read_pci_to_cardbus_bridge_header(header, &bus_device_function);
|
||||||
let box_pci_cardbus_bridge = Box::new(pci_cardbus_bridge);
|
let box_pci_cardbus_bridge = Arc::new(pci_cardbus_bridge);
|
||||||
let box_pci_cardbus_bridge_clone = box_pci_cardbus_bridge.clone();
|
let box_pci_cardbus_bridge_clone = box_pci_cardbus_bridge.clone();
|
||||||
if add_to_list {
|
if add_to_list {
|
||||||
PCI_DEVICE_LINKEDLIST.add(box_pci_cardbus_bridge);
|
PCI_DEVICE_LINKEDLIST.add(box_pci_cardbus_bridge);
|
||||||
@ -772,7 +760,7 @@ fn pci_read_general_device_header(
|
|||||||
common_header: PciDeviceStructureHeader,
|
common_header: PciDeviceStructureHeader,
|
||||||
bus_device_function: &BusDeviceFunction,
|
bus_device_function: &BusDeviceFunction,
|
||||||
) -> PciDeviceStructureGeneralDevice {
|
) -> PciDeviceStructureGeneralDevice {
|
||||||
let standard_device_bar = PciStandardDeviceBar::default();
|
let standard_device_bar = RwLock::new(PciStandardDeviceBar::default());
|
||||||
let cardbus_cis_pointer = pci_root_0().read_config(*bus_device_function, 0x28);
|
let cardbus_cis_pointer = pci_root_0().read_config(*bus_device_function, 0x28);
|
||||||
|
|
||||||
let result = pci_root_0().read_config(*bus_device_function, 0x2c);
|
let result = pci_root_0().read_config(*bus_device_function, 0x2c);
|
||||||
@ -795,8 +783,8 @@ fn pci_read_general_device_header(
|
|||||||
let max_latency = (result >> 24) as u8;
|
let max_latency = (result >> 24) as u8;
|
||||||
PciDeviceStructureGeneralDevice {
|
PciDeviceStructureGeneralDevice {
|
||||||
common_header,
|
common_header,
|
||||||
irq_type: IrqType::Unused,
|
irq_type: RwLock::new(IrqType::Unused),
|
||||||
irq_vector: Vec::new(),
|
irq_vector: RwLock::new(Vec::new()),
|
||||||
standard_device_bar,
|
standard_device_bar,
|
||||||
cardbus_cis_pointer,
|
cardbus_cis_pointer,
|
||||||
subsystem_vendor_id,
|
subsystem_vendor_id,
|
||||||
@ -810,6 +798,7 @@ fn pci_read_general_device_header(
|
|||||||
interrupt_pin,
|
interrupt_pin,
|
||||||
min_grant,
|
min_grant,
|
||||||
max_latency,
|
max_latency,
|
||||||
|
self_ptr: RwLock::new(Weak::new()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -865,8 +854,8 @@ fn pci_read_pci_to_pci_bridge_header(
|
|||||||
let bridge_control = (result >> 16) as u16;
|
let bridge_control = (result >> 16) as u16;
|
||||||
PciDeviceStructurePciToPciBridge {
|
PciDeviceStructurePciToPciBridge {
|
||||||
common_header,
|
common_header,
|
||||||
irq_type: IrqType::Unused,
|
irq_type: RwLock::new(IrqType::Unused),
|
||||||
irq_vector: Vec::new(),
|
irq_vector: RwLock::new(Vec::new()),
|
||||||
bar0,
|
bar0,
|
||||||
bar1,
|
bar1,
|
||||||
primary_bus_number,
|
primary_bus_number,
|
||||||
|
@ -155,7 +155,7 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param flag 选择的中断类型(支持多个选择),如PCI_IRQ_ALL_TYPES表示所有中断类型均可,让系统按顺序进行选择
|
/// @param flag 选择的中断类型(支持多个选择),如PCI_IRQ_ALL_TYPES表示所有中断类型均可,让系统按顺序进行选择
|
||||||
/// @return Option<IrqType> 失败返回None,成功则返回对应中断类型
|
/// @return Option<IrqType> 失败返回None,成功则返回对应中断类型
|
||||||
fn irq_init(&mut self, flag: IRQ) -> Option<IrqType> {
|
fn irq_init(&self, flag: IRQ) -> Option<IrqType> {
|
||||||
// MSIX中断优先
|
// MSIX中断优先
|
||||||
if flag.contains(IRQ::PCI_IRQ_MSIX) {
|
if flag.contains(IRQ::PCI_IRQ_MSIX) {
|
||||||
if let Some(cap_offset) = self.msix_capability_offset() {
|
if let Some(cap_offset) = self.msix_capability_offset() {
|
||||||
@ -174,7 +174,7 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
);
|
);
|
||||||
let pending_table_bar = (data & 0x07) as u8;
|
let pending_table_bar = (data & 0x07) as u8;
|
||||||
let pending_table_offset = data & (!0x07);
|
let pending_table_offset = data & (!0x07);
|
||||||
*self.irq_type_mut()? = IrqType::Msix {
|
*self.irq_type_mut()?.write() = IrqType::Msix {
|
||||||
msix_table_bar,
|
msix_table_bar,
|
||||||
msix_table_offset,
|
msix_table_offset,
|
||||||
pending_table_bar,
|
pending_table_bar,
|
||||||
@ -201,7 +201,7 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
let maskable = (message_control & 0x0100) != 0;
|
let maskable = (message_control & 0x0100) != 0;
|
||||||
let address_64 = (message_control & 0x0080) != 0;
|
let address_64 = (message_control & 0x0080) != 0;
|
||||||
let irq_max_num = (1 << (((message_control & 0x000e) >> 1) + 1)) as u16;
|
let irq_max_num = (1 << (((message_control & 0x000e) >> 1) + 1)) as u16;
|
||||||
*self.irq_type_mut()? = IrqType::Msi {
|
*self.irq_type_mut()?.write() = IrqType::Msi {
|
||||||
address_64,
|
address_64,
|
||||||
maskable,
|
maskable,
|
||||||
irq_max_num,
|
irq_max_num,
|
||||||
@ -217,7 +217,7 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
}
|
}
|
||||||
// 最后选择legacy#
|
// 最后选择legacy#
|
||||||
if flag.contains(IRQ::PCI_IRQ_LEGACY) {
|
if flag.contains(IRQ::PCI_IRQ_LEGACY) {
|
||||||
*self.irq_type_mut()? = IrqType::Legacy;
|
*self.irq_type_mut()?.write() = IrqType::Legacy;
|
||||||
return Some(IrqType::Legacy);
|
return Some(IrqType::Legacy);
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
@ -226,9 +226,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @brief 启动/关闭设备中断
|
/// @brief 启动/关闭设备中断
|
||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param enable 开启/关闭
|
/// @param enable 开启/关闭
|
||||||
fn irq_enable(&mut self, enable: bool) -> Result<u8, PciError> {
|
fn irq_enable(&self, enable: bool) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix { .. } => {
|
IrqType::Msix { .. } => {
|
||||||
return self.msix_enable(enable);
|
return self.msix_enable(enable);
|
||||||
}
|
}
|
||||||
@ -248,9 +248,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @brief 启动/关闭设备MSIX中断
|
/// @brief 启动/关闭设备MSIX中断
|
||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param enable 开启/关闭
|
/// @param enable 开启/关闭
|
||||||
fn msix_enable(&mut self, enable: bool) -> Result<u8, PciError> {
|
fn msix_enable(&self, enable: bool) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix { cap_offset, .. } => {
|
IrqType::Msix { cap_offset, .. } => {
|
||||||
let mut message = pci_root_0()
|
let mut message = pci_root_0()
|
||||||
.read_config(self.common_header().bus_device_function, cap_offset.into());
|
.read_config(self.common_header().bus_device_function, cap_offset.into());
|
||||||
@ -279,9 +279,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @brief 启动/关闭设备MSI中断
|
/// @brief 启动/关闭设备MSI中断
|
||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param enable 开启/关闭
|
/// @param enable 开启/关闭
|
||||||
fn msi_enable(&mut self, enable: bool) -> Result<u8, PciError> {
|
fn msi_enable(&self, enable: bool) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msi { cap_offset, .. } => {
|
IrqType::Msi { cap_offset, .. } => {
|
||||||
let mut message = pci_root_0()
|
let mut message = pci_root_0()
|
||||||
.read_config(self.common_header().bus_device_function, cap_offset.into());
|
.read_config(self.common_header().bus_device_function, cap_offset.into());
|
||||||
@ -315,9 +315,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param msg PCI设备install中断时需要传递的共同参数
|
/// @param msg PCI设备install中断时需要传递的共同参数
|
||||||
/// @return 一切正常返回Ok(0),有错误返回对应错误原因
|
/// @return 一切正常返回Ok(0),有错误返回对应错误原因
|
||||||
fn irq_install(&mut self, msg: PciIrqMsg) -> Result<u8, PciError> {
|
fn irq_install(&self, msg: PciIrqMsg) -> Result<u8, PciError> {
|
||||||
if let Some(irq_vector) = self.irq_vector_mut() {
|
if let Some(irq_vector) = self.irq_vector_mut() {
|
||||||
if msg.irq_common_message.irq_index as usize > irq_vector.len() {
|
if msg.irq_common_message.irq_index as usize > irq_vector.read().len() {
|
||||||
return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
|
return Err(PciError::PciIrqError(PciIrqError::InvalidIrqIndex(
|
||||||
msg.irq_common_message.irq_index,
|
msg.irq_common_message.irq_index,
|
||||||
)));
|
)));
|
||||||
@ -325,7 +325,7 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
}
|
}
|
||||||
self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断
|
self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix { .. } => {
|
IrqType::Msix { .. } => {
|
||||||
return self.msix_install(msg);
|
return self.msix_install(msg);
|
||||||
}
|
}
|
||||||
@ -346,9 +346,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param msg PCI设备install中断时需要传递的共同参数
|
/// @param msg PCI设备install中断时需要传递的共同参数
|
||||||
/// @return 一切正常返回Ok(0),有错误返回对应错误原因
|
/// @return 一切正常返回Ok(0),有错误返回对应错误原因
|
||||||
fn msi_install(&mut self, msg: PciIrqMsg) -> Result<u8, PciError> {
|
fn msi_install(&self, msg: PciIrqMsg) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msi {
|
IrqType::Msi {
|
||||||
address_64,
|
address_64,
|
||||||
irq_max_num,
|
irq_max_num,
|
||||||
@ -356,11 +356,11 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
// 注意:MSI中断分配的中断号必须连续且大小为2的倍数
|
// 注意:MSI中断分配的中断号必须连续且大小为2的倍数
|
||||||
if self.irq_vector_mut().unwrap().len() > irq_max_num as usize {
|
if self.irq_vector_mut().unwrap().read().len() > irq_max_num as usize {
|
||||||
return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow));
|
return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow));
|
||||||
}
|
}
|
||||||
let irq_num =
|
let irq_num = self.irq_vector_mut().unwrap().read()
|
||||||
self.irq_vector_mut().unwrap()[msg.irq_common_message.irq_index as usize];
|
[msg.irq_common_message.irq_index as usize];
|
||||||
|
|
||||||
let irq_num = IrqNumber::new(irq_num.into());
|
let irq_num = IrqNumber::new(irq_num.into());
|
||||||
let common_msg = &msg.irq_common_message;
|
let common_msg = &msg.irq_common_message;
|
||||||
@ -441,7 +441,7 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
cap_offset.into(),
|
cap_offset.into(),
|
||||||
);
|
);
|
||||||
let message_control = (data >> 16) as u16;
|
let message_control = (data >> 16) as u16;
|
||||||
match self.irq_vector_mut().unwrap().len() {
|
match self.irq_vector_mut().unwrap().read().len() {
|
||||||
1 => {
|
1 => {
|
||||||
let temp = message_control & (!0x0070);
|
let temp = message_control & (!0x0070);
|
||||||
pci_root_0().write_config(
|
pci_root_0().write_config(
|
||||||
@ -511,20 +511,20 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param msg PCI设备install中断时需要传递的共同参数
|
/// @param msg PCI设备install中断时需要传递的共同参数
|
||||||
/// @return 一切正常返回Ok(0),有错误返回对应错误原因
|
/// @return 一切正常返回Ok(0),有错误返回对应错误原因
|
||||||
fn msix_install(&mut self, msg: PciIrqMsg) -> Result<u8, PciError> {
|
fn msix_install(&self, msg: PciIrqMsg) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix {
|
IrqType::Msix {
|
||||||
irq_max_num,
|
irq_max_num,
|
||||||
msix_table_bar,
|
msix_table_bar,
|
||||||
msix_table_offset,
|
msix_table_offset,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
if self.irq_vector_mut().unwrap().len() > irq_max_num as usize {
|
if self.irq_vector_mut().unwrap().read().len() > irq_max_num as usize {
|
||||||
return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow));
|
return Err(PciError::PciIrqError(PciIrqError::DeviceIrqOverflow));
|
||||||
}
|
}
|
||||||
let irq_num =
|
let irq_num = self.irq_vector_mut().unwrap().read()
|
||||||
self.irq_vector_mut().unwrap()[msg.irq_common_message.irq_index as usize];
|
[msg.irq_common_message.irq_index as usize];
|
||||||
|
|
||||||
let common_msg = &msg.irq_common_message;
|
let common_msg = &msg.irq_common_message;
|
||||||
|
|
||||||
@ -571,7 +571,8 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
//写入Message Data和Message Address
|
//写入Message Data和Message Address
|
||||||
let pcistandardbar = self
|
let pcistandardbar = self
|
||||||
.bar()
|
.bar()
|
||||||
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))?;
|
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))?
|
||||||
|
.read();
|
||||||
let msix_bar = pcistandardbar.get_bar(msix_table_bar)?;
|
let msix_bar = pcistandardbar.get_bar(msix_table_bar)?;
|
||||||
let vaddr: crate::mm::VirtAddr = msix_bar
|
let vaddr: crate::mm::VirtAddr = msix_bar
|
||||||
.virtual_address()
|
.virtual_address()
|
||||||
@ -603,7 +604,7 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
fn irq_uninstall(&mut self) -> Result<u8, PciError> {
|
fn irq_uninstall(&mut self) -> Result<u8, PciError> {
|
||||||
self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断
|
self.irq_enable(false)?; //中断设置更改前先关闭对应PCI设备的中断
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix { .. } => {
|
IrqType::Msix { .. } => {
|
||||||
return self.msix_uninstall();
|
return self.msix_uninstall();
|
||||||
}
|
}
|
||||||
@ -622,15 +623,15 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
}
|
}
|
||||||
/// @brief 进行PCI设备中断的卸载(MSI)
|
/// @brief 进行PCI设备中断的卸载(MSI)
|
||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
fn msi_uninstall(&mut self) -> Result<u8, PciError> {
|
fn msi_uninstall(&self) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msi {
|
IrqType::Msi {
|
||||||
address_64,
|
address_64,
|
||||||
cap_offset,
|
cap_offset,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
for vector in self.irq_vector_mut().unwrap() {
|
for vector in self.irq_vector_mut().unwrap().read().iter() {
|
||||||
let irq = IrqNumber::new((*vector).into());
|
let irq = IrqNumber::new((*vector).into());
|
||||||
irq_manager().free_irq(irq, None);
|
irq_manager().free_irq(irq, None);
|
||||||
}
|
}
|
||||||
@ -670,9 +671,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
}
|
}
|
||||||
/// @brief 进行PCI设备中断的卸载(MSIX)
|
/// @brief 进行PCI设备中断的卸载(MSIX)
|
||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
fn msix_uninstall(&mut self) -> Result<u8, PciError> {
|
fn msix_uninstall(&self) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix {
|
IrqType::Msix {
|
||||||
irq_max_num,
|
irq_max_num,
|
||||||
cap_offset,
|
cap_offset,
|
||||||
@ -680,7 +681,7 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
msix_table_offset,
|
msix_table_offset,
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
for vector in self.irq_vector_mut().unwrap() {
|
for vector in self.irq_vector_mut().unwrap().read().iter() {
|
||||||
let irq = IrqNumber::new((*vector).into());
|
let irq = IrqNumber::new((*vector).into());
|
||||||
irq_manager().free_irq(irq, None);
|
irq_manager().free_irq(irq, None);
|
||||||
}
|
}
|
||||||
@ -692,7 +693,8 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
let pcistandardbar = self
|
let pcistandardbar = self
|
||||||
.bar()
|
.bar()
|
||||||
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
|
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.read();
|
||||||
let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
|
let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
|
||||||
for index in 0..irq_max_num {
|
for index in 0..irq_max_num {
|
||||||
let vaddr = msix_bar
|
let vaddr = msix_bar
|
||||||
@ -726,7 +728,7 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
||||||
fn irq_mask(&mut self, irq_index: u16) -> Result<u8, PciError> {
|
fn irq_mask(&mut self, irq_index: u16) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix { .. } => {
|
IrqType::Msix { .. } => {
|
||||||
return self.msix_mask(irq_index);
|
return self.msix_mask(irq_index);
|
||||||
}
|
}
|
||||||
@ -746,9 +748,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @brief 屏蔽相应位置的中断(MSI)
|
/// @brief 屏蔽相应位置的中断(MSI)
|
||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
||||||
fn msi_mask(&mut self, irq_index: u16) -> Result<u8, PciError> {
|
fn msi_mask(&self, irq_index: u16) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msi {
|
IrqType::Msi {
|
||||||
maskable,
|
maskable,
|
||||||
address_64,
|
address_64,
|
||||||
@ -804,9 +806,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @brief 屏蔽相应位置的中断(MSIX)
|
/// @brief 屏蔽相应位置的中断(MSIX)
|
||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
||||||
fn msix_mask(&mut self, irq_index: u16) -> Result<u8, PciError> {
|
fn msix_mask(&self, irq_index: u16) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix {
|
IrqType::Msix {
|
||||||
irq_max_num,
|
irq_max_num,
|
||||||
msix_table_bar,
|
msix_table_bar,
|
||||||
@ -821,7 +823,8 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
let pcistandardbar = self
|
let pcistandardbar = self
|
||||||
.bar()
|
.bar()
|
||||||
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
|
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.read();
|
||||||
let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
|
let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
|
||||||
let vaddr = msix_bar.virtual_address().unwrap()
|
let vaddr = msix_bar.virtual_address().unwrap()
|
||||||
+ msix_table_offset as usize
|
+ msix_table_offset as usize
|
||||||
@ -845,9 +848,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @brief 解除屏蔽相应位置的中断
|
/// @brief 解除屏蔽相应位置的中断
|
||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
||||||
fn irq_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> {
|
fn irq_unmask(&self, irq_index: u16) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix { .. } => {
|
IrqType::Msix { .. } => {
|
||||||
return self.msix_unmask(irq_index);
|
return self.msix_unmask(irq_index);
|
||||||
}
|
}
|
||||||
@ -867,9 +870,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @brief 解除屏蔽相应位置的中断(MSI)
|
/// @brief 解除屏蔽相应位置的中断(MSI)
|
||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
||||||
fn msi_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> {
|
fn msi_unmask(&self, irq_index: u16) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msi {
|
IrqType::Msi {
|
||||||
maskable,
|
maskable,
|
||||||
address_64,
|
address_64,
|
||||||
@ -924,9 +927,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @brief 解除屏蔽相应位置的中断(MSIX)
|
/// @brief 解除屏蔽相应位置的中断(MSIX)
|
||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
||||||
fn msix_unmask(&mut self, irq_index: u16) -> Result<u8, PciError> {
|
fn msix_unmask(&self, irq_index: u16) -> Result<u8, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix {
|
IrqType::Msix {
|
||||||
irq_max_num,
|
irq_max_num,
|
||||||
msix_table_bar,
|
msix_table_bar,
|
||||||
@ -941,7 +944,8 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
let pcistandardbar = self
|
let pcistandardbar = self
|
||||||
.bar()
|
.bar()
|
||||||
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
|
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.read();
|
||||||
let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
|
let msix_bar = pcistandardbar.get_bar(msix_table_bar).unwrap();
|
||||||
let vaddr = msix_bar.virtual_address().unwrap()
|
let vaddr = msix_bar.virtual_address().unwrap()
|
||||||
+ msix_table_offset as usize
|
+ msix_table_offset as usize
|
||||||
@ -966,9 +970,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
||||||
/// @return 是否在挂起过程中产生中断(异常情况也返回false)
|
/// @return 是否在挂起过程中产生中断(异常情况也返回false)
|
||||||
fn irq_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> {
|
fn irq_check_pending(&self, irq_index: u16) -> Result<bool, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix { .. } => {
|
IrqType::Msix { .. } => {
|
||||||
return self.msix_check_pending(irq_index);
|
return self.msix_check_pending(irq_index);
|
||||||
}
|
}
|
||||||
@ -989,9 +993,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
||||||
/// @return 是否在挂起过程中产生中断(异常情况也返回false)
|
/// @return 是否在挂起过程中产生中断(异常情况也返回false)
|
||||||
fn msi_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> {
|
fn msi_check_pending(&self, irq_index: u16) -> Result<bool, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msi {
|
IrqType::Msi {
|
||||||
maskable,
|
maskable,
|
||||||
address_64,
|
address_64,
|
||||||
@ -1038,9 +1042,9 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
/// @param self PCI设备的可变引用
|
/// @param self PCI设备的可变引用
|
||||||
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
/// @param irq_index 中断的位置(在vec中的index和安装的index相同)
|
||||||
/// @return 是否在挂起过程中产生中断(异常情况也返回false)
|
/// @return 是否在挂起过程中产生中断(异常情况也返回false)
|
||||||
fn msix_check_pending(&mut self, irq_index: u16) -> Result<bool, PciError> {
|
fn msix_check_pending(&self, irq_index: u16) -> Result<bool, PciError> {
|
||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type.read() {
|
||||||
IrqType::Msix {
|
IrqType::Msix {
|
||||||
irq_max_num,
|
irq_max_num,
|
||||||
pending_table_bar,
|
pending_table_bar,
|
||||||
@ -1055,7 +1059,8 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
let pcistandardbar = self
|
let pcistandardbar = self
|
||||||
.bar()
|
.bar()
|
||||||
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
|
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
|
||||||
.unwrap();
|
.unwrap()
|
||||||
|
.read();
|
||||||
let pending_bar = pcistandardbar.get_bar(pending_table_bar).unwrap();
|
let pending_bar = pcistandardbar.get_bar(pending_table_bar).unwrap();
|
||||||
let vaddr = pending_bar.virtual_address().unwrap()
|
let vaddr = pending_bar.virtual_address().unwrap()
|
||||||
+ pending_table_offset as usize
|
+ pending_table_offset as usize
|
||||||
|
@ -37,9 +37,9 @@ struct InnerPciGeneralDevice {
|
|||||||
device_common: DeviceCommonData,
|
device_common: DeviceCommonData,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&PciDeviceStructureGeneralDevice> for PciGeneralDevice {
|
impl From<Arc<PciDeviceStructureGeneralDevice>> for PciGeneralDevice {
|
||||||
fn from(value: &PciDeviceStructureGeneralDevice) -> Self {
|
fn from(value: Arc<PciDeviceStructureGeneralDevice>) -> Self {
|
||||||
let value = Arc::new(value.clone());
|
// let value = Arc::new(value.clone());
|
||||||
let name: String = value.common_header.bus_device_function.into();
|
let name: String = value.common_header.bus_device_function.into();
|
||||||
let kobj_state = LockedKObjectState::new(None);
|
let kobj_state = LockedKObjectState::new(None);
|
||||||
let dev_id = PciDeviceID::dummpy();
|
let dev_id = PciDeviceID::dummpy();
|
||||||
@ -80,6 +80,30 @@ impl PciDevice for PciGeneralDevice {
|
|||||||
fn subsystem_device(&self) -> u16 {
|
fn subsystem_device(&self) -> u16 {
|
||||||
self.header.subsystem_id
|
self.header.subsystem_id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn class_code(&self) -> u8 {
|
||||||
|
self.header.common_header.class_code
|
||||||
|
}
|
||||||
|
|
||||||
|
fn revision(&self) -> u8 {
|
||||||
|
self.header.common_header.revision_id
|
||||||
|
}
|
||||||
|
|
||||||
|
fn irq_type(&self) -> &RwLock<super::pci_irq::IrqType> {
|
||||||
|
&self.header.irq_type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn irq_line(&self) -> u8 {
|
||||||
|
self.header.interrupt_line
|
||||||
|
}
|
||||||
|
|
||||||
|
fn interface_code(&self) -> u8 {
|
||||||
|
self.header.common_header.prog_if
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subclass(&self) -> u8 {
|
||||||
|
self.header.common_header.subclass
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Device for PciGeneralDevice {
|
impl Device for PciGeneralDevice {
|
||||||
|
@ -14,7 +14,7 @@ use crate::{
|
|||||||
kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
|
kobject::{KObjType, KObject, KObjectCommonData, KObjectState, LockedKObjectState},
|
||||||
kset::KSet,
|
kset::KSet,
|
||||||
},
|
},
|
||||||
pci::{dev_id::PciDeviceID, device::PciDevice},
|
pci::{dev_id::PciDeviceID, device::PciDevice, pci_irq::IrqType},
|
||||||
},
|
},
|
||||||
filesystem::{
|
filesystem::{
|
||||||
kernfs::KernFSInode,
|
kernfs::KernFSInode,
|
||||||
@ -36,6 +36,7 @@ pub struct TestDevice {
|
|||||||
device_data: RwLock<DeviceCommonData>,
|
device_data: RwLock<DeviceCommonData>,
|
||||||
kobj_data: RwLock<KObjectCommonData>,
|
kobj_data: RwLock<KObjectCommonData>,
|
||||||
kobj_state: LockedKObjectState,
|
kobj_state: LockedKObjectState,
|
||||||
|
static_type: RwLock<IrqType>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TestDevice {
|
impl TestDevice {
|
||||||
@ -46,6 +47,7 @@ impl TestDevice {
|
|||||||
device_data: common_dev,
|
device_data: common_dev,
|
||||||
kobj_data: common_kobj,
|
kobj_data: common_kobj,
|
||||||
kobj_state: LockedKObjectState::new(None),
|
kobj_state: LockedKObjectState::new(None),
|
||||||
|
static_type: RwLock::new(IrqType::Unused),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,6 +72,30 @@ impl PciDevice for TestDevice {
|
|||||||
fn subsystem_device(&self) -> u16 {
|
fn subsystem_device(&self) -> u16 {
|
||||||
return 0xffff;
|
return 0xffff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn class_code(&self) -> u8 {
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn irq_line(&self) -> u8 {
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn revision(&self) -> u8 {
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn irq_type(&self) -> &RwLock<crate::driver::pci::pci_irq::IrqType> {
|
||||||
|
return &self.static_type;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn interface_code(&self) -> u8 {
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn subclass(&self) -> u8 {
|
||||||
|
return 0xff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Device for TestDevice {
|
impl Device for TestDevice {
|
||||||
|
@ -33,8 +33,7 @@ impl VirtIOTransport {
|
|||||||
/// 设置中断
|
/// 设置中断
|
||||||
pub fn setup_irq(&self, dev_id: Arc<DeviceId>) -> Result<(), PciError> {
|
pub fn setup_irq(&self, dev_id: Arc<DeviceId>) -> Result<(), PciError> {
|
||||||
if let VirtIOTransport::Pci(transport) = self {
|
if let VirtIOTransport::Pci(transport) = self {
|
||||||
let mut pci_device_guard = transport.pci_device();
|
let standard_device = transport.pci_device().as_standard_device().unwrap();
|
||||||
let standard_device = pci_device_guard.as_standard_device_mut().unwrap();
|
|
||||||
standard_device
|
standard_device
|
||||||
.irq_init(IRQ::PCI_IRQ_MSIX | IRQ::PCI_IRQ_MSI)
|
.irq_init(IRQ::PCI_IRQ_MSIX | IRQ::PCI_IRQ_MSI)
|
||||||
.ok_or(PciError::PciIrqError(PciIrqError::IrqNotInited))?;
|
.ok_or(PciError::PciIrqError(PciIrqError::IrqNotInited))?;
|
||||||
|
@ -10,7 +10,6 @@ use crate::driver::pci::root::pci_root_0;
|
|||||||
|
|
||||||
use crate::exception::IrqNumber;
|
use crate::exception::IrqNumber;
|
||||||
|
|
||||||
use crate::libs::spinlock::{SpinLock, SpinLockGuard};
|
|
||||||
use crate::libs::volatile::{
|
use crate::libs::volatile::{
|
||||||
volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
|
volread, volwrite, ReadOnly, Volatile, VolatileReadable, VolatileWritable, WriteOnly,
|
||||||
};
|
};
|
||||||
@ -102,7 +101,7 @@ pub struct PciTransport {
|
|||||||
config_space: Option<NonNull<[u32]>>,
|
config_space: Option<NonNull<[u32]>>,
|
||||||
irq: IrqNumber,
|
irq: IrqNumber,
|
||||||
dev_id: Arc<DeviceId>,
|
dev_id: Arc<DeviceId>,
|
||||||
device: Arc<SpinLock<PciDeviceStructureGeneralDevice>>,
|
device: Arc<PciDeviceStructureGeneralDevice>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PciTransport {
|
impl PciTransport {
|
||||||
@ -117,7 +116,7 @@ impl PciTransport {
|
|||||||
/// - `irq_number_offset` - Currently, this parameter is just simple make a offset to the irq number, cause it's not be allowed to have the same irq number within different device
|
/// - `irq_number_offset` - Currently, this parameter is just simple make a offset to the irq number, cause it's not be allowed to have the same irq number within different device
|
||||||
#[allow(clippy::extra_unused_type_parameters)]
|
#[allow(clippy::extra_unused_type_parameters)]
|
||||||
pub fn new<H: Hal>(
|
pub fn new<H: Hal>(
|
||||||
device: &mut PciDeviceStructureGeneralDevice,
|
device: Arc<PciDeviceStructureGeneralDevice>,
|
||||||
dev_id: Arc<DeviceId>,
|
dev_id: Arc<DeviceId>,
|
||||||
) -> Result<Self, VirtioPciError> {
|
) -> Result<Self, VirtioPciError> {
|
||||||
let irq = VIRTIO_RECV_VECTOR;
|
let irq = VIRTIO_RECV_VECTOR;
|
||||||
@ -135,11 +134,12 @@ impl PciTransport {
|
|||||||
let mut device_cfg = None;
|
let mut device_cfg = None;
|
||||||
device.bar_ioremap().unwrap()?;
|
device.bar_ioremap().unwrap()?;
|
||||||
device.enable_master();
|
device.enable_master();
|
||||||
let standard_device = device.as_standard_device_mut().unwrap();
|
let standard_device = device.as_standard_device().unwrap();
|
||||||
// 目前缺少对PCI设备中断号的统一管理,所以这里需要指定一个中断号。不能与其他中断重复
|
// 目前缺少对PCI设备中断号的统一管理,所以这里需要指定一个中断号。不能与其他中断重复
|
||||||
let irq_vector = standard_device.irq_vector_mut().unwrap();
|
let irq_vector = standard_device.irq_vector_mut().unwrap();
|
||||||
irq_vector.push(irq);
|
irq_vector.write().push(irq);
|
||||||
|
|
||||||
|
// panic!();
|
||||||
//device_capability为迭代器,遍历其相当于遍历所有的cap空间
|
//device_capability为迭代器,遍历其相当于遍历所有的cap空间
|
||||||
for capability in device.capabilities().unwrap() {
|
for capability in device.capabilities().unwrap() {
|
||||||
if capability.id != PCI_CAP_ID_VNDR {
|
if capability.id != PCI_CAP_ID_VNDR {
|
||||||
@ -187,7 +187,7 @@ impl PciTransport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let common_cfg = get_bar_region::<_>(
|
let common_cfg = get_bar_region::<_>(
|
||||||
&device.standard_device_bar,
|
&device.standard_device_bar.read(),
|
||||||
&common_cfg.ok_or(VirtioPciError::MissingCommonConfig)?,
|
&common_cfg.ok_or(VirtioPciError::MissingCommonConfig)?,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -198,14 +198,15 @@ impl PciTransport {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
//debug!("notify.offset={},notify.length={}",notify_cfg.offset,notify_cfg.length);
|
//debug!("notify.offset={},notify.length={}",notify_cfg.offset,notify_cfg.length);
|
||||||
let notify_region = get_bar_region_slice::<_>(&device.standard_device_bar, ¬ify_cfg)?;
|
let notify_region =
|
||||||
|
get_bar_region_slice::<_>(&device.standard_device_bar.read(), ¬ify_cfg)?;
|
||||||
let isr_status = get_bar_region::<_>(
|
let isr_status = get_bar_region::<_>(
|
||||||
&device.standard_device_bar,
|
&device.standard_device_bar.read(),
|
||||||
&isr_cfg.ok_or(VirtioPciError::MissingIsrConfig)?,
|
&isr_cfg.ok_or(VirtioPciError::MissingIsrConfig)?,
|
||||||
)?;
|
)?;
|
||||||
let config_space = if let Some(device_cfg) = device_cfg {
|
let config_space = if let Some(device_cfg) = device_cfg {
|
||||||
Some(get_bar_region_slice::<_>(
|
Some(get_bar_region_slice::<_>(
|
||||||
&device.standard_device_bar,
|
&device.standard_device_bar.read(),
|
||||||
&device_cfg,
|
&device_cfg,
|
||||||
)?)
|
)?)
|
||||||
} else {
|
} else {
|
||||||
@ -221,12 +222,12 @@ impl PciTransport {
|
|||||||
config_space,
|
config_space,
|
||||||
irq,
|
irq,
|
||||||
dev_id,
|
dev_id,
|
||||||
device: Arc::new(SpinLock::new(device.clone())),
|
device,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pci_device(&self) -> SpinLockGuard<PciDeviceStructureGeneralDevice> {
|
pub fn pci_device(&self) -> Arc<PciDeviceStructureGeneralDevice> {
|
||||||
self.device.lock()
|
self.device.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn irq(&self) -> IrqNumber {
|
pub fn irq(&self) -> IrqNumber {
|
||||||
|
@ -6,17 +6,15 @@ use crate::driver::base::device::{Device, DeviceId};
|
|||||||
use crate::driver::block::virtio_blk::virtio_blk;
|
use crate::driver::block::virtio_blk::virtio_blk;
|
||||||
use crate::driver::net::virtio_net::virtio_net;
|
use crate::driver::net::virtio_net::virtio_net;
|
||||||
use crate::driver::pci::pci::{
|
use crate::driver::pci::pci::{
|
||||||
get_pci_device_structures_mut_by_vendor_id, PciDeviceStructure,
|
get_pci_device_structures_mut_by_vendor_id, PciDeviceStructureGeneralDevice,
|
||||||
PciDeviceStructureGeneralDevice, PCI_DEVICE_LINKEDLIST,
|
PCI_DEVICE_LINKEDLIST,
|
||||||
};
|
};
|
||||||
use crate::driver::pci::subsys::pci_bus;
|
use crate::driver::pci::subsys::pci_bus;
|
||||||
use crate::driver::virtio::transport::VirtIOTransport;
|
use crate::driver::virtio::transport::VirtIOTransport;
|
||||||
use crate::libs::rwlock::RwLockWriteGuard;
|
|
||||||
|
|
||||||
use alloc::string::String;
|
use alloc::string::String;
|
||||||
use alloc::sync::Arc;
|
use alloc::sync::Arc;
|
||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use alloc::{boxed::Box, collections::LinkedList};
|
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, warn};
|
||||||
use virtio_drivers::transport::{DeviceType, Transport};
|
use virtio_drivers::transport::{DeviceType, Transport};
|
||||||
|
|
||||||
@ -29,12 +27,11 @@ pub fn virtio_probe() {
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn virtio_probe_pci() {
|
fn virtio_probe_pci() {
|
||||||
let mut list = PCI_DEVICE_LINKEDLIST.write();
|
let virtio_list = virtio_device_search();
|
||||||
let virtio_list = virtio_device_search(&mut list);
|
|
||||||
for virtio_device in virtio_list {
|
for virtio_device in virtio_list {
|
||||||
let dev_id = virtio_device.common_header.device_id;
|
let dev_id = virtio_device.common_header.device_id;
|
||||||
let dev_id = DeviceId::new(None, Some(format!("{dev_id}"))).unwrap();
|
let dev_id = DeviceId::new(None, Some(format!("{dev_id}"))).unwrap();
|
||||||
match PciTransport::new::<HalImpl>(virtio_device, dev_id.clone()) {
|
match PciTransport::new::<HalImpl>(virtio_device.clone(), dev_id.clone()) {
|
||||||
Ok(mut transport) => {
|
Ok(mut transport) => {
|
||||||
debug!(
|
debug!(
|
||||||
"Detected virtio PCI device with device type {:?}, features {:#018x}",
|
"Detected virtio PCI device with device type {:?}, features {:#018x}",
|
||||||
@ -87,19 +84,17 @@ pub(super) fn virtio_device_init(
|
|||||||
/// ## 返回值
|
/// ## 返回值
|
||||||
///
|
///
|
||||||
/// 返回一个包含所有找到的virtio设备的数组
|
/// 返回一个包含所有找到的virtio设备的数组
|
||||||
fn virtio_device_search<'a>(
|
fn virtio_device_search() -> Vec<Arc<PciDeviceStructureGeneralDevice>> {
|
||||||
list: &'a mut RwLockWriteGuard<'_, LinkedList<Box<dyn PciDeviceStructure>>>,
|
let list = &*PCI_DEVICE_LINKEDLIST;
|
||||||
) -> Vec<&'a mut PciDeviceStructureGeneralDevice> {
|
|
||||||
let mut virtio_list = Vec::new();
|
let mut virtio_list = Vec::new();
|
||||||
let result = get_pci_device_structures_mut_by_vendor_id(list, 0x1AF4);
|
let result = get_pci_device_structures_mut_by_vendor_id(list, 0x1AF4);
|
||||||
|
|
||||||
for device in result {
|
for device in result {
|
||||||
let standard_device = device.as_standard_device_mut().unwrap();
|
let standard_device = device.as_standard_device().unwrap();
|
||||||
let header = &standard_device.common_header;
|
let header = &standard_device.common_header;
|
||||||
if header.device_id >= 0x1000 && header.device_id <= 0x103F {
|
if header.device_id >= 0x1000 && header.device_id <= 0x103F {
|
||||||
virtio_list.push(standard_device);
|
virtio_list.push(standard_device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return virtio_list;
|
return virtio_list;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user