// SPDX-License-Identifier: GPL-2.0
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>

#include "helpers/helpers.h"

static const char *cpu_vendor_table[X86_VENDOR_MAX] = {
	"Unknown", "GenuineIntel", "AuthenticAMD", "HygonGenuine",
};

#if defined(__i386__) || defined(__x86_64__)

/* from gcc */
#include <cpuid.h>

/*
 * CPUID functions returning a single datum
 *
 * Define unsigned int cpuid_e[abcd]x(unsigned int op)
 */
#define cpuid_func(reg)					\
	unsigned int cpuid_##reg(unsigned int op)	\
	{						\
	unsigned int eax, ebx, ecx, edx;		\
	__cpuid(op, eax, ebx, ecx, edx);		\
	return reg;					\
	}
cpuid_func(eax);
cpuid_func(ebx);
cpuid_func(ecx);
cpuid_func(edx);

#endif /* defined(__i386__) || defined(__x86_64__) */

/* get_cpu_info
 *
 * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo
 *
 * Returns 0 on success or a negativ error code
 *
 * TBD: Should there be a cpuid alternative for this if /proc is not mounted?
 */
int get_cpu_info(struct cpupower_cpu_info *cpu_info)
{
	FILE *fp;
	char value[64];
	unsigned int proc, x;
	unsigned int unknown = 0xffffff;
	unsigned int cpuid_level, ext_cpuid_level;

	int ret = -EINVAL;

	cpu_info->vendor		= X86_VENDOR_UNKNOWN;
	cpu_info->family		= unknown;
	cpu_info->model			= unknown;
	cpu_info->stepping		= unknown;
	cpu_info->caps			= 0;

	fp = fopen("/proc/cpuinfo", "r");
	if (!fp)
		return -EIO;

	while (!feof(fp)) {
		if (!fgets(value, 64, fp))
			continue;
		value[63 - 1] = '\0';

		if (!strncmp(value, "processor\t: ", 12))
			sscanf(value, "processor\t: %u", &proc);

		if (proc != (unsigned int)base_cpu)
			continue;

		/* Get CPU vendor */
		if (!strncmp(value, "vendor_id", 9)) {
			for (x = 1; x < X86_VENDOR_MAX; x++) {
				if (strstr(value, cpu_vendor_table[x]))
					cpu_info->vendor = x;
			}
		/* Get CPU family, etc. */
		} else if (!strncmp(value, "cpu family\t: ", 13)) {
			sscanf(value, "cpu family\t: %u",
			       &cpu_info->family);
		} else if (!strncmp(value, "model\t\t: ", 9)) {
			sscanf(value, "model\t\t: %u",
			       &cpu_info->model);
		} else if (!strncmp(value, "stepping\t: ", 10)) {
			sscanf(value, "stepping\t: %u",
			       &cpu_info->stepping);

			/* Exit -> all values must have been set */
			if (cpu_info->vendor == X86_VENDOR_UNKNOWN ||
			    cpu_info->family == unknown ||
			    cpu_info->model == unknown ||
			    cpu_info->stepping == unknown) {
				ret = -EINVAL;
				goto out;
			}

			ret = 0;
			goto out;
		}
	}
	ret = -ENODEV;
out:
	fclose(fp);
	/* Get some useful CPU capabilities from cpuid */
	if (cpu_info->vendor != X86_VENDOR_AMD &&
	    cpu_info->vendor != X86_VENDOR_HYGON &&
	    cpu_info->vendor != X86_VENDOR_INTEL)
		return ret;

	cpuid_level	= cpuid_eax(0);
	ext_cpuid_level	= cpuid_eax(0x80000000);

	/* Invariant TSC */
	if (ext_cpuid_level >= 0x80000007 &&
	    (cpuid_edx(0x80000007) & (1 << 8)))
		cpu_info->caps |= CPUPOWER_CAP_INV_TSC;

	/* Aperf/Mperf registers support */
	if (cpuid_level >= 6 && (cpuid_ecx(6) & 0x1))
		cpu_info->caps |= CPUPOWER_CAP_APERF;

	/* AMD or Hygon Boost state enable/disable register */
	if (cpu_info->vendor == X86_VENDOR_AMD ||
	    cpu_info->vendor == X86_VENDOR_HYGON) {
		if (ext_cpuid_level >= 0x80000007) {
			if (cpuid_edx(0x80000007) & (1 << 9)) {
				cpu_info->caps |= CPUPOWER_CAP_AMD_CPB;

				if (cpu_info->family >= 0x17)
					cpu_info->caps |= CPUPOWER_CAP_AMD_CPB_MSR;
			}

			if ((cpuid_edx(0x80000007) & (1 << 7)) &&
			    cpu_info->family != 0x14) {
				/* HW pstate was not implemented in family 0x14 */
				cpu_info->caps |= CPUPOWER_CAP_AMD_HW_PSTATE;

				if (cpu_info->family >= 0x17)
					cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATEDEF;
			}
		}

		if (ext_cpuid_level >= 0x80000008 &&
		    cpuid_ebx(0x80000008) & (1 << 4))
			cpu_info->caps |= CPUPOWER_CAP_AMD_RDPRU;

		if (cpupower_amd_pstate_enabled()) {
			cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATE;

			/*
			 * If AMD P-State is enabled, the firmware will treat
			 * AMD P-State function as high priority.
			 */
			cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB;
			cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB_MSR;
			cpu_info->caps &= ~CPUPOWER_CAP_AMD_HW_PSTATE;
			cpu_info->caps &= ~CPUPOWER_CAP_AMD_PSTATEDEF;
		}
	}

	if (cpu_info->vendor == X86_VENDOR_INTEL) {
		if (cpuid_level >= 6 &&
		    (cpuid_eax(6) & (1 << 1)))
			cpu_info->caps |= CPUPOWER_CAP_INTEL_IDA;
	}

	if (cpu_info->vendor == X86_VENDOR_INTEL) {
		/* Intel's perf-bias MSR support */
		if (cpuid_level >= 6 && (cpuid_ecx(6) & (1 << 3)))
			cpu_info->caps |= CPUPOWER_CAP_PERF_BIAS;

		/* Intel's Turbo Ratio Limit support */
		if (cpu_info->family == 6) {
			switch (cpu_info->model) {
			case 0x1A:	/* Core i7, Xeon 5500 series
					 * Bloomfield, Gainstown NHM-EP
					 */
			case 0x1E:	/* Core i7 and i5 Processor
					 * Clarksfield, Lynnfield, Jasper Forest
					 */
			case 0x1F:	/* Core i7 and i5 Processor - Nehalem */
			case 0x25:	/* Westmere Client
					 * Clarkdale, Arrandale
					 */
			case 0x2C:	/* Westmere EP - Gulftown */
				cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
				break;
			case 0x2A:	/* SNB */
			case 0x2D:	/* SNB Xeon */
			case 0x3A:	/* IVB */
			case 0x3E:	/* IVB Xeon */
				cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
				cpu_info->caps |= CPUPOWER_CAP_IS_SNB;
				break;
			case 0x2E:	/* Nehalem-EX Xeon - Beckton */
			case 0x2F:	/* Westmere-EX Xeon - Eagleton */
			default:
				break;
			}
		}
	}

	/*	printf("ID: %u - Extid: 0x%x - Caps: 0x%llx\n",
		cpuid_level, ext_cpuid_level, cpu_info->caps);
	*/
	return ret;
}
