Date: Thu, 14 May 1998 01:42:46 -0400 (EDT) From: cjohnson@netgsi.com To: FreeBSD-gnats-submit@FreeBSD.ORG Subject: kern/6630: Fix for Cyrix I8254 bug Message-ID: <199805140542.BAA12770@neunacht.netgsi.com>
next in thread | raw e-mail | index | archive | help
>Number: 6630 >Category: kern >Synopsis: Fix for Cyrix I8254 bug >Confidential: no >Severity: critical >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Wed May 13 22:40:01 PDT 1998 >Last-Modified: >Originator: Christopher T. Johnson >Organization: NetGSi, Inc >Release: FreeBSD 3.0-CURRENT i386 >Environment: Any Cyrix GX(m) cpu using the 5510 or 5520 support chipset. >Description: The Cyrix 5510 and 5520 chipset has a serious flaw in the I8254 programmable interupt timer. When the I8254 PIT is sent a "LATCH" command, it is suppose to copy the current counter into a 16 bit latch counter as an atomic action. Instead, either the latch fails to take place, or there is no latch register. When the standard clock calibration loops run, the i8254 is miss tracked giving bogus timings. In addition, the TSC is callibrated against the i8254 using the same busted logic giving such wonderful readings as a Pentium MMX running at 180 Mhz being detected as a 9Mhz Pentium. (poor english sorry) In addition to these simple things going astray, the callout() routines die because they are based on the calibrations of the TSC or I8254. The biggest problem is that the DELAY() routine dies. This causes things like APM to panic as well as many other kernel drivers that need sub second timing. >How-To-Repeat: find a Compaq Presario 1215 and boot FreeBSD. Type date a few times and see what the time warp is like. >Fix: Index: LINT =================================================================== RCS file: /usr/cvsroot/src/sys/i386/conf/LINT,v retrieving revision 1.429 diff -u -r1.429 LINT --- LINT 1998/04/29 17:09:41 1.429 +++ LINT 1998/05/14 05:09:57 @@ -136,6 +136,11 @@ # of Cyrix 6x86 and 6x86MX CPUs. If this option is not set and # FAILESAFE is defined, NO_LOCK bit of CCR1 is cleared. (NOTE 3) # +# CPU_CYRIX_NO_I8254_LATCH enables a patch to deal with the I8254 +# programable interupt timer failing to latch in a number of cyrix +# chipsets. This can be seen by run away Time of Day clocks and +# panics when trying to do sub second time keeping. +# # CPU_DISABLE_5X86_LSSER disables load store serialize (i.e. enables # reorder). This option should not be used if you use memory mapped # I/O device(s). @@ -196,6 +201,7 @@ options "CPU_SUSP_HLT" options "CYRIX_CACHE_WORKS" options "CYRIX_CACHE_REALLY_WORKS" +options "CPU_CYRIX_NO_I8254_LATCH" #options "NO_F00F_HACK" # Index: options.i386 =================================================================== RCS file: /usr/cvsroot/src/sys/i386/conf/options.i386,v retrieving revision 1.77 diff -u -r1.77 options.i386 --- options.i386 1998/04/18 04:58:01 1.77 +++ options.i386 1998/05/14 05:12:18 @@ -68,6 +68,7 @@ CPU_UPGRADE_HW_CACHE opt_cpu.h CYRIX_CACHE_WORKS opt_cpu.h CYRIX_CACHE_REALLY_WORKS opt_cpu.h +CPU_CYRIX_NO_I8254_LATCH opt_clock.h # The CPU type affects the endian conversion functions all over the kernel. I386_CPU opt_global.h Index: clock.c =================================================================== RCS file: /usr/cvsroot/src/sys/i386/isa/clock.c,v retrieving revision 1.119 diff -u -r1.119 clock.c --- clock.c 1998/04/05 01:04:48 1.119 +++ clock.c 1998/05/14 05:20:02 @@ -402,7 +402,9 @@ { u_long ef; int high, low; - +#if CPU_CYRIX_NO_I8254_LATCH + int ret1, ret2; +#endif ef = read_eflags(); disable_intr(); @@ -411,10 +413,21 @@ low = inb(TIMER_CNTR0); high = inb(TIMER_CNTR0); +#if CPU_CYRIX_NO_I8254_LATCH + ret1 = (high << 8) | low; + outb(TIMER_MODE, TIMER_SEL0 | TIMER_LATCH); + low = inb(TIMER_CNTR0); + high= inb(TIMER_CNTR0); + ret2 = (high <<8) | low; +#endif CLOCK_UNLOCK(); write_eflags(ef); +#if CPU_CYRIX_NO_I8254_LATCH + return (ret1 > ret2 ? ret1 : ret2); +#else return ((high << 8) | low); +#fi } /* >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199805140542.BAA12770>