summary refs log tree commit diff
path: root/devices
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2018-09-21 10:18:23 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-10-01 11:30:03 -0700
commitaee0ac2d67bb669fecfae56403bfd7352d2a4d0c (patch)
tree7368b216ccc24f81d62f82ba58cad71232162656 /devices
parentb2d6ffac5e2fb898e8c768ddcb6c21587de15162 (diff)
downloadcrosvm-aee0ac2d67bb669fecfae56403bfd7352d2a4d0c.tar
crosvm-aee0ac2d67bb669fecfae56403bfd7352d2a4d0c.tar.gz
crosvm-aee0ac2d67bb669fecfae56403bfd7352d2a4d0c.tar.bz2
crosvm-aee0ac2d67bb669fecfae56403bfd7352d2a4d0c.tar.lz
crosvm-aee0ac2d67bb669fecfae56403bfd7352d2a4d0c.tar.xz
crosvm-aee0ac2d67bb669fecfae56403bfd7352d2a4d0c.tar.zst
crosvm-aee0ac2d67bb669fecfae56403bfd7352d2a4d0c.zip
devices: pci: make more registers read only
Most of PCI configuration space should be read only; initialize the
writable_bits field accordingly.

Change-Id: I67f93d81cfbac6000db51663bdf76e54aeac08f3
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1240659
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'devices')
-rw-r--r--devices/src/pci/pci_configuration.rs18
1 files changed, 15 insertions, 3 deletions
diff --git a/devices/src/pci/pci_configuration.rs b/devices/src/pci/pci_configuration.rs
index 4d801ed..5cc62e1 100644
--- a/devices/src/pci/pci_configuration.rs
+++ b/devices/src/pci/pci_configuration.rs
@@ -184,7 +184,10 @@ impl PciConfiguration {
         subsystem_id: u16,
     ) -> Self {
         let mut registers = [0u32; NUM_CONFIGURATION_REGISTERS];
+        let mut writable_bits = [0u32; NUM_CONFIGURATION_REGISTERS];
         registers[0] = u32::from(device_id) << 16 | u32::from(vendor_id);
+        // TODO(dverkamp): Status should be write-1-to-clear
+        writable_bits[1] = 0x0000_ffff; // Status (r/o), command (r/w)
         let pi = if let Some(pi) = programming_interface {
             pi.get_register_value()
         } else {
@@ -193,14 +196,23 @@ impl PciConfiguration {
         registers[2] = u32::from(class_code.get_register_value()) << 24
             | u32::from(subclass.get_register_value()) << 16
             | u32::from(pi) << 8;
+        writable_bits[3] = 0x0000_00ff; // Cacheline size (r/w)
         match header_type {
-            PciHeaderType::Device => (),
-            PciHeaderType::Bridge => registers[3] = 0x0001_0000,
+            PciHeaderType::Device => {
+                registers[3] = 0x0000_0000; // Header type 0 (device)
+                writable_bits[15] = 0x0000_00ff; // Interrupt line (r/w)
+            },
+            PciHeaderType::Bridge => {
+                registers[3] = 0x0001_0000; // Header type 1 (bridge)
+                writable_bits[9] = 0xfff0_fff0; // Memory base and limit
+                writable_bits[15] = 0xffff_00ff; // Bridge control (r/w), interrupt line (r/w)
+            },
         };
         registers[11] = u32::from(subsystem_id) << 16 | u32::from(subsystem_vendor_id);
+
         PciConfiguration {
             registers,
-            writable_bits: [0xffff_ffff; NUM_CONFIGURATION_REGISTERS],
+            writable_bits,
             num_bars: 0,
             last_capability: None,
         }