Linux-libre 4.7-rc7-gnu
[librecmc/linux-libre.git] / drivers / gpu / drm / vmwgfx / vmwgfx_msg.h
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 /* In the 32-bit version of this macro, we use "m" because there is no
139  * more register left for bp
140  */
141 #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di,      \
142                         port_num, magic, bp,            \
143                         eax, ebx, ecx, edx, si, di)     \
144 ({                                                      \
145         asm volatile ("push %%ebp;"                     \
146                 "mov %12, %%ebp;"                       \
147                 "rep outsb;"                            \
148                 "pop %%ebp;" :                          \
149                 "=a"(eax),                              \
150                 "=b"(ebx),                              \
151                 "=c"(ecx),                              \
152                 "=d"(edx),                              \
153                 "=S"(si),                               \
154                 "=D"(di) :                              \
155                 "a"(magic),                             \
156                 "b"(cmd),                               \
157                 "c"(in_ecx),                            \
158                 "d"(port_num),                          \
159                 "S"(in_si),                             \
160                 "D"(in_di),                             \
161                 "m"(bp) :                               \
162                 "memory", "cc");                        \
163 })
164
165
166 #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di,       \
167                        port_num, magic, bp,             \
168                        eax, ebx, ecx, edx, si, di)      \
169 ({                                                      \
170         asm volatile ("push %%ebp;"                     \
171                 "mov %12, %%ebp;"                       \
172                 "rep insb;"                             \
173                 "pop %%ebp" :                           \
174                 "=a"(eax),                              \
175                 "=b"(ebx),                              \
176                 "=c"(ecx),                              \
177                 "=d"(edx),                              \
178                 "=S"(si),                               \
179                 "=D"(di) :                              \
180                 "a"(magic),                             \
181                 "b"(cmd),                               \
182                 "c"(in_ecx),                            \
183                 "d"(port_num),                          \
184                 "S"(in_si),                             \
185                 "D"(in_di),                             \
186                 "m"(bp) :                               \
187                 "memory", "cc");                        \
188 })
189 #endif /* #if __x86_64__ */
190
191 #endif