]> xenbits.xensource.com Git - xenclient/ioemu.git/commitdiff
- Add some pci function to read pci register value on the host's pci
authorJean Guyader <jean.guyader@eu.citrix.com>
Thu, 9 Oct 2008 16:45:11 +0000 (17:45 +0100)
committerVincent Hanquez <vincent@snarc.org>
Fri, 31 Oct 2008 12:10:55 +0000 (12:10 +0000)
    bus.
  - Map and unmap the legacy ioport/iomem when we attach/detach the device.

hw/pass-through.c
hw/pass-through.h

index 77ab759a59cf0ccc8fbdd2085f5c0c430ad567e6..9bb13fe25e65647c092cc3ebe9173867c4f00dd8 100644 (file)
@@ -28,6 +28,8 @@
 #include "pt-msi.h"
 #include "qemu-xen.h"
 
+extern int vga_passthrough;
+
 struct php_dev {
     struct pt_dev *pt_dev;
     uint8_t valid;
@@ -2876,6 +2878,7 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
     uint8_t e_device, e_intx;
     struct pci_config_cf8 machine_bdf;
     int free_pci_slot = -1;
+    uint16_t class, vendor_id;
 
     PT_LOG("Assigning real physical device %02x:%02x.%x ...\n",
         r_bus, r_dev, r_func);
@@ -2983,6 +2986,29 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
             *(uint16_t *)(&assigned_device->dev.config[0x04]));
     }
 
+    /* Map legacy ioport and iomem, for specific devices */
+    vendor_id = pci_read_word(pci_dev, 0x00);
+    class = pci_read_word(pci_dev, 0x0a);
+    
+    PT_LOG("Real device vendor_id=0x%x class=0x%x\n", vendor_id, class);
+    if ( vga_passthrough && class == 0x0300 )
+    {
+        PT_LOG("add an intel graphic card\n");
+
+        rc = xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, 0x3C0, 32,
+                                      DPCI_ADD_MAPPING);
+        rc |= xc_domain_memory_mapping(xc_handle, domid, 0xa0, 0xa0, 32,
+                                       DPCI_ADD_MAPPING);
+        if ( vendor_id == 0x8086 )
+            rc |= xc_domain_memory_mapping(xc_handle, domid, 0x7d5ae, 0x7d5ae, 2,
+                                           DPCI_ADD_MAPPING);
+        if ( rc != 0 )
+        {
+            PT_LOG("legacy mapping failed !\n");
+            return NULL;
+        }
+    }
+
 out:
     PT_LOG("Real physical device %02x:%02x.%x registered successfuly!\n", 
         r_bus, r_dev, r_func);
@@ -2999,6 +3025,7 @@ int unregister_real_device(int php_slot)
     uint32_t machine_irq;
     uint32_t bdf = 0;
     int rc = -1;
+    uint16_t class, vendor_id;
 
     if ( php_slot < 0 || php_slot >= PHP_SLOT_LEN )
        return -1;
@@ -3035,6 +3062,30 @@ int unregister_real_device(int php_slot)
 
     /* unregister real device's MMIO/PIO BARs */
     pt_unregister_regions(assigned_device);
+
+    /* unmap legacy ioport and iomem, for specific devices */
+    vendor_id = pci_read_word(pci_dev, 0x00);
+    class = pci_read_word(pci_dev, 0x0a);
+    
+    PT_LOG("Real device vendor_id=0x%x class=0x%x\n", vendor_id, class);
+    if ( vga_passthrough && class == 0x0300 )
+    {
+        PT_LOG("remove an intel graphic card\n");
+
+        rc = xc_domain_ioport_mapping(xc_handle, domid, 0x3C0, 0x3C0, 32,
+                                       DPCI_REMOVE_MAPPING);
+        rc |= xc_domain_memory_mapping(xc_handle, domid, 0xa0, 0xa0, 32,
+                                        DPCI_REMOVE_MAPPING);
+        if ( vendor_id == 0x8086 )
+            rc |= xc_domain_memory_mapping(xc_handle, domid, 0x7d5ae, 0x7d5ae, 2,
+                                           DPCI_REMOVE_MAPPING);
+        if ( rc != 0 )
+        {
+            PT_LOG("legacy unmapping failed !\n");
+            return NULL;
+        }
+    }
+
     
     /* deassign the dev to dom0 */
     bdf |= (pci_dev->bus  & 0xff) << 16;
@@ -3149,3 +3200,42 @@ int pt_init(PCIBus *e_bus, const char *direct_pci)
     return 0;
 }
 
+
+u8      pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr)
+{
+    struct pci_dev*     pci_dev;
+    u8                  val;
+
+    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
+    if (!pci_dev)
+        return 0;
+    val = pci_read_byte(pci_dev, addr);
+    pci_free_dev(pci_dev);
+    return val;
+}
+
+u16     pt_pci_host_read_word(int bus, int dev, int fn, u32 addr)
+{
+    struct pci_dev*     pci_dev;
+    u16                 val;
+
+    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
+    if (!pci_dev)
+        return 0;
+    val = pci_read_word(pci_dev, addr);
+    pci_free_dev(pci_dev);
+    return val;
+}
+
+u32     pt_pci_host_read_long(int bus, int dev, int fn, u32 addr)
+{
+    struct pci_dev*     pci_dev;
+    u32                 val;
+
+    pci_dev = pci_get_dev(dpci_infos.pci_access, 0, bus, dev, fn);
+    if (!pci_dev)
+        return 0;
+    val = pci_read_long(pci_dev, addr);
+    pci_free_dev(pci_dev);
+    return val;
+}
index bc3ef8cbbc2e7d0b18a52962e941ac648323ae5e..b08af8cb1a6fe0ba829c978c8709775844883bb5 100644 (file)
@@ -292,5 +292,9 @@ struct pt_reg_info_tbl {
     } u;
 };
 
+u8  pt_pci_host_read_byte(int bus, int dev, int fn, u32 addr);
+u16 pt_pci_host_read_word(int bus, int dev, int fn, u32 addr);
+u32 pt_pci_host_read_long(int bus, int dev, int fn, u32 addr);
+
 #endif /* __PASSTHROUGH_H__ */