lkml.org 
[lkml]   [1997]   [Dec]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Date
Subject[PATCH] Intel clock speed detection
Fellow kernel enthusiasts -

I've been playing with routines to determine actual cpu speed on Intel
chips; hoping to replace the "75+" notation with something accurate.

Using some assembly routines from a patch I acquired a few months ago,
whose author I have completely forgotten, I've made some preliminary
patches against 2.1.75. Here is what I did:

. added a field called "x86_mhz" to cpuinfo_x86
. added a function called "get_cpu_speed" to setup.c
. calling get_cpu_speed from identify_cpu() in setup.c
. added reporting of the speed to print_cpu_info() and get_cpuinfo()
in setup.c

Here are the problems I know I haven't addressed:

. does my mhz detection routine work reliably (ie, at all)
with all non-intel cpu's?
. what about SMP machines?
. slight variation of reported mhz (132 vs 133)
. struct cpu_model_info now has redundant elements of "Pentium"
(since I removed the 60/66, 75+). I'm not sure how these are
referenced in the first place, so I didn't compact them together
(as they should be).

The first I am hoping that some people out there will try my patch on
their AMD and Cyrix systems and let me know. The second, uhhhhh, well,
I'm over my head with this one. I would certainly appreciate any and
all help that might come my direction. Regardless of knowledge,
though, I have no practical way of testing SMP's reaction to my
patch. So I must rely on others for this.

I know that in the past, Linus has refused to include clock speed
detecting into the kernel. From what I understand, the original patch
did the calculations on the fly when you examined /proc/cpuinfo and
this was the reason for the refusal. My patch doesn't. It calculates
the rate upon boot and stores the information into
cpuinfo_x86. Hopefully, this will allow its inclusion into the
mainstream kernel once all the issues have been taken care of.

Please, take the time and look at what I've done. I know its not
anything amazing, but since the kernel isn't written in Perl, there's
not a lot I can contribute :) This, however, might be one of those
things I _can_ do.

Thank you for your time!

[ patch attached ]


___________________________________________________________________________

simple is elegant nicholas@binary9.net
___________________________________________________________________________
diff -Nur linux.75.prist/Makefile linux/Makefile
--- linux.75.prist/Makefile Sun Dec 21 20:58:14 1997
+++ linux/Makefile Mon Dec 22 20:22:40 1997
@@ -11,7 +11,7 @@
#
# NOTE! SMP is experimental. See the file Documentation/SMP.txt
#
-SMP = 1
+#SMP = 1
#
# SMP profiling options
# SMP_PROF = 1
diff -Nur linux.75.prist/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- linux.75.prist/arch/i386/kernel/setup.c Sun Dec 21 20:27:18 1997
+++ linux/arch/i386/kernel/setup.c Tue Dec 23 13:39:33 1997
@@ -323,6 +323,38 @@
c->x86_vendor = X86_VENDOR_UNKNOWN;
}

+__initfunc(int get_cpu_speed(void))
+{
+ unsigned long int a,b,j,q;
+
+ __asm__ __volatile__ (
+ "movl $1,%%eax
+ cpuid"
+ :"=d" (a)
+ :
+ :"%eax","%ebx","%ecx","%edx");
+
+ if ((a & 0x10)==0) {
+ return 0;
+ }
+ j=jiffies;
+ for (;j==jiffies;); j=jiffies;
+ __asm__ __volatile__ (
+ "rdtsc"
+ : "=a" (a)
+ :
+ : "%eax","%edx");
+ for (;j==jiffies;);
+ __asm__ __volatile__ (
+ "rdtsc"
+ : "=a" (b)
+ :
+ : "%eax","%edx");
+ q=((b-a)+(500000/HZ))/(1000000/HZ);
+
+ return q;
+}
+
struct cpu_model_info {
int vendor;
int x86;
@@ -334,9 +366,9 @@
{ "486 DX-25/33", "486 DX-50", "486 SX", "487 DX", "486 DX/2", "486 SL", "486 SX/2",
NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL }},
{ X86_VENDOR_INTEL, 5,
- { "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75+",
+ { "Pentium A-step", "Pentium", "Pentium",
"OverDrive PODP5V83", "Pentium MMX", NULL, NULL,
- "Mobile Pentium 75+", "Mobile Pentium MMX", NULL, NULL, NULL,
+ "Mobile Pentium", "Mobile Pentium MMX", NULL, NULL, NULL,
NULL, NULL, NULL, NULL }},
{ X86_VENDOR_INTEL, 6,
{ "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II", NULL,
@@ -397,6 +429,8 @@
strcpy(c->x86_model_id, p);
else
sprintf(c->x86_model_id, "%02x/%02x", c->x86_vendor, c->x86_model);
+
+ c->x86_mhz=get_cpu_speed();
}

static char *cpu_vendor_names[] __initdata = {
@@ -419,6 +453,9 @@
else
printk("%s", c->x86_model_id);

+ if (c->x86_mhz)
+ printk(" %i Mhz",c->x86_mhz);
+
if (c->x86_mask)
printk(" stepping %02x", c->x86_mask);

@@ -450,10 +487,12 @@
p += sprintf(p, "processor\t: %d\n"
"cpu family\t: %c\n"
"model\t\t: %s\n"
+ "clock speed\t: %d Mhz\n"
"vendor_id\t: %s\n",
n,
c->x86 + '0',
c->x86_model_id[0] ? c->x86_model_id : "unknown",
+ c->x86_mhz,
c->x86_vendor_id[0] ? c->x86_vendor_id : "unknown");
if (c->x86_mask) {
if (c->x86_vendor == X86_VENDOR_CYRIX)
diff -Nur linux.75.prist/include/asm-i386/processor.h linux/include/asm-i386/processor.h
--- linux.75.prist/include/asm-i386/processor.h Sun Dec 21 20:27:18 1997
+++ linux/include/asm-i386/processor.h Tue Dec 23 13:14:43 1997
@@ -33,6 +33,7 @@
int fdiv_bug;
int f00f_bug;
unsigned long loops_per_sec;
+ u16 x86_mhz;
};

#define X86_VENDOR_INTEL 0
\
 
 \ /
  Last update: 2005-03-22 13:40    [W:0.071 / U:2.416 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site