Hi!

> > Unfortunately, when my toshiba changes speed, it changes speed of
> > cycle counter, too :-(. That sounds like show stopper.
> 
> Thats a gift not a show stopper. Just check the rdtsc change between each
> timer tick looks believeable. Timer ticks might get delayed but if you start
> to get an excessive numbers of ticks per n cycles of the tsc you know your
> CPU slowed down

Detecting this is easy (and actually works): [It does not recalculate
bogomips just now. Should we really recalculate them or just scale
them according to the tsc?]

But... That is wrong solution. We already ran for at least one tick
with wrong bogomips. If by chance some flaky device is used for that
one-tick period, we already lost the game...
                                                                Pavel

--- clean/arch/i386/kernel/time.c       Sun Oct 10 11:22:47 1999
+++ linux/arch/i386/kernel/time.c       Sun Oct 31 23:17:28 1999
@@ -429,6 +466,27 @@
         */
        write_lock(&xtime_lock);
 
+       if (use_tsc) {
+               long off = do_gettimeoffset();
+               static int faster = 0, slower = 0;
+               if (off > (1100000/HZ))
+                       faster++;
+               else
+                       faster = 0;
+
+               if (off < (900000/HZ))
+                       slower++;
+               else
+                       slower = 0;
+
+               if ((faster > 10) || (slower > 10)) {
+                       printk( KERN_ERR "TSC is %s than it should be! ", (faster > 
+10) ? "faster" : "slower" );
+                       big_calibrate_tsc();
+                       faster = 0;
+                       slower = 0;
+               }
+       }
+
        if (use_tsc)
        {
                /*
@@ -547,7 +605,7 @@
 #define CALIBRATE_LATCH        (5 * LATCH)
 #define CALIBRATE_TIME (5 * 1000020/HZ)
 
-static unsigned long __init calibrate_tsc(void)
+static unsigned long calibrate_tsc(void)
 {
        /* Set the Gate high, disable speaker */
        outb((inb(0x61) & ~0x02) | 0x01, 0x61);
@@ -612,11 +670,39 @@
        return 0;
 }
 
+void big_calibrate_tsc(void)
+{
+       if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) {
+               unsigned long tsc_quotient = calibrate_tsc();
+               if (tsc_quotient) {
+                       fast_gettimeoffset_quotient = tsc_quotient;
+                       use_tsc = 1;
+#ifndef do_gettimeoffset
+                       do_gettimeoffset = do_fast_gettimeoffset;
+#endif
+                       do_get_fast_time = do_gettimeofday;
+
+                       /* report CPU clock rate in Hz.
+                        * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
+                        * clock/second. Our precision is about 100 ppm.
+                        */
+                       {       unsigned long eax=0, edx=1000000;
+                               __asm__("divl %2"
+                               :"=a" (cpu_hz), "=d" (edx)
+                               :"r" (tsc_quotient),
+                               "0" (eax), "1" (edx));
+                               printk("Detected %ld Hz processor.\n", cpu_hz);
+                       }
+               }
+       }
+}
+
 void __init time_init(void)
 {
        xtime.tv_sec = get_cmos_time();
        xtime.tv_usec = 0;
 
+  
 /*
  * If we have APM enabled or the CPU clock speed is variable
  * (CPU stops clock on HLT or slows clock to save power)
@@ -644,29 +730,7 @@
  
        dodgy_tsc();
        
-       if (boot_cpu_data.x86_capability & X86_FEATURE_TSC) {
-               unsigned long tsc_quotient = calibrate_tsc();
-               if (tsc_quotient) {
-                       fast_gettimeoffset_quotient = tsc_quotient;
-                       use_tsc = 1;
-#ifndef do_gettimeoffset
-                       do_gettimeoffset = do_fast_gettimeoffset;
-#endif
-                       do_get_fast_time = do_gettimeofday;
-
-                       /* report CPU clock rate in Hz.
-                        * The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
-                        * clock/second. Our precision is about 100 ppm.
-                        */
-                       {       unsigned long eax=0, edx=1000000;
-                               __asm__("divl %2"
-                               :"=a" (cpu_hz), "=d" (edx)
-                               :"r" (tsc_quotient),
-                               "0" (eax), "1" (edx));
-                               printk("Detected %ld Hz processor.\n", cpu_hz);
-                       }
-               }
-       }
+       big_calibrate_tsc();
 
 #ifdef CONFIG_VISWS
        printk("Starting Cobalt Timer system clock\n");
@@ -686,3 +750,4 @@
        setup_irq(0, &irq0);
 #endif
 }
+


-- 
I'm really [EMAIL PROTECTED] Look at http://195.113.31.123/~pavel.  Pavel
Hi! I'm a .signature virus! Copy me into your ~/.signature, please!

Reply via email to