Module Name: src
Committed By: martin
Date: Sat May 29 21:59:34 UTC 2010
Modified Files:
src/sys/arch/sparc64/include: cpu.h
src/sys/arch/sparc64/sparc64: ipifuncs.c mp_subr.S
Log Message:
Add a generic ipi to call arbitrary C functions on another (or all other)
cpu(s). Will be used in the near future by some code Mindaugas is working on.
To generate a diff of this commit:
cvs rdiff -u -r1.91 -r1.92 src/sys/arch/sparc64/include/cpu.h
cvs rdiff -u -r1.37 -r1.38 src/sys/arch/sparc64/sparc64/ipifuncs.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/sparc64/sparc64/mp_subr.S
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/sparc64/include/cpu.h
diff -u src/sys/arch/sparc64/include/cpu.h:1.91 src/sys/arch/sparc64/include/cpu.h:1.92
--- src/sys/arch/sparc64/include/cpu.h:1.91 Mon May 24 09:49:17 2010
+++ src/sys/arch/sparc64/include/cpu.h Sat May 29 21:59:33 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.91 2010/05/24 09:49:17 martin Exp $ */
+/* $NetBSD: cpu.h,v 1.92 2010/05/29 21:59:33 martin Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -247,12 +247,21 @@
* multicast - send to everyone in the sparc64_cpuset_t
* broadcast - send to to all cpus but ourselves
* send - send to just this cpu
+ * The called function do not follow the C ABI, so need to be coded in
+ * assembler.
*/
typedef void (* ipifunc_t)(void *, void *);
void sparc64_multicast_ipi(sparc64_cpuset_t, ipifunc_t, uint64_t, uint64_t);
void sparc64_broadcast_ipi(ipifunc_t, uint64_t, uint64_t);
void sparc64_send_ipi(int, ipifunc_t, uint64_t, uint64_t);
+
+/*
+ * Call an arbitrary C function on another cpu (or all others but ourself)
+ */
+typedef void (*ipi_c_call_func_t)(void*);
+void sparc64_generic_xcall(struct cpu_info*, ipi_c_call_func_t, void*);
+
#endif
/*
Index: src/sys/arch/sparc64/sparc64/ipifuncs.c
diff -u src/sys/arch/sparc64/sparc64/ipifuncs.c:1.37 src/sys/arch/sparc64/sparc64/ipifuncs.c:1.38
--- src/sys/arch/sparc64/sparc64/ipifuncs.c:1.37 Mon May 24 09:49:17 2010
+++ src/sys/arch/sparc64/sparc64/ipifuncs.c Sat May 29 21:59:34 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: ipifuncs.c,v 1.37 2010/05/24 09:49:17 martin Exp $ */
+/* $NetBSD: ipifuncs.c,v 1.38 2010/05/29 21:59:34 martin Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.37 2010/05/24 09:49:17 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.38 2010/05/29 21:59:34 martin Exp $");
#include "opt_ddb.h"
@@ -65,7 +65,7 @@
/*
- * These are the "function" entry points in locore.s to handle IPI's.
+ * These are the "function" entry points in locore.s/mp_subr.s to handle IPI's.
*/
void sparc64_ipi_halt(void *, void *);
void sparc64_ipi_pause(void *, void *);
@@ -74,6 +74,7 @@
void sparc64_ipi_dcache_flush_page_us(void *, void *);
void sparc64_ipi_dcache_flush_page_usiii(void *, void *);
void sparc64_ipi_blast_dcache(void *, void *);
+void sparc64_ipi_ccall(void *, void *);
/*
* Process cpu stop-self event.
@@ -461,3 +462,30 @@
printf("\n");
}
+
+void
+sparc64_generic_xcall(struct cpu_info *target, ipi_c_call_func_t func,
+ void *arg)
+{
+ /* if target == NULL broadcast to everything but curcpu */
+ if (target)
+ sparc64_send_ipi(target->ci_cpuid, sparc64_ipi_ccall,
+ (uint64_t)(uintptr_t)func, (uint64_t)(uintptr_t)arg);
+ else {
+
+ sparc64_multicast_ipi(cpus_active, sparc64_ipi_ccall,
+ (uint64_t)(uintptr_t)func, (uint64_t)(uintptr_t)arg);
+ }
+}
+
+#if 0
+/* XXX: remove once a public prototype is available */
+void xc_ipi_handler(void);
+void xc_send_ipi(struct cpu_info *);
+
+void
+xc_send_ipi(struct cpu_info *target)
+{
+ sparc64_generic_xcall(target, (ipi_c_call_func_t)xc_ipi_handler, NULL);
+}
+#endif
Index: src/sys/arch/sparc64/sparc64/mp_subr.S
diff -u src/sys/arch/sparc64/sparc64/mp_subr.S:1.1 src/sys/arch/sparc64/sparc64/mp_subr.S:1.2
--- src/sys/arch/sparc64/sparc64/mp_subr.S:1.1 Sun May 23 18:49:14 2010
+++ src/sys/arch/sparc64/sparc64/mp_subr.S Sat May 29 21:59:34 2010
@@ -1,4 +1,4 @@
-/* $NetBSD: mp_subr.S,v 1.1 2010/05/23 18:49:14 martin Exp $ */
+/* $NetBSD: mp_subr.S,v 1.2 2010/05/29 21:59:34 martin Exp $ */
/*
* Copyright (c) 2006-2010 Matthew R. Green
@@ -407,5 +407,23 @@
membar #Sync
ba,a ret_from_intr_vector
nop
-#endif
+/*
+ * Setup a C compatible environment and call a MI function.
+ *
+ * On entry:
+ * %g2 = function to call
+ * %g3 = single argument to called function
+ */
+ENTRY(sparc64_ipi_ccall)
+ save %sp, -CC64FSZ-16, %sp ! create a stack frame
+ stx %g2, [%fp + BIAS -16 + 0] ! save function pointer
+ stx %g3, [%fp + BIAS -16 + 8] ! and argument
+ wrpr %g0, PSTATE_KERN, %pstate ! switch globals
+ ldx [%fp + BIAS -16 + 0], %l0 ! reload function
+ call %l0 ! call function
+ ldx [%fp + BIAS -16 + 8], %o0 ! reload argument
+ restore ! pop stack frame
+ ba,a ret_from_intr_vector ! and return from IPI
+ nop
+#endif