Module Name:    src
Committed By:   martin
Date:           Sat Oct 26 15:28:56 UTC 2024

Modified Files:
        src/sys/arch/evbppc/wii [netbsd-10]: machdep.c
        src/sys/arch/powerpc/powerpc [netbsd-10]: clock.c

Log Message:
Pull up following revision(s) (requested by jmcneill in ticket #986):

        sys/arch/evbppc/wii/machdep.c: revision 1.8
        sys/arch/powerpc/powerpc/clock.c: revision 1.19

Improve delay() accuracy on Nintendo Wii.

The PowerPC delay() implementation converts the timebase frequency to
a number of nanoseconds per tick and uses that value to compute the
delay interval. On the Wii's Broadway processor with a timebase
frequency of 60.75 MHz, some precision is lost as each tick is
approximately 16.46 nanoseconds. The end result is that we sleep for
approximately 2.875% longer than necessary. This also has an impact
on CPU speed calculation on Broadway, which incorrectly reports itself
as 750MHz instead of 729MHz (2.875% faster).

Fix this by introducing an (optional) ticks_per_msec variable that can
be set by the platform and allows delay() to improve the accuracy of
longer delays.

Measured CPU frequency before this change:
[     1.000000] cpu0: 750.00 MHz, 256KB WB with ECC L2 cache
Measured CPU frequency after this change:
[     1.000000] cpu0: 729.00 MHz, 256KB WB with ECC L2 cache


To generate a diff of this commit:
cvs rdiff -u -r1.4.2.3 -r1.4.2.4 src/sys/arch/evbppc/wii/machdep.c
cvs rdiff -u -r1.17.20.1 -r1.17.20.2 src/sys/arch/powerpc/powerpc/clock.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/evbppc/wii/machdep.c
diff -u src/sys/arch/evbppc/wii/machdep.c:1.4.2.3 src/sys/arch/evbppc/wii/machdep.c:1.4.2.4
--- src/sys/arch/evbppc/wii/machdep.c:1.4.2.3	Mon Oct 14 16:44:42 2024
+++ src/sys/arch/evbppc/wii/machdep.c	Sat Oct 26 15:28:55 2024
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.4.2.3 2024/10/14 16:44:42 martin Exp $ */
+/* $NetBSD: machdep.c,v 1.4.2.4 2024/10/26 15:28:55 martin Exp $ */
 
 /*
  * Copyright (c) 2002, 2024 The NetBSD Foundation, Inc.
@@ -63,7 +63,7 @@
 #define _POWERPC_BUS_DMA_PRIVATE
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.4.2.3 2024/10/14 16:44:42 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.4.2.4 2024/10/26 15:28:55 martin Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_ddb.h"
@@ -231,7 +231,8 @@ static void init_decrementer(void);
 void
 initppc(u_int startkernel, u_int endkernel, u_int args, void *btinfo)
 {
-	extern u_long ticks_per_sec;
+	extern uint32_t ticks_per_sec;
+	extern uint32_t ticks_per_msec;
 	extern unsigned char edata[], end[];
 	extern struct wii_argv wii_argv;
 	uint32_t mem2_start, mem2_end;
@@ -319,6 +320,7 @@ initppc(u_int startkernel, u_int endkern
 	 * Get CPU clock
 	 */
 	ticks_per_sec = TIMEBASE_FREQ_HZ;
+	ticks_per_msec = ticks_per_sec / 1000;
 	cpu_timebase = ticks_per_sec;
 
 	wii_setup();
@@ -442,7 +444,7 @@ init_decrementer(void)
 {
 	extern uint32_t ns_per_tick;
 	extern uint32_t ticks_per_intr;
-	extern u_long ticks_per_sec;
+	extern uint32_t ticks_per_sec;
 	int scratch, msr;
 
 	KASSERT(ticks_per_sec != 0);

Index: src/sys/arch/powerpc/powerpc/clock.c
diff -u src/sys/arch/powerpc/powerpc/clock.c:1.17.20.1 src/sys/arch/powerpc/powerpc/clock.c:1.17.20.2
--- src/sys/arch/powerpc/powerpc/clock.c:1.17.20.1	Sat Feb  3 11:47:08 2024
+++ src/sys/arch/powerpc/powerpc/clock.c	Sat Oct 26 15:28:56 2024
@@ -1,4 +1,4 @@
-/*	$NetBSD: clock.c,v 1.17.20.1 2024/02/03 11:47:08 martin Exp $	*/
+/*	$NetBSD: clock.c,v 1.17.20.2 2024/10/26 15:28:56 martin Exp $	*/
 /*      $OpenBSD: clock.c,v 1.3 1997/10/13 13:42:53 pefo Exp $	*/
 
 /*
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.17.20.1 2024/02/03 11:47:08 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: clock.c,v 1.17.20.2 2024/10/26 15:28:56 martin Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ppcarch.h"
@@ -67,6 +67,7 @@ static u_int get_601_timecount(struct ti
 #endif
 
 uint32_t ticks_per_sec;
+uint32_t ticks_per_msec;
 uint32_t ns_per_tick;
 uint32_t ticks_per_intr = 0;
 
@@ -232,6 +233,10 @@ delay(unsigned int n)
 #endif /* !_ARCH_PPC64 */
 	{
 		tb = mftb();
+		if (ticks_per_msec != 0 && n >= 1000) {
+			tb += (n / 1000ULL) * ticks_per_msec;
+			n = n % 1000;
+		}
 		tb += (n * 1000ULL + ns_per_tick - 1) / ns_per_tick;
 #ifdef _ARCH_PPC64
 		__asm volatile ("1: mftb %0; cmpld %0,%1; blt 1b;"

Reply via email to