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_configuration; 13 mod pci_device; 14 #[cfg(feature = "pci-hotplug")] 15 mod pci_hotplug; 16 mod pci_root; 17 #[cfg(any(target_os = "android", target_os = "linux"))] 18 mod pcie; 19 pub mod pm; 20 mod pvpanic; 21 mod stub; 22 #[cfg(any(target_os = "android", target_os = "linux"))] 23 mod vfio_pci; 24 25 use libc::EINVAL; 26 pub use resources::PciAddress; 27 pub use resources::PciAddressError; 28 use serde::Deserialize; 29 use serde::Serialize; 30 31 pub use self::acpi::GpeScope; 32 #[cfg(any(target_os = "android", target_os = "linux"))] 33 pub use self::coiommu::CoIommuDev; 34 #[cfg(any(target_os = "android", target_os = "linux"))] 35 pub use self::coiommu::CoIommuParameters; 36 #[cfg(any(target_os = "android", target_os = "linux"))] 37 pub use self::coiommu::CoIommuUnpinPolicy; 38 pub use self::msi::MsiConfig; 39 pub use self::msix::MsixCap; 40 pub use self::msix::MsixConfig; 41 pub use self::msix::MsixStatus; 42 pub use self::pci_configuration::PciBarConfiguration; 43 pub use self::pci_configuration::PciBarIndex; 44 pub use self::pci_configuration::PciBarPrefetchable; 45 pub use self::pci_configuration::PciBarRegionType; 46 pub use self::pci_configuration::PciBaseSystemPeripheralSubclass; 47 pub use self::pci_configuration::PciCapability; 48 pub use self::pci_configuration::PciCapabilityID; 49 pub use self::pci_configuration::PciClassCode; 50 pub use self::pci_configuration::PciConfiguration; 51 pub use self::pci_configuration::PciDisplaySubclass; 52 pub use self::pci_configuration::PciHeaderType; 53 pub use self::pci_configuration::PciInputDeviceSubclass; 54 pub use self::pci_configuration::PciMassStorageSubclass; 55 pub use self::pci_configuration::PciMultimediaSubclass; 56 pub use self::pci_configuration::PciNetworkControllerSubclass; 57 pub use self::pci_configuration::PciProgrammingInterface; 58 pub use self::pci_configuration::PciSerialBusSubClass; 59 pub use self::pci_configuration::PciSimpleCommunicationControllerSubclass; 60 pub use self::pci_configuration::PciSubclass; 61 pub use self::pci_configuration::PciWirelessControllerSubclass; 62 pub use self::pci_device::BarRange; 63 pub use self::pci_device::Error as PciDeviceError; 64 pub use self::pci_device::PciBus; 65 pub use self::pci_device::PciDevice; 66 pub use self::pci_device::PreferredIrq; 67 #[cfg(feature = "pci-hotplug")] 68 pub use self::pci_hotplug::HotPluggable; 69 #[cfg(feature = "pci-hotplug")] 70 pub use self::pci_hotplug::IntxParameter; 71 #[cfg(feature = "pci-hotplug")] 72 pub use self::pci_hotplug::NetResourceCarrier; 73 #[cfg(feature = "pci-hotplug")] 74 pub use self::pci_hotplug::ResourceCarrier; 75 pub use self::pci_root::PciConfigIo; 76 pub use self::pci_root::PciConfigMmio; 77 pub use self::pci_root::PciMmioMapper; 78 pub use self::pci_root::PciRoot; 79 pub use self::pci_root::PciRootCommand; 80 pub use self::pci_root::PciVirtualConfigMmio; 81 #[cfg(any(target_os = "android", target_os = "linux"))] 82 pub use self::pcie::PciBridge; 83 #[cfg(any(target_os = "android", target_os = "linux"))] 84 pub use self::pcie::PcieDownstreamPort; 85 #[cfg(any(target_os = "android", target_os = "linux"))] 86 pub use self::pcie::PcieHostPort; 87 #[cfg(any(target_os = "android", target_os = "linux"))] 88 pub use self::pcie::PcieRootPort; 89 #[cfg(any(target_os = "android", target_os = "linux"))] 90 pub use self::pcie::PcieUpstreamPort; 91 pub use self::pvpanic::PvPanicCode; 92 pub use self::pvpanic::PvPanicPciDevice; 93 pub use self::stub::StubPciDevice; 94 pub use self::stub::StubPciParameters; 95 #[cfg(any(target_os = "android", target_os = "linux"))] 96 pub use self::vfio_pci::VfioPciDevice; 97 98 /// PCI has four interrupt pins A->D. 99 #[derive(Copy, Clone, Ord, PartialOrd, PartialEq, Eq, Serialize, Deserialize)] 100 pub enum PciInterruptPin { 101 IntA, 102 IntB, 103 IntC, 104 IntD, 105 } 106 107 impl PciInterruptPin { to_mask(self) -> u32108 pub fn to_mask(self) -> u32 { 109 self as u32 110 } 111 } 112 113 // VCFG 114 pub const PCI_VCFG_PM: usize = 0x0; 115 pub const PCI_VCFG_DSM: usize = 0x1; 116 pub const PCI_VCFG_NOTY: usize = 0x2; 117 118 pub const PCI_VENDOR_ID_INTEL: u16 = 0x8086; 119 pub const PCI_VENDOR_ID_REDHAT: u16 = 0x1b36; 120 121 #[repr(u16)] 122 #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] 123 pub 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 149 impl TryFrom<u16> for CrosvmDeviceId { 150 type Error = base::Error; 151 try_from(value: u16) -> Result<Self, Self::Error>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 _ => Err(base::Error::new(EINVAL)), 176 } 177 } 178 } 179 180 /// A wrapper structure for pci device and vendor id. 181 #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] 182 pub struct PciId { 183 vendor_id: u16, 184 device_id: u16, 185 } 186 187 impl PciId { new(vendor_id: u16, device_id: u16) -> Self188 pub fn new(vendor_id: u16, device_id: u16) -> Self { 189 Self { 190 vendor_id, 191 device_id, 192 } 193 } 194 } 195 196 impl From<PciId> for u32 { from(pci_id: PciId) -> Self197 fn from(pci_id: PciId) -> Self { 198 // vendor ID is the lower 16 bits and device id is the upper 16 bits 199 pci_id.vendor_id as u32 | (pci_id.device_id as u32) << 16 200 } 201 } 202 203 impl From<u32> for PciId { from(value: u32) -> Self204 fn from(value: u32) -> Self { 205 let vendor_id = (value & 0xFFFF) as u16; 206 let device_id = (value >> 16) as u16; 207 Self::new(vendor_id, device_id) 208 } 209 } 210