1523375c9SZack Rusin /* SPDX-License-Identifier: GPL-2.0+ OR MIT */ 2523375c9SZack Rusin /************************************************************************** 3523375c9SZack Rusin * 4523375c9SZack Rusin * Copyright 2016-2021 VMware, Inc., Palo Alto, CA., USA 5523375c9SZack Rusin * 6523375c9SZack Rusin * Permission is hereby granted, free of charge, to any person obtaining a 7523375c9SZack Rusin * copy of this software and associated documentation files (the 8523375c9SZack Rusin * "Software"), to deal in the Software without restriction, including 9523375c9SZack Rusin * without limitation the rights to use, copy, modify, merge, publish, 10523375c9SZack Rusin * distribute, sub license, and/or sell copies of the Software, and to 11523375c9SZack Rusin * permit persons to whom the Software is furnished to do so, subject to 12523375c9SZack Rusin * the following conditions: 13523375c9SZack Rusin * 14523375c9SZack Rusin * The above copyright notice and this permission notice (including the 15523375c9SZack Rusin * next paragraph) shall be included in all copies or substantial portions 16523375c9SZack Rusin * of the Software. 17523375c9SZack Rusin * 18523375c9SZack Rusin * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19523375c9SZack Rusin * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20523375c9SZack Rusin * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21523375c9SZack Rusin * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 22523375c9SZack Rusin * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23523375c9SZack Rusin * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24523375c9SZack Rusin * USE OR OTHER DEALINGS IN THE SOFTWARE. 25523375c9SZack Rusin * 26523375c9SZack Rusin ************************************************************************** 27523375c9SZack Rusin * 28523375c9SZack Rusin * Based on code from vmware.c and vmmouse.c. 29523375c9SZack Rusin * Author: 30523375c9SZack Rusin * Sinclair Yeh <syeh@vmware.com> 31523375c9SZack Rusin */ 32523375c9SZack Rusin #ifndef _VMWGFX_MSG_X86_H 33523375c9SZack Rusin #define _VMWGFX_MSG_X86_H 34523375c9SZack Rusin 35523375c9SZack Rusin 36523375c9SZack Rusin #if defined(__i386__) || defined(__x86_64__) 37523375c9SZack Rusin 38523375c9SZack Rusin #include <asm/vmware.h> 39523375c9SZack Rusin 40523375c9SZack Rusin /** 41523375c9SZack Rusin * Hypervisor-specific bi-directional communication channel. Should never 42523375c9SZack Rusin * execute on bare metal hardware. The caller must make sure to check for 43523375c9SZack Rusin * supported hypervisor before using these macros. 44523375c9SZack Rusin * 45523375c9SZack Rusin * The last two parameters are both input and output and must be initialized. 46523375c9SZack Rusin * 47523375c9SZack Rusin * @cmd: [IN] Message Cmd 48523375c9SZack Rusin * @in_ebx: [IN] Message Len, through EBX 49523375c9SZack Rusin * @in_si: [IN] Input argument through SI, set to 0 if not used 50523375c9SZack Rusin * @in_di: [IN] Input argument through DI, set ot 0 if not used 51523375c9SZack Rusin * @flags: [IN] hypercall flags + [channel id] 52523375c9SZack Rusin * @magic: [IN] hypervisor magic value 53523375c9SZack Rusin * @eax: [OUT] value of EAX register 54523375c9SZack Rusin * @ebx: [OUT] e.g. status from an HB message status command 55523375c9SZack Rusin * @ecx: [OUT] e.g. status from a non-HB message status command 56523375c9SZack Rusin * @edx: [OUT] e.g. channel id 57523375c9SZack Rusin * @si: [OUT] 58523375c9SZack Rusin * @di: [OUT] 59523375c9SZack Rusin */ 60523375c9SZack Rusin #define VMW_PORT(cmd, in_ebx, in_si, in_di, \ 61523375c9SZack Rusin flags, magic, \ 62523375c9SZack Rusin eax, ebx, ecx, edx, si, di) \ 63523375c9SZack Rusin ({ \ 64523375c9SZack Rusin asm volatile (VMWARE_HYPERCALL : \ 65523375c9SZack Rusin "=a"(eax), \ 66523375c9SZack Rusin "=b"(ebx), \ 67523375c9SZack Rusin "=c"(ecx), \ 68523375c9SZack Rusin "=d"(edx), \ 69523375c9SZack Rusin "=S"(si), \ 70523375c9SZack Rusin "=D"(di) : \ 71523375c9SZack Rusin "a"(magic), \ 72523375c9SZack Rusin "b"(in_ebx), \ 73523375c9SZack Rusin "c"(cmd), \ 74523375c9SZack Rusin "d"(flags), \ 75523375c9SZack Rusin "S"(in_si), \ 76523375c9SZack Rusin "D"(in_di) : \ 77523375c9SZack Rusin "memory"); \ 78523375c9SZack Rusin }) 79523375c9SZack Rusin 80523375c9SZack Rusin 81523375c9SZack Rusin /** 82523375c9SZack Rusin * Hypervisor-specific bi-directional communication channel. Should never 83523375c9SZack Rusin * execute on bare metal hardware. The caller must make sure to check for 84523375c9SZack Rusin * supported hypervisor before using these macros. 85523375c9SZack Rusin * 86523375c9SZack Rusin * The last 3 parameters are both input and output and must be initialized. 87523375c9SZack Rusin * 88523375c9SZack Rusin * @cmd: [IN] Message Cmd 89523375c9SZack Rusin * @in_ecx: [IN] Message Len, through ECX 90523375c9SZack Rusin * @in_si: [IN] Input argument through SI, set to 0 if not used 91523375c9SZack Rusin * @in_di: [IN] Input argument through DI, set to 0 if not used 92523375c9SZack Rusin * @flags: [IN] hypercall flags + [channel id] 93523375c9SZack Rusin * @magic: [IN] hypervisor magic value 94523375c9SZack Rusin * @bp: [IN] 95523375c9SZack Rusin * @eax: [OUT] value of EAX register 96523375c9SZack Rusin * @ebx: [OUT] e.g. status from an HB message status command 97523375c9SZack Rusin * @ecx: [OUT] e.g. status from a non-HB message status command 98523375c9SZack Rusin * @edx: [OUT] e.g. channel id 99523375c9SZack Rusin * @si: [OUT] 100523375c9SZack Rusin * @di: [OUT] 101523375c9SZack Rusin */ 102523375c9SZack Rusin #ifdef __x86_64__ 103523375c9SZack Rusin 104523375c9SZack Rusin #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, \ 105523375c9SZack Rusin flags, magic, bp, \ 106523375c9SZack Rusin eax, ebx, ecx, edx, si, di) \ 107523375c9SZack Rusin ({ \ 108*a9da8247SJosh Poimboeuf asm volatile ( \ 109*a9da8247SJosh Poimboeuf UNWIND_HINT_SAVE \ 110*a9da8247SJosh Poimboeuf "push %%rbp;" \ 111*a9da8247SJosh Poimboeuf UNWIND_HINT_UNDEFINED \ 112523375c9SZack Rusin "mov %12, %%rbp;" \ 113523375c9SZack Rusin VMWARE_HYPERCALL_HB_OUT \ 114*a9da8247SJosh Poimboeuf "pop %%rbp;" \ 115*a9da8247SJosh Poimboeuf UNWIND_HINT_RESTORE : \ 116523375c9SZack Rusin "=a"(eax), \ 117523375c9SZack Rusin "=b"(ebx), \ 118523375c9SZack Rusin "=c"(ecx), \ 119523375c9SZack Rusin "=d"(edx), \ 120523375c9SZack Rusin "=S"(si), \ 121523375c9SZack Rusin "=D"(di) : \ 122523375c9SZack Rusin "a"(magic), \ 123523375c9SZack Rusin "b"(cmd), \ 124523375c9SZack Rusin "c"(in_ecx), \ 125523375c9SZack Rusin "d"(flags), \ 126523375c9SZack Rusin "S"(in_si), \ 127523375c9SZack Rusin "D"(in_di), \ 128523375c9SZack Rusin "r"(bp) : \ 129523375c9SZack Rusin "memory", "cc"); \ 130523375c9SZack Rusin }) 131523375c9SZack Rusin 132523375c9SZack Rusin 133523375c9SZack Rusin #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, \ 134523375c9SZack Rusin flags, magic, bp, \ 135523375c9SZack Rusin eax, ebx, ecx, edx, si, di) \ 136523375c9SZack Rusin ({ \ 137*a9da8247SJosh Poimboeuf asm volatile ( \ 138*a9da8247SJosh Poimboeuf UNWIND_HINT_SAVE \ 139*a9da8247SJosh Poimboeuf "push %%rbp;" \ 140*a9da8247SJosh Poimboeuf UNWIND_HINT_UNDEFINED \ 141523375c9SZack Rusin "mov %12, %%rbp;" \ 142523375c9SZack Rusin VMWARE_HYPERCALL_HB_IN \ 143*a9da8247SJosh Poimboeuf "pop %%rbp;" \ 144*a9da8247SJosh Poimboeuf UNWIND_HINT_RESTORE : \ 145523375c9SZack Rusin "=a"(eax), \ 146523375c9SZack Rusin "=b"(ebx), \ 147523375c9SZack Rusin "=c"(ecx), \ 148523375c9SZack Rusin "=d"(edx), \ 149523375c9SZack Rusin "=S"(si), \ 150523375c9SZack Rusin "=D"(di) : \ 151523375c9SZack Rusin "a"(magic), \ 152523375c9SZack Rusin "b"(cmd), \ 153523375c9SZack Rusin "c"(in_ecx), \ 154523375c9SZack Rusin "d"(flags), \ 155523375c9SZack Rusin "S"(in_si), \ 156523375c9SZack Rusin "D"(in_di), \ 157523375c9SZack Rusin "r"(bp) : \ 158523375c9SZack Rusin "memory", "cc"); \ 159523375c9SZack Rusin }) 160523375c9SZack Rusin 161523375c9SZack Rusin #elif defined(__i386__) 162523375c9SZack Rusin 163523375c9SZack Rusin /* 164523375c9SZack Rusin * In the 32-bit version of this macro, we store bp in a memory location 165523375c9SZack Rusin * because we've ran out of registers. 166523375c9SZack Rusin * Now we can't reference that memory location while we've modified 167523375c9SZack Rusin * %esp or %ebp, so we first push it on the stack, just before we push 168523375c9SZack Rusin * %ebp, and then when we need it we read it from the stack where we 169523375c9SZack Rusin * just pushed it. 170523375c9SZack Rusin */ 171523375c9SZack Rusin #define VMW_PORT_HB_OUT(cmd, in_ecx, in_si, in_di, \ 172523375c9SZack Rusin flags, magic, bp, \ 173523375c9SZack Rusin eax, ebx, ecx, edx, si, di) \ 174523375c9SZack Rusin ({ \ 175523375c9SZack Rusin asm volatile ("push %12;" \ 176523375c9SZack Rusin "push %%ebp;" \ 177523375c9SZack Rusin "mov 0x04(%%esp), %%ebp;" \ 178523375c9SZack Rusin VMWARE_HYPERCALL_HB_OUT \ 179523375c9SZack Rusin "pop %%ebp;" \ 180523375c9SZack Rusin "add $0x04, %%esp;" : \ 181523375c9SZack Rusin "=a"(eax), \ 182523375c9SZack Rusin "=b"(ebx), \ 183523375c9SZack Rusin "=c"(ecx), \ 184523375c9SZack Rusin "=d"(edx), \ 185523375c9SZack Rusin "=S"(si), \ 186523375c9SZack Rusin "=D"(di) : \ 187523375c9SZack Rusin "a"(magic), \ 188523375c9SZack Rusin "b"(cmd), \ 189523375c9SZack Rusin "c"(in_ecx), \ 190523375c9SZack Rusin "d"(flags), \ 191523375c9SZack Rusin "S"(in_si), \ 192523375c9SZack Rusin "D"(in_di), \ 193523375c9SZack Rusin "m"(bp) : \ 194523375c9SZack Rusin "memory", "cc"); \ 195523375c9SZack Rusin }) 196523375c9SZack Rusin 197523375c9SZack Rusin 198523375c9SZack Rusin #define VMW_PORT_HB_IN(cmd, in_ecx, in_si, in_di, \ 199523375c9SZack Rusin flags, magic, bp, \ 200523375c9SZack Rusin eax, ebx, ecx, edx, si, di) \ 201523375c9SZack Rusin ({ \ 202523375c9SZack Rusin asm volatile ("push %12;" \ 203523375c9SZack Rusin "push %%ebp;" \ 204523375c9SZack Rusin "mov 0x04(%%esp), %%ebp;" \ 205523375c9SZack Rusin VMWARE_HYPERCALL_HB_IN \ 206523375c9SZack Rusin "pop %%ebp;" \ 207523375c9SZack Rusin "add $0x04, %%esp;" : \ 208523375c9SZack Rusin "=a"(eax), \ 209523375c9SZack Rusin "=b"(ebx), \ 210523375c9SZack Rusin "=c"(ecx), \ 211523375c9SZack Rusin "=d"(edx), \ 212523375c9SZack Rusin "=S"(si), \ 213523375c9SZack Rusin "=D"(di) : \ 214523375c9SZack Rusin "a"(magic), \ 215523375c9SZack Rusin "b"(cmd), \ 216523375c9SZack Rusin "c"(in_ecx), \ 217523375c9SZack Rusin "d"(flags), \ 218523375c9SZack Rusin "S"(in_si), \ 219523375c9SZack Rusin "D"(in_di), \ 220523375c9SZack Rusin "m"(bp) : \ 221523375c9SZack Rusin "memory", "cc"); \ 222523375c9SZack Rusin }) 223523375c9SZack Rusin #endif /* defined(__i386__) */ 224523375c9SZack Rusin 225523375c9SZack Rusin #endif /* defined(__i386__) || defined(__x86_64__) */ 226523375c9SZack Rusin 227523375c9SZack Rusin #endif /* _VMWGFX_MSG_X86_H */ 228