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