mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-10 16:26:48 +00:00
pci: 统一使用ecam root (#744)
This commit is contained in:
parent
418ad41fd8
commit
2709e017d0
@ -10,7 +10,7 @@ impl TraitPciArch for RiscV64PciArch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) {
|
fn write_config(bus_device_function: &BusDeviceFunction, offset: u8, data: u32) {
|
||||||
unimplemented!("RiscV64PciArch::write_config")
|
unimplemented!("RiscV64pci_root_0().write_config")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn address_pci_to_physical(pci_address: PciAddr) -> crate::mm::PhysAddr {
|
fn address_pci_to_physical(pci_address: PciAddr) -> crate::mm::PhysAddr {
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::arch::TraitPciArch;
|
use crate::arch::TraitPciArch;
|
||||||
use crate::driver::acpi::acpi_manager;
|
use crate::driver::acpi::acpi_manager;
|
||||||
use crate::driver::pci::pci::{
|
use crate::driver::pci::pci::{
|
||||||
BusDeviceFunction, PciAddr, PciError, PciRoot, SegmentGroupNumber, PORT_PCI_CONFIG_ADDRESS,
|
BusDeviceFunction, PciAddr, PciCam, PciError, PciRoot, SegmentGroupNumber,
|
||||||
PORT_PCI_CONFIG_DATA,
|
PORT_PCI_CONFIG_ADDRESS, PORT_PCI_CONFIG_DATA,
|
||||||
};
|
};
|
||||||
use crate::include::bindings::bindings::{io_in32, io_out32};
|
use crate::include::bindings::bindings::{io_in32, io_out32};
|
||||||
use crate::mm::PhysAddr;
|
use crate::mm::PhysAddr;
|
||||||
@ -57,6 +57,7 @@ impl TraitPciArch for X86_64PciArch {
|
|||||||
segement_group_number: segement,
|
segement_group_number: segement,
|
||||||
bus_begin: mcfg_entry.bus_number_start,
|
bus_begin: mcfg_entry.bus_number_start,
|
||||||
bus_end: mcfg_entry.bus_number_end,
|
bus_end: mcfg_entry.bus_number_end,
|
||||||
|
cam: PciCam::Ecam,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ use core::{
|
|||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref PCI_DEVICE_LINKEDLIST: PciDeviceLinkedList = PciDeviceLinkedList::new();
|
pub static ref PCI_DEVICE_LINKEDLIST: PciDeviceLinkedList = PciDeviceLinkedList::new();
|
||||||
pub static ref PCI_ROOT_0: Option<PciRoot> = {
|
pub static ref PCI_ROOT_0: Option<PciRoot> = {
|
||||||
match PciRoot::new(0) {
|
match PciRoot::new(0, PciCam::Ecam) {
|
||||||
Ok(root) => Some(root),
|
Ok(root) => Some(root),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
kerror!("Pci_root init failed because of error: {}", err);
|
kerror!("Pci_root init failed because of error: {}", err);
|
||||||
@ -34,6 +34,12 @@ lazy_static! {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn pci_root_0() -> &'static PciRoot {
|
||||||
|
PCI_ROOT_0.as_ref().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
/// PCI域地址
|
/// PCI域地址
|
||||||
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
|
#[derive(Clone, Copy, Eq, Ord, PartialEq, PartialOrd)]
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
@ -326,9 +332,9 @@ pub trait PciDeviceStructure: Send + Sync {
|
|||||||
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 = command;
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&common_header.bus_device_function,
|
common_header.bus_device_function,
|
||||||
STATUS_COMMAND_OFFSET,
|
STATUS_COMMAND_OFFSET.into(),
|
||||||
command as u32,
|
command as u32,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -602,7 +608,35 @@ pub struct PciRoot {
|
|||||||
pub segement_group_number: SegmentGroupNumber, //segement greoup的id
|
pub segement_group_number: SegmentGroupNumber, //segement greoup的id
|
||||||
pub bus_begin: u8, //该分组中的最小bus
|
pub bus_begin: u8, //该分组中的最小bus
|
||||||
pub bus_end: u8, //该分组中的最大bus
|
pub bus_end: u8, //该分组中的最大bus
|
||||||
|
/// 配置空间访问机制
|
||||||
|
pub cam: PciCam,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// PCI配置空间访问机制
|
||||||
|
///
|
||||||
|
/// 用于访问PCI设备的功能配置空间的一组机制。
|
||||||
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||||
|
pub enum PciCam {
|
||||||
|
/// PCI内存映射配置访问机制
|
||||||
|
///
|
||||||
|
/// 为每个设备功能提供256字节的配置空间访问。
|
||||||
|
MmioCam,
|
||||||
|
/// PCIe内存映射增强配置访问机制
|
||||||
|
///
|
||||||
|
/// 为每个设备功能提供4千字节(4096字节)的配置空间访问。
|
||||||
|
Ecam,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PciCam {
|
||||||
|
/// Returns the total size in bytes of the memory-mapped region.
|
||||||
|
pub const fn size(self) -> u32 {
|
||||||
|
match self {
|
||||||
|
Self::MmioCam => 0x1000000,
|
||||||
|
Self::Ecam => 0x10000000,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
///线程间共享需要,该结构体只需要在初始化时写入数据,无需读写锁保证线程安全
|
///线程间共享需要,该结构体只需要在初始化时写入数据,无需读写锁保证线程安全
|
||||||
unsafe impl Send for PciRoot {}
|
unsafe impl Send for PciRoot {}
|
||||||
unsafe impl Sync for PciRoot {}
|
unsafe impl Sync for PciRoot {}
|
||||||
@ -618,9 +652,24 @@ impl Display for PciRoot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl PciRoot {
|
impl PciRoot {
|
||||||
/// @brief 初始化结构体,获取ecam root所在物理地址后map到虚拟地址,再将该虚拟地址加入mmio_base变量
|
/// 此函数用于初始化一个PciRoot结构体实例,
|
||||||
/// @return 成功返回结果,错误返回错误类型
|
/// 该结构体基于ECAM根的物理地址,将其映射到虚拟地址
|
||||||
pub fn new(segment_group_number: SegmentGroupNumber) -> Result<Self, PciError> {
|
///
|
||||||
|
/// ## 参数
|
||||||
|
///
|
||||||
|
/// - segment_group_number: ECAM根的段组号。
|
||||||
|
/// - cam: PCI配置空间访问机制
|
||||||
|
///
|
||||||
|
/// ## 返回值
|
||||||
|
///
|
||||||
|
/// - Ok(Self): 初始化成功,返回一个新的结构体实例。
|
||||||
|
/// - Err(PciError): 初始化过程中发生错误,返回错误信息。
|
||||||
|
///
|
||||||
|
/// ## 副作用
|
||||||
|
///
|
||||||
|
/// - 成功执行后,结构体的内部状态将被初始化为包含映射后的虚拟地址。
|
||||||
|
pub fn new(segment_group_number: SegmentGroupNumber, cam: PciCam) -> Result<Self, PciError> {
|
||||||
|
assert_eq!(cam, PciCam::Ecam);
|
||||||
let mut pci_root = PciArch::ecam_root(segment_group_number)?;
|
let mut pci_root = PciArch::ecam_root(segment_group_number)?;
|
||||||
pci_root.map()?;
|
pci_root.map()?;
|
||||||
Ok(pci_root)
|
Ok(pci_root)
|
||||||
@ -646,16 +695,34 @@ impl PciRoot {
|
|||||||
}
|
}
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
/// @brief 获得要操作的寄存器相对于mmio_offset的偏移量
|
|
||||||
/// @param bus_device_function 在同一个group中pci设备的唯一标识符
|
/// # cam_offset - 获得要操作的寄存器相对于mmio_offset的偏移量
|
||||||
/// @param register_offset 寄存器在设备中的offset
|
///
|
||||||
/// @return u32 要操作的寄存器相对于mmio_offset的偏移量
|
/// 此函数用于计算一个PCI设备中特定寄存器相对于该设备的MMIO基地址的偏移量。
|
||||||
|
///
|
||||||
|
/// ## 参数
|
||||||
|
///
|
||||||
|
/// - `bus_device_function`: BusDeviceFunction,用于标识在同一组中的PCI设备。
|
||||||
|
/// - `register_offset`: u16,寄存器在设备中的偏移量。
|
||||||
|
///
|
||||||
|
/// ## 返回值
|
||||||
|
///
|
||||||
|
/// - `u32`: 成功时,返回要操作的寄存器相对于mmio_offset的偏移量。
|
||||||
|
///
|
||||||
|
/// ## Panic
|
||||||
|
///
|
||||||
|
/// - 此函数在参数有效性方面进行了断言,如果传入的`bus_device_function`无效,将panic。
|
||||||
|
/// - 此函数计算出的地址需要是字对齐的(即地址与0x3对齐)。如果不是,将panic。
|
||||||
fn cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
|
fn cam_offset(&self, bus_device_function: BusDeviceFunction, register_offset: u16) -> u32 {
|
||||||
assert!(bus_device_function.valid());
|
assert!(bus_device_function.valid());
|
||||||
let bdf = ((bus_device_function.bus - self.bus_begin) as u32) << 8
|
let bdf = ((bus_device_function.bus - self.bus_begin) as u32) << 8
|
||||||
| (bus_device_function.device as u32) << 3
|
| (bus_device_function.device as u32) << 3
|
||||||
| bus_device_function.function as u32;
|
| bus_device_function.function as u32;
|
||||||
let address = bdf << 12 | register_offset as u32;
|
let address =
|
||||||
|
bdf << match self.cam {
|
||||||
|
PciCam::MmioCam => 8,
|
||||||
|
PciCam::Ecam => 12,
|
||||||
|
} | register_offset as u32;
|
||||||
// Ensure that address is word-aligned.
|
// Ensure that address is word-aligned.
|
||||||
assert!(address & 0x3 == 0);
|
assert!(address & 0x3 == 0);
|
||||||
address
|
address
|
||||||
@ -679,7 +746,7 @@ impl PciRoot {
|
|||||||
/// @param register_offset 寄存器在设备中的offset
|
/// @param register_offset 寄存器在设备中的offset
|
||||||
/// @param data 要写入的值
|
/// @param data 要写入的值
|
||||||
pub fn write_config(
|
pub fn write_config(
|
||||||
&mut self,
|
&self,
|
||||||
bus_device_function: BusDeviceFunction,
|
bus_device_function: BusDeviceFunction,
|
||||||
register_offset: u16,
|
register_offset: u16,
|
||||||
data: u32,
|
data: u32,
|
||||||
@ -711,10 +778,10 @@ impl PciRoot {
|
|||||||
/// @param bus_device_function PCI设备的唯一标识
|
/// @param bus_device_function PCI设备的唯一标识
|
||||||
/// @return Option<u8> offset
|
/// @return Option<u8> offset
|
||||||
pub fn capabilities_offset(bus_device_function: BusDeviceFunction) -> Option<u8> {
|
pub fn capabilities_offset(bus_device_function: BusDeviceFunction) -> Option<u8> {
|
||||||
let result = PciArch::read_config(&bus_device_function, STATUS_COMMAND_OFFSET);
|
let result = pci_root_0().read_config(bus_device_function, STATUS_COMMAND_OFFSET.into());
|
||||||
let status: Status = Status::from_bits_truncate((result >> 16) as u16);
|
let status: Status = Status::from_bits_truncate((result >> 16) as u16);
|
||||||
if status.contains(Status::CAPABILITIES_LIST) {
|
if status.contains(Status::CAPABILITIES_LIST) {
|
||||||
let cap_pointer = PciArch::read_config(&bus_device_function, 0x34) as u8 & 0xFC;
|
let cap_pointer = pci_root_0().read_config(bus_device_function, 0x34) as u8 & 0xFC;
|
||||||
Some(cap_pointer)
|
Some(cap_pointer)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@ -730,21 +797,21 @@ fn pci_read_header(
|
|||||||
add_to_list: bool,
|
add_to_list: bool,
|
||||||
) -> Result<Box<dyn PciDeviceStructure>, PciError> {
|
) -> Result<Box<dyn PciDeviceStructure>, PciError> {
|
||||||
// 先读取公共header
|
// 先读取公共header
|
||||||
let result = PciArch::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 = PciArch::read_config(&bus_device_function, 0x04);
|
let result = pci_root_0().read_config(bus_device_function, 0x04);
|
||||||
let command = result as u16;
|
let command = result as u16;
|
||||||
let status = (result >> 16) as u16;
|
let status = (result >> 16) as u16;
|
||||||
|
|
||||||
let result = PciArch::read_config(&bus_device_function, 0x08);
|
let result = pci_root_0().read_config(bus_device_function, 0x08);
|
||||||
let revision_id = result as u8;
|
let revision_id = result as u8;
|
||||||
let prog_if = (result >> 8) as u8;
|
let prog_if = (result >> 8) as u8;
|
||||||
let subclass = (result >> 16) as u8;
|
let subclass = (result >> 16) as u8;
|
||||||
let class_code = (result >> 24) as u8;
|
let class_code = (result >> 24) as u8;
|
||||||
|
|
||||||
let result = PciArch::read_config(&bus_device_function, 0x0c);
|
let result = pci_root_0().read_config(bus_device_function, 0x0c);
|
||||||
let cache_line_size = result as u8;
|
let cache_line_size = result as u8;
|
||||||
let latency_timer = (result >> 8) as u8;
|
let latency_timer = (result >> 8) as u8;
|
||||||
let header_type = (result >> 16) as u8;
|
let header_type = (result >> 16) as u8;
|
||||||
@ -810,22 +877,22 @@ fn pci_read_general_device_header(
|
|||||||
bus_device_function: &BusDeviceFunction,
|
bus_device_function: &BusDeviceFunction,
|
||||||
) -> PciDeviceStructureGeneralDevice {
|
) -> PciDeviceStructureGeneralDevice {
|
||||||
let standard_device_bar = PciStandardDeviceBar::default();
|
let standard_device_bar = PciStandardDeviceBar::default();
|
||||||
let cardbus_cis_pointer = PciArch::read_config(bus_device_function, 0x28);
|
let cardbus_cis_pointer = pci_root_0().read_config(*bus_device_function, 0x28);
|
||||||
|
|
||||||
let result = PciArch::read_config(bus_device_function, 0x2c);
|
let result = pci_root_0().read_config(*bus_device_function, 0x2c);
|
||||||
let subsystem_vendor_id = result as u16;
|
let subsystem_vendor_id = result as u16;
|
||||||
let subsystem_id = (result >> 16) as u16;
|
let subsystem_id = (result >> 16) as u16;
|
||||||
|
|
||||||
let expansion_rom_base_address = PciArch::read_config(bus_device_function, 0x30);
|
let expansion_rom_base_address = pci_root_0().read_config(*bus_device_function, 0x30);
|
||||||
|
|
||||||
let result = PciArch::read_config(bus_device_function, 0x34);
|
let result = pci_root_0().read_config(*bus_device_function, 0x34);
|
||||||
let capabilities_pointer = result as u8;
|
let capabilities_pointer = result as u8;
|
||||||
let reserved0 = (result >> 8) as u8;
|
let reserved0 = (result >> 8) as u8;
|
||||||
let reserved1 = (result >> 16) as u16;
|
let reserved1 = (result >> 16) as u16;
|
||||||
|
|
||||||
let reserved2 = PciArch::read_config(bus_device_function, 0x38);
|
let reserved2 = pci_root_0().read_config(*bus_device_function, 0x38);
|
||||||
|
|
||||||
let result = PciArch::read_config(bus_device_function, 0x3c);
|
let result = pci_root_0().read_config(*bus_device_function, 0x3c);
|
||||||
let interrupt_line = result as u8;
|
let interrupt_line = result as u8;
|
||||||
let interrupt_pin = (result >> 8) as u8;
|
let interrupt_pin = (result >> 8) as u8;
|
||||||
let min_grant = (result >> 16) as u8;
|
let min_grant = (result >> 16) as u8;
|
||||||
@ -859,44 +926,44 @@ fn pci_read_pci_to_pci_bridge_header(
|
|||||||
common_header: PciDeviceStructureHeader,
|
common_header: PciDeviceStructureHeader,
|
||||||
bus_device_function: &BusDeviceFunction,
|
bus_device_function: &BusDeviceFunction,
|
||||||
) -> PciDeviceStructurePciToPciBridge {
|
) -> PciDeviceStructurePciToPciBridge {
|
||||||
let bar0 = PciArch::read_config(bus_device_function, 0x10);
|
let bar0 = pci_root_0().read_config(*bus_device_function, 0x10);
|
||||||
let bar1 = PciArch::read_config(bus_device_function, 0x14);
|
let bar1 = pci_root_0().read_config(*bus_device_function, 0x14);
|
||||||
|
|
||||||
let result = PciArch::read_config(bus_device_function, 0x18);
|
let result = pci_root_0().read_config(*bus_device_function, 0x18);
|
||||||
|
|
||||||
let primary_bus_number = result as u8;
|
let primary_bus_number = result as u8;
|
||||||
let secondary_bus_number = (result >> 8) as u8;
|
let secondary_bus_number = (result >> 8) as u8;
|
||||||
let subordinate_bus_number = (result >> 16) as u8;
|
let subordinate_bus_number = (result >> 16) as u8;
|
||||||
let secondary_latency_timer = (result >> 24) as u8;
|
let secondary_latency_timer = (result >> 24) as u8;
|
||||||
|
|
||||||
let result = PciArch::read_config(bus_device_function, 0x1c);
|
let result = pci_root_0().read_config(*bus_device_function, 0x1c);
|
||||||
let io_base = result as u8;
|
let io_base = result as u8;
|
||||||
let io_limit = (result >> 8) as u8;
|
let io_limit = (result >> 8) as u8;
|
||||||
let secondary_status = (result >> 16) as u16;
|
let secondary_status = (result >> 16) as u16;
|
||||||
|
|
||||||
let result = PciArch::read_config(bus_device_function, 0x20);
|
let result = pci_root_0().read_config(*bus_device_function, 0x20);
|
||||||
let memory_base = result as u16;
|
let memory_base = result as u16;
|
||||||
let memory_limit = (result >> 16) as u16;
|
let memory_limit = (result >> 16) as u16;
|
||||||
|
|
||||||
let result = PciArch::read_config(bus_device_function, 0x24);
|
let result = pci_root_0().read_config(*bus_device_function, 0x24);
|
||||||
let prefetchable_memory_base = result as u16;
|
let prefetchable_memory_base = result as u16;
|
||||||
let prefetchable_memory_limit = (result >> 16) as u16;
|
let prefetchable_memory_limit = (result >> 16) as u16;
|
||||||
|
|
||||||
let prefetchable_base_upper_32_bits = PciArch::read_config(bus_device_function, 0x28);
|
let prefetchable_base_upper_32_bits = pci_root_0().read_config(*bus_device_function, 0x28);
|
||||||
let prefetchable_limit_upper_32_bits = PciArch::read_config(bus_device_function, 0x2c);
|
let prefetchable_limit_upper_32_bits = pci_root_0().read_config(*bus_device_function, 0x2c);
|
||||||
|
|
||||||
let result = PciArch::read_config(bus_device_function, 0x30);
|
let result = pci_root_0().read_config(*bus_device_function, 0x30);
|
||||||
let io_base_upper_16_bits = result as u16;
|
let io_base_upper_16_bits = result as u16;
|
||||||
let io_limit_upper_16_bits = (result >> 16) as u16;
|
let io_limit_upper_16_bits = (result >> 16) as u16;
|
||||||
|
|
||||||
let result = PciArch::read_config(bus_device_function, 0x34);
|
let result = pci_root_0().read_config(*bus_device_function, 0x34);
|
||||||
let capability_pointer = result as u8;
|
let capability_pointer = result as u8;
|
||||||
let reserved0 = (result >> 8) as u8;
|
let reserved0 = (result >> 8) as u8;
|
||||||
let reserved1 = (result >> 16) as u16;
|
let reserved1 = (result >> 16) as u16;
|
||||||
|
|
||||||
let expansion_rom_base_address = PciArch::read_config(bus_device_function, 0x38);
|
let expansion_rom_base_address = pci_root_0().read_config(*bus_device_function, 0x38);
|
||||||
|
|
||||||
let result = PciArch::read_config(bus_device_function, 0x3c);
|
let result = pci_root_0().read_config(*bus_device_function, 0x3c);
|
||||||
let interrupt_line = result as u8;
|
let interrupt_line = result as u8;
|
||||||
let interrupt_pin = (result >> 8) as u8;
|
let interrupt_pin = (result >> 8) as u8;
|
||||||
let bridge_control = (result >> 16) as u16;
|
let bridge_control = (result >> 16) as u16;
|
||||||
@ -940,38 +1007,39 @@ fn pci_read_pci_to_cardbus_bridge_header(
|
|||||||
common_header: PciDeviceStructureHeader,
|
common_header: PciDeviceStructureHeader,
|
||||||
busdevicefunction: &BusDeviceFunction,
|
busdevicefunction: &BusDeviceFunction,
|
||||||
) -> PciDeviceStructurePciToCardbusBridge {
|
) -> PciDeviceStructurePciToCardbusBridge {
|
||||||
let cardbus_socket_ex_ca_base_address = PciArch::read_config(busdevicefunction, 0x10);
|
let cardbus_socket_ex_ca_base_address = pci_root_0().read_config(*busdevicefunction, 0x10);
|
||||||
|
|
||||||
let result = PciArch::read_config(busdevicefunction, 0x14);
|
let result = pci_root_0().read_config(*busdevicefunction, 0x14);
|
||||||
let offset_of_capabilities_list = result as u8;
|
let offset_of_capabilities_list = result as u8;
|
||||||
let reserved = (result >> 8) as u8;
|
let reserved = (result >> 8) as u8;
|
||||||
let secondary_status = (result >> 16) as u16;
|
let secondary_status = (result >> 16) as u16;
|
||||||
|
|
||||||
let result = PciArch::read_config(busdevicefunction, 0x18);
|
let result = pci_root_0().read_config(*busdevicefunction, 0x18);
|
||||||
let pci_bus_number = result as u8;
|
let pci_bus_number = result as u8;
|
||||||
let card_bus_bus_number = (result >> 8) as u8;
|
let card_bus_bus_number = (result >> 8) as u8;
|
||||||
let subordinate_bus_number = (result >> 16) as u8;
|
let subordinate_bus_number = (result >> 16) as u8;
|
||||||
let card_bus_latency_timer = (result >> 24) as u8;
|
let card_bus_latency_timer = (result >> 24) as u8;
|
||||||
|
|
||||||
let memory_base_address0 = PciArch::read_config(busdevicefunction, 0x1c);
|
let memory_base_address0 = pci_root_0().read_config(*busdevicefunction, 0x1c);
|
||||||
let memory_limit0 = PciArch::read_config(busdevicefunction, 0x20);
|
let memory_limit0 = pci_root_0().read_config(*busdevicefunction, 0x20);
|
||||||
let memory_base_address1 = PciArch::read_config(busdevicefunction, 0x24);
|
let memory_base_address1 = pci_root_0().read_config(*busdevicefunction, 0x24);
|
||||||
let memory_limit1 = PciArch::read_config(busdevicefunction, 0x28);
|
let memory_limit1 = pci_root_0().read_config(*busdevicefunction, 0x28);
|
||||||
|
|
||||||
let io_base_address0 = PciArch::read_config(busdevicefunction, 0x2c);
|
let io_base_address0 = pci_root_0().read_config(*busdevicefunction, 0x2c);
|
||||||
let io_limit0 = PciArch::read_config(busdevicefunction, 0x30);
|
let io_limit0 = pci_root_0().read_config(*busdevicefunction, 0x30);
|
||||||
let io_base_address1 = PciArch::read_config(busdevicefunction, 0x34);
|
let io_base_address1 = pci_root_0().read_config(*busdevicefunction, 0x34);
|
||||||
let io_limit1 = PciArch::read_config(busdevicefunction, 0x38);
|
let io_limit1 = pci_root_0().read_config(*busdevicefunction, 0x38);
|
||||||
let result = PciArch::read_config(busdevicefunction, 0x3c);
|
let result = pci_root_0().read_config(*busdevicefunction, 0x3c);
|
||||||
let interrupt_line = result as u8;
|
let interrupt_line = result as u8;
|
||||||
let interrupt_pin = (result >> 8) as u8;
|
let interrupt_pin = (result >> 8) as u8;
|
||||||
let bridge_control = (result >> 16) as u16;
|
let bridge_control = (result >> 16) as u16;
|
||||||
|
|
||||||
let result = PciArch::read_config(busdevicefunction, 0x40);
|
let result = pci_root_0().read_config(*busdevicefunction, 0x40);
|
||||||
let subsystem_device_id = result as u16;
|
let subsystem_device_id = result as u16;
|
||||||
let subsystem_vendor_id = (result >> 16) as u16;
|
let subsystem_vendor_id = (result >> 16) as u16;
|
||||||
|
|
||||||
let pc_card_legacy_mode_base_address_16_bit = PciArch::read_config(busdevicefunction, 0x44);
|
let pc_card_legacy_mode_base_address_16_bit =
|
||||||
|
pci_root_0().read_config(*busdevicefunction, 0x44);
|
||||||
PciDeviceStructurePciToCardbusBridge {
|
PciDeviceStructurePciToCardbusBridge {
|
||||||
common_header,
|
common_header,
|
||||||
cardbus_socket_ex_ca_base_address,
|
cardbus_socket_ex_ca_base_address,
|
||||||
@ -1353,19 +1421,25 @@ pub fn pci_bar_init(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let bar_info;
|
let bar_info;
|
||||||
let bar_orig = PciArch::read_config(&bus_device_function, BAR0_OFFSET + 4 * bar_index);
|
let bar_orig =
|
||||||
PciArch::write_config(
|
pci_root_0().read_config(bus_device_function, (BAR0_OFFSET + 4 * bar_index).into());
|
||||||
&bus_device_function,
|
pci_root_0().write_config(
|
||||||
BAR0_OFFSET + 4 * bar_index,
|
bus_device_function,
|
||||||
|
(BAR0_OFFSET + 4 * bar_index).into(),
|
||||||
0xffffffff,
|
0xffffffff,
|
||||||
);
|
);
|
||||||
let size_mask = PciArch::read_config(&bus_device_function, BAR0_OFFSET + 4 * bar_index);
|
let size_mask =
|
||||||
|
pci_root_0().read_config(bus_device_function, (BAR0_OFFSET + 4 * bar_index).into());
|
||||||
// A wrapping add is necessary to correctly handle the case of unused BARs, which read back
|
// A wrapping add is necessary to correctly handle the case of unused BARs, which read back
|
||||||
// as 0, and should be treated as size 0.
|
// as 0, and should be treated as size 0.
|
||||||
let size = (!(size_mask & 0xfffffff0)).wrapping_add(1);
|
let size = (!(size_mask & 0xfffffff0)).wrapping_add(1);
|
||||||
//kdebug!("bar_orig:{:#x},size: {:#x}", bar_orig,size);
|
//kdebug!("bar_orig:{:#x},size: {:#x}", bar_orig,size);
|
||||||
// Restore the original value.
|
// Restore the original value.
|
||||||
PciArch::write_config(&bus_device_function, BAR0_OFFSET + 4 * bar_index, bar_orig);
|
pci_root_0().write_config(
|
||||||
|
bus_device_function,
|
||||||
|
(BAR0_OFFSET + 4 * bar_index).into(),
|
||||||
|
bar_orig,
|
||||||
|
);
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1382,8 +1456,10 @@ pub fn pci_bar_init(
|
|||||||
if bar_index >= 5 {
|
if bar_index >= 5 {
|
||||||
return Err(PciError::InvalidBarType);
|
return Err(PciError::InvalidBarType);
|
||||||
}
|
}
|
||||||
let address_top =
|
let address_top = pci_root_0().read_config(
|
||||||
PciArch::read_config(&bus_device_function, BAR0_OFFSET + 4 * (bar_index + 1));
|
bus_device_function,
|
||||||
|
(BAR0_OFFSET + 4 * (bar_index + 1)).into(),
|
||||||
|
);
|
||||||
address |= u64::from(address_top) << 32;
|
address |= u64::from(address_top) << 32;
|
||||||
bar_index_ignore = bar_index + 1; //下个bar跳过,因为64位的memory bar覆盖了两个bar
|
bar_index_ignore = bar_index + 1; //下个bar跳过,因为64位的memory bar覆盖了两个bar
|
||||||
}
|
}
|
||||||
@ -1463,7 +1539,7 @@ impl Iterator for CapabilityIterator {
|
|||||||
let offset = self.next_capability_offset?;
|
let offset = self.next_capability_offset?;
|
||||||
|
|
||||||
// Read the first 4 bytes of the capability.
|
// Read the first 4 bytes of the capability.
|
||||||
let capability_header = PciArch::read_config(&self.bus_device_function, offset);
|
let capability_header = pci_root_0().read_config(self.bus_device_function, offset.into());
|
||||||
let id = capability_header as u8;
|
let id = capability_header as u8;
|
||||||
let next_offset = (capability_header >> 8) as u8;
|
let next_offset = (capability_header >> 8) as u8;
|
||||||
let private_header = (capability_header >> 16) as u16;
|
let private_header = (capability_header >> 16) as u16;
|
||||||
|
@ -8,9 +8,8 @@ use alloc::sync::Arc;
|
|||||||
use alloc::vec::Vec;
|
use alloc::vec::Vec;
|
||||||
use system_error::SystemError;
|
use system_error::SystemError;
|
||||||
|
|
||||||
use super::pci::{PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError};
|
use super::pci::{pci_root_0, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError};
|
||||||
use crate::arch::msi::{arch_msi_message_address, arch_msi_message_data};
|
use crate::arch::msi::{arch_msi_message_address, arch_msi_message_data};
|
||||||
use crate::arch::{PciArch, TraitPciArch};
|
|
||||||
|
|
||||||
use crate::driver::base::device::DeviceId;
|
use crate::driver::base::device::DeviceId;
|
||||||
use crate::exception::irqdesc::{IrqHandleFlags, IrqHandler};
|
use crate::exception::irqdesc::{IrqHandleFlags, IrqHandler};
|
||||||
@ -158,15 +157,19 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
// 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() {
|
||||||
let data =
|
let data = pci_root_0()
|
||||||
PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
|
.read_config(self.common_header().bus_device_function, cap_offset.into());
|
||||||
let irq_max_num = ((data >> 16) & 0x7ff) as u16 + 1;
|
let irq_max_num = ((data >> 16) & 0x7ff) as u16 + 1;
|
||||||
let data =
|
let data = pci_root_0().read_config(
|
||||||
PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 4);
|
self.common_header().bus_device_function,
|
||||||
|
(cap_offset + 4).into(),
|
||||||
|
);
|
||||||
let msix_table_bar = (data & 0x07) as u8;
|
let msix_table_bar = (data & 0x07) as u8;
|
||||||
let msix_table_offset = data & (!0x07);
|
let msix_table_offset = data & (!0x07);
|
||||||
let data =
|
let data = pci_root_0().read_config(
|
||||||
PciArch::read_config(&self.common_header().bus_device_function, cap_offset + 8);
|
self.common_header().bus_device_function,
|
||||||
|
(cap_offset + 8).into(),
|
||||||
|
);
|
||||||
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()? = IrqType::Msix {
|
||||||
@ -190,8 +193,8 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
// 其次MSI
|
// 其次MSI
|
||||||
if flag.contains(IRQ::PCI_IRQ_MSI) {
|
if flag.contains(IRQ::PCI_IRQ_MSI) {
|
||||||
if let Some(cap_offset) = self.msi_capability_offset() {
|
if let Some(cap_offset) = self.msi_capability_offset() {
|
||||||
let data =
|
let data = pci_root_0()
|
||||||
PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
|
.read_config(self.common_header().bus_device_function, cap_offset.into());
|
||||||
let message_control = (data >> 16) as u16;
|
let message_control = (data >> 16) as u16;
|
||||||
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;
|
||||||
@ -247,16 +250,16 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type {
|
||||||
IrqType::Msix { cap_offset, .. } => {
|
IrqType::Msix { cap_offset, .. } => {
|
||||||
let mut message =
|
let mut message = pci_root_0()
|
||||||
PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
|
.read_config(self.common_header().bus_device_function, cap_offset.into());
|
||||||
if enable {
|
if enable {
|
||||||
message |= 1 << 31;
|
message |= 1 << 31;
|
||||||
} else {
|
} else {
|
||||||
message &= !(1 << 31);
|
message &= !(1 << 31);
|
||||||
}
|
}
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
message,
|
message,
|
||||||
);
|
);
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
@ -278,16 +281,16 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
if let Some(irq_type) = self.irq_type_mut() {
|
if let Some(irq_type) = self.irq_type_mut() {
|
||||||
match *irq_type {
|
match *irq_type {
|
||||||
IrqType::Msi { cap_offset, .. } => {
|
IrqType::Msi { cap_offset, .. } => {
|
||||||
let mut message =
|
let mut message = pci_root_0()
|
||||||
PciArch::read_config(&self.common_header().bus_device_function, cap_offset);
|
.read_config(self.common_header().bus_device_function, cap_offset.into());
|
||||||
if enable {
|
if enable {
|
||||||
message |= 1 << 16;
|
message |= 1 << 16;
|
||||||
} else {
|
} else {
|
||||||
message &= !(1 << 16);
|
message &= !(1 << 16);
|
||||||
}
|
}
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
message,
|
message,
|
||||||
);
|
);
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
@ -404,84 +407,84 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
let msg_data = arch_msi_message_data(irq_num.data() as u16, 0, trigger);
|
let msg_data = arch_msi_message_data(irq_num.data() as u16, 0, trigger);
|
||||||
// 写入Message Data和Message Address
|
// 写入Message Data和Message Address
|
||||||
if address_64 {
|
if address_64 {
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 4,
|
(cap_offset + 4).into(),
|
||||||
msg_address,
|
msg_address,
|
||||||
);
|
);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 8,
|
(cap_offset + 8).into(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 12,
|
(cap_offset + 12).into(),
|
||||||
msg_data,
|
msg_data,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 4,
|
(cap_offset + 4).into(),
|
||||||
msg_address,
|
msg_address,
|
||||||
);
|
);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 8,
|
(cap_offset + 8).into(),
|
||||||
msg_data,
|
msg_data,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
let data = PciArch::read_config(
|
let data = pci_root_0().read_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
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().len() {
|
||||||
1 => {
|
1 => {
|
||||||
let temp = message_control & (!0x0070);
|
let temp = message_control & (!0x0070);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
(temp as u32) << 16,
|
(temp as u32) << 16,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
let temp = message_control & (!0x0070);
|
let temp = message_control & (!0x0070);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
((temp | (0x0001 << 4)) as u32) << 16,
|
((temp | (0x0001 << 4)) as u32) << 16,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
4 => {
|
4 => {
|
||||||
let temp = message_control & (!0x0070);
|
let temp = message_control & (!0x0070);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
((temp | (0x0002 << 4)) as u32) << 16,
|
((temp | (0x0002 << 4)) as u32) << 16,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
8 => {
|
8 => {
|
||||||
let temp = message_control & (!0x0070);
|
let temp = message_control & (!0x0070);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
((temp | (0x0003 << 4)) as u32) << 16,
|
((temp | (0x0003 << 4)) as u32) << 16,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
16 => {
|
16 => {
|
||||||
let temp = message_control & (!0x0070);
|
let temp = message_control & (!0x0070);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
((temp | (0x0004 << 4)) as u32) << 16,
|
((temp | (0x0004 << 4)) as u32) << 16,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
32 => {
|
32 => {
|
||||||
let temp = message_control & (!0x0070);
|
let temp = message_control & (!0x0070);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
((temp | (0x0005 << 4)) as u32) << 16,
|
((temp | (0x0005 << 4)) as u32) << 16,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -629,21 +632,25 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
let irq = IrqNumber::new((*vector).into());
|
let irq = IrqNumber::new((*vector).into());
|
||||||
irq_manager().free_irq(irq, None);
|
irq_manager().free_irq(irq, None);
|
||||||
}
|
}
|
||||||
PciArch::write_config(&self.common_header().bus_device_function, cap_offset, 0);
|
pci_root_0().write_config(
|
||||||
PciArch::write_config(
|
self.common_header().bus_device_function,
|
||||||
&self.common_header().bus_device_function,
|
cap_offset.into(),
|
||||||
cap_offset + 4,
|
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 8,
|
(cap_offset + 4).into(),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
pci_root_0().write_config(
|
||||||
|
self.common_header().bus_device_function,
|
||||||
|
(cap_offset + 8).into(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
if address_64 {
|
if address_64 {
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 12,
|
(cap_offset + 12).into(),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -675,7 +682,11 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
let irq = IrqNumber::new((*vector).into());
|
let irq = IrqNumber::new((*vector).into());
|
||||||
irq_manager().free_irq(irq, None);
|
irq_manager().free_irq(irq, None);
|
||||||
}
|
}
|
||||||
PciArch::write_config(&self.common_header().bus_device_function, cap_offset, 0);
|
pci_root_0().write_config(
|
||||||
|
self.common_header().bus_device_function,
|
||||||
|
cap_offset.into(),
|
||||||
|
0,
|
||||||
|
);
|
||||||
let pcistandardbar = self
|
let pcistandardbar = self
|
||||||
.bar()
|
.bar()
|
||||||
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
|
.ok_or(PciError::PciIrqError(PciIrqError::PciBarNotInited))
|
||||||
@ -750,26 +761,26 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
if maskable {
|
if maskable {
|
||||||
match address_64 {
|
match address_64 {
|
||||||
true => {
|
true => {
|
||||||
let mut mask = PciArch::read_config(
|
let mut mask = pci_root_0().read_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 16,
|
(cap_offset + 16).into(),
|
||||||
);
|
);
|
||||||
mask |= 1 << irq_index;
|
mask |= 1 << irq_index;
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
mask,
|
mask,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
false => {
|
false => {
|
||||||
let mut mask = PciArch::read_config(
|
let mut mask = pci_root_0().read_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 12,
|
(cap_offset + 12).into(),
|
||||||
);
|
);
|
||||||
mask |= 1 << irq_index;
|
mask |= 1 << irq_index;
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
mask,
|
mask,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -871,26 +882,26 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
if maskable {
|
if maskable {
|
||||||
match address_64 {
|
match address_64 {
|
||||||
true => {
|
true => {
|
||||||
let mut mask = PciArch::read_config(
|
let mut mask = pci_root_0().read_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 16,
|
(cap_offset + 16).into(),
|
||||||
);
|
);
|
||||||
mask &= !(1 << irq_index);
|
mask &= !(1 << irq_index);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
mask,
|
mask,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
false => {
|
false => {
|
||||||
let mut mask = PciArch::read_config(
|
let mut mask = pci_root_0().read_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 12,
|
(cap_offset + 12).into(),
|
||||||
);
|
);
|
||||||
mask &= !(1 << irq_index);
|
mask &= !(1 << irq_index);
|
||||||
PciArch::write_config(
|
pci_root_0().write_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset,
|
cap_offset.into(),
|
||||||
mask,
|
mask,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -993,17 +1004,17 @@ pub trait PciInterrupt: PciDeviceStructure {
|
|||||||
if maskable {
|
if maskable {
|
||||||
match address_64 {
|
match address_64 {
|
||||||
true => {
|
true => {
|
||||||
let mut pend = PciArch::read_config(
|
let mut pend = pci_root_0().read_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 20,
|
(cap_offset + 20).into(),
|
||||||
);
|
);
|
||||||
pend &= 1 << irq_index;
|
pend &= 1 << irq_index;
|
||||||
return Ok(pend != 0);
|
return Ok(pend != 0);
|
||||||
}
|
}
|
||||||
false => {
|
false => {
|
||||||
let mut pend = PciArch::read_config(
|
let mut pend = pci_root_0().read_config(
|
||||||
&self.common_header().bus_device_function,
|
self.common_header().bus_device_function,
|
||||||
cap_offset + 16,
|
(cap_offset + 16).into(),
|
||||||
);
|
);
|
||||||
pend &= 1 << irq_index;
|
pend &= 1 << irq_index;
|
||||||
return Ok(pend != 0);
|
return Ok(pend != 0);
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
//! PCI transport for VirtIO.
|
//! PCI transport for VirtIO.
|
||||||
use crate::arch::{PciArch, TraitPciArch};
|
|
||||||
use crate::driver::base::device::DeviceId;
|
use crate::driver::base::device::DeviceId;
|
||||||
use crate::driver::pci::pci::{
|
use crate::driver::pci::pci::{
|
||||||
BusDeviceFunction, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
|
pci_root_0, BusDeviceFunction, PciDeviceStructure, PciDeviceStructureGeneralDevice, PciError,
|
||||||
PciStandardDeviceBar, PCI_CAP_ID_VNDR,
|
PciStandardDeviceBar, PCI_CAP_ID_VNDR,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -169,15 +169,17 @@ impl PciTransport {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let struct_info = VirtioCapabilityInfo {
|
let struct_info = VirtioCapabilityInfo {
|
||||||
bar: PciArch::read_config(&bus_device_function, capability.offset + CAP_BAR_OFFSET)
|
bar: pci_root_0().read_config(
|
||||||
as u8,
|
bus_device_function,
|
||||||
offset: PciArch::read_config(
|
(capability.offset + CAP_BAR_OFFSET).into(),
|
||||||
&bus_device_function,
|
) as u8,
|
||||||
capability.offset + CAP_BAR_OFFSET_OFFSET,
|
offset: pci_root_0().read_config(
|
||||||
|
bus_device_function,
|
||||||
|
(capability.offset + CAP_BAR_OFFSET_OFFSET).into(),
|
||||||
),
|
),
|
||||||
length: PciArch::read_config(
|
length: pci_root_0().read_config(
|
||||||
&bus_device_function,
|
bus_device_function,
|
||||||
capability.offset + CAP_LENGTH_OFFSET,
|
(capability.offset + CAP_LENGTH_OFFSET).into(),
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -187,9 +189,9 @@ impl PciTransport {
|
|||||||
}
|
}
|
||||||
VIRTIO_PCI_CAP_NOTIFY_CFG if cap_len >= 20 && notify_cfg.is_none() => {
|
VIRTIO_PCI_CAP_NOTIFY_CFG if cap_len >= 20 && notify_cfg.is_none() => {
|
||||||
notify_cfg = Some(struct_info);
|
notify_cfg = Some(struct_info);
|
||||||
notify_off_multiplier = PciArch::read_config(
|
notify_off_multiplier = pci_root_0().read_config(
|
||||||
&bus_device_function,
|
bus_device_function,
|
||||||
capability.offset + CAP_NOTIFY_OFF_MULTIPLIER_OFFSET,
|
(capability.offset + CAP_NOTIFY_OFF_MULTIPLIER_OFFSET).into(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
VIRTIO_PCI_CAP_ISR_CFG if isr_cfg.is_none() => {
|
VIRTIO_PCI_CAP_ISR_CFG if isr_cfg.is_none() => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user