Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/hppa/hppa Commit work in progress ipi functions.
details: https://anonhg.NetBSD.org/src/rev/579de43dc7e2
branches: trunk
changeset: 778574:579de43dc7e2
user: skrll <skrll%NetBSD.org@localhost>
date: Thu Apr 05 16:13:46 2012 +0000
description:
Commit work in progress ipi functions.
diffstat:
sys/arch/hppa/hppa/ipifuncs.c | 211 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 211 insertions(+), 0 deletions(-)
diffs (215 lines):
diff -r 0c7c68110c57 -r 579de43dc7e2 sys/arch/hppa/hppa/ipifuncs.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/hppa/hppa/ipifuncs.c Thu Apr 05 16:13:46 2012 +0000
@@ -0,0 +1,211 @@
+/* $NetBSD: ipifuncs.c,v 1.1 2012/04/05 16:13:46 skrll Exp $ */
+/* $OpenBSD: ipi.c,v 1.4 2011/01/14 13:20:06 jsing Exp $ */
+
+/*
+ * Copyright (c) 2010 Joel Sing <jsing%openbsd.org@localhost>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/mutex.h>
+#include <sys/device.h>
+#include <sys/atomic.h>
+#include <sys/xcall.h>
+
+#include <machine/cpu.h>
+#include <machine/cpufunc.h>
+#if 0
+#include <machine/fpu.h>
+#endif
+#include <machine/iomod.h>
+#include <machine/intr.h>
+#include <machine/mutex.h>
+#include <machine/reg.h>
+#include <machine/int_fmtio.h>
+
+#include <hppa/hppa/cpuvar.h>
+
+void hppa_ipi_nop(void);
+void hppa_ipi_halt(void);
+void hppa_ipi_xcall(void);
+
+void (*ipifunc[HPPA_NIPI])(void) =
+{
+ hppa_ipi_nop,
+ hppa_ipi_halt,
+ hppa_ipi_xcall
+};
+
+const char *ipinames[HPPA_NIPI] = {
+ "nop ipi",
+ "halt ipi",
+ "xcall ipi"
+};
+
+void
+hppa_ipi_init(struct cpu_info *ci)
+{
+ struct cpu_softc *sc = ci->ci_softc;
+ int i;
+
+ evcnt_attach_dynamic(&sc->sc_evcnt_ipi, EVCNT_TYPE_INTR,
+ NULL, device_xname(sc->sc_dev), "ipi");
+
+ for (i = 0; i < HPPA_NIPI; i++) {
+ evcnt_attach_dynamic(&sc->sc_evcnt_which_ipi[i],
+ EVCNT_TYPE_INTR, NULL, device_xname(sc->sc_dev),
+ ipinames[i]);
+ }
+}
+
+int
+hppa_ipi_intr(void *arg)
+{
+ struct cpu_info *ci = curcpu();
+ struct cpu_softc *sc = ci->ci_softc;
+ u_long ipi_pending;
+ int bit = 0;
+
+printf_nolog("%s: ci %p\n",__func__, curcpu());
+
+ /* Handle an IPI. */
+ ipi_pending = atomic_swap_ulong(&ci->ci_ipi, 0);
+
+ KASSERT(ipi_pending);
+
+ sc->sc_evcnt_ipi.ev_count++;
+
+ while (ipi_pending) {
+ if (ipi_pending & (1L << bit)) {
+ sc->sc_evcnt_which_ipi[bit].ev_count++;
+ (*ipifunc[bit])();
+ }
+ ipi_pending &= ~(1L << bit);
+ bit++;
+ }
+
+ return 1;
+}
+
+int
+hppa_ipi_send(struct cpu_info *ci, u_long ipi)
+{
+ struct iomod *cpu;
+printf_nolog("%s: made it\n", __func__);
+ KASSERT(ci->ci_flags & CPUF_RUNNING);
+
+ atomic_or_ulong(&ci->ci_ipi, (1L << ipi));
+printf_nolog("%s: after atomic\n",__func__);
+
+ /* Send an IPI to the specified CPU by triggering EIR{1} (irq 30). */
+ cpu = (struct iomod *)(ci->ci_hpa);
+ cpu->io_eir = 1;
+ membar_sync();
+printf_nolog("%s: after io_eir ci %p\n",__func__, curcpu());
+
+ return 0;
+}
+
+int
+hppa_ipi_broadcast(u_long ipi)
+{
+ CPU_INFO_ITERATOR cii;
+ struct cpu_info *ci;
+ int count = 0;
+
+ for (CPU_INFO_FOREACH(cii, ci)) {
+ if (ci != curcpu() && (ci->ci_flags & CPUF_RUNNING))
+ if (hppa_ipi_send(ci, ipi))
+ count++;
+ }
+
+ return count;
+}
+
+void
+hppa_ipi_nop(void)
+{
+}
+
+void
+hppa_ipi_halt(void)
+{
+ struct cpu_info *ci = curcpu();
+
+ /* Turn off interrupts and halt CPU. */
+// hppa_intr_disable();
+ ci->ci_flags &= ~CPUF_RUNNING;
+
+ for (;;)
+ ;
+}
+
+#if 0
+void
+hppa_ipi_fpu_save(void)
+{
+ fpu_cpu_save(1);
+}
+
+void
+hppa_ipi_fpu_flush(void)
+{
+ fpu_cpu_save(0);
+}
+
+#endif
+
+void
+hppa_ipi_xcall(void)
+{
+
+ xc_ipi_handler();
+}
+
+void
+xc_send_ipi(struct cpu_info *ci)
+{
+
+ KASSERT(kpreempt_disabled());
+ KASSERT(curcpu() != ci);
+Debugger();
+ if (ci) {
+ /* Unicast: remote CPU. */
+ hppa_ipi_send(ci, HPPA_IPI_XCALL);
+ } else {
+ /* Broadcast: all, but local CPU (caller will handle it). */
+ hppa_ipi_broadcast(HPPA_IPI_XCALL);
+ }
+}
+
+void hppa_ipi_counts(void);
+void
+hppa_ipi_counts(void)
+{
+ CPU_INFO_ITERATOR cii;
+ struct cpu_info *ci;
+ struct cpu_softc *sc;
+
+ for (CPU_INFO_FOREACH(cii, ci)) {
+ if ((ci->ci_flags & CPUF_RUNNING)) {
+ sc = ci->ci_softc;
+ printf("%s: ci %p cpuid %d total ipis %" PRIu64 "\n", __func__, ci, ci->ci_cpuid, sc->sc_evcnt_ipi.ev_count);
+ printf("%s: ci %p cpuid %d ipis bit 0 %" PRIu64 "\n", __func__, ci, ci->ci_cpuid, sc->sc_evcnt_which_ipi[0].ev_count);
+ printf("%s: ci %p cpuid %d ipis bit 1 %" PRIu64 "\n", __func__, ci, ci->ci_cpuid, sc->sc_evcnt_which_ipi[1].ev_count);
+ printf("%s: ci %p cpuid %d ipis bit 2 %" PRIu64 "\n", __func__, ci, ci->ci_cpuid, sc->sc_evcnt_which_ipi[2].ev_count);
+ }
+ }
+}
Home |
Main Index |
Thread Index |
Old Index