Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107027543
D29136.id85360.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D29136.id85360.diff
View Options
diff --git a/sys/powerpc/aim/mp_cpudep.c b/sys/powerpc/aim/mp_cpudep.c
--- a/sys/powerpc/aim/mp_cpudep.c
+++ b/sys/powerpc/aim/mp_cpudep.c
@@ -312,7 +312,8 @@
vers = mfpvr() >> 16;
/* The following is needed for restoring from sleep. */
- platform_smp_timebase_sync(0, 1);
+ if (PCPU_GET(restore))
+ platform_smp_timebase_sync(0, 1);
switch(vers) {
case IBM970:
diff --git a/sys/powerpc/powermac/macio.c b/sys/powerpc/powermac/macio.c
--- a/sys/powerpc/powermac/macio.c
+++ b/sys/powerpc/powermac/macio.c
@@ -54,6 +54,7 @@
#include <dev/ofw/openfirm.h>
#include <powerpc/powermac/maciovar.h>
+#include <powerpc/powermac/platform_powermac.h>
#include <dev/pci/pcivar.h>
#include <dev/pci/pcireg.h>
@@ -70,6 +71,9 @@
/* FCR registers */
int sc_memrid;
struct resource *sc_memr;
+
+ /* GPIO offsets */
+ int sc_timebase;
};
static MALLOC_DEFINE(M_MACIO, "macio", "macio device information");
@@ -89,6 +93,9 @@
struct resource *);
static struct resource_list *macio_get_resource_list (device_t, device_t);
static ofw_bus_get_devinfo_t macio_get_devinfo;
+#if !defined(__powerpc64__) && defined(SMP)
+static void macio_freeze_timebase(device_t, bool);
+#endif
/*
* Bus interface definition
@@ -430,6 +437,26 @@
}
}
+#if !defined(__powerpc64__) && defined(SMP)
+ /*
+ * Detect an SMP G4 machine.
+ *
+ * On SMP G4, timebase freeze is via a GPIO on macio.
+ *
+ * When we are on an SMP G4, we need to install a handler to
+ * perform timebase freeze/unfreeze on behalf of the platform.
+ */
+ if ((child = OF_finddevice("/cpus/PowerPC,G4@0")) != -1 &&
+ OF_peer(child) != -1) {
+ if (OF_getprop(child, "timebase-enable", &sc->sc_timebase,
+ sizeof(sc->sc_timebase)) <= 0)
+ sc->sc_timebase = KEYLARGO_GPIO_BASE + 0x09;
+ powermac_register_timebase(dev, macio_freeze_timebase);
+ device_printf(dev, "GPIO timebase control at 0x%x\n",
+ sc->sc_timebase);
+ }
+#endif
+
return (bus_generic_attach(dev));
}
@@ -693,3 +720,18 @@
return (0);
}
+
+#if !defined(__powerpc64__) && defined(SMP)
+static void
+macio_freeze_timebase(device_t dev, bool frozen)
+{
+ struct macio_softc *sc = device_get_softc(dev);
+
+ if (frozen) {
+ bus_write_1(sc->sc_memr, sc->sc_timebase, 4);
+ } else {
+ bus_write_1(sc->sc_memr, sc->sc_timebase, 0);
+ }
+ bus_read_1(sc->sc_memr, sc->sc_timebase);
+}
+#endif
diff --git a/sys/powerpc/powermac/platform_powermac.h b/sys/powerpc/powermac/platform_powermac.h
new file mode 100644
--- /dev/null
+++ b/sys/powerpc/powermac/platform_powermac.h
@@ -0,0 +1,34 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Brandon Bergren <bdragon@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _PLATFORM_POWERMAC_H_
+#define _PLATFORM_POWERMAC_H_
+
+typedef void (*powermac_tb_disable_t)(device_t, bool);
+extern void powermac_register_timebase(device_t, powermac_tb_disable_t);
+
+#endif /* _PLATFORM_POWERMAC_H_ */
diff --git a/sys/powerpc/powermac/platform_powermac.c b/sys/powerpc/powermac/platform_powermac.c
--- a/sys/powerpc/powermac/platform_powermac.c
+++ b/sys/powerpc/powermac/platform_powermac.c
@@ -53,9 +53,17 @@
#include <dev/ofw/openfirm.h>
#include <machine/ofw_machdep.h>
+#include <powerpc/powermac/platform_powermac.h>
+
#include "platform_if.h"
-extern void *ap_pcpu;
+extern volatile void *ap_pcpu;
+
+static void dummy_timebase(device_t, bool);
+static device_t powermac_tb_dev;
+static void (*freeze_timebase)(device_t, bool) = dummy_timebase;
+
+void powermac_register_timebase(device_t, powermac_tb_disable_t);
static int powermac_probe(platform_t);
static int powermac_attach(platform_t);
@@ -391,11 +399,62 @@
#endif
}
+void
+powermac_register_timebase(device_t dev, powermac_tb_disable_t cb)
+{
+ powermac_tb_dev = dev;
+ freeze_timebase = cb;
+}
+
static void
powermac_smp_timebase_sync(platform_t plat, u_long tb, int ap)
{
+ static volatile bool tb_ready;
+ static volatile int cpu_done;
+ /*
+ * 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.
+ */
mttb(tb);
+ if (freeze_timebase == dummy_timebase)
+ return;
+
+ if (ap) {
+ /* APs. Hold off until we get a stable timebase. */
+ critical_enter();
+ while (!tb_ready)
+ atomic_thread_fence_seq_cst();
+ mttb(tb);
+ atomic_add_int(&cpu_done, 1);
+ while (cpu_done < mp_ncpus)
+ atomic_thread_fence_seq_cst();
+ 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);
+ tb_ready = true;
+ mttb(tb);
+ atomic_add_int(&cpu_done, 1);
+ while (cpu_done < mp_ncpus)
+ atomic_thread_fence_seq_cst();
+ freeze_timebase(powermac_tb_dev, false);
+ /* Reset tb_ready so we can resync at runtime */
+ tb_ready = false;
+ critical_exit();
+ }
+}
+
+/* Fallback freeze. In case no real handler is found in the device tree. */
+static void
+dummy_timebase(device_t dev, bool freeze)
+{
+ /* Nothing to do here, move along. */
}
static void
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 10, 4:35 AM (11 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15739434
Default Alt Text
D29136.id85360.diff (6 KB)
Attached To
Mode
D29136: WIP: [PowerPC] PowerMac timebase sync for G4
Attached
Detach File
Event Timeline
Log In to Comment