From ohashi@mickey.ai.kyutech.ac.jp  Mon Nov  4 20:54:47 1996
Received: from at_ohasi.mickey.ai.kyutech.ac.jp (at_ohasi.mickey.ai.kyutech.ac.jp [131.206.21.80])
          by freefall.freebsd.org (8.7.5/8.7.3) with ESMTP id UAA02802
          for <FreeBSD-gnats-submit@freebsd.org>; Mon, 4 Nov 1996 20:54:44 -0800 (PST)
Received: (from ohashi@localhost) by at_ohasi.mickey.ai.kyutech.ac.jp (8.7.5/3.4Wbeta6) id NAA11117; Tue, 5 Nov 1996 13:48:36 +0900 (JST)
Message-Id: <199611050448.NAA11117@at_ohasi.mickey.ai.kyutech.ac.jp>
Date: Tue, 5 Nov 1996 13:48:36 +0900 (JST)
From: ohashi@mickey.ai.kyutech.ac.jp
Reply-To: ohashi@mickey.ai.kyutech.ac.jp
To: FreeBSD-gnats-submit@freebsd.org
Subject: DELAY() in /sys/i386/isa/clock.c 
X-Send-Pr-Version: 3.2

>Number:         1959
>Category:       i386
>Synopsis:       DELAY() won't work for fast CPUs
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:
>Keywords:
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Nov  4 21:00:01 PST 1996
>Closed-Date:    Thu Sep 18 07:45:39 PDT 1997
>Last-Modified:  Thu Sep 18 07:46:07 PDT 1997
>Originator:     Takeshi Ohashi
>Release:        FreeBSD 2.2-961014-SNAP, current and 2.1.5-R
>Organization:
Dept. of AI, Kyushu Inst. of Tech., Iizuka, JAPAN.
>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.
===============================================

	

>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: phk 
State-Changed-When: Thu Sep 18 07:45:39 PDT 1997 
State-Changed-Why:  

worked around in other ways. 
>Unformatted:
Takeshi OHASHI
