From df42397cea90b46d2676631160146ed409b464ee Mon Sep 17 00:00:00 2001 From: Yuke Peng Date: Thu, 10 Aug 2023 16:23:02 +0800 Subject: [PATCH] Remove jinux-pci and hide PCI ports --- Cargo.lock | 19 - Cargo.toml | 1 - Components.toml | 1 - .../jinux-frame/src/arch/x86/device/mod.rs | 1 - framework/jinux-frame/src/arch/x86/mod.rs | 1 + .../src/arch/x86/{device => }/pci.rs | 3 +- .../jinux-frame/src/bus/pci/device_info.rs | 2 +- services/comps/block/Cargo.toml | 1 - services/comps/input/Cargo.toml | 1 - services/comps/network/Cargo.toml | 1 - services/comps/pci/Cargo.toml | 22 - services/comps/pci/src/capability/exp.rs | 23 - services/comps/pci/src/capability/mod.rs | 111 ---- services/comps/pci/src/capability/msi.rs | 52 -- services/comps/pci/src/capability/msix.rs | 21 - services/comps/pci/src/capability/pm.rs | 29 - services/comps/pci/src/capability/sata.rs | 24 - .../comps/pci/src/capability/vendor/mod.rs | 28 - .../comps/pci/src/capability/vendor/virtio.rs | 30 -- services/comps/pci/src/lib.rs | 90 ---- services/comps/pci/src/msix.rs | 121 ----- services/comps/pci/src/util.rs | 498 ------------------ services/comps/virtio/Cargo.toml | 1 - 23 files changed, 3 insertions(+), 1078 deletions(-) rename framework/jinux-frame/src/arch/x86/{device => }/pci.rs (70%) delete mode 100644 services/comps/pci/Cargo.toml delete mode 100644 services/comps/pci/src/capability/exp.rs delete mode 100644 services/comps/pci/src/capability/mod.rs delete mode 100644 services/comps/pci/src/capability/msi.rs delete mode 100644 services/comps/pci/src/capability/msix.rs delete mode 100644 services/comps/pci/src/capability/pm.rs delete mode 100644 services/comps/pci/src/capability/sata.rs delete mode 100644 services/comps/pci/src/capability/vendor/mod.rs delete mode 100644 services/comps/pci/src/capability/vendor/virtio.rs delete mode 100644 services/comps/pci/src/lib.rs delete mode 100644 services/comps/pci/src/msix.rs delete mode 100644 services/comps/pci/src/util.rs diff --git a/Cargo.lock b/Cargo.lock index ea38f7f85..dfb6e6c7e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -659,7 +659,6 @@ dependencies = [ "bitflags 1.3.2", "component", "jinux-frame", - "jinux-pci", "jinux-util", "jinux-virtio", "lazy_static", @@ -716,7 +715,6 @@ dependencies = [ "bitflags 1.3.2", "component", "jinux-frame", - "jinux-pci", "jinux-rights", "jinux-util", "jinux-virtio", @@ -732,7 +730,6 @@ version = "0.1.0" dependencies = [ "component", "jinux-frame", - "jinux-pci", "jinux-rights", "jinux-util", "jinux-virtio", @@ -742,21 +739,6 @@ dependencies = [ "spin 0.9.8", ] -[[package]] -name = "jinux-pci" -version = "0.1.0" -dependencies = [ - "bitflags 1.3.2", - "component", - "jinux-frame", - "jinux-rights", - "jinux-util", - "lazy_static", - "log", - "pod", - "spin 0.9.8", -] - [[package]] name = "jinux-rights" version = "0.1.0" @@ -847,7 +829,6 @@ dependencies = [ "component", "int-to-c-enum", "jinux-frame", - "jinux-pci", "jinux-rights", "jinux-util", "log", diff --git a/Cargo.toml b/Cargo.toml index 15a5c398b..d78f71130 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,6 @@ jinux-framebuffer = { path = "services/comps/framebuffer" } members = [ "build", "framework/jinux-frame", - "services/comps/pci", "services/comps/virtio", "services/comps/input", "services/comps/block", diff --git a/Components.toml b/Components.toml index 2f247f914..a608eaa3d 100644 --- a/Components.toml +++ b/Components.toml @@ -1,7 +1,6 @@ # template [components] std = { name = "jinux-std" } -pci = { name = "jinux-pci" } virtio = { name = "jinux-virtio" } input = { name = "jinux-input" } block = { name = "jinux-block" } diff --git a/framework/jinux-frame/src/arch/x86/device/mod.rs b/framework/jinux-frame/src/arch/x86/device/mod.rs index 33c4ca704..9499ac3f2 100644 --- a/framework/jinux-frame/src/arch/x86/device/mod.rs +++ b/framework/jinux-frame/src/arch/x86/device/mod.rs @@ -3,5 +3,4 @@ pub mod cmos; pub mod io_port; -pub mod pci; pub mod serial; diff --git a/framework/jinux-frame/src/arch/x86/mod.rs b/framework/jinux-frame/src/arch/x86/mod.rs index 4ec8d00ad..a55be1644 100644 --- a/framework/jinux-frame/src/arch/x86/mod.rs +++ b/framework/jinux-frame/src/arch/x86/mod.rs @@ -5,6 +5,7 @@ pub mod iommu; pub(crate) mod irq; mod kernel; pub(crate) mod mm; +pub(crate) mod pci; pub(crate) mod timer; use alloc::fmt; diff --git a/framework/jinux-frame/src/arch/x86/device/pci.rs b/framework/jinux-frame/src/arch/x86/pci.rs similarity index 70% rename from framework/jinux-frame/src/arch/x86/device/pci.rs rename to framework/jinux-frame/src/arch/x86/pci.rs index ae8545981..34a8d9bcb 100644 --- a/framework/jinux-frame/src/arch/x86/device/pci.rs +++ b/framework/jinux-frame/src/arch/x86/pci.rs @@ -1,7 +1,6 @@ //! PCI bus io port -use super::io_port::IoPort; -use super::io_port::{ReadWriteAccess, WriteOnlyAccess}; +use super::device::io_port::{IoPort, ReadWriteAccess, WriteOnlyAccess}; pub static PCI_ADDRESS_PORT: IoPort = unsafe { IoPort::new(0x0CF8) }; pub static PCI_DATA_PORT: IoPort = unsafe { IoPort::new(0x0CFC) }; diff --git a/framework/jinux-frame/src/bus/pci/device_info.rs b/framework/jinux-frame/src/bus/pci/device_info.rs index 6d31ded94..1c646f783 100644 --- a/framework/jinux-frame/src/bus/pci/device_info.rs +++ b/framework/jinux-frame/src/bus/pci/device_info.rs @@ -1,6 +1,6 @@ use core::iter; -use crate::arch::device::pci::{PCI_ADDRESS_PORT, PCI_DATA_PORT}; +use crate::arch::pci::{PCI_ADDRESS_PORT, PCI_DATA_PORT}; use super::cfg_space::PciDeviceCommonCfgOffset; diff --git a/services/comps/block/Cargo.toml b/services/comps/block/Cargo.toml index d500b8c51..9c239281a 100644 --- a/services/comps/block/Cargo.toml +++ b/services/comps/block/Cargo.toml @@ -9,7 +9,6 @@ edition = "2021" bitflags = "1.3" spin = "0.9.4" jinux-frame = { path = "../../../framework/jinux-frame" } -jinux-pci = { path = "../pci" } jinux-virtio = { path = "../virtio" } jinux-util = { path = "../../libs/jinux-util" } component = { path = "../../libs/comp-sys/component" } diff --git a/services/comps/input/Cargo.toml b/services/comps/input/Cargo.toml index addd1ab7d..bcb054b97 100644 --- a/services/comps/input/Cargo.toml +++ b/services/comps/input/Cargo.toml @@ -9,7 +9,6 @@ edition = "2021" bitflags = "1.3" spin = "0.9.4" jinux-frame = { path = "../../../framework/jinux-frame" } -jinux-pci = { path = "../pci" } jinux-virtio = { path = "../virtio" } jinux-util = { path = "../../libs/jinux-util" } jinux-rights = { path = "../../libs/jinux-rights" } diff --git a/services/comps/network/Cargo.toml b/services/comps/network/Cargo.toml index 89bc49499..7e3c13af1 100644 --- a/services/comps/network/Cargo.toml +++ b/services/comps/network/Cargo.toml @@ -10,7 +10,6 @@ component = { path = "../../libs/comp-sys/component" } jinux-frame = { path = "../../../framework/jinux-frame" } jinux-virtio = { path = "../virtio" } jinux-util = { path = "../../libs/jinux-util" } -jinux-pci = { path = "../pci" } jinux-rights = { path = "../../libs/jinux-rights" } spin = "0.9.4" ringbuf = { version = "0.3.2", default-features = false, features = ["alloc"] } diff --git a/services/comps/pci/Cargo.toml b/services/comps/pci/Cargo.toml deleted file mode 100644 index 843fdad9f..000000000 --- a/services/comps/pci/Cargo.toml +++ /dev/null @@ -1,22 +0,0 @@ -[package] -name = "jinux-pci" -version = "0.1.0" -edition = "2021" - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -bitflags = "1.3" -spin = "0.9.4" -jinux-frame = { path = "../../../framework/jinux-frame" } -jinux-util = { path = "../../libs/jinux-util" } -jinux-rights = { path = "../../libs/jinux-rights" } -pod = { git = "https://github.com/jinzhao-dev/pod", rev = "71e59ec" } -component = { path = "../../libs/comp-sys/component" } -log = "0.4" - -[dependencies.lazy_static] -version = "1.0" -features = ["spin_no_std"] - -[features] diff --git a/services/comps/pci/src/capability/exp.rs b/services/comps/pci/src/capability/exp.rs deleted file mode 100644 index 6018054c4..000000000 --- a/services/comps/pci/src/capability/exp.rs +++ /dev/null @@ -1,23 +0,0 @@ -use crate::util::CSpaceAccessMethod; -use jinux_frame::bus::pci::PciDeviceLocation; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct CapabilityEXPData { - interrupt_message_number: u16, - slot_implemented: u16, - device_port_type: u16, - cap_version: u16, -} - -impl CapabilityEXPData { - pub(crate) fn new(loc: PciDeviceLocation, cap_ptr: u16) -> Self { - let am = CSpaceAccessMethod::IO; - let cap = am.read16(loc, cap_ptr + 0x2); - Self { - interrupt_message_number: (cap >> 9) & 0b11111, - slot_implemented: (cap >> 8) & 0x1, - device_port_type: (cap >> 4) & 0xf, - cap_version: cap & 0xf, - } - } -} diff --git a/services/comps/pci/src/capability/mod.rs b/services/comps/pci/src/capability/mod.rs deleted file mode 100644 index 1d8be9190..000000000 --- a/services/comps/pci/src/capability/mod.rs +++ /dev/null @@ -1,111 +0,0 @@ -//! This mod is used in frame to do device initialization -use crate::util::CSpaceAccessMethod; -use alloc::vec::Vec; -use jinux_frame::bus::pci::PciDeviceLocation; - -use self::{ - exp::CapabilityEXPData, msi::CapabilityMSIData, msix::CapabilityMSIXData, pm::CapabilityPMData, - sata::CapabilitySATAData, vendor::CapabilityVNDRData, -}; - -use super::PCI_CAP_PTR; - -pub mod exp; -pub mod msi; -pub mod msix; -pub mod pm; -pub mod sata; -pub mod vendor; - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub enum CapabilityData { - /// Id:0x01, Power Management - PM(CapabilityPMData), - /// Id:0x02, Accelerated Graphics Part - AGP, - /// Id:0x03, Vital Product Data - VPD, - /// Id:0x04, Slot Identification - SLOTID, - /// Id:0x05, Message Signalled Interrupts - MSI(CapabilityMSIData), - /// Id:0x06, CompactPCI HotSwap - CHSWP, - /// Id:0x07, PCI-X - PCIX, - /// Id:0x08, HyperTransport - HP, - /// Id:0x09, Vendor-Specific - VNDR(CapabilityVNDRData), - /// Id:0x0A, Debug port - DBG, - /// Id:0x0B, CompactPCI Central Resource Control - CCRC, - /// Id:0x0C, PCI Standard Hot-Plug Controller - SHPC, - /// Id:0x0D, Bridge subsystem vendor/device ID - SSVID, - /// Id:0x0R, AGP Target PCI-PCI bridge - AGP3, - /// Id:0x0F, Secure Device - SECDEV, - /// Id:0x10, PCI Express - EXP(CapabilityEXPData), - /// Id:0x11, MSI-X - MSIX(CapabilityMSIXData), - /// Id:0x12, SATA Data/Index Conf - SATA(CapabilitySATAData), - /// Id:0x13, PCI Advanced Features - AF, - /// Id:0x14, Enhanced Allocation - EA, - /// Id:?, Unknown - Unknown(u8), -} - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -pub struct Capability { - pub cap_ptr: u16, - pub data: CapabilityData, -} - -impl Capability { - /// get the capabilities of one device - pub fn device_capabilities(loc: PciDeviceLocation) -> Vec { - let mut capabilities = Vec::new(); - let am = CSpaceAccessMethod::IO; - let mut cap_ptr = am.read8(loc, PCI_CAP_PTR) as u16; - while cap_ptr > 0 { - let cap_vndr = am.read8(loc, cap_ptr); - let data = match cap_vndr { - 0x01 => CapabilityData::PM(CapabilityPMData::new(loc, cap_ptr)), - 0x02 => CapabilityData::AGP, - 0x03 => CapabilityData::VPD, - 0x04 => CapabilityData::SLOTID, - 0x05 => CapabilityData::MSI(CapabilityMSIData::new(loc, cap_ptr)), - 0x06 => CapabilityData::CHSWP, - 0x07 => CapabilityData::PCIX, - 0x08 => CapabilityData::HP, - 0x09 => CapabilityData::VNDR(CapabilityVNDRData::new(loc, cap_ptr)), - 0x0A => CapabilityData::DBG, - 0x0B => CapabilityData::CCRC, - 0x0C => CapabilityData::SHPC, - 0x0D => CapabilityData::SSVID, - 0x0E => CapabilityData::AGP3, - 0x0F => CapabilityData::SECDEV, - 0x10 => CapabilityData::EXP(CapabilityEXPData::new(loc, cap_ptr)), - 0x11 => CapabilityData::MSIX(CapabilityMSIXData::new(loc, cap_ptr)), - 0x12 => CapabilityData::SATA(CapabilitySATAData::new(loc, cap_ptr)), - 0x13 => CapabilityData::AF, - 0x14 => CapabilityData::EA, - _ => CapabilityData::Unknown(cap_vndr), - }; - capabilities.push(Self { - cap_ptr: cap_ptr, - data: data, - }); - cap_ptr = am.read8(loc, cap_ptr + 1) as u16; - } - capabilities - } -} diff --git a/services/comps/pci/src/capability/msi.rs b/services/comps/pci/src/capability/msi.rs deleted file mode 100644 index 68918be3b..000000000 --- a/services/comps/pci/src/capability/msi.rs +++ /dev/null @@ -1,52 +0,0 @@ -use crate::util::CSpaceAccessMethod; -use bitflags::bitflags; -use jinux_frame::bus::pci::PciDeviceLocation; -bitflags! { - pub struct CapabilityMSIMessageControl: u16 { - const ADDR64_CAPABLE = 1 << 7; - const MULTIPLE_MESSAGE_ENABLE_2 = 1 << 4; - const MULTIPLE_MESSAGE_ENABLE_4 = 2 << 4; - const MULTIPLE_MESSAGE_ENABLE_8 = 3 << 4; - const MULTIPLE_MESSAGE_ENABLE_16 = 4 << 4; - const MULTIPLE_MESSAGE_ENABLE_32 = 5 << 4; - const MULTIPLE_MESSAGE_CAPABLE_2 = 1 << 1; - const MULTIPLE_MESSAGE_CAPABLE_4 = 2 << 1; - const MULTIPLE_MESSAGE_CAPABLE_8 = 3 << 1; - const MULTIPLE_MESSAGE_CAPABLE_16 = 4 << 1; - const MULTIPLE_MESSAGE_CAPABLE_32 = 5 << 1; - const ENABLE = 1 << 0; - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct CapabilityMSIData { - message_control: CapabilityMSIMessageControl, - message_address: u64, - message_data: u16, -} - -impl CapabilityMSIData { - pub(crate) fn new(loc: PciDeviceLocation, cap_ptr: u16) -> Self { - let am = CSpaceAccessMethod::IO; - let message_control = - CapabilityMSIMessageControl::from_bits_truncate(am.read16(loc, cap_ptr + 0x02)); - let (addr, data) = if message_control.contains(CapabilityMSIMessageControl::ADDR64_CAPABLE) - { - // 64bit - let lo = am.read32(loc, cap_ptr + 0x04) as u64; - let hi = am.read32(loc, cap_ptr + 0x08) as u64; - let data = am.read16(loc, cap_ptr + 0x0C); - ((hi << 32) | lo, data) - } else { - // 32bit - let addr = am.read32(loc, cap_ptr + 0x04) as u64; - let data = am.read16(loc, cap_ptr + 0x0C); - (addr, data) - }; - Self { - message_control: message_control, - message_address: addr, - message_data: data, - } - } -} diff --git a/services/comps/pci/src/capability/msix.rs b/services/comps/pci/src/capability/msix.rs deleted file mode 100644 index b88733424..000000000 --- a/services/comps/pci/src/capability/msix.rs +++ /dev/null @@ -1,21 +0,0 @@ -use crate::util::CSpaceAccessMethod; -use jinux_frame::bus::pci::PciDeviceLocation; - -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -#[repr(C)] -pub struct CapabilityMSIXData { - pub message_control: u16, - pub table_info: u32, - pub pba_info: u32, -} - -impl CapabilityMSIXData { - pub fn new(loc: PciDeviceLocation, cap_ptr: u16) -> Self { - let am = CSpaceAccessMethod::IO; - Self { - message_control: am.read16(loc, cap_ptr + 2), - table_info: am.read32(loc, cap_ptr + 4), - pba_info: am.read32(loc, cap_ptr + 8), - } - } -} diff --git a/services/comps/pci/src/capability/pm.rs b/services/comps/pci/src/capability/pm.rs deleted file mode 100644 index 0c68b750b..000000000 --- a/services/comps/pci/src/capability/pm.rs +++ /dev/null @@ -1,29 +0,0 @@ -use crate::util::CSpaceAccessMethod; -use jinux_frame::bus::pci::PciDeviceLocation; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct CapabilityPMData { - pub pme_support: u32, - pub d2_support: u32, - pub d1_support: u32, - pub aux_current: u32, - pub dsi: u32, - pub pme_clock: u32, - pub version: u32, -} - -impl CapabilityPMData { - pub(crate) fn new(loc: PciDeviceLocation, cap_ptr: u16) -> Self { - let am = CSpaceAccessMethod::IO; - let cap = am.read32(loc, cap_ptr + 0x4); - Self { - pme_support: cap >> 27, - d2_support: (cap >> 26) & 0x1, - d1_support: (cap >> 25) & 0x1, - aux_current: (cap >> 22) & 0x7, - dsi: (cap >> 21) & 0x1, - pme_clock: (cap >> 19) & 0x1, - version: (cap >> 16) & 0x7, - } - } -} diff --git a/services/comps/pci/src/capability/sata.rs b/services/comps/pci/src/capability/sata.rs deleted file mode 100644 index c4a62ccb2..000000000 --- a/services/comps/pci/src/capability/sata.rs +++ /dev/null @@ -1,24 +0,0 @@ -use crate::util::CSpaceAccessMethod; -use jinux_frame::bus::pci::PciDeviceLocation; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct CapabilitySATAData { - major_revision: u32, - minor_revision: u32, - bar_offset: u32, - bar_location: u32, -} - -impl CapabilitySATAData { - pub(crate) fn new(loc: PciDeviceLocation, cap_ptr: u16) -> Self { - let am = CSpaceAccessMethod::IO; - let sata_cr0 = am.read32(loc, cap_ptr); - let sata_cr1 = am.read32(loc, cap_ptr + 0x4); - Self { - major_revision: (sata_cr0 >> 20) & 0xf, - minor_revision: (sata_cr0 >> 16) & 0xf, - bar_offset: (sata_cr1 >> 4) & 0xfffff, - bar_location: sata_cr1 & 0xf, - } - } -} diff --git a/services/comps/pci/src/capability/vendor/mod.rs b/services/comps/pci/src/capability/vendor/mod.rs deleted file mode 100644 index 53930ddfd..000000000 --- a/services/comps/pci/src/capability/vendor/mod.rs +++ /dev/null @@ -1,28 +0,0 @@ -pub mod virtio; - -use virtio::CapabilityVirtioData; - -use crate::util::CSpaceAccessMethod; -use jinux_frame::bus::pci::PciDeviceLocation; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum CapabilityVNDRData { - /// Virtio - VIRTIO(CapabilityVirtioData), -} - -impl CapabilityVNDRData { - pub(crate) fn new(loc: PciDeviceLocation, cap_ptr: u16) -> Self { - let am = CSpaceAccessMethod::IO; - let vid = am.read16(loc, 0); - match vid { - 0x1af4 => Self::VIRTIO(CapabilityVirtioData::new(loc, cap_ptr)), - _ => { - panic!( - "unsupport vendor-specific capability, deivce vendor id:{}", - vid - ) - } - } - } -} diff --git a/services/comps/pci/src/capability/vendor/virtio.rs b/services/comps/pci/src/capability/vendor/virtio.rs deleted file mode 100644 index b85e3ca38..000000000 --- a/services/comps/pci/src/capability/vendor/virtio.rs +++ /dev/null @@ -1,30 +0,0 @@ -use crate::util::CSpaceAccessMethod; -use jinux_frame::bus::pci::PciDeviceLocation; - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct CapabilityVirtioData { - pub cfg_type: u8, - pub bar: u8, - pub offset: u32, - pub length: u32, - pub option: Option, -} - -impl CapabilityVirtioData { - pub(crate) fn new(loc: PciDeviceLocation, cap_ptr: u16) -> Self { - let am = CSpaceAccessMethod::IO; - let cap_len = am.read8(loc, cap_ptr + 2); - let option = if cap_len > 0x10 { - Some(am.read32(loc, cap_ptr + 16)) - } else { - None - }; - Self { - cfg_type: am.read8(loc, cap_ptr + 3), - bar: am.read8(loc, cap_ptr + 4), - offset: am.read32(loc, cap_ptr + 8), - length: am.read32(loc, cap_ptr + 12), - option: option, - } - } -} diff --git a/services/comps/pci/src/lib.rs b/services/comps/pci/src/lib.rs deleted file mode 100644 index ce3a60738..000000000 --- a/services/comps/pci/src/lib.rs +++ /dev/null @@ -1,90 +0,0 @@ -//! The pci of jinux -#![no_std] -#![forbid(unsafe_code)] -#![allow(dead_code)] -pub mod capability; -pub mod msix; -pub mod util; -extern crate alloc; - -use component::init_component; -use component::ComponentInitError; - -use alloc::{sync::Arc, vec::Vec}; -use jinux_frame::bus::pci::PciDeviceLocation; -use jinux_frame::sync::Mutex; -use spin::Once; -use util::CSpaceAccessMethod; - -pub use crate::util::PciDevice; - -pub const PCI_COMMAND: u16 = 0x04; -pub const PCI_BAR: u16 = 0x10; -pub const PCI_CAP_PTR: u16 = 0x34; -pub const PCI_INTERRUPT_LINE: u16 = 0x3c; -pub const PCI_INTERRUPT_PIN: u16 = 0x3d; - -pub const PCI_MSIX_CTRL_CAP: u16 = 0x00; -pub const PCI_MSIX_TABLE: u16 = 0x04; -pub const PCI_MSIX_PBA: u16 = 0x08; - -pub const PCI_CAP_ID_MSI: u8 = 0x05; - -pub static PCI_COMPONENT: Once = Once::new(); - -#[init_component] -fn pci_component_init() -> Result<(), ComponentInitError> { - let a = PCIComponent::init()?; - PCI_COMPONENT.call_once(|| a); - Ok(()) -} -pub struct PCIComponent { - pci_device: Mutex>>, -} - -impl PCIComponent { - pub fn init() -> Result { - let mut devices = Vec::new(); - for location in PciDeviceLocation::all() { - let Some(device) = util::find_device(location, CSpaceAccessMethod::IO) else { - continue; - }; - log::info!( - "pci: {:02x}:{:02x}.{} {:#x} {:#x} ({} {}) command: {:?} status: {:?} irq: {}:{:?}", - device.loc.bus, - device.loc.device, - device.loc.function, - device.id.vendor_id, - device.id.device_id, - device.id.class, - device.id.subclass, - device.command, - device.status, - device.pic_interrupt_line, - device.interrupt_pin - ); - devices.push(Arc::new(device)); - } - Ok(Self { - pci_device: Mutex::new(devices), - }) - } - - pub const fn name() -> &'static str { - "PCI" - } - // 0~65535 - pub const fn priority() -> u16 { - 0 - } -} - -impl PCIComponent { - pub fn get_pci_devices(self: &Self, index: usize) -> Option> { - self.pci_device.lock().get(index).cloned() - } - - pub fn device_amount(self: &Self) -> usize { - self.pci_device.lock().len() - } -} diff --git a/services/comps/pci/src/msix.rs b/services/comps/pci/src/msix.rs deleted file mode 100644 index fea9848b0..000000000 --- a/services/comps/pci/src/msix.rs +++ /dev/null @@ -1,121 +0,0 @@ -use core::mem::size_of; - -use alloc::vec::Vec; -use log::debug; -use pod::Pod; - -use crate::util::{CSpaceAccessMethod, BAR}; - -use super::capability::msix::CapabilityMSIXData; - -use jinux_frame::{bus::pci::PciDeviceLocation, io_mem::IoMem, offset_of, trap::IrqAllocateHandle}; -use jinux_util::{field_ptr, safe_ptr::SafePtr}; - -#[derive(Debug, Default)] -pub struct MSIX { - pub table_size: u16, - pub table: Vec, - /// pointing to the Pending Table - pub pba_paddr: u64, -} - -#[derive(Debug)] -pub struct MSIXEntry { - pub table_entry: SafePtr, - pub irq_handle: IrqAllocateHandle, -} - -#[derive(Debug, Default, Copy, Clone, PartialEq, Eq, Pod)] -#[repr(C)] -pub struct MSIXTableEntry { - pub msg_addr: u32, - pub msg_upper_addr: u32, - pub msg_data: u32, - pub vector_control: u32, -} - -impl MSIX { - /// create a MSIX instance, it allocate the irq number automatically. - pub fn new( - cap: &CapabilityMSIXData, - bars: [Option; 6], - loc: PciDeviceLocation, - cap_ptr: u16, - ) -> Self { - let table_info = cap.table_info; - let pba_info = cap.pba_info; - let table_size = (table_info & (0b11_1111_1111)) + 1; - let table_bar_address; - let pba_bar_address; - match bars[(pba_info & 0b111) as usize].expect("MSIX cfg:table bar is none") { - BAR::Memory(address, _, _, _) => { - pba_bar_address = address; - } - BAR::IO(_, _) => { - panic!("MSIX cfg:table bar is IO type") - } - } - match bars[(table_info & 0b111) as usize].expect("MSIX cfg:table bar is none") { - BAR::Memory(address, _, _, _) => { - table_bar_address = address; - } - BAR::IO(_, _) => { - panic!("MSIX cfg:table bar is IO type") - } - } - // let pba_base_address = (pba_info >> 3 ) as u64 + pba_bar_address; - // let table_base_address = (table_info >>3 ) as u64 + table_bar_address; - let pba_base_address = (pba_info & (!(0b111 as u32))) as u64 + pba_bar_address; - let table_base_address = (table_info & (!(0b111 as u32))) as u64 + table_bar_address; - debug!("MSIX table size:{}, pba_info:{:x}, table_info:{:x}, pba_address:{:x}, table_address:{:x}", - table_size,pba_info,table_info,pba_base_address,table_base_address); - let mut cap = Self { - table_size: table_size as u16, - table: Vec::new(), - pba_paddr: pba_base_address, - }; - // enable MSI-X disable INTx - let am = CSpaceAccessMethod::IO; - debug!("command before:{:x}", am.read16(loc, crate::PCI_COMMAND)); - am.write16( - loc, - crate::PCI_COMMAND, - am.read16(loc, crate::PCI_COMMAND) | 0x40f, - ); - debug!("command after:{:x}", am.read16(loc, crate::PCI_COMMAND)); - let message_control = am.read16(loc, cap_ptr + 2) | 0x8000; - am.write16(loc, cap_ptr + 2, message_control); - let mut table_iter: SafePtr = SafePtr::new( - IoMem::new( - table_base_address as usize - ..table_base_address as usize - + (size_of::() * table_size as usize), - ) - .unwrap(), - 0, - ); - for _ in 0..table_size { - // local APIC address: 0xFEE0_0000 - field_ptr!(&table_iter, MSIXTableEntry, msg_addr) - .write(&0xFEE0_0000u32) - .unwrap(); - field_ptr!(&table_iter, MSIXTableEntry, msg_upper_addr) - .write(&0u32) - .unwrap(); - // allocate irq number - let handle = jinux_frame::trap::allocate_irq().expect("not enough irq"); - field_ptr!(&table_iter, MSIXTableEntry, msg_data) - .write(&(handle.num() as u32)) - .unwrap(); - field_ptr!(&table_iter, MSIXTableEntry, vector_control) - .write(&0u32) - .unwrap(); - cap.table.push(MSIXEntry { - table_entry: table_iter.clone(), - irq_handle: handle, - }); - table_iter.add(1); - } - cap - } -} diff --git a/services/comps/pci/src/util.rs b/services/comps/pci/src/util.rs deleted file mode 100644 index 4fdef4e23..000000000 --- a/services/comps/pci/src/util.rs +++ /dev/null @@ -1,498 +0,0 @@ -extern crate jinux_frame; -use crate::capability::Capability; -use alloc::vec::Vec; -use bitflags::bitflags; -use jinux_frame::bus::pci::PciDeviceLocation; - -pub enum PCIDeviceCommonCfgOffset { - VendorId = 0x00, - DeviceId = 0x02, - Command = 0x04, - Status = 0x06, - RevisionId = 0x08, - ClassCode = 0x09, - CacheLineSize = 0x0C, - LatencyTimer = 0x0D, - HeaderType = 0x0E, - BIST = 0x0F, - BAR0 = 0x10, - BAR1 = 0x14, - BAR2 = 0x18, - BAR3 = 0x1C, - BAR4 = 0x20, - BAR5 = 0x24, - CardbusCisPtr = 0x28, - SubsystemVendorId = 0x2C, - SubsystemId = 0x2E, - XROMBAR = 0x30, - CapabilitiesPointer = 0x34, - InterruptLine = 0x3C, - InterruptPin = 0x3D, - MinGrant = 0x3E, - MaxLatency = 0x3F, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum CSpaceAccessMethod { - // The legacy, deprecated (as of PCI 2.0) IO-range method. - // Until/unless there is a relevant platform that requires this, leave it out. - // IO_Mechanism_2 - /// The legacy (pre-PCIe) 2-IO port method as specified on page 50 of PCI Local Bus - /// Specification 3.0. - IO, - // PCIe memory-mapped configuration space access - //MemoryMapped(*mut u8), -} - -// All IO-bus ops are 32-bit, we mask and shift to get the values we want. - -impl CSpaceAccessMethod { - pub fn read8(self, loc: PciDeviceLocation, offset: u16) -> u8 { - let val = self.read32(loc, offset & 0b11111100); - ((val >> ((offset as usize & 0b11) << 3)) & 0xFF) as u8 - } - - /// Returns a value in native endian. - pub fn read16(self, loc: PciDeviceLocation, offset: u16) -> u16 { - let val = self.read32(loc, offset & 0b11111100); - ((val >> ((offset as usize & 0b10) << 3)) & 0xFFFF) as u16 - } - - /// Returns a value in native endian. - pub fn read32(self, loc: PciDeviceLocation, offset: u16) -> u32 { - debug_assert!( - (offset & 0b11) == 0, - "misaligned PCI configuration dword u32 read" - ); - match self { - CSpaceAccessMethod::IO => { - jinux_frame::arch::x86::device::pci::PCI_ADDRESS_PORT - .write(loc.encode_as_x86_address_value() | ((offset as u32) & 0b11111100)); - jinux_frame::arch::x86::device::pci::PCI_DATA_PORT - .read() - .to_le() - } //MemoryMapped(ptr) => { - // // FIXME: Clarify whether the rules for GEP/GEPi forbid using regular .offset() here. - // ::core::intrinsics::volatile_load(::core::intrinsics::arith_offset(ptr, offset as usize)) - //} - } - } - - pub fn write8(self, loc: PciDeviceLocation, offset: u16, val: u8) { - let old = self.read32(loc, offset & (0xFFFC)); - let dest = offset as usize & 0b11 << 3; - let mask = (0xFF << dest) as u32; - self.write32( - loc, - offset & (0xFFFC), - ((val as u32) << dest | (old & !mask)).to_le(), - ); - } - - /// Converts val to little endian before writing. - pub fn write16(self, loc: PciDeviceLocation, offset: u16, val: u16) { - let old = self.read32(loc, offset & (0xFFFC)); - let dest = offset as usize & 0b10 << 3; - let mask = (0xFFFF << dest) as u32; - self.write32( - loc, - offset & (0xFFFC), - ((val as u32) << dest | (old & !mask)).to_le(), - ); - } - - /// Takes a value in native endian, converts it to little-endian, and writes it to the PCI - /// device configuration space at register `offset`. - pub fn write32(self, loc: PciDeviceLocation, offset: u16, val: u32) { - debug_assert!( - (offset & 0b11) == 0, - "misaligned PCI configuration dword u32 read" - ); - match self { - CSpaceAccessMethod::IO => { - jinux_frame::arch::x86::device::pci::PCI_ADDRESS_PORT - .write(loc.encode_as_x86_address_value() | (offset as u32 & 0b11111100)); - jinux_frame::arch::x86::device::pci::PCI_DATA_PORT.write(val.to_le()) - } //MemoryMapped(ptr) => { - // // FIXME: Clarify whether the rules for GEP/GEPi forbid using regular .offset() here. - // ::core::intrinsics::volatile_load(::core::intrinsics::arith_offset(ptr, offset as usize)) - //} - } - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct Identifier { - pub vendor_id: u16, - pub device_id: u16, - pub revision_id: u8, - pub prog_if: u8, - pub class: u8, - pub subclass: u8, -} - -bitflags! { - pub struct Command: u16 { - const IO_SPACE = 1 << 0; - const MEMORY_SPACE = 1 << 1; - const BUS_MASTER = 1 << 2; - const SPECIAL_CYCLES = 1 << 3; - const MWI_ENABLE = 1 << 4; - const VGA_PALETTE_SNOOP = 1 << 5; - const PARITY_ERROR_RESPONSE = 1 << 6; - const STEPPING_CONTROL = 1 << 7; - const SERR_ENABLE = 1 << 8; - const FAST_BACK_TO_BACK_ENABLE = 1 << 9; - const INTERRUPT_DISABLE = 1 << 10; - const RESERVED_11 = 1 << 11; - const RESERVED_12 = 1 << 12; - const RESERVED_13 = 1 << 13; - const RESERVED_14 = 1 << 14; - const RESERVED_15 = 1 << 15; - } -} - -bitflags! { - pub struct Status: u16 { - const RESERVED_0 = 1 << 0; - const RESERVED_1 = 1 << 1; - const RESERVED_2 = 1 << 2; - const INTERRUPT_STATUS = 1 << 3; - const CAPABILITIES_LIST = 1 << 4; - const MHZ66_CAPABLE = 1 << 5; - const RESERVED_6 = 1 << 6; - const FAST_BACK_TO_BACK_CAPABLE = 1 << 7; - const MASTER_DATA_PARITY_ERROR = 1 << 8; - const DEVSEL_MEDIUM_TIMING = 1 << 9; - const DEVSEL_SLOW_TIMING = 1 << 10; - const SIGNALED_TARGET_ABORT = 1 << 11; - const RECEIVED_TARGET_ABORT = 1 << 12; - const RECEIVED_MASTER_ABORT = 1 << 13; - const SIGNALED_SYSTEM_ERROR = 1 << 14; - const DETECTED_PARITY_ERROR = 1 << 15; - } -} - -bitflags! { - pub struct BridgeControl: u16 { - const PARITY_ERROR_RESPONSE_ENABLE = 1 << 0; - const SERR_ENABLE = 1 << 1; - const ISA_ENABLE = 1 << 2; - const VGA_ENABLE = 1 << 3; - const RESERVED_4 = 1 << 4; - const MASTER_ABORT_MODE = 1 << 5; - const SECONDARY_BUS_RESET = 1 << 6; - const FAST_BACK_TO_BACK_ENABLE = 1 << 7; - const PRIMARY_DISCARD_TIMER = 1 << 8; - const SECONDARY_DISCARD_TIMER = 1 << 9; - const DISCARD_TIMER_STATUS = 1 << 10; - const DISCARD_TIMER_SERR_ENABLED = 1 << 11; - const RESERVED_12 = 1 << 12; - const RESERVED_13 = 1 << 13; - const RESERVED_14 = 1 << 14; - const RESERVED_15 = 1 << 15; - } -} - -/// A device on the PCI bus. -/// -/// Although accessing configuration space may be expensive, it is not cached. -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct PciDevice { - pub loc: PciDeviceLocation, - pub id: Identifier, - pub command: Command, - pub status: Status, - pub cache_line_size: u8, - pub latency_timer: u8, - pub multifunction: bool, - pub bist_capable: bool, - pub bars: [Option; 6], - pub kind: DeviceKind, - pub pic_interrupt_line: u8, - pub interrupt_pin: Option, - pub cspace_access_method: CSpaceAccessMethod, - pub capabilities: Vec, -} - -impl PciDevice { - /// set the status bits - pub fn set_status_bits(&self, status: Status) { - let am = CSpaceAccessMethod::IO; - let status = am.read16(self.loc, 0x06) | status.bits; - am.write16(self.loc, 0x06, status) - } -} - -pub enum PCIScanError {} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum Prefetchable { - Yes, - No, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum Type { - Bits32, - Bits64, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum DeviceKind { - Device(DeviceDetails), - PciBridge(PciBridgeDetails), - CardbusBridge(CardbusBridgeDetails), - Unknown, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct DeviceDetails { - pub cardbus_cis_ptr: u32, - pub subsystem_vendor_id: u16, - pub subsystem_id: u16, - pub expansion_rom_base_addr: u32, - pub min_grant: u8, - pub max_latency: u8, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct PciBridgeDetails { - pub primary_bus: u8, - pub secondary_bus: u8, - pub subordinate_bus: u8, - pub secondary_latency_timer: u8, - pub io_base: u32, - pub io_limit: u32, - pub secondary_status: Status, - pub mem_base: u32, - pub mem_limit: u32, - pub prefetchable_mem_base: u64, - pub prefetchable_mem_limit: u64, - pub expansion_rom_base_addr: u32, - pub bridge_control: BridgeControl, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub struct CardbusBridgeDetails { - pub socket_base_addr: u32, - pub secondary_status: Status, - pub pci_bus: u8, - pub cardbus_bus: u8, - pub subordinate_bus: u8, - pub cardbus_latency_timer: u8, - pub mem_base_0: u32, - pub mem_limit_0: u32, - pub mem_base_1: u32, - pub mem_limit_1: u32, - pub io_base_0: u32, - pub io_limit_0: u32, - pub io_base_1: u32, - pub io_limit_1: u32, - pub subsystem_device_id: u16, - pub subsystem_vendor_id: u16, - pub legacy_mode_base_addr: u32, - pub bridge_control: BridgeControl, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum InterruptPin { - INTA = 1, - INTB, - INTC, - INTD, -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq)] -pub enum BAR { - Memory(u64, u32, Prefetchable, Type), - /// first element is address, second element is size - IO(u32, u32), -} - -impl BAR { - pub fn decode( - loc: PciDeviceLocation, - am: CSpaceAccessMethod, - idx: u16, - ) -> (Option, usize) { - let raw = am.read32(loc, 16 + (idx << 2)); - am.write32(loc, 16 + (idx << 2), !0); - let len_encoded = am.read32(loc, 16 + (idx << 2)); - am.write32(loc, 16 + (idx << 2), raw); - if raw == 0 && len_encoded == 0 { - return (None, idx as usize + 1); - } - if raw & 1 == 0 { - let mut bits64 = false; - let base: u64 = match (raw & 0b110) >> 1 { - 0 => (raw & !0xF) as u64, - 2 => { - bits64 = true; - ((raw & !0xF) as u64) | ((am.read32(loc, 16 + ((idx + 1) << 2)) as u64) << 32) - } - _ => { - debug_assert!(false, "bad type in memory BAR"); - return (None, idx as usize + 1); - } - }; - let len = !(len_encoded & !0xF).wrapping_add(1); - ( - Some(BAR::Memory( - base, - len, - if raw & 0b1000 == 0 { - Prefetchable::No - } else { - Prefetchable::Yes - }, - if bits64 { Type::Bits64 } else { Type::Bits32 }, - )), - if bits64 { idx + 2 } else { idx + 1 } as usize, - ) - } else { - let len = !(len_encoded & !0x3) + 1; - (Some(BAR::IO(raw & !0x3, len)), idx as usize + 1) - } - } -} - -pub(crate) fn find_device(loc: PciDeviceLocation, am: CSpaceAccessMethod) -> Option { - // FIXME: it'd be more efficient to use read32 and decode separately. - let vid = am.read16(loc, 0); - if vid == 0xFFFF { - return None; - } - let did = am.read16(loc, 2); - let command = Command::from_bits_truncate(am.read16(loc, 4)); - let status = Status::from_bits_truncate(am.read16(loc, 6)); - let rid = am.read8(loc, 8); - let prog_if = am.read8(loc, 9); - let subclass = am.read8(loc, 10); - let class = am.read8(loc, 11); - let id = Identifier { - vendor_id: vid, - device_id: did, - revision_id: rid, - prog_if: prog_if, - class: class, - subclass: subclass, - }; - let cache_line_size = am.read8(loc, 12); - let latency_timer = am.read8(loc, 13); - let bist_capable = am.read8(loc, 15) & (1 << 7) != 0; - let hdrty_mf = am.read8(loc, 14); - let hdrty = hdrty_mf & !(1 << 7); - let mf = hdrty_mf & (1 << 7) != 0; - let pic_interrupt_line = am.read8(loc, 0x3C); - let interrupt_pin = match am.read8(loc, 0x3D) { - 1 => Some(InterruptPin::INTA), - 2 => Some(InterruptPin::INTB), - 3 => Some(InterruptPin::INTC), - 4 => Some(InterruptPin::INTD), - _ => None, - }; - let kind; - let max; - - match hdrty { - 0 => { - max = 6; - kind = DeviceKind::Device(DeviceDetails { - cardbus_cis_ptr: am.read32(loc, 0x28), - subsystem_vendor_id: am.read16(loc, 0x2C), - subsystem_id: am.read16(loc, 0x2E), - expansion_rom_base_addr: am.read32(loc, 0x30), - min_grant: am.read8(loc, 0x3E), - max_latency: am.read8(loc, 0x3F), - }); - } - 1 => { - max = 2; - kind = DeviceKind::PciBridge(PciBridgeDetails { - primary_bus: am.read8(loc, 0x18), - secondary_bus: am.read8(loc, 0x19), - subordinate_bus: am.read8(loc, 0x1a), - secondary_latency_timer: am.read8(loc, 0x1b), - secondary_status: Status::from_bits_truncate(am.read16(loc, 0x1e)), - io_base: (am.read8(loc, 0x1c) as u32 & 0xF0) << 8 - | (am.read16(loc, 0x30) as u32) << 16, - io_limit: 0xFFF - | (am.read8(loc, 0x1d) as u32 & 0xF0) << 8 - | (am.read16(loc, 0x32) as u32) << 16, - mem_base: (am.read16(loc, 0x20) as u32 & 0xFFF0) << 16, - mem_limit: 0xFFFFF | (am.read16(loc, 0x22) as u32 & 0xFFF0) << 16, - prefetchable_mem_base: (am.read16(loc, 0x24) as u64 & 0xFFF0) << 16 - | am.read32(loc, 0x28) as u64, - prefetchable_mem_limit: 0xFFFFF - | (am.read16(loc, 0x26) as u64 & 0xFFF0) << 16 - | am.read32(loc, 0x2c) as u64, - expansion_rom_base_addr: am.read32(loc, 0x38), - bridge_control: BridgeControl::from_bits_truncate(am.read16(loc, 0x3e)), - }); - } - 2 => { - max = 0; - kind = DeviceKind::CardbusBridge(CardbusBridgeDetails { - socket_base_addr: am.read32(loc, 0x10), - secondary_status: Status::from_bits_truncate(am.read16(loc, 0x16)), - pci_bus: am.read8(loc, 0x18), - cardbus_bus: am.read8(loc, 0x19), - subordinate_bus: am.read8(loc, 0x1a), - cardbus_latency_timer: am.read8(loc, 0x1b), - mem_base_0: am.read32(loc, 0x1c), - mem_limit_0: am.read32(loc, 0x20), - mem_base_1: am.read32(loc, 0x24), - mem_limit_1: am.read32(loc, 0x28), - io_base_0: am.read32(loc, 0x2c), - io_limit_0: am.read32(loc, 0x30), - io_base_1: am.read32(loc, 0x34), - io_limit_1: am.read32(loc, 0x38), - bridge_control: BridgeControl::from_bits_truncate(am.read16(loc, 0x3e)), - subsystem_device_id: am.read16(loc, 0x40), - subsystem_vendor_id: am.read16(loc, 0x42), - legacy_mode_base_addr: am.read32(loc, 0x44), - }); - } - _ => { - max = 0; - kind = DeviceKind::Unknown; - debug_assert!( - false, - "pci: unknown device header type {} for {:?} {:?}", - hdrty, loc, id - ); - } - }; - - let capabilities = if status.contains(Status::CAPABILITIES_LIST) { - Capability::device_capabilities(loc) - } else { - Vec::new() - }; - - let mut bars = [None, None, None, None, None, None]; - let mut i = 0; - while i < max { - let (bar, next) = BAR::decode(loc, am, i as u16); - bars[i] = bar; - i = next; - } - - Some(PciDevice { - loc: loc, - id: id, - command: command, - status: status, - cache_line_size: cache_line_size, - latency_timer: latency_timer, - multifunction: mf, - bist_capable: bist_capable, - bars: bars, - kind: kind, - pic_interrupt_line: pic_interrupt_line, - interrupt_pin: interrupt_pin, - cspace_access_method: am, - capabilities: capabilities, - }) -} diff --git a/services/comps/virtio/Cargo.toml b/services/comps/virtio/Cargo.toml index 251ad0a5a..4d01839b5 100644 --- a/services/comps/virtio/Cargo.toml +++ b/services/comps/virtio/Cargo.toml @@ -11,7 +11,6 @@ spin = "0.9.4" bytes = { version = "1.4.0", default-features = false } align_ext = { path = "../../../framework/libs/align_ext" } jinux-frame = { path = "../../../framework/jinux-frame" } -jinux-pci = { path = "../pci" } jinux-util = { path = "../../libs/jinux-util" } jinux-rights = { path = "../../libs/jinux-rights" } typeflags-util = { path = "../../libs/typeflags-util" }