patch: please test buildkernel

From: Nate Lawson <nate_at_root.org>
Date: Mon, 31 Jan 2005 22:56:15 -0800
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 least
Received 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