• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016, VMware, Inc.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
12  * NON INFRINGEMENT.  See the GNU General Public License for more
13  * details.
14  *
15  * Based on code from vmware.c and vmmouse.c.
16  * Author:
17  *   Sinclair Yeh <syeh@vmware.com>
18  */
19 #ifndef _VMWGFX_MSG_H
20 #define _VMWGFX_MSG_H
21 
22 
23 /**
24  * Hypervisor-specific bi-directional communication channel.  Should never
25  * execute on bare metal hardware.  The caller must make sure to check for
26  * supported hypervisor before using these macros.
27  *
28  * The last two parameters are both input and output and must be initialized.
29  *
30  * @cmd: [IN] Message Cmd
31  * @in_ebx: [IN] Message Len, through EBX
32  * @in_si: [IN] Input argument through SI, set to 0 if not used
33  * @in_di: [IN] Input argument through DI, set ot 0 if not used
34  * @port_num: [IN] port number + [channel id]
35  * @magic: [IN] hypervisor magic value
36  * @eax: [OUT] value of EAX register
37  * @ebx: [OUT] e.g. status from an HB message status command
38  * @ecx: [OUT] e.g. status from a non-HB message status command
39  * @edx: [OUT] e.g. channel id
40  * @si:  [OUT]
41  * @di:  [OUT]
42  */
43 #define VMW_PORT(cmd, in_ebx, in_si, in_di,	\
44 		 port_num, magic,		\
45 		 eax, ebx, ecx, edx, si, di)	\
46 ({						\
47 	asm volatile ("inl %%dx, %%eax;" :	\
48 		"=a"(eax),			\
49 		"=b"(ebx),			\
50 		"=c"(ecx),			\
51 		"=d"(edx),			\
52 		"=S"(si),			\
53 		"=D"(di) :			\
54 		"a"(magic),			\
55 		"b"(in_ebx),			\
56 		"c"(cmd),			\
57 		"d"(port_num),			\
58 		"S"(in_si),			\
59 		"D"(in_di) :			\
60 		"memory");			\
61 })
62 
63 
64 /**
65  * Hypervisor-specific bi-directional communication channel.  Should never
66  * execute on bare metal hardware.  The caller must make sure to check for
67  * supported hypervisor before using these macros.
68  *
69  * The last 3 parameters are both input and output and must be initialized.
70  *
71  * @cmd: [IN] Message Cmd
72  * @in_ecx: [IN] Message Len, through ECX
73  * @in_si: [IN] Input argument through SI, set to 0 if not used
74  * @in_di: [IN] Input argument through DI, set to 0 if not used
75  * @port_num: [IN] port number + [channel id]
76  * @magic: [IN] hypervisor magic value
77  * @bp:  [IN]
78  * @eax: [OUT] value of EAX register
79  * @ebx: [OUT] e.g. status from an HB message status command
80  * @ecx: [OUT] e.g. status from a non-HB message status command
81  * @edx: [OUT] e.g. channel id
82  * @si:  [OUT]
83  * @di:  [OUT]
84  */
85 #ifdef __x86_64__
86 
87 #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di,	\
88 			port_num, magic, bp,		\
89 			eax, ebx, ecx, edx, si, di)	\
90 ({							\
91 	asm volatile ("push %%rbp;"			\
92 		"mov %12, %%rbp;"			\
93 		"rep outsb;"				\
94 		"pop %%rbp;" :				\
95 		"=a"(eax),				\
96 		"=b"(ebx),				\
97 		"=c"(ecx),				\
98 		"=d"(edx),				\
99 		"=S"(si),				\
100 		"=D"(di) :				\
101 		"a"(magic),				\
102 		"b"(cmd),				\
103 		"c"(in_ecx),				\
104 		"d"(port_num),				\
105 		"S"(in_si),				\
106 		"D"(in_di),				\
107 		"r"(bp) :				\
108 		"memory", "cc");			\
109 })
110 
111 
112 #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di,	\
113 		       port_num, magic, bp,		\
114 		       eax, ebx, ecx, edx, si, di)	\
115 ({							\
116 	asm volatile ("push %%rbp;"			\
117 		"mov %12, %%rbp;"			\
118 		"rep insb;"				\
119 		"pop %%rbp" :				\
120 		"=a"(eax),				\
121 		"=b"(ebx),				\
122 		"=c"(ecx),				\
123 		"=d"(edx),				\
124 		"=S"(si),				\
125 		"=D"(di) :				\
126 		"a"(magic),				\
127 		"b"(cmd),				\
128 		"c"(in_ecx),				\
129 		"d"(port_num),				\
130 		"S"(in_si),				\
131 		"D"(in_di),				\
132 		"r"(bp) :				\
133 		"memory", "cc");			\
134 })
135 
136 #else
137 
138 /*
139  * In the 32-bit version of this macro, we store bp in a memory location
140  * because we've ran out of registers.
141  * Now we can't reference that memory location while we've modified
142  * %esp or %ebp, so we first push it on the stack, just before we push
143  * %ebp, and then when we need it we read it from the stack where we
144  * just pushed it.
145  */
146 #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di,	\
147 			port_num, magic, bp,		\
148 			eax, ebx, ecx, edx, si, di)	\
149 ({							\
150 	asm volatile ("push %12;"			\
151 		"push %%ebp;"				\
152 		"mov 0x04(%%esp), %%ebp;"		\
153 		"rep outsb;"				\
154 		"pop %%ebp;"				\
155 		"add $0x04, %%esp;" :			\
156 		"=a"(eax),				\
157 		"=b"(ebx),				\
158 		"=c"(ecx),				\
159 		"=d"(edx),				\
160 		"=S"(si),				\
161 		"=D"(di) :				\
162 		"a"(magic),				\
163 		"b"(cmd),				\
164 		"c"(in_ecx),				\
165 		"d"(port_num),				\
166 		"S"(in_si),				\
167 		"D"(in_di),				\
168 		"m"(bp) :				\
169 		"memory", "cc");			\
170 })
171 
172 
173 #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di,	\
174 		       port_num, magic, bp,		\
175 		       eax, ebx, ecx, edx, si, di)	\
176 ({							\
177 	asm volatile ("push %12;"			\
178 		"push %%ebp;"				\
179 		"mov 0x04(%%esp), %%ebp;"		\
180 		"rep insb;"				\
181 		"pop %%ebp;"				\
182 		"add $0x04, %%esp;" :			\
183 		"=a"(eax),				\
184 		"=b"(ebx),				\
185 		"=c"(ecx),				\
186 		"=d"(edx),				\
187 		"=S"(si),				\
188 		"=D"(di) :				\
189 		"a"(magic),				\
190 		"b"(cmd),				\
191 		"c"(in_ecx),				\
192 		"d"(port_num),				\
193 		"S"(in_si),				\
194 		"D"(in_di),				\
195 		"m"(bp) :				\
196 		"memory", "cc");			\
197 })
198 #endif /* #if __x86_64__ */
199 
200 #endif
201