All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PULL 0/7] Vga 20180524 patches
@ 2018-05-24 15:45 Gerd Hoffmann
  2018-05-24 15:45 ` [Qemu-devel] [PULL 1/7] vga: catch depth 0 Gerd Hoffmann
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-05-24 15:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

The following changes since commit 4f50c1673a89b07f376ce5c42d22d79a79cd466d:

  Merge remote-tracking branch 'remotes/ehabkost/tags/x86-next-pull-request' into staging (2018-05-22 09:43:58 +0100)

are available in the git repository at:

  git://git.kraxel.org/qemu tags/vga-20180524-pull-request

for you to fetch changes up to dbb2e4726c76dbffb39efe6623bf75d2ec1db8bc:

  MAINTAINERS: add vga entries (2018-05-24 10:42:13 +0200)

----------------------------------------------------------------
vga: catch depth 0
hw/display: add new bochs-display device
some cleanups.

----------------------------------------------------------------

Gerd Hoffmann (7):
  vga: catch depth 0
  vga: move bochs vbe defines to header file
  vga-pci: use PCI_VGA_MMIO_SIZE
  hw/display: add new bochs-display device
  bochs-display: add dirty tracking support
  bochs-display: add pcie support
  MAINTAINERS: add vga entries

 hw/display/vga_int.h           |  35 +---
 include/hw/display/bochs-vbe.h |  69 ++++++++
 hw/display/bochs-display.c     | 363 +++++++++++++++++++++++++++++++++++++++++
 hw/display/vga-pci.c           |  19 +--
 hw/display/vga.c               |  23 ++-
 MAINTAINERS                    |  21 +++
 hw/display/Makefile.objs       |   1 +
 7 files changed, 478 insertions(+), 53 deletions(-)
 create mode 100644 include/hw/display/bochs-vbe.h
 create mode 100644 hw/display/bochs-display.c

-- 
2.9.3

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 1/7] vga: catch depth 0
  2018-05-24 15:45 [Qemu-devel] [PULL 0/7] Vga 20180524 patches Gerd Hoffmann
@ 2018-05-24 15:45 ` Gerd Hoffmann
  2018-05-24 15:45 ` [Qemu-devel] [PULL 2/7] vga: move bochs vbe defines to header file Gerd Hoffmann
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-05-24 15:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

depth == 0 is used to indicate 256 color modes.  Our region calculation
goes wrong in that case.  So detect that and just take the safe code
path we already have for the wraparound case.

While being at it also catch depth == 15 (where our region size
calculation goes wrong too).  And make the comment more verbose,
explaining what is going on here.

Without this windows guest install might trigger an assert due to trying
to check dirty bitmap outside the snapshot region.

Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1575541
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20180514103117.21059-1-kraxel@redhat.com
---
 hw/display/vga.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/hw/display/vga.c b/hw/display/vga.c
index 72181330b8..a7794f6d1f 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -1480,13 +1480,28 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
 
     s->get_resolution(s, &width, &height);
     disp_width = width;
+    depth = s->get_bpp(s);
 
     region_start = (s->start_addr * 4);
     region_end = region_start + (ram_addr_t)s->line_offset * height;
-    region_end += width * s->get_bpp(s) / 8; /* scanline length */
+    region_end += width * depth / 8; /* scanline length */
     region_end -= s->line_offset;
-    if (region_end > s->vbe_size) {
-        /* wraps around (can happen with cirrus vbe modes) */
+    if (region_end > s->vbe_size || depth == 0 || depth == 15) {
+        /*
+         * We land here on:
+         *  - wraps around (can happen with cirrus vbe modes)
+         *  - depth == 0 (256 color palette video mode)
+         *  - depth == 15
+         *
+         * Take the safe and slow route:
+         *   - create a dirty bitmap snapshot for all vga memory.
+         *   - force shadowing (so all vga memory access goes
+         *     through vga_read_*() helpers).
+         *
+         * Given this affects only vga features which are pretty much
+         * unused by modern guests there should be no performance
+         * impact.
+         */
         region_start = 0;
         region_end = s->vbe_size;
         force_shadow = true;
@@ -1520,8 +1535,6 @@ static void vga_draw_graphic(VGACommonState *s, int full_update)
         }
     }
 
-    depth = s->get_bpp(s);
-
     /*
      * Check whether we can share the surface with the backend
      * or whether we need a shadow surface. We share native
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 2/7] vga: move bochs vbe defines to header file
  2018-05-24 15:45 [Qemu-devel] [PULL 0/7] Vga 20180524 patches Gerd Hoffmann
  2018-05-24 15:45 ` [Qemu-devel] [PULL 1/7] vga: catch depth 0 Gerd Hoffmann
@ 2018-05-24 15:45 ` Gerd Hoffmann
  2018-05-24 15:45 ` [Qemu-devel] [PULL 3/7] vga-pci: use PCI_VGA_MMIO_SIZE Gerd Hoffmann
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-05-24 15:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Create a new header file, move the bochs vbe dispi interface
defines to it, so they can be used outside vga code.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20180522165058.15404-2-kraxel@redhat.com
---
 hw/display/vga_int.h           | 35 ++-------------------
 include/hw/display/bochs-vbe.h | 69 ++++++++++++++++++++++++++++++++++++++++++
 hw/display/vga-pci.c           | 13 --------
 3 files changed, 71 insertions(+), 46 deletions(-)
 create mode 100644 include/hw/display/bochs-vbe.h

diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index fe23b81442..313cff84fc 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -29,42 +29,11 @@
 #include "exec/memory.h"
 #include "ui/console.h"
 
+#include "hw/display/bochs-vbe.h"
+
 #define ST01_V_RETRACE      0x08
 #define ST01_DISP_ENABLE    0x01
 
-#define VBE_DISPI_MAX_XRES              16000
-#define VBE_DISPI_MAX_YRES              12000
-#define VBE_DISPI_MAX_BPP               32
-
-#define VBE_DISPI_INDEX_ID              0x0
-#define VBE_DISPI_INDEX_XRES            0x1
-#define VBE_DISPI_INDEX_YRES            0x2
-#define VBE_DISPI_INDEX_BPP             0x3
-#define VBE_DISPI_INDEX_ENABLE          0x4
-#define VBE_DISPI_INDEX_BANK            0x5
-#define VBE_DISPI_INDEX_VIRT_WIDTH      0x6
-#define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
-#define VBE_DISPI_INDEX_X_OFFSET        0x8
-#define VBE_DISPI_INDEX_Y_OFFSET        0x9
-#define VBE_DISPI_INDEX_NB              0xa /* size of vbe_regs[] */
-#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa /* read-only, not in vbe_regs */
-
-#define VBE_DISPI_ID0                   0xB0C0
-#define VBE_DISPI_ID1                   0xB0C1
-#define VBE_DISPI_ID2                   0xB0C2
-#define VBE_DISPI_ID3                   0xB0C3
-#define VBE_DISPI_ID4                   0xB0C4
-#define VBE_DISPI_ID5                   0xB0C5
-
-#define VBE_DISPI_DISABLED              0x00
-#define VBE_DISPI_ENABLED               0x01
-#define VBE_DISPI_GETCAPS               0x02
-#define VBE_DISPI_8BIT_DAC              0x20
-#define VBE_DISPI_LFB_ENABLED           0x40
-#define VBE_DISPI_NOCLEARMEM            0x80
-
-#define VBE_DISPI_LFB_PHYSICAL_ADDRESS  0xE0000000
-
 #define CH_ATTR_SIZE (160 * 100)
 #define VGA_MAX_HEIGHT 2048
 
diff --git a/include/hw/display/bochs-vbe.h b/include/hw/display/bochs-vbe.h
new file mode 100644
index 0000000000..bc2f046eee
--- /dev/null
+++ b/include/hw/display/bochs-vbe.h
@@ -0,0 +1,69 @@
+#ifndef HW_DISPLAY_BOCHS_VBE_H
+#define HW_DISPLAY_BOCHS_VBE_H
+
+/*
+ * bochs vesa bios extension interface
+ */
+
+#define VBE_DISPI_MAX_XRES              16000
+#define VBE_DISPI_MAX_YRES              12000
+#define VBE_DISPI_MAX_BPP               32
+
+#define VBE_DISPI_INDEX_ID              0x0
+#define VBE_DISPI_INDEX_XRES            0x1
+#define VBE_DISPI_INDEX_YRES            0x2
+#define VBE_DISPI_INDEX_BPP             0x3
+#define VBE_DISPI_INDEX_ENABLE          0x4
+#define VBE_DISPI_INDEX_BANK            0x5
+#define VBE_DISPI_INDEX_VIRT_WIDTH      0x6
+#define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
+#define VBE_DISPI_INDEX_X_OFFSET        0x8
+#define VBE_DISPI_INDEX_Y_OFFSET        0x9
+#define VBE_DISPI_INDEX_NB              0xa /* size of vbe_regs[] */
+#define VBE_DISPI_INDEX_VIDEO_MEMORY_64K 0xa /* read-only, not in vbe_regs */
+
+/* VBE_DISPI_INDEX_ID */
+#define VBE_DISPI_ID0                   0xB0C0
+#define VBE_DISPI_ID1                   0xB0C1
+#define VBE_DISPI_ID2                   0xB0C2
+#define VBE_DISPI_ID3                   0xB0C3
+#define VBE_DISPI_ID4                   0xB0C4
+#define VBE_DISPI_ID5                   0xB0C5
+
+/* VBE_DISPI_INDEX_ENABLE */
+#define VBE_DISPI_DISABLED              0x00
+#define VBE_DISPI_ENABLED               0x01
+#define VBE_DISPI_GETCAPS               0x02
+#define VBE_DISPI_8BIT_DAC              0x20
+#define VBE_DISPI_LFB_ENABLED           0x40
+#define VBE_DISPI_NOCLEARMEM            0x80
+
+/* only used by isa-vga, pci vga devices use a memory bar */
+#define VBE_DISPI_LFB_PHYSICAL_ADDRESS  0xE0000000
+
+
+/*
+ * qemu extension: mmio bar (region 2)
+ */
+
+#define PCI_VGA_MMIO_SIZE     0x1000
+
+/* vga register region */
+#define PCI_VGA_IOPORT_OFFSET 0x400
+#define PCI_VGA_IOPORT_SIZE   (0x3e0 - 0x3c0)
+
+/* bochs vbe register region */
+#define PCI_VGA_BOCHS_OFFSET  0x500
+#define PCI_VGA_BOCHS_SIZE    (0x0b * 2)
+
+/* qemu extension register region */
+#define PCI_VGA_QEXT_OFFSET   0x600
+#define PCI_VGA_QEXT_SIZE     (2 * 4)
+
+/* qemu extension registers */
+#define PCI_VGA_QEXT_REG_SIZE         (0 * 4)
+#define PCI_VGA_QEXT_REG_BYTEORDER    (1 * 4)
+#define  PCI_VGA_QEXT_LITTLE_ENDIAN   0x1e1e1e1e
+#define  PCI_VGA_QEXT_BIG_ENDIAN      0xbebebebe
+
+#endif /* HW_DISPLAY_BOCHS_VBE_H */
diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
index f312930664..fb3e4cd400 100644
--- a/hw/display/vga-pci.c
+++ b/hw/display/vga-pci.c
@@ -31,19 +31,6 @@
 #include "qemu/timer.h"
 #include "hw/loader.h"
 
-#define PCI_VGA_IOPORT_OFFSET 0x400
-#define PCI_VGA_IOPORT_SIZE   (0x3e0 - 0x3c0)
-#define PCI_VGA_BOCHS_OFFSET  0x500
-#define PCI_VGA_BOCHS_SIZE    (0x0b * 2)
-#define PCI_VGA_QEXT_OFFSET   0x600
-#define PCI_VGA_QEXT_SIZE     (2 * 4)
-#define PCI_VGA_MMIO_SIZE     0x1000
-
-#define PCI_VGA_QEXT_REG_SIZE         (0 * 4)
-#define PCI_VGA_QEXT_REG_BYTEORDER    (1 * 4)
-#define  PCI_VGA_QEXT_LITTLE_ENDIAN   0x1e1e1e1e
-#define  PCI_VGA_QEXT_BIG_ENDIAN      0xbebebebe
-
 enum vga_pci_flags {
     PCI_VGA_FLAG_ENABLE_MMIO = 1,
     PCI_VGA_FLAG_ENABLE_QEXT = 2,
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 3/7] vga-pci: use PCI_VGA_MMIO_SIZE
  2018-05-24 15:45 [Qemu-devel] [PULL 0/7] Vga 20180524 patches Gerd Hoffmann
  2018-05-24 15:45 ` [Qemu-devel] [PULL 1/7] vga: catch depth 0 Gerd Hoffmann
  2018-05-24 15:45 ` [Qemu-devel] [PULL 2/7] vga: move bochs vbe defines to header file Gerd Hoffmann
@ 2018-05-24 15:45 ` Gerd Hoffmann
  2018-05-24 15:45 ` [Qemu-devel] [PULL 4/7] hw/display: add new bochs-display device Gerd Hoffmann
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-05-24 15:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20180522165058.15404-3-kraxel@redhat.com
---
 hw/display/vga-pci.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/hw/display/vga-pci.c b/hw/display/vga-pci.c
index fb3e4cd400..700ac58c69 100644
--- a/hw/display/vga-pci.c
+++ b/hw/display/vga-pci.c
@@ -232,7 +232,8 @@ static void pci_std_vga_realize(PCIDevice *dev, Error **errp)
 
     /* mmio bar for vga register access */
     if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_MMIO)) {
-        memory_region_init(&d->mmio, NULL, "vga.mmio", 4096);
+        memory_region_init(&d->mmio, NULL, "vga.mmio",
+                           PCI_VGA_MMIO_SIZE);
 
         if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) {
             qext = true;
@@ -267,7 +268,8 @@ static void pci_secondary_vga_realize(PCIDevice *dev, Error **errp)
     s->con = graphic_console_init(DEVICE(dev), 0, s->hw_ops, s);
 
     /* mmio bar */
-    memory_region_init(&d->mmio, OBJECT(dev), "vga.mmio", 4096);
+    memory_region_init(&d->mmio, OBJECT(dev), "vga.mmio",
+                       PCI_VGA_MMIO_SIZE);
 
     if (d->flags & (1 << PCI_VGA_FLAG_ENABLE_QEXT)) {
         qext = true;
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 4/7] hw/display: add new bochs-display device
  2018-05-24 15:45 [Qemu-devel] [PULL 0/7] Vga 20180524 patches Gerd Hoffmann
                   ` (2 preceding siblings ...)
  2018-05-24 15:45 ` [Qemu-devel] [PULL 3/7] vga-pci: use PCI_VGA_MMIO_SIZE Gerd Hoffmann
@ 2018-05-24 15:45 ` Gerd Hoffmann
  2018-05-24 15:45 ` [Qemu-devel] [PULL 5/7] bochs-display: add dirty tracking support Gerd Hoffmann
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-05-24 15:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

After writing up the virtual mdev device emulating a display supporting
the bochs vbe dispi interface (mbochs.ko) and seeing how simple it
actually is I've figured that would be useful for qemu too.

So, here it is, -device bochs-display.  It is basically -device VGA
without legacy vga emulation.  PCI bar 0 is the framebuffer, PCI bar 2
is mmio with the registers.  The vga registers are simply not there
though, neither in the legacy ioport location nor in the mmio bar.
Consequently it is PCI class DISPLAY_OTHER not DISPLAY_VGA.

So there is no text mode emulation, no weird video modes (planar,
256color palette), no memory window at 0xa0000.  Just a linear
framebuffer in the pci memory bar.  And the amount of code to emulate
this (and therefore the attack surface) is an order of magnitude smaller
when compared to vga emulation.

Compatibility wise it works with OVMF (latest git master).
The bochs-drm.ko linux kernel module can handle it just fine too.
So UEFI guests should not see any functional difference to VGA.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20180522165058.15404-4-kraxel@redhat.com
---
 hw/display/bochs-display.c | 325 +++++++++++++++++++++++++++++++++++++++++++++
 hw/display/Makefile.objs   |   1 +
 2 files changed, 326 insertions(+)
 create mode 100644 hw/display/bochs-display.c

diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c
new file mode 100644
index 0000000000..a523e81d1d
--- /dev/null
+++ b/hw/display/bochs-display.c
@@ -0,0 +1,325 @@
+/*
+ * QEMU PCI bochs display adapter.
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ */
+#include "qemu/osdep.h"
+#include "hw/hw.h"
+#include "hw/pci/pci.h"
+#include "hw/display/bochs-vbe.h"
+
+#include "qapi/error.h"
+
+#include "ui/console.h"
+#include "ui/qemu-pixman.h"
+
+typedef struct BochsDisplayMode {
+    pixman_format_code_t format;
+    uint32_t             bytepp;
+    uint32_t             width;
+    uint32_t             height;
+    uint32_t             stride;
+    uint64_t             offset;
+    uint64_t             size;
+} BochsDisplayMode;
+
+typedef struct BochsDisplayState {
+    /* parent */
+    PCIDevice        pci;
+
+    /* device elements */
+    QemuConsole      *con;
+    MemoryRegion     vram;
+    MemoryRegion     mmio;
+    MemoryRegion     vbe;
+    MemoryRegion     qext;
+
+    /* device config */
+    uint64_t         vgamem;
+
+    /* device registers */
+    uint16_t         vbe_regs[VBE_DISPI_INDEX_NB];
+    bool             big_endian_fb;
+
+    /* device state */
+    BochsDisplayMode mode;
+} BochsDisplayState;
+
+#define TYPE_BOCHS_DISPLAY "bochs-display"
+#define BOCHS_DISPLAY(obj) OBJECT_CHECK(BochsDisplayState, (obj), \
+                                        TYPE_BOCHS_DISPLAY)
+
+static const VMStateDescription vmstate_bochs_display = {
+    .name = "bochs-display",
+    .fields = (VMStateField[]) {
+        VMSTATE_PCI_DEVICE(pci, BochsDisplayState),
+        VMSTATE_UINT16_ARRAY(vbe_regs, BochsDisplayState, VBE_DISPI_INDEX_NB),
+        VMSTATE_BOOL(big_endian_fb, BochsDisplayState),
+        VMSTATE_END_OF_LIST()
+    }
+};
+
+static uint64_t bochs_display_vbe_read(void *ptr, hwaddr addr,
+                                       unsigned size)
+{
+    BochsDisplayState *s = ptr;
+    unsigned int index = addr >> 1;
+
+    switch (index) {
+    case VBE_DISPI_INDEX_ID:
+        return VBE_DISPI_ID5;
+    case VBE_DISPI_INDEX_VIDEO_MEMORY_64K:
+        return s->vgamem / (64 * 1024);
+    }
+
+    if (index >= ARRAY_SIZE(s->vbe_regs)) {
+        return -1;
+    }
+    return s->vbe_regs[index];
+}
+
+static void bochs_display_vbe_write(void *ptr, hwaddr addr,
+                                    uint64_t val, unsigned size)
+{
+    BochsDisplayState *s = ptr;
+    unsigned int index = addr >> 1;
+
+    if (index >= ARRAY_SIZE(s->vbe_regs)) {
+        return;
+    }
+    s->vbe_regs[index] = val;
+}
+
+static const MemoryRegionOps bochs_display_vbe_ops = {
+    .read = bochs_display_vbe_read,
+    .write = bochs_display_vbe_write,
+    .valid.min_access_size = 1,
+    .valid.max_access_size = 4,
+    .impl.min_access_size = 2,
+    .impl.max_access_size = 2,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static uint64_t bochs_display_qext_read(void *ptr, hwaddr addr,
+                                        unsigned size)
+{
+    BochsDisplayState *s = ptr;
+
+    switch (addr) {
+    case PCI_VGA_QEXT_REG_SIZE:
+        return PCI_VGA_QEXT_SIZE;
+    case PCI_VGA_QEXT_REG_BYTEORDER:
+        return s->big_endian_fb ?
+            PCI_VGA_QEXT_BIG_ENDIAN : PCI_VGA_QEXT_LITTLE_ENDIAN;
+    default:
+        return 0;
+    }
+}
+
+static void bochs_display_qext_write(void *ptr, hwaddr addr,
+                                     uint64_t val, unsigned size)
+{
+    BochsDisplayState *s = ptr;
+
+    switch (addr) {
+    case PCI_VGA_QEXT_REG_BYTEORDER:
+        if (val == PCI_VGA_QEXT_BIG_ENDIAN) {
+            s->big_endian_fb = true;
+        }
+        if (val == PCI_VGA_QEXT_LITTLE_ENDIAN) {
+            s->big_endian_fb = false;
+        }
+        break;
+    }
+}
+
+static const MemoryRegionOps bochs_display_qext_ops = {
+    .read = bochs_display_qext_read,
+    .write = bochs_display_qext_write,
+    .valid.min_access_size = 4,
+    .valid.max_access_size = 4,
+    .endianness = DEVICE_LITTLE_ENDIAN,
+};
+
+static int bochs_display_get_mode(BochsDisplayState *s,
+                                   BochsDisplayMode *mode)
+{
+    uint16_t *vbe = s->vbe_regs;
+    uint32_t virt_width;
+
+    if (!(vbe[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
+        return -1;
+    }
+
+    memset(mode, 0, sizeof(*mode));
+    switch (vbe[VBE_DISPI_INDEX_BPP]) {
+    case 16:
+        /* best effort: support native endianess only */
+        mode->format = PIXMAN_r5g6b5;
+        mode->bytepp = 2;
+    case 32:
+        mode->format = s->big_endian_fb
+            ? PIXMAN_BE_x8r8g8b8
+            : PIXMAN_LE_x8r8g8b8;
+        mode->bytepp = 4;
+        break;
+    default:
+        return -1;
+    }
+
+    mode->width  = vbe[VBE_DISPI_INDEX_XRES];
+    mode->height = vbe[VBE_DISPI_INDEX_YRES];
+    virt_width  = vbe[VBE_DISPI_INDEX_VIRT_WIDTH];
+    if (virt_width < mode->width) {
+        virt_width = mode->width;
+    }
+    mode->stride = virt_width * mode->bytepp;
+    mode->size   = (uint64_t)mode->stride * mode->height;
+    mode->offset = ((uint64_t)vbe[VBE_DISPI_INDEX_X_OFFSET] * mode->bytepp +
+                    (uint64_t)vbe[VBE_DISPI_INDEX_Y_OFFSET] * mode->stride);
+
+    if (mode->width < 64 || mode->height < 64) {
+        return -1;
+    }
+    if (mode->offset + mode->size > s->vgamem) {
+        return -1;
+    }
+    return 0;
+}
+
+static void bochs_display_update(void *opaque)
+{
+    BochsDisplayState *s = opaque;
+    BochsDisplayMode mode;
+    DisplaySurface *ds;
+    uint8_t *ptr;
+    int ret;
+
+    ret = bochs_display_get_mode(s, &mode);
+    if (ret < 0) {
+        /* no (valid) video mode */
+        return;
+    }
+
+    if (memcmp(&s->mode, &mode, sizeof(mode)) != 0) {
+        /* video mode switch */
+        s->mode = mode;
+        ptr = memory_region_get_ram_ptr(&s->vram);
+        ds = qemu_create_displaysurface_from(mode.width,
+                                             mode.height,
+                                             mode.format,
+                                             mode.stride,
+                                             ptr + mode.offset);
+        dpy_gfx_replace_surface(s->con, ds);
+    }
+
+    dpy_gfx_update_full(s->con);
+}
+
+static const GraphicHwOps bochs_display_gfx_ops = {
+    .gfx_update = bochs_display_update,
+};
+
+static void bochs_display_realize(PCIDevice *dev, Error **errp)
+{
+    BochsDisplayState *s = BOCHS_DISPLAY(dev);
+    Object *obj = OBJECT(dev);
+
+    s->con = graphic_console_init(DEVICE(dev), 0, &bochs_display_gfx_ops, s);
+
+    if (s->vgamem < (4 * 1024 * 1024)) {
+        error_setg(errp, "bochs-display: video memory too small");
+    }
+    if (s->vgamem > (256 * 1024 * 1024)) {
+        error_setg(errp, "bochs-display: video memory too big");
+    }
+    s->vgamem = pow2ceil(s->vgamem);
+
+    memory_region_init_ram(&s->vram, obj, "bochs-display-vram", s->vgamem,
+                           &error_fatal);
+    memory_region_init_io(&s->vbe, obj, &bochs_display_vbe_ops, s,
+                          "bochs dispi interface", PCI_VGA_BOCHS_SIZE);
+    memory_region_init_io(&s->qext, obj, &bochs_display_qext_ops, s,
+                          "qemu extended regs", PCI_VGA_QEXT_SIZE);
+
+    memory_region_init(&s->mmio, obj, "bochs-display-mmio",
+                       PCI_VGA_MMIO_SIZE);
+    memory_region_add_subregion(&s->mmio, PCI_VGA_BOCHS_OFFSET, &s->vbe);
+    memory_region_add_subregion(&s->mmio, PCI_VGA_QEXT_OFFSET, &s->qext);
+
+    pci_set_byte(&s->pci.config[PCI_REVISION_ID], 2);
+    pci_register_bar(&s->pci, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
+    pci_register_bar(&s->pci, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
+}
+
+static bool bochs_display_get_big_endian_fb(Object *obj, Error **errp)
+{
+    BochsDisplayState *s = BOCHS_DISPLAY(obj);
+
+    return s->big_endian_fb;
+}
+
+static void bochs_display_set_big_endian_fb(Object *obj, bool value,
+                                            Error **errp)
+{
+    BochsDisplayState *s = BOCHS_DISPLAY(obj);
+
+    s->big_endian_fb = value;
+}
+
+static void bochs_display_init(Object *obj)
+{
+    /* Expose framebuffer byteorder via QOM */
+    object_property_add_bool(obj, "big-endian-framebuffer",
+                             bochs_display_get_big_endian_fb,
+                             bochs_display_set_big_endian_fb,
+                             NULL);
+}
+
+static void bochs_display_exit(PCIDevice *dev)
+{
+    BochsDisplayState *s = BOCHS_DISPLAY(dev);
+
+    graphic_console_close(s->con);
+}
+
+static Property bochs_display_properties[] = {
+    DEFINE_PROP_SIZE("vgamem", BochsDisplayState, vgamem, 16 * 1024 * 1024),
+    DEFINE_PROP_END_OF_LIST(),
+};
+
+static void bochs_display_class_init(ObjectClass *klass, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(klass);
+    PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
+
+    k->class_id  = PCI_CLASS_DISPLAY_OTHER;
+    k->vendor_id = PCI_VENDOR_ID_QEMU;
+    k->device_id = PCI_DEVICE_ID_QEMU_VGA;
+
+    k->realize   = bochs_display_realize;
+    k->exit      = bochs_display_exit;
+    dc->vmsd     = &vmstate_bochs_display;
+    dc->props    = bochs_display_properties;
+    set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
+}
+
+static const TypeInfo bochs_display_type_info = {
+    .name           = TYPE_BOCHS_DISPLAY,
+    .parent         = TYPE_PCI_DEVICE,
+    .instance_size  = sizeof(BochsDisplayState),
+    .instance_init  = bochs_display_init,
+    .class_init     = bochs_display_class_init,
+    .interfaces     = (InterfaceInfo[]) {
+        { INTERFACE_CONVENTIONAL_PCI_DEVICE },
+        { },
+    },
+};
+
+static void bochs_display_register_types(void)
+{
+    type_register_static(&bochs_display_type_info);
+}
+
+type_init(bochs_display_register_types)
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index 11321e466b..d907b381ae 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -9,6 +9,7 @@ common-obj-$(CONFIG_SSD0323) += ssd0323.o
 common-obj-$(CONFIG_XEN) += xenfb.o
 
 common-obj-$(CONFIG_VGA_PCI) += vga-pci.o
+common-obj-$(CONFIG_VGA_PCI) += bochs-display.o
 common-obj-$(CONFIG_VGA_ISA) += vga-isa.o
 common-obj-$(CONFIG_VGA_ISA_MM) += vga-isa-mm.o
 common-obj-$(CONFIG_VMWARE_VGA) += vmware_vga.o
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 5/7] bochs-display: add dirty tracking support
  2018-05-24 15:45 [Qemu-devel] [PULL 0/7] Vga 20180524 patches Gerd Hoffmann
                   ` (3 preceding siblings ...)
  2018-05-24 15:45 ` [Qemu-devel] [PULL 4/7] hw/display: add new bochs-display device Gerd Hoffmann
@ 2018-05-24 15:45 ` Gerd Hoffmann
  2018-05-24 15:45 ` [Qemu-devel] [PULL 6/7] bochs-display: add pcie support Gerd Hoffmann
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-05-24 15:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 20180522165058.15404-5-kraxel@redhat.com
---
 hw/display/bochs-display.c | 34 ++++++++++++++++++++++++++++++++--
 1 file changed, 32 insertions(+), 2 deletions(-)

diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c
index a523e81d1d..9607df1c34 100644
--- a/hw/display/bochs-display.c
+++ b/hw/display/bochs-display.c
@@ -191,10 +191,13 @@ static int bochs_display_get_mode(BochsDisplayState *s,
 static void bochs_display_update(void *opaque)
 {
     BochsDisplayState *s = opaque;
+    DirtyBitmapSnapshot *snap = NULL;
+    bool full_update = false;
     BochsDisplayMode mode;
     DisplaySurface *ds;
     uint8_t *ptr;
-    int ret;
+    bool dirty;
+    int y, ys, ret;
 
     ret = bochs_display_get_mode(s, &mode);
     if (ret < 0) {
@@ -212,9 +215,34 @@ static void bochs_display_update(void *opaque)
                                              mode.stride,
                                              ptr + mode.offset);
         dpy_gfx_replace_surface(s->con, ds);
+        full_update = true;
     }
 
-    dpy_gfx_update_full(s->con);
+    if (full_update) {
+        dpy_gfx_update_full(s->con);
+    } else {
+        snap = memory_region_snapshot_and_clear_dirty(&s->vram,
+                                                      mode.offset, mode.size,
+                                                      DIRTY_MEMORY_VGA);
+        ys = -1;
+        for (y = 0; y < mode.height; y++) {
+            dirty = memory_region_snapshot_get_dirty(&s->vram, snap,
+                                                     mode.offset + mode.stride * y,
+                                                     mode.stride);
+            if (dirty && ys < 0) {
+                ys = y;
+            }
+            if (!dirty && ys >= 0) {
+                dpy_gfx_update(s->con, 0, ys,
+                               mode.width, y - ys);
+                ys = -1;
+            }
+        }
+        if (ys >= 0) {
+            dpy_gfx_update(s->con, 0, ys,
+                           mode.width, y - ys);
+        }
+    }
 }
 
 static const GraphicHwOps bochs_display_gfx_ops = {
@@ -251,6 +279,8 @@ static void bochs_display_realize(PCIDevice *dev, Error **errp)
     pci_set_byte(&s->pci.config[PCI_REVISION_ID], 2);
     pci_register_bar(&s->pci, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
     pci_register_bar(&s->pci, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
+
+    memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
 }
 
 static bool bochs_display_get_big_endian_fb(Object *obj, Error **errp)
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 6/7] bochs-display: add pcie support
  2018-05-24 15:45 [Qemu-devel] [PULL 0/7] Vga 20180524 patches Gerd Hoffmann
                   ` (4 preceding siblings ...)
  2018-05-24 15:45 ` [Qemu-devel] [PULL 5/7] bochs-display: add dirty tracking support Gerd Hoffmann
@ 2018-05-24 15:45 ` Gerd Hoffmann
  2018-05-24 15:45 ` [Qemu-devel] [PULL 7/7] MAINTAINERS: add vga entries Gerd Hoffmann
  2018-05-24 17:33 ` [Qemu-devel] [PULL 0/7] Vga 20180524 patches Peter Maydell
  7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-05-24 15:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 20180522165058.15404-6-kraxel@redhat.com
---
 hw/display/bochs-display.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c
index 9607df1c34..c33524b558 100644
--- a/hw/display/bochs-display.c
+++ b/hw/display/bochs-display.c
@@ -253,6 +253,7 @@ static void bochs_display_realize(PCIDevice *dev, Error **errp)
 {
     BochsDisplayState *s = BOCHS_DISPLAY(dev);
     Object *obj = OBJECT(dev);
+    int ret;
 
     s->con = graphic_console_init(DEVICE(dev), 0, &bochs_display_gfx_ops, s);
 
@@ -280,6 +281,12 @@ static void bochs_display_realize(PCIDevice *dev, Error **errp)
     pci_register_bar(&s->pci, 0, PCI_BASE_ADDRESS_MEM_PREFETCH, &s->vram);
     pci_register_bar(&s->pci, 2, PCI_BASE_ADDRESS_SPACE_MEMORY, &s->mmio);
 
+    if (pci_bus_is_express(pci_get_bus(dev))) {
+        dev->cap_present |= QEMU_PCI_CAP_EXPRESS;
+        ret = pcie_endpoint_cap_init(dev, 0x80);
+        assert(ret > 0);
+    }
+
     memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA);
 }
 
@@ -342,6 +349,7 @@ static const TypeInfo bochs_display_type_info = {
     .instance_init  = bochs_display_init,
     .class_init     = bochs_display_class_init,
     .interfaces     = (InterfaceInfo[]) {
+        { INTERFACE_PCIE_DEVICE },
         { INTERFACE_CONVENTIONAL_PCI_DEVICE },
         { },
     },
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [Qemu-devel] [PULL 7/7] MAINTAINERS: add vga entries
  2018-05-24 15:45 [Qemu-devel] [PULL 0/7] Vga 20180524 patches Gerd Hoffmann
                   ` (5 preceding siblings ...)
  2018-05-24 15:45 ` [Qemu-devel] [PULL 6/7] bochs-display: add pcie support Gerd Hoffmann
@ 2018-05-24 15:45 ` Gerd Hoffmann
  2018-05-24 17:33 ` [Qemu-devel] [PULL 0/7] Vga 20180524 patches Peter Maydell
  7 siblings, 0 replies; 9+ messages in thread
From: Gerd Hoffmann @ 2018-05-24 15:45 UTC (permalink / raw)
  To: qemu-devel; +Cc: Gerd Hoffmann

Add entries for standard vga, virtio-gpu and cirrus.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Message-id: 20180522165058.15404-7-kraxel@redhat.com
---
 MAINTAINERS | 21 +++++++++++++++++++++
 1 file changed, 21 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index e187b1f18f..2af3ad5172 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1314,6 +1314,27 @@ S: Maintained
 F: include/hw/misc/unimp.h
 F: hw/misc/unimp.c
 
+Standard VGA
+M: Gerd Hoffmann <kraxel@redhat.com>
+S: Maintained
+F: hw/display/vga*
+F: hw/display/bochs-display.c
+F: include/hw/display/vga.h
+F: include/hw/display/bochs-vbe.h
+
+virtio-gpu
+M: Gerd Hoffmann <kraxel@redhat.com>
+S: Maintained
+F: hw/display/virtio-gpu*
+F: hw/display/virtio-vga.c
+F: include/hw/virtio/virtio-gpu.h
+
+Cirrus VGA
+M: Gerd Hoffmann <kraxel@redhat.com>
+S: Odd Fixes
+W: https://www.kraxel.org/blog/2014/10/qemu-using-cirrus-considered-harmful/
+F: hw/display/cirrus*
+
 Subsystems
 ----------
 Audio
-- 
2.9.3

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [Qemu-devel] [PULL 0/7] Vga 20180524 patches
  2018-05-24 15:45 [Qemu-devel] [PULL 0/7] Vga 20180524 patches Gerd Hoffmann
                   ` (6 preceding siblings ...)
  2018-05-24 15:45 ` [Qemu-devel] [PULL 7/7] MAINTAINERS: add vga entries Gerd Hoffmann
@ 2018-05-24 17:33 ` Peter Maydell
  7 siblings, 0 replies; 9+ messages in thread
From: Peter Maydell @ 2018-05-24 17:33 UTC (permalink / raw)
  To: Gerd Hoffmann; +Cc: QEMU Developers

On 24 May 2018 at 16:45, Gerd Hoffmann <kraxel@redhat.com> wrote:
> The following changes since commit 4f50c1673a89b07f376ce5c42d22d79a79cd466d:
>
>   Merge remote-tracking branch 'remotes/ehabkost/tags/x86-next-pull-request' into staging (2018-05-22 09:43:58 +0100)
>
> are available in the git repository at:
>
>   git://git.kraxel.org/qemu tags/vga-20180524-pull-request
>
> for you to fetch changes up to dbb2e4726c76dbffb39efe6623bf75d2ec1db8bc:
>
>   MAINTAINERS: add vga entries (2018-05-24 10:42:13 +0200)
>
> ----------------------------------------------------------------
> vga: catch depth 0
> hw/display: add new bochs-display device
> some cleanups.
>
> ----------------------------------------------------------------

Applied, thanks.

-- PMM

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2018-05-24 17:33 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-05-24 15:45 [Qemu-devel] [PULL 0/7] Vga 20180524 patches Gerd Hoffmann
2018-05-24 15:45 ` [Qemu-devel] [PULL 1/7] vga: catch depth 0 Gerd Hoffmann
2018-05-24 15:45 ` [Qemu-devel] [PULL 2/7] vga: move bochs vbe defines to header file Gerd Hoffmann
2018-05-24 15:45 ` [Qemu-devel] [PULL 3/7] vga-pci: use PCI_VGA_MMIO_SIZE Gerd Hoffmann
2018-05-24 15:45 ` [Qemu-devel] [PULL 4/7] hw/display: add new bochs-display device Gerd Hoffmann
2018-05-24 15:45 ` [Qemu-devel] [PULL 5/7] bochs-display: add dirty tracking support Gerd Hoffmann
2018-05-24 15:45 ` [Qemu-devel] [PULL 6/7] bochs-display: add pcie support Gerd Hoffmann
2018-05-24 15:45 ` [Qemu-devel] [PULL 7/7] MAINTAINERS: add vga entries Gerd Hoffmann
2018-05-24 17:33 ` [Qemu-devel] [PULL 0/7] Vga 20180524 patches Peter Maydell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.