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