Huang Cheng | 13 Mar 2008 03:53
Picon
Favicon

a test case for #8544 bug

Hi all,
I am a freshman, I add a test case in linuxfirmware kit to detect this
kind of BIOS bugs, invalid trip points have _PSV but no _PSL, or have
_ACx but no _ALx.

The acpidump of the buggy bios can be found at
http://bugzilla.kernel.org/show_bug.cgi?id=8544

Attachment (8544.patch): text/x-patch, 15 KiB
_______________________________________________
Firmwarekit-discuss mailing list
Firmwarekit-discuss <at> bughost.org
http://www.bughost.org/mailman/listinfo/firmwarekit-discuss
Thomas Renninger | 13 Mar 2008 10:39
Picon

Re: a test case for #8544 bug

On Thu, 2008-03-13 at 10:53 +0800, Huang Cheng wrote:
> Hi all,
> I am a freshman, I add a test case in linuxfirmware kit to detect this
> kind of BIOS bugs, invalid trip points have _PSV but no _PSL, or have
> _ACx but no _ALx.

Wow, a test kernel module.
This is the first of this kind?
Now the decision has to be taken whether ACPI bugs that cannot be found
by the iasl binary should be found via:
  A) kernel acpi driver
  B) userspace code that makes use of the ACPICA suite

I don't know what is better (the latter could be used for other OS than
Linux, but I expect this is not that important for the firmwarekit?),
but for both a general interface should be introduced first, IMO.

E.g. the netlink socket in kernel should an own kind of "firmwarekit"
driver that other upcoming firmwarekit kernel modules have to depend on
and can make use of.

Just thinking about the future..., but maybe it makes sense to push this
into a kernel/firmwaretest or firmwaretest or just kernel/test directory
in the kernel. This could be done already, creating a 8544 (bug #
right?) directory in the kernel structure looks wrong.
I could imagine, if this is not firmwarekit specific, but just exports
general netlink, sysfs, debugfs or whatever interfaces, this could find
its way to the mainline kernel at some point later as
CONFIG_FIRMWARETEST or similar. Arjan?

(Continue reading)

Huang Cheng | 17 Mar 2008 09:25
Picon
Favicon

linuxfirmware test case for bug 9444

This is a test case for bug 9444, which is to Check if there are
multiple RSDP pointers.

http://bugzilla.kernel.org/show_bug.cgi?id=9444

best regards,
Huang Cheng

Attachment (9444.patch): text/x-patch, 6284 bytes
_______________________________________________
Firmwarekit-discuss mailing list
Firmwarekit-discuss <at> bughost.org
http://www.bughost.org/mailman/listinfo/firmwarekit-discuss
Selbak, Rolla N | 28 Mar 2008 19:30
Picon
Favicon

Re: LFK cpufreq issue on dual core processor

Hi Alexandre,
 
thanks for your submissions, the changes look good to me...
 
unless Arjan has any additional comments, I'll check this code in...
 
rs

From: April, Alexandre [mailto:alexandre.april <at> ca.kontron.com]
Sent: Friday, March 28, 2008 11:02 AM
To: Selbak, Rolla N; firmwarekit-discuss <at> bughost.org
Cc: April, Alexandre; Guay, Alain Christian
Subject: RE: [Firmwarekit-discuss] LFK cpufreq issue on dual core processor

            Any feedback on this issue?

 

Attached is a diff between my modified file cpufreq.c and the one on http://linuxfirmwarekit.googlecode.com/svn/trunk/cpufreq/cpufreq.c. That should help see the modification.

     

      One of my colleagues also found a bug on DMI, he sent you an email in January but never got any response. I’ve attached a diff of his file as well with a copy of the email he sent you.

 

      Your feedback would be appreciated.

 

      Thanks in advance.

 

      Alexandre April

 

     

De : Selbak, Rolla N [mailto:rolla.n.selbak <at> intel.com]
Envoyé : 11 janvier 2008 17:53
À : April, Alexandre; firmwarekit-discuss <at> bughost.org
Objet : RE: [Firmwarekit-discuss] LFK cpufreq issue on dual core processor

 

Hi Alexandre,

 

thanks for your comments! - I really would like to see the modified code if you have it handy...

 

rs

 

From: firmwarekit-discuss-bounces <at> bughost.org [mailto:firmwarekit-discuss-bounces <at> bughost.org] On Behalf Of April, Alexandre
Sent: Tuesday, January 08, 2008 10:04 AM
To: firmwarekit-discuss <at> bughost.org
Subject: [Firmwarekit-discuss] LFK cpufreq issue on dual core processor

        Hi all,

        I was running the latest release code R3 cd on my system (2 Dual Core Intel Processor) and I kept getting failure. So I got the source code and start looking at it and I think I found some bug.

Basically I found 2 bugs on the cpufreq test source code.

Bug #1: check_sw_any

       

        At some point in this function there’s an IF statement that compare high_perf vs newhigh_perf and low_perf. The first compare subtract the newhigh_perf from the high_perf. If by any “no so lucky” chance the newhigh_perf is just few decimal bigger then the high_perf, the result might not be the one expected. So what I’ve done is use the abs function the get the absolute value from that subtraction.

Bug #2:  do_sw_any_test & do_sw_all_test

        Those 2 functions are using the get_performance_repeat function to retrieve a performance value for a specific CPU. At some point in those functions a call to “highest_speed” is done in order to set the highest frequency supported by the specified processor. The next call is a call to “get_performance_repeat” with the second parameter set to 0. That parameter is then used in the function and passed as a frequency for the set_HZ function. Now the call to “set_HZ” with 0 as the second parameter have the effect of putting the processor to it’s lowest supported speed. So that just removes the effect of the “highest_speed” function that was previously called and also has the effect of failing that specific test.

I would really appreciate a feedback from you on this. If you want I can provide the modified code to you.

Thanks in advance.

Alexandre April

_______________________________________________
Firmwarekit-discuss mailing list
Firmwarekit-discuss <at> bughost.org
http://www.bughost.org/mailman/listinfo/firmwarekit-discuss
April, Alexandre | 28 Mar 2008 19:01

Re: LFK cpufreq issue on dual core processor

            Any feedback on this issue?

 

Attached is a diff between my modified file cpufreq.c and the one on http://linuxfirmwarekit.googlecode.com/svn/trunk/cpufreq/cpufreq.c. That should help see the modification.

     

      One of my colleagues also found a bug on DMI, he sent you an email in January but never got any response. I’ve attached a diff of his file as well with a copy of the email he sent you.

 

      Your feedback would be appreciated.

 

      Thanks in advance.

 

      Alexandre April

 

     

De : Selbak, Rolla N [mailto:rolla.n.selbak <at> intel.com]
Envoyé : 11 janvier 2008 17:53
À : April, Alexandre; firmwarekit-discuss <at> bughost.org
Objet : RE: [Firmwarekit-discuss] LFK cpufreq issue on dual core processor

 

Hi Alexandre,

 

thanks for your comments! - I really would like to see the modified code if you have it handy...

 

rs

 

From: firmwarekit-discuss-bounces <at> bughost.org [mailto:firmwarekit-discuss-bounces <at> bughost.org] On Behalf Of April, Alexandre
Sent: Tuesday, January 08, 2008 10:04 AM
To: firmwarekit-discuss <at> bughost.org
Subject: [Firmwarekit-discuss] LFK cpufreq issue on dual core processor

        Hi all,

        I was running the latest release code R3 cd on my system (2 Dual Core Intel Processor) and I kept getting failure. So I got the source code and start looking at it and I think I found some bug.

Basically I found 2 bugs on the cpufreq test source code.

Bug #1: check_sw_any

       

        At some point in this function there’s an IF statement that compare high_perf vs newhigh_perf and low_perf. The first compare subtract the newhigh_perf from the high_perf. If by any “no so lucky” chance the newhigh_perf is just few decimal bigger then the high_perf, the result might not be the one expected. So what I’ve done is use the abs function the get the absolute value from that subtraction.

Bug #2:  do_sw_any_test & do_sw_all_test

        Those 2 functions are using the get_performance_repeat function to retrieve a performance value for a specific CPU. At some point in those functions a call to “highest_speed” is done in order to set the highest frequency supported by the specified processor. The next call is a call to “get_performance_repeat” with the second parameter set to 0. That parameter is then used in the function and passed as a frequency for the set_HZ function. Now the call to “set_HZ” with 0 as the second parameter have the effect of putting the processor to it’s lowest supported speed. So that just removes the effect of the “highest_speed” function that was previously called and also has the effect of failing that specific test.

I would really appreciate a feedback from you on this. If you want I can provide the modified code to you.

Thanks in advance.

Alexandre April

From: Guay, Alain Christian <alain.christian.guay <at> ca.kontron.com>
Subject: FW: dmi.c correction
Date: 2008-03-28 16:19:51 GMT



     -----Original Message-----
    From:   Guay, Alain Christian 
    Sent:   2008-01-22 3:16 PM
    To:     'firmwarekit-discuss <at> bughost.org'
    Subject:        dmi.c correction

    Hi all, there is a small problem with the dmi.c file.

    When error are found the same message appear:
    "No SMBIOS nor DMI entry point found."

    But a table is present....

    The function:

    static void report_dmi_error (char *id, int res, char *summ, char* detail, char* uri) {
            report_result("dmi", FAIL, "No SMBIOS nor DMI entry point found.", NULL, "dmi://");
            found_error++;
    }
    is bad

    it should be:

    static void report_dmi_error (char *id, int res, char *summ, char* detail, char* uri) {
            report_result(id, res,summ,detail,uri);
            found_error++;
    }


    Then all errors will be posted.

    Can you do the modification.

    Thanks.
    A.Christian Guay, ing. mailto:alain.christian.guay <at> ca.kontron.com
    Software Engineer. - BIOS
    Kontron Canada Inc.
    Support: ftp.kontron.ca
    Sale: www.kontron.com

    Tel.: (450) 437-4661 ext.: 2391
    Fax.: (450) 437-8053

    L'information contenue dans le présent document est la propriété de Kontron Canada Inc. et est divulguée en toute confidentialité. Cette information ne doit pas être révisée, utilisée, divulguée ou distribuée sans le consentement écrit explicite de Kontron Canada Inc. Si vous n'êtes pas le destinataire prévu et avez reçu cette communication par erreur, veuillez contacter l'originateur et supprimer toute copie.

    The information contained in this document is confidential and property of Kontron Canada Inc. Any unauthorized review, use, disclosure or distribution is prohibited without express written consent of Kontron Canada Inc. If you are not the intended recipient, please contact the sender and destroy all copies of the original message and enclosed attachments.

Attachment (cpufreq.diff): application/octet-stream, 1279 bytes
Attachment (dmi.diff): application/octet-stream, 2096 bytes
_______________________________________________
Firmwarekit-discuss mailing list
Firmwarekit-discuss <at> bughost.org
http://www.bughost.org/mailman/listinfo/firmwarekit-discuss
April, Alexandre | 28 Mar 2008 20:44

Re: LFK cpufreq issue on dual core processor

            I made a mistake; the diff must be looked the other way around! The (-) is what I added. So the typo is from the original source.

 

            Attached is the good patch.

 

            Sorry!

 

            Alex

 

De : Brian Maly [mailto:bmaly <at> redhat.com]
Envoyé : 28 mars 2008 15:36
À : April, Alexandre
Cc : Selbak, Rolla N; firmwarekit-discuss <at> bughost.org; Guay, Alain Christian
Objet : Re: [Firmwarekit-discuss] LFK cpufreq issue on dual core processor

 

April, Alexandre wrote:

            Any feedback on this issue?

-        report_result("cpufreq", PASS, "P-state coordination done by Hardware", NULL, NULL);
+        report_result("cpufreq", PASS, "P-state coordination done by Harware", NULL, NULL);

Noticed there is a small typo here....  a cosmetic issue. Should be "Hardware" not "Harware".
Probably this would be noticed when its checked in, but I figure I would mention it anyway.

Brian

Attachment (cpufreq.diff): application/octet-stream, 1279 bytes
Attachment (dmi.diff): application/octet-stream, 2100 bytes
_______________________________________________
Firmwarekit-discuss mailing list
Firmwarekit-discuss <at> bughost.org
http://www.bughost.org/mailman/listinfo/firmwarekit-discuss
Selbak, Rolla N | 28 Mar 2008 20:48
Picon
Favicon

Re: LFK cpufreq issue on dual core processor

hehe, yeah, I was just gonna reverse it, but thanks for doing it yourself...
 
yes, caught the 'Harware' mispell, thanks  ;)
 
rs

From: April, Alexandre [mailto:alexandre.april <at> ca.kontron.com]
Sent: Friday, March 28, 2008 12:44 PM
To: Brian Maly
Cc: Selbak, Rolla N; firmwarekit-discuss <at> bughost.org; Guay, Alain Christian; April, Alexandre
Subject: RE: [Firmwarekit-discuss] LFK cpufreq issue on dual core processor

            I made a mistake; the diff must be looked the other way around! The (-) is what I added. So the typo is from the original source.

 

            Attached is the good patch.

 

            Sorry!

 

            Alex

 

De : Brian Maly [mailto:bmaly <at> redhat.com]
Envoyé : 28 mars 2008 15:36
À : April, Alexandre
Cc : Selbak, Rolla N; firmwarekit-discuss <at> bughost.org; Guay, Alain Christian
Objet : Re: [Firmwarekit-discuss] LFK cpufreq issue on dual core processor

 

April, Alexandre wrote:

            Any feedback on this issue?

-        report_result("cpufreq", PASS, "P-state coordination done by Hardware", NULL, NULL);
+        report_result("cpufreq", PASS, "P-state coordination done by Harware", NULL, NULL);

Noticed there is a small typo here....  a cosmetic issue. Should be "Hardware" not "Harware".
Probably this would be noticed when its checked in, but I figure I would mention it anyway.

Brian

_______________________________________________
Firmwarekit-discuss mailing list
Firmwarekit-discuss <at> bughost.org
http://www.bughost.org/mailman/listinfo/firmwarekit-discuss
Brian Maly | 28 Mar 2008 20:35
Picon
Favicon

Re: LFK cpufreq issue on dual core processor

April, Alexandre wrote:
LFK cpufreq issue on dual core processor

            Any feedback on this issue?

-        report_result("cpufreq", PASS, "P-state coordination done by Hardware", NULL, NULL);
+        report_result("cpufreq", PASS, "P-state coordination done by Harware", NULL, NULL);

Noticed there is a small typo here....  a cosmetic issue. Should be "Hardware" not "Harware".
Probably this would be noticed when its checked in, but I figure I would mention it anyway.

Brian

_______________________________________________
Firmwarekit-discuss mailing list
Firmwarekit-discuss <at> bughost.org
http://www.bughost.org/mailman/listinfo/firmwarekit-discuss
Yi Yang | 30 Mar 2008 17:22
Picon
Favicon

[PATCH]: Add a T-state test case (resent)

This test case seems missed, it is very similar to cpufreq test case, please consider to
merge it and let me know if any problem, thanks.

Add T-state test case to linuxfirmwarekit, performance evaluation method
is from cpufreq test case but is modified in order to provide a good
precision.

Signed-off-by: Yi Yang <yi.y.yang <at> intel.com>
---
 Makefile  |   25 +++
 tstates.c |  428 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 453 insertions(+)

--- /dev/null	2008-02-21 05:07:22.465822503 +0800
+++ linuxfirmwarekit/tstates/tstates.c	2008-02-21 06:57:20.000000000 +0800
 <at>  <at>  -0,0 +1,428  <at>  <at> 
+/* 
+ * Copyright (C) 2006, Intel Corporation
+ * 
+ * This file is part of the Linux-ready Firmware Developer Kit
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation;version 2.1 of the License.
+ * 
+ * This library is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
+ * for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program in a file named COPYING; if not, write to the 
+ * Free Software Foundation, Inc., 
+ * 51 Franklin Street, Fifth Floor, 
+ * Boston, MA 02110-1301 USA
+ */
+
+#define _GNU_SOURCE
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <stdint.h>
+#include <sched.h>
+#include <time.h>
+#include <math.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/mman.h>
+
+#include <glib.h>
+
+#include <firmwarekit.h>
+
+struct tstateinfo {
+	int tperf;
+	int speed;
+	int diff;
+};
+
+#define GET_PERFORMANCE_MAX (0)
+#define GET_PERFORMANCE_MIN (1)
+#define GET_PERFORMANCE_AVG (2)
+
+static cpu_set_t mask, oldset;
+static int oldscheduler;
+static int oldpriority;
+
+static int max_tstate = 0;
+static int oldtstate = 0;
+static struct tstateinfo * tstates = NULL;
+static char governor[256];
+static char oldfreq[256];
+
+#define rdtscll(val) \
+	__asm__ __volatile__ ("rdtsc" : "=A" (val))
+#define abs(x) ((x) < 0 ? -x : x)
+
+static void bind_to_cpu(int cpunr)
+{
+
+        sched_getaffinity(0, sizeof(oldset), &oldset);
+
+        CPU_ZERO(&mask);
+        CPU_SET(cpunr, &mask);
+        sched_setaffinity(0, sizeof(mask), &mask);
+}
+
+static void unbind_to_cpu(int cpunr)
+{
+        sched_setaffinity(0, sizeof(oldset), &oldset);
+}
+
+static int godme(void)
+{
+	struct sched_param schedparam;
+	/*
+	 * set the process to realtime privs
+	 */
+	oldscheduler = sched_getscheduler(getpid());
+	oldpriority = getpriority(PRIO_PROCESS, getpid());
+
+	memset(&schedparam, 0, sizeof(schedparam));
+	schedparam.sched_priority = sched_get_priority_max(SCHED_FIFO);
+	
+	if (sched_setscheduler(0, SCHED_FIFO, &schedparam) != 0) {
+		perror("sched_setscheduler");
+		exit(1);
+	}
+
+	if (mlockall(MCL_CURRENT|MCL_FUTURE) != 0) {
+		perror("mlockall");
+		exit(1);
+	}
+
+	return 0;
+}
+
+static int commonme(void)
+{
+	struct sched_param schedparam;
+
+	munlockall();
+	memset(&schedparam, 0, sizeof(schedparam));
+	schedparam.sched_priority = oldpriority;
+	if (sched_setscheduler(0, oldscheduler, &schedparam) != 0) {
+		perror("sched_setscheduler");
+		exit(1);
+	}
+}
+
+static unsigned long diff_time(struct timeval start, struct timeval end)
+{
+        return (end.tv_sec - start.tv_sec) * 1000000 + (end.tv_usec - start.tv_usec);
+}
+
+static unsigned long  get_performance(int cpunr)
+{
+	struct timeval  t1, t2;
+	unsigned long loopcount = 0;
+	unsigned long interval = 4000; //4 milliseconds
+	double A, B;	
+
+	godme();
+	bind_to_cpu(cpunr);
+
+	gettimeofday(&t1, NULL);
+	do {
+		A = 1.234567;
+		B = 3.121213; 
+		A = A * B;
+		B = A * A;
+		A = A - B + sqrt(A);
+		A = A * B;
+		B = A * A;
+		A = A - B + sqrt(A);
+		A = A * B;
+		B = A * A;
+		A = A - B + sqrt(A);
+		A = A * B;
+		B = A * A;
+		A = A - B + sqrt(A);
+		loopcount++;
+		gettimeofday(&t2, NULL);
+	} while (diff_time(t1, t2) < interval);
+
+	unbind_to_cpu(cpunr);
+	commonme();
+
+	return loopcount;
+}
+
+static unsigned long  get_performance_repeat(int cpunr, int count, int type)
+{
+	int i;
+
+	unsigned long max = 0, min = ULONG_MAX, real_count = 0;
+	unsigned long long cumulative;
+	unsigned long retval;
+
+	for (i = 0; i < count; i++) {
+		unsigned long temp;
+		temp = get_performance(cpunr);
+		if (temp) {
+			if (temp < min)
+				min = temp;
+
+			if (temp > max)
+				max = temp;
+
+			cumulative += temp;
+			real_count++;
+		}
+	}
+	switch (type) {
+	    case GET_PERFORMANCE_MAX:
+		retval = max;
+		break;
+	    case GET_PERFORMANCE_MIN:
+		retval = min;
+		break;
+	    case GET_PERFORMANCE_AVG:
+		retval = cumulative/real_count;
+		break;
+	    default:
+		retval = 0;
+		break;
+	}
+	return retval;
+}
+
+static int get_tstates(cpunr)
+{
+	char path[PATH_MAX];
+	char line[4096];
+	FILE *file;
+	int i, ret, tmp;
+
+	sprintf(path, "/proc/acpi/processor/CPU%x/throttling", cpunr);
+	file = fopen(path, "r");
+	if (file == NULL) {
+		return -1;
+	}
+	memset(line, 0, 4096);
+	if (fgets(line, 4095, file)==NULL) {
+		return -1;
+	}
+	ret = sscanf(line, "state count:             %d", &max_tstate);
+	if (ret <= 0) {
+		return -1;
+	}
+
+	if (max_tstate > 0) {
+		tstates = malloc(max_tstate * sizeof(struct tstateinfo));
+		if (tstates == NULL) {
+			return -1;
+		}
+	}
+
+	i = 0;
+	while (i < max_tstate) {
+		memset(line, 0, 4096);
+		if (fgets(line, 4095, file)==NULL) {
+			return -1;
+		}
+		ret = sscanf(line + 4, "T%d:                  %d", &tmp, &tstates[i].tperf);
+		if (ret != 2) {
+			continue;
+		}
+		i++;
+		if (line[3] == '*') {
+			oldtstate = tmp;
+		}
+	}
+
+	fclose(file);
+	return 0;
+}
+
+static int stop_pstate(int cpunr)
+{
+	char filename[256];
+	FILE * fp = NULL;
+	char line[1024];
+
+	sprintf(filename, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpunr);
+	fp = fopen(filename, "r+");
+	if (fp == NULL) {
+		return 0;
+	}
+	memset(line, 0, 1024);
+	if (fgets(line, 1024, fp) == NULL) {
+		return 0;
+	}
+	strcpy(governor, line);
+	fseek(fp, 0L, SEEK_SET);
+	fputs("userspace", fp);
+	fclose(fp);
+
+	sprintf(filename, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_cur_freq", cpunr);
+	fp = fopen(filename, "r");
+	if (fp == NULL) {
+		return 0;
+	}
+	memset(line, 0, 1024);
+	if (fgets(line, 1024, fp) == NULL) {
+		return 0;
+	}
+	strcpy(oldfreq, line);
+	fclose(fp);
+
+	sprintf(filename, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_max_freq", cpunr);
+	fp = fopen(filename, "r");
+	if (fp == NULL) {
+		return 0;
+	}
+
+	memset(line, 0, 1024);
+	if (fgets(line, 1024, fp) == NULL) {
+		return 0;
+	}
+	fclose(fp);
+	
+	sprintf(filename, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_setspeed", cpunr);
+	fp = fopen(filename, "r+");
+	if (fp == NULL) {
+		return 0;
+	}
+	fputs(line, fp);
+	fclose(fp);
+
+	return 0;
+}
+
+static int start_pstate(int cpunr)
+{
+	char filename[256];
+	FILE * fp = NULL;
+	char line[1024];
+
+	sprintf(filename, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", cpunr);
+	fp = fopen(filename, "r+");
+	if (fp == NULL) {
+		return 0;
+	}
+	fputs(governor, fp);
+	fclose(fp);
+
+	sprintf(filename, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_setspeed", cpunr);
+	fp = fopen(filename, "r+");
+	if (fp == NULL) {
+		return 0;
+	}
+	fputs(oldfreq, fp);
+	fclose(fp);
+
+	return 0;
+}
+
+static int set_tstate(cpunr, tstate)
+{
+	char filename[256];
+	FILE * fp = NULL;
+	char buffer[16];
+
+	sprintf(filename, "/proc/acpi/processor/CPU%x/throttling", cpunr);
+	fp = fopen(filename, "r+");
+	if (fp == NULL) {
+		return 0;
+	}
+	sprintf(buffer, "%d", tstate);
+	fputs(buffer, fp);
+	fclose(fp);
+}
+
+static int do_tstate_test(int cpunr)
+{
+	char summary[256];
+	char details[4096];
+	int ret = 0;
+	int i, j, speed, max_speed;
+	int max_diff = 10;
+	int diff, len;
+
+	ret = get_tstates(cpunr);
+	if (ret == -1) {
+		printf("FATAL: tstates: /proc/acpi/processor/CPU*/throttling didn't exist or format error.\n");
+		return ret;
+	}
+
+	stop_pstate(cpunr);
+	set_tstate(cpunr, 0);
+	max_speed = get_performance(cpunr);
+	for (i = 0; i < max_tstate; i++) {
+		set_tstate(cpunr, i);
+		tstates[i].speed = get_performance(cpunr);
+		tstates[i].diff = (tstates[i].speed * 100)/max_speed - tstates[i].tperf;
+		report_testrun_progress((i+1)*100/max_tstate);
+		if (abs(tstates[i].diff) > max_diff) {
+			break;
+		} 
+	}
+	set_tstate(cpunr, oldtstate);
+	start_pstate(cpunr);
+	len = sprintf(details, "CPU #%d\nT-state    Theorical speed    Real Speed    Diff\n"
+			                "=======    ===============    ==========    ====\n"
+			,cpunr);
+	for (j = 0; j < max_tstate; j++) {
+		len += sprintf(details + len, "  T%d\t%12d%%\t%12d%%\t%+6d%%\n",
+				j, tstates[j].tperf, (tstates[j].speed * 100)/max_speed, tstates[j].diff);
+		if (j == i) break;
+	}
+	if (i >= max_tstate) {
+		sprintf(summary, "T-state of CPU #%d is good.", cpunr);
+		report_result("tstates", PASS, summary, details, NULL);
+	} else {
+		sprintf(summary, "T-state of CPU #%d is bad, theorical freq is %d%% greater/less than real freq",
cpunr, diff);
+		report_result("tstates", FAIL, summary, details, NULL);
+	}
+	if (tstates != NULL) {
+		free(tstates);
+		tstates = NULL;
+	}
+}
+
+int main(int argc, char **argv)
+{
+	DIR *dir;
+	struct dirent *entry;
+	char cpupath[2048];
+	int ret = 0;
+	int cpunr;
+
+	start_test("tstates", "Processor T state support", 
+	"This test checks if all processors work as T-states definition in ACPI spec. it measures the real
runtime frequency for every T-state every CPU, and check if frequency change is consistent with
percentage of every T-state."
+	);
+
+	dir = opendir("/proc/acpi/processor");
+	if (!dir) {
+		printf("FATAL: tstates: /proc/acpi/processor didn't exist.\n");
+		return 0;
+	}
+
+	do {
+		entry = readdir(dir);
+		if (entry && strlen(entry->d_name)>3) {
+			sprintf(cpupath, "/proc/acpi/processor/%s", entry->d_name);
+			cpunr = strtoul(entry->d_name+3,NULL,16);
+			if ((cpunr == 0) && (entry->d_name[3] != '0')) {
+				continue;
+			}
+			ret = do_tstate_test(cpunr);
+			if (ret == -1) {
+				exit(-1);
+			}
+		}
+	} while (entry);
+
+	finish_test("tstates");
+	return 0;
+}
--- /dev/null	2008-02-21 05:07:22.465822503 +0800
+++ linuxfirmwarekit/tstates/Makefile	2008-02-21 05:37:05.000000000 +0800
 <at>  <at>  -0,0 +1,25  <at>  <at> 
+override CFLAGS += `pkg-config --cflags glib-2.0`  -I.. -fPIC -O
+LDFLAGS =  `pkg-config --libs glib-2.0` -lm -L.. -lstandalone
+
+
+all: tstates.exe
+
+tstates.exe: tstates.o .depend
+	gcc tstates.o $(LDFLAGS) -o tstates.exe
+	cp tstates.exe ../plugins
+
+clean:
+	rm -rf *~ *.o
+	rm -f tstates.so tstates.exe
+
+# most of the makefile remains as it was before.
+# at the bottom, we add these lines:
+
+# rule for building dependency lists, and writing them to a file
+# named ".depend".
+.depend:
+	rm -f .depend
+	gccmakedep -f- -- $(CFLAGS) -- *.c > .depend 
+
+# now add a line to include the dependency list.
+include .depend

Gmane