svn commit: r216443 - in head/sys: amd64/amd64 dev/acpica i386/i386
Jung-uk Kim
jkim at FreeBSD.org
Tue Dec 14 20:07:51 UTC 2010
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;
More information about the svn-src-head
mailing list