The attached patch adds a new interface. It works on i386 but I need compile testing on amd64, ia64, and one other arch (sparc, powerpc, etc.) Thanks! -- Nate Index: sys/cpu.h =================================================================== RCS file: sys/cpu.h diff -N sys/cpu.h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/cpu.h 1 Feb 2005 06:53:21 -0000 _at__at_ -0,0 +1,121 _at__at_ +/*- + * Copyright (c) 2005 Nate Lawson (SDG) + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _SYS_CPU_H_ +#define _SYS_CPU_H_ + +/* + * CPU device support. + */ + +#define CPU_IVAR_PCPU 1 + +static __inline struct pcpu *cpu_get_pcpu(device_t dev) +{ + uintptr_t v = 0; + BUS_READ_IVAR(device_get_parent(dev), dev, CPU_IVAR_PCPU, &v); + return ((struct pcpu *)v); +} + +/* + * CPU frequency control interface. + */ + +/* Each driver's CPU frequency setting is exported in this format. */ +struct cf_setting { + int freq; /* Processor clock in Mhz or percent (in 100ths.) */ + int volts; /* Voltage in mV. */ + int power; /* Power consumed in mW. */ + int lat; /* Transition latency in us. */ + device_t dev; /* Driver providing this setting. */ +}; + +/* Maximum number of settings a given driver can have. */ +#define MAX_SETTINGS 16 + +/* A combination of settings is a level. */ +struct cf_level { + struct cf_setting total_set; + struct cf_setting abs_set; + struct cf_setting rel_set[MAX_SETTINGS]; + int rel_count; + TAILQ_ENTRY(cf_level) link; +}; + +TAILQ_HEAD(cf_level_lst, cf_level); + +/* Drivers should set all unknown values to this. */ +#define CPUFREQ_VAL_UNKNOWN (-1) + +/* + * Every driver offers a type of CPU control. Absolute levels are mutually + * exclusive while relative levels modify the current absolute level. There + * may be multiple absolute and relative drivers available on a given + * system. + * + * For example, consider a system with two absolute drivers that provide + * frequency settings of 100, 200 and 300, 400 and a relative driver that + * provides settings of 50%, 100%. The cpufreq core would export frequency + * levels of 50, 100, 150, 200, 300, 400. + */ +#define CPUFREQ_TYPE_RELATIVE (1<<0) +#define CPUFREQ_TYPE_ABSOLUTE (1<<1) + +/* + * When setting a level, the caller indicates the priority of this request. + * Priorities determine, among other things, whether a level can be + * overridden by other callers. For example, if the user sets a level but + * the system thermal driver needs to override it for emergency cooling, + * the driver would use a higher priority. Once the event has passed, the + * driver would call cpufreq to resume any previous level. + */ +#define CPUFREQ_PRIO_HIGHEST 1000000 +#define CPUFREQ_PRIO_KERN 1000 +#define CPUFREQ_PRIO_USER 100 +#define CPUFREQ_PRIO_LOWEST 0 + +/* + * Register and unregister a driver with the cpufreq core. Once a driver + * is registered, it must support calls to its CPUFREQ_GET, CPUFREQ_GET_LEVEL, + * and CPUFREQ_SET methods. It must also unregister before returning from + * its DEVICE_DETACH method. + */ +int cpufreq_register(device_t dev); +int cpufreq_unregister(device_t dev); + +/* Allow values to be +/- a bit since sometimes we have to estimate. */ +#define CPUFREQ_CMP(x, y) (abs((x) - (y)) < 25) + +/* + * Machine-dependent functions. + */ + +/* Estimate the current clock rate for the given CPU id. */ +int cpu_est_clockrate(int cpu_id, uint64_t *rate); + +#endif /* !_SYS_CPU_H_ */ Index: i386/i386/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/machdep.c,v retrieving revision 1.603 diff -u -r1.603 machdep.c --- i386/i386/machdep.c 27 Nov 2004 06:51:35 -0000 1.603 +++ i386/i386/machdep.c 1 Feb 2005 06:33:20 -0000 _at__at_ -56,8 +56,12 _at__at_ #include <sys/param.h> #include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/signalvar.h> +#include <sys/bio.h> +#include <sys/buf.h> +#include <sys/bus.h> +#include <sys/callout.h> +#include <sys/cpu.h> +#include <sys/eventhandler.h> #include <sys/imgact.h> #include <sys/kdb.h> #include <sys/kernel.h> _at__at_ -66,21 +70,18 _at__at_ #include <sys/lock.h> #include <sys/malloc.h> #include <sys/memrange.h> +#include <sys/msgbuf.h> #include <sys/mutex.h> #include <sys/pcpu.h> #include <sys/proc.h> -#include <sys/bio.h> -#include <sys/buf.h> #include <sys/reboot.h> -#include <sys/callout.h> -#include <sys/msgbuf.h> #include <sys/sched.h> -#include <sys/sysent.h> +#include <sys/signalvar.h> #include <sys/sysctl.h> +#include <sys/sysent.h> +#include <sys/sysproto.h> #include <sys/ucontext.h> #include <sys/vmmeter.h> -#include <sys/bus.h> -#include <sys/eventhandler.h> #include <vm/vm.h> #include <vm/vm_param.h> _at__at_ -104,6 +105,7 _at__at_ #include <net/netisr.h> +#include <machine/clock.h> #include <machine/cpu.h> #include <machine/cputypes.h> #include <machine/reg.h> _at__at_ -1022,6 +1024,46 _at__at_ { } +/* 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 */ Index: amd64/amd64/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/amd64/amd64/machdep.c,v retrieving revision 1.625 diff -u -r1.625 machdep.c --- amd64/amd64/machdep.c 29 Nov 2004 23:27:07 -0000 1.625 +++ amd64/amd64/machdep.c 1 Feb 2005 06:44:09 -0000 _at__at_ -56,8 +56,12 _at__at_ #include <sys/param.h> #include <sys/systm.h> -#include <sys/sysproto.h> -#include <sys/signalvar.h> +#include <sys/bio.h> +#include <sys/buf.h> +#include <sys/bus.h> +#include <sys/callout.h> +#include <sys/cpu.h> +#include <sys/eventhandler.h> #include <sys/imgact.h> #include <sys/kdb.h> #include <sys/kernel.h> _at__at_ -69,19 +73,17 _at__at_ #include <sys/mutex.h> #include <sys/pcpu.h> #include <sys/proc.h> -#include <sys/bio.h> -#include <sys/buf.h> #include <sys/reboot.h> -#include <sys/callout.h> #include <sys/msgbuf.h> #include <sys/sched.h> +#include <sys/signalvar.h> #include <sys/sysent.h> #include <sys/sysctl.h> +#include <sys/sysproto.h> #include <sys/ucontext.h> #include <sys/vmmeter.h> -#include <sys/bus.h> -#include <sys/eventhandler.h> +#include <machine/clock.h> #include <machine/pcb.h> #include <vm/vm.h> _at__at_ -450,6 +452,44 _at__at_ { } +/* 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 */ Index: ia64/ia64/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/ia64/ia64/machdep.c,v retrieving revision 1.193 diff -u -r1.193 machdep.c --- ia64/ia64/machdep.c 8 Dec 2004 05:46:54 -0000 1.193 +++ ia64/ia64/machdep.c 1 Feb 2005 06:47:52 -0000 _at__at_ -35,6 +35,7 _at__at_ #include <sys/param.h> #include <sys/systm.h> +#include <sys/cpu.h> #include <sys/eventhandler.h> #include <sys/kdb.h> #include <sys/sysproto.h> _at__at_ -287,6 +288,17 _at__at_ 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() { Index: alpha/alpha/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/alpha/alpha/machdep.c,v retrieving revision 1.228 diff -u -r1.228 machdep.c --- alpha/alpha/machdep.c 5 Jan 2005 20:05:49 -0000 1.228 +++ alpha/alpha/machdep.c 1 Feb 2005 06:50:03 -0000 _at__at_ -98,6 +98,7 _at__at_ #include <sys/param.h> #include <sys/systm.h> +#include <sys/cpu.h> #include <sys/eventhandler.h> #include <sys/imgact.h> #include <sys/kdb.h> _at__at_ -1718,6 +1719,14 _at__at_ { } +/* 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 */ Index: arm/arm/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/arm/arm/machdep.c,v retrieving revision 1.9 diff -u -r1.9 machdep.c --- arm/arm/machdep.c 10 Jan 2005 22:43:16 -0000 1.9 +++ arm/arm/machdep.c 1 Feb 2005 06:50:41 -0000 _at__at_ -48,6 +48,7 _at__at_ #include <sys/param.h> #include <sys/systm.h> +#include <sys/cpu.h> #include <sys/sysproto.h> #include <sys/signalvar.h> #include <sys/imgact.h> _at__at_ -236,6 +237,14 _at__at_ 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) { Index: powerpc/powerpc/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/powerpc/powerpc/machdep.c,v retrieving revision 1.79 diff -u -r1.79 machdep.c --- powerpc/powerpc/machdep.c 7 Jan 2005 02:29:20 -0000 1.79 +++ powerpc/powerpc/machdep.c 1 Feb 2005 06:51:03 -0000 _at__at_ -64,6 +64,7 _at__at_ #include <sys/param.h> #include <sys/systm.h> +#include <sys/cpu.h> #include <sys/kdb.h> #include <sys/eventhandler.h> #include <sys/imgact.h> _at__at_ -700,6 +701,14 _at__at_ { } +/* 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. */ Index: sparc64/sparc64/machdep.c =================================================================== RCS file: /home/ncvs/src/sys/sparc64/sparc64/machdep.c,v retrieving revision 1.117 diff -u -r1.117 machdep.c --- sparc64/sparc64/machdep.c 27 Nov 2004 06:51:38 -0000 1.117 +++ sparc64/sparc64/machdep.c 1 Feb 2005 06:51:39 -0000 _at__at_ -44,6 +44,7 _at__at_ #include <sys/param.h> #include <sys/systm.h> #include <sys/cons.h> +#include <sys/cpu.h> #include <sys/imgact.h> #include <sys/kdb.h> #include <sys/kernel.h> _at__at_ -669,6 +670,14 _at__at_ 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 leastReceived on Tue Feb 01 2005 - 05:58:22 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:27 UTC