Module Name: src Committed By: jruoho Date: Sat Sep 24 19:41:40 UTC 2011
Modified Files: src/sys/arch/x86/acpi: acpi_cpu_md.c Log Message: Try to obtain reliable MHz values for AMD familiesi 10h and 11h. To generate a diff of this commit: cvs rdiff -u -r1.66 -r1.67 src/sys/arch/x86/acpi/acpi_cpu_md.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/x86/acpi/acpi_cpu_md.c diff -u src/sys/arch/x86/acpi/acpi_cpu_md.c:1.66 src/sys/arch/x86/acpi/acpi_cpu_md.c:1.67 --- src/sys/arch/x86/acpi/acpi_cpu_md.c:1.66 Sat Sep 24 11:17:25 2011 +++ src/sys/arch/x86/acpi/acpi_cpu_md.c Sat Sep 24 19:41:40 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: acpi_cpu_md.c,v 1.66 2011/09/24 11:17:25 jruoho Exp $ */ +/* $NetBSD: acpi_cpu_md.c,v 1.67 2011/09/24 19:41:40 jruoho Exp $ */ /*- * Copyright (c) 2010, 2011 Jukka Ruohonen <jruoho...@iki.fi> @@ -27,7 +27,7 @@ * SUCH DAMAGE. */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.66 2011/09/24 11:17:25 jruoho Exp $"); +__KERNEL_RCSID(0, "$NetBSD: acpi_cpu_md.c,v 1.67 2011/09/24 19:41:40 jruoho Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -106,6 +106,7 @@ static char native_idle_text[16]; void (*native_idle)(void) = NULL; static int acpicpu_md_quirk_piix4(const struct pci_attach_args *); +static void acpicpu_md_quirk_amd(struct acpicpu_pstate *, uint32_t); static void acpicpu_md_pstate_hwf_reset(void *, void *); static int acpicpu_md_pstate_fidvid_get(struct acpicpu_softc *, uint32_t *); @@ -334,6 +335,55 @@ acpicpu_md_quirk_piix4(const struct pci_ return 0; } +static void +acpicpu_md_quirk_amd(struct acpicpu_pstate *ps, uint32_t i) +{ + struct cpu_info *ci = &cpu_info_primary; + uint32_t family, fid, freq, did, zeta; + uint64_t val; + + if (i > 7 || cpu_vendor != CPUVENDOR_AMD) + return; + + family = CPUID2FAMILY(ci->ci_signature); + + if (family == 0xf) + family += CPUID2EXTFAMILY(ci->ci_signature); + + switch (family) { + + case 0x10: + zeta = 0x10; + break; + + case 0x11: + zeta = 0x08; + break; + + default: + return; + } + + /* + * The following eight P-state control MSRs define + * the static per-core values; the MSB indicates + * whether the state is enabled, and the first eight + * bits define the frequency divisor and multiplier. + */ + val = rdmsr(MSR_10H_CONFIG + i); + + if ((val & __BIT(63)) == 0) + return; + + fid = __SHIFTOUT(val, __BITS(0, 5)); + did = __SHIFTOUT(val, __BITS(6, 8)); + + freq = 100 * (fid + zeta) >> did; + + if (freq != 0 && ps->ps_freq != freq) + ps->ps_freq = freq; +} + void acpicpu_md_quirk_c1e(void) { @@ -596,6 +646,13 @@ acpicpu_md_pstate_init(struct acpicpu_so if (msr.ps_control_mask != 0) ps->ps_control_mask = msr.ps_control_mask; + /* + * Some AMD systems may round the frequencies + * reported in the tables. Try to fix these. + */ + if (cpu_vendor == CPUVENDOR_AMD) + acpicpu_md_quirk_amd(ps, i); + i++; }