* [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.