[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [PATCH 2/2] qemu-xen: Intel GPU passthrough
On Tue, 31 Jan 2012, Jean Guyader wrote: > > Reset Intel GPU fences when the domain starts (first mapping > of Bar0). > > Signed-off-by: Jean Guyader <jean.guyader@xxxxxxxxxxxxx> > --- > hw/pt-graphics.c | 133 > ++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 133 insertions(+), 0 deletions(-) > inline patches please > diff --git a/hw/pt-graphics.c b/hw/pt-graphics.c > index 5d5e5da..7403abe 100644 > --- a/hw/pt-graphics.c > +++ b/hw/pt-graphics.c > @@ -13,6 +13,31 @@ > extern int gfx_passthru; > extern int igd_passthru; > > +#define IGFX_CANTIGA 0x10 > +#define IGFX_IRONLAKE 0x20 > +#define IGFX_IBEXPEAK 0x30 > +#define IGFX_COUGARPOINT 0x40 > + > +struct igfx_chip > +{ > + int chip; > + uint16_t device_id; > +}; > + > +struct igfx_chip igfx_chips[] = > +{ > + {IGFX_IRONLAKE, 0x0042}, > + {IGFX_IRONLAKE, 0x0046}, > + {IGFX_CANTIGA, 0x20e4}, > + {IGFX_CANTIGA, 0x2a42}, > + {IGFX_CANTIGA, 0x2e12}, > + {IGFX_COUGARPOINT, 0x0152}, > + {IGFX_COUGARPOINT, 0x0112}, > + {IGFX_COUGARPOINT, 0x0116}, > + {IGFX_COUGARPOINT, 0x0126}, > + {0, 0} > +}; > + > static int pch_map_irq(PCIDevice *pci_dev, int irq_num) > { > PT_LOG("pch_map_irq called\n"); > @@ -37,6 +62,98 @@ void intel_pch_init(PCIBus *bus) > pch_map_irq, "intel_bridge_1f"); > } > > +static int igd_get_chip(struct pt_dev *p) > +{ > + int i; > + int chip = 0; > + int devid = p->pci_dev->device_id; > + > + for (i = 0; igfx_chips[i].chip; i++) > + if (devid == igfx_chips[i].device_id) > + { > + chip = igfx_chips[i].chip; > + break; > + } > + > + if (!chip) > + { > + if (devid & 0x2000) > + chip = IGFX_CANTIGA; > + else if (devid & 0x100) > + chip = IGFX_COUGARPOINT; > + else > + chip = IGFX_IRONLAKE; > + PT_LOG("GUESS FOR CHIP 0x%04x as type %x", devid, chip); > + } > + return chip; > +} > + > + > +static uint32_t igd_mmio_read(struct pt_dev *p, uint32_t addr, uint8_t size) > +{ > + uint8_t *map = p->bases[0].map; > + uint32_t ret; > + > + switch (size) > + { > + case 1: > + ret = *(volatile uint8_t *)(map + addr); > + break; > + case 2: > + ret = *(volatile uint16_t *)(map + addr); > + break; > + case 4: > + ret = *(volatile uint32_t *)(map + addr); > + break; > + default: > + PT_LOG("igd_do_mmio: Unknown size %d\n", size); > + } > + return ret; > +} igd_mmio_read is currently unused > +static void igd_mmio_write(struct pt_dev *p, uint32_t addr, uint32_t val, > + uint8_t size) > +{ > + uint8_t *map = p->bases[0].map; > + > + switch (size) > + { > + case 1: > + *(volatile uint8_t *)(map + addr) = (uint8_t)val; > + break; > + case 2: > + *(volatile uint16_t *)(map + addr) = (uint16_t)val; > + break; > + case 4: > + *(volatile uint32_t *)(map + addr) = (uint32_t)val; > + break; > + default: > + PT_LOG("igd_do_mmio: Unknown size %d\n", size); > + } > +} > + > +static void igd_reset_fences(struct pt_dev *pt_dev) > +{ > + int i = 0; > + uint32_t fence_addr; > + > + switch (igd_get_chip(pt_dev)) > + { > + case IGFX_CANTIGA: > + case IGFX_IRONLAKE: > + case IGFX_IBEXPEAK: > + fence_addr = 0x3000; > + case IGFX_COUGARPOINT: > + fence_addr = 0x100000; > + } > + > + for (i = 0; i < 16; i++) > + { > + igd_mmio_write(pt_dev, fence_addr + (i << 4), 0, 4); > + igd_mmio_write(pt_dev, fence_addr + (i << 4) + 4, 0, 4); > + } > +} > + > void igd_pci_write(PCIDevice *pci_dev, uint32_t config_addr, uint32_t val, > int len) > { > struct pci_dev *pci_dev_host_bridge = pt_pci_get_dev(0, 0, 0); > @@ -98,6 +215,16 @@ uint32_t igd_pci_read(PCIDevice *pci_dev, uint32_t > config_addr, int len) > */ > void pt_graphic_bar_remap(struct pt_dev *real_device, int bar, int > first_map, int map) > { > + /* > + * Reset the fence register on the first remap > + * of Bar0 for a Intel GPU > + */ > + if (real_device->pci_dev->device_class == 0x0300 && > + real_device->pci_dev->device_id == PCI_VENDOR_ID_INTEL && > + bar == 0 && first_map && map == DPCI_ADD_MAPPING) > + { > + igd_reset_fences(real_device); > + } > } coding style, see http://git.savannah.gnu.org/cgit/qemu.git/tree/CODING_STYLE > /* > @@ -137,6 +264,12 @@ int register_vga_regions(struct pt_dev *real_device) > PT_LOG("register_vga: igd_opregion = %x\n", igd_opregion); > } > > + if (vendor_id == PCI_VENDOR_ID_INTEL) > + { > + if (pt_pci_host_map_bar(real_device, 0) != 0) > + PT_LOG("Can't map Intel Bar 0\n"); > + } How fatal is this error? Maybe we need to return an error from register_vga_regions and propagate it upward? _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |