From owner-FreeBSD-users-jp@jp.freebsd.org  Tue Mar 14 22:19:17 2000
Received: (from daemon@localhost)
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) id WAA65449;
	Tue, 14 Mar 2000 22:19:17 +0900 (JST)
	(envelope-from owner-FreeBSD-users-jp@jp.FreeBSD.org)
Received: from tama5.ecl.ntt.co.jp (tama5.ecl.ntt.co.jp [129.60.39.102])
	by castle.jp.freebsd.org (8.9.3+3.2W/8.7.3) with ESMTP id WAA65444
	for <FreeBSD-users-jp@jp.freebsd.org>; Tue, 14 Mar 2000 22:19:16 +0900 (JST)
	(envelope-from kihara@isl.ntt.co.jp)
Received: from nttmail3.ecl.ntt.co.jp (nttmail3.ecl.ntt.co.jp [129.60.39.100])
	by tama5.ecl.ntt.co.jp (8.9.3+3.2W/3.7W/01/21/00) with ESMTP id WAA03046;
	Tue, 14 Mar 2000 22:19:15 +0900 (JST)
	(envelope-from kihara@isl.ntt.co.jp)
Received: from qlair.isl.ntt.co.jp
	by nttmail3.ecl.ntt.co.jp (8.9.3+3.2W/3.7W/01/18/00) with ESMTP id WAA23613;
	Tue, 14 Mar 2000 22:19:14 +0900 (JST)
	(envelope-from kihara@isl.ntt.co.jp)
Received: from qlair.isl.ntt.co.jp (kihara@localhost [127.0.0.1])
	by qlair.isl.ntt.co.jp (8.8.8/3.7W+isl1.3) with ESMTP id WAA21008;
	Tue, 14 Mar 2000 22:19:12 +0900 (JST)
	(envelope-from kihara@isl.ntt.co.jp)
Date: Tue, 14 Mar 2000 22:19:12 +0900
Message-ID: <14542.15440.25392.72159A@qlair.isl.ntt.co.jp>
From: Seiji Kihara <kihara@isl.ntt.co.jp>
To: kato@ganko.eps.nagoya-u.ac.jp
Cc: FreeBSD-users-jp@jp.freebsd.org, bsd-nomads@clave.gr.jp
In-Reply-To: In your message of "Tue, 14 Mar 2000 19:36:54 +0900"
	<20000314193654U.kato@gneiss.eps.nagoya-u.ac.jp>
References: <14541.7874.582119.72159A@qlair.isl.ntt.co.jp>
	<20000314193654U.kato@gneiss.eps.nagoya-u.ac.jp>
User-Agent: Wanderlust/1.0.3 (Notorious) SEMI/1.13.4 (Terai) FLIM/1.12.7
 (=?ISO-8859-4?Q?Y=FEzaki?=) MULE/2.3 (SUETSUMUHANA) (based on Emacs 19.34)
MIME-Version: 1.0 (generated by SEMI 1.13.4 - "Terai")
Content-Type: text/plain; charset=ISO-2022-JP
Reply-To: FreeBSD-users-jp@jp.freebsd.org
Precedence: list
X-Distribute: distribute version 2.1 (Alpha) patchlevel 24e+990727
X-Sequence: FreeBSD-users-jp 50520
Subject: [FreeBSD-users-jp 50520] Re: [bsd-nomads:13129] Re: MediaGX clock patch
Errors-To: owner-FreeBSD-users-jp@jp.freebsd.org
Sender: owner-FreeBSD-users-jp@jp.freebsd.org
X-Originator: kihara@isl.ntt.co.jp

$BLZ86(B@NTT$B$G$9!#(B

In article <20000314193654U.kato@gneiss.eps.nagoya-u.ac.jp>, 
	KATO Takenori <kato@ganko.eps.nagoya-u.ac.jp> writes:
> MediaGX$B$N8!=P$,IT40A4$G$O$J$$$G$7$g$&$+!%(B

$B$&!<$`!"3N$+$K!#$"$j$,$H$&$4$6$$$^$9!#Bg$7$?Bg$-$5$G$O(B
$B$J$$$N$G!"$$$?$@$$$?;XE&$r:N$jF~$l$?$b$N$r$D$1$F$*$-$^$9!#(B
$B$[$\<+L@$G$9$,!"F0$/$3$H$r3NG'$7$^$7$?!#(B

$B$J$*!"@h$N$b$N$O!"(B

http://home.jp.FreeBSD.ORG/cgi-bin/showmail/bsd-nomads/12160

$B$K=q$$$F$"$k!"(BNetBSD$B$J%Q%C%A(B(kern/8654)$B$r(BFreeBSD$BMQ$K>/$7(B
$B=q$-49$($?$@$1$G!"$b$H$b$H(Bcpu_vendor$B$N%A%'%C%/$O$7$F$^$;$s$7!"(B

http://cvsweb.netbsd.org/bsdweb.cgi/syssrc/sys/arch/i386/isa/clock.c?rev=1.63.2.1&content-type=text/x-cvsweb-markup

$B$"$?$j$r$_$F$b%A%'%C%/$O$7$F$J$$$s$G$9$1$I!"(BNetBSD$B$G$O(B
$B$3$NJU$j$I$&$J$C$F$k$s$G$7$g$&$M!#(B
-- 
$BLZ86(B $B@?;J(B
NTT$B%5!<%S%9%$%s%F%0%l!<%7%g%s4pHW8&5f=j(B($B2#?\2l(B)


--- /usr/src/sys/i386/isa/clock.c.orig	Sun Oct 31 15:04:52 1999
+++ /usr/src/sys/i386/isa/clock.c	Tue Mar 14 22:05:28 2000
@@ -101,6 +101,11 @@
 #endif
 #endif /* SMP */
 
+#ifndef NO_CHECK_CLOCK
+static void check_clock_bug __P((void));
+static __inline int getit_broken_latch __P((void));
+#endif /* NO_CHECK_CLOCK */
+
 /*
  * 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
  * can use a simple formula for leap years.
@@ -196,6 +201,88 @@
 SYSCTL_OPAQUE(_debug, OID_AUTO, i8254_timecounter, CTLFLAG_RD, 
 	&i8254_timecounter, sizeof(i8254_timecounter), "S,timecounter", "");
 
+#ifndef NO_CHECK_CLOCK
+static int clock_broken_latch = 0;
+
+/*
+ * check i8254 latch routine:
+ *	set the variable 'clock_broken_latch'
+ *	XXX check only cpu_id
+ */
+static void
+check_clock_bug()
+{
+	if (strcmp(cpu_vendor, "CyrixInstead") == 0) {
+		switch (cpu_id & 0xff0) {
+		case 0x440:     /* Cyrix MediaGX */
+		case 0x540:     /* GXm */
+			clock_broken_latch = 1;
+			break;
+		}
+	}
+}
+
+int
+getit_broken_latch()
+{
+	u_long ef;
+	int v1, v2, v3;
+	int w1, w2, w3;
+
+	/* Don't want someone screwing with the counter
+	   while we're here. */
+	ef = read_eflags();
+	disable_intr();
+
+	v1 = inb(TIMER_CNTR0);
+	v1 |= inb(TIMER_CNTR0) << 8;
+	v2 = inb(TIMER_CNTR0);
+	v2 |= inb(TIMER_CNTR0) << 8;
+	v3 = inb(TIMER_CNTR0);
+	v3 |= inb(TIMER_CNTR0) << 8;
+
+	write_eflags(ef);
+
+	if (v1 >= v2 && v2 >= v3 && v1 - v3 < 0x200)
+		return (v2);
+
+#define _swap_val(a, b) do { \
+	int c = a; \
+	a = b; \
+	b = c; \
+} while (0)
+
+	/*
+	 * sort v1 v2 v3
+	 */
+	if (v1 < v2)
+		_swap_val(v1, v2);
+	if (v2 < v3)
+		_swap_val(v2, v3);
+	if (v1 < v2)
+		_swap_val(v1, v2);
+
+	/*
+	 * compute the middle value
+	 */
+
+	if (v1 - v3 < 0x200)
+		return (v2);
+
+	w1 = v2 - v3;
+	w2 = v3 - v1 + timer0_max_count;
+	w3 = v1 - v2;
+	if (w1 >= w2) {
+		if (w1 >= w3)
+			return (v1);
+	} else {
+		if (w2 >= w3)
+			return (v2);
+	}
+	return (v3);
+}
+#endif /* NO_CHECK_CLOCK */
+
 static void
 clkintr(struct clockframe frame)
 {
@@ -418,6 +505,11 @@
 	u_long ef;
 	int high, low;
 
+#ifndef NO_CHECK_CLOCK
+	if (clock_broken_latch)
+		return (getit_broken_latch());
+#endif /* NO_CHECK_CLOCK */
+
 	ef = read_eflags();
 	disable_intr();
 
@@ -732,6 +824,10 @@
 startrtclock()
 {
 	u_int delta, freq;
+
+#ifndef NO_CHECK_CLOCK
+	check_clock_bug();
+#endif /* NO_CHECK_CLOCK */
 
 	if (cpu_feature & CPUID_TSC)
 		tsc_present = 1;
