/* SPDX-License-Identifier: GPL-2.0-only */

#include <acpi/acpigen.h>
#include <acpi/acpi.h>
#include <console/console.h>
#include <console/debug.h>
#include <cpu/cpu.h>
#include <cpu/intel/cpu_ids.h>
#include <cpu/intel/common/common.h>
#include <cpu/intel/em64t101_save_state.h>
#include <cpu/intel/microcode.h>
#include <cpu/intel/smm_reloc.h>
#include <cpu/intel/turbo.h>
#include <cpu/x86/lapic.h>
#include <cpu/x86/mp.h>
#include <cpu/x86/mtrr.h>
#include <cpu/x86/topology.h>
#include <device/pci_mmio_cfg.h>
#include <intelblocks/cpulib.h>
#include <intelblocks/mp_init.h>
#include <intelpch/lockdown.h>
#include <soc/msr.h>
#include <soc/pci_devs.h>
#include <soc/pm.h>
#include <soc/soc_util.h>
#include <soc/smmrelocate.h>
#include <soc/util.h>

#include "chip.h"

static const void *microcode_patch;

static const config_t *chip_config = NULL;

bool cpu_soc_is_in_untrusted_mode(void)
{
	return false;
}

void cpu_soc_bios_done(void)
{
}

static void xeon_configure_mca(void)
{
	msr_t msr;
	struct cpuid_result cpuid_regs;

	/*
	 * Check feature flag in CPUID.(EAX=1):EDX[7]==1  MCE
	 *                   and CPUID.(EAX=1):EDX[14]==1 MCA
	 */
	cpuid_regs = cpuid(1);
	if ((cpuid_regs.edx & (1 << 7 | 1 << 14)) != (1 << 7 | 1 << 14))
		return;

	msr = rdmsr(IA32_MCG_CAP);
	if (msr.lo & IA32_MCG_CAP_CTL_P_MASK) {
		/* Enable all error logging */
		msr.lo = msr.hi = 0xffffffff;
		wrmsr(IA32_MCG_CTL, msr);
	}

	mca_configure();
}

/*
 * On server platforms the FIT mechanism only updates the microcode on
 * the BSP. Loading MCU on AP in parallel seems to fail in 10% of the cases
 * so do it serialized.
 */
void get_microcode_info(const void **microcode, int *parallel)
{
	*microcode = intel_microcode_find();
	*parallel = 0;
}

static void each_cpu_init(struct device *cpu)
{
	msr_t msr;

	printk(BIOS_SPEW, "%s dev: %s, cpu: %lu, apic_id: 0x%x, package_id: 0x%x\n",
	       __func__, dev_path(cpu), cpu_index(), cpu->path.apic.apic_id,
	       cpu->path.apic.package_id);

	/* Populate the node ID. It will be used as proximity ID. */
	set_cpu_node_id_leaf_1f_b(cpu);
	assert (cpu->path.apic.node_id < CONFIG_MAX_SOCKET);

	/*
	 * Enable PWR_PERF_PLTFRM_OVR and PROCHOT_LOCK.
	 * The value set by FSP is 20_005f, we set it to 1a_00a4_005b.
	 */
	msr = rdmsr(MSR_POWER_CTL);
	msr.lo |= (0x16 << RESERVED1_SHIFT) | PWR_PERF_PLTFRM_OVR | PROCHOT_LOCK;
	msr.hi = 0x1a;
	wrmsr(MSR_POWER_CTL, msr);

	/* Set static, idle, dynamic load line impedance */
	msr = rdmsr(MSR_VR_MISC_CONFIG);
	msr.lo = 0x1a1a1a;
	wrmsr(MSR_VR_MISC_CONFIG, msr);

	/* Set current limitation */
	msr = rdmsr(MSR_VR_CURRENT_CONFIG);
	msr.lo = 0x1130;
	msr.lo |= CURRENT_LIMIT_LOCK;
	wrmsr(MSR_VR_CURRENT_CONFIG, msr);

	/* Set Turbo Ratio Limits */
	msr.lo = chip_config->turbo_ratio_limit & 0xffffffff;
	msr.hi = (chip_config->turbo_ratio_limit >> 32) & 0xffffffff;
	wrmsr(MSR_TURBO_RATIO_LIMIT, msr);

	/* Set Turbo Ratio Limit Cores */
	msr.lo = chip_config->turbo_ratio_limit_cores & 0xffffffff;
	msr.hi = (chip_config->turbo_ratio_limit_cores >> 32) & 0xffffffff;
	wrmsr(MSR_TURBO_RATIO_LIMIT_CORES, msr);

	/* Set energy policy */
	msr = rdmsr(MSR_ENERGY_PERF_BIAS_CONFIG);
	msr.lo = 0x178fa038;
	wrmsr(MSR_ENERGY_PERF_BIAS_CONFIG, msr);

	msr.hi = 0x158d20;
	msr.lo = 0x00158af0;
	wrmsr(PACKAGE_RAPL_LIMIT, msr);

	/*
	 * Set HWP base feature, EPP reg enumeration, lock thermal and msr
	 * This is package level MSR. Need to check if it updates correctly on
	 * multi-socket platform.
	 */
	msr = rdmsr(MSR_MISC_PWR_MGMT);
	if (!(msr.lo & LOCK_MISC_PWR_MGMT_MSR)) { /* if already locked skip update */
		msr.lo = (HWP_ENUM_ENABLE | HWP_EPP_ENUM_ENABLE | LOCK_MISC_PWR_MGMT_MSR
			  | LOCK_THERM_INT);
		wrmsr(MSR_MISC_PWR_MGMT, msr);
	}

	/* Enable Fast Strings */
	msr = rdmsr(IA32_MISC_ENABLE);
	msr.lo |= FAST_STRINGS_ENABLE_BIT;
	wrmsr(IA32_MISC_ENABLE, msr);
	/* Enable Turbo */
	enable_turbo();

	/* Enable speed step. */
	if (get_turbo_state() == TURBO_ENABLED) {
		msr = rdmsr(IA32_MISC_ENABLE);
		msr.lo |= SPEED_STEP_ENABLE_BIT;
		wrmsr(IA32_MISC_ENABLE, msr);
	}

	/* Lock the supported Cstates */
	msr = rdmsr(MSR_PKG_CST_CONFIG_CONTROL);
	msr.lo |= CST_CFG_LOCK_MASK;
	wrmsr(MSR_PKG_CST_CONFIG_CONTROL, msr);

	/* Disable all writes to overclocking limits MSR */
	msr = rdmsr(MSR_FLEX_RATIO);
	msr.lo |= MSR_FLEX_RATIO_OC_LOCK;
	wrmsr(MSR_FLEX_RATIO, msr);

	/* Lock Power Plane Limit MSR */
	msr = rdmsr(MSR_DRAM_PLANE_POWER_LIMIT);
	msr.hi |= MSR_HI_PP_PWR_LIM_LOCK;
	wrmsr(MSR_DRAM_PLANE_POWER_LIMIT, msr);

	/* Clear out pending MCEs */
	xeon_configure_mca();

	/* Enable Vmx */
	// set_vmx_and_lock();
	/* only lock. let vmx enable by FSP  */
	set_feature_ctrl_lock();
}

static struct device_operations cpu_dev_ops = {
	.init = each_cpu_init,
};

static const struct cpu_device_id cpu_table[] = {
	{X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_D, CPUID_EXACT_MATCH_MASK},
	{X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_E0, CPUID_EXACT_MATCH_MASK},
	{X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_E2, CPUID_EXACT_MATCH_MASK},
	{X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_E3, CPUID_EXACT_MATCH_MASK},
	{X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_E4, CPUID_EXACT_MATCH_MASK},
	{X86_VENDOR_INTEL, CPUID_SAPPHIRERAPIDS_SP_Ex, CPUID_EXACT_MATCH_MASK},
	CPU_TABLE_END
};

static const struct cpu_driver driver __cpu_driver = {
	.ops = &cpu_dev_ops,
	.id_table = cpu_table,
};

static void set_max_turbo_freq(void)
{
	msr_t msr, perf_ctl;

	FUNC_ENTER();
	perf_ctl.hi = 0;

	/* Check for configurable TDP option */
	if (get_turbo_state() == TURBO_ENABLED) {
		msr = rdmsr(MSR_TURBO_RATIO_LIMIT);
		perf_ctl.lo = (msr.lo & 0xff) << 8;
	} else if (cpu_config_tdp_levels()) {
		/* Set to nominal TDP ratio */
		msr = rdmsr(MSR_CONFIG_TDP_NOMINAL);
		perf_ctl.lo = (msr.lo & 0xff) << 8;
	} else {
		/* Platform Info bits 15:8 give max ratio */
		msr = rdmsr(MSR_PLATFORM_INFO);
		perf_ctl.lo = msr.lo & 0xff00;
	}
	wrmsr(IA32_PERF_CTL, perf_ctl);

	printk(BIOS_DEBUG, "cpu: frequency set to %d\n",
	       ((perf_ctl.lo >> 8) & 0xff) * CONFIG_CPU_BCLK_MHZ);
	FUNC_EXIT();
}

/*
 * Do essential initialization tasks before APs can be fired up
 */
static void pre_mp_init(void)
{
	x86_setup_mtrrs_with_detect();
	x86_mtrr_check();
}

static int get_thread_count(void)
{
	unsigned int num_phys = 0, num_virts = 0;

	cpu_read_topology(&num_phys, &num_virts);
	printk(BIOS_SPEW, "Detected %u cores and %u threads\n", num_phys, num_virts);
	return num_virts * soc_get_num_cpus();
}

static void post_mp_init(void)
{
	/* Set Max Ratio */
	set_max_turbo_freq();

	if (CONFIG(HAVE_SMI_HANDLER)) {
		global_smi_enable();
		if (get_lockdown_config() == CHIPSET_LOCKDOWN_COREBOOT)
			pmc_lock_smi();
	}
}

static const struct mp_ops mp_ops = {
	.pre_mp_init = pre_mp_init,
	.get_cpu_count = get_thread_count,
#if CONFIG(HAVE_SMI_HANDLER)
	.get_smm_info = get_smm_info,
	.pre_mp_smm_init = smm_southbridge_clear_state,
	.relocation_handler = smm_relocation_handler,
#endif
	.get_microcode_info = get_microcode_info,
	.post_mp_init = post_mp_init,
};

void mp_init_cpus(struct bus *bus)
{
	/*
	 * chip_config is used in cpu device callback. Other than cpu 0,
	 * rest of the CPU devices do not have chip_info updated.
	 */
	chip_config = bus->dev->chip_info;

	microcode_patch = intel_microcode_find();

	if (!microcode_patch)
		printk(BIOS_ERR, "microcode not found in CBFS!\n");

	intel_microcode_load_unlocked(microcode_patch);

	if (mp_init_with_smm(bus, &mp_ops) < 0)
		printk(BIOS_ERR, "MP initialization failure.\n");
}
