diff options
Diffstat (limited to 'qemu/hw/xen/xen_pt_graphics.c')
-rw-r--r-- | qemu/hw/xen/xen_pt_graphics.c | 275 |
1 files changed, 0 insertions, 275 deletions
diff --git a/qemu/hw/xen/xen_pt_graphics.c b/qemu/hw/xen/xen_pt_graphics.c deleted file mode 100644 index 0f4c8d77e..000000000 --- a/qemu/hw/xen/xen_pt_graphics.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * graphics passthrough - */ -#include "qemu/osdep.h" -#include "qapi/error.h" -#include "xen_pt.h" -#include "xen-host-pci-device.h" -#include "hw/xen/xen_backend.h" - -static unsigned long igd_guest_opregion; -static unsigned long igd_host_opregion; - -#define XEN_PCI_INTEL_OPREGION_MASK 0xfff - -typedef struct VGARegion { - int type; /* Memory or port I/O */ - uint64_t guest_base_addr; - uint64_t machine_base_addr; - uint64_t size; /* size of the region */ - int rc; -} VGARegion; - -#define IORESOURCE_IO 0x00000100 -#define IORESOURCE_MEM 0x00000200 - -static struct VGARegion vga_args[] = { - { - .type = IORESOURCE_IO, - .guest_base_addr = 0x3B0, - .machine_base_addr = 0x3B0, - .size = 0xC, - .rc = -1, - }, - { - .type = IORESOURCE_IO, - .guest_base_addr = 0x3C0, - .machine_base_addr = 0x3C0, - .size = 0x20, - .rc = -1, - }, - { - .type = IORESOURCE_MEM, - .guest_base_addr = 0xa0000 >> XC_PAGE_SHIFT, - .machine_base_addr = 0xa0000 >> XC_PAGE_SHIFT, - .size = 0x20, - .rc = -1, - }, -}; - -/* - * register VGA resources for the domain with assigned gfx - */ -int xen_pt_register_vga_regions(XenHostPCIDevice *dev) -{ - int i = 0; - - if (!is_igd_vga_passthrough(dev)) { - return 0; - } - - for (i = 0 ; i < ARRAY_SIZE(vga_args); i++) { - if (vga_args[i].type == IORESOURCE_IO) { - vga_args[i].rc = xc_domain_ioport_mapping(xen_xc, xen_domid, - vga_args[i].guest_base_addr, - vga_args[i].machine_base_addr, - vga_args[i].size, DPCI_ADD_MAPPING); - } else { - vga_args[i].rc = xc_domain_memory_mapping(xen_xc, xen_domid, - vga_args[i].guest_base_addr, - vga_args[i].machine_base_addr, - vga_args[i].size, DPCI_ADD_MAPPING); - } - - if (vga_args[i].rc) { - XEN_PT_ERR(NULL, "VGA %s mapping failed! (rc: %i)\n", - vga_args[i].type == IORESOURCE_IO ? "ioport" : "memory", - vga_args[i].rc); - return vga_args[i].rc; - } - } - - return 0; -} - -/* - * unregister VGA resources for the domain with assigned gfx - */ -int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev) -{ - int i = 0; - int ret = 0; - - if (!is_igd_vga_passthrough(dev)) { - return 0; - } - - for (i = 0 ; i < ARRAY_SIZE(vga_args); i++) { - if (vga_args[i].type == IORESOURCE_IO) { - vga_args[i].rc = xc_domain_ioport_mapping(xen_xc, xen_domid, - vga_args[i].guest_base_addr, - vga_args[i].machine_base_addr, - vga_args[i].size, DPCI_REMOVE_MAPPING); - } else { - vga_args[i].rc = xc_domain_memory_mapping(xen_xc, xen_domid, - vga_args[i].guest_base_addr, - vga_args[i].machine_base_addr, - vga_args[i].size, DPCI_REMOVE_MAPPING); - } - - if (vga_args[i].rc) { - XEN_PT_ERR(NULL, "VGA %s unmapping failed! (rc: %i)\n", - vga_args[i].type == IORESOURCE_IO ? "ioport" : "memory", - vga_args[i].rc); - return vga_args[i].rc; - } - } - - if (igd_guest_opregion) { - ret = xc_domain_memory_mapping(xen_xc, xen_domid, - (unsigned long)(igd_guest_opregion >> XC_PAGE_SHIFT), - (unsigned long)(igd_host_opregion >> XC_PAGE_SHIFT), - 3, - DPCI_REMOVE_MAPPING); - if (ret) { - return ret; - } - } - - return 0; -} - -static void *get_vgabios(XenPCIPassthroughState *s, int *size, - XenHostPCIDevice *dev) -{ - return pci_assign_dev_load_option_rom(&s->dev, OBJECT(&s->dev), size, - dev->domain, dev->bus, - dev->dev, dev->func); -} - -/* Refer to Seabios. */ -struct rom_header { - uint16_t signature; - uint8_t size; - uint8_t initVector[4]; - uint8_t reserved[17]; - uint16_t pcioffset; - uint16_t pnpoffset; -} __attribute__((packed)); - -struct pci_data { - uint32_t signature; - uint16_t vendor; - uint16_t device; - uint16_t vitaldata; - uint16_t dlen; - uint8_t drevision; - uint8_t class_lo; - uint16_t class_hi; - uint16_t ilen; - uint16_t irevision; - uint8_t type; - uint8_t indicator; - uint16_t reserved; -} __attribute__((packed)); - -void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev, - Error **errp) -{ - unsigned char *bios = NULL; - struct rom_header *rom; - int bios_size; - char *c = NULL; - char checksum = 0; - uint32_t len = 0; - struct pci_data *pd = NULL; - - if (!is_igd_vga_passthrough(dev)) { - error_setg(errp, "Need to enable igd-passthrough"); - return; - } - - bios = get_vgabios(s, &bios_size, dev); - if (!bios) { - error_setg(errp, "VGA: Can't get VBIOS"); - return; - } - - /* Currently we fixed this address as a primary. */ - rom = (struct rom_header *)bios; - pd = (void *)(bios + (unsigned char)rom->pcioffset); - - /* We may need to fixup Device Identification. */ - if (pd->device != s->real_device.device_id) { - pd->device = s->real_device.device_id; - - len = rom->size * 512; - /* Then adjust the bios checksum */ - for (c = (char *)bios; c < ((char *)bios + len); c++) { - checksum += *c; - } - if (checksum) { - bios[len - 1] -= checksum; - XEN_PT_LOG(&s->dev, "vga bios checksum is adjusted %x!\n", - checksum); - } - } - - /* Currently we fixed this address as a primary for legacy BIOS. */ - cpu_physical_memory_rw(0xc0000, bios, bios_size, 1); -} - -uint32_t igd_read_opregion(XenPCIPassthroughState *s) -{ - uint32_t val = 0; - - if (!igd_guest_opregion) { - return val; - } - - val = igd_guest_opregion; - - XEN_PT_LOG(&s->dev, "Read opregion val=%x\n", val); - return val; -} - -#define XEN_PCI_INTEL_OPREGION_PAGES 0x3 -#define XEN_PCI_INTEL_OPREGION_ENABLE_ACCESSED 0x1 -void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val) -{ - int ret; - - if (igd_guest_opregion) { - XEN_PT_LOG(&s->dev, "opregion register already been set, ignoring %x\n", - val); - return; - } - - /* We just work with LE. */ - xen_host_pci_get_block(&s->real_device, XEN_PCI_INTEL_OPREGION, - (uint8_t *)&igd_host_opregion, 4); - igd_guest_opregion = (unsigned long)(val & ~XEN_PCI_INTEL_OPREGION_MASK) - | (igd_host_opregion & XEN_PCI_INTEL_OPREGION_MASK); - - ret = xc_domain_iomem_permission(xen_xc, xen_domid, - (unsigned long)(igd_host_opregion >> XC_PAGE_SHIFT), - XEN_PCI_INTEL_OPREGION_PAGES, - XEN_PCI_INTEL_OPREGION_ENABLE_ACCESSED); - - if (ret) { - XEN_PT_ERR(&s->dev, "[%d]:Can't enable to access IGD host opregion:" - " 0x%lx.\n", ret, - (unsigned long)(igd_host_opregion >> XC_PAGE_SHIFT)), - igd_guest_opregion = 0; - return; - } - - ret = xc_domain_memory_mapping(xen_xc, xen_domid, - (unsigned long)(igd_guest_opregion >> XC_PAGE_SHIFT), - (unsigned long)(igd_host_opregion >> XC_PAGE_SHIFT), - XEN_PCI_INTEL_OPREGION_PAGES, - DPCI_ADD_MAPPING); - - if (ret) { - XEN_PT_ERR(&s->dev, "[%d]:Can't map IGD host opregion:0x%lx to" - " guest opregion:0x%lx.\n", ret, - (unsigned long)(igd_host_opregion >> XC_PAGE_SHIFT), - (unsigned long)(igd_guest_opregion >> XC_PAGE_SHIFT)); - igd_guest_opregion = 0; - return; - } - - XEN_PT_LOG(&s->dev, "Map OpRegion: 0x%lx -> 0x%lx\n", - (unsigned long)(igd_host_opregion >> XC_PAGE_SHIFT), - (unsigned long)(igd_guest_opregion >> XC_PAGE_SHIFT)); -} |