]> git.proxmox.com Git - mirror_qemu.git/commitdiff
display/stdvga: add edid support.
authorGerd Hoffmann <kraxel@redhat.com>
Tue, 25 Sep 2018 07:56:46 +0000 (09:56 +0200)
committerGerd Hoffmann <kraxel@redhat.com>
Thu, 27 Sep 2018 06:07:51 +0000 (08:07 +0200)
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

docs/specs/standard-vga.txt
hw/display/vga-pci.c
hw/display/vga_int.h
hw/display/virtio-vga.c

index 19d2a7450904108a6443c0e43aefa7b5be8ef8de..18f75f1b302a6ad206ab081643a0ad15b1ed0294 100644 (file)
@@ -61,7 +61,7 @@ MMIO area spec
 
 Likewise applies to the pci variant only for obvious reasons.
 
-0000 - 03ff : reserved, for possible virtio extension.
+0000 - 03ff : edid data blob.
 0400 - 041f : vga ioports (0x3c0 -> 0x3df), remapped 1:1.
               word access is supported, bytes are written
               in little endia order (aka index port first),
index e9e62eac704fbc687dde19c93236911b6b70744d..24ca1b3e1fddc0e9ca131a4175586a06bde38331 100644 (file)
 #include "ui/pixel_ops.h"
 #include "qemu/timer.h"
 #include "hw/loader.h"
+#include "hw/display/edid.h"
 
 enum vga_pci_flags {
     PCI_VGA_FLAG_ENABLE_MMIO = 1,
     PCI_VGA_FLAG_ENABLE_QEXT = 2,
+    PCI_VGA_FLAG_ENABLE_EDID = 3,
 };
 
 typedef struct PCIVGAState {
     PCIDevice dev;
     VGACommonState vga;
     uint32_t flags;
+    qemu_edid_info edid_info;
     MemoryRegion mmio;
-    MemoryRegion mrs[3];
+    MemoryRegion mrs[4];
+    uint8_t edid[256];
 } PCIVGAState;
 
 #define TYPE_PCI_VGA "pci-vga"
@@ -195,8 +199,10 @@ void pci_std_vga_mmio_region_init(VGACommonState *s,
                                   Object *owner,
                                   MemoryRegion *parent,
                                   MemoryRegion *subs,
-                                  bool qext)
+                                  bool qext, bool edid)
 {
+    PCIVGAState *d = container_of(s, PCIVGAState, vga);
+
     memory_region_init_io(&subs[0], owner, &pci_vga_ioport_ops, s,
                           "vga ioports remapped", PCI_VGA_IOPORT_SIZE);
     memory_region_add_subregion(parent, PCI_VGA_IOPORT_OFFSET,
@@ -213,6 +219,12 @@ void pci_std_vga_mmio_region_init(VGACommonState *s,
         memory_region_add_subregion(parent, PCI_VGA_QEXT_OFFSET,
                                     &subs[2]);
     }
+
+    if (edid) {
+        qemu_edid_generate(d->edid, sizeof(d->edid), &d->edid_info);
+        qemu_edid_region_io(&subs[3], owner, d->edid, sizeof(d->edid));
+        memory_region_add_subregion(parent, 0, &subs[3]);
+    }
 }
 
 static void pci_std_vga_realize(PCIDevice *dev, Error **errp)
@@ -220,6 +232,7 @@ static void pci_std_vga_realize(PCIDevice *dev, Error **errp)
     PCIVGAState *d = PCI_VGA(dev);
     VGACommonState *s = &d->vga;
     bool qext = false;
+    bool edid = false;
 
     /* vga + console init */
     vga_common_init(s, OBJECT(dev));
@@ -240,7 +253,11 @@ static void pci_std_vga_realize(PCIDevice *dev, Error **errp)
             qext = true;
             pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2);
         }
-        pci_std_vga_mmio_region_init(s, OBJECT(dev), &d->mmio, d->mrs, qext);
+        if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_EDID)) {
+            edid = true;
+        }
+        pci_std_vga_mmio_region_init(s, OBJECT(dev), &d->mmio, d->mrs,
+                                     qext, edid);
 
         pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
     }
@@ -263,6 +280,7 @@ static void pci_secondary_vga_realize(PCIDevice *dev, Error **errp)
     PCIVGAState *d = PCI_VGA(dev);
     VGACommonState *s = &d->vga;
     bool qext = false;
+    bool edid = false;
 
     /* vga + console init */
     vga_common_init(s, OBJECT(dev));
@@ -276,7 +294,10 @@ static void pci_secondary_vga_realize(PCIDevice *dev, Error **errp)
         qext = true;
         pci_set_byte(&d->dev.config[PCI_REVISION_ID], 2);
     }
-    pci_std_vga_mmio_region_init(s, OBJECT(dev), &d->mmio, d->mrs, qext);
+    if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_EDID)) {
+        edid = true;
+    }
+    pci_std_vga_mmio_region_init(s, OBJECT(dev), &d->mmio, d->mrs, qext, edid);
 
     pci_register_bar(&d->dev, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
     pci_register_bar(&d->dev, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &d->mmio);
@@ -308,6 +329,9 @@ static Property vga_pci_properties[] = {
     DEFINE_PROP_BIT("mmio", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_MMIO, true),
     DEFINE_PROP_BIT("qemu-extended-regs",
                     PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, true),
+    DEFINE_PROP_BIT("edid",
+                    PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_EDID, false),
+    DEFINE_EDID_PROPERTIES(PCIVGAState, edid_info),
     DEFINE_PROP_BOOL("global-vmstate", PCIVGAState, vga.global_vmstate, false),
     DEFINE_PROP_END_OF_LIST(),
 };
@@ -316,6 +340,9 @@ static Property secondary_pci_properties[] = {
     DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
     DEFINE_PROP_BIT("qemu-extended-regs",
                     PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_QEXT, true),
+    DEFINE_PROP_BIT("edid",
+                    PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_EDID, false),
+    DEFINE_EDID_PROPERTIES(PCIVGAState, edid_info),
     DEFINE_PROP_END_OF_LIST(),
 };
 
index 339661bc0137fa5da2260a6733de980d32fc11ae..6e4fa48a79b73ae560214517ae5328b2890e5682 100644 (file)
@@ -197,6 +197,6 @@ void pci_std_vga_mmio_region_init(VGACommonState *s,
                                   Object *owner,
                                   MemoryRegion *parent,
                                   MemoryRegion *subs,
-                                  bool qext);
+                                  bool qext, bool edid);
 
 #endif
index 1e601c1a3bf6a9bc73ed3c80a10fab65af8e7fba..ab2e369b2867770897b7e16be65b6572afee403d 100644 (file)
@@ -153,7 +153,7 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
 
     /* add stdvga mmio regions */
     pci_std_vga_mmio_region_init(vga, OBJECT(vvga), &vpci_dev->modern_bar,
-                                 vvga->vga_mrs, true);
+                                 vvga->vga_mrs, true, false);
 
     vga->con = g->scanout[0].con;
     graphic_console_set_hwops(vga->con, &virtio_vga_ops, vvga);