Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 5 Nov 1996 13:48:36 +0900 (JST)
From:      ohashi@mickey.ai.kyutech.ac.jp
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   i386/1959: DELAY() in /sys/i386/isa/clock.c 
Message-ID:  <199611050448.NAA11117@at_ohasi.mickey.ai.kyutech.ac.jp>
Resent-Message-ID: <199611050500.VAA03161@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         1959
>Category:       i386
>Synopsis:       DELAY() won't work for fast CPUs
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov  4 21:00:01 PST 1996
>Last-Modified:
>Originator:     Takeshi Ohashi
>Organization:
Dept. of AI, Kyushu Inst. of Tech., Iizuka, JAPAN.
>Release:        FreeBSD 2.2-961014-SNAP, current and 2.1.5-R
>Environment:

	Pentium Pro 200MHz and faster Pentium CPUs
	

>Description:

	Some PentiumPro boxes hang up the keyboard.
	

>How-To-Repeat:

	When fast typing.
	

>Fix:
	
	Patch for FreeBSD 2.2-961014-SNAP /sys/i386/isa/clock.c

===============================================
--- clock.c     Thu Oct 10 04:47:31 1996
+++ clock.c.new Mon Nov  4 17:54:03 1996
@@ -145,6 +145,7 @@
 static u_char  timer0_state;
 static u_char  timer2_state;
 static         void    (*timer_func) __P((struct clockframe *frame)) = hardcloc
k;
+static u_int   delay_offset = 20;      /* 20usec for i386 */
 
 #if defined(I586_CPU) || defined(I686_CPU)
 static void    set_i586_ctr_freq(u_int i586_freq, u_int i8254_freq);
@@ -388,7 +389,7 @@
         * multiplications and divisions to scale the count take a while).
         */
        prev_tick = getit();
-       n -= 20;
+       n = (n <= delay_offset) ? 1 : (n - delay_offset);
        /*
         * Calculate (n * (timer_freq / 1e6)) without using floating point
         * and without any avoidable overflows.
@@ -565,6 +566,32 @@
                printf("i586 clock: %u Hz, ", i586_ctr_freq);
        }
 #endif
+
+       switch(cpu_class) {
+#if defined(I386_CPU)
+       case CPUCLASS_386:
+               delay_offset = 20;
+               break;
+#endif
+#if defined(I486_CPU)
+       case CPUCLASS_486:
+               delay_offset = 9;
+               break;
+#endif
+#if defined(I586_CPU)
+       case CPUCLASS_586:
+               delay_offset = 5;
+               break;
+#endif
+#if defined(I686_CPU)
+       case CPUCLASS_686:
+               delay_offset = 2;
+               break;
+#endif
+        default:
+               delay_offset = 0;
+               break;
+        }
 
        printf("i8254 clock: %u Hz\n", tot_count);
        return (tot_count);
===============================================

	Patch for FreeBSD 2.1.5-RELEASE /sys/i386/isa/clock.c

===============================================
--- clock.c.dist        Tue Apr 23 04:48:26 1996
+++ clock.c     Tue Nov  5 01:21:06 1996
@@ -52,6 +52,7 @@
 #include <sys/time.h>
 #include <sys/kernel.h>
 #include <machine/clock.h>
+#include <machine/cpu.h>
 #include <machine/frame.h>
 #include <i386/isa/icu.h>
 #include <i386/isa/isa.h>
@@ -121,6 +122,7 @@
 static         char    timer0_state = 0;
 static char    timer2_state = 0;
 static         void    (*timer_func) __P((struct clockframe *frame)) = hardcloc
k;
+static u_int   delay_offset = 20;      /* 20usec for i386 */
 
 #if 0
 void
@@ -304,6 +306,32 @@
         * XX lose if the clock rate is not nearly a multiple of 1000000.
         */
        pentium_mhz = ((count - last_count) + 500000) / 1000000;
+
+       switch(cpu_class) {
+#if defined(I386_CPU)
+       case CPUCLASS_386:
+               delay_offset = 20;
+               break;
+#endif
+#if defined(I486_CPU)
+       case CPUCLASS_486:
+               delay_offset = 9;
+               break;
+#endif
+#if defined(I586_CPU)
+       case CPUCLASS_586:
+               delay_offset = 5;
+               break;
+#endif
+#if defined(I686_CPU)
+       case CPUCLASS_686:
+               delay_offset = 2;
+               break;
+#endif
+        default:
+               delay_offset = 0;
+               break;
+        }
 }
 #endif
 
@@ -339,7 +367,7 @@
         * multiplications and divisions to scale the count take a while).
         */
        prev_tick = getit();
-       n -= 20;
+       n = (n <= delay_offset) ? 1 : (n - delay_offset);
        /*
         * Calculate (n * (TIMER_FREQ / 1e6)) without using floating point
         * and without any avoidable overflows.
===============================================

	

>Audit-Trail:
>Unformatted:
Takeshi OHASHI



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611050448.NAA11117>