Module Name:    src
Committed By:   skrll
Date:           Thu Apr  5 16:13:47 UTC 2012

Added Files:
        src/sys/arch/hppa/hppa: ipifuncs.c

Log Message:
Commit work in progress ipi functions.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/arch/hppa/hppa/ipifuncs.c

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

Added files:

Index: src/sys/arch/hppa/hppa/ipifuncs.c
diff -u /dev/null src/sys/arch/hppa/hppa/ipifuncs.c:1.1
--- /dev/null	Thu Apr  5 16:13:47 2012
+++ src/sys/arch/hppa/hppa/ipifuncs.c	Thu Apr  5 16:13:46 2012
@@ -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 <js...@openbsd.org>
+ *
+ * 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);
+		}
+	}
+}

Reply via email to