tools/power/cpupower/utils/helpers/cpuid.c

Source file repositories/reference/linux-study-clean/tools/power/cpupower/utils/helpers/cpuid.c

File Facts

System
Linux kernel
Corpus path
tools/power/cpupower/utils/helpers/cpuid.c
Extension
.c
Size
5562 bytes
Lines
214
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

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) {

Annotation

Implementation Notes