aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2018-05-24 17:48:01 +0100
committerPeter Maydell <peter.maydell@linaro.org>2018-05-24 17:48:01 +0100
commit62b9b076d9d37117696ec64f0b3544c1205ff7f9 (patch)
treecb56b7f7ee9b99669b51fc2cd5354e5330057e26
parent45eabb2ede0caf2f3dd0e1ace045d0915c53ef4d (diff)
parentdbb2e4726c76dbffb39efe6623bf75d2ec1db8bc (diff)
Merge remote-tracking branch 'remotes/kraxel/tags/vga-20180524-pull-request' into staging
vga: catch depth 0 hw/display: add new bochs-display device some cleanups. # gpg: Signature made Thu 24 May 2018 16:45:46 BST # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/vga-20180524-pull-request: MAINTAINERS: add vga entries bochs-display: add pcie support bochs-display: add dirty tracking support hw/display: add new bochs-display device vga-pci: use PCI_VGA_MMIO_SIZE vga: move bochs vbe defines to header file vga: catch depth 0 Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--MAINTAINERS21
-rw-r--r--hw/display/Makefile.objs1
-rw-r--r--hw/display/bochs-display.c363
-rw-r--r--hw/display/vga-pci.c19
-rw-r--r--hw/display/vga.c23
-rw-r--r--hw/display/vga_int.h35
-rw-r--r--include/hw/display/bochs-vbe.h69
7 files changed, 478 insertions, 53 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 5b335aa948..bf482fd4e9 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
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
diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c
new file mode 100644
index 0000000000..c33524b558
--- /dev/null
+++ b/hw/display/bochs-display.c
@@ -0,0 +1,363 @@
+/*
+ * 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;
+ DirtyBitmapSnapshot *snap = NULL;
+ bool full_update = false;
+ BochsDisplayMode mode;
+ DisplaySurface *ds;
+ uint8_t *ptr;
+ bool dirty;
+ int y, ys, 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);
+ full_update = true;
+ }
+
+ 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 = {
+ .gfx_update = bochs_display_update,
+};
+
+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);
+
+ 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);
+
+ 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);
+}
+
+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_PCIE_DEVICE },
+ { 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/vga-pci.c b/hw/display/vga-pci.c
index f312930664..700ac58c69 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,
@@ -245,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;
@@ -280,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;
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
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 */