|
|
5544c1 |
From f5c2bd00890dc32e940e8b2fae09f62f758317eb Mon Sep 17 00:00:00 2001
|
|
Hans de Goede |
93b7e3 |
From: Alon Levy <alevy@redhat.com>
|
|
Hans de Goede |
93b7e3 |
Date: Wed, 12 Sep 2012 16:13:28 +0300
|
|
|
5544c1 |
Subject: [PATCH] hw/qxl: support client monitor configuration via device
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
Until now we used only the agent to change the monitor count and each
|
|
Hans de Goede |
93b7e3 |
monitor resolution. This patch introduces the qemu part of using the
|
|
Hans de Goede |
93b7e3 |
device as the mediator instead of the agent via virtio-serial.
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
Spice (>=0.11.5) calls the new QXLInterface::client_monitors_config,
|
|
Hans de Goede |
93b7e3 |
which returns wether the interrupt is enabled, and if so and given a non
|
|
Hans de Goede |
93b7e3 |
NULL monitors config will
|
|
Hans de Goede |
93b7e3 |
generate an interrupt QXL_INTERRUPT_CLIENT_MONITORS_CONFIG with crc
|
|
Hans de Goede |
93b7e3 |
checksum for the guest to verify a second call hasn't interfered.
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
The maximal number of monitors is limited on the QXLRom to 64.
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
Signed-off-by: Alon Levy <alevy@redhat.com>
|
|
Hans de Goede |
93b7e3 |
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
|
Hans de Goede |
93b7e3 |
---
|
|
Hans de Goede |
93b7e3 |
configure | 7 ++++++
|
|
Hans de Goede |
93b7e3 |
hw/qxl.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
Hans de Goede |
93b7e3 |
trace-events | 6 ++++-
|
|
Hans de Goede |
93b7e3 |
3 files changed, 91 insertions(+), 1 deletion(-)
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
diff --git a/configure b/configure
|
|
|
5544c1 |
index f528146..83c478c 100755
|
|
Hans de Goede |
93b7e3 |
--- a/configure
|
|
Hans de Goede |
93b7e3 |
+++ b/configure
|
|
|
5544c1 |
@@ -2706,6 +2706,9 @@ EOF
|
|
Hans de Goede |
93b7e3 |
if $pkg_config --atleast-version=0.12.0 spice-protocol >/dev/null 2>&1; then
|
|
Hans de Goede |
93b7e3 |
spice_qxl_io_monitors_config_async="yes"
|
|
Hans de Goede |
93b7e3 |
fi
|
|
Hans de Goede |
93b7e3 |
+ if $pkg_config --atleast-version=0.12.2 spice-protocol > /dev/null 2>&1; then
|
|
Hans de Goede |
93b7e3 |
+ spice_qxl_client_monitors_config="yes"
|
|
Hans de Goede |
93b7e3 |
+ fi
|
|
Hans de Goede |
93b7e3 |
else
|
|
Hans de Goede |
93b7e3 |
if test "$spice" = "yes" ; then
|
|
Hans de Goede |
93b7e3 |
feature_not_found "spice"
|
|
|
5544c1 |
@@ -3453,6 +3456,10 @@ if test "$spice_qxl_io_monitors_config_async" = "yes" ; then
|
|
Hans de Goede |
93b7e3 |
echo "CONFIG_QXL_IO_MONITORS_CONFIG_ASYNC=y" >> $config_host_mak
|
|
Hans de Goede |
93b7e3 |
fi
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
+if test "$spice_qxl_client_monitors_config" = "yes" ; then
|
|
Hans de Goede |
93b7e3 |
+ echo "CONFIG_QXL_CLIENT_MONITORS_CONFIG=y" >> $config_host_mak
|
|
Hans de Goede |
93b7e3 |
+fi
|
|
Hans de Goede |
93b7e3 |
+
|
|
Hans de Goede |
93b7e3 |
if test "$smartcard" = "yes" ; then
|
|
Hans de Goede |
93b7e3 |
echo "CONFIG_SMARTCARD=y" >> $config_host_mak
|
|
Hans de Goede |
93b7e3 |
fi
|
|
Hans de Goede |
93b7e3 |
diff --git a/hw/qxl.c b/hw/qxl.c
|
|
Hans de Goede |
93b7e3 |
index 1ef117a..0695872 100644
|
|
Hans de Goede |
93b7e3 |
--- a/hw/qxl.c
|
|
Hans de Goede |
93b7e3 |
+++ b/hw/qxl.c
|
|
Hans de Goede |
93b7e3 |
@@ -18,6 +18,8 @@
|
|
Hans de Goede |
93b7e3 |
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
Hans de Goede |
93b7e3 |
*/
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
+#include <zlib.h>
|
|
Hans de Goede |
93b7e3 |
+
|
|
Hans de Goede |
93b7e3 |
#include "qemu-common.h"
|
|
Hans de Goede |
93b7e3 |
#include "qemu-timer.h"
|
|
Hans de Goede |
93b7e3 |
#include "qemu-queue.h"
|
|
Hans de Goede |
93b7e3 |
@@ -971,6 +973,79 @@ static void interface_set_client_capabilities(QXLInstance *sin,
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
#endif
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
+#if defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG) \
|
|
Hans de Goede |
93b7e3 |
+ && SPICE_SERVER_VERSION >= 0x000b05
|
|
Hans de Goede |
93b7e3 |
+
|
|
Hans de Goede |
93b7e3 |
+static uint32_t qxl_crc32(const uint8_t *p, unsigned len)
|
|
Hans de Goede |
93b7e3 |
+{
|
|
Hans de Goede |
93b7e3 |
+ /*
|
|
Hans de Goede |
93b7e3 |
+ * zlib xors the seed with 0xffffffff, and xors the result
|
|
Hans de Goede |
93b7e3 |
+ * again with 0xffffffff; Both are not done with linux's crc32,
|
|
Hans de Goede |
93b7e3 |
+ * which we want to be compatible with, so undo that.
|
|
Hans de Goede |
93b7e3 |
+ */
|
|
Hans de Goede |
93b7e3 |
+ return crc32(0xffffffff, p, len) ^ 0xffffffff;
|
|
Hans de Goede |
93b7e3 |
+}
|
|
Hans de Goede |
93b7e3 |
+
|
|
Hans de Goede |
93b7e3 |
+/* called from main context only */
|
|
Hans de Goede |
93b7e3 |
+static int interface_client_monitors_config(QXLInstance *sin,
|
|
Hans de Goede |
93b7e3 |
+ VDAgentMonitorsConfig *monitors_config)
|
|
Hans de Goede |
93b7e3 |
+{
|
|
Hans de Goede |
93b7e3 |
+ PCIQXLDevice *qxl = container_of(sin, PCIQXLDevice, ssd.qxl);
|
|
Hans de Goede |
93b7e3 |
+ QXLRom *rom = memory_region_get_ram_ptr(&qxl->rom_bar);
|
|
Hans de Goede |
93b7e3 |
+ int i;
|
|
Hans de Goede |
93b7e3 |
+
|
|
Hans de Goede |
93b7e3 |
+ /*
|
|
Hans de Goede |
93b7e3 |
+ * Older windows drivers set int_mask to 0 when their ISR is called,
|
|
Hans de Goede |
93b7e3 |
+ * then later set it to ~0. So it doesn't relate to the actual interrupts
|
|
Hans de Goede |
93b7e3 |
+ * handled. However, they are old, so clearly they don't support this
|
|
Hans de Goede |
93b7e3 |
+ * interrupt
|
|
Hans de Goede |
93b7e3 |
+ */
|
|
Hans de Goede |
93b7e3 |
+ if (qxl->ram->int_mask == 0 || qxl->ram->int_mask == ~0 ||
|
|
Hans de Goede |
93b7e3 |
+ !(qxl->ram->int_mask & QXL_INTERRUPT_CLIENT_MONITORS_CONFIG)) {
|
|
Hans de Goede |
93b7e3 |
+ trace_qxl_client_monitors_config_unsupported_by_guest(qxl->id,
|
|
Hans de Goede |
93b7e3 |
+ qxl->ram->int_mask,
|
|
Hans de Goede |
93b7e3 |
+ monitors_config);
|
|
Hans de Goede |
93b7e3 |
+ return 0;
|
|
Hans de Goede |
93b7e3 |
+ }
|
|
Hans de Goede |
93b7e3 |
+ if (!monitors_config) {
|
|
Hans de Goede |
93b7e3 |
+ return 1;
|
|
Hans de Goede |
93b7e3 |
+ }
|
|
Hans de Goede |
93b7e3 |
+ memset(&rom->client_monitors_config, 0,
|
|
Hans de Goede |
93b7e3 |
+ sizeof(rom->client_monitors_config));
|
|
Hans de Goede |
93b7e3 |
+ rom->client_monitors_config.count = monitors_config->num_of_monitors;
|
|
Hans de Goede |
93b7e3 |
+ /* monitors_config->flags ignored */
|
|
Hans de Goede |
93b7e3 |
+ if (rom->client_monitors_config.count >=
|
|
Hans de Goede |
93b7e3 |
+ ARRAY_SIZE(rom->client_monitors_config.heads)) {
|
|
Hans de Goede |
93b7e3 |
+ trace_qxl_client_monitors_config_capped(qxl->id,
|
|
Hans de Goede |
93b7e3 |
+ monitors_config->num_of_monitors,
|
|
Hans de Goede |
93b7e3 |
+ ARRAY_SIZE(rom->client_monitors_config.heads));
|
|
Hans de Goede |
93b7e3 |
+ rom->client_monitors_config.count =
|
|
Hans de Goede |
93b7e3 |
+ ARRAY_SIZE(rom->client_monitors_config.heads);
|
|
Hans de Goede |
93b7e3 |
+ }
|
|
Hans de Goede |
93b7e3 |
+ for (i = 0 ; i < rom->client_monitors_config.count ; ++i) {
|
|
Hans de Goede |
93b7e3 |
+ VDAgentMonConfig *monitor = &monitors_config->monitors[i];
|
|
Hans de Goede |
93b7e3 |
+ QXLURect *rect = &rom->client_monitors_config.heads[i];
|
|
Hans de Goede |
93b7e3 |
+ /* monitor->depth ignored */
|
|
Hans de Goede |
93b7e3 |
+ rect->left = monitor->x;
|
|
Hans de Goede |
93b7e3 |
+ rect->top = monitor->y;
|
|
Hans de Goede |
93b7e3 |
+ rect->right = monitor->x + monitor->width;
|
|
Hans de Goede |
93b7e3 |
+ rect->bottom = monitor->y + monitor->height;
|
|
Hans de Goede |
93b7e3 |
+ }
|
|
Hans de Goede |
93b7e3 |
+ rom->client_monitors_config_crc = qxl_crc32(
|
|
Hans de Goede |
93b7e3 |
+ (const uint8_t *)&rom->client_monitors_config,
|
|
Hans de Goede |
93b7e3 |
+ sizeof(rom->client_monitors_config));
|
|
Hans de Goede |
93b7e3 |
+ trace_qxl_client_monitors_config_crc(qxl->id,
|
|
Hans de Goede |
93b7e3 |
+ sizeof(rom->client_monitors_config),
|
|
Hans de Goede |
93b7e3 |
+ rom->client_monitors_config_crc);
|
|
Hans de Goede |
93b7e3 |
+
|
|
Hans de Goede |
93b7e3 |
+ trace_qxl_interrupt_client_monitors_config(qxl->id,
|
|
Hans de Goede |
93b7e3 |
+ rom->client_monitors_config.count,
|
|
Hans de Goede |
93b7e3 |
+ rom->client_monitors_config.heads);
|
|
Hans de Goede |
93b7e3 |
+ qxl_send_events(qxl, QXL_INTERRUPT_CLIENT_MONITORS_CONFIG);
|
|
Hans de Goede |
93b7e3 |
+ return 1;
|
|
Hans de Goede |
93b7e3 |
+}
|
|
Hans de Goede |
93b7e3 |
+#endif
|
|
Hans de Goede |
93b7e3 |
+
|
|
Hans de Goede |
93b7e3 |
static const QXLInterface qxl_interface = {
|
|
Hans de Goede |
93b7e3 |
.base.type = SPICE_INTERFACE_QXL,
|
|
Hans de Goede |
93b7e3 |
.base.description = "qxl gpu",
|
|
Hans de Goede |
93b7e3 |
@@ -995,6 +1070,10 @@ static const QXLInterface qxl_interface = {
|
|
Hans de Goede |
93b7e3 |
#if SPICE_SERVER_VERSION >= 0x000b04
|
|
Hans de Goede |
93b7e3 |
.set_client_capabilities = interface_set_client_capabilities,
|
|
Hans de Goede |
93b7e3 |
#endif
|
|
Hans de Goede |
93b7e3 |
+#if SPICE_SERVER_VERSION >= 0x000b05 && \
|
|
Hans de Goede |
93b7e3 |
+ defined(CONFIG_QXL_CLIENT_MONITORS_CONFIG)
|
|
Hans de Goede |
93b7e3 |
+ .client_monitors_config = interface_client_monitors_config,
|
|
Hans de Goede |
93b7e3 |
+#endif
|
|
Hans de Goede |
93b7e3 |
};
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
static void qxl_enter_vga_mode(PCIQXLDevice *d)
|
|
Hans de Goede |
93b7e3 |
diff --git a/trace-events b/trace-events
|
|
|
5544c1 |
index 80a52d9..07b63f1 100644
|
|
Hans de Goede |
93b7e3 |
--- a/trace-events
|
|
Hans de Goede |
93b7e3 |
+++ b/trace-events
|
|
|
5544c1 |
@@ -930,7 +930,7 @@ qxl_interface_update_area_complete_rest(int qid, uint32_t num_updated_rects) "%d
|
|
Hans de Goede |
93b7e3 |
qxl_interface_update_area_complete_overflow(int qid, int max) "%d max=%d"
|
|
Hans de Goede |
93b7e3 |
qxl_interface_update_area_complete_schedule_bh(int qid, uint32_t num_dirty) "%d #dirty=%d"
|
|
Hans de Goede |
93b7e3 |
qxl_io_destroy_primary_ignored(int qid, const char *mode) "%d %s"
|
|
Hans de Goede |
93b7e3 |
-qxl_io_log(int qid, const uint8_t *str) "%d %s"
|
|
Hans de Goede |
93b7e3 |
+qxl_io_log(int qid, const uint8_t *log_buf) "%d %s"
|
|
Hans de Goede |
93b7e3 |
qxl_io_read_unexpected(int qid) "%d"
|
|
Hans de Goede |
93b7e3 |
qxl_io_unexpected_vga_mode(int qid, uint64_t addr, uint64_t val, const char *desc) "%d 0x%"PRIx64"=%"PRIu64" (%s)"
|
|
Hans de Goede |
93b7e3 |
qxl_io_write(int qid, const char *mode, uint64_t addr, uint64_t val, unsigned size, int async) "%d %s addr=%"PRIu64 " val=%"PRIu64" size=%u async=%d"
|
|
|
5544c1 |
@@ -974,6 +974,10 @@ qxl_spice_update_area_rest(int qid, uint32_t num_dirty_rects, uint32_t clear_dir
|
|
Hans de Goede |
93b7e3 |
qxl_surfaces_dirty(int qid, int surface, int offset, int size) "%d surface=%d offset=%d size=%d"
|
|
Hans de Goede |
93b7e3 |
qxl_send_events(int qid, uint32_t events) "%d %d"
|
|
Hans de Goede |
93b7e3 |
qxl_set_guest_bug(int qid) "%d"
|
|
Hans de Goede |
93b7e3 |
+qxl_interrupt_client_monitors_config(int qid, int num_heads, void *heads) "%d %d %p"
|
|
Hans de Goede |
93b7e3 |
+qxl_client_monitors_config_unsupported_by_guest(int qid, uint32_t int_mask, void *client_monitors_config) "%d %X %p"
|
|
Hans de Goede |
93b7e3 |
+qxl_client_monitors_config_capped(int qid, int requested, int limit) "%d %d %d"
|
|
Hans de Goede |
93b7e3 |
+qxl_client_monitors_config_crc(int qid, unsigned size, uint32_t crc32) "%d %u %u"
|
|
Hans de Goede |
93b7e3 |
|
|
Hans de Goede |
93b7e3 |
# hw/qxl-render.c
|
|
Hans de Goede |
93b7e3 |
qxl_render_blit_guest_primary_initialized(void) ""
|
|
Hans de Goede |
93b7e3 |
--
|
|
|
5544c1 |
1.7.12.1
|
|
Hans de Goede |
93b7e3 |
|