mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-11 04:26:38 +00:00
devices: pci: move PciAddress to its own file
PciAddress is not really related to pci_root. Split it out so that it is easier to find and so it can have its own tests nearby. No code changes. BUG=None TEST=cargo build Change-Id: I2bdad518de76587506593292cf0fbdb6b7066c1e Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3475439 Reviewed-by: Alexandre Courbot <acourbot@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
parent
4bc52e6aa5
commit
6cba335802
3 changed files with 92 additions and 85 deletions
|
@ -14,6 +14,7 @@ mod ac97_mixer;
|
|||
mod ac97_regs;
|
||||
mod coiommu;
|
||||
mod msix;
|
||||
mod pci_address;
|
||||
mod pci_configuration;
|
||||
mod pci_device;
|
||||
mod pci_root;
|
||||
|
@ -25,6 +26,7 @@ mod vfio_pci;
|
|||
pub use self::ac97::{Ac97Backend, Ac97Dev, Ac97Parameters};
|
||||
pub use self::coiommu::{CoIommuDev, CoIommuParameters, CoIommuUnpinPolicy};
|
||||
pub use self::msix::{MsixCap, MsixConfig, MsixStatus};
|
||||
pub use self::pci_address::PciAddress;
|
||||
pub use self::pci_configuration::{
|
||||
PciBarConfiguration, PciBarIndex, PciBarPrefetchable, PciBarRegionType, PciCapability,
|
||||
PciCapabilityID, PciClassCode, PciConfiguration, PciDisplaySubclass, PciHeaderType,
|
||||
|
@ -32,7 +34,7 @@ pub use self::pci_configuration::{
|
|||
};
|
||||
pub use self::pci_device::Error as PciDeviceError;
|
||||
pub use self::pci_device::PciDevice;
|
||||
pub use self::pci_root::{PciAddress, PciConfigIo, PciConfigMmio, PciRoot};
|
||||
pub use self::pci_root::{PciConfigIo, PciConfigMmio, PciRoot};
|
||||
pub use self::pcie::{PciBridge, PcieRootPort};
|
||||
pub use self::stub::{StubPciDevice, StubPciParameters};
|
||||
pub use self::vfio_pci::VfioPciDevice;
|
||||
|
|
88
devices/src/pci/pci_address.rs
Normal file
88
devices/src/pci/pci_address.rs
Normal file
|
@ -0,0 +1,88 @@
|
|||
// Copyright 2018 The Chromium OS Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
use std::fmt::{self, Display};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// PCI Device Address, AKA Bus:Device.Function
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct PciAddress {
|
||||
pub bus: u8,
|
||||
pub dev: u8, /* u5 */
|
||||
pub func: u8, /* u3 */
|
||||
}
|
||||
|
||||
impl Display for PciAddress {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:04x}:{:02x}.{:0x}", self.bus, self.dev, self.func)
|
||||
}
|
||||
}
|
||||
|
||||
impl PciAddress {
|
||||
const BUS_MASK: u32 = 0x00ff;
|
||||
const DEVICE_BITS_NUM: usize = 5;
|
||||
const DEVICE_MASK: u32 = 0x1f;
|
||||
const FUNCTION_BITS_NUM: usize = 3;
|
||||
const FUNCTION_MASK: u32 = 0x07;
|
||||
const REGISTER_OFFSET: usize = 2;
|
||||
|
||||
/// Construct PciAddress and register tuple from CONFIG_ADDRESS value.
|
||||
pub fn from_config_address(config_address: u32, register_bits_num: usize) -> (Self, usize) {
|
||||
let bus_offset = register_bits_num + Self::FUNCTION_BITS_NUM + Self::DEVICE_BITS_NUM;
|
||||
let bus = ((config_address >> bus_offset) & Self::BUS_MASK) as u8;
|
||||
let dev_offset = register_bits_num + Self::FUNCTION_BITS_NUM;
|
||||
let dev = ((config_address >> dev_offset) & Self::DEVICE_MASK) as u8;
|
||||
let func = ((config_address >> register_bits_num) & Self::FUNCTION_MASK) as u8;
|
||||
let register_mask: u32 = (1_u32 << (register_bits_num - Self::REGISTER_OFFSET)) - 1;
|
||||
let register = ((config_address >> Self::REGISTER_OFFSET) & register_mask) as usize;
|
||||
|
||||
(PciAddress { bus, dev, func }, register)
|
||||
}
|
||||
|
||||
/// Construct PciAddress from string domain:bus:device.function.
|
||||
pub fn from_string(address: &str) -> Self {
|
||||
let mut func_dev_bus_domain = address
|
||||
.split(|c| c == ':' || c == '.')
|
||||
.map(|v| u8::from_str_radix(v, 16).unwrap_or_default())
|
||||
.rev()
|
||||
.collect::<Vec<u8>>();
|
||||
func_dev_bus_domain.resize(4, 0);
|
||||
PciAddress {
|
||||
bus: func_dev_bus_domain[2],
|
||||
dev: func_dev_bus_domain[1],
|
||||
func: func_dev_bus_domain[0],
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode PciAddress into CONFIG_ADDRESS value.
|
||||
pub fn to_config_address(&self, register: usize, register_bits_num: usize) -> u32 {
|
||||
let bus_offset = register_bits_num + Self::FUNCTION_BITS_NUM + Self::DEVICE_BITS_NUM;
|
||||
let dev_offset = register_bits_num + Self::FUNCTION_BITS_NUM;
|
||||
let register_mask: u32 = (1_u32 << (register_bits_num - Self::REGISTER_OFFSET)) - 1;
|
||||
((Self::BUS_MASK & self.bus as u32) << bus_offset)
|
||||
| ((Self::DEVICE_MASK & self.dev as u32) << dev_offset)
|
||||
| ((Self::FUNCTION_MASK & self.func as u32) << register_bits_num)
|
||||
| ((register_mask & register as u32) << Self::REGISTER_OFFSET)
|
||||
}
|
||||
|
||||
/// Convert B:D:F PCI address to unsigned 32 bit integer
|
||||
pub fn to_u32(&self) -> u32 {
|
||||
((Self::BUS_MASK & self.bus as u32) << (Self::FUNCTION_BITS_NUM + Self::DEVICE_BITS_NUM))
|
||||
| ((Self::DEVICE_MASK & self.dev as u32) << Self::FUNCTION_BITS_NUM)
|
||||
| (Self::FUNCTION_MASK & self.func as u32)
|
||||
}
|
||||
|
||||
/// Returns true if the address points to PCI root host-bridge.
|
||||
pub fn is_root(&self) -> bool {
|
||||
matches!(
|
||||
&self,
|
||||
PciAddress {
|
||||
bus: 0,
|
||||
dev: 0,
|
||||
func: 0
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
|
@ -4,12 +4,10 @@
|
|||
|
||||
use std::collections::BTreeMap;
|
||||
use std::convert::TryInto;
|
||||
use std::fmt::{self, Display};
|
||||
use std::ops::Bound::Included;
|
||||
use std::sync::{Arc, Weak};
|
||||
|
||||
use base::{error, Event, RawDescriptor};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sync::Mutex;
|
||||
|
||||
use crate::pci::pci_configuration::{
|
||||
|
@ -17,7 +15,7 @@ use crate::pci::pci_configuration::{
|
|||
HEADER_TYPE_MULTIFUNCTION_MASK, HEADER_TYPE_REG,
|
||||
};
|
||||
use crate::pci::pci_device::{Error, PciDevice};
|
||||
use crate::pci::PCI_VENDOR_ID_INTEL;
|
||||
use crate::pci::{PciAddress, PCI_VENDOR_ID_INTEL};
|
||||
use crate::{Bus, BusAccessInfo, BusDevice, BusType};
|
||||
use resources::SystemAllocator;
|
||||
|
||||
|
@ -58,87 +56,6 @@ impl PciDevice for PciRootConfiguration {
|
|||
}
|
||||
}
|
||||
|
||||
/// PCI Device Address, AKA Bus:Device.Function
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct PciAddress {
|
||||
pub bus: u8,
|
||||
pub dev: u8, /* u5 */
|
||||
pub func: u8, /* u3 */
|
||||
}
|
||||
|
||||
impl Display for PciAddress {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "{:04x}:{:02x}.{:0x}", self.bus, self.dev, self.func)
|
||||
}
|
||||
}
|
||||
|
||||
impl PciAddress {
|
||||
const BUS_MASK: u32 = 0x00ff;
|
||||
const DEVICE_BITS_NUM: usize = 5;
|
||||
const DEVICE_MASK: u32 = 0x1f;
|
||||
const FUNCTION_BITS_NUM: usize = 3;
|
||||
const FUNCTION_MASK: u32 = 0x07;
|
||||
const REGISTER_OFFSET: usize = 2;
|
||||
|
||||
/// Construct PciAddress and register tuple from CONFIG_ADDRESS value.
|
||||
pub fn from_config_address(config_address: u32, register_bits_num: usize) -> (Self, usize) {
|
||||
let bus_offset = register_bits_num + Self::FUNCTION_BITS_NUM + Self::DEVICE_BITS_NUM;
|
||||
let bus = ((config_address >> bus_offset) & Self::BUS_MASK) as u8;
|
||||
let dev_offset = register_bits_num + Self::FUNCTION_BITS_NUM;
|
||||
let dev = ((config_address >> dev_offset) & Self::DEVICE_MASK) as u8;
|
||||
let func = ((config_address >> register_bits_num) & Self::FUNCTION_MASK) as u8;
|
||||
let register_mask: u32 = (1_u32 << (register_bits_num - Self::REGISTER_OFFSET)) - 1;
|
||||
let register = ((config_address >> Self::REGISTER_OFFSET) & register_mask) as usize;
|
||||
|
||||
(PciAddress { bus, dev, func }, register)
|
||||
}
|
||||
|
||||
/// Construct PciAddress from string domain:bus:device.function.
|
||||
pub fn from_string(address: &str) -> Self {
|
||||
let mut func_dev_bus_domain = address
|
||||
.split(|c| c == ':' || c == '.')
|
||||
.map(|v| u8::from_str_radix(v, 16).unwrap_or_default())
|
||||
.rev()
|
||||
.collect::<Vec<u8>>();
|
||||
func_dev_bus_domain.resize(4, 0);
|
||||
PciAddress {
|
||||
bus: func_dev_bus_domain[2],
|
||||
dev: func_dev_bus_domain[1],
|
||||
func: func_dev_bus_domain[0],
|
||||
}
|
||||
}
|
||||
|
||||
/// Encode PciAddress into CONFIG_ADDRESS value.
|
||||
pub fn to_config_address(&self, register: usize, register_bits_num: usize) -> u32 {
|
||||
let bus_offset = register_bits_num + Self::FUNCTION_BITS_NUM + Self::DEVICE_BITS_NUM;
|
||||
let dev_offset = register_bits_num + Self::FUNCTION_BITS_NUM;
|
||||
let register_mask: u32 = (1_u32 << (register_bits_num - Self::REGISTER_OFFSET)) - 1;
|
||||
((Self::BUS_MASK & self.bus as u32) << bus_offset)
|
||||
| ((Self::DEVICE_MASK & self.dev as u32) << dev_offset)
|
||||
| ((Self::FUNCTION_MASK & self.func as u32) << register_bits_num)
|
||||
| ((register_mask & register as u32) << Self::REGISTER_OFFSET)
|
||||
}
|
||||
|
||||
/// Convert B:D:F PCI address to unsigned 32 bit integer
|
||||
pub fn to_u32(&self) -> u32 {
|
||||
((Self::BUS_MASK & self.bus as u32) << (Self::FUNCTION_BITS_NUM + Self::DEVICE_BITS_NUM))
|
||||
| ((Self::DEVICE_MASK & self.dev as u32) << Self::FUNCTION_BITS_NUM)
|
||||
| (Self::FUNCTION_MASK & self.func as u32)
|
||||
}
|
||||
|
||||
/// Returns true if the address points to PCI root host-bridge.
|
||||
fn is_root(&self) -> bool {
|
||||
matches!(
|
||||
&self,
|
||||
PciAddress {
|
||||
bus: 0,
|
||||
dev: 0,
|
||||
func: 0
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/// Emulates the PCI Root bridge.
|
||||
#[allow(dead_code)] // TODO(b/174705596): remove once mmio_bus and io_bus are used
|
||||
pub struct PciRoot {
|
||||
|
|
Loading…
Reference in a new issue