Date: Tue, 14 Dec 2010 20:07:51 +0000 (UTC) From: Jung-uk Kim <jkim@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r216443 - in head/sys: amd64/amd64 dev/acpica i386/i386 Message-ID: <201012142007.oBEK7pLd028994@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jkim Date: Tue Dec 14 20:07:51 2010 New Revision: 216443 URL: http://svn.freebsd.org/changeset/base/216443 Log: Stop lying about supporting cpu_est_clockrate() when TSC is invariant. This function always returned the nominal frequency instead of current frequency because we use RDTSC instruction to calculate difference in CPU ticks, which is supposedly constant for the case. Now we support cpu_get_nominal_mhz() for the case, instead. Note it should be just enough for most usage cases because cpu_est_clockrate() is often times abused to find maximum frequency of the processor. Modified: head/sys/amd64/amd64/legacy.c head/sys/amd64/amd64/machdep.c head/sys/dev/acpica/acpi_cpu.c head/sys/i386/i386/legacy.c head/sys/i386/i386/machdep.c Modified: head/sys/amd64/amd64/legacy.c ============================================================================== --- head/sys/amd64/amd64/legacy.c Tue Dec 14 20:06:55 2010 (r216442) +++ head/sys/amd64/amd64/legacy.c Tue Dec 14 20:07:51 2010 (r216443) @@ -47,6 +47,7 @@ __FBSDID("$FreeBSD$"); #include <sys/rman.h> #include <sys/smp.h> +#include <machine/clock.h> #include <machine/legacyvar.h> #include <machine/resource.h> @@ -313,9 +314,19 @@ cpu_read_ivar(device_t dev, device_t chi { struct cpu_device *cpdev; - if (index != CPU_IVAR_PCPU) + switch (index) { + case CPU_IVAR_PCPU: + cpdev = device_get_ivars(child); + *result = (uintptr_t)cpdev->cd_pcpu; + break; + case CPU_IVAR_NOMINAL_MHZ: + if (tsc_is_invariant) { + *result = (uintptr_t)(tsc_freq / 1000000); + break; + } + /* FALLTHROUGH */ + default: return (ENOENT); - cpdev = device_get_ivars(child); - *result = (uintptr_t)cpdev->cd_pcpu; + } return (0); } Modified: head/sys/amd64/amd64/machdep.c ============================================================================== --- head/sys/amd64/amd64/machdep.c Tue Dec 14 20:06:55 2010 (r216442) +++ head/sys/amd64/amd64/machdep.c Tue Dec 14 20:07:51 2010 (r216443) @@ -537,6 +537,10 @@ cpu_est_clockrate(int cpu_id, uint64_t * if (pcpu_find(cpu_id) == NULL || rate == NULL) return (EINVAL); + /* If TSC is P-state invariant, DELAY(9) based logic fails. */ + if (tsc_is_invariant) + return (EOPNOTSUPP); + /* If we're booting, trust the rate calibrated moments ago. */ if (cold) { *rate = tsc_freq; Modified: head/sys/dev/acpica/acpi_cpu.c ============================================================================== --- head/sys/dev/acpica/acpi_cpu.c Tue Dec 14 20:06:55 2010 (r216442) +++ head/sys/dev/acpica/acpi_cpu.c Tue Dec 14 20:07:51 2010 (r216443) @@ -44,6 +44,9 @@ __FBSDID("$FreeBSD$"); #include <dev/pci/pcivar.h> #include <machine/atomic.h> #include <machine/bus.h> +#if defined(__amd64__) || defined(__i386__) +#include <machine/clock.h> +#endif #include <sys/rman.h> #include <contrib/dev/acpica/include/acpi.h> @@ -510,6 +513,14 @@ acpi_cpu_read_ivar(device_t dev, device_ case CPU_IVAR_PCPU: *result = (uintptr_t)sc->cpu_pcpu; break; +#if defined(__amd64__) || defined(__i386__) + case CPU_IVAR_NOMINAL_MHZ: + if (tsc_is_invariant) { + *result = (uintptr_t)(tsc_freq / 1000000); + break; + } + /* FALLTHROUGH */ +#endif default: return (ENOENT); } Modified: head/sys/i386/i386/legacy.c ============================================================================== --- head/sys/i386/i386/legacy.c Tue Dec 14 20:06:55 2010 (r216442) +++ head/sys/i386/i386/legacy.c Tue Dec 14 20:07:51 2010 (r216443) @@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$"); #include <i386/bios/mca_machdep.h> #endif +#include <machine/clock.h> #include <machine/legacyvar.h> #include <machine/resource.h> @@ -334,9 +335,19 @@ cpu_read_ivar(device_t dev, device_t chi { struct cpu_device *cpdev; - if (index != CPU_IVAR_PCPU) + switch (index) { + case CPU_IVAR_PCPU: + cpdev = device_get_ivars(child); + *result = (uintptr_t)cpdev->cd_pcpu; + break; + case CPU_IVAR_NOMINAL_MHZ: + if (tsc_is_invariant) { + *result = (uintptr_t)(tsc_freq / 1000000); + break; + } + /* FALLTHROUGH */ + default: return (ENOENT); - cpdev = device_get_ivars(child); - *result = (uintptr_t)cpdev->cd_pcpu; + } return (0); } Modified: head/sys/i386/i386/machdep.c ============================================================================== --- head/sys/i386/i386/machdep.c Tue Dec 14 20:06:55 2010 (r216442) +++ head/sys/i386/i386/machdep.c Tue Dec 14 20:07:51 2010 (r216443) @@ -1131,6 +1131,10 @@ cpu_est_clockrate(int cpu_id, uint64_t * if (!tsc_present) return (EOPNOTSUPP); + /* If TSC is P-state invariant, DELAY(9) based logic fails. */ + if (tsc_is_invariant) + return (EOPNOTSUPP); + /* If we're booting, trust the rate calibrated moments ago. */ if (cold) { *rate = tsc_freq;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201012142007.oBEK7pLd028994>