vga: bugfixes for qxl, cirrus, ati.

vga: add "-vga help" support.
 vga: move i2c-ddc to display.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2.0.22 (GNU/Linux)
 
 iQIcBAABAgAGBQJc0T+UAAoJEEy22O7T6HE4G08P/38oXT11HX7XIXk4XB7qOUnS
 sh+FbaEbMTw7FDbX6/8H2JmNWJ81fRkTD+vj7ANSqmb1uCvmDtX8PEL7uL9ZxIwR
 YfdDONazMtpSngpS4E11gnIXZjAEMfhbez+/kIoirtwuXUtR7opMI/qLtshZK9Rx
 vBnqi67rSvYYIphs9vw1QJWfGUR8Z8L0K4eRXmNoEzd7jMwME6ASP6M+2E8wTUDu
 LuuiTet2ALHDsCXowXTAb5eytJ9hY+foYOf7pal1Ar5MtQiTpgywd7Si5EOjLAg8
 3tdZql2oD9e8I/bTIpmptyBtjg4CTQrpo52MkOTURvdFqh656cvf17Q/c6U/CSYr
 wq4mNQk3keAHJI8oac5L/lGs/Cwku8ATaCQRxVKcxEKWHSHFr7S2/vRlUjDEKmOm
 xwxCkd56iPuZ/A5Lj+MSRyB+cBHW/2Ye7nORm/Kbdj1paMOgohpSbdWpZArx7Q7H
 RK7zdilwQq5wj9P3HqasLH12lJhD+5lhtlX/7IbJp+0UFcdyjMk+dyavN9Ah8jk/
 6MTf75rd0EIeD106YKVdEMbdRgGHe/VuKj04pxT2HiZ0yw2MKKjaZYmqKKJ11mTB
 8cAmmsS2PIQQc74vwAwyHnDkrCCYLhHnxGWD7RILPq73cfKrOniRLbeY+emSh9vF
 q0MWmU4TjtRM78g99H9h
 =ag3g
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kraxel/tags/vga-20190507-pull-request' into staging

vga: bugfixes for qxl, cirrus, ati.
vga: add "-vga help" support.
vga: move i2c-ddc to display.

# gpg: Signature made Tue 07 May 2019 09:19:32 BST
# gpg:                using RSA key 4CB6D8EED3E87138
# gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full]
# gpg:                 aka "Gerd Hoffmann <gerd@kraxel.org>" [full]
# gpg:                 aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full]
# Primary key fingerprint: A032 8CFF B93A 17A7 9901  FE7D 4CB6 D8EE D3E8 7138

* remotes/kraxel/tags/vga-20190507-pull-request:
  i2c-ddc: move it to hw/display
  ati-vga: Fix check for blt outside vram
  qxl: avoid unaligned pointer reads/writes
  vl: add -vga help support
  vl: constify VGAInterfaceInfo
  hw/display/cirrus_vga: Remove unused include
  hw/display/cirrus_vga: Update the documentation URL
  qxl: check release info object

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-05-07 21:39:28 +01:00
commit a6f6d24757
13 changed files with 84 additions and 62 deletions

View file

@ -1,3 +1,8 @@
config DDC
bool
depends on I2C
select EDID
config EDID
bool

View file

@ -1,3 +1,4 @@
common-obj-$(CONFIG_DDC) += i2c-ddc.o
common-obj-$(CONFIG_EDID) += edid-generate.o edid-region.o
common-obj-$(CONFIG_FW_CFG_DMA) += ramfb.o

View file

@ -79,10 +79,10 @@ void ati_2d_blt(ATIVGAState *s)
s->regs.dst_width, s->regs.dst_height);
end = s->vga.vram_ptr + s->vga.vram_size;
if (src_bits >= end || dst_bits >= end ||
src_bits + (s->regs.src_y + s->regs.dst_height) * src_stride +
s->regs.src_x >= end ||
dst_bits + (s->regs.dst_y + s->regs.dst_height) * dst_stride +
s->regs.dst_x >= end) {
src_bits + s->regs.src_x + (s->regs.src_y + s->regs.dst_height) *
src_stride * sizeof(uint32_t) >= end ||
dst_bits + s->regs.dst_x + (s->regs.dst_y + s->regs.dst_height) *
dst_stride * sizeof(uint32_t) >= end) {
qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
return;
}
@ -140,8 +140,8 @@ void ati_2d_blt(ATIVGAState *s)
filler);
end = s->vga.vram_ptr + s->vga.vram_size;
if (dst_bits >= end ||
dst_bits + (s->regs.dst_y + s->regs.dst_height) * dst_stride +
s->regs.dst_x >= end) {
dst_bits + s->regs.dst_x + (s->regs.dst_y + s->regs.dst_height) *
dst_stride * sizeof(uint32_t) >= end) {
qemu_log_mask(LOG_UNIMP, "blt outside vram not implemented\n");
return;
}

View file

@ -23,8 +23,13 @@
* THE SOFTWARE.
*/
/*
* Reference: Finn Thogersons' VGADOC4b
* available at http://home.worldonline.dk/~finth/
* Reference: Finn Thogersons' VGADOC4b:
*
* http://web.archive.org/web/20021019054927/http://home.worldonline.dk/finth/
*
* VGADOC4b.ZIP content available at:
*
* https://pdos.csail.mit.edu/6.828/2005/readings/hardware/vgadoc
*/
#include "qemu/osdep.h"
#include "qemu/units.h"
@ -33,7 +38,6 @@
#include "hw/hw.h"
#include "hw/pci/pci.h"
#include "ui/pixel_ops.h"
#include "hw/loader.h"
#include "cirrus_vga_internal.h"
/*

View file

@ -20,7 +20,7 @@
#include "qemu-common.h"
#include "qemu/log.h"
#include "hw/i2c/i2c.h"
#include "hw/i2c/i2c-ddc.h"
#include "hw/display/i2c-ddc.h"
#ifndef DEBUG_I2CDDC
#define DEBUG_I2CDDC 0

View file

@ -33,24 +33,6 @@
#include "qxl.h"
/*
* NOTE: SPICE_RING_PROD_ITEM accesses memory on the pci bar and as
* such can be changed by the guest, so to avoid a guest trigerrable
* abort we just qxl_set_guest_bug and set the return to NULL. Still
* it may happen as a result of emulator bug as well.
*/
#undef SPICE_RING_PROD_ITEM
#define SPICE_RING_PROD_ITEM(qxl, r, ret) { \
uint32_t prod = (r)->prod & SPICE_RING_INDEX_MASK(r); \
if (prod >= ARRAY_SIZE((r)->items)) { \
qxl_set_guest_bug(qxl, "SPICE_RING_PROD_ITEM indices mismatch " \
"%u >= %zu", prod, ARRAY_SIZE((r)->items)); \
ret = NULL; \
} else { \
ret = &(r)->items[prod].el; \
} \
}
#undef SPICE_RING_CONS_ITEM
#define SPICE_RING_CONS_ITEM(qxl, r, ret) { \
uint32_t cons = (r)->cons & SPICE_RING_INDEX_MASK(r); \
@ -414,7 +396,8 @@ static void init_qxl_rom(PCIQXLDevice *d)
static void init_qxl_ram(PCIQXLDevice *d)
{
uint8_t *buf;
uint64_t *item;
uint32_t prod;
QXLReleaseRing *ring;
buf = d->vga.vram_ptr;
d->ram = (QXLRam *)(buf + le32_to_cpu(d->shadow_rom.ram_header_offset));
@ -426,9 +409,12 @@ static void init_qxl_ram(PCIQXLDevice *d)
SPICE_RING_INIT(&d->ram->cmd_ring);
SPICE_RING_INIT(&d->ram->cursor_ring);
SPICE_RING_INIT(&d->ram->release_ring);
SPICE_RING_PROD_ITEM(d, &d->ram->release_ring, item);
assert(item);
*item = 0;
ring = &d->ram->release_ring;
prod = ring->prod & SPICE_RING_INDEX_MASK(ring);
assert(prod < ARRAY_SIZE(ring->items));
ring->items[prod].el = 0;
qxl_ring_set_dirty(d);
}
@ -732,7 +718,7 @@ static int interface_req_cmd_notification(QXLInstance *sin)
static inline void qxl_push_free_res(PCIQXLDevice *d, int flush)
{
QXLReleaseRing *ring = &d->ram->release_ring;
uint64_t *item;
uint32_t prod;
int notify;
#define QXL_FREE_BUNCH_SIZE 32
@ -759,11 +745,15 @@ static inline void qxl_push_free_res(PCIQXLDevice *d, int flush)
if (notify) {
qxl_send_events(d, QXL_INTERRUPT_DISPLAY);
}
SPICE_RING_PROD_ITEM(d, ring, item);
if (!item) {
ring = &d->ram->release_ring;
prod = ring->prod & SPICE_RING_INDEX_MASK(ring);
if (prod >= ARRAY_SIZE(ring->items)) {
qxl_set_guest_bug(d, "SPICE_RING_PROD_ITEM indices mismatch "
"%u >= %zu", prod, ARRAY_SIZE(ring->items));
return;
}
*item = 0;
ring->items[prod].el = 0;
d->num_free_res = 0;
d->last_release = NULL;
qxl_ring_set_dirty(d);
@ -775,8 +765,12 @@ static void interface_release_resource(QXLInstance *sin,
{
PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
QXLReleaseRing *ring;
uint64_t *item, id;
uint32_t prod;
uint64_t id;
if (!ext.info) {
return;
}
if (ext.group_id == MEMSLOT_GROUP_HOST) {
/* host group -> vga mode update request */
QXLCommandExt *cmdext = (void *)(intptr_t)(ext.info->id);
@ -792,16 +786,18 @@ static void interface_release_resource(QXLInstance *sin,
* pci bar 0, $command.release_info
*/
ring = &qxl->ram->release_ring;
SPICE_RING_PROD_ITEM(qxl, ring, item);
if (!item) {
prod = ring->prod & SPICE_RING_INDEX_MASK(ring);
if (prod >= ARRAY_SIZE(ring->items)) {
qxl_set_guest_bug(qxl, "SPICE_RING_PROD_ITEM indices mismatch "
"%u >= %zu", prod, ARRAY_SIZE(ring->items));
return;
}
if (*item == 0) {
if (ring->items[prod].el == 0) {
/* stick head into the ring */
id = ext.info->id;
ext.info->next = 0;
qxl_ram_set_dirty(qxl, &ext.info->next);
*item = id;
ring->items[prod].el = id;
qxl_ring_set_dirty(qxl);
} else {
/* append item to the list */

View file

@ -16,7 +16,7 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "hw/i2c/i2c.h"
#include "hw/i2c/i2c-ddc.h"
#include "hw/display/i2c-ddc.h"
#include "trace.h"
#define SII9022_SYS_CTRL_DATA 0x1a

View file

@ -35,7 +35,7 @@
#include "hw/sysbus.h"
#include "hw/pci/pci.h"
#include "hw/i2c/i2c.h"
#include "hw/i2c/i2c-ddc.h"
#include "hw/display/i2c-ddc.h"
#include "qemu/range.h"
#include "ui/pixel_ops.h"
#include "qemu/bswap.h"

View file

@ -5,11 +5,6 @@ config SMBUS_EEPROM
bool
depends on I2C
config DDC
bool
depends on I2C
select EDID
config VERSATILE_I2C
bool
select I2C

View file

@ -1,6 +1,5 @@
common-obj-$(CONFIG_I2C) += core.o smbus_slave.o smbus_master.o
common-obj-$(CONFIG_SMBUS_EEPROM) += smbus_eeprom.o
common-obj-$(CONFIG_DDC) += i2c-ddc.o
common-obj-$(CONFIG_VERSATILE_I2C) += versatile_i2c.o
common-obj-$(CONFIG_ACPI_X86_ICH) += smbus_ich9.o
common-obj-$(CONFIG_ACPI_SMBUS) += pm_smbus.o

View file

@ -27,7 +27,7 @@
#include "hw/misc/auxbus.h"
#include "hw/i2c/i2c.h"
#include "hw/display/dpcd.h"
#include "hw/i2c/i2c-ddc.h"
#include "hw/display/i2c-ddc.h"
#include "qemu/fifo8.h"
#include "qemu/units.h"
#include "hw/dma/xlnx_dpdma.h"

46
vl.c
View file

@ -2015,7 +2015,7 @@ typedef struct VGAInterfaceInfo {
const char *class_names[2];
} VGAInterfaceInfo;
static VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = {
static const VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = {
[VGA_NONE] = {
.opt_name = "none",
},
@ -2061,7 +2061,7 @@ static VGAInterfaceInfo vga_interfaces[VGA_TYPE_MAX] = {
static bool vga_interface_available(VGAInterfaceType t)
{
VGAInterfaceInfo *ti = &vga_interfaces[t];
const VGAInterfaceInfo *ti = &vga_interfaces[t];
assert(t < VGA_TYPE_MAX);
return !ti->class_names[0] ||
@ -2069,14 +2069,42 @@ static bool vga_interface_available(VGAInterfaceType t)
object_class_by_name(ti->class_names[1]);
}
static void select_vgahw(const char *p)
static const char *
get_default_vga_model(const MachineClass *machine_class)
{
if (machine_class->default_display) {
return machine_class->default_display;
} else if (vga_interface_available(VGA_CIRRUS)) {
return "cirrus";
} else if (vga_interface_available(VGA_STD)) {
return "std";
}
return NULL;
}
static void select_vgahw(const MachineClass *machine_class, const char *p)
{
const char *opts;
int t;
if (g_str_equal(p, "help")) {
const char *def = get_default_vga_model(machine_class);
for (t = 0; t < VGA_TYPE_MAX; t++) {
const VGAInterfaceInfo *ti = &vga_interfaces[t];
if (vga_interface_available(t) && ti->opt_name) {
printf("%-20s %s%s\n", ti->opt_name, ti->name ?: "",
g_str_equal(ti->opt_name, def) ? " (default)" : "");
}
}
exit(0);
}
assert(vga_interface_type == VGA_NONE);
for (t = 0; t < VGA_TYPE_MAX; t++) {
VGAInterfaceInfo *ti = &vga_interfaces[t];
const VGAInterfaceInfo *ti = &vga_interfaces[t];
if (ti->opt_name && strstart(p, ti->opt_name, &opts)) {
if (!vga_interface_available(t)) {
error_report("%s not available", ti->name);
@ -4424,16 +4452,10 @@ int main(int argc, char **argv, char **envp)
/* If no default VGA is requested, the default is "none". */
if (default_vga) {
if (machine_class->default_display) {
vga_model = machine_class->default_display;
} else if (vga_interface_available(VGA_CIRRUS)) {
vga_model = "cirrus";
} else if (vga_interface_available(VGA_STD)) {
vga_model = "std";
}
vga_model = get_default_vga_model(machine_class);
}
if (vga_model) {
select_vgahw(vga_model);
select_vgahw(machine_class, vga_model);
}
if (watchdog) {