summaryrefslogtreecommitdiffstats
path: root/qemu/hw/xen/xen_pt_graphics.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/hw/xen/xen_pt_graphics.c')
-rw-r--r--qemu/hw/xen/xen_pt_graphics.c275
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));
-}