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>
