// 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
#include "arch/x86/feature.h"

#include <assert.h>
#include <bits.h>
#include <stdint.h>
#include <string.h>
#include <trace.h>

#include <arch/ops.h>
#include <arch/x86/cpuid.h>
#include <arch/x86/platform_access.h>
#include <platform/pc/bootbyte.h>
#include <fbl/algorithm.h>

#define LOCAL_TRACE 0

struct cpuid_leaf _cpuid[MAX_SUPPORTED_CPUID + 1];
struct cpuid_leaf _cpuid_hyp[MAX_SUPPORTED_CPUID_HYP - X86_CPUID_HYP_BASE + 1];
struct cpuid_leaf _cpuid_ext[MAX_SUPPORTED_CPUID_EXT - X86_CPUID_EXT_BASE + 1];
uint32_t max_cpuid = 0;
uint32_t max_hyp_cpuid = 0;
uint32_t max_ext_cpuid = 0;

enum x86_vendor_list x86_vendor;
enum x86_microarch_list x86_microarch;
const x86_microarch_config_t* x86_microarch_config;

static struct x86_model_info model_info;

bool g_x86_feature_fsgsbase;
bool g_x86_feature_pcid_good;
bool g_x86_feature_has_smap;
bool g_has_meltdown;
bool g_has_l1tf;
bool g_has_mds;

enum x86_hypervisor_list x86_hypervisor;

static int initialized = 0;

static enum x86_microarch_list get_microarch(struct x86_model_info* info);
static const x86_microarch_config_t* select_microarch_config(enum x86_microarch_list info);

static enum x86_hypervisor_list get_hypervisor();

void x86_feature_init(void) {
  if (atomic_swap(&initialized, 1)) {
    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;

  LTRACEF("max cpuid 0x%x\n", max_cpuid);

  /* figure out the vendor */
  union {
    uint32_t vendor_id[3];
    char vendor_string[12];
  } vu;
  vu.vendor_id[0] = _cpuid[0].b;
  vu.vendor_id[1] = _cpuid[0].d;
  vu.vendor_id[2] = _cpuid[0].c;
  if (!memcmp(vu.vendor_string, "GenuineIntel", sizeof(vu.vendor_string))) {
    x86_vendor = X86_VENDOR_INTEL;
  } else if (!memcmp(vu.vendor_string, "AuthenticAMD", sizeof(vu.vendor_string))) {
    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_c(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;
  LTRACEF("max extended cpuid 0x%x\n", max_ext_cpuid);
  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_c(i, 0, &_cpuid_ext[index].a, &_cpuid_ext[index].b, &_cpuid_ext[index].c,
            &_cpuid_ext[index].d);
  }

  /* read in the hypervisor cpuids. the maximum leaf is reported at X86_CPUID_HYP_BASE. */
  cpuid(X86_CPUID_HYP_VENDOR, &_cpuid_ext[0].a, &_cpuid_ext[0].b, &_cpuid_ext[0].c,
        &_cpuid_ext[0].d);
  max_hyp_cpuid = _cpuid_ext[0].a;
  if (max_hyp_cpuid > MAX_SUPPORTED_CPUID_HYP)
    max_hyp_cpuid = MAX_SUPPORTED_CPUID_HYP;
  for (uint32_t i = X86_CPUID_HYP_BASE; i <= max_hyp_cpuid; i++) {
    uint32_t index = i - X86_CPUID_HYP_BASE;
    cpuid(i, &_cpuid_hyp[index].a, &_cpuid_hyp[index].b, &_cpuid_hyp[index].c,
          &_cpuid_hyp[index].d);
  }

  /* populate the model info */
  const struct cpuid_leaf* leaf = x86_get_cpuid_leaf(X86_CPUID_MODEL_FEATURES);
  if (leaf) {
    model_info.processor_type = (uint8_t)BITS_SHIFT(leaf->a, 13, 12);
    model_info.family = (uint8_t)BITS_SHIFT(leaf->a, 11, 8);
    model_info.model = (uint8_t)BITS_SHIFT(leaf->a, 7, 4);
    model_info.stepping = (uint8_t)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;
    }

    x86_microarch = get_microarch(&model_info);
  }
  // Get microcode patch level
  switch (x86_vendor) {
    case X86_VENDOR_INTEL:
      model_info.patch_level = x86_intel_get_patch_level();
      break;
    case X86_VENDOR_AMD:
      model_info.patch_level = x86_amd_get_patch_level();
      break;
    default:
      break;
  }
  x86_microarch_config = select_microarch_config(x86_microarch);

  g_x86_feature_fsgsbase = x86_feature_test(X86_FEATURE_FSGSBASE);
  g_x86_feature_pcid_good =
      x86_feature_test(X86_FEATURE_PCID) && x86_feature_test(X86_FEATURE_INVPCID);

  x86_hypervisor = get_hypervisor();

  if (x86_vendor == X86_VENDOR_INTEL) {
    cpu_id::CpuId cpuid;
    MsrAccess msr;
    g_has_meltdown = x86_intel_cpu_has_meltdown(&cpuid, &msr);
    g_has_l1tf = x86_intel_cpu_has_l1tf(&cpuid, &msr);
    g_has_mds = x86_intel_cpu_has_mds(&cpuid, &msr);
  }

  g_x86_feature_has_smap = x86_feature_test(X86_FEATURE_SMAP);
}

static enum x86_microarch_list get_microarch(struct x86_model_info* info) {
  if (x86_vendor == X86_VENDOR_INTEL && info->family == 0x6) {
    switch (info->display_model) {
      case 0x1a: /* Nehalem */
      case 0x1e: /* Nehalem */
      case 0x1f: /* Nehalem */
      case 0x2e: /* Nehalem */
        return X86_MICROARCH_INTEL_NEHALEM;
      case 0x25: /* Westmere */
      case 0x2c: /* Westmere */
      case 0x2f: /* Westmere */
        return X86_MICROARCH_INTEL_WESTMERE;
      case 0x2a: /* Sandy Bridge */
      case 0x2d: /* Sandy Bridge EP */
        return X86_MICROARCH_INTEL_SANDY_BRIDGE;
      case 0x3a: /* Ivy Bridge */
      case 0x3e: /* Ivy Bridge EP */
        return X86_MICROARCH_INTEL_IVY_BRIDGE;
      case 0x3c: /* Haswell DT */
      case 0x3f: /* Haswell MB */
      case 0x45: /* Haswell ULT */
      case 0x46: /* Haswell ULX */
        return X86_MICROARCH_INTEL_HASWELL;
      case 0x3d: /* Broadwell */
      case 0x47: /* Broadwell H */
      case 0x56: /* Broadwell EP */
      case 0x4f: /* Broadwell EX */
        return X86_MICROARCH_INTEL_BROADWELL;
      case 0x4e: /* Skylake Y/U */
      case 0x5e: /* Skylake H/S */
      case 0x55: /* Skylake E */
        return X86_MICROARCH_INTEL_SKYLAKE;
      case 0x8e: /* Kabylake Y/U */
      case 0x9e: /* Kabylake H/S */
        return X86_MICROARCH_INTEL_KABYLAKE;
      case 0x37: /* Silvermont */
      case 0x4a: /* Silvermont "Cherry View" */
      case 0x4d: /* Silvermont "Avoton" */
      case 0x4c: /* Airmont "Braswell" */
      case 0x5a: /* Airmont */
        return X86_MICROARCH_INTEL_SILVERMONT;
      case 0x5c: /* Goldmont */
        return X86_MICROARCH_INTEL_GOLDMONT;
    }
  } else if (x86_vendor == X86_VENDOR_AMD && info->family == 0xf) {
    switch (info->display_family) {  // zen
      case 0x15:                     /* Bulldozer */
        return X86_MICROARCH_AMD_BULLDOZER;
      case 0x16: /* Jaguar */
        return X86_MICROARCH_AMD_JAGUAR;
      case 0x17: /* Zen */
        return X86_MICROARCH_AMD_ZEN;
    }
  }
  return X86_MICROARCH_UNKNOWN;
}

static enum x86_hypervisor_list get_hypervisor() {
  if (!x86_feature_test(X86_FEATURE_HYPERVISOR)) {
    return X86_HYPERVISOR_NONE;
  }
  uint32_t a, b, c, d;
  cpuid(X86_CPUID_HYP_VENDOR, &a, &b, &c, &d);
  union {
    uint32_t vendor_id[3];
    char vendor_string[12];
  } vu;
  vu.vendor_id[0] = b;
  vu.vendor_id[1] = c;
  vu.vendor_id[2] = d;
  if (a >= X86_CPUID_KVM_FEATURES &&
      !memcmp(vu.vendor_string, "KVMKVMKVM\0\0\0", sizeof(vu.vendor_string))) {
    return X86_HYPERVISOR_KVM;
  } else {
    return X86_HYPERVISOR_UNKNOWN;
  }
}

bool x86_get_cpuid_subleaf(enum x86_cpuid_leaf_num num, uint32_t subleaf, struct cpuid_leaf* leaf) {
  if (num < X86_CPUID_EXT_BASE) {
    if (num > max_cpuid)
      return false;
  } else if (num > max_ext_cpuid) {
    return false;
  }

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

bool x86_topology_enumerate(uint8_t level, struct x86_topology_level* info) {
  DEBUG_ASSERT(info);

  uint32_t eax, ebx, ecx, edx;
  cpuid_c(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) { return &model_info; }

void x86_feature_debug(void) {
  const struct {
    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_PCID, "pcid"},
      {X86_FEATURE_XSAVE, "xsave"},
      {X86_FEATURE_MON, "mon"},
      {X86_FEATURE_AESNI, "aesni"},
      {X86_FEATURE_CLFLUSH, "clflush"},
      {X86_FEATURE_CLFLUSHOPT, "clflushopt"},
      {X86_FEATURE_CLWB, "clwb"},
      {X86_FEATURE_FSGSBASE, "fsgsbase"},
      {X86_FEATURE_TSC_ADJUST, "tsc_adj"},
      {X86_FEATURE_SMEP, "smep"},
      {X86_FEATURE_SMAP, "smap"},
      {X86_FEATURE_ERMS, "erms"},
      {X86_FEATURE_RDRAND, "rdrand"},
      {X86_FEATURE_RDSEED, "rdseed"},
      {X86_FEATURE_UMIP, "umip"},
      {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_X2APIC, "x2apic"},
      {X86_FEATURE_VMX, "vmx"},
      {X86_FEATURE_HYPERVISOR, "hypervisor"},
      {X86_FEATURE_PT, "pt"},
      {X86_FEATURE_HWP, "hwp"},
  };

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

  const char* microarch_string = nullptr;
  switch (x86_microarch) {
    case X86_MICROARCH_UNKNOWN:
      microarch_string = "unknown";
      break;
    case X86_MICROARCH_INTEL_NEHALEM:
      microarch_string = "Nehalem";
      break;
    case X86_MICROARCH_INTEL_WESTMERE:
      microarch_string = "Westmere";
      break;
    case X86_MICROARCH_INTEL_SANDY_BRIDGE:
      microarch_string = "Sandy Bridge";
      break;
    case X86_MICROARCH_INTEL_IVY_BRIDGE:
      microarch_string = "Ivy Bridge";
      break;
    case X86_MICROARCH_INTEL_BROADWELL:
      microarch_string = "Broadwell";
      break;
    case X86_MICROARCH_INTEL_HASWELL:
      microarch_string = "Haswell";
      break;
    case X86_MICROARCH_INTEL_SKYLAKE:
      microarch_string = "Skylake";
      break;
    case X86_MICROARCH_INTEL_KABYLAKE:
      microarch_string = "Kaby Lake";
      break;
    case X86_MICROARCH_INTEL_SILVERMONT:
      microarch_string = "Silvermont";
      break;
    case X86_MICROARCH_INTEL_GOLDMONT:
      microarch_string = "Goldmont";
      break;
    case X86_MICROARCH_AMD_BULLDOZER:
      microarch_string = "Bulldozer";
      break;
    case X86_MICROARCH_AMD_JAGUAR:
      microarch_string = "Jaguar";
      break;
    case X86_MICROARCH_AMD_ZEN:
      microarch_string = "Zen";
      break;
  }
  printf("Microarch: %s\n", microarch_string);
  printf("F/M/S: %x/%x/%x\n", model_info.display_family, model_info.display_model,
         model_info.stepping);
  printf("patch_level: %x\n", model_info.patch_level);

  char brand_string[50];
  memset(brand_string, 0, sizeof(brand_string));
  const struct cpuid_leaf* leaf;
  uint32_t leaf_num = X86_CPUID_BRAND;
  for (int i = 0; i < 3; i++) {
    leaf = x86_get_cpuid_leaf((enum x86_cpuid_leaf_num)(leaf_num + i));
    if (!leaf) {
      break;
    }
    memcpy(brand_string + (i * 16), &leaf->a, sizeof(uint32_t));
    memcpy(brand_string + (i * 16) + 4, &leaf->b, sizeof(uint32_t));
    memcpy(brand_string + (i * 16) + 8, &leaf->c, sizeof(uint32_t));
    memcpy(brand_string + (i * 16) + 12, &leaf->d, sizeof(uint32_t));
  }
  printf("Brand: %s\n", brand_string);

  printf("Features: ");
  uint col = 0;
  for (uint i = 0; i < fbl::count_of(features); ++i) {
    if (x86_feature_test(features[i].bit))
      col += printf("%s ", features[i].name);
    if (col >= 80) {
      printf("\n");
      col = 0;
    }
  }
  if (col > 0)
    printf("\n");
  // Print synthetic 'features'/properties
  printf("Properties: ");
  if (g_has_meltdown)
    printf("meltdown ");
  if (g_has_l1tf)
    printf("l1tf ");
  if (g_has_mds)
    printf("mds ");
  if (g_x86_feature_pcid_good)
    printf("pcid_good ");
  printf("\n");
}

static uint64_t default_apic_freq() {
  // The APIC frequency is the core crystal clock frequency if it is
  // enumerated in the CPUID leaf 0x15, or the processor's bus clock
  // frequency.

  const struct cpuid_leaf* tsc_leaf = x86_get_cpuid_leaf(X86_CPUID_TSC);
  if (tsc_leaf && tsc_leaf->c != 0) {
    return tsc_leaf->c;
  }
  return 0;
}

static uint64_t kbl_apic_freq() {
  uint64_t v = default_apic_freq();
  if (v != 0) {
    return v;
  }
  return 24ul * 1000 * 1000;
}

static uint64_t bdw_apic_freq() {
  uint64_t v = default_apic_freq();
  if (v != 0) {
    return v;
  }
  uint64_t platform_info;
  const uint32_t msr_platform_info = 0xce;
  if (read_msr_safe(msr_platform_info, &platform_info) == ZX_OK) {
    uint64_t bus_freq_mult = (platform_info >> 8) & 0xf;
    return bus_freq_mult * 100 * 1000 * 1000;
  }
  return 0;
}

static uint64_t bulldozer_apic_freq() {
  uint64_t v = default_apic_freq();
  if (v != 0) {
    return v;
  }

  // 15h-17h BKDGs mention the APIC timer rate is 2xCLKIN,
  // which experimentally appears to be 100Mhz always
  return 100ul * 1000 * 1000;
}

static uint64_t unknown_freq() { return 0; }

static uint64_t intel_tsc_freq() {
  const uint64_t core_crystal_clock_freq = x86_get_microarch_config()->get_apic_freq();

  // If this leaf is present, then 18.18.3 (Determining the Processor Base
  // Frequency) documents this as the nominal TSC frequency.
  const struct cpuid_leaf* tsc_leaf = x86_get_cpuid_leaf(X86_CPUID_TSC);
  if (tsc_leaf && tsc_leaf->a) {
    return (core_crystal_clock_freq * tsc_leaf->b) / tsc_leaf->a;
  }
  return 0;
}

static uint64_t amd_compute_p_state_clock(uint64_t p_state_msr) {
  // is it valid?
  if (!BIT(p_state_msr, 63))
    return 0;

  // different AMD microarchitectures use slightly different formulas to compute
  // the effective clock rate of a P state
  uint64_t clock = 0;
  switch (x86_microarch) {
    case X86_MICROARCH_AMD_BULLDOZER:
    case X86_MICROARCH_AMD_JAGUAR: {
      uint64_t did = BITS_SHIFT(p_state_msr, 8, 6);
      uint64_t fid = BITS(p_state_msr, 5, 0);

      clock = (100 * (fid + 0x10) / (1 << did)) * 1000 * 1000;
      break;
    }
    case X86_MICROARCH_AMD_ZEN: {
      uint64_t fid = BITS(p_state_msr, 7, 0);

      clock = (fid * 25) * 1000 * 1000;
      break;
    }
    default:
      break;
  }

  return clock;
}

static uint64_t zen_tsc_freq() {
  const uint32_t p0_state_msr = 0xc0010064;  // base P-state MSR
  // According to the Family 17h PPR, the first P-state MSR is indeed
  // P0 state and appears to be experimentally so
  uint64_t p0_state;
  if (read_msr_safe(p0_state_msr, &p0_state) != ZX_OK)
    return 0;

  return amd_compute_p_state_clock(p0_state);
}

static void unknown_reboot_system(void) { return; }

static void unknown_reboot_reason(uint64_t) { return; }

static void hsw_reboot_system(void) {
  // 100-Series Chipset Reset Control Register: CPU + SYS Reset
  outp(0xcf9, 0x06);
}

static void hsw_reboot_reason(uint64_t reason) {
  bootbyte_set_reason(reason);

  // 100-Series Chipset Reset Control Register: CPU + SYS Reset
  // clear PCI reset sequence
  outp(0xcf9, 0x02);
  // discarded reads acting as a small delay on the bus
  (void)inp(0xcf9);
  (void)inp(0xcf9);
  outp(0xcf9, 0x04);
}

// Intel microarches
static const x86_microarch_config_t kbl_config{
    .get_apic_freq = kbl_apic_freq,
    .get_tsc_freq = intel_tsc_freq,
    .reboot_system = hsw_reboot_system,
    .reboot_reason = hsw_reboot_reason,
    .disable_c1e = true,
    .idle_states =
        {
            .states =
                {
                    {.name = "C10", .mwait_hint = 0x60, .exit_latency = 890, .flushes_tlb = true},
                    {.name = "C9", .mwait_hint = 0x50, .exit_latency = 480, .flushes_tlb = true},
                    {.name = "C8", .mwait_hint = 0x40, .exit_latency = 200, .flushes_tlb = true},
                    {.name = "C7s", .mwait_hint = 0x33, .exit_latency = 124, .flushes_tlb = true},
                    {.name = "C6", .mwait_hint = 0x20, .exit_latency = 85, .flushes_tlb = true},
                    {.name = "C3", .mwait_hint = 0x10, .exit_latency = 70, .flushes_tlb = true},
                    {.name = "C1E", .mwait_hint = 0x01, .exit_latency = 10, .flushes_tlb = false},
                    X86_CSTATE_C1(0),
                },
        },
};
static const x86_microarch_config_t skl_config{
    .get_apic_freq = kbl_apic_freq,
    .get_tsc_freq = intel_tsc_freq,
    .reboot_system = hsw_reboot_system,
    .reboot_reason = hsw_reboot_reason,
    .disable_c1e = true,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t bdw_config{
    .get_apic_freq = bdw_apic_freq,
    .get_tsc_freq = intel_tsc_freq,
    .reboot_system = hsw_reboot_system,
    .reboot_reason = hsw_reboot_reason,
    .disable_c1e = true,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t hsw_config{
    .get_apic_freq = bdw_apic_freq,
    .get_tsc_freq = intel_tsc_freq,
    .reboot_system = hsw_reboot_system,
    .reboot_reason = hsw_reboot_reason,
    .disable_c1e = true,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t ivb_config{
    .get_apic_freq = bdw_apic_freq,
    .get_tsc_freq = intel_tsc_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = true,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t snb_config{
    .get_apic_freq = bdw_apic_freq,
    .get_tsc_freq = intel_tsc_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = true,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t westmere_config{
    .get_apic_freq = default_apic_freq,
    .get_tsc_freq = intel_tsc_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = true,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t nehalem_config{
    .get_apic_freq = default_apic_freq,
    .get_tsc_freq = intel_tsc_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = true,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t smt_config{
    .get_apic_freq = default_apic_freq,
    .get_tsc_freq = intel_tsc_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = false,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t intel_default_config{
    .get_apic_freq = default_apic_freq,
    .get_tsc_freq = intel_tsc_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = false,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};

// AMD microarches
static const x86_microarch_config_t zen_config{
    .get_apic_freq = bulldozer_apic_freq,
    .get_tsc_freq = zen_tsc_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = false,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t jaguar_config{
    .get_apic_freq = bulldozer_apic_freq,
    .get_tsc_freq = unknown_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = false,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t bulldozer_config{
    .get_apic_freq = bulldozer_apic_freq,
    .get_tsc_freq = unknown_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = false,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};
static const x86_microarch_config_t amd_default_config{
    .get_apic_freq = default_apic_freq,
    .get_tsc_freq = unknown_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = false,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};

// Unknown vendor config
static const x86_microarch_config_t unknown_vendor_config{
    .get_apic_freq = unknown_freq,
    .get_tsc_freq = unknown_freq,
    .reboot_system = unknown_reboot_system,
    .reboot_reason = unknown_reboot_reason,
    .disable_c1e = false,
    .idle_states =
        {
            .states = {X86_CSTATE_C1(0)},
        },
};

const x86_microarch_config_t* select_microarch_config(enum x86_microarch_list info) {
  switch (info) {
    case X86_MICROARCH_INTEL_NEHALEM:
      return &nehalem_config;
    case X86_MICROARCH_INTEL_WESTMERE:
      return &westmere_config;
    case X86_MICROARCH_INTEL_SANDY_BRIDGE:
      return &snb_config;
    case X86_MICROARCH_INTEL_IVY_BRIDGE:
      return &ivb_config;
    case X86_MICROARCH_INTEL_BROADWELL:
      return &bdw_config;
    case X86_MICROARCH_INTEL_HASWELL:
      return &hsw_config;
    case X86_MICROARCH_INTEL_SKYLAKE:
      return &skl_config;
    case X86_MICROARCH_INTEL_KABYLAKE:
      return &kbl_config;
    case X86_MICROARCH_INTEL_SILVERMONT:
      return &smt_config;
    case X86_MICROARCH_INTEL_GOLDMONT:
      // Placeholder; TODO(ZX-4201): Separate Goldmont/Goldmont Plus config from Silvermont.
      return &smt_config;
    case X86_MICROARCH_AMD_BULLDOZER:
      return &bulldozer_config;
    case X86_MICROARCH_AMD_JAGUAR:
      return &jaguar_config;
    case X86_MICROARCH_AMD_ZEN:
      return &zen_config;
    case X86_MICROARCH_UNKNOWN: {
      switch (x86_vendor) {
        case X86_VENDOR_INTEL:
          return &intel_default_config;
        case X86_VENDOR_AMD:
          return &amd_default_config;
        case X86_VENDOR_UNKNOWN:
          return &unknown_vendor_config;
      }
    }
  }
  return &unknown_vendor_config;
}
