]>
git.proxmox.com Git - mirror_qemu.git/blob - hw/xen/xen_pt_graphics.c
5 #include "xen-host-pci-device.h"
6 #include "hw/xen/xen_backend.h"
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 */
16 #define IORESOURCE_IO 0x00000100
17 #define IORESOURCE_MEM 0x00000200
19 static struct VGARegion vga_args
[] = {
21 .type
= IORESOURCE_IO
,
22 .guest_base_addr
= 0x3B0,
23 .machine_base_addr
= 0x3B0,
28 .type
= IORESOURCE_IO
,
29 .guest_base_addr
= 0x3C0,
30 .machine_base_addr
= 0x3C0,
35 .type
= IORESOURCE_MEM
,
36 .guest_base_addr
= 0xa0000 >> XC_PAGE_SHIFT
,
37 .machine_base_addr
= 0xa0000 >> XC_PAGE_SHIFT
,
44 * register VGA resources for the domain with assigned gfx
46 int xen_pt_register_vga_regions(XenHostPCIDevice
*dev
)
50 if (!is_igd_vga_passthrough(dev
)) {
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
);
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
);
68 XEN_PT_ERR(NULL
, "VGA %s mapping failed! (rc: %i)\n",
69 vga_args
[i
].type
== IORESOURCE_IO
? "ioport" : "memory",
71 return vga_args
[i
].rc
;
79 * unregister VGA resources for the domain with assigned gfx
81 int xen_pt_unregister_vga_regions(XenHostPCIDevice
*dev
)
85 if (!is_igd_vga_passthrough(dev
)) {
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
);
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
);
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",
106 return vga_args
[i
].rc
;
113 static void *get_vgabios(XenPCIPassthroughState
*s
, int *size
,
114 XenHostPCIDevice
*dev
)
116 return pci_assign_dev_load_option_rom(&s
->dev
, OBJECT(&s
->dev
), size
,
117 dev
->domain
, dev
->bus
,
118 dev
->dev
, dev
->func
);
121 /* Refer to Seabios. */
125 uint8_t initVector
[4];
126 uint8_t reserved
[17];
129 } __attribute__((packed
));
145 } __attribute__((packed
));
147 int xen_pt_setup_vga(XenPCIPassthroughState
*s
, XenHostPCIDevice
*dev
)
149 unsigned char *bios
= NULL
;
150 struct rom_header
*rom
;
155 struct pci_data
*pd
= NULL
;
157 if (!is_igd_vga_passthrough(dev
)) {
161 bios
= get_vgabios(s
, &bios_size
, dev
);
163 XEN_PT_ERR(&s
->dev
, "VGA: Can't getting VBIOS!\n");
167 /* Currently we fixed this address as a primary. */
168 rom
= (struct rom_header
*)bios
;
169 pd
= (void *)(bios
+ (unsigned char)rom
->pcioffset
);
171 /* We may need to fixup Device Identification. */
172 if (pd
->device
!= s
->real_device
.device_id
) {
173 pd
->device
= s
->real_device
.device_id
;
175 len
= rom
->size
* 512;
176 /* Then adjust the bios checksum */
177 for (c
= (char *)bios
; c
< ((char *)bios
+ len
); c
++) {
181 bios
[len
- 1] -= checksum
;
182 XEN_PT_LOG(&s
->dev
, "vga bios checksum is adjusted %x!\n",
187 /* Currently we fixed this address as a primary for legacy BIOS. */
188 cpu_physical_memory_rw(0xc0000, bios
, bios_size
, 1);