/*
 * Copyright 2014, NICTA
 *
 * This software may be distributed and modified according to the terms of
 * the GNU General Public License version 2. Note that NO WARRANTY is provided.
 * See "LICENSE_GPLv2.txt" for details.
 *
 * @TAG(NICTA_GPL)
 */

/* This file contains macros for CPUID emulation in x86.
 * Most of the code in this file is from arch/x86/kvm/cpuid.h Linux 3.8.8
 
 *     Authors:
 *         Qian Ge
 */

#include <stdio.h>
#include <stdlib.h>

#include <sel4/sel4.h>

#include "vmm/debug.h"

#include "vmm/vmm.h"

#include "vmm/processor/cpuid.h"
#include "vmm/processor/cpufeature.h"

static inline void native_cpuid(unsigned int *eax, unsigned int *ebx,
                unsigned int *ecx, unsigned int *edx) {
    /* ecx is often an input as well as an output. */
    asm volatile("cpuid"
        : "=a" (*eax),
          "=b" (*ebx),
          "=c" (*ecx),
          "=d" (*edx)
        : "0" (*eax), "2" (*ecx)
        : "memory");
}


static int vmm_cpuid_virt(unsigned int function, unsigned int index, struct cpuid_val *val, vmm_vcpu_t *vcpu) {
    unsigned int eax, ebx, ecx, edx;

    eax = function;
    ecx = index;

    native_cpuid(&eax, &ebx, &ecx, &edx);

    /* cpuid 1.edx */
    const unsigned int kvm_supported_word0_x86_features =
        F(FPU) | 0 /*F(VME)*/ | 0 /*F(DE)*/ | 0/*F(PSE)*/ |
        F(TSC) | 0/*F(MSR)*/ | 0 /*F(PAE)*/ | 0/*F(MCE)*/ |
        0 /*F(CX8)*/ | F(APIC) | 0 /* Reserved */ | F(SEP) |
        /*F(MTRR)*/ 0 | F(PGE) | 0/*F(MCA)*/ | F(CMOV) |
        0 /*F(PAT)*/ | 0 /* F(PSE36)*/ | 0 /* PSN */ | 0/*F(CLFLSH)*/ |
        0 /* Reserved, DS, ACPI */ | F(MMX) |
        F(FXSR) | F(XMM) | F(XMM2) | 0/*F(SELFSNOOP)*/ |
        0 /* HTT, TM, Reserved, PBE */;

    /* cpuid 1.ecx */
    const unsigned int kvm_supported_word4_x86_features =
        F(XMM3) | 0 /*F(PCLMULQDQ)*/ | 0 /* DTES64, MONITOR */ |
        0 /* DS-CPL, VMX, SMX, EST */ |
        0 /* TM2 */ | F(SSSE3) | 0 /* CNXT-ID */ | 0 /* Reserved */ |
        0 /*F(FMA)*/ | 0 /*F(CX16)*/ | 0 /* xTPR Update, PDCM */ |
        0 /*F(PCID)*/ | 0 /* Reserved, DCA */ | F(XMM4_1) |
        F(XMM4_2) | 0 /*F(X2APIC)*/ | 0 /*F(MOVBE)*/ | 0 /*F(POPCNT)*/ |
        0 /* Reserved*/ | 0 /*F(AES)*/ | 0/*F(XSAVE)*/ | 0/*F(OSXSAVE)*/ | 0 /*F(AVX)*/ |
        0 /*F(F16C)*/ | 0 /*F(RDRAND)*/;

    /* cpuid 0x80000001.edx */
    const unsigned int kvm_supported_word1_x86_features =
        0 /*F(NX)*/ | 0/*F(RDTSCP)*/;  /*not support x86 64*/

    /* cpuid 0x80000001.ecx */
    const unsigned int kvm_supported_word6_x86_features = 0;

#if 0
    /* cpuid 0xC0000001.edx */
    const unsigned int kvm_supported_word5_x86_features =
        F(XSTORE) | F(XSTORE_EN) | F(XCRYPT) | F(XCRYPT_EN) |
        F(ACE2) | F(ACE2_EN) | F(PHE) | F(PHE_EN) |
        F(PMM) | F(PMM_EN);

    /* cpuid 7.0.ebx */
    const unsigned int kvm_supported_word9_x86_features =
        F(FSGSBASE) | F(BMI1) | F(HLE) | F(AVX2) | F(SMEP) |
        F(BMI2) | F(ERMS) | 0 /*invpcid*/| F(RTM);
#endif

    /* Virtualize the return value according to the function. */

    DPRINTF(4, "cpuid function 0x%x index 0x%x eax 0x%x ebx 0%x ecx 0x%x edx 0x%x\n", function, index, eax, ebx, ecx, edx);

    /* ref: http://www.sandpile.org/x86/cpuid.htm */

    switch (function) {
        case 0: /* Get highest function supported plus vendor ID */
	    if (eax > 0xb)
	        eax = 0xb;
	    break;

        case 1: /* Processor, info and feature. family, model, stepping */
            edx &= kvm_supported_word0_x86_features;
            ecx &= kvm_supported_word4_x86_features;
            break;

        case 2:
        case 4: /* Cache and TLB descriptor information */
            /* Simply pass through information from native CPUID. */
            break;

        case 7: /* Extended flags */
            break;

        case 0xa: /* disable performance monitoring */
            eax = ebx = ecx = edx = 0;
            break;

        case 0xb: /* Disable topology information */
            eax = ebx = ecx = edx = 0;
            break;

        case VMM_CPUID_KVM_SIGNATURE: /* Unsupported KVM features. We are not KVM. */
        case VMM_CPUID_KVM_FEATURES:
            eax = ebx = ecx = edx = 0;
            break;

        case 0x80000000: /* Get highest extended function supported */
            break;

        case 0x80000001: /* extended processor info and feature bits */
            ecx &= kvm_supported_word6_x86_features;
            edx &= kvm_supported_word1_x86_features;
            break;

        case 0x80000002: /* Get processor name string. */
        case 0x80000003:
        case 0x80000004:
        case 0x80000006: /* Cache information. */
            /* Pass through brand name from native CPUID. */
            break;

        case 0x80000008: /* Virtual and Physics address sizes */
            break;

        case 3: /* Processor serial number. */
            break;
        case 5: /* MONITOR / MWAIT */
        case 6: /* Thermal management */
        case 0x80000007: /* Advanced power management - unsupported. */
        case 0xC0000002:
        case 0xC0000003:
        case 0xC0000004:
            eax = ebx = ecx = edx = 0;
            break;

        default:
            /* TODO: Adding more CPUID functions whenever necessary */
            DPRINTF(1, "CPUID unimplemented function 0x%x\n", function);
            return -1;

    }

    val->eax = eax;
    val->ebx = ebx;
    val->ecx = ecx;
    val->edx = edx;

    DPRINTF(4, "cpuid virt value eax 0x%x ebx 0x%x ecx 0x%x edx 0x%x\n", eax, ebx, ecx, edx);

    return 0;

}

#if 0
            /* function 2 entries are STATEFUL. That is, repeated cpuid commands
             * may return different values. This forces us to get_cpu() before
             * issuing the first command, and also to emulate this annoying behavior
             * in kvm_emulate_cpuid() using KVM_CPUID_FLAG_STATE_READ_NEXT */
        case 2: {
                    int t, times = entry->eax & 0xff;

                    entry->flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
                    entry->flags |= KVM_CPUID_FLAG_STATE_READ_NEXT;
                    for (t = 1; t < times; ++t) {
                        if (*nent >= maxnent)
                            goto out;

                        do_cpuid_1_ent(&entry[t], function, 0);
                        entry[t].flags |= KVM_CPUID_FLAG_STATEFUL_FUNC;
                        ++*nent;
                    }
                    break;
                }
                /* function 4 has additional index. */
        case 4: {
                    int i, cache_type;

                    entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                    /* read more entries until cache_type is zero */
                    for (i = 1; ; ++i) {
                        if (*nent >= maxnent)
                            goto out;

                        cache_type = entry[i - 1].eax & 0x1f;
                        if (!cache_type)
                            break;
                        do_cpuid_1_ent(&entry[i], function, i);
                        entry[i].flags |=
                            KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                        ++*nent;
                    }
                    break;
                }
        case 7: {
                    entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                    /* Mask ebx against host capability word 9 */
                    if (index == 0) {
                        entry->ebx &= kvm_supported_word9_x86_features;
                        cpuid_mask(&entry->ebx, 9);
                        // TSC_ADJUST is emulated
                        entry->ebx |= F(TSC_ADJUST);
                    } else
                        entry->ebx = 0;
                    entry->eax = 0;
                    entry->ecx = 0;
                    entry->edx = 0;
                    break;
                }
        case 9:
                break;
        case 0xa: { /* Architectural Performance Monitoring */
                      struct x86_pmu_capability cap;
                      union cpuid10_eax eax;
                      union cpuid10_edx edx;

                      perf_get_x86_pmu_capability(&cap);

                      /*
                       * Only support guest architectural pmu on a host
                       * with architectural pmu.
                       */
                      if (!cap.version)
                          memset(&cap, 0, sizeof(cap));

                      eax.split.version_id = min(cap.version, 2);
                      eax.split.num_counters = cap.num_counters_gp;
                      eax.split.bit_width = cap.bit_width_gp;
                      eax.split.mask_length = cap.events_mask_len;

                      edx.split.num_counters_fixed = cap.num_counters_fixed;
                      edx.split.bit_width_fixed = cap.bit_width_fixed;
                      edx.split.reserved = 0;

                      entry->eax = eax.full;
                      entry->ebx = cap.events_mask;
                      entry->ecx = 0;
                      entry->edx = edx.full;
                      break;
                  }
                  /* function 0xb has additional index. */
        case 0xb: {
                      int i, level_type;

                      entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                      /* read more entries until level_type is zero */
                      for (i = 1; ; ++i) {
                          if (*nent >= maxnent)
                              goto out;

                          level_type = entry[i - 1].ecx & 0xff00;
                          if (!level_type)
                              break;
                          do_cpuid_1_ent(&entry[i], function, i);
                          entry[i].flags |=
                              KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                          ++*nent;
                      }
                      break;
                  }
        case 0xd: {
                      int idx, i;

                      entry->flags |= KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                      for (idx = 1, i = 1; idx < 64; ++idx) {
                          if (*nent >= maxnent)
                              goto out;

                          do_cpuid_1_ent(&entry[i], function, idx);
                          if (entry[i].eax == 0 || !supported_xcr0_bit(idx))
                              continue;
                          entry[i].flags |=
                              KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
                          ++*nent;
                          ++i;
                      }
                      break;
                  }
        case KVM_CPUID_SIGNATURE: {
                                      static const char signature[12] = "KVMKVMKVM\0\0";
                                      const unsigned int *sigptr = (const unsigned int *)signature;
                                      entry->eax = KVM_CPUID_FEATURES;
                                      entry->ebx = sigptr[0];
                                      entry->ecx = sigptr[1];
                                      entry->edx = sigptr[2];
                                      break;
                                  }
        case KVM_CPUID_FEATURES:
                                  entry->eax = (1 << KVM_FEATURE_CLOCKSOURCE) |
                                      (1 << KVM_FEATURE_NOP_IO_DELAY) |
                                      (1 << KVM_FEATURE_CLOCKSOURCE2) |
                                      (1 << KVM_FEATURE_ASYNC_PF) |
                                      (1 << KVM_FEATURE_PV_EOI) |
                                      (1 << KVM_FEATURE_CLOCKSOURCE_STABLE_BIT);

                                  if (sched_info_on())
                                      entry->eax |= (1 << KVM_FEATURE_STEAL_TIME);

                                  entry->ebx = 0;
                                  entry->ecx = 0;
                                  entry->edx = 0;
                                  break;
       case 0x80000019:
                         entry->ecx = entry->edx = 0;
                         break;
        case 0x8000001a:
                         break;
        case 0x8000001d:
                         break;
                         /*Add support for Centaur's CPUID instruction*/
        case 0xC0000000:
                         /*Just support up to 0xC0000004 now*/
                         entry->eax = min(entry->eax, 0xC0000004);
                         break;
        case 0xC0000001:
                         entry->edx &= kvm_supported_word5_x86_features;
                         cpuid_mask(&entry->edx, 5);
                         break;
        case 3: /* Processor serial number */
        case 5: /* MONITOR/MWAIT */
        case 6: /* Thermal management */
        case 0x80000007: /* Advanced power management */
        case 0xC0000002:
        case 0xC0000003:
        case 0xC0000004:
        default:
                         entry->eax = entry->ebx = entry->ecx = entry->edx = 0;
                         break;
    }
#endif

/* VM exit handler: for the CPUID instruction. */
int vmm_cpuid_handler(vmm_vcpu_t *vcpu) {

    int ret;
    struct cpuid_val val;

    /* Read parameter information. */
    unsigned int function = vmm_read_user_context(&vcpu->guest_state, USER_CONTEXT_EAX);
    unsigned int index = vmm_read_user_context(&vcpu->guest_state, USER_CONTEXT_ECX);

    /* Virtualise the CPUID instruction. */
    ret = vmm_cpuid_virt(function, index, &val, vcpu);
    if (ret)
        return ret;

    /* Set the return values in guest context. */
    vmm_set_user_context(&vcpu->guest_state, USER_CONTEXT_EAX, val.eax);
    vmm_set_user_context(&vcpu->guest_state, USER_CONTEXT_EBX, val.ebx);
    vmm_set_user_context(&vcpu->guest_state, USER_CONTEXT_ECX, val.ecx);
    vmm_set_user_context(&vcpu->guest_state, USER_CONTEXT_EDX, val.edx);

    vmm_guest_exit_next_instruction(&vcpu->guest_state, vcpu->guest_vcpu);

    /* Return success. */
    return 0;
}
