vmwgfx_msg.h 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  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. * Hypervisor-specific bi-directional communication channel. Should never
  36. * execute on bare metal hardware. The caller must make sure to check for
  37. * supported hypervisor before using these macros.
  38. *
  39. * The last two parameters are both input and output and must be initialized.
  40. *
  41. * @cmd: [IN] Message Cmd
  42. * @in_ebx: [IN] Message Len, through EBX
  43. * @in_si: [IN] Input argument through SI, set to 0 if not used
  44. * @in_di: [IN] Input argument through DI, set ot 0 if not used
  45. * @port_num: [IN] port number + [channel id]
  46. * @magic: [IN] hypervisor magic value
  47. * @eax: [OUT] value of EAX register
  48. * @ebx: [OUT] e.g. status from an HB message status command
  49. * @ecx: [OUT] e.g. status from a non-HB message status command
  50. * @edx: [OUT] e.g. channel id
  51. * @si: [OUT]
  52. * @di: [OUT]
  53. */
  54. #define VMW_PORT(cmd, in_ebx, in_si, in_di, \
  55. port_num, magic, \
  56. eax, ebx, ecx, edx, si, di) \
  57. ({ \
  58. asm volatile ("inl %%dx, %%eax;" : \
  59. "=a"(eax), \
  60. "=b"(ebx), \
  61. "=c"(ecx), \
  62. "=d"(edx), \
  63. "=S"(si), \
  64. "=D"(di) : \
  65. "a"(magic), \
  66. "b"(in_ebx), \
  67. "c"(cmd), \
  68. "d"(port_num), \
  69. "S"(in_si), \
  70. "D"(in_di) : \
  71. "memory"); \
  72. })
  73. /**
  74. * Hypervisor-specific bi-directional communication channel. Should never
  75. * execute on bare metal hardware. The caller must make sure to check for
  76. * supported hypervisor before using these macros.
  77. *
  78. * The last 3 parameters are both input and output and must be initialized.
  79. *
  80. * @cmd: [IN] Message Cmd
  81. * @in_ecx: [IN] Message Len, through ECX
  82. * @in_si: [IN] Input argument through SI, set to 0 if not used
  83. * @in_di: [IN] Input argument through DI, set to 0 if not used
  84. * @port_num: [IN] port number + [channel id]
  85. * @magic: [IN] hypervisor magic value
  86. * @bp: [IN]
  87. * @eax: [OUT] value of EAX register
  88. * @ebx: [OUT] e.g. status from an HB message status command
  89. * @ecx: [OUT] e.g. status from a non-HB message status command
  90. * @edx: [OUT] e.g. channel id
  91. * @si: [OUT]
  92. * @di: [OUT]
  93. */
  94. #ifdef __x86_64__
  95. #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, \
  96. port_num, magic, bp, \
  97. eax, ebx, ecx, edx, si, di) \
  98. ({ \
  99. asm volatile ("push %%rbp;" \
  100. "mov %12, %%rbp;" \
  101. "rep outsb;" \
  102. "pop %%rbp;" : \
  103. "=a"(eax), \
  104. "=b"(ebx), \
  105. "=c"(ecx), \
  106. "=d"(edx), \
  107. "=S"(si), \
  108. "=D"(di) : \
  109. "a"(magic), \
  110. "b"(cmd), \
  111. "c"(in_ecx), \
  112. "d"(port_num), \
  113. "S"(in_si), \
  114. "D"(in_di), \
  115. "r"(bp) : \
  116. "memory", "cc"); \
  117. })
  118. #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, \
  119. port_num, magic, bp, \
  120. eax, ebx, ecx, edx, si, di) \
  121. ({ \
  122. asm volatile ("push %%rbp;" \
  123. "mov %12, %%rbp;" \
  124. "rep insb;" \
  125. "pop %%rbp" : \
  126. "=a"(eax), \
  127. "=b"(ebx), \
  128. "=c"(ecx), \
  129. "=d"(edx), \
  130. "=S"(si), \
  131. "=D"(di) : \
  132. "a"(magic), \
  133. "b"(cmd), \
  134. "c"(in_ecx), \
  135. "d"(port_num), \
  136. "S"(in_si), \
  137. "D"(in_di), \
  138. "r"(bp) : \
  139. "memory", "cc"); \
  140. })
  141. #else
  142. /*
  143. * In the 32-bit version of this macro, we store bp in a memory location
  144. * because we've ran out of registers.
  145. * Now we can't reference that memory location while we've modified
  146. * %esp or %ebp, so we first push it on the stack, just before we push
  147. * %ebp, and then when we need it we read it from the stack where we
  148. * just pushed it.
  149. */
  150. #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, \
  151. port_num, magic, bp, \
  152. eax, ebx, ecx, edx, si, di) \
  153. ({ \
  154. asm volatile ("push %12;" \
  155. "push %%ebp;" \
  156. "mov 0x04(%%esp), %%ebp;" \
  157. "rep outsb;" \
  158. "pop %%ebp;" \
  159. "add $0x04, %%esp;" : \
  160. "=a"(eax), \
  161. "=b"(ebx), \
  162. "=c"(ecx), \
  163. "=d"(edx), \
  164. "=S"(si), \
  165. "=D"(di) : \
  166. "a"(magic), \
  167. "b"(cmd), \
  168. "c"(in_ecx), \
  169. "d"(port_num), \
  170. "S"(in_si), \
  171. "D"(in_di), \
  172. "m"(bp) : \
  173. "memory", "cc"); \
  174. })
  175. #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, \
  176. port_num, magic, bp, \
  177. eax, ebx, ecx, edx, si, di) \
  178. ({ \
  179. asm volatile ("push %12;" \
  180. "push %%ebp;" \
  181. "mov 0x04(%%esp), %%ebp;" \
  182. "rep insb;" \
  183. "pop %%ebp;" \
  184. "add $0x04, %%esp;" : \
  185. "=a"(eax), \
  186. "=b"(ebx), \
  187. "=c"(ecx), \
  188. "=d"(edx), \
  189. "=S"(si), \
  190. "=D"(di) : \
  191. "a"(magic), \
  192. "b"(cmd), \
  193. "c"(in_ecx), \
  194. "d"(port_num), \
  195. "S"(in_si), \
  196. "D"(in_di), \
  197. "m"(bp) : \
  198. "memory", "cc"); \
  199. })
  200. #endif /* #if __x86_64__ */
  201. #endif