diff --git a/sys/alpha/alpha/machdep.c b/sys/alpha/alpha/machdep.c index d93a86d68eec..ebf971f71e5d 100644 --- a/sys/alpha/alpha/machdep.c +++ b/sys/alpha/alpha/machdep.c @@ -98,6 +98,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -1718,6 +1719,14 @@ cpu_boot(int howto) { } +/* Get current clock frequency for the given cpu id. */ +int +cpu_est_clockrate(int cpu_id, uint64_t *rate) +{ + + return (ENXIO); +} + /* * Shutdown the CPU as much as possible */ diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c index 16157c107311..527c61bd1dbb 100644 --- a/sys/amd64/amd64/machdep.c +++ b/sys/amd64/amd64/machdep.c @@ -56,8 +56,12 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -69,19 +73,17 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include -#include #include -#include #include #include +#include #include #include +#include #include #include -#include -#include +#include #include #include @@ -450,6 +452,44 @@ cpu_boot(int howto) { } +/* Get current clock frequency for the given cpu id. */ +int +cpu_est_clockrate(int cpu_id, uint64_t *rate) +{ + uint64_t tsc1, tsc2; + + if (pcpu_find(cpu_id) == NULL || rate == NULL) + return (EINVAL); + + /* If we're booting, trust the rate calibrated moments ago. */ + if (cold) { + *rate = tsc_freq; + return (0); + } + +#ifdef SMP + /* Schedule ourselves on the indicated cpu. */ + mtx_lock_spin(&sched_lock); + sched_bind(curthread, cpu_id); + mtx_unlock_spin(&sched_lock); +#endif + + /* Calibrate by measuring a short delay. */ + tsc1 = rdtsc(); + DELAY(1000); + tsc2 = rdtsc(); + +#ifdef SMP + mtx_lock_spin(&sched_lock); + sched_unbind(curthread); + mtx_unlock_spin(&sched_lock); +#endif + + tsc_freq = (tsc2 - tsc1) * 1000; + *rate = tsc_freq; + return (0); +} + /* * Shutdown the CPU as much as possible */ diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c index 9a9f6150e494..06d33c382fd8 100644 --- a/sys/arm/arm/machdep.c +++ b/sys/arm/arm/machdep.c @@ -48,6 +48,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -236,6 +237,14 @@ cpu_startup(void *dummy) SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_startup, NULL) +/* Get current clock frequency for the given cpu id. */ +int +cpu_est_clockrate(int cpu_id, uint64_t *rate) +{ + + return (ENXIO); +} + void cpu_idle(void) { diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 9c3b98ade7c8..ef82b80959d9 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -56,8 +56,12 @@ __FBSDID("$FreeBSD$"); #include #include -#include -#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -66,21 +70,18 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include -#include -#include #include -#include -#include #include -#include +#include #include +#include +#include #include #include -#include -#include #include #include @@ -104,6 +105,7 @@ __FBSDID("$FreeBSD$"); #include +#include #include #include #include @@ -1022,6 +1024,46 @@ cpu_boot(int howto) { } +/* Get current clock frequency for the given cpu id. */ +int +cpu_est_clockrate(int cpu_id, uint64_t *rate) +{ + uint64_t tsc1, tsc2; + + if (pcpu_find(cpu_id) == NULL || rate == NULL) + return (EINVAL); + if (!tsc_present) + return (EOPNOTSUPP); + + /* If we're booting, trust the rate calibrated moments ago. */ + if (cold) { + *rate = tsc_freq; + return (0); + } + +#ifdef SMP + /* Schedule ourselves on the indicated cpu. */ + mtx_lock_spin(&sched_lock); + sched_bind(curthread, cpu_id); + mtx_unlock_spin(&sched_lock); +#endif + + /* Calibrate by measuring a short delay. */ + tsc1 = rdtsc(); + DELAY(1000); + tsc2 = rdtsc(); + +#ifdef SMP + mtx_lock_spin(&sched_lock); + sched_unbind(curthread); + mtx_unlock_spin(&sched_lock); +#endif + + tsc_freq = (tsc2 - tsc1) * 1000; + *rate = tsc_freq; + return (0); +} + /* * Shutdown the CPU as much as possible */ diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 608943d4f2da..289c3e1ea25a 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -35,6 +35,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -287,6 +288,17 @@ cpu_boot(int howto) efi_reset_system(); } +/* Get current clock frequency for the given cpu id. */ +int +cpu_est_clockrate(int cpu_id, uint64_t *rate) +{ + + if (pcpu_find(cpu_id) == NULL || rate == NULL) + return (EINVAL); + *rate = processor_frequency; + return (0); +} + void cpu_halt() { diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index 1748c02db1e3..c54f3363b23f 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -700,6 +701,14 @@ cpu_boot(int howto) { } +/* Get current clock frequency for the given cpu id. */ +int +cpu_est_clockrate(int cpu_id, uint64_t *rate) +{ + + return (ENXIO); +} + /* * Shutdown the CPU as much as possible. */ diff --git a/sys/powerpc/powerpc/machdep.c b/sys/powerpc/powerpc/machdep.c index 1748c02db1e3..c54f3363b23f 100644 --- a/sys/powerpc/powerpc/machdep.c +++ b/sys/powerpc/powerpc/machdep.c @@ -64,6 +64,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include #include @@ -700,6 +701,14 @@ cpu_boot(int howto) { } +/* Get current clock frequency for the given cpu id. */ +int +cpu_est_clockrate(int cpu_id, uint64_t *rate) +{ + + return (ENXIO); +} + /* * Shutdown the CPU as much as possible. */ diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c index b70ac9ab5405..7fe6acdd41f3 100644 --- a/sys/sparc64/sparc64/machdep.c +++ b/sys/sparc64/sparc64/machdep.c @@ -44,6 +44,7 @@ #include #include #include +#include #include #include #include @@ -669,6 +670,14 @@ cpu_shutdown(void *args) openfirmware_exit(args); } +/* Get current clock frequency for the given cpu id. */ +int +cpu_est_clockrate(int cpu_id, uint64_t *rate) +{ + + return (ENXIO); +} + /* * Duplicate OF_exit() with a different firmware call function that restores * the trap table, otherwise a RED state exception is triggered in at least