From owner-freebsd-current@FreeBSD.ORG Sun Sep 5 16:55:56 2004 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1556016A4CE; Sun, 5 Sep 2004 16:55:56 +0000 (GMT) Received: from web.portaone.com (support.portaone.com [195.70.151.35]) by mx1.FreeBSD.org (Postfix) with ESMTP id 73DA143D41; Sun, 5 Sep 2004 16:55:52 +0000 (GMT) (envelope-from sobomax@portaone.com) Received: from [192.168.0.20] (xDSL-2-2.united.net.ua [193.111.9.226]) (authenticated bits=0) by web.portaone.com (8.12.8p2/8.12.8) with ESMTP id i85GskmE046365 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sun, 5 Sep 2004 18:55:41 +0200 (CEST) (envelope-from sobomax@portaone.com) Message-ID: <413B44B9.7020704@portaone.com> Date: Sun, 05 Sep 2004 19:54:17 +0300 From: Maxim Sobolev Organization: Porta Software Ltd User-Agent: Mozilla Thunderbird 0.7.3 (Windows/20040803) X-Accept-Language: en-us, en MIME-Version: 1.0 To: Colin Percival References: <6.1.0.6.1.20040816074348.03f99338@popserver.sfu.ca> <4120F823.2040802@portaone.com> In-Reply-To: <4120F823.2040802@portaone.com> Content-Type: multipart/mixed; boundary="------------080500030706020202000104" cc: freebsd-current@FreeBSD.ORG cc: freebsd-mobile@FreeBSD.ORG Subject: Re: Enhanced SpeedStep driver available X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 05 Sep 2004 16:55:56 -0000 This is a multi-part message in MIME format. --------------080500030706020202000104 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Please see attached a patch which adds support to TCC speed control available in every intel p4 processor. This patch requires up-to-date current system to work properly, since I've recently addes ESS-like sysctl that can be used to obtain list of speed steps supported by TCC circuit. It would be nice to have it integrated into the estctrl. Thanks! -Maxim Maxim Sobolev wrote: > Colin Percival wrote: > >> Thanks to everyone who has been sending me data about their >> processors (and in particular, the 90nm versions), I now have >> a first draft of a Enhanced SpeedStep driver available. For >> people with the appropriate processors (Pentium M only), this >> makes it possible to adjust the cpu frequency via a new sysctl >> (hw.est_curfreq), and have the cpu voltage adjusted at the >> same time. >> I've also put together a very simple control daemon which >> reads kern.cp_time every second and adjusts the cpu frequency >> based on the fraction of cpu time which is idle. This increases >> my laptop's battery life by around 40%. > > > It would be nice if you can extend it to use whatever speed control > method is available (e.g. ACPI, TCC, ESS etc), so that it can be used on > older machines as well. > > -Maxim > > >> All the code is online at >> http://www.daemonology.net/freebsd-est/ >> Assuming I don't hear any major bug reports in the next few >> days, I'll package these into ports and hopefully get them into >> the ports tree in time for 5.3-RELEASE. >> >> Colin Percival >> >> _______________________________________________ >> freebsd-current@freebsd.org mailing list >> http://lists.freebsd.org/mailman/listinfo/freebsd-current >> To unsubscribe, send any mail to >> "freebsd-current-unsubscribe@freebsd.org" >> >> >> > > _______________________________________________ > freebsd-current@freebsd.org mailing list > http://lists.freebsd.org/mailman/listinfo/freebsd-current > To unsubscribe, send any mail to "freebsd-current-unsubscribe@freebsd.org" > > > --------------080500030706020202000104 Content-Type: text/plain; name="estctrl.c.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="estctrl.c.diff" --- estctrl.c 2004/08/21 15:43:59 1.1 +++ estctrl.c 2004/08/23 19:04:51 @@ -38,9 +38,21 @@ #include static int readtimes(long * idle, long * total); -static int readfreqs(int * numfreqs, int ** freqs); -static int readcurfreq(int * curfreq); -static int setcurfreq(int freq); +static int readfreqs(int cmethod, int * numfreqs, int ** freqs); +static int readcurfreq(int cmethod, int * curfreq); +static int setcurfreq(int cmethod, int freq); + +#define CMETHOD_ESS (0) +#define CMETHOD_TCC (1) + +const struct { + const char *slevels; + const char *clevel; + const char *measure; +} sctl_names[2] = { + {"hw.est_freqs", "hw.est_curfreq", "MHz"}, + {"hw.p4tcc.cpuperf_levels", "hw.p4tcc.cpuperf", "%"} +}; static int readtimes(long * idle, long * total) { @@ -67,17 +79,18 @@ return 0; } -static int readfreqs(int * numfreqs, int ** freqs) +static int readfreqs(int cmethod, int * numfreqs, int ** freqs) { char *freqstr, *p, *q; int i; size_t len = 0; - if (sysctlbyname("hw.est_freqs", NULL, &len, NULL, 0)) + if (sysctlbyname(sctl_names[cmethod].slevels, NULL, &len, NULL, 0)) return -1; if ((freqstr = malloc(len)) == NULL) return -1; - if (sysctlbyname("hw.est_freqs", (void *)freqstr, &len, NULL, 0)) + if (sysctlbyname(sctl_names[cmethod].slevels, (void *)freqstr, &len, + NULL, 0)) return -1; *numfreqs = 1; @@ -105,21 +118,23 @@ return 0; } -static int readcurfreq(int * curfreq) +static int readcurfreq(int cmethod, int * curfreq) { size_t len = sizeof(*curfreq); - if (sysctlbyname("hw.est_curfreq", curfreq, &len, NULL, 0)) + if (sysctlbyname(sctl_names[cmethod].clevel, curfreq, &len, NULL, 0)) return -1; return 0; } -static int setcurfreq(int freq) +static int setcurfreq(int cmethod, int freq) { - printf("Setting frequency to %d\n", freq); - if (sysctlbyname("hw.est_curfreq", NULL, NULL, &freq, sizeof(freq))) + printf("Setting frequency to %d%s\n", freq, + sctl_names[cmethod].measure); + if (sysctlbyname(sctl_names[cmethod].clevel, NULL, NULL, &freq, + sizeof(freq))) return -1; return 0; @@ -130,16 +145,31 @@ long idle, total; int * freqs, numfreqs; int curfreq, i; + int cmethod; if (readtimes(NULL, NULL)) err(1, "readtimes"); - if (readfreqs(&numfreqs, &freqs)) + + if (readfreqs(CMETHOD_ESS, &numfreqs, &freqs) == 0) { + cmethod = CMETHOD_ESS; + } else if (readfreqs(CMETHOD_TCC, &numfreqs, &freqs) == 0) { + cmethod = CMETHOD_TCC; + /* + * On some machines, TCC lies right after boot, + * so that set it explicitly to the current level. + */ + if (readcurfreq(cmethod, &curfreq)) + err(1, "Error reading current CPU frequency"); + if (setcurfreq(cmethod, curfreq)) + err(1, "Error setting CPU frequency"); + } else { err(1, "Error reading supported CPU frequencies"); + } do { sleep(1); - if (readcurfreq(&curfreq)) + if (readcurfreq(cmethod, &curfreq)) err(1, "Error reading current CPU frequency"); if (readtimes(&idle, &total)) err(1, "readtimes"); @@ -149,9 +179,10 @@ if (curfreq < freqs[i]) break; printf("Idle time < 50%%, increasing clock" - " speed from %dMHz to %dMHz\n", curfreq, - freqs[i]); - if (setcurfreq(freqs[i])) + " speed from %d%s to %d%s\n", curfreq, + sctl_names[cmethod].measure, freqs[i], + sctl_names[cmethod].measure); + if (setcurfreq(cmethod, freqs[i])) err(1, "Error setting CPU frequency"); } if ((idle > (total * 3) / 4) && (curfreq > freqs[0])) { @@ -159,9 +190,10 @@ if (curfreq > freqs[i]) break; printf("Idle time > 75%%, decreasing clock" - " speed from %dMHz to %dMHz\n", curfreq, - freqs[i]); - if (setcurfreq(freqs[i])) + " speed from %d%s to %d%s\n", curfreq, + sctl_names[cmethod].measure, freqs[i], + sctl_names[cmethod].measure); + if (setcurfreq(cmethod, freqs[i])) err(1, "Error setting CPU frequency"); } } while(1); --------------080500030706020202000104--