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