* [Qemu-devel] [PATCH] Share Vmware communication port between devices
@ 2007-08-21 18:17 Hervé Poussineau
2007-08-21 18:38 ` Anthony Liguori
0 siblings, 1 reply; 6+ messages in thread
From: Hervé Poussineau @ 2007-08-21 18:17 UTC (permalink / raw)
To: qemu-devel
[-- Attachment #1: Type: text/plain, Size: 847 bytes --]
Hi,
VMware registers the port 0x5658 to communicate between guest and host.
At the moment, vmmouse.c is the only one to use this communication channel,
so it registers the port. IMO, this design is not right because it will be
hard to implement other functionalities of VMware.
I extracted non-mouse part from this file and created a framework for VMware
communication in a new file. Devices can then register for specific
commands, so communication port will be shared between devices.
I also added support for "Get RAM size" command. More commands will be added
later.
Attached files:
0 - vmmouse-formatting.diff
Replace tabs by 8 spaces. No code change
1 - adding-vmport.diff
Add a generic framework for VMware communication port
2 - vmmouse-using-vmport.diff
Use the framework for the VMware mouse emulation
Hervé
[-- Attachment #2: 0 - vmmouse-formatting.diff --]
[-- Type: application/octet-stream, Size: 5955 bytes --]
Index: hw/vmmouse.c
===================================================================
RCS file: /cvsroot/qemu/qemu/hw/vmmouse.c,v
retrieving revision 1.1
diff -u -r1.1 vmmouse.c
--- hw/vmmouse.c 20 Mar 2007 16:45:27 -0000 1.1
+++ hw/vmmouse.c 21 Aug 2007 10:05:21 -0000
@@ -77,21 +77,21 @@
int buttons = 0;
if (s->nb_queue > (VMMOUSE_QUEUE_SIZE - 4))
- return;
+ return;
DPRINTF("vmmouse_mouse_event(%d, %d, %d, %d)\n",
- x, y, dz, buttons_state);
+ x, y, dz, buttons_state);
if ((buttons_state & MOUSE_EVENT_LBUTTON))
- buttons |= 0x20;
+ buttons |= 0x20;
if ((buttons_state & MOUSE_EVENT_RBUTTON))
- buttons |= 0x10;
+ buttons |= 0x10;
if ((buttons_state & MOUSE_EVENT_MBUTTON))
- buttons |= 0x08;
+ buttons |= 0x08;
if (s->absolute) {
- x <<= 1;
- y <<= 1;
+ x <<= 1;
+ y <<= 1;
}
s->queue[s->nb_queue++] = buttons;
@@ -107,13 +107,13 @@
static void vmmouse_update_handler(VMMouseState *s)
{
if (s->entry) {
- qemu_remove_mouse_event_handler(s->entry);
- s->entry = NULL;
+ qemu_remove_mouse_event_handler(s->entry);
+ s->entry = NULL;
}
if (s->status == 0)
- s->entry = qemu_add_mouse_event_handler(vmmouse_mouse_event,
- s, s->absolute,
- "vmmouse");
+ s->entry = qemu_add_mouse_event_handler(vmmouse_mouse_event,
+ s, s->absolute,
+ "vmmouse");
}
static void vmmouse_read_id(VMMouseState *s)
@@ -121,7 +121,7 @@
DPRINTF("vmmouse_read_id()\n");
if (s->nb_queue == VMMOUSE_QUEUE_SIZE)
- return;
+ return;
s->queue[s->nb_queue++] = VMMOUSE_VERSION;
s->status = 0;
@@ -156,18 +156,18 @@
DPRINTF("vmmouse_data(%d)\n", size);
if (size == 0 || size > 6 || size > s->nb_queue) {
- printf("vmmouse: driver requested too much data %d\n", size);
- s->status = 0xffff;
- vmmouse_update_handler(s);
- return;
+ printf("vmmouse: driver requested too much data %d\n", size);
+ s->status = 0xffff;
+ vmmouse_update_handler(s);
+ return;
}
for (i = 0; i < size; i++)
- data[i] = s->queue[i];
+ data[i] = s->queue[i];
s->nb_queue -= size;
if (s->nb_queue)
- memmove(s->queue, &s->queue[size], sizeof(s->queue[0]) * s->nb_queue);
+ memmove(s->queue, &s->queue[size], sizeof(s->queue[0]) * s->nb_queue);
}
static void vmmouse_get_data(uint32_t *data)
@@ -179,7 +179,7 @@
data[4] = env->regs[R_ESI]; data[5] = env->regs[R_EDI];
DPRINTF("get_data = {%x, %x, %x, %x, %x, %x}\n",
- data[0], data[1], data[2], data[3], data[4], data[5]);
+ data[0], data[1], data[2], data[3], data[4], data[5]);
}
static void vmmouse_set_data(const uint32_t *data)
@@ -187,7 +187,7 @@
CPUState *env = cpu_single_env;
DPRINTF("set_data = {%x, %x, %x, %x, %x, %x}\n",
- data[0], data[1], data[2], data[3], data[4], data[5]);
+ data[0], data[1], data[2], data[3], data[4], data[5]);
env->regs[R_EAX] = data[0]; env->regs[R_EBX] = data[1];
env->regs[R_ECX] = data[2]; env->regs[R_EDX] = data[3];
@@ -202,42 +202,42 @@
vmmouse_get_data(data);
if (data[0] != VMMOUSE_MAGIC)
- goto error;
+ goto error;
command = data[2] & 0xFFFF;
switch (command) {
case VMMOUSE_GETVERSION:
- data[0] = vmmouse_get_version(s, &data[1]);
- break;
+ data[0] = vmmouse_get_version(s, &data[1]);
+ break;
case VMMOUSE_STATUS:
- data[0] = vmmouse_get_status(s);
- break;
+ data[0] = vmmouse_get_status(s);
+ break;
case VMMOUSE_COMMAND:
- switch (data[1]) {
- case VMMOUSE_DISABLE:
- vmmouse_disable(s);
- break;
- case VMMOUSE_READ_ID:
- vmmouse_read_id(s);
- break;
- case VMMOUSE_REQUEST_RELATIVE:
- vmmouse_request_relative(s);
- break;
- case VMMOUSE_REQUEST_ABSOLUTE:
- vmmouse_request_absolute(s);
- break;
- default:
- printf("vmmouse: unknown command %x\n", data[1]);
- break;
- }
- break;
+ switch (data[1]) {
+ case VMMOUSE_DISABLE:
+ vmmouse_disable(s);
+ break;
+ case VMMOUSE_READ_ID:
+ vmmouse_read_id(s);
+ break;
+ case VMMOUSE_REQUEST_RELATIVE:
+ vmmouse_request_relative(s);
+ break;
+ case VMMOUSE_REQUEST_ABSOLUTE:
+ vmmouse_request_absolute(s);
+ break;
+ default:
+ printf("vmmouse: unknown command %x\n", data[1]);
+ break;
+ }
+ break;
case VMMOUSE_DATA:
- vmmouse_data(s, data, data[1]);
- break;
+ vmmouse_data(s, data, data[1]);
+ break;
default:
- printf("vmmouse: unknown command %x\n", command);
- break;
+ printf("vmmouse: unknown command %x\n", command);
+ break;
}
error:
@@ -252,7 +252,7 @@
qemu_put_be32(f, VMMOUSE_QUEUE_SIZE);
for (i = 0; i < VMMOUSE_QUEUE_SIZE; i++)
- qemu_put_be32s(f, &s->queue[i]);
+ qemu_put_be32s(f, &s->queue[i]);
qemu_put_be16s(f, &s->nb_queue);
qemu_put_be16s(f, &s->status);
qemu_put_8s(f, &s->absolute);
@@ -267,9 +267,9 @@
return -EINVAL;
if (qemu_get_be32(f) != VMMOUSE_QUEUE_SIZE)
- return -EINVAL;
+ return -EINVAL;
for (i = 0; i < VMMOUSE_QUEUE_SIZE; i++)
- qemu_get_be32s(f, &s->queue[i]);
+ qemu_get_be32s(f, &s->queue[i]);
qemu_get_be16s(f, &s->nb_queue);
qemu_get_be16s(f, &s->status);
qemu_get_8s(f, &s->absolute);
@@ -287,7 +287,7 @@
s = qemu_mallocz(sizeof(VMMouseState));
if (!s)
- return NULL;
+ return NULL;
s->status = 0xffff;
s->ps2_mouse = m;
[-- Attachment #3: 1 - adding-vmport.diff --]
[-- Type: application/octet-stream, Size: 4569 bytes --]
Index: Makefile.target
===================================================================
RCS file: /cvsroot/qemu/qemu/Makefile.target,v
retrieving revision 1.191
diff -u -r1.191 Makefile.target
--- Makefile.target 31 Jul 2007 23:44:21 -0000 1.191
+++ Makefile.target 21 Aug 2007 09:20:39 -0000
@@ -428,7 +428,7 @@
VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV)
VL_OBJS+= fdc.o mc146818rtc.o serial.o i8259.o i8254.o pcspk.o pc.o
VL_OBJS+= cirrus_vga.o apic.o parallel.o acpi.o piix_pci.o
-VL_OBJS+= usb-uhci.o smbus_eeprom.o vmmouse.o vmware_vga.o
+VL_OBJS+= usb-uhci.o smbus_eeprom.o vmmouse.o vmport.o vmware_vga.o
CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
endif
ifeq ($(TARGET_BASE_ARCH), ppc)
Index: vl.h
===================================================================
RCS file: /cvsroot/qemu/qemu/vl.h,v
retrieving revision 1.261
diff -u -r1.261 vl.h
--- vl.h 19 Aug 2007 21:56:03 -0000 1.261
+++ vl.h 21 Aug 2007 09:20:49 -0000
@@ -1058,6 +1058,12 @@
/* vmmouse.c */
void *vmmouse_init(void *m);
+/* vmport.c */
+#ifdef TARGET_I386
+void vmport_init(CPUState *env);
+void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque);
+#endif
+
/* pckbd.c */
void i8042_init(qemu_irq kbd_irq, qemu_irq mouse_irq, uint32_t io_base);
Index: hw/vmport.c
===================================================================
diff -u /dev/null hw/vmport.c
--- /dev/null Tue Aug 21 09:51:19 2007
+++ hw/vmport.c Tue Aug 21 09:45:40 2007
@@ -0,0 +1,96 @@
+/*
+ * QEMU VMPort emulation
+ *
+ * Copyright (C) 2007 Hervé Poussineau
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "vl.h"
+#include "cpu-all.h"
+
+#define VMPORT_CMD_GETVERSION 0x0a
+#define VMPORT_CMD_GETRAMSIZE 0x14
+
+#define VMPORT_ENTRIES 0x2c
+#define VMPORT_MAGIC 0x564D5868
+
+typedef struct _VMPortState
+{
+ CPUState *env;
+ IOPortReadFunc *func[VMPORT_ENTRIES];
+ void *opaque[VMPORT_ENTRIES];
+} VMPortState;
+
+static VMPortState port_state;
+
+void vmport_register(unsigned char command, IOPortReadFunc *func, void *opaque)
+{
+ if (command >= VMPORT_ENTRIES)
+ return;
+
+ port_state.func[command] = func;
+ port_state.opaque[command] = opaque;
+}
+
+static uint32_t vmport_ioport_read(void *opaque, uint32_t addr)
+{
+ VMPortState *s = opaque;
+ unsigned char command;
+ target_ulong eax;
+
+ eax = s->env->regs[R_EAX];
+ if (eax != VMPORT_MAGIC)
+ return eax;
+
+ command = s->env->regs[R_ECX];
+ if (command >= VMPORT_ENTRIES)
+ return eax;
+ if (!s->func[command])
+ {
+ printf("vmport: unknown command %x\n", command);
+ return eax;
+ }
+
+ return s->func[command](s->opaque[command], addr);
+}
+
+static uint32_t vmport_cmd_get_version(void *opaque, uint32_t addr)
+{
+ CPUState *env = opaque;
+ env->regs[R_EBX] = VMPORT_MAGIC;
+ return 6;
+}
+
+static uint32_t vmport_cmd_ram_size(void *opaque, uint32_t addr)
+{
+ CPUState *env = opaque;
+ env->regs[R_EBX] = 0x1177;
+ return ram_size;
+}
+
+void vmport_init(CPUState *env)
+{
+ port_state.env = env;
+
+ register_ioport_read(0x5658, 1, 4, vmport_ioport_read, &port_state);
+
+ /* Register some generic port commands */
+ vmport_register(VMPORT_CMD_GETVERSION, vmport_cmd_get_version, env);
+ vmport_register(VMPORT_CMD_GETRAMSIZE, vmport_cmd_ram_size, env);
+}
[-- Attachment #4: 2 - vmmouse-using-vmport.diff --]
[-- Type: application/octet-stream, Size: 2132 bytes --]
Index: hw/pc.c
===================================================================
RCS file: /cvsroot/qemu/qemu/hw/pc.c,v
retrieving revision 1.81
diff -u -r1.81 pc.c
--- hw/pc.c 6 Jun 2007 16:26:13 -0000 1.81
+++ hw/pc.c 21 Aug 2007 09:20:52 -0000
@@ -692,6 +692,7 @@
if (pci_enabled) {
apic_init(env);
}
+ vmport_init(env);
}
/* allocate RAM */
Index: hw/vmmouse.c
===================================================================
RCS file: /cvsroot/qemu/qemu/hw/vmmouse.c,v
retrieving revision 1.1
diff -u -r1.1 vmmouse.c
--- hw/vmmouse.c 20 Mar 2007 16:45:27 -0000 1.1
+++ hw/vmmouse.c 21 Aug 2007 09:20:53 -0000
@@ -39,7 +39,6 @@
#define VMMOUSE_QUEUE_SIZE 1024
-#define VMMOUSE_MAGIC 0x564D5868
#define VMMOUSE_VERSION 0x3442554a
#ifdef DEBUG_VMMOUSE
@@ -58,13 +57,6 @@
void *ps2_mouse;
} VMMouseState;
-static uint32_t vmmouse_get_version(VMMouseState *s, uint32_t *magic)
-{
- DPRINTF("vmmouse_get_version(%x)\n", *magic);
- *magic = VMMOUSE_MAGIC;
- return VMMOUSE_VERSION;
-}
-
static uint32_t vmmouse_get_status(VMMouseState *s)
{
DPRINTF("vmmouse_get_status()\n");
@@ -201,15 +193,10 @@
uint16_t command;
vmmouse_get_data(data);
- if (data[0] != VMMOUSE_MAGIC)
- goto error;
command = data[2] & 0xFFFF;
switch (command) {
- case VMMOUSE_GETVERSION:
- data[0] = vmmouse_get_version(s, &data[1]);
- break;
case VMMOUSE_STATUS:
data[0] = vmmouse_get_status(s);
break;
@@ -240,7 +227,6 @@
break;
}
-error:
vmmouse_set_data(data);
return data[0];
}
@@ -292,7 +278,9 @@
s->status = 0xffff;
s->ps2_mouse = m;
- register_ioport_read(0x5658, 1, 4, vmmouse_ioport_read, s);
+ vmport_register(VMMOUSE_STATUS, vmmouse_ioport_read, s);
+ vmport_register(VMMOUSE_COMMAND, vmmouse_ioport_read, s);
+ vmport_register(VMMOUSE_DATA, vmmouse_ioport_read, s);
register_savevm("vmmouse", 0, 0, vmmouse_save, vmmouse_load, s);
return s;
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH] Share Vmware communication port between devices
2007-08-21 18:17 [Qemu-devel] [PATCH] Share Vmware communication port between devices Hervé Poussineau
@ 2007-08-21 18:38 ` Anthony Liguori
2007-08-21 19:16 ` Thomas Frey
0 siblings, 1 reply; 6+ messages in thread
From: Anthony Liguori @ 2007-08-21 18:38 UTC (permalink / raw)
To: qemu-devel
On Tue, 2007-08-21 at 20:17 +0200, Hervé Poussineau wrote:
> Hi,
>
> VMware registers the port 0x5658 to communicate between guest and host.
> At the moment, vmmouse.c is the only one to use this communication channel,
> so it registers the port. IMO, this design is not right because it will be
> hard to implement other functionalities of VMware.
>
> I extracted non-mouse part from this file and created a framework for VMware
> communication in a new file. Devices can then register for specific
> commands, so communication port will be shared between devices.
> I also added support for "Get RAM size" command. More commands will be added
> later.
What other things are used for this port and where is it documented?
What is the "Get RAM size" command used by?
AFAIK, the vmware tools have a EULA that prevents them from being used
in QEMU guests. Unless there's an open source driver that uses these
commands, I don't see the use of supporting them if the drivers are
restricted from being used within QEMU.
Regards,
Anthony Liguori
> Attached files:
> 0 - vmmouse-formatting.diff
> Replace tabs by 8 spaces. No code change
> 1 - adding-vmport.diff
> Add a generic framework for VMware communication port
> 2 - vmmouse-using-vmport.diff
> Use the framework for the VMware mouse emulation
>
> Hervé
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH] Share Vmware communication port between devices
2007-08-21 18:38 ` Anthony Liguori
@ 2007-08-21 19:16 ` Thomas Frey
0 siblings, 0 replies; 6+ messages in thread
From: Thomas Frey @ 2007-08-21 19:16 UTC (permalink / raw)
To: qemu-devel
On 8/21/07, Anthony Liguori <anthony@codemonkey.ws> wrote:
>
> On Tue, 2007-08-21 at 20:17 +0200, Hervé Poussineau wrote:
> > Hi,
> >
> > VMware registers the port 0x5658 to communicate between guest and host.
> > At the moment, vmmouse.c is the only one to use this communication channel,
> > so it registers the port. IMO, this design is not right because it will be
> > hard to implement other functionalities of VMware.
> >
> > I extracted non-mouse part from this file and created a framework for VMware
> > communication in a new file. Devices can then register for specific
> > commands, so communication port will be shared between devices.
> > I also added support for "Get RAM size" command. More commands will be added
> > later.
>
> What other things are used for this port and where is it documented?
> What is the "Get RAM size" command used by?
>
> AFAIK, the vmware tools have a EULA that prevents them from being used
> in QEMU guests. Unless there's an open source driver that uses these
> commands, I don't see the use of supporting them if the drivers are
> restricted from being used within QEMU.
There are open source implementations for this interface. E.g. the
Bluebottle OS (ETH Zuerich) has such an implementation.
(In recent builds there are some installation issues on QEmu with ATA
detection, ask if you want to try. I can extract and upload/mail the
respective source if it is of any help)
--Thomas
^ permalink raw reply [flat|nested] 6+ messages in thread
* [Qemu-devel] [PATCH] Share Vmware communication port between devices
@ 2007-08-21 20:10 Hervé Poussineau
2007-08-21 21:10 ` Anthony Liguori
0 siblings, 1 reply; 6+ messages in thread
From: Hervé Poussineau @ 2007-08-21 20:10 UTC (permalink / raw)
To: qemu-devel
Hi,
Some more information about the VMware backdoor can be found at:
http://chitchat.at.infoseek.co.jp/vmware/backdoor.html
Hervé
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [Qemu-devel] [PATCH] Share Vmware communication port between devices
2007-08-21 20:10 [Qemu-devel] [PATCH] Share Vmware communication port between devices Hervé Poussineau
@ 2007-08-21 21:10 ` Anthony Liguori
2007-08-21 21:49 ` [Qemu-devel] [PATCH] Share Vmware communication port betweendevices Dor Laor
0 siblings, 1 reply; 6+ messages in thread
From: Anthony Liguori @ 2007-08-21 21:10 UTC (permalink / raw)
To: qemu-devel
On Tue, 2007-08-21 at 22:10 +0200, Hervé Poussineau wrote:
> Hi,
>
> Some more information about the VMware backdoor can be found at:
> http://chitchat.at.infoseek.co.jp/vmware/backdoor.html
Are there interesting apps that make use of this? I really don't like
the idea of supporting this PV protocol if we're not going to get
interesting apps out of it. The project you referenced earlier didn't
have source code available (you had to request it privately) and I don't
think it's being generally used.
The problem with this particular protocol is that it's inherently
x86-specific b/c it depends on doing PIO in userspace. If we're just
looking to get this functionality, it would be better to do it as a PCI
device or something that could actually work on non-x86 architectures.
In my mind, vmmouse was worth implementing since the driver already
exists and was packaged in a number of distros.
Regards,
Anthony Liguori
> Hervé
>
>
>
^ permalink raw reply [flat|nested] 6+ messages in thread
* RE: [Qemu-devel] [PATCH] Share Vmware communication port betweendevices
2007-08-21 21:10 ` Anthony Liguori
@ 2007-08-21 21:49 ` Dor Laor
0 siblings, 0 replies; 6+ messages in thread
From: Dor Laor @ 2007-08-21 21:49 UTC (permalink / raw)
To: qemu-devel
>> Hi,
>>
>> Some more information about the VMware backdoor can be found at:
>> http://chitchat.at.infoseek.co.jp/vmware/backdoor.html
>
>Are there interesting apps that make use of this? I really don't like
>the idea of supporting this PV protocol if we're not going to get
>interesting apps out of it. The project you referenced earlier didn't
>have source code available (you had to request it privately) and I don't
>think it's being generally used.
>
>The problem with this particular protocol is that it's inherently
>x86-specific b/c it depends on doing PIO in userspace. If we're just
>looking to get this functionality, it would be better to do it as a PCI
>device or something that could actually work on non-x86 architectures.
Actually we have implemented such device + driver in qemu for kvm.
You can check out the code, currently is uses ioport too but is accessed
by guest pci driver.
It is called vmchannel device. From the guest view it's a pci device.
From the host view it's a qemu device that can be contacted as a socket/file/..
It is used for mgmt proposes.
--Dor
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2007-08-21 21:50 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-08-21 20:10 [Qemu-devel] [PATCH] Share Vmware communication port between devices Hervé Poussineau
2007-08-21 21:10 ` Anthony Liguori
2007-08-21 21:49 ` [Qemu-devel] [PATCH] Share Vmware communication port betweendevices Dor Laor
-- strict thread matches above, loose matches on Subject: below --
2007-08-21 18:17 [Qemu-devel] [PATCH] Share Vmware communication port between devices Hervé Poussineau
2007-08-21 18:38 ` Anthony Liguori
2007-08-21 19:16 ` Thomas Frey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).