162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 or MIT */
262306a36Sopenharmony_ci#ifndef _ASM_X86_VMWARE_H
362306a36Sopenharmony_ci#define _ASM_X86_VMWARE_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <asm/cpufeatures.h>
662306a36Sopenharmony_ci#include <asm/alternative.h>
762306a36Sopenharmony_ci#include <linux/stringify.h>
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci/*
1062306a36Sopenharmony_ci * The hypercall definitions differ in the low word of the %edx argument
1162306a36Sopenharmony_ci * in the following way: the old port base interface uses the port
1262306a36Sopenharmony_ci * number to distinguish between high- and low bandwidth versions.
1362306a36Sopenharmony_ci *
1462306a36Sopenharmony_ci * The new vmcall interface instead uses a set of flags to select
1562306a36Sopenharmony_ci * bandwidth mode and transfer direction. The flags should be loaded
1662306a36Sopenharmony_ci * into %dx by any user and are automatically replaced by the port
1762306a36Sopenharmony_ci * number if the VMWARE_HYPERVISOR_PORT method is used.
1862306a36Sopenharmony_ci *
1962306a36Sopenharmony_ci * In short, new driver code should strictly use the new definition of
2062306a36Sopenharmony_ci * %dx content.
2162306a36Sopenharmony_ci */
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ci/* Old port-based version */
2462306a36Sopenharmony_ci#define VMWARE_HYPERVISOR_PORT    0x5658
2562306a36Sopenharmony_ci#define VMWARE_HYPERVISOR_PORT_HB 0x5659
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci/* Current vmcall / vmmcall version */
2862306a36Sopenharmony_ci#define VMWARE_HYPERVISOR_HB   BIT(0)
2962306a36Sopenharmony_ci#define VMWARE_HYPERVISOR_OUT  BIT(1)
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci/* The low bandwidth call. The low word of edx is presumed clear. */
3262306a36Sopenharmony_ci#define VMWARE_HYPERCALL						\
3362306a36Sopenharmony_ci	ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT) ", %%dx; " \
3462306a36Sopenharmony_ci		      "inl (%%dx), %%eax",				\
3562306a36Sopenharmony_ci		      "vmcall", X86_FEATURE_VMCALL,			\
3662306a36Sopenharmony_ci		      "vmmcall", X86_FEATURE_VMW_VMMCALL)
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/*
3962306a36Sopenharmony_ci * The high bandwidth out call. The low word of edx is presumed to have the
4062306a36Sopenharmony_ci * HB and OUT bits set.
4162306a36Sopenharmony_ci */
4262306a36Sopenharmony_ci#define VMWARE_HYPERCALL_HB_OUT						\
4362306a36Sopenharmony_ci	ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \
4462306a36Sopenharmony_ci		      "rep outsb",					\
4562306a36Sopenharmony_ci		      "vmcall", X86_FEATURE_VMCALL,			\
4662306a36Sopenharmony_ci		      "vmmcall", X86_FEATURE_VMW_VMMCALL)
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci/*
4962306a36Sopenharmony_ci * The high bandwidth in call. The low word of edx is presumed to have the
5062306a36Sopenharmony_ci * HB bit set.
5162306a36Sopenharmony_ci */
5262306a36Sopenharmony_ci#define VMWARE_HYPERCALL_HB_IN						\
5362306a36Sopenharmony_ci	ALTERNATIVE_2("movw $" __stringify(VMWARE_HYPERVISOR_PORT_HB) ", %%dx; " \
5462306a36Sopenharmony_ci		      "rep insb",					\
5562306a36Sopenharmony_ci		      "vmcall", X86_FEATURE_VMCALL,			\
5662306a36Sopenharmony_ci		      "vmmcall", X86_FEATURE_VMW_VMMCALL)
5762306a36Sopenharmony_ci#endif
58