]> git.proxmox.com Git - mirror_qemu.git/blob - hw/xen/xen_pt_graphics.c
xen, gfx passthrough: basic graphics passthrough support
[mirror_qemu.git] / hw / xen / xen_pt_graphics.c
1 /*
2 * graphics passthrough
3 */
4 #include "xen_pt.h"
5 #include "xen-host-pci-device.h"
6 #include "hw/xen/xen_backend.h"
7
8 typedef struct VGARegion {
9 int type; /* Memory or port I/O */
10 uint64_t guest_base_addr;
11 uint64_t machine_base_addr;
12 uint64_t size; /* size of the region */
13 int rc;
14 } VGARegion;
15
16 #define IORESOURCE_IO 0x00000100
17 #define IORESOURCE_MEM 0x00000200
18
19 static struct VGARegion vga_args[] = {
20 {
21 .type = IORESOURCE_IO,
22 .guest_base_addr = 0x3B0,
23 .machine_base_addr = 0x3B0,
24 .size = 0xC,
25 .rc = -1,
26 },
27 {
28 .type = IORESOURCE_IO,
29 .guest_base_addr = 0x3C0,
30 .machine_base_addr = 0x3C0,
31 .size = 0x20,
32 .rc = -1,
33 },
34 {
35 .type = IORESOURCE_MEM,
36 .guest_base_addr = 0xa0000 >> XC_PAGE_SHIFT,
37 .machine_base_addr = 0xa0000 >> XC_PAGE_SHIFT,
38 .size = 0x20,
39 .rc = -1,
40 },
41 };
42
43 /*
44 * register VGA resources for the domain with assigned gfx
45 */
46 int xen_pt_register_vga_regions(XenHostPCIDevice *dev)
47 {
48 int i = 0;
49
50 if (!is_igd_vga_passthrough(dev)) {
51 return 0;
52 }
53
54 for (i = 0 ; i < ARRAY_SIZE(vga_args); i++) {
55 if (vga_args[i].type == IORESOURCE_IO) {
56 vga_args[i].rc = xc_domain_ioport_mapping(xen_xc, xen_domid,
57 vga_args[i].guest_base_addr,
58 vga_args[i].machine_base_addr,
59 vga_args[i].size, DPCI_ADD_MAPPING);
60 } else {
61 vga_args[i].rc = xc_domain_memory_mapping(xen_xc, xen_domid,
62 vga_args[i].guest_base_addr,
63 vga_args[i].machine_base_addr,
64 vga_args[i].size, DPCI_ADD_MAPPING);
65 }
66
67 if (vga_args[i].rc) {
68 XEN_PT_ERR(NULL, "VGA %s mapping failed! (rc: %i)\n",
69 vga_args[i].type == IORESOURCE_IO ? "ioport" : "memory",
70 vga_args[i].rc);
71 return vga_args[i].rc;
72 }
73 }
74
75 return 0;
76 }
77
78 /*
79 * unregister VGA resources for the domain with assigned gfx
80 */
81 int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev)
82 {
83 int i = 0;
84
85 if (!is_igd_vga_passthrough(dev)) {
86 return 0;
87 }
88
89 for (i = 0 ; i < ARRAY_SIZE(vga_args); i++) {
90 if (vga_args[i].type == IORESOURCE_IO) {
91 vga_args[i].rc = xc_domain_ioport_mapping(xen_xc, xen_domid,
92 vga_args[i].guest_base_addr,
93 vga_args[i].machine_base_addr,
94 vga_args[i].size, DPCI_REMOVE_MAPPING);
95 } else {
96 vga_args[i].rc = xc_domain_memory_mapping(xen_xc, xen_domid,
97 vga_args[i].guest_base_addr,
98 vga_args[i].machine_base_addr,
99 vga_args[i].size, DPCI_REMOVE_MAPPING);
100 }
101
102 if (vga_args[i].rc) {
103 XEN_PT_ERR(NULL, "VGA %s unmapping failed! (rc: %i)\n",
104 vga_args[i].type == IORESOURCE_IO ? "ioport" : "memory",
105 vga_args[i].rc);
106 return vga_args[i].rc;
107 }
108 }
109
110 return 0;
111 }