• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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