/*
 *  i386 CPUID helper functions
 *
 *  Copyright (c) 2003 Fabrice Bellard
 *  Copyright (c) 2017 Google Inc.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, see <http://www.gnu.org/licenses/>.
 *
 * cpuid
 */

#include "qemu/osdep.h"
#include "qemu/cpuid.h"
#include "host/cpuinfo.h"
#include "cpu.h"
#include "x86.h"
#include "vmx.h"
#include "sysemu/hvf.h"
#include "hvf-i386.h"

static bool cached_xcr0;
static uint64_t supported_xcr0;

static void cache_host_xcr0(void)
{
    if (cached_xcr0) {
        return;
    }

    if (cpuinfo & CPUINFO_OSXSAVE) {
        uint64_t host_xcr0 = xgetbv_low(0);

        /* Only show xcr0 bits corresponding to usable features.  */
        supported_xcr0 = host_xcr0 & (XSTATE_FP_MASK |
                                      XSTATE_SSE_MASK | XSTATE_YMM_MASK |
                                      XSTATE_OPMASK_MASK | XSTATE_ZMM_Hi256_MASK |
                                      XSTATE_Hi16_ZMM_MASK);
        if ((supported_xcr0 & (XSTATE_FP_MASK | XSTATE_SSE_MASK)) !=
            (XSTATE_FP_MASK | XSTATE_SSE_MASK)) {
            supported_xcr0 = 0;
        }
    }

    cached_xcr0 = true;
}

uint32_t hvf_get_supported_cpuid(uint32_t func, uint32_t idx,
                                 int reg)
{
    uint64_t cap;
    uint32_t eax, ebx, ecx, edx;

    cache_host_xcr0();
    host_cpuid(func, idx, &eax, &ebx, &ecx, &edx);

    switch (func) {
    case 0:
        eax = eax < (uint32_t)0xd ? eax : (uint32_t)0xd;
        break;
    case 1:
        edx &= CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC |
             CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC |
             CPUID_SEP | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
             CPUID_PAT | CPUID_PSE36 | CPUID_CLFLUSH | CPUID_MMX |
             CPUID_FXSR | CPUID_SSE | CPUID_SSE2 | CPUID_SS;
        ecx &= CPUID_EXT_SSE3 | CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSSE3 |
             CPUID_EXT_FMA | CPUID_EXT_CX16 | CPUID_EXT_PCID |
             CPUID_EXT_SSE41 | CPUID_EXT_SSE42 | CPUID_EXT_MOVBE |
             CPUID_EXT_POPCNT | CPUID_EXT_AES | CPUID_EXT_X2APIC |
             (supported_xcr0 ? CPUID_EXT_XSAVE : 0) |
             CPUID_EXT_AVX | CPUID_EXT_F16C | CPUID_EXT_RDRAND;
        ecx |= CPUID_EXT_HYPERVISOR;
        break;
    case 6:
        eax = CPUID_6_EAX_ARAT;
        ebx = 0;
        ecx = 0;
        edx = 0;
        break;
    case 7:
        if (idx == 0) {
            ebx &= CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
                    CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 |
                    CPUID_7_0_EBX_SMEP | CPUID_7_0_EBX_BMI2 |
                    CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_RTM |
                    CPUID_7_0_EBX_RDSEED | CPUID_7_0_EBX_ADX |
                    CPUID_7_0_EBX_SMAP | CPUID_7_0_EBX_AVX512IFMA |
                    CPUID_7_0_EBX_AVX512F | CPUID_7_0_EBX_AVX512PF |
                    CPUID_7_0_EBX_AVX512ER | CPUID_7_0_EBX_AVX512CD |
                    CPUID_7_0_EBX_CLFLUSHOPT | CPUID_7_0_EBX_CLWB |
                    CPUID_7_0_EBX_AVX512DQ | CPUID_7_0_EBX_SHA_NI |
                    CPUID_7_0_EBX_AVX512BW | CPUID_7_0_EBX_AVX512VL |
                    CPUID_7_0_EBX_INVPCID;

            hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap);
            if (!(cap & CPU_BASED2_INVPCID)) {
                ebx &= ~CPUID_7_0_EBX_INVPCID;
            }

            ecx &= CPUID_7_0_ECX_AVX512_VBMI | CPUID_7_0_ECX_AVX512_VPOPCNTDQ |
                   CPUID_7_0_ECX_RDPID;
            edx &= CPUID_7_0_EDX_AVX512_4VNNIW | CPUID_7_0_EDX_AVX512_4FMAPS;
        } else {
            ebx = 0;
            ecx = 0;
            edx = 0;
        }
        eax = 0;
        break;
    case 0xD:
        if (!supported_xcr0 || idx >= 63 ||
            (idx > 1 && !(supported_xcr0 & (UINT64_C(1) << idx)))) {
            eax = ebx = ecx = edx = 0;
            break;
        }

        if (idx == 0) {
            eax = supported_xcr0;
        } else if (idx == 1) {
            hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap);
            eax &= CPUID_XSAVE_XSAVEOPT | CPUID_XSAVE_XGETBV1;
            if (!(cap & CPU_BASED2_XSAVES_XRSTORS)) {
                eax &= ~CPUID_XSAVE_XSAVES;
            }
        }
        break;
    case 0x80000001:
        /* LM only if HVF in 64-bit mode */
        edx &= CPUID_FP87 | CPUID_VME | CPUID_DE | CPUID_PSE | CPUID_TSC |
                CPUID_MSR | CPUID_PAE | CPUID_MCE | CPUID_CX8 | CPUID_APIC |
                CPUID_EXT2_SYSCALL | CPUID_MTRR | CPUID_PGE | CPUID_MCA | CPUID_CMOV |
                CPUID_PAT | CPUID_PSE36 | CPUID_EXT2_MMXEXT | CPUID_MMX |
                CPUID_FXSR | CPUID_EXT2_FXSR | CPUID_EXT2_PDPE1GB | CPUID_EXT2_3DNOWEXT |
                CPUID_EXT2_3DNOW | CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX;
        hv_vmx_read_capability(HV_VMX_CAP_PROCBASED2, &cap);
        if (!(cap2ctrl(cap, CPU_BASED2_RDTSCP) & CPU_BASED2_RDTSCP)) {
            edx &= ~CPUID_EXT2_RDTSCP;
        }
        hv_vmx_read_capability(HV_VMX_CAP_PROCBASED, &cap);
        if (!(cap2ctrl(cap, CPU_BASED_TSC_OFFSET) & CPU_BASED_TSC_OFFSET)) {
            edx &= ~CPUID_EXT2_RDTSCP;
        }
        ecx &= CPUID_EXT3_LAHF_LM | CPUID_EXT3_CMP_LEG | CPUID_EXT3_CR8LEG |
                CPUID_EXT3_ABM | CPUID_EXT3_SSE4A | CPUID_EXT3_MISALIGNSSE |
                CPUID_EXT3_3DNOWPREFETCH | CPUID_EXT3_OSVW | CPUID_EXT3_XOP |
                CPUID_EXT3_FMA4 | CPUID_EXT3_TBM;
        break;
    case 0x80000007:
        edx &= CPUID_APM_INVTSC;
        eax = ebx = ecx = 0;
        break;
    default:
        return 0;
    }

    switch (reg) {
    case R_EAX:
        return eax;
    case R_EBX:
        return ebx;
    case R_ECX:
        return ecx;
    case R_EDX:
        return edx;
    default:
        return 0;
    }
}
