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>