[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: PowerPC portingのtimebase処理について



埜中です。

On Tue, Nov 15, 2005 at 06:04:20PM +0900, SAITOH Masanobu wrote:

>  > いまのコードがどうなってるのか知りませんが、少なくとも
>  > hardclock() を呼ぶ時 (つまり time が変化する時) だけ lasttb
>  > を更新するようになっていないと microtime() が正確でなくなる
>  > はずです。
>  >
>  > (…が、macppcのをいじった本人の言うことだから意見の数には
>  > なりません:-)
>
> 手元のコードを確認したら、その部分は macppc と同様に修正されてました
> (commit メッセージは macppc に合わせましたとなっていた :-) )。
>
> 誰か(含む tsubai さん) powerpc 系をまとめて直しておいて頂けるとみんなが
> 嬉しいかと…(僕は -current 使ってないし -current の状況を知らないので
> (decr_intr() 部分は見ればわかるけど))。

とりあえず修正してみました。
おかしい所が無い様であれば、このまま commit します。

--
Kimihiro Nonaka (埜中公博)
email: aw9k-nnk@asahi-net.or.jp, nonaka@netbsd.org
Index: bebox/bebox/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/bebox/bebox/clock.c,v
retrieving revision 1.14
diff -u -r1.14 clock.c
--- bebox/bebox/clock.c	10 Jun 2005 15:42:41 -0000	1.14
+++ bebox/bebox/clock.c	20 Nov 2005 11:53:32 -0000
@@ -71,17 +71,11 @@
 	 * Based on the actual time delay since the last decrementer reload,
 	 * we arrange for earlier interrupt next time.
 	 */
-	asm ("mftb %0; mfdec %1" : "=r"(tb), "=r"(ticks));
+	asm ("mfdec %0" : "=r"(ticks));
 	for (nticks = 0; ticks < 0; nticks++)
 		ticks += ticks_per_intr;
 	asm volatile ("mtdec %0" :: "r"(ticks));
 
-	/*
-	 * lasttb is used during microtime. Set it to the virtual
-	 * start of this tick interval.
-	 */
-	lasttb = tb + ticks - ticks_per_intr;
-
 	intrcnt[CNT_CLOCK]++;
 
 	pri = splclock();
@@ -92,6 +86,13 @@
 		tickspending = 0;
 
 		/*
+		 * lasttb is used during microtime. Set it to the virtual
+		 * start of this tick interval.
+		 */
+		asm ("mftb %0" : "=r"(tb));
+		lasttb = tb + ticks - ticks_per_intr;
+
+		/*
 		 * Reenable interrupts
 		 */
 		asm volatile ("mfmsr %0; ori %0, %0, %1; mtmsr %0"
Index: evbppc/ev64260/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/ev64260/clock.c,v
retrieving revision 1.6
diff -u -r1.6 clock.c
--- evbppc/ev64260/clock.c	3 Jun 2005 11:17:42 -0000	1.6
+++ evbppc/ev64260/clock.c	20 Nov 2005 11:53:32 -0000
@@ -249,18 +249,11 @@
 	 * Based on the actual time delay since the last decrementer reload,
 	 * we arrange for earlier interrupt next time.
 	 */
-	tb = mftb();
 	__asm __volatile ("mfdec %0" : "=r"(decrtick));
 	for (nticks = 0; decrtick < 0; nticks++)
 		decrtick += ticks_per_intr;
 	__asm __volatile ("mtdec %0" :: "r"(decrtick));
 
-	/*
-	 * lasttb is used during microtime. Set it to the virtual
-	 * start of this tick interval.
-	 */
-	ci->ci_lasttb = tb + (decrtick - ticks_per_intr);
-
 	uvmexp.intrs++;
 	curcpu()->ci_ev_clock.ev_count++;
 
@@ -283,6 +276,13 @@
 		nticks += ci->ci_tickspending;
 		ci->ci_tickspending = 0;
 
+		/*
+		 * lasttb is used during microtime. Set it to the virtual
+		 * start of this tick interval.
+		 */
+		tb = mftb();
+		ci->ci_lasttb = tb + (decrtick - ticks_per_intr);
+
 		oipl = ci->ci_cpl;
 		ci->ci_cpl = IPL_CLOCK;
 		SPL_STATS_LOG(IPL_CLOCK, 0);
Index: ibmnws/ibmnws/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ibmnws/ibmnws/clock.c,v
retrieving revision 1.2
diff -u -r1.2 clock.c
--- ibmnws/ibmnws/clock.c	3 Jun 2005 20:15:59 -0000	1.2
+++ ibmnws/ibmnws/clock.c	20 Nov 2005 11:53:32 -0000
@@ -275,17 +275,11 @@
 	 * Based on the actual time delay since the last decrementer reload,
 	 * we arrange for earlier interrupt next time.
 	 */
-	asm ("mftb %0; mfdec %1" : "=r"(tb), "=r"(count));
+	asm ("mfdec %0" : "=r"(count));
 	for (nticks = 0; count < 0; nticks++)
 		count += ticks_per_intr;
 	asm volatile ("mtdec %0" :: "r"(count));
 
-	/*
-	 * lasttb is used during microtime. Set it to the virtual
-	 * start of this tick interval.
-	 */
-	lasttb = tb + count - ticks_per_intr;
-
 	intrcnt[CNT_CLOCK]++;
 
 	pri = splclock();
@@ -296,6 +290,13 @@
 		tickspending = 0;
 
 		/*
+		 * lasttb is used during microtime. Set it to the virtual
+		 * start of this tick interval.
+		 */
+		asm ("mftb %0" : "=r"(tb));
+		lasttb = tb + count - ticks_per_intr;
+
+		/*
 		 * Reenable interrupts
 		 */
 		asm volatile ("mfmsr %0; ori %0, %0, %1; mtmsr %0"
Index: mvmeppc/mvmeppc/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mvmeppc/mvmeppc/clock.c,v
retrieving revision 1.9
diff -u -r1.9 clock.c
--- mvmeppc/mvmeppc/clock.c	4 Jun 2005 20:14:24 -0000	1.9
+++ mvmeppc/mvmeppc/clock.c	20 Nov 2005 11:53:32 -0000
@@ -76,17 +76,11 @@
 	 * Based on the actual time delay since the last decrementer reload,
 	 * we arrange for earlier interrupt next time.
 	 */
-	asm ("mftb %0; mfdec %1" : "=r"(tb), "=r"(decrtick));
+	asm ("mfdec %0" : "=r"(decrtick));
 	for (nticks = 0; decrtick < 0; nticks++)
 		decrtick += ticks_per_intr;
 	asm volatile ("mtdec %0" :: "r"(decrtick));
 
-	/*
-	 * lasttb is used during microtime. Set it to the virtual
-	 * start of this tick interval.
-	 */
-	lasttb = tb + decrtick - ticks_per_intr;
-
 	intrcnt[CNT_CLOCK]++;
 
 	pri = splclock();
@@ -97,6 +91,13 @@
 		tickspending = 0;
 
 		/*
+		 * lasttb is used during microtime. Set it to the virtual
+		 * start of this tick interval.
+		 */
+		asm ("mftb %0" : "=r"(tb));
+		lasttb = tb + decrtick - ticks_per_intr;
+
+		/*
 		 * Reenable interrupts
 		 */
 		asm volatile ("mfmsr %0; ori %0, %0, %1; mtmsr %0"
Index: powerpc/ibm4xx/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/ibm4xx/clock.c,v
retrieving revision 1.12
diff -u -r1.12 clock.c
--- powerpc/ibm4xx/clock.c	3 Jun 2005 11:54:48 -0000	1.12
+++ powerpc/ibm4xx/clock.c	20 Nov 2005 11:53:32 -0000
@@ -50,7 +50,7 @@
 static u_long ticks_per_sec;
 static u_long ns_per_tick;
 static long ticks_per_intr;
-static volatile u_long lasttb;
+static volatile u_long lasttb, lasttb2;
 static u_long ticksmissed;
 static volatile int tickspending;
 
@@ -93,14 +93,11 @@
 
 	tbtick = mftbl();
 	mtspr(SPR_TSR, TSR_PIS);	/* Clear TSR[PIS] */
-	/*
-	 * lasttb is used during microtime. Set it to the virtual
-	 * start of this tick interval.
-	 */
-	xticks = tbtick - lasttb;	/* Number of TLB cycles since last exception */
+
+	xticks = tbtick - lasttb2;	/* Number of TLB cycles since last exception */
 	for (nticks = 0; xticks > ticks_per_intr; nticks++)
 		xticks -= ticks_per_intr;
-	lasttb = tbtick - xticks;
+	lasttb2 = tbtick - xticks;
 
 	intrcnt[CNT_CLOCK]++;
 	pri = splclock();
@@ -112,6 +109,12 @@
 		tickspending = 0;
 
 		/*
+		 * lasttb is used during microtime. Set it to the virtual
+		 * start of this tick interval.
+		 */
+		lasttb = lasttb2;
+
+		/*
 		 * Reenable interrupts
 		 */
 		asm volatile ("wrteei 1");
@@ -136,7 +139,7 @@
 	ticks_per_intr = ticks_per_sec / hz;
 	stathz = profhz = ticks_per_sec / (1 << PERIOD_POWER);
 	printf("Setting PIT to %ld/%d = %ld\n", ticks_per_sec, hz, ticks_per_intr);
-	lasttb = mftbl();
+	lasttb2 = lasttb = mftbl();
 	mtspr(SPR_PIT, ticks_per_intr);
 	/* Enable PIT & FIT(2^17c = 0.655ms) interrupts and auto-reload */
 	mtspr(SPR_TCR, TCR_PIE | TCR_ARE | TCR_FIE | TCR_PERIOD);
Index: prep/prep/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/prep/prep/clock.c,v
retrieving revision 1.11
diff -u -r1.11 clock.c
--- prep/prep/clock.c	5 Jun 2005 17:56:31 -0000	1.11
+++ prep/prep/clock.c	20 Nov 2005 11:53:32 -0000
@@ -40,6 +40,8 @@
 #include <sys/systm.h>
 #include <sys/device.h>
 
+#include <uvm/uvm_extern.h>
+
 #include <dev/clock_subr.h>
 
 #include <powerpc/spr.h>
@@ -48,9 +50,6 @@
 
 void decr_intr __P((struct clockframe *));
 
-/*
- * Initially we assume a processor with a bus frequency of 12.5 MHz.
- */
 u_long ticks_per_sec;
 u_long ns_per_tick;
 static long ticks_per_intr;
@@ -188,37 +187,38 @@
 	 * Based on the actual time delay since the last decrementer reload,
 	 * we arrange for earlier interrupt next time.
 	 */
-	if ((mfpvr() >> 16) == MPC601) {
-		asm volatile ("mfspr %0,%1" : "=r"(tb) : "n"(SPR_RTCL_R));
-	} else {
-		asm volatile ("mftb %0" : "=r"(tb));
-	}
 	asm ("mfdec %0" : "=r"(ticks));
 	for (nticks = 0; ticks < 0; nticks++)
 		ticks += ticks_per_intr;
 	asm volatile ("mtdec %0" :: "r"(ticks));
 
-	/*
-	 * lasttb is used during microtime. Set it to the virtual
-	 * start of this tick interval.
-	 */
-	lasttb = tb + ticks - ticks_per_intr;
-
+	uvmexp.intrs++;
 	intrcnt[CNT_CLOCK]++;
 
 	pri = splclock();
-	if (pri & SPL_CLOCK)
+	if (pri & SPL_CLOCK) {
 		tickspending += nticks;
-	else {
+	} else {
 		nticks += tickspending;
 		tickspending = 0;
 
 		/*
+		 * lasttb is used during microtime. Set it to the virtual
+		 * start of this tick interval.
+		 */
+		if ((mfpvr() >> 16) == MPC601) {
+			asm volatile ("mfspr %0,%1" : "=r"(tb) : "n"(SPR_RTCL_R));
+		} else {
+			asm volatile ("mftb %0" : "=r"(tb));
+		}
+		lasttb = tb + ticks - ticks_per_intr;
+
+		/*
 		 * Reenable interrupts
 		 */
 		asm volatile ("mfmsr %0; ori %0, %0, %1; mtmsr %0"
 			      : "=r"(msr) : "K"(PSL_EE));
-		
+
 		/*
 		 * Do standard timer interrupt stuff.
 		 * Do softclock stuff only on the last iteration.
Index: sandpoint/sandpoint/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sandpoint/sandpoint/clock.c,v
retrieving revision 1.7
diff -u -r1.7 clock.c
--- sandpoint/sandpoint/clock.c	2 Jun 2005 14:11:19 -0000	1.7
+++ sandpoint/sandpoint/clock.c	20 Nov 2005 11:53:32 -0000
@@ -73,17 +73,11 @@
 	 * Based on the actual time delay since the last decrementer reload,
 	 * we arrange for earlier interrupt next time.
 	 */
-	asm ("mftb %0; mfdec %1" : "=r"(tb), "=r"(ticks));
+	asm ("mfdec %0" : "=r"(ticks));
 	for (nticks = 0; ticks < 0; nticks++)
 		ticks += ticks_per_intr;
 	asm volatile ("mtdec %0" :: "r"(ticks));
 
-	/*
-	 * lasttb is used during microtime. Set it to the virtual
-	 * start of this tick interval.
-	 */
-	lasttb = tb + ticks - ticks_per_intr;
-
 	intrcnt[CNT_CLOCK]++;
 
 	pri = splclock();
@@ -94,6 +88,13 @@
 		tickspending = 0;
 
 		/*
+		 * lasttb is used during microtime. Set it to the virtual
+		 * start of this tick interval.
+		 */
+		asm ("mftb %0" : "=r"(tb));
+		lasttb = tb + ticks - ticks_per_intr;
+
+		/*
 		 * Reenable interrupts
 		 */
 		asm volatile ("mfmsr %0; ori %0, %0, %1; mtmsr %0"
Index: ofppc/ofppc/clock.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ofppc/ofppc/clock.c,v
retrieving revision 1.9
diff -u -r1.9 clock.c
--- ofppc/ofppc/clock.c	9 Jun 2005 12:25:32 -0000	1.9
+++ ofppc/ofppc/clock.c	20 Nov 2005 11:53:32 -0000
@@ -47,8 +47,8 @@
  * Initially we assume a processor with a bus frequency of 12.5 MHz.
  */
 static u_long ns_per_tick = 320;
-static long ticks_per_intr;
-static volatile u_long lasttb;
+long ticks_per_intr;
+volatile u_long lasttb;
 
 /*
  * For now we let the machine run with boot time, not changing the clock
@@ -76,7 +76,6 @@
 decr_intr(frame)
 	struct clockframe *frame;
 {
-	u_long tb;
 	long ticks;
 	int nticks;
 
@@ -90,17 +89,12 @@
 	 * Based on the actual time delay since the last decrementer reload,
 	 * we arrange for earlier interrupt next time.
 	 */
-	asm ("mftb %0; mfdec %1" : "=r"(tb), "=r"(ticks));
+	asm ("mfdec %0" : "=r"(ticks));
 	for (nticks = 0; ticks < 0; nticks++)
 		ticks += ticks_per_intr;
 	asm volatile ("mtdec %0" :: "r"(ticks));
-	/*
-	 * lasttb is used during microtime. Set it to the virtual
-	 * start of this tick interval.
-	 */
-	lasttb = tb + ticks - ticks_per_intr;
 
-	clock_return(frame, nticks);
+	clock_return(frame, nticks, ticks);
 }
 
 void
Index: ofppc/ofppc/machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ofppc/ofppc/machdep.c,v
retrieving revision 1.87
diff -u -r1.87 machdep.c
--- ofppc/ofppc/machdep.c	20 Oct 2003 00:12:10 -0000	1.87
+++ ofppc/ofppc/machdep.c	20 Nov 2005 11:53:32 -0000
@@ -85,7 +85,7 @@
 static int fake_spl __P((int));
 static void fake_splx __P((int));
 static void fake_setsoft __P((int));
-static void fake_clock_return __P((struct clockframe *, int));
+static void fake_clock_return __P((struct clockframe *, int, long));
 static void *fake_intr_establish __P((int, int, int, int (*)(void *), void *));
 static void fake_intr_disestablish __P((void *));
 
@@ -369,11 +369,17 @@
 }
 
 static void
-fake_clock_return(frame, nticks)
+fake_clock_return(frame, nticks, ticks)
 	struct clockframe *frame;
 	int nticks;
+	long ticks;
 {
-	/* Do nothing */
+
+	/*
+	 * lasttb is used during microtime. Set it to the virtual
+	 * start of this tick interval.
+	 */
+	lasttb = mftb() + ticks - ticks_per_intr;
 }
 
 static void *
Index: ofppc/include/intr.h
===================================================================
RCS file: /cvsroot/src/sys/arch/ofppc/include/intr.h,v
retrieving revision 1.5
diff -u -r1.5 intr.h
--- ofppc/include/intr.h	3 Sep 2003 21:33:33 -0000	1.5
+++ ofppc/include/intr.h	20 Nov 2005 11:53:32 -0000
@@ -99,13 +99,15 @@
 struct clockframe;
 
 extern int imask[];
+extern long ticks_per_intr;
+extern volatile u_long lasttb;
 
 struct machvec {
 	int (*mvec_splraise)(int);
 	int (*mvec_spllower)(int);
 	void (*mvec_splx)(int);
 	void (*mvec_setsoft)(int);
-	void (*mvec_clock_return)(struct clockframe *, int);
+	void (*mvec_clock_return)(struct clockframe *, int, long);
 	void *(*mvec_intr_establish)(int, int, int, int (*)(void *), void *);
 	void (*mvec_intr_disestablish)(void *);
 };
@@ -116,7 +118,7 @@
 #define	_spllower(x)	((*machine_interface.mvec_spllower)(x))
 #define	splx(x)		((*machine_interface.mvec_splx)(x))
 #define	setsoftintr(x)	((*machine_interface.mvec_setsoft)(x))
-#define	clock_return(x, y) ((*machine_interface.mvec_clock_return)(x, y))
+#define	clock_return(x, y, z) ((*machine_interface.mvec_clock_return)(x, y, z))
 #define	intr_establish(irq, lvl, ist, func, arg)			\
 	((*machine_interface.mvec_intr_establish)((irq), (lvl), (ist),	\
 	    (func), (arg)))
Index: ofppc/ofwgen/ofwgen_intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ofppc/ofwgen/ofwgen_intr.c,v
retrieving revision 1.7
diff -u -r1.7 ofwgen_intr.c
--- ofppc/ofwgen/ofwgen_intr.c	15 Jul 2003 02:46:33 -0000	1.7
+++ ofppc/ofwgen/ofwgen_intr.c	20 Nov 2005 11:53:32 -0000
@@ -52,7 +52,7 @@
 int	ofwgen_spllower(int);
 void	ofwgen_splx(int);
 void	ofwgen_setsoft(int);
-void	ofwgen_clock_return(struct clockframe *, int);
+void	ofwgen_clock_return(struct clockframe *, int, long);
 void	*ofwgen_intr_establish(int, int, int, int (*)(void *), void *);
 void	ofwgen_intr_disestablish(void *);
 
@@ -351,7 +351,7 @@
 }
 
 void
-ofwgen_clock_return(struct clockframe *frame, int nticks)
+ofwgen_clock_return(struct clockframe *frame, int nticks, long ticks)
 {
 	int pri;
 
@@ -362,6 +362,12 @@
 	else {
 		cpl = pri | imask[IPL_CLOCK];
 
+		/*
+		 * lasttb is used during microtime. Set it to the virtual
+		 * start of this tick interval.
+		 */
+		lasttb = mftb() + ticks - ticks_per_intr;
+
 		/* Reenable interrupts. */
 		mtmsr(mfmsr() | PSL_EE);
 
Index: ofppc/firepower/firepower_intr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ofppc/firepower/firepower_intr.c,v
retrieving revision 1.6
diff -u -r1.6 firepower_intr.c
--- ofppc/firepower/firepower_intr.c	15 Jul 2003 02:46:31 -0000	1.6
+++ ofppc/firepower/firepower_intr.c	20 Nov 2005 11:53:32 -0000
@@ -63,7 +63,7 @@
 int	firepower_spllower(int);
 void	firepower_splx(int);
 void	firepower_setsoft(int);
-void	firepower_clock_return(struct clockframe *, int);
+void	firepower_clock_return(struct clockframe *, int, long);
 void	*firepower_intr_establish(int, int, int, int (*)(void *), void *);
 void	firepower_intr_disestablish(void *);
 void	firepower_do_softnet(void);
@@ -524,7 +524,7 @@
 }
 
 void
-firepower_clock_return(struct clockframe *frame, int nticks)
+firepower_clock_return(struct clockframe *frame, int nticks, long ticks)
 {
 	int pri, msr;
 
@@ -535,6 +535,12 @@
 	else {
 		cpl = pri | imask[IPL_CLOCK];
 
+		/*
+		 * lasttb is used during microtime. Set it to the virtual
+		 * start of this tick interval.
+		 */
+		lasttb = mftb() + ticks - ticks_per_intr;
+
 		/* Reenable interrupts. */
 		msr = mfmsr();
 		mtmsr(msr | PSL_EE);