summary refs log tree commit diff
path: root/devices
diff options
context:
space:
mode:
authorTomasz Jeznach <tjeznach@chromium.org>2020-05-01 09:54:59 -0700
committerCommit Bot <commit-bot@chromium.org>2020-05-05 00:03:46 +0000
commite94b5f84da58d7f74a2c093143b665699c1bebca (patch)
treeded356f3de7bd0b56fe6394b342f3460aa69e121 /devices
parent6fe08fa36338ee6339dd4748173865763bfc7b31 (diff)
downloadcrosvm-e94b5f84da58d7f74a2c093143b665699c1bebca.tar
crosvm-e94b5f84da58d7f74a2c093143b665699c1bebca.tar.gz
crosvm-e94b5f84da58d7f74a2c093143b665699c1bebca.tar.bz2
crosvm-e94b5f84da58d7f74a2c093143b665699c1bebca.tar.lz
crosvm-e94b5f84da58d7f74a2c093143b665699c1bebca.tar.xz
crosvm-e94b5f84da58d7f74a2c093143b665699c1bebca.tar.zst
crosvm-e94b5f84da58d7f74a2c093143b665699c1bebca.zip
pci: refactor FDT/MPTABLE creation to use PciAddress.
Simple refactor of FDT and MPTables generation to use PCI device
addressing and allow declatation of non-zero PCI bus ids for x86
architectures. It also allows non sequential IRQ allocation for
PCI devices.

BUG=None
TEST=build_test & tast run crostini.Sanity

Change-Id: I6cc31ce412199a732499b2d8d18d99f08d765690
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2175739
Tested-by: Tomasz Jeznach <tjeznach@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Commit-Queue: Tomasz Jeznach <tjeznach@chromium.org>
Diffstat (limited to 'devices')
-rw-r--r--devices/src/pci/pci_root.rs55
1 files changed, 31 insertions, 24 deletions
diff --git a/devices/src/pci/pci_root.rs b/devices/src/pci/pci_root.rs
index 4f0e453..91d6094 100644
--- a/devices/src/pci/pci_root.rs
+++ b/devices/src/pci/pci_root.rs
@@ -56,6 +56,33 @@ impl Display for PciAddress {
 }
 
 impl PciAddress {
+    const BUS_OFFSET: usize = 16;
+    const BUS_MASK: u32 = 0x00ff;
+    const DEVICE_OFFSET: usize = 11;
+    const DEVICE_MASK: u32 = 0x1f;
+    const FUNCTION_OFFSET: usize = 8;
+    const FUNCTION_MASK: u32 = 0x07;
+    const REGISTER_OFFSET: usize = 2;
+    const REGISTER_MASK: u32 = 0x3f;
+
+    /// Construct PciAddress and register tuple from CONFIG_ADDRESS value.
+    pub fn from_config_address(config_address: u32) -> (Self, usize) {
+        let bus = ((config_address >> Self::BUS_OFFSET) & Self::BUS_MASK) as u8;
+        let dev = ((config_address >> Self::DEVICE_OFFSET) & Self::DEVICE_MASK) as u8;
+        let func = ((config_address >> Self::FUNCTION_OFFSET) & Self::FUNCTION_MASK) as u8;
+        let register = ((config_address >> Self::REGISTER_OFFSET) & Self::REGISTER_MASK) as usize;
+
+        (PciAddress { bus, dev, func }, register)
+    }
+
+    /// Encode PciAddress into CONFIG_ADDRESS value.
+    pub fn to_config_address(&self, register: usize) -> u32 {
+        ((Self::BUS_MASK & self.bus as u32) << Self::BUS_OFFSET)
+            | ((Self::DEVICE_MASK & self.dev as u32) << Self::DEVICE_OFFSET)
+            | ((Self::FUNCTION_MASK & self.func as u32) << Self::FUNCTION_OFFSET)
+            | ((Self::REGISTER_MASK & register as u32) << Self::REGISTER_OFFSET)
+    }
+
     /// Returns true if the address points to PCI root host-bridge.
     fn is_root(&self) -> bool {
         matches!(
@@ -159,7 +186,7 @@ impl PciConfigIo {
             return 0xffff_ffff;
         }
 
-        let (address, register) = parse_config_address(self.config_address & !0x8000_0000);
+        let (address, register) = PciAddress::from_config_address(self.config_address);
         self.pci_root.config_space_read(address, register)
     }
 
@@ -169,7 +196,7 @@ impl PciConfigIo {
             return;
         }
 
-        let (address, register) = parse_config_address(self.config_address & !0x8000_0000);
+        let (address, register) = PciAddress::from_config_address(self.config_address);
         self.pci_root
             .config_space_write(address, register, offset, data)
     }
@@ -243,12 +270,12 @@ impl PciConfigMmio {
     }
 
     fn config_space_read(&self, config_address: u32) -> u32 {
-        let (address, register) = parse_config_address(config_address);
+        let (address, register) = PciAddress::from_config_address(config_address);
         self.pci_root.config_space_read(address, register)
     }
 
     fn config_space_write(&mut self, config_address: u32, offset: u64, data: &[u8]) {
-        let (address, register) = parse_config_address(config_address);
+        let (address, register) = PciAddress::from_config_address(config_address);
         self.pci_root
             .config_space_write(address, register, offset, data)
     }
@@ -283,23 +310,3 @@ impl BusDevice for PciConfigMmio {
         self.config_space_write(offset as u32, offset % 4, data)
     }
 }
-
-// Parse the CONFIG_ADDRESS register to a (bus, device, function, register) tuple.
-fn parse_config_address(config_address: u32) -> (PciAddress, usize) {
-    const BUS_NUMBER_OFFSET: usize = 16;
-    const BUS_NUMBER_MASK: u32 = 0x00ff;
-    const DEVICE_NUMBER_OFFSET: usize = 11;
-    const DEVICE_NUMBER_MASK: u32 = 0x1f;
-    const FUNCTION_NUMBER_OFFSET: usize = 8;
-    const FUNCTION_NUMBER_MASK: u32 = 0x07;
-    const REGISTER_NUMBER_OFFSET: usize = 2;
-    const REGISTER_NUMBER_MASK: u32 = 0x3f;
-
-    let bus = ((config_address >> BUS_NUMBER_OFFSET) & BUS_NUMBER_MASK) as u8;
-    let dev = ((config_address >> DEVICE_NUMBER_OFFSET) & DEVICE_NUMBER_MASK) as u8;
-    let func = ((config_address >> FUNCTION_NUMBER_OFFSET) & FUNCTION_NUMBER_MASK) as u8;
-    let register_number =
-        ((config_address >> REGISTER_NUMBER_OFFSET) & REGISTER_NUMBER_MASK) as usize;
-
-    (PciAddress { bus, dev, func }, register_number)
-}