]> xenbits.xensource.com Git - xen.git/commitdiff
x86/pci: introduce hvm_pci_decode_addr
authorRoger Pau Monné <roger.pau@citrix.com>
Fri, 25 Aug 2017 12:08:19 +0000 (14:08 +0200)
committerJan Beulich <jbeulich@suse.com>
Fri, 25 Aug 2017 12:08:19 +0000 (14:08 +0200)
And use it in the ioreq code to decode accesses to the PCI IO ports
into bus, slot, function and register values.

Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Paul Durrant <paul.durrant@citrix.com>
xen/arch/x86/hvm/io.c
xen/arch/x86/hvm/ioreq.c
xen/include/asm-x86/hvm/io.h

index 214ab307c4807b329fcf260632656b2275454db6..bf41954f59452401bceee73cea22dcf9cf4ac5b6 100644 (file)
@@ -256,6 +256,25 @@ void register_g2m_portio_handler(struct domain *d)
     handler->ops = &g2m_portio_ops;
 }
 
+unsigned int hvm_pci_decode_addr(unsigned int cf8, unsigned int addr,
+                                 unsigned int *bus, unsigned int *slot,
+                                 unsigned int *func)
+{
+    unsigned int bdf;
+
+    ASSERT(CF8_ENABLED(cf8));
+
+    bdf = CF8_BDF(cf8);
+    *bus = PCI_BUS(bdf);
+    *slot = PCI_SLOT(bdf);
+    *func = PCI_FUNC(bdf);
+    /*
+     * NB: the lower 2 bits of the register address are fetched from the
+     * offset into the 0xcfc register when reading/writing to it.
+     */
+    return CF8_ADDR_LO(cf8) | (addr & 3);
+}
+
 /*
  * Local variables:
  * mode: C
index b2a8b0e9868664c120dd49d563023a059f8b404a..752976d16d541000063e113b7bb93a3eef3c56fa 100644 (file)
@@ -1178,18 +1178,16 @@ struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
          CF8_ENABLED(cf8) )
     {
         uint32_t sbdf, x86_fam;
+        unsigned int bus, slot, func, reg;
+
+        reg = hvm_pci_decode_addr(cf8, p->addr, &bus, &slot, &func);
 
         /* PCI config data cycle */
 
-        sbdf = XEN_DMOP_PCI_SBDF(0,
-                                 PCI_BUS(CF8_BDF(cf8)),
-                                 PCI_SLOT(CF8_BDF(cf8)),
-                                 PCI_FUNC(CF8_BDF(cf8)));
+        sbdf = XEN_DMOP_PCI_SBDF(0, bus, slot, func);
 
         type = XEN_DMOP_IO_RANGE_PCI;
-        addr = ((uint64_t)sbdf << 32) |
-               CF8_ADDR_LO(cf8) |
-               (p->addr & 3);
+        addr = ((uint64_t)sbdf << 32) | reg;
         /* AMD extended configuration space access? */
         if ( CF8_ADDR_HI(cf8) &&
              d->arch.cpuid->x86_vendor == X86_VENDOR_AMD &&
index 2484eb1c7531f165b1fedb477cd93854d640a6fe..51659b6c7f243bef32ce1a82445b01f4eff58796 100644 (file)
@@ -149,6 +149,11 @@ void stdvga_deinit(struct domain *d);
 
 extern void hvm_dpci_msi_eoi(struct domain *d, int vector);
 
+/* Decode a PCI port IO access into a bus/slot/func/reg. */
+unsigned int hvm_pci_decode_addr(unsigned int cf8, unsigned int addr,
+                                 unsigned int *bus, unsigned int *slot,
+                                 unsigned int *func);
+
 /*
  * HVM port IO handler that performs forwarding of guest IO ports into machine
  * IO ports.