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 #[cfg(feature = "audio")] 8 mod ac97; 9 #[cfg(feature = "audio")] 10 mod ac97_bus_master; 11 #[cfg(feature = "audio")] 12 mod ac97_mixer; 13 #[cfg(feature = "audio")] 14 mod ac97_regs; 15 mod acpi; 16 #[cfg(unix)] 17 mod coiommu; 18 mod msi; 19 mod msix; 20 mod pci_address; 21 mod pci_configuration; 22 mod pci_device; 23 mod pci_root; 24 #[cfg(unix)] 25 mod pcie; 26 mod pm; 27 mod pvpanic; 28 mod stub; 29 #[cfg(unix)] 30 mod vfio_pci; 31 32 use libc::EINVAL; 33 use serde::Deserialize; 34 use serde::Serialize; 35 36 #[cfg(feature = "audio")] 37 pub use self::ac97::Ac97Backend; 38 #[cfg(feature = "audio")] 39 pub use self::ac97::Ac97Dev; 40 #[cfg(feature = "audio")] 41 pub use self::ac97::Ac97Parameters; 42 pub use self::acpi::DeviceVcfgRegister; 43 pub use self::acpi::PowerResourceMethod; 44 #[cfg(unix)] 45 pub use self::coiommu::CoIommuDev; 46 #[cfg(unix)] 47 pub use self::coiommu::CoIommuParameters; 48 #[cfg(unix)] 49 pub use self::coiommu::CoIommuUnpinPolicy; 50 pub use self::msi::MsiConfig; 51 pub use self::msix::MsixCap; 52 pub use self::msix::MsixConfig; 53 pub use self::msix::MsixStatus; 54 pub use self::pci_address::Error as PciAddressError; 55 pub use self::pci_address::PciAddress; 56 pub use self::pci_configuration::PciBarConfiguration; 57 pub use self::pci_configuration::PciBarIndex; 58 pub use self::pci_configuration::PciBarPrefetchable; 59 pub use self::pci_configuration::PciBarRegionType; 60 pub use self::pci_configuration::PciCapability; 61 pub use self::pci_configuration::PciCapabilityID; 62 pub use self::pci_configuration::PciClassCode; 63 pub use self::pci_configuration::PciConfiguration; 64 pub use self::pci_configuration::PciDisplaySubclass; 65 pub use self::pci_configuration::PciHeaderType; 66 pub use self::pci_configuration::PciProgrammingInterface; 67 pub use self::pci_configuration::PciSerialBusSubClass; 68 pub use self::pci_configuration::PciSubclass; 69 pub use self::pci_configuration::CAPABILITY_LIST_HEAD_OFFSET; 70 pub use self::pci_device::BarRange; 71 pub use self::pci_device::Error as PciDeviceError; 72 pub use self::pci_device::IoEventError as PciIoEventError; 73 pub use self::pci_device::PciBus; 74 pub use self::pci_device::PciDevice; 75 pub use self::pci_device::PreferredIrq; 76 pub use self::pci_root::PciConfigIo; 77 pub use self::pci_root::PciConfigMmio; 78 pub use self::pci_root::PciRoot; 79 pub use self::pci_root::PciRootCommand; 80 pub use self::pci_root::PciVirtualConfigMmio; 81 #[cfg(unix)] 82 pub use self::pcie::PciBridge; 83 #[cfg(unix)] 84 pub use self::pcie::PcieDownstreamPort; 85 #[cfg(unix)] 86 pub use self::pcie::PcieHostPort; 87 #[cfg(unix)] 88 pub use self::pcie::PcieRootPort; 89 #[cfg(unix)] 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(unix)] 96 pub use self::vfio_pci::VfioPciDevice; 97 98 /// PCI has four interrupt pins A->D. 99 #[derive(Copy, Clone, Ord, PartialOrd, PartialEq, Eq)] 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 pub const PCI_VENDOR_ID_INTEL: u16 = 0x8086; 114 pub const PCI_VENDOR_ID_REDHAT: u16 = 0x1b36; 115 116 #[repr(u16)] 117 #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] 118 pub enum CrosvmDeviceId { 119 Pit = 1, 120 Pic = 2, 121 Ioapic = 3, 122 Serial = 4, 123 Cmos = 5, 124 I8042 = 6, 125 Pl030 = 7, 126 ACPIPMResource = 8, 127 GoldfishBattery = 9, 128 DebugConsole = 10, 129 ProxyDevice = 11, 130 VfioPlatformDevice = 12, 131 DirectGsi = 13, 132 DirectIo = 14, 133 DirectMmio = 15, 134 UserspaceIrqChip = 16, 135 VmWatchdog = 17, 136 Pflash = 18, 137 VirtioMmio = 19, 138 AcAdapter = 20, 139 } 140 141 impl TryFrom<u16> for CrosvmDeviceId { 142 type Error = base::Error; 143 try_from(value: u16) -> Result<Self, Self::Error>144 fn try_from(value: u16) -> Result<Self, Self::Error> { 145 match value { 146 1 => Ok(CrosvmDeviceId::Pit), 147 2 => Ok(CrosvmDeviceId::Pic), 148 3 => Ok(CrosvmDeviceId::Ioapic), 149 4 => Ok(CrosvmDeviceId::Serial), 150 5 => Ok(CrosvmDeviceId::Cmos), 151 6 => Ok(CrosvmDeviceId::I8042), 152 7 => Ok(CrosvmDeviceId::Pl030), 153 8 => Ok(CrosvmDeviceId::ACPIPMResource), 154 9 => Ok(CrosvmDeviceId::GoldfishBattery), 155 10 => Ok(CrosvmDeviceId::DebugConsole), 156 11 => Ok(CrosvmDeviceId::ProxyDevice), 157 12 => Ok(CrosvmDeviceId::VfioPlatformDevice), 158 13 => Ok(CrosvmDeviceId::DirectGsi), 159 14 => Ok(CrosvmDeviceId::DirectMmio), 160 15 => Ok(CrosvmDeviceId::DirectIo), 161 16 => Ok(CrosvmDeviceId::UserspaceIrqChip), 162 17 => Ok(CrosvmDeviceId::VmWatchdog), 163 18 => Ok(CrosvmDeviceId::Pflash), 164 19 => Ok(CrosvmDeviceId::VirtioMmio), 165 20 => Ok(CrosvmDeviceId::AcAdapter), 166 _ => Err(base::Error::new(EINVAL)), 167 } 168 } 169 } 170 171 /// A wrapper structure for pci device and vendor id. 172 #[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] 173 pub struct PciId { 174 vendor_id: u16, 175 device_id: u16, 176 } 177 178 impl PciId { new(vendor_id: u16, device_id: u16) -> Self179 pub fn new(vendor_id: u16, device_id: u16) -> Self { 180 Self { 181 vendor_id, 182 device_id, 183 } 184 } 185 } 186 187 impl From<PciId> for u32 { from(pci_id: PciId) -> Self188 fn from(pci_id: PciId) -> Self { 189 // vendor ID is the lower 16 bits and device id is the upper 16 bits 190 pci_id.vendor_id as u32 | (pci_id.device_id as u32) << 16 191 } 192 } 193 194 impl From<u32> for PciId { from(value: u32) -> Self195 fn from(value: u32) -> Self { 196 let vendor_id = (value & 0xFFFF) as u16; 197 let device_id = (value >> 16) as u16; 198 Self::new(vendor_id, device_id) 199 } 200 } 201