* [PATCH] NSC Geode Companion chip workaround
@ 2002-02-06 2:20 Hiroshi MIURA
2002-02-06 14:06 ` Maciej W. Rozycki
2002-02-06 14:08 ` Alan Cox
0 siblings, 2 replies; 5+ messages in thread
From: Hiroshi MIURA @ 2002-02-06 2:20 UTC (permalink / raw)
To: linux-kernel
Cyrix MediaGX/GXm or NSC Geode have PIT bug not TSC bug.
but in linux kernel, if CPU is Cyrix, then TSC flag is disabled.
This is not correct way, I think.
A patch atached below is originally from NetBSD kernel code.
In FreeBSD bug tracking system, this was discussed.
http://www.freebsd.org/cgi/query-pr.cgi?pr=6630
Here is NetBSD patch.
http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=8654
in this patch, this code is activate only if you defines CONFIG_CS5520.
I've tryed several month with this patch, It seems good for me.
trial machine: Casio CASSIOPEIA FIVA 101 and Fiva 103.
MediaGX 200MHz and NSC Geode 300MHz.
diff -ur kernel-source-2.4.7/arch/i386/kernel/setup.c linux/arch/i386/kernel/setup.c
--- kernel-source-2.4.7/arch/i386/kernel/setup.c Thu Jul 12 01:31:44 2001
+++ linux/arch/i386/kernel/setup.c Fri Aug 10 21:12:06 2001
@@ -1425,14 +1425,18 @@
/* GXm supports extended cpuid levels 'ala' AMD */
if (c->cpuid_level == 2) {
get_model_name(c); /* get CPU marketing name */
+#ifndef CONFIG_CS5520
clear_bit(X86_FEATURE_TSC, c->x86_capability);
+#endif
return;
}
else { /* MediaGX */
Cx86_cb[2] = (dir0_lsn & 1) ? '3' : '4';
p = Cx86_cb+2;
c->x86_model = (dir1 & 0x20) ? 1 : 2;
+#ifndef CONFIG_CS5520
clear_bit(X86_FEATURE_TSC, &c->x86_capability);
+#endif
}
break;
diff -ur kernel-source-2.4.7/arch/i386/kernel/time.c linux/arch/i386/kernel/time.c
--- kernel-source-2.4.7/arch/i386/kernel/time.c Sat Dec 30 07:07:57 2000
+++ linux/arch/i386/kernel/time.c Fri Aug 10 21:04:26 2001
@@ -28,6 +28,9 @@
* 1998-12-24 Copyright (C) 1998 Andrea Arcangeli
* Fixed a xtime SMP race (we need the xtime_lock rw spinlock to
* serialize accesses to xtime/lost_ticks).
+ * 2001-02-20 Hiroshi Miura <miura@da-cha.org>
+ * Work around for Cyrix/IBM/NSC MediaGX/GXm, NSC Geode southbridge
+ * PIT bug. (NSC Cx5510/5520)
*/
#include <linux/errno.h>
@@ -459,6 +462,10 @@
static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int count;
+#ifdef CONFIG_CS5520
+ int count1, count2, count3;
+ int n1, n2, n3;
+#endif
/*
* Here we are in the timer irq handler. We just have irqs locally
@@ -487,6 +494,7 @@
rdtscl(last_tsc_low);
+#ifndef CONFIG_CS5520
spin_lock(&i8253_lock);
outb_p(0x00, 0x43); /* latch the count ASAP */
@@ -499,6 +507,59 @@
}
do_timer_interrupt(irq, NULL, regs);
+#else
+ spin_lock(&i8253_lock);
+ outb_p(0x00, 0x43); /* latch the count ASAP */
+/* this codes comes from FreeBSD */
+ count1 = inb_p(0x40);
+ count1 |= inb(0x40) << 8;
+ count2 = inb_p(0x40);
+ count2 = inb(0x40) << 8;
+ count3 = inb_p(0x40);
+ count3 = inb(0x40) << 8;
+ spin_unlock(&i8253_lock);
+
+ if (count1 >= count2 && count2 >= count3 && count1 - count2 < 0x200)
+ count = count2;
+ else {
+
+#define _swap_val(a, b) do { \
+ int c = a;\
+ a = b; \
+ b = c; \
+} while(0)
+ /* sort values */
+ if (count1 < count2)
+ _swap_val(count1, count2);
+ if (count2 < count3)
+ _swap_val(count2, count3);
+ if (count1 < count2)
+ _swap_val(count1, count2);
+
+ /* compare the middle value */
+ if (count1 - count3 < 0x200)
+ count = count2;
+ else
+ {
+ n1 = count2 - count3;
+ n2 = count3 - count1 + LATCH;
+ n3 = count1 - count2;
+ count = count3;
+ if (n1 >= n2) {
+ if (n1 >= n3)
+ count = count1;
+ } else {
+ if (n2 >= n3)
+ count = count2;
+ }
+ }
+ }
+ count = ((LATCH-1) - count) * TICK_SIZE;
+ delay_at_last_interrupt = (count + LATCH/2) / LATCH;
+ }
+
+ do_timer_interrupt(irq, NULL, regs);
+#endif
write_unlock(&xtime_lock);
@@ -659,6 +720,9 @@
if (cpu_has_tsc) {
unsigned long tsc_quotient = calibrate_tsc();
+#ifdef CONFIG_CS5520
+ if (!tsc_quotient) tsc_quotient = calibrate_tsc();
+#endif
if (tsc_quotient) {
fast_gettimeoffset_quotient = tsc_quotient;
use_tsc = 1;
Hiroshi Miura --- miura@da-cha.org http://www.da-cha.org/
CCNA, Oracle Silver Master, Network Specialist(JITEC)
My interest: http://www.cis.com.tw/Product/WS-U50R.htm
^ permalink raw reply [flat|nested] 5+ messages in thread* Re: [PATCH] NSC Geode Companion chip workaround 2002-02-06 2:20 [PATCH] NSC Geode Companion chip workaround Hiroshi MIURA @ 2002-02-06 14:06 ` Maciej W. Rozycki 2002-02-09 4:14 ` Hiroshi MIURA 2002-02-06 14:08 ` Alan Cox 1 sibling, 1 reply; 5+ messages in thread From: Maciej W. Rozycki @ 2002-02-06 14:06 UTC (permalink / raw) To: Hiroshi MIURA; +Cc: linux-kernel On Wed, 6 Feb 2002, Hiroshi MIURA wrote: > I've tryed several month with this patch, It seems good for me. > trial machine: Casio CASSIOPEIA FIVA 101 and Fiva 103. > MediaGX 200MHz and NSC Geode 300MHz. Does the chip fail with the readback 8254 command as well? If not, it would be a less intrusive change. -- + Maciej W. Rozycki, Technical University of Gdansk, Poland + +--------------------------------------------------------------+ + e-mail: macro@ds2.pg.gda.pl, PGP key available + ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] NSC Geode Companion chip workaround 2002-02-06 14:06 ` Maciej W. Rozycki @ 2002-02-09 4:14 ` Hiroshi MIURA 2002-02-10 4:24 ` Hiroshi MIURA 0 siblings, 1 reply; 5+ messages in thread From: Hiroshi MIURA @ 2002-02-09 4:14 UTC (permalink / raw) To: macro; +Cc: miura, linux-kernel In message "Re: [PATCH] NSC Geode Companion chip workaround" on 02/02/06, "Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes: > On Wed, 6 Feb 2002, Hiroshi MIURA wrote: > > > I've tryed several month with this patch, It seems good for me. > > trial machine: Casio CASSIOPEIA FIVA 101 and Fiva 103. > > MediaGX 200MHz and NSC Geode 300MHz. > > Does the chip fail with the readback 8254 command as well? If not, it > would be a less intrusive change. OK, I want to try 8254 readback command. I will report after weekend. Hiroshi Miura --- miura@da-cha.org http://www.da-cha.org/ CCNA, Oracle Silver Master, Network Specialist(JITEC) My interest: http://www.cis.com.tw/Product/WS-U50R.htm ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] NSC Geode Companion chip workaround 2002-02-09 4:14 ` Hiroshi MIURA @ 2002-02-10 4:24 ` Hiroshi MIURA 0 siblings, 0 replies; 5+ messages in thread From: Hiroshi MIURA @ 2002-02-10 4:24 UTC (permalink / raw) To: macro, Alan Cox; +Cc: linux-kernel, Ian S. Nelson the MediaGX/Geode companion chip CS5520 fails the latch with the read-back 8254 command as well as 8253 latch command. test program: <list1> kernel configuration: CONFIG_M586 kernel code with read-back command: <list2> test results: 1. kernel 2.4.16 (without any fix, TSC disable) fails iteration: 500-1,500 value of '(now - prev)' when fail: -100 - -200 micro sec 2. kernel 2.4.16 (with my patch) fails iteration: 35,000-70,000 error value: -10 - -20 micro sec 3. kernel 2.4.16 (with read-back command, TSC enable) fails iteration: 5,000-7,000 error value: about -20,000 micro sec 4. kernel 2.4.16 (without any fix but TSC enable) fails iteration: 5,000-7,000 error value: about -20,000 micro sec these means 'read-back command' fails as well as 'latch command'. and my patch is better than others. In message "Re: [PATCH] NSC Geode Companion chip workaround" on 02/02/09, Hiroshi MIURA <miura@da-cha.org> writes: > In message "Re: [PATCH] NSC Geode Companion chip workaround" > on 02/02/06, "Maciej W. Rozycki" <macro@ds2.pg.gda.pl> writes: > > On Wed, 6 Feb 2002, Hiroshi MIURA wrote: > > > > > I've tryed several month with this patch, It seems good for me. > > > trial machine: Casio CASSIOPEIA FIVA 101 and Fiva 103. > > > MediaGX 200MHz and NSC Geode 300MHz. > > > > Does the chip fail with the readback 8254 command as well? If not, it > > would be a less intrusive change. > > OK, I want to try 8254 readback command. I will report after weekend. <list1> ---------------- #include <sys/time.h> #include <time.h> #include <assert.h> int main(void) { struct timeval tv[2]; struct timeval *now, *prev; int iterations = 0; now = &tv[0]; prev = &tv[1]; gettimeofday(prev, NULL); for (;;) { struct timeval *tmp; gettimeofday(now, NULL); if (!((now->tv_sec > prev->tv_sec) || (now->tv_sec == prev->tv_sec && now->tv_usec >= prev->tv_usec))) printf ("Err: prev: %d, %d, now: %d, %d, iter: %d\n", prev->tv_sec, prev->tv_usec, now->tv_sec, now->tv_usec, iterations); tmp = prev; prev = now; now = tmp; iterations++; } return iterations; } ---------------- <list2> ---------------- --- /usr/src/linux/arch/i386/kernel/time.c.multiread Sat Feb 9 22:24:51 2002 +++ /usr/src/linux/arch/i386/kernel/time.c.readback Sat Feb 9 20:36:41 2002 @@ -474,6 +474,7 @@ #ifdef CONFIG_CS5520 int count1, count2, count3; int n1, n2, n3; + int i, cont, status; #endif /* @@ -517,6 +518,26 @@ do_timer_interrupt(irq, NULL, regs); #else +#if 1 + for (i = 0, cont = 1; cont && ( i < 3 ); i++) { + spin_lock(&i8253_lock); + outb_p(0xf2, 0x43); /* read-back command */ + status = inb_p(0x40); + count = inb_p(0x40); + count |= inb_p(0x40) << 8; + spin_unlock(&i8253_lock); + + cont = status & (1 << 6); + } + + if (cont) + printk("PIT latch fails 3 times.\n"); + + count = ((LATCH-1) - count) * TICK_SIZE; + delay_at_last_interrupt = (count + LATCH/2) / LATCH; + } + do_timer_interrupt(irq, NULL, regs); +#else spin_lock(&i8253_lock); outb_p(0x00, 0x43); /* latch the count ASAP */ /* this codes comes from FreeBSD */ @@ -568,6 +589,7 @@ } do_timer_interrupt(irq, NULL, regs); +#endif #endif write_unlock(&xtime_lock); -- Hiroshi Miura --- miura@da-cha.org http://www.da-cha.org/ CCNA, Oracle Silver Master, Network Specialist(JITEC) My interest: http://www.cis.com.tw/Product/WS-U50R.htm ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] NSC Geode Companion chip workaround 2002-02-06 2:20 [PATCH] NSC Geode Companion chip workaround Hiroshi MIURA 2002-02-06 14:06 ` Maciej W. Rozycki @ 2002-02-06 14:08 ` Alan Cox 1 sibling, 0 replies; 5+ messages in thread From: Alan Cox @ 2002-02-06 14:08 UTC (permalink / raw) To: Hiroshi MIURA; +Cc: linux-kernel > in this patch, this code is activate only if you defines CONFIG_CS5520. > I've tryed several month with this patch, It seems good for me. > trial machine: Casio CASSIOPEIA FIVA 101 and Fiva 103. > MediaGX 200MHz and NSC Geode 300MHz. Interesting. That would explain a lot. Unfortunately when I first reported that problem and disabled the TSC Cyrix actually refused to believe the problem existed. With the below it looks fixable (The CONFIG_CS5520 we can replace I think with a check for the PCI device) ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2002-02-10 3:13 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-02-06 2:20 [PATCH] NSC Geode Companion chip workaround Hiroshi MIURA 2002-02-06 14:06 ` Maciej W. Rozycki 2002-02-09 4:14 ` Hiroshi MIURA 2002-02-10 4:24 ` Hiroshi MIURA 2002-02-06 14:08 ` Alan Cox
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®