vga: catch depth 0
hw/display: add new bochs-display device some cleanups. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJbBt4qAAoJEEy22O7T6HE49zIQAJpmAAqJidE14l6mcnxzxqoS yC0VyXFqEbwueTeNd4VIjrJRkOHk8auWCes+QKoR1ZfbEEsLDzD8CF4tKbSj8Y41 0Poe+vYrOQQazkxWSB08xBE6mdTtXTkDC4zkmNSDxb5LIBGBa1A/juPksaXawFDK pfDaCYZdO7RgnU2EgoykDteHMnzKeCO9fMPQvdVuen4DDqeIlXyYAUDEYDag5gJy DhZqDDz31m7g9JYLOVSGW0Qd2uZXvw55A3pnDNiCyyDKJl0xLeJOBif714J2GI0r wDLDY9sSjx78d/qmNtX+X4lvXW7GWGDw228VjW2XBKqzligg9rM/8h6aIPbqqT5N XWdOT6Qx4lSbcsbinSWVmWu9XDb7NXKSu3oc/tTC/ImJTuBPUkaGuMTmd5kCe5Mk VG5ZY8ow9pQ9THU1pFW6CA/MRWWfm5IPxkJBiT4sJb8i5aSPxTSBEZjMfVdCvh78 av2g5NB4IYCOHDDwAOra+NDKULuDFRBYFKyb4Ge52zKe2UB3sKnxlIWeOGS88C6D gH/j+02eO4Q8EWauUUFUJNW3TGUirlcl5oxvyZjhEbjsh+2RasOT1ULW54IIdpnU ijhHfnRcMNG4iNq1HA49tjHq3QraGQ9zZF3wOSrwyq47uU2Rjp+HS5TnZuzz3Mi4 VEjZXPmVd9R9++c3E+o1 =FJjD -----END PGP SIGNATURE----- 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>
This commit is contained in:
commit
62b9b076d9
21
MAINTAINERS
21
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
|
||||
|
@ -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
|
||||
|
363
hw/display/bochs-display.c
Normal file
363
hw/display/bochs-display.c
Normal file
@ -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)
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
69
include/hw/display/bochs-vbe.h
Normal file
69
include/hw/display/bochs-vbe.h
Normal file
@ -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 */
|
Loading…
Reference in New Issue
Block a user