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