vmmouse_proto.c revision 8746cb53
1/*
2 * Copyright 1999-2006 by VMware, Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Except as contained in this notice, the name of the copyright holder(s)
23 * and author(s) shall not be used in advertising or otherwise to promote
24 * the sale, use or other dealings in this Software without prior written
25 * authorization from the copyright holder(s) and author(s).
26 */
27
28/*
29 * vmmouse_proto.c --
30 *
31 *      The communication protocol between the guest and the vmmouse
32 *      virtual device.
33 */
34
35
36#ifdef HAVE_CONFIG_H
37#include "config.h"
38#endif
39
40#include "vmmouse_proto.h"
41
42
43/*
44 *----------------------------------------------------------------------------
45 *
46 * VMMouseProtoInOut --
47 *
48 *      Send a low-bandwidth basic request (16 bytes) to vmware, and return its
49 *      reply (24 bytes).
50 *
51 * Results:
52 *      Host-side response returned in cmd IN/OUT parameter.
53 *
54 * Side effects:
55 *      Pokes the communication port.
56 *
57 *----------------------------------------------------------------------------
58 */
59
60static void
61VMMouseProtoInOut(VMMouseProtoCmd *cmd) // IN/OUT
62{
63#ifdef __x86_64__
64   uint64_t dummy;
65
66   __asm__ __volatile__(
67        "pushq %%rax"           "\n\t"
68        "movq 40(%%rax), %%rdi" "\n\t"
69        "movq 32(%%rax), %%rsi" "\n\t"
70        "movq 24(%%rax), %%rdx" "\n\t"
71        "movq 16(%%rax), %%rcx" "\n\t"
72        "movq  8(%%rax), %%rbx" "\n\t"
73        "movq   (%%rax), %%rax" "\n\t"
74        "inl %%dx, %%eax"       "\n\t"  /* NB: There is no inq instruction */
75        "xchgq %%rax, (%%rsp)"  "\n\t"
76        "movq %%rdi, 40(%%rax)" "\n\t"
77        "movq %%rsi, 32(%%rax)" "\n\t"
78        "movq %%rdx, 24(%%rax)" "\n\t"
79        "movq %%rcx, 16(%%rax)" "\n\t"
80        "movq %%rbx,  8(%%rax)" "\n\t"
81        "popq          (%%rax)"
82      : "=a" (dummy)
83      : "0" (cmd)
84      /*
85       * vmware can modify the whole VM state without the compiler knowing
86       * it. So far it does not modify EFLAGS. --hpreg
87       */
88      : "rbx", "rcx", "rdx", "rsi", "rdi", "memory"
89   );
90#else
91#ifdef __i386__
92   uint32_t dummy;
93
94   __asm__ __volatile__(
95        "pushl %%ebx"           "\n\t"
96        "pushl %%eax"           "\n\t"
97        "movl 20(%%eax), %%edi" "\n\t"
98        "movl 16(%%eax), %%esi" "\n\t"
99        "movl 12(%%eax), %%edx" "\n\t"
100        "movl  8(%%eax), %%ecx" "\n\t"
101        "movl  4(%%eax), %%ebx" "\n\t"
102        "movl   (%%eax), %%eax" "\n\t"
103        "inl %%dx, %%eax"       "\n\t"
104        "xchgl %%eax, (%%esp)"  "\n\t"
105        "movl %%edi, 20(%%eax)" "\n\t"
106        "movl %%esi, 16(%%eax)" "\n\t"
107        "movl %%edx, 12(%%eax)" "\n\t"
108        "movl %%ecx,  8(%%eax)" "\n\t"
109        "movl %%ebx,  4(%%eax)" "\n\t"
110        "popl          (%%eax)" "\n\t"
111        "popl           %%ebx"
112      : "=a" (dummy)
113      : "0" (cmd)
114      /*
115       * vmware can modify the whole VM state without the compiler knowing
116       * it. So far it does not modify EFLAGS. --hpreg
117       */
118      : "ecx", "edx", "esi", "edi", "memory"
119   );
120#else
121#error "VMMouse is only supported on x86 and x86-64."
122#endif
123#endif
124}
125
126
127/*
128 *-----------------------------------------------------------------------------
129 *
130 * VMMouseProto_SendCmd --
131 *
132 *      Send a request (16 bytes) to vmware, and synchronously return its
133 *      reply (24 bytes).
134 *
135 * Result:
136 *      None
137 *
138 * Side-effects:
139 *      None
140 *
141 *-----------------------------------------------------------------------------
142 */
143
144void
145VMMouseProto_SendCmd(VMMouseProtoCmd *cmd) // IN/OUT
146{
147   cmd->in.magic = VMMOUSE_PROTO_MAGIC;
148   cmd->in.port = VMMOUSE_PROTO_PORT;
149
150   VMMouseProtoInOut(cmd);
151}
152