aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-05-07 21:39:28 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-05-07 21:39:28 +0100
commita6f6d24757a73f7176989134b97284a1a7df11e5 (patch)
tree0ff1de73d0b2d8623b0e237d1c5c3fb6ce779696
parentd6de7fed802f2bf42efdc0d081c67dc2ecf01e3f (diff)
parent6306cae275c7091aa4e785809d956b475bfedab4 (diff)
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>
-rw-r--r--hw/display/Kconfig5
-rw-r--r--hw/display/Makefile.objs1
-rw-r--r--hw/display/ati_2d.c12
-rw-r--r--hw/display/cirrus_vga.c10
-rw-r--r--hw/display/i2c-ddc.c (renamed from hw/i2c/i2c-ddc.c)2
-rw-r--r--hw/display/qxl.c58
-rw-r--r--hw/display/sii9022.c2
-rw-r--r--hw/display/sm501.c2
-rw-r--r--hw/i2c/Kconfig5
-rw-r--r--hw/i2c/Makefile.objs1
-rw-r--r--include/hw/display/i2c-ddc.h (renamed from include/hw/i2c/i2c-ddc.h)0
-rw-r--r--include/hw/display/xlnx_dp.h2
-rw-r--r--vl.c46
13 files changed, 84 insertions, 62 deletions
diff --git a/hw/display/Kconfig b/hw/display/Kconfig
index 72be57a403..c236cd2d0a 100644
--- a/hw/display/Kconfig
+++ b/hw/display/Kconfig
@@ -1,3 +1,8 @@
+config DDC
+ bool
+ depends on I2C
+ select EDID
+
config EDID
bool
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index dbd453ab1b..650031f725 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -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
diff --git a/hw/display/ati_2d.c b/hw/display/ati_2d.c
index bc98ba6eeb..fe3ae14864 100644
--- a/hw/display/ati_2d.c
+++ b/hw/display/ati_2d.c
@@ -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;
}
diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
index a0e71469f4..76c052c702 100644
--- a/hw/display/cirrus_vga.c
+++ b/hw/display/cirrus_vga.c
@@ -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"
/*
diff --git a/hw/i2c/i2c-ddc.c b/hw/display/i2c-ddc.c
index 7aa8727771..9fe5403a92 100644
--- a/hw/i2c/i2c-ddc.c
+++ b/hw/display/i2c-ddc.c
@@ -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
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index c8ce5781e0..3880a7410b 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -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 */
diff --git a/hw/display/sii9022.c b/hw/display/sii9022.c
index 9994385c35..9c36e4c17e 100644
--- a/hw/display/sii9022.c
+++ b/hw/display/sii9022.c
@@ -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
diff --git a/hw/display/sm501.c b/hw/display/sm501.c
index 2122291308..1e2709b2d0 100644
--- a/hw/display/sm501.c
+++ b/hw/display/sm501.c
@@ -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"
diff --git a/hw/i2c/Kconfig b/hw/i2c/Kconfig
index 820b24de5b..78a2008e3a 100644
--- a/hw/i2c/Kconfig
+++ b/hw/i2c/Kconfig
@@ -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
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index 5f76b6a990..d7073a401f 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -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
diff --git a/include/hw/i2c/i2c-ddc.h b/include/hw/display/i2c-ddc.h
index c29443c5af..c29443c5af 100644
--- a/include/hw/i2c/i2c-ddc.h
+++ b/include/hw/display/i2c-ddc.h
diff --git a/include/hw/display/xlnx_dp.h b/include/hw/display/xlnx_dp.h
index 26b759cd44..45a805033a 100644
--- a/include/hw/display/xlnx_dp.h
+++ b/include/hw/display/xlnx_dp.h
@@ -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"
diff --git a/vl.c b/vl.c
index d9fea0a119..b6709514c1 100644
--- a/vl.c
+++ b/vl.c
@@ -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) {