qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH 9/9] virtio-vga: make compatible with stdvga


From: Gerd Hoffmann
Subject: [Qemu-devel] [PATCH 9/9] virtio-vga: make compatible with stdvga
Date: Fri, 10 Apr 2015 14:31:51 +0200

Arrange things in a way that virtio-vga is both a virtio-1.0 device
(acting like virtio-gpu-pci in virtio mode) and fully compatible with
stdvga (in vga mode, i.e. when virtio is not enabled).

PCI bar #0 is identical for both stdvga and virtio-vga.
PCI bar #1 is msi-x for virtio-vga and unused for stdvga,
PCI bar #2 is the mmio area, looks like this for virtio-vga:

  00000000fe800000-00000000fe87ffff (prio 1, RW): virtio-pci
    00000000fe800400-00000000fe80041f (prio 0, RW): vga ioports remapped
    00000000fe800500-00000000fe800515 (prio 0, RW): bochs dispi interface
    00000000fe800600-00000000fe800607 (prio 0, RW): qemu extended regs
    00000000fe83d000-00000000fe83dfff (prio 0, RW): virtio-pci-common
    00000000fe83e000-00000000fe83efff (prio 0, RW): virtio-pci-isr
    00000000fe83f000-00000000fe83ffff (prio 0, RW): virtio-pci-device
    00000000fe840000-00000000fe87ffff (prio 0, RW): virtio-pci-notify

PCI bar #2 for stdvga looks this way:

  00000000febf0000-00000000febf0fff (prio 1, RW): vga.mmio
    00000000febf0400-00000000febf041f (prio 0, RW): vga ioports remapped
    00000000febf0500-00000000febf0515 (prio 0, RW): bochs dispi interface
    00000000febf0600-00000000febf0607 (prio 0, RW): qemu extended regs

i.e. it is smaller, lacks the virtio subregions, and seabios picks a
different place because of the size difference.  But otherwise the mmio
bar is identical.

Signed-off-by: Gerd Hoffmann <address@hidden>
---
 hw/display/vga-pci.c    |  8 ++++----
 hw/display/vga_int.h    |  6 ++++++
 hw/display/virtio-vga.c | 20 +++++++++++++++++++-
 3 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
index bfe58c7..09e4faa 100644
--- a/hw/display/vga-pci.c
+++ b/hw/display/vga-pci.c
@@ -201,10 +201,10 @@ static const MemoryRegionOps pci_vga_qext_ops = {
     .endianness = DEVICE_LITTLE_ENDIAN,
 };
 
-static void pci_std_vga_mmio_region_init(VGACommonState *s,
-                                         MemoryRegion *parent,
-                                         MemoryRegion *subs,
-                                         bool qext)
+void pci_std_vga_mmio_region_init(VGACommonState *s,
+                                  MemoryRegion *parent,
+                                  MemoryRegion *subs,
+                                  bool qext)
 {
     memory_region_init_io(&subs[0], NULL, &pci_vga_ioport_ops, s,
                           "vga ioports remapped", PCI_VGA_IOPORT_SIZE);
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index 7ca2ad2..141ff30 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -221,4 +221,10 @@ extern const uint8_t gr_mask[16];
 
 extern const MemoryRegionOps vga_mem_ops;
 
+/* vga-pci.c */
+void pci_std_vga_mmio_region_init(VGACommonState *s,
+                                  MemoryRegion *parent,
+                                  MemoryRegion *subs,
+                                  bool qext);
+
 #endif
diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
index ded28c1..4b76e26 100644
--- a/hw/display/virtio-vga.c
+++ b/hw/display/virtio-vga.c
@@ -15,6 +15,7 @@ typedef struct VirtIOVGA {
     VirtIOPCIProxy parent_obj;
     VirtIOGPU      vdev;
     VGACommonState vga;
+    MemoryRegion   vga_mrs[3];
     uint32_t       dummy;
 } VirtIOVGA;
 
@@ -78,15 +79,28 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, 
Error **errp)
     VirtIOVGA *vvga = VIRTIO_VGA(vpci_dev);
     VirtIOGPU *g = &vvga->vdev;
     VGACommonState *vga = &vvga->vga;
+    uint32_t offset;
 
     /* init vga compat bits */
     vga->vram_size_mb = 8;
     vga_common_init(vga, OBJECT(vpci_dev), false);
     vga_init(vga, OBJECT(vpci_dev), pci_address_space(&vpci_dev->pci_dev),
              pci_address_space_io(&vpci_dev->pci_dev), true);
-    pci_register_bar(&vpci_dev->pci_dev, 2,
+    pci_register_bar(&vpci_dev->pci_dev, 0,
                      PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram);
 
+    /* configure virtio bar and regions */
+    vpci_dev->modern_mem_bar = 2;
+    offset = memory_region_size(&vpci_dev->modern_bar);
+    offset -= memory_region_size(&vpci_dev->notify.mr);
+    vpci_dev->notify.offset = offset;
+    offset -= memory_region_size(&vpci_dev->device.mr);
+    vpci_dev->device.offset = offset;
+    offset -= memory_region_size(&vpci_dev->isr.mr);
+    vpci_dev->isr.offset = offset;
+    offset -= memory_region_size(&vpci_dev->common.mr);
+    vpci_dev->common.offset = offset;
+
     /* init virtio bits */
     qdev_set_parent_bus(DEVICE(g), BUS(&vpci_dev->bus));
     /* force virtio-1.0 */
@@ -94,6 +108,10 @@ static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, 
Error **errp)
     vpci_dev->flags |= VIRTIO_PCI_FLAG_DISABLE_LEGACY;
     object_property_set_bool(OBJECT(g), true, "realized", errp);
 
+    /* add stdvga mmio regions */
+    pci_std_vga_mmio_region_init(vga, &vpci_dev->modern_bar,
+                                 vvga->vga_mrs, true);
+
     vga->con = g->scanout[0].con;
     graphic_console_set_hwops(vga->con, &virtio_vga_ops, vvga);
 }
-- 
1.8.3.1




reply via email to

[Prev in Thread] Current Thread [Next in Thread]