Subject: Re: port-mips/26959: mips mc_cpuspeed() returns wrong value on gcc3
To: None <tsutsui@ceres.dti.ne.jp>
From: Simon Burge <simonb@wasabisystems.com>
List: netbsd-bugs
Date: 09/17/2004 12:17:35
tsutsui@ceres.dti.ne.jp wrote:

> >Number:         26959
> >Category:       port-mips
> >Synopsis:       mips mc_cpuspeed() returns wrong value on gcc3

Can you try the following patch?  I have no boxes turned on right now
that use mc_cpuspeed.  It compiles for pmax on -current (after I remove
graphics support - separate issue I need to file a PR about) and should
apply reasonably cleanly to the 2.0 branch as well.

Simon.
--
Simon Burge                            <simonb@wasabisystems.com>
NetBSD Support and Service:         http://www.wasabisystems.com/


Index: arch/mips/mips/mips_mcclock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mips_mcclock.c,v
retrieving revision 1.11
diff -d -p -u -r1.11 mips_mcclock.c
--- arch/mips/mips/mips_mcclock.c	5 Mar 2002 15:54:33 -0000	1.11
+++ arch/mips/mips/mips_mcclock.c	17 Sep 2004 02:11:51 -0000
@@ -146,7 +146,7 @@ mips_mcclock_tickloop(mcclock_addr, cloc
 	void *mcclock_addr;
 	int clockmask;
 {
-	int iters = 0;
+	int iters;
 	volatile int junk;
 	volatile struct mcclock_pad32_clockdatum *clk = mcclock_addr;
 
@@ -164,19 +164,12 @@ mips_mcclock_tickloop(mcclock_addr, cloc
 	junk++;	junk++;	junk++;	junk++;
 
 	/* Count loops until next tick-interrupt request occurs (4ms). */
-	if (MIPS_HAS_CLOCK) {
-		while ((mips_cp0_cause_read() & clockmask) == 0) {
-			__asm __volatile ("nop; nop; nop; nop");
-			iters++;
-		}
-	} else {
-		while ((mips_cp0_cause_read() & clockmask) == 0) {
-			__asm __volatile ("nop; nop;");
-			iters++;
-		}
-	}
+	if (MIPS_HAS_CLOCK)
+		iters = mips_mcclock_loop_with_clock(clockmask);
+	else
+		iters = mips_mcclock_loop_without_clock(clockmask);
 
-	/* Ack the  interrupt from the just-gone-off tick */
+	/* Ack the interrupt from the just-gone-off tick */
 	junk = clk[MC_REGC].datum;
 
 	return (iters);
Index: arch/mips/mips/mips_mcclock.h
===================================================================
RCS file: /cvsroot/src/sys/arch/mips/mips/mips_mcclock.h,v
retrieving revision 1.3
diff -d -p -u -r1.3 mips_mcclock.h
--- arch/mips/mips/mips_mcclock.h	5 Mar 2002 14:12:30 -0000	1.3
+++ arch/mips/mips/mips_mcclock.h	17 Sep 2004 02:11:51 -0000
@@ -40,10 +40,11 @@
  * counting iterations of an loop between successive ticks.
  */
 unsigned mc_cpuspeed(vaddr_t, int);
+int mips_mcclock_loop_with_clock(int);
+int mips_mcclock_loop_without_clock(int);
 
 /*
  * CPU speed in MHz, as estimated by mc_cpuspeed(). Read-only.
  */
 extern int cpu_mhz;
-
 #endif
Index: arch/mips/mips/mips_mcclock_loop.S
===================================================================
RCS file: arch/mips/mips/mips_mcclock_loop.S
diff -N arch/mips/mips/mips_mcclock_loop.S
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ arch/mips/mips/mips_mcclock_loop.S	17 Sep 2004 02:11:51 -0000
@@ -0,0 +1,42 @@
+/* $NetBSD$ */
+
+/* XXX copyright... */
+
+#include <mips/asm.h>
+#include <mips/cpuregs.h>
+
+/*
+ * These two functions are not profiled!
+ */
+
+LEAF_NOPROFILE(mips_mcclock_loop_with_clock)
+	move	t0,zero			# iters = 0;
+	j	2f
+	 nop
+1:	nop				# asm ("nop;nop;nop;nop");
+	nop
+	nop
+	nop
+	addu	s0,1			# iters++;
+2:	jal	mips_cp0_cause_read	# v0 = mips_cp0_cause_read();
+	 nop
+	and	t0,a0			# v0 &= clockmask;
+	beqz	t0,1b			# if zero then repeat
+	 move	 v0,t0			# return iters
+	j	ra
+END(mips_mcclock_loop_with_clock)
+
+LEAF_NOPROFILE(mips_mcclock_loop_without_clock)
+	move	t0,zero			# iters = 0;
+	j	2f
+	 nop
+1:	nop				# asm ("nop;nop");
+	nop
+	addu	s0,1			# iters++;
+2:	jal	mips_cp0_cause_read	# v0 = mips_cp0_cause_read();
+	 nop
+	and	t0,a0			# v0 &= clockmask;
+	beqz	t0,1b			# if zero then repeat
+	 move	 v0,t0			# return iters
+	j	ra
+END(mips_mcclock_loop_without_clock)
Index: arch/pmax/conf/files.pmax
===================================================================
RCS file: /cvsroot/src/sys/arch/pmax/conf/files.pmax,v
retrieving revision 1.107
diff -d -p -u -r1.107 files.pmax
--- arch/pmax/conf/files.pmax	13 Dec 2003 23:04:37 -0000	1.107
+++ arch/pmax/conf/files.pmax	17 Sep 2004 02:11:52 -0000
@@ -81,11 +81,12 @@ device	mcclock
 attach	mcclock at ioasic with mcclock_ioasic
 attach	mcclock at ibus with mcclock_ibus
 file	arch/pmax/pmax/clock.c
-file	dev/dec/mcclock.c		mcclock
-file	dev/dec/mcclock_pad32.c		mcclock
-file	arch/pmax/tc/mcclock_ioasic.c	mcclock_ioasic
-file	arch/pmax/ibus/mcclock_ibus.c	mcclock_ibus
-file	arch/mips/mips/mips_mcclock.c	mcclock # CPU speed via mcclock
+file	dev/dec/mcclock.c			mcclock
+file	dev/dec/mcclock_pad32.c			mcclock
+file	arch/pmax/tc/mcclock_ioasic.c		mcclock_ioasic
+file	arch/pmax/ibus/mcclock_ibus.c		mcclock_ibus
+file	arch/mips/mips/mips_mcclock.c		mcclock # CPU speed via mcclock
+file	arch/mips/mips/mips_mcclock_loop.S	mcclock # CPU speed via mcclock
 
 include "dev/scsipi/files.scsipi"