qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

display/stdvga: add edid support.

This patch adds edid support to the qemu stdvga. It is turned off by
default and can be enabled with the new edid property. The patch also
adds xres and yres properties to specify the video mode you want the
guest use. Works only with edid enabled and updated guest driver.

The mmio bar of the stdvga has some unused address space at the start.
It was reserved just in case it'll be needed for virtio, but it turned
out to not be needed for that. So let's use that region to place the
EDID data block there.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20180925075646.25114-6-kraxel@redhat.com

+34 -7
+1 -1
docs/specs/standard-vga.txt
··· 61 61 62 62 Likewise applies to the pci variant only for obvious reasons. 63 63 64 - 0000 - 03ff : reserved, for possible virtio extension. 64 + 0000 - 03ff : edid data blob. 65 65 0400 - 041f : vga ioports (0x3c0 -> 0x3df), remapped 1:1. 66 66 word access is supported, bytes are written 67 67 in little endia order (aka index port first),
+31 -4
hw/display/vga-pci.c
··· 30 30 #include "ui/pixel_ops.h" 31 31 #include "qemu/timer.h" 32 32 #include "hw/loader.h" 33 + #include "hw/display/edid.h" 33 34 34 35 enum vga_pci_flags { 35 36 PCI_VGA_FLAG_ENABLE_MMIO = 1, 36 37 PCI_VGA_FLAG_ENABLE_QEXT = 2, 38 + PCI_VGA_FLAG_ENABLE_EDID = 3, 37 39 }; 38 40 39 41 typedef struct PCIVGAState { 40 42 PCIDevice dev; 41 43 VGACommonState vga; 42 44 uint32_t flags; 45 + qemu_edid_info edid_info; 43 46 MemoryRegion mmio; 44 - MemoryRegion mrs[3]; 47 + MemoryRegion mrs[4]; 48 + uint8_t edid[256]; 45 49 } PCIVGAState; 46 50 47 51 #define TYPE_PCI_VGA "pci-vga" ··· 195 199 Object *owner, 196 200 MemoryRegion *parent, 197 201 MemoryRegion *subs, 198 - bool qext) 202 + bool qext, bool edid) 199 203 { 204 + PCIVGAState *d = container_of(s, PCIVGAState, vga); 205 + 200 206 memory_region_init_io(&subs[0], owner, &pci_vga_ioport_ops, s, 201 207 "vga ioports remapped", PCI_VGA_IOPORT_SIZE); 202 208 memory_region_add_subregion(parent, PCI_VGA_IOPORT_OFFSET, ··· 213 219 memory_region_add_subregion(parent, PCI_VGA_QEXT_OFFSET, 214 220 &subs[2]); 215 221 } 222 + 223 + if (edid) { 224 + qemu_edid_generate(d->edid, sizeof(d->edid), &d->edid_info); 225 + qemu_edid_region_io(&subs[3], owner, d->edid, sizeof(d->edid)); 226 + memory_region_add_subregion(parent, 0, &subs[3]); 227 + } 216 228 } 217 229 218 230 static void pci_std_vga_realize(PCIDevice *dev, Error **errp) ··· 220 232 PCIVGAState *d = PCI_VGA(dev); 221 233 VGACommonState *s = &d->vga; 222 234 bool qext = false; 235 + bool edid = false; 223 236 224 237 /* vga + console init */ 225 238 vga_common_init(s, OBJECT(dev)); ··· 240 253 qext = true; 241 254 pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2); 242 255 } 243 - pci_std_vga_mmio_region_init(s, OBJECT(dev), &d->mmio, d->mrs, qext); 256 + if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_EDID)) { 257 + edid = true; 258 + } 259 + pci_std_vga_mmio_region_init(s, OBJECT(dev), &d->mmio, d->mrs, 260 + qext, edid); 244 261 245 262 pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); 246 263 } ··· 263 280 PCIVGAState *d = PCI_VGA(dev); 264 281 VGACommonState *s = &d->vga; 265 282 bool qext = false; 283 + bool edid = false; 266 284 267 285 /* vga + console init */ 268 286 vga_common_init(s, OBJECT(dev)); ··· 276 294 qext = true; 277 295 pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2); 278 296 } 279 - pci_std_vga_mmio_region_init(s, OBJECT(dev), &d->mmio, d->mrs, qext); 297 + if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_EDID)) { 298 + edid = true; 299 + } 300 + pci_std_vga_mmio_region_init(s, OBJECT(dev), &d->mmio, d->mrs, qext, edid); 280 301 281 302 pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram); 282 303 pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio); ··· 308 329 DEFINE_PROP_BIT("mmio", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_MMIO, true), 309 330 DEFINE_PROP_BIT("qemu-extended-regs", 310 331 PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, true), 332 + DEFINE_PROP_BIT("edid", 333 + PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_EDID, false), 334 + DEFINE_EDID_PROPERTIES(PCIVGAState, edid_info), 311 335 DEFINE_PROP_BOOL("global-vmstate", PCIVGAState, vga.global_vmstate, false), 312 336 DEFINE_PROP_END_OF_LIST(), 313 337 }; ··· 316 340 DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16), 317 341 DEFINE_PROP_BIT("qemu-extended-regs", 318 342 PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, true), 343 + DEFINE_PROP_BIT("edid", 344 + PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_EDID, false), 345 + DEFINE_EDID_PROPERTIES(PCIVGAState, edid_info), 319 346 DEFINE_PROP_END_OF_LIST(), 320 347 }; 321 348
+1 -1
hw/display/vga_int.h
··· 197 197 Object *owner, 198 198 MemoryRegion *parent, 199 199 MemoryRegion *subs, 200 - bool qext); 200 + bool qext, bool edid); 201 201 202 202 #endif
+1 -1
hw/display/virtio-vga.c
··· 153 153 154 154 /* add stdvga mmio regions */ 155 155 pci_std_vga_mmio_region_init(vga, OBJECT(vvga), &vpci_dev->modern_bar, 156 - vvga->vga_mrs, true); 156 + vvga->vga_mrs, true, false); 157 157 158 158 vga->con = g->scanout[0].con; 159 159 graphic_console_set_hwops(vga->con, &virtio_vga_ops, vvga);