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:
Daniel Verkamp 2022-02-18 14:18:24 -08:00 committed by Commit Bot
parent 4bc52e6aa5
commit 6cba335802
3 changed files with 92 additions and 85 deletions

View file

@ -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;

View 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
}
)
}
}

View file

@ -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 {