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