vmwgfx_msg.h revision 1.2 1 /* $NetBSD: vmwgfx_msg.h,v 1.2 2021/12/18 23:45:45 riastradh Exp $ */
2
3 /* SPDX-License-Identifier: GPL-2.0+ OR MIT */
4 /**************************************************************************
5 *
6 * Copyright 2016 VMware, Inc., Palo Alto, CA., USA
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
23 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
24 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
26 * USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
28 **************************************************************************
29 *
30 * Based on code from vmware.c and vmmouse.c.
31 * Author:
32 * Sinclair Yeh <syeh (at) vmware.com>
33 */
34 #ifndef _VMWGFX_MSG_H
35 #define _VMWGFX_MSG_H
36
37 #include <asm/vmware.h>
38
39 /**
40 * Hypervisor-specific bi-directional communication channel. Should never
41 * execute on bare metal hardware. The caller must make sure to check for
42 * supported hypervisor before using these macros.
43 *
44 * The last two parameters are both input and output and must be initialized.
45 *
46 * @cmd: [IN] Message Cmd
47 * @in_ebx: [IN] Message Len, through EBX
48 * @in_si: [IN] Input argument through SI, set to 0 if not used
49 * @in_di: [IN] Input argument through DI, set ot 0 if not used
50 * @flags: [IN] hypercall flags + [channel id]
51 * @magic: [IN] hypervisor magic value
52 * @eax: [OUT] value of EAX register
53 * @ebx: [OUT] e.g. status from an HB message status command
54 * @ecx: [OUT] e.g. status from a non-HB message status command
55 * @edx: [OUT] e.g. channel id
56 * @si: [OUT]
57 * @di: [OUT]
58 */
59 #define VMW_PORT(cmd, in_ebx, in_si, in_di, \
60 flags, magic, \
61 eax, ebx, ecx, edx, si, di) \
62 ({ \
63 asm volatile (VMWARE_HYPERCALL : \
64 "=a"(eax), \
65 "=b"(ebx), \
66 "=c"(ecx), \
67 "=d"(edx), \
68 "=S"(si), \
69 "=D"(di) : \
70 "a"(magic), \
71 "b"(in_ebx), \
72 "c"(cmd), \
73 "d"(flags), \
74 "S"(in_si), \
75 "D"(in_di) : \
76 "memory"); \
77 })
78
79
80 /**
81 * Hypervisor-specific bi-directional communication channel. Should never
82 * execute on bare metal hardware. The caller must make sure to check for
83 * supported hypervisor before using these macros.
84 *
85 * The last 3 parameters are both input and output and must be initialized.
86 *
87 * @cmd: [IN] Message Cmd
88 * @in_ecx: [IN] Message Len, through ECX
89 * @in_si: [IN] Input argument through SI, set to 0 if not used
90 * @in_di: [IN] Input argument through DI, set to 0 if not used
91 * @flags: [IN] hypercall flags + [channel id]
92 * @magic: [IN] hypervisor magic value
93 * @bp: [IN]
94 * @eax: [OUT] value of EAX register
95 * @ebx: [OUT] e.g. status from an HB message status command
96 * @ecx: [OUT] e.g. status from a non-HB message status command
97 * @edx: [OUT] e.g. channel id
98 * @si: [OUT]
99 * @di: [OUT]
100 */
101 #ifdef __x86_64__
102
103 #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, \
104 flags, magic, bp, \
105 eax, ebx, ecx, edx, si, di) \
106 ({ \
107 asm volatile ("push %%rbp;" \
108 "mov %12, %%rbp;" \
109 VMWARE_HYPERCALL_HB_OUT \
110 "pop %%rbp;" : \
111 "=a"(eax), \
112 "=b"(ebx), \
113 "=c"(ecx), \
114 "=d"(edx), \
115 "=S"(si), \
116 "=D"(di) : \
117 "a"(magic), \
118 "b"(cmd), \
119 "c"(in_ecx), \
120 "d"(flags), \
121 "S"(in_si), \
122 "D"(in_di), \
123 "r"(bp) : \
124 "memory", "cc"); \
125 })
126
127
128 #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, \
129 flags, magic, bp, \
130 eax, ebx, ecx, edx, si, di) \
131 ({ \
132 asm volatile ("push %%rbp;" \
133 "mov %12, %%rbp;" \
134 VMWARE_HYPERCALL_HB_IN \
135 "pop %%rbp" : \
136 "=a"(eax), \
137 "=b"(ebx), \
138 "=c"(ecx), \
139 "=d"(edx), \
140 "=S"(si), \
141 "=D"(di) : \
142 "a"(magic), \
143 "b"(cmd), \
144 "c"(in_ecx), \
145 "d"(flags), \
146 "S"(in_si), \
147 "D"(in_di), \
148 "r"(bp) : \
149 "memory", "cc"); \
150 })
151
152 #else
153
154 /*
155 * In the 32-bit version of this macro, we store bp in a memory location
156 * because we've ran out of registers.
157 * Now we can't reference that memory location while we've modified
158 * %esp or %ebp, so we first push it on the stack, just before we push
159 * %ebp, and then when we need it we read it from the stack where we
160 * just pushed it.
161 */
162 #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, \
163 flags, magic, bp, \
164 eax, ebx, ecx, edx, si, di) \
165 ({ \
166 asm volatile ("push %12;" \
167 "push %%ebp;" \
168 "mov 0x04(%%esp), %%ebp;" \
169 VMWARE_HYPERCALL_HB_OUT \
170 "pop %%ebp;" \
171 "add $0x04, %%esp;" : \
172 "=a"(eax), \
173 "=b"(ebx), \
174 "=c"(ecx), \
175 "=d"(edx), \
176 "=S"(si), \
177 "=D"(di) : \
178 "a"(magic), \
179 "b"(cmd), \
180 "c"(in_ecx), \
181 "d"(flags), \
182 "S"(in_si), \
183 "D"(in_di), \
184 "m"(bp) : \
185 "memory", "cc"); \
186 })
187
188
189 #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, \
190 flags, magic, bp, \
191 eax, ebx, ecx, edx, si, di) \
192 ({ \
193 asm volatile ("push %12;" \
194 "push %%ebp;" \
195 "mov 0x04(%%esp), %%ebp;" \
196 VMWARE_HYPERCALL_HB_IN \
197 "pop %%ebp;" \
198 "add $0x04, %%esp;" : \
199 "=a"(eax), \
200 "=b"(ebx), \
201 "=c"(ecx), \
202 "=d"(edx), \
203 "=S"(si), \
204 "=D"(di) : \
205 "a"(magic), \
206 "b"(cmd), \
207 "c"(in_ecx), \
208 "d"(flags), \
209 "S"(in_si), \
210 "D"(in_di), \
211 "m"(bp) : \
212 "memory", "cc"); \
213 })
214 #endif /* #if __x86_64__ */
215
216 #endif
217