smp g5 testing!

Adrian Chadd <[email protected]> Mon, 19 Jan 2026 18:56:29 -0800
Newsgroups gmane.os.freebsd.devel.ppc
Message-ID <CAJ-Vmom-yKR2f4JrezCh=QxG=KsdMPamR2ds9o8GEOxRXDoNfA@mail.gmail.com>
hi!

i have attached a trashpanda style diff to
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=271826 ; if you have
a dual or quad g5 then please test it out and report back.

I have /just/ this diff in my tree and my dual cpu g5 is
booting/building world right now with two CPUs.

I have other issues to chase down on the g5 (notably why things don't
work right when I boot a non-debug kernel) but those can wait a little
bit.

Thanks!


-a
20260119-ppc64-g5-smp-timebase-hack.diff (application/octet-stream, 3.6 KB)
commit 52175ee4f8b85ccfcbeb862079246fb230c114b4
Author: Adrian Chadd <[email protected]>
Date:   Mon Jan 19 18:38:43 2026 -0800

    powerpc: absolute trash commit to force these two CPUs into sync
    
    There's no timebase freeze platform routine registered on my dual 2.3GHz
    G5 PPC970FX apple powermac thing.
    
    So, I figured I could just .. smash them together like this and pray.
    
    Heres the output on the mac itself:
    
    [adrian] [0] powermac_smp_timebase_sync: called, AP tb=0x4d72654c tb=0x4d726554
    [adrian] [1] powermac_smp_timebase_sync: called, AP tb=0x4d72654c tb=0x57a2ffbf
    [adrian] [1] powermac_smp_timebase_sync: finished; AP tb=0x4d72654c called tb=0x4d72654d
    [adrian] [0] powermac_smp_timebase_sync: finished; AP tb=0x4d72654c called tb=0x4d72654d

diff --git a/sys/powerpc/powermac/platform_powermac.c b/sys/powerpc/powermac/platform_powermac.c
index c63ef521ca8f..11ad5ab3b315 100644
--- a/sys/powerpc/powermac/platform_powermac.c
+++ b/sys/powerpc/powermac/platform_powermac.c
@@ -213,6 +213,7 @@ powermac_attach(platform_t plat)
 
 	rootnode = OF_finddevice("/");
 	if (OF_getprop(rootnode, "model", model, sizeof(model)) > 0) {
+		printf("[adrian] %s: model=%s\n", __func__, model);
 		if (strcmp(model, "PowerMac11,2") == 0 ||
 		    strcmp(model, "PowerMac12,1") == 0) {
 			ofw_quiesce();
@@ -401,6 +402,7 @@ powermac_smp_start_cpu(platform_t plat, struct pcpu *pc)
 void
 powermac_register_timebase(device_t dev, powermac_tb_disable_t cb)
 {
+	printf("[adrian] %s: called, tb_dev=%p, freeze_timebase=%p\n", __func__, dev, cb);
 	powermac_tb_dev = dev;
 	freeze_timebase = cb;
 }
@@ -408,18 +410,21 @@ powermac_register_timebase(device_t dev, powermac_tb_disable_t cb)
 static void
 powermac_smp_timebase_sync(platform_t plat, u_long tb, int ap)
 {
-	static volatile bool tb_ready;
+	static volatile bool tb_ready = false;
 	static volatile int cpu_done;
 
+	printf("[adrian] [%d] %s: called, AP tb=0x%lx tb=0x%lx\n",
+	    ap, __func__, tb, mftb());
+
 	/*
 	 * XXX Temporary fallback for platforms we don't know how to freeze.
 	 *
 	 * This needs to be replaced with a cpu-to-cpu software sync
 	 * protocol, because this is not a consistent way to sync timebase.
 	 */
+
+	/* Do initial timebase sync */
 	mttb(tb);
-	if (freeze_timebase == dummy_timebase)
-		return;
 
 	if (ap) {
 		/* APs.  Hold off until we get a stable timebase. */
@@ -428,25 +433,29 @@ powermac_smp_timebase_sync(platform_t plat, u_long tb, int ap)
 			atomic_thread_fence_seq_cst();
 		mttb(tb);
 		atomic_add_int(&cpu_done, 1);
-		while (cpu_done < mp_ncpus)
+		do {
 			atomic_thread_fence_seq_cst();
+		} while (cpu_done < mp_ncpus);
+		mttb(tb);
 		critical_exit();
 	} else {
 		/* BSP */
 		critical_enter();
 		/* Ensure cpu_done is zeroed so we can resync at runtime */
-		atomic_set_int(&cpu_done, 0);
-		freeze_timebase(powermac_tb_dev, true);
+		atomic_store_int(&cpu_done, 0);
 		tb_ready = true;
 		mttb(tb);
 		atomic_add_int(&cpu_done, 1);
-		while (cpu_done < mp_ncpus)
+		do {
 			atomic_thread_fence_seq_cst();
-		freeze_timebase(powermac_tb_dev, false);
+		} while (cpu_done < mp_ncpus);
+		mttb(tb);
 		/* Reset tb_ready so we can resync at runtime */
 		tb_ready = false;
 		critical_exit();
 	}
+	printf("[adrian] [%d] %s: finished; AP tb=0x%lx called tb=0x%lx\n",
+	    ap, __func__, tb, mftb());
 }
 
 /* Fallback freeze. In case no real handler is found in the device tree. */
@@ -454,6 +463,7 @@ static void
 dummy_timebase(device_t dev, bool freeze)
 {
 	/* Nothing to do here, move along. */
+	printf("[adrian] %s: called; freeze=%d\n", __func__, freeze);
 }
 
 static void