[OpenBIOS] r407 - openbios-devel/arch/ppc/qemu

svn at openbios.org svn at openbios.org
Thu Jan 15 00:25:41 CET 2009


Author: laurent
Date: 2009-01-15 00:25:41 +0100 (Thu, 15 Jan 2009)
New Revision: 407

Modified:
   openbios-devel/arch/ppc/qemu/methods.c
Log:
PowerPC: Fix milliseconds prom call

The current implementation of the milliseconds prom call on PowerPC is
totally buggy:
- The timer frequency returned by get_timer_freq() does not correspond
  to the timer which is read.
- The dividend and the divisor of the division are swapped
- If called very often, this function is not precise
- Depending on the timer frequency and of the frequency of the calls,
  the variable overflow after a few dozen of seconds.

Please find in this patch a totally new implementation. This fixes the
problem observed with the quik when a timeout is defined.

The timer frequency is defined using #define, I wonder if there is a
better place to put it.

It reads both low and high part of the timer to make sure there is no
overflow. It also removes the function that returns 0 on the first call
as this is not needed according to IEEE 1275-1994. Finally it computes
the real value of the timer each time, instead of adding a small value
to a variable at each function calls, in order to get a correct
precision if this method is call very often.

(Aurelien Jarno)


Modified: openbios-devel/arch/ppc/qemu/methods.c
===================================================================
--- openbios-devel/arch/ppc/qemu/methods.c	2009-01-13 20:24:52 UTC (rev 406)
+++ openbios-devel/arch/ppc/qemu/methods.c	2009-01-14 23:25:41 UTC (rev 407)
@@ -122,19 +122,28 @@
 }
 
 /* ( -- ms ) */
+#define TIMER_FREQUENCY 16600000ULL
+
 static void
 ciface_milliseconds( ulong args[], ulong ret[] )
 {
-        extern unsigned long get_timer_freq(void);
-	static ulong mticks=0, usecs=0;
-	ulong t;
+	ulong tbu, tbl, temp;
+	ullong ticks, msecs;
 
-	asm volatile("mftb %0" : "=r" (t) : );
-	if( mticks )
-		usecs += get_timer_freq() / 1000000 * ( t-mticks );
-	mticks = t;
+	asm volatile(
+		"1:\n"
+		"mftbu  %2\n"
+		"mftb   %0\n"
+		"mftbu  %1\n"
+		"cmpw   %2,%1\n"
+		"bne    1b\n"
+		: "=r"(tbl), "=r"(tbu), "=r"(temp)
+		:
+		: "cc");
 
-	PUSH( usecs/1000 );
+	ticks = (((ullong)tbu) << 32) | (ullong)tbl;
+	msecs = (1000 * ticks) / TIMER_FREQUENCY;
+	PUSH( msecs );
 }
 
 




More information about the OpenBIOS mailing list