devices/pci/
mod.rs

1// Copyright 2018 The ChromiumOS Authors
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Implements pci devices and busses.
6
7mod acpi;
8#[cfg(any(target_os = "android", target_os = "linux"))]
9mod coiommu;
10mod msi;
11mod msix;
12mod pci_configuration;
13mod pci_device;
14#[cfg(feature = "pci-hotplug")]
15mod pci_hotplug;
16mod pci_root;
17#[cfg(any(target_os = "android", target_os = "linux"))]
18mod pcie;
19pub mod pm;
20mod pvpanic;
21mod stub;
22#[cfg(any(target_os = "android", target_os = "linux"))]
23mod vfio_pci;
24
25use libc::EINVAL;
26pub use resources::PciAddress;
27pub use resources::PciAddressError;
28use serde::Deserialize;
29use serde::Serialize;
30
31pub use self::acpi::GpeScope;
32#[cfg(any(target_os = "android", target_os = "linux"))]
33pub use self::coiommu::CoIommuDev;
34#[cfg(any(target_os = "android", target_os = "linux"))]
35pub use self::coiommu::CoIommuParameters;
36#[cfg(any(target_os = "android", target_os = "linux"))]
37pub use self::coiommu::CoIommuUnpinPolicy;
38pub use self::msi::MsiConfig;
39pub use self::msix::MsixCap;
40pub use self::msix::MsixConfig;
41pub use self::msix::MsixStatus;
42pub use self::pci_configuration::PciBarConfiguration;
43pub use self::pci_configuration::PciBarIndex;
44pub use self::pci_configuration::PciBarPrefetchable;
45pub use self::pci_configuration::PciBarRegionType;
46pub use self::pci_configuration::PciBaseSystemPeripheralSubclass;
47pub use self::pci_configuration::PciCapability;
48pub use self::pci_configuration::PciCapabilityID;
49pub use self::pci_configuration::PciClassCode;
50pub use self::pci_configuration::PciConfiguration;
51pub use self::pci_configuration::PciDisplaySubclass;
52pub use self::pci_configuration::PciHeaderType;
53pub use self::pci_configuration::PciInputDeviceSubclass;
54pub use self::pci_configuration::PciMassStorageSubclass;
55pub use self::pci_configuration::PciMultimediaSubclass;
56pub use self::pci_configuration::PciNetworkControllerSubclass;
57pub use self::pci_configuration::PciProgrammingInterface;
58pub use self::pci_configuration::PciSerialBusSubClass;
59pub use self::pci_configuration::PciSimpleCommunicationControllerSubclass;
60pub use self::pci_configuration::PciSubclass;
61pub use self::pci_configuration::PciWirelessControllerSubclass;
62pub use self::pci_device::BarRange;
63pub use self::pci_device::Error as PciDeviceError;
64pub use self::pci_device::PciBus;
65pub use self::pci_device::PciDevice;
66pub use self::pci_device::PreferredIrq;
67#[cfg(feature = "pci-hotplug")]
68pub use self::pci_hotplug::HotPluggable;
69#[cfg(feature = "pci-hotplug")]
70pub use self::pci_hotplug::IntxParameter;
71#[cfg(feature = "pci-hotplug")]
72pub use self::pci_hotplug::NetResourceCarrier;
73#[cfg(feature = "pci-hotplug")]
74pub use self::pci_hotplug::ResourceCarrier;
75pub use self::pci_root::PciConfigIo;
76pub use self::pci_root::PciConfigMmio;
77pub use self::pci_root::PciMmioMapper;
78pub use self::pci_root::PciRoot;
79pub use self::pci_root::PciRootCommand;
80pub use self::pci_root::PciVirtualConfigMmio;
81#[cfg(any(target_os = "android", target_os = "linux"))]
82pub use self::pcie::PciBridge;
83#[cfg(any(target_os = "android", target_os = "linux"))]
84pub use self::pcie::PcieDownstreamPort;
85#[cfg(any(target_os = "android", target_os = "linux"))]
86pub use self::pcie::PcieHostPort;
87#[cfg(any(target_os = "android", target_os = "linux"))]
88pub use self::pcie::PcieRootPort;
89#[cfg(any(target_os = "android", target_os = "linux"))]
90pub use self::pcie::PcieUpstreamPort;
91pub use self::pvpanic::PvPanicCode;
92pub use self::pvpanic::PvPanicPciDevice;
93pub use self::stub::StubPciDevice;
94pub use self::stub::StubPciParameters;
95#[cfg(any(target_os = "android", target_os = "linux"))]
96pub use self::vfio_pci::VfioPciDevice;
97
98/// PCI has four interrupt pins A->D.
99#[derive(Copy, Clone, Ord, PartialOrd, PartialEq, Eq, Serialize, Deserialize)]
100pub enum PciInterruptPin {
101    IntA,
102    IntB,
103    IntC,
104    IntD,
105}
106
107impl PciInterruptPin {
108    pub fn to_mask(self) -> u32 {
109        self as u32
110    }
111}
112
113// VCFG
114pub const PCI_VCFG_PM: usize = 0x0;
115pub const PCI_VCFG_DSM: usize = 0x1;
116pub const PCI_VCFG_NOTY: usize = 0x2;
117
118pub const PCI_VENDOR_ID_INTEL: u16 = 0x8086;
119pub const PCI_VENDOR_ID_REDHAT: u16 = 0x1b36;
120
121#[repr(u16)]
122#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
123pub enum CrosvmDeviceId {
124    Pit = 1,
125    Pic = 2,
126    Ioapic = 3,
127    Serial = 4,
128    Cmos = 5,
129    I8042 = 6,
130    Pl030 = 7,
131    ACPIPMResource = 8,
132    GoldfishBattery = 9,
133    DebugConsole = 10,
134    ProxyDevice = 11,
135    VfioPlatformDevice = 12,
136    DirectGsi = 13,
137    DirectIo = 14,
138    DirectMmio = 15,
139    UserspaceIrqChip = 16,
140    VmWatchdog = 17,
141    Pflash = 18,
142    VirtioMmio = 19,
143    AcAdapter = 20,
144    VirtualPmc = 21,
145    VirtCpufreq = 22,
146    FwCfg = 23,
147}
148
149impl TryFrom<u16> for CrosvmDeviceId {
150    type Error = base::Error;
151
152    fn try_from(value: u16) -> Result<Self, Self::Error> {
153        match value {
154            1 => Ok(CrosvmDeviceId::Pit),
155            2 => Ok(CrosvmDeviceId::Pic),
156            3 => Ok(CrosvmDeviceId::Ioapic),
157            4 => Ok(CrosvmDeviceId::Serial),
158            5 => Ok(CrosvmDeviceId::Cmos),
159            6 => Ok(CrosvmDeviceId::I8042),
160            7 => Ok(CrosvmDeviceId::Pl030),
161            8 => Ok(CrosvmDeviceId::ACPIPMResource),
162            9 => Ok(CrosvmDeviceId::GoldfishBattery),
163            10 => Ok(CrosvmDeviceId::DebugConsole),
164            11 => Ok(CrosvmDeviceId::ProxyDevice),
165            12 => Ok(CrosvmDeviceId::VfioPlatformDevice),
166            13 => Ok(CrosvmDeviceId::DirectGsi),
167            14 => Ok(CrosvmDeviceId::DirectMmio),
168            15 => Ok(CrosvmDeviceId::DirectIo),
169            16 => Ok(CrosvmDeviceId::UserspaceIrqChip),
170            17 => Ok(CrosvmDeviceId::VmWatchdog),
171            18 => Ok(CrosvmDeviceId::Pflash),
172            19 => Ok(CrosvmDeviceId::VirtioMmio),
173            20 => Ok(CrosvmDeviceId::AcAdapter),
174            21 => Ok(CrosvmDeviceId::VirtualPmc),
175            22 => Ok(CrosvmDeviceId::VirtCpufreq),
176            23 => Ok(CrosvmDeviceId::FwCfg),
177            _ => Err(base::Error::new(EINVAL)),
178        }
179    }
180}
181
182/// A wrapper structure for pci device and vendor id.
183#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
184pub struct PciId {
185    vendor_id: u16,
186    device_id: u16,
187}
188
189impl PciId {
190    pub fn new(vendor_id: u16, device_id: u16) -> Self {
191        Self {
192            vendor_id,
193            device_id,
194        }
195    }
196}
197
198impl From<PciId> for u32 {
199    fn from(pci_id: PciId) -> Self {
200        // vendor ID is the lower 16 bits and device id is the upper 16 bits
201        pci_id.vendor_id as u32 | (pci_id.device_id as u32) << 16
202    }
203}
204
205impl From<u32> for PciId {
206    fn from(value: u32) -> Self {
207        let vendor_id = (value & 0xFFFF) as u16;
208        let device_id = (value >> 16) as u16;
209        Self::new(vendor_id, device_id)
210    }
211}