#include "pt-msi.h"
#include "qemu-xen.h"
+extern int vga_passthrough;
+
struct php_dev {
struct pt_dev *pt_dev;
uint8_t valid;
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);
*(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);
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;
/* 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;
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;
+}