From 6cba33580263963af9a79fb73ee88debd533991f Mon Sep 17 00:00:00 2001 From: Daniel Verkamp Date: Fri, 18 Feb 2022 14:18:24 -0800 Subject: [PATCH] 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 Tested-by: kokoro Commit-Queue: Daniel Verkamp --- devices/src/pci/mod.rs | 4 +- devices/src/pci/pci_address.rs | 88 ++++++++++++++++++++++++++++++++++ devices/src/pci/pci_root.rs | 85 +------------------------------- 3 files changed, 92 insertions(+), 85 deletions(-) create mode 100644 devices/src/pci/pci_address.rs diff --git a/devices/src/pci/mod.rs b/devices/src/pci/mod.rs index ddfd8d835f..e8cb0043e6 100644 --- a/devices/src/pci/mod.rs +++ b/devices/src/pci/mod.rs @@ -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; diff --git a/devices/src/pci/pci_address.rs b/devices/src/pci/pci_address.rs new file mode 100644 index 0000000000..44e6bae34b --- /dev/null +++ b/devices/src/pci/pci_address.rs @@ -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::>(); + 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 + } + ) + } +} diff --git a/devices/src/pci/pci_root.rs b/devices/src/pci/pci_root.rs index 2476651f7e..86860c9eeb 100644 --- a/devices/src/pci/pci_root.rs +++ b/devices/src/pci/pci_root.rs @@ -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::>(); - 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 {