// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT

// This file is based on zircon/kernel/arch/x86/feature.c.
// TODO(dje): As with generic elf, dwarf, et.al, move to application
// independent library.

#include "x86_cpuid.h"

#include <cpuid.h>

#include <atomic>
#include <cstdint>
#include <cstring>
#include <mutex>

namespace debugger_utils {

// Trick to get a 1 of the right size.
#define ONE(x) (1 + ((x) - (x)))
#define BITS_SHIFT(x, high, low) (((x) >> (low)) & ((ONE(x) << ((high) - (low) + 1)) - 1))

// Note: cpuid state is constant once computed, and thus isn't guarded.

static struct x86_cpuid_leaf cpuid[MAX_SUPPORTED_CPUID + 1];
static struct x86_cpuid_leaf cpuid_ext[MAX_SUPPORTED_CPUID_EXT - X86_CPUID_EXT_BASE + 1];
static uint32_t max_cpuid = 0;
static uint32_t max_ext_cpuid = 0;

static enum x86_vendor_list x86_vendor;

static struct x86_model_info model_info;

static std::mutex cpuid_mutex;

static bool initialized = false;  // TODO(dje): add guard annotation

static const x86_cpuid_leaf* x86_get_cpuid_leaf_raw(enum x86_cpuid_leaf_num leaf);

void x86_feature_init(void) {
  std::lock_guard<std::mutex> lock(cpuid_mutex);

  if (initialized)
    return;

  // test for cpuid count
  __cpuid(0, cpuid[0].a, cpuid[0].b, cpuid[0].c, cpuid[0].d);

  max_cpuid = cpuid[0].a;
  if (max_cpuid > MAX_SUPPORTED_CPUID)
    max_cpuid = MAX_SUPPORTED_CPUID;

  // figure out the vendor
  union {
    uint32_t vendor_id[3];
    char vendor_string[13];
  } vu;
  vu.vendor_id[0] = cpuid[0].b;
  vu.vendor_id[1] = cpuid[0].d;
  vu.vendor_id[2] = cpuid[0].c;
  vu.vendor_string[12] = '\0';
  if (!strcmp(vu.vendor_string, "GenuineIntel")) {
    x86_vendor = X86_VENDOR_INTEL;
  } else if (!strcmp(vu.vendor_string, "AuthenticAMD")) {
    x86_vendor = X86_VENDOR_AMD;
  } else {
    x86_vendor = X86_VENDOR_UNKNOWN;
  }

  // read in the base cpuids
  for (uint32_t i = 1; i <= max_cpuid; i++) {
    __cpuid_count(i, 0, cpuid[i].a, cpuid[i].b, cpuid[i].c, cpuid[i].d);
  }

  // test for extended cpuid count
  __cpuid(X86_CPUID_EXT_BASE, cpuid_ext[0].a, cpuid_ext[0].b, cpuid_ext[0].c, cpuid_ext[0].d);

  max_ext_cpuid = cpuid_ext[0].a;
  if (max_ext_cpuid > MAX_SUPPORTED_CPUID_EXT)
    max_ext_cpuid = MAX_SUPPORTED_CPUID_EXT;

  // read in the extended cpuids
  for (uint32_t i = X86_CPUID_EXT_BASE + 1; i - 1 < max_ext_cpuid; i++) {
    uint32_t index = i - X86_CPUID_EXT_BASE;
    __cpuid_count(i, 0, cpuid_ext[index].a, cpuid_ext[index].b, cpuid_ext[index].c,
                  cpuid_ext[index].d);
  }

  // populate the model info
  const struct x86_cpuid_leaf* leaf = x86_get_cpuid_leaf_raw(X86_CPUID_MODEL_FEATURES);
  if (leaf) {
    model_info.processor_type = BITS_SHIFT(leaf->a, 13, 12);
    model_info.family = BITS_SHIFT(leaf->a, 11, 8);
    model_info.model = BITS_SHIFT(leaf->a, 7, 4);
    model_info.stepping = BITS_SHIFT(leaf->a, 3, 0);
    model_info.display_family = model_info.family;
    model_info.display_model = model_info.model;

    if (model_info.family == 0xf) {
      model_info.display_family += BITS_SHIFT(leaf->a, 27, 20);
    }
    if (model_info.family == 0xf || model_info.family == 0x6) {
      model_info.display_model += BITS_SHIFT(leaf->a, 19, 16) << 4;
    }
  }

  initialized = true;
}

bool x86_get_cpuid_subleaf(enum x86_cpuid_leaf_num num, uint32_t subleaf,
                           struct x86_cpuid_leaf* leaf) {
  x86_feature_init();

  if (num < X86_CPUID_EXT_BASE) {
    if (num > max_cpuid)
      return false;
  } else if (num > max_ext_cpuid) {
    return false;
  }

  __cpuid_count((uint32_t)num, subleaf, leaf->a, leaf->b, leaf->c, leaf->d);
  return true;
}

static const x86_cpuid_leaf* x86_get_cpuid_leaf_raw(enum x86_cpuid_leaf_num leaf) {
  if (leaf < X86_CPUID_EXT_BASE) {
    if (leaf > max_cpuid)
      return nullptr;

    return &cpuid[leaf];
  } else {
    if (leaf > max_ext_cpuid)
      return nullptr;

    return &cpuid_ext[(uint32_t)leaf - (uint32_t)X86_CPUID_EXT_BASE];
  }
}

const x86_cpuid_leaf* x86_get_cpuid_leaf(enum x86_cpuid_leaf_num leaf) {
  x86_feature_init();
  return x86_get_cpuid_leaf_raw(leaf);
}

bool x86_feature_test(struct x86_cpuid_bit bit) {
  FX_DCHECK(bit.word <= 3 && bit.bit <= 31);

  if (bit.word > 3 || bit.bit > 31)
    return false;

  const x86_cpuid_leaf* leaf = x86_get_cpuid_leaf(bit.leaf_num);
  if (!leaf)
    return false;

  switch (bit.word) {
    case 0:
      return !!((1u << bit.bit) & leaf->a);
    case 1:
      return !!((1u << bit.bit) & leaf->b);
    case 2:
      return !!((1u << bit.bit) & leaf->c);
    case 3:
      return !!((1u << bit.bit) & leaf->d);
    default:
      return false;
  }
}

bool x86_topology_enumerate(uint8_t level, struct x86_topology_level* info) {
  uint32_t eax, ebx, ecx, edx;
  __cpuid_count(X86_CPUID_TOPOLOGY, level, eax, ebx, ecx, edx);

  uint8_t type = (ecx >> 8) & 0xff;
  if (type == X86_TOPOLOGY_INVALID)
    return false;

  info->right_shift = eax & 0x1f;
  info->type = type;
  return true;
}

const struct x86_model_info* x86_get_model(void) {
  x86_feature_init();
  return &model_info;
}

// N.B. The output is parsed by spt-sideband.cc.

void x86_feature_debug(FILE* out) {
  static const struct {
    x86_cpuid_bit bit;
    const char* name;
  } features[] = {
      {X86_FEATURE_FPU, "fpu"},
      {X86_FEATURE_SSE, "sse"},
      {X86_FEATURE_SSE2, "sse2"},
      {X86_FEATURE_SSE3, "sse3"},
      {X86_FEATURE_SSSE3, "ssse3"},
      {X86_FEATURE_SSE4_1, "sse4.1"},
      {X86_FEATURE_SSE4_2, "sse4.2"},
      {X86_FEATURE_MMX, "mmx"},
      {X86_FEATURE_AVX, "avx"},
      {X86_FEATURE_AVX2, "avx2"},
      {X86_FEATURE_FXSR, "fxsr"},
      {X86_FEATURE_XSAVE, "xsave"},
      {X86_FEATURE_AESNI, "aesni"},
      {X86_FEATURE_TSC_ADJUST, "tsc_adj"},
      {X86_FEATURE_SMEP, "smep"},
      {X86_FEATURE_SMAP, "smap"},
      {X86_FEATURE_RDRAND, "rdrand"},
      {X86_FEATURE_RDSEED, "rdseed"},
      {X86_FEATURE_PT, "pt"},
      {X86_FEATURE_PKU, "pku"},
      {X86_FEATURE_SYSCALL, "syscall"},
      {X86_FEATURE_NX, "nx"},
      {X86_FEATURE_HUGE_PAGE, "huge"},
      {X86_FEATURE_RDTSCP, "rdtscp"},
      {X86_FEATURE_INVAR_TSC, "invar_tsc"},
      {X86_FEATURE_TSC_DEADLINE, "tsc_deadline"},
  };

  x86_feature_init();

  const char* vendor_string;
  switch (x86_vendor) {
    default:
    case X86_VENDOR_UNKNOWN:
      vendor_string = "unknown";
      break;
    case X86_VENDOR_INTEL:
      vendor_string = "Intel";
      break;
    case X86_VENDOR_AMD:
      vendor_string = "AMD";
      break;
  }
  fprintf(out, "Vendor: %s\n", vendor_string);

  auto model = x86_get_model();
  fprintf(out, "Model:\n");
  fprintf(out, "  processor: %u\n", model->processor_type);
  // TODO(dje): It's not clear which "variant" of family/model IPT wants,
  // but it seems like it would want the more detailed version, so that's
  // what we use.
  fprintf(out, "  base family: %u\n", model->family);
  fprintf(out, "  base model: %u\n", model->model);
  fprintf(out, "  family: %u\n", model->display_family);
  fprintf(out, "  model: %u\n", model->display_model);
  fprintf(out, "  stepping: %u\n", model->stepping);

  fprintf(out, "Features:\n");
  size_t col = 0;
  for (auto& f : features) {
    if (x86_feature_test(f.bit))
      col += fprintf(out, " %s", f.name);
    if (col >= 80) {
      fprintf(out, "\n");
      col = 0;
    }
  }
  if (col > 0)
    fprintf(out, "\n");
}

}  // namespace debugger_utils
