Patchwork [RfC] add secondary stdvga variant

login
register
mail settings
Submitter Gerd Hoffmann
Date Nov. 14, 2012, 10:36 a.m.
Message ID <1352889405-7643-1-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/198859/
State New
Headers show

Comments

Gerd Hoffmann - Nov. 14, 2012, 10:36 a.m.
Add a standard vga variant which doesn't occupy any legacy
ressources and thus can easily be used as secondary (or legacy-free)
graphics adapter.  Programming must be done using the MMIO bar.
---
 docs/specs/standard-vga.txt |   13 +++++++--
 hw/vga-pci.c                |   62 +++++++++++++++++++++++++++++++++++++++++++
 hw/vga.c                    |    4 +++
 3 files changed, 76 insertions(+), 3 deletions(-)

Patch

diff --git a/docs/specs/standard-vga.txt b/docs/specs/standard-vga.txt
index 8a4c1e9..f82773e 100644
--- a/docs/specs/standard-vga.txt
+++ b/docs/specs/standard-vga.txt
@@ -5,9 +5,10 @@  QEMU Standard VGA
 Exists in two variants, for isa and pci.
 
 command line switches:
-    -vga std            [ picks isa for -M isapc, otherwise pci ]
-    -device VGA         [ pci variant ]
-    -device isa-vga     [ isa variant ]
+    -vga std               [ picks isa for -M isapc, otherwise pci ]
+    -device VGA            [ pci variant ]
+    -device isa-vga        [ isa variant ]
+    -device secondary-vga  [ legacy-free pci variant ]
 
 
 PCI spec
@@ -31,9 +32,15 @@  PCI ROM Region:
    Holds the vgabios (qemu 0.14+).
 
 
+The legacy-free variant has no ROM and has PCI_CLASS_DISPLAY_OTHER
+instead of PCI_CLASS_DISPLAY_VGA.
+
+
 IO ports used
 -------------
 
+Doesn't apply to the legacy-free pci variant, use the MMIO bar instead.
+
 03c0 - 03df : standard vga ports
 01ce        : bochs vbe interface index port
 01cf        : bochs vbe interface data port (x86 only)
diff --git a/hw/vga-pci.c b/hw/vga-pci.c
index 947e35c..ed23454 100644
--- a/hw/vga-pci.c
+++ b/hw/vga-pci.c
@@ -179,12 +179,52 @@  static int pci_std_vga_initfn(PCIDevice *dev)
     return 0;
 }
 
+static int pci_secondary_vga_initfn(PCIDevice *dev)
+{
+    PCIVGAState *d = DO_UPCAST(PCIVGAState, dev, dev);
+    VGACommonState *s = &d->vga;
+
+    /* vga + console init */
+    vga_common_init(s);
+    s->ds = graphic_console_init(s->update, s->invalidate,
+                                 s->screen_dump, s->text_update, s);
+
+    /* mmio bar */
+    memory_region_init(&d->mmio, "vga.mmio", 4096);
+    memory_region_init_io(&d->ioport, &pci_vga_ioport_ops, d,
+                          "vga ioports remapped", PCI_VGA_IOPORT_SIZE);
+    memory_region_init_io(&d->bochs, &pci_vga_bochs_ops, d,
+                          "bochs dispi interface", PCI_VGA_BOCHS_SIZE);
+
+    memory_region_add_subregion(&d->mmio, PCI_VGA_IOPORT_OFFSET,
+                                &d->ioport);
+    memory_region_add_subregion(&d->mmio, PCI_VGA_BOCHS_OFFSET,
+                                &d->bochs);
+
+    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);
+
+    return 0;
+}
+
+static void pci_secondary_vga_reset(DeviceState *dev)
+{
+    PCIVGAState *d = DO_UPCAST(PCIVGAState, dev.qdev, dev);
+
+    vga_common_reset(&d->vga);
+}
+
 static Property vga_pci_properties[] = {
     DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
     DEFINE_PROP_BIT("mmio", PCIVGAState, flags, PCI_VGA_FLAG_ENABLE_MMIO, true),
     DEFINE_PROP_END_OF_LIST(),
 };
 
+static Property secondary_pci_properties[] = {
+    DEFINE_PROP_UINT32("vgamem_mb", PCIVGAState, vga.vram_size_mb, 16),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
 static void vga_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
@@ -200,6 +240,20 @@  static void vga_class_init(ObjectClass *klass, void *data)
     dc->props = vga_pci_properties;
 }
 
+static void secondary_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->init = pci_secondary_vga_initfn;
+    k->vendor_id = PCI_VENDOR_ID_QEMU;
+    k->device_id = PCI_DEVICE_ID_QEMU_VGA;
+    k->class_id = PCI_CLASS_DISPLAY_OTHER;
+    dc->vmsd = &vmstate_vga_pci;
+    dc->props = secondary_pci_properties;
+    dc->reset = pci_secondary_vga_reset;
+}
+
 static TypeInfo vga_info = {
     .name          = "VGA",
     .parent        = TYPE_PCI_DEVICE,
@@ -207,9 +261,17 @@  static TypeInfo vga_info = {
     .class_init    = vga_class_init,
 };
 
+static TypeInfo secondary_info = {
+    .name          = "secondary-vga",
+    .parent        = TYPE_PCI_DEVICE,
+    .instance_size = sizeof(PCIVGAState),
+    .class_init    = secondary_class_init,
+};
+
 static void vga_register_types(void)
 {
     type_register_static(&vga_info);
+    type_register_static(&secondary_info);
 }
 
 type_init(vga_register_types)
diff --git a/hw/vga.c b/hw/vga.c
index 2b0200a..b25a058 100644
--- a/hw/vga.c
+++ b/hw/vga.c
@@ -174,6 +174,10 @@  static void vga_update_memory_access(VGACommonState *s)
     MemoryRegion *region, *old_region = s->chain4_alias;
     hwaddr base, offset, size;
 
+    if (s->legacy_address_space == NULL) {
+        return;
+    }
+
     s->chain4_alias = NULL;
 
     if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) ==