Module Name: src
Committed By: rmind
Date: Mon May 19 22:47:54 UTC 2014
Modified Files:
src/sys/arch/alpha/alpha: ipifuncs.c
src/sys/arch/alpha/include: intr.h
src/sys/arch/arm/arm32: arm32_machdep.c
src/sys/arch/arm/cortex: gic.c
src/sys/arch/arm/pic: pic.c picvar.h
src/sys/arch/hppa/hppa: ipifuncs.c
src/sys/arch/hppa/include: intrdefs.h
src/sys/arch/mips/include: intr.h
src/sys/arch/mips/mips: cpu_subr.c ipifuncs.c
src/sys/arch/powerpc/booke: e500_intr.c
src/sys/arch/powerpc/include/booke: intr.h
src/sys/arch/powerpc/pic: ipi.c ipivar.h
src/sys/arch/powerpc/powerpc: powerpc_machdep.c
src/sys/arch/sparc/sparc: cpu.c
src/sys/arch/sparc64/sparc64: ipifuncs.c
src/sys/arch/vax/include: cpu.h
src/sys/arch/vax/vax: multicpu.c
src/sys/arch/x86/include: intrdefs.h
src/sys/arch/x86/x86: ipi.c
src/sys/arch/xen/include: intrdefs.h
src/sys/arch/xen/x86: xen_ipi.c
src/sys/conf: files
src/sys/kern: init_main.c
Added Files:
src/sys/kern: subr_ipi.c
src/sys/sys: ipi.h
Log Message:
Implement MI IPI interface with cross-call support.
To generate a diff of this commit:
cvs rdiff -u -r1.47 -r1.48 src/sys/arch/alpha/alpha/ipifuncs.c
cvs rdiff -u -r1.70 -r1.71 src/sys/arch/alpha/include/intr.h
cvs rdiff -u -r1.104 -r1.105 src/sys/arch/arm/arm32/arm32_machdep.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/cortex/gic.c
cvs rdiff -u -r1.21 -r1.22 src/sys/arch/arm/pic/pic.c
cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/pic/picvar.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/hppa/hppa/ipifuncs.c
cvs rdiff -u -r1.1 -r1.2 src/sys/arch/hppa/include/intrdefs.h
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/mips/include/intr.h
cvs rdiff -u -r1.16 -r1.17 src/sys/arch/mips/mips/cpu_subr.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/mips/mips/ipifuncs.c
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/powerpc/booke/e500_intr.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/powerpc/include/booke/intr.h
cvs rdiff -u -r1.10 -r1.11 src/sys/arch/powerpc/pic/ipi.c
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/powerpc/pic/ipivar.h
cvs rdiff -u -r1.69 -r1.70 src/sys/arch/powerpc/powerpc/powerpc_machdep.c
cvs rdiff -u -r1.244 -r1.245 src/sys/arch/sparc/sparc/cpu.c
cvs rdiff -u -r1.47 -r1.48 src/sys/arch/sparc64/sparc64/ipifuncs.c
cvs rdiff -u -r1.98 -r1.99 src/sys/arch/vax/include/cpu.h
cvs rdiff -u -r1.32 -r1.33 src/sys/arch/vax/vax/multicpu.c
cvs rdiff -u -r1.19 -r1.20 src/sys/arch/x86/include/intrdefs.h
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/x86/x86/ipi.c
cvs rdiff -u -r1.11 -r1.12 src/sys/arch/xen/include/intrdefs.h
cvs rdiff -u -r1.17 -r1.18 src/sys/arch/xen/x86/xen_ipi.c
cvs rdiff -u -r1.1090 -r1.1091 src/sys/conf/files
cvs rdiff -u -r1.454 -r1.455 src/sys/kern/init_main.c
cvs rdiff -u -r0 -r1.1 src/sys/kern/subr_ipi.c
cvs rdiff -u -r0 -r1.1 src/sys/sys/ipi.h
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/alpha/alpha/ipifuncs.c
diff -u src/sys/arch/alpha/alpha/ipifuncs.c:1.47 src/sys/arch/alpha/alpha/ipifuncs.c:1.48
--- src/sys/arch/alpha/alpha/ipifuncs.c:1.47 Tue Jun 14 15:34:22 2011
+++ src/sys/arch/alpha/alpha/ipifuncs.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipifuncs.c,v 1.47 2011/06/14 15:34:22 matt Exp $ */
+/* $NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.47 2011/06/14 15:34:22 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:53 rmind Exp $");
/*
* Interprocessor interrupt handlers.
@@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v
#include <sys/reboot.h>
#include <sys/atomic.h>
#include <sys/cpu.h>
+#include <sys/ipi.h>
#include <sys/intr.h>
#include <sys/xcall.h>
#include <sys/bitops.h>
@@ -59,12 +60,13 @@ __KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v
typedef void (*ipifunc_t)(struct cpu_info *, struct trapframe *);
-void alpha_ipi_halt(struct cpu_info *, struct trapframe *);
-void alpha_ipi_microset(struct cpu_info *, struct trapframe *);
-void alpha_ipi_imb(struct cpu_info *, struct trapframe *);
-void alpha_ipi_ast(struct cpu_info *, struct trapframe *);
-void alpha_ipi_pause(struct cpu_info *, struct trapframe *);
-void alpha_ipi_xcall(struct cpu_info *, struct trapframe *);
+static void alpha_ipi_halt(struct cpu_info *, struct trapframe *);
+static void alpha_ipi_microset(struct cpu_info *, struct trapframe *);
+static void alpha_ipi_imb(struct cpu_info *, struct trapframe *);
+static void alpha_ipi_ast(struct cpu_info *, struct trapframe *);
+static void alpha_ipi_pause(struct cpu_info *, struct trapframe *);
+static void alpha_ipi_xcall(struct cpu_info *, struct trapframe *);
+static void alpha_ipi_generic(struct cpu_info *, struct trapframe *);
/*
* NOTE: This table must be kept in order with the bit definitions
@@ -77,7 +79,8 @@ const ipifunc_t ipifuncs[ALPHA_NIPIS] =
[ilog2(ALPHA_IPI_IMB)] = alpha_ipi_imb,
[ilog2(ALPHA_IPI_AST)] = alpha_ipi_ast,
[ilog2(ALPHA_IPI_PAUSE)] = alpha_ipi_pause,
- [ilog2(ALPHA_IPI_XCALL)] = alpha_ipi_xcall
+ [ilog2(ALPHA_IPI_XCALL)] = alpha_ipi_xcall,
+ [ilog2(ALPHA_IPI_GENERIC)] = alpha_ipi_generic
};
const char * const ipinames[ALPHA_NIPIS] = {
@@ -87,7 +90,8 @@ const char * const ipinames[ALPHA_NIPIS]
[ilog2(ALPHA_IPI_IMB)] = "imb ipi",
[ilog2(ALPHA_IPI_AST)] = "ast ipi",
[ilog2(ALPHA_IPI_PAUSE)] = "pause ipi",
- [ilog2(ALPHA_IPI_XCALL)] = "xcall ipi"
+ [ilog2(ALPHA_IPI_XCALL)] = "xcall ipi",
+ [ilog2(ALPHA_IPI_GENERIC)] = "generic ipi",
};
/*
@@ -208,7 +212,7 @@ alpha_multicast_ipi(u_long cpumask, u_lo
}
}
-void
+static void
alpha_ipi_halt(struct cpu_info *ci, struct trapframe *framep)
{
u_long cpu_id = ci->ci_cpuid;
@@ -241,21 +245,21 @@ alpha_ipi_halt(struct cpu_info *ci, stru
/* NOTREACHED */
}
-void
+static void
alpha_ipi_microset(struct cpu_info *ci, struct trapframe *framep)
{
cc_calibrate_cpu(ci);
}
-void
+static void
alpha_ipi_imb(struct cpu_info *ci, struct trapframe *framep)
{
alpha_pal_imb();
}
-void
+static void
alpha_ipi_ast(struct cpu_info *ci, struct trapframe *framep)
{
@@ -263,7 +267,7 @@ alpha_ipi_ast(struct cpu_info *ci, struc
aston(ci->ci_curlwp);
}
-void
+static void
alpha_ipi_pause(struct cpu_info *ci, struct trapframe *framep)
{
u_long cpumask = (1UL << ci->ci_cpuid);
@@ -295,17 +299,15 @@ alpha_ipi_pause(struct cpu_info *ci, str
* MD support for xcall(9) interface.
*/
-void
+static void
alpha_ipi_xcall(struct cpu_info *ci, struct trapframe *framep)
{
-
xc_ipi_handler();
}
void
xc_send_ipi(struct cpu_info *ci)
{
-
KASSERT(kpreempt_disabled());
KASSERT(curcpu() != ci);
@@ -317,3 +319,24 @@ xc_send_ipi(struct cpu_info *ci)
alpha_broadcast_ipi(ALPHA_IPI_XCALL);
}
}
+
+static void
+alpha_ipi_generic(struct cpu_info *ci, struct trapframe *framep)
+{
+ ipi_cpu_handler();
+}
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+ KASSERT(kpreempt_disabled());
+ KASSERT(curcpu() != ci);
+
+ if (ci) {
+ /* Unicast: remote CPU. */
+ alpha_send_ipi(ci->ci_cpuid, ALPHA_IPI_GENERIC);
+ } else {
+ /* Broadcast: all, but local CPU (caller will handle it). */
+ alpha_broadcast_ipi(ALPHA_IPI_GENERIC);
+ }
+}
Index: src/sys/arch/alpha/include/intr.h
diff -u src/sys/arch/alpha/include/intr.h:1.70 src/sys/arch/alpha/include/intr.h:1.71
--- src/sys/arch/alpha/include/intr.h:1.70 Mon Feb 6 02:14:13 2012
+++ src/sys/arch/alpha/include/intr.h Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.70 2012/02/06 02:14:13 matt Exp $ */
+/* $NetBSD: intr.h,v 1.71 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2000, 2001, 2002 The NetBSD Foundation, Inc.
@@ -164,8 +164,9 @@ _splraise(int s)
#define ALPHA_IPI_AST (1UL << 4)
#define ALPHA_IPI_PAUSE (1UL << 5)
#define ALPHA_IPI_XCALL (1UL << 6)
+#define ALPHA_IPI_GENERIC (1UL << 7)
-#define ALPHA_NIPIS 7 /* must not exceed 64 */
+#define ALPHA_NIPIS 8 /* must not exceed 64 */
struct cpu_info;
struct trapframe;
Index: src/sys/arch/arm/arm32/arm32_machdep.c
diff -u src/sys/arch/arm/arm32/arm32_machdep.c:1.104 src/sys/arch/arm/arm32/arm32_machdep.c:1.105
--- src/sys/arch/arm/arm32/arm32_machdep.c:1.104 Fri Apr 11 04:19:47 2014
+++ src/sys/arch/arm/arm32/arm32_machdep.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: arm32_machdep.c,v 1.104 2014/04/11 04:19:47 matt Exp $ */
+/* $NetBSD: arm32_machdep.c,v 1.105 2014/05/19 22:47:53 rmind Exp $ */
/*
* Copyright (c) 1994-1998 Mark Brinicombe.
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.104 2014/04/11 04:19:47 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: arm32_machdep.c,v 1.105 2014/05/19 22:47:53 rmind Exp $");
#include "opt_modular.h"
#include "opt_md.h"
@@ -65,6 +65,7 @@ __KERNEL_RCSID(0, "$NetBSD: arm32_machde
#include <sys/module.h>
#include <sys/atomic.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <uvm/uvm_extern.h>
@@ -706,6 +707,16 @@ xc_send_ipi(struct cpu_info *ci)
intr_ipi_send(ci != NULL ? ci->ci_kcpuset : NULL, IPI_XCALL);
}
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+ KASSERT(kpreempt_disabled());
+ KASSERT(curcpu() != ci);
+
+ intr_ipi_send(ci != NULL ? ci->ci_kcpuset : NULL, IPI_GENERIC);
+}
+
#endif /* MULTIPROCESSOR */
#ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
Index: src/sys/arch/arm/cortex/gic.c
diff -u src/sys/arch/arm/cortex/gic.c:1.9 src/sys/arch/arm/cortex/gic.c:1.10
--- src/sys/arch/arm/cortex/gic.c:1.9 Sun Apr 27 16:22:13 2014
+++ src/sys/arch/arm/cortex/gic.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: gic.c,v 1.9 2014/04/27 16:22:13 matt Exp $ */
+/* $NetBSD: gic.c,v 1.10 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2012 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -33,7 +33,7 @@
#define _INTR_PRIVATE
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.9 2014/04/27 16:22:13 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.10 2014/05/19 22:47:53 rmind Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -42,7 +42,6 @@ __KERNEL_RCSID(0, "$NetBSD: gic.c,v 1.9
#include <sys/intr.h>
#include <sys/cpu.h>
#include <sys/proc.h>
-#include <sys/xcall.h> /* for xc_ipi_handler */
#include <arm/armreg.h>
#include <arm/cpufunc.h>
@@ -612,6 +611,8 @@ armgic_attach(device_t parent, device_t
pic_ipi_nop, (void *)-1);
intr_establish(ARMGIC_SGI_IPIBASE + IPI_XCALL, IPL_VM, IST_EDGE,
pic_ipi_xcall, (void *)-1);
+ intr_establish(ARMGIC_SGI_IPIBASE + IPI_GENERIC, IPL_VM, IST_EDGE,
+ pic_ipi_generic, (void *)-1);
intr_establish(ARMGIC_SGI_IPIBASE + IPI_NOP, IPL_VM, IST_EDGE,
pic_ipi_nop, (void *)-1);
intr_establish(ARMGIC_SGI_IPIBASE + IPI_SHOOTDOWN, IPL_VM, IST_EDGE,
Index: src/sys/arch/arm/pic/pic.c
diff -u src/sys/arch/arm/pic/pic.c:1.21 src/sys/arch/arm/pic/pic.c:1.22
--- src/sys/arch/arm/pic/pic.c:1.21 Thu Mar 13 23:47:53 2014
+++ src/sys/arch/arm/pic/pic.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: pic.c,v 1.21 2014/03/13 23:47:53 matt Exp $ */
+/* $NetBSD: pic.c,v 1.22 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -32,7 +32,7 @@
#include "opt_ddb.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.21 2014/03/13 23:47:53 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.22 2014/05/19 22:47:53 rmind Exp $");
#include <sys/param.h>
#include <sys/atomic.h>
@@ -42,6 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: pic.c,v 1.21
#include <sys/kernel.h>
#include <sys/kmem.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <arm/armreg.h>
#include <arm/cpufunc.h>
@@ -107,6 +108,13 @@ pic_ipi_xcall(void *arg)
return 1;
}
+int
+pic_ipi_generic(void *arg)
+{
+ ipi_cpu_handler();
+ return 1;
+}
+
#ifdef DDB
int
pic_ipi_ddb(void *arg)
Index: src/sys/arch/arm/pic/picvar.h
diff -u src/sys/arch/arm/pic/picvar.h:1.9 src/sys/arch/arm/pic/picvar.h:1.10
--- src/sys/arch/arm/pic/picvar.h:1.9 Thu Mar 13 23:47:53 2014
+++ src/sys/arch/arm/pic/picvar.h Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: picvar.h,v 1.9 2014/03/13 23:47:53 matt Exp $ */
+/* $NetBSD: picvar.h,v 1.10 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -49,11 +49,12 @@ struct cpu_info;
#define IPI_NOP 2 /* just get an interrupt (armv6) */
#define IPI_SHOOTDOWN 3 /* cause a tlb shootdown */
#define IPI_DDB 4 /* enter DDB */
+#define IPI_GENERIC 5 /* generic IPI */
#ifdef __HAVE_PREEMPTION
-#define IPI_KPREEMPT 5 /* cause a preemption */
-#define NIPI 6
+#define IPI_KPREEMPT 6 /* cause a preemption */
+#define NIPI 7
#else
-#define NIPI 5
+#define NIPI 6
#endif
int pic_handle_intr(void *);
@@ -160,6 +161,7 @@ void pic_do_pending_int(void);
#ifdef MULTIPROCESSOR
int pic_ipi_nop(void *);
int pic_ipi_xcall(void *);
+int pic_ipi_generic(void *);
int pic_ipi_shootdown(void *);
int pic_ipi_ddb(void *);
#endif
Index: src/sys/arch/hppa/hppa/ipifuncs.c
diff -u src/sys/arch/hppa/hppa/ipifuncs.c:1.2 src/sys/arch/hppa/hppa/ipifuncs.c:1.3
--- src/sys/arch/hppa/hppa/ipifuncs.c:1.2 Thu Apr 5 16:16:01 2012
+++ src/sys/arch/hppa/hppa/ipifuncs.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipifuncs.c,v 1.2 2012/04/05 16:16:01 skrll Exp $ */
+/* $NetBSD: ipifuncs.c,v 1.3 2014/05/19 22:47:53 rmind Exp $ */
/* $OpenBSD: ipi.c,v 1.4 2011/01/14 13:20:06 jsing Exp $ */
/*
@@ -24,6 +24,7 @@
#include <sys/device.h>
#include <sys/atomic.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <machine/cpu.h>
#include <machine/cpufunc.h>
@@ -38,21 +39,22 @@
#include <hppa/hppa/cpuvar.h>
-void hppa_ipi_nop(void);
-void hppa_ipi_halt(void);
-void hppa_ipi_xcall(void);
+static void hppa_ipi_nop(void);
+static void hppa_ipi_halt(void);
void (*ipifunc[HPPA_NIPI])(void) =
{
hppa_ipi_nop,
hppa_ipi_halt,
- hppa_ipi_xcall
+ xc_ipi_handler,
+ ipi_cpu_handler,
};
const char *ipinames[HPPA_NIPI] = {
"nop ipi",
"halt ipi",
"xcall ipi"
+ "generic ipi"
};
void
@@ -130,16 +132,16 @@ hppa_ipi_broadcast(u_long ipi)
return count;
}
-void
+static void
hppa_ipi_nop(void)
{
}
-void
+static void
hppa_ipi_halt(void)
{
struct cpu_info *ci = curcpu();
-
+
/* Turn off interrupts and halt CPU. */
// hppa_intr_disable();
ci->ci_flags &= ~CPUF_RUNNING;
@@ -149,24 +151,31 @@ hppa_ipi_halt(void)
}
void
-hppa_ipi_xcall(void)
+xc_send_ipi(struct cpu_info *ci)
{
-
- xc_ipi_handler();
+ KASSERT(kpreempt_disabled());
+ KASSERT(curcpu() != ci);
+
+ 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
-xc_send_ipi(struct cpu_info *ci)
+cpu_ipi(struct cpu_info *)
{
-
KASSERT(kpreempt_disabled());
KASSERT(curcpu() != ci);
if (ci) {
/* Unicast: remote CPU. */
- hppa_ipi_send(ci, HPPA_IPI_XCALL);
+ hppa_ipi_send(ci, HPPA_IPI_GENERIC);
} else {
/* Broadcast: all, but local CPU (caller will handle it). */
- hppa_ipi_broadcast(HPPA_IPI_XCALL);
+ hppa_ipi_broadcast(HPPA_IPI_GENERIC);
}
}
Index: src/sys/arch/hppa/include/intrdefs.h
diff -u src/sys/arch/hppa/include/intrdefs.h:1.1 src/sys/arch/hppa/include/intrdefs.h:1.2
--- src/sys/arch/hppa/include/intrdefs.h:1.1 Mon Feb 24 07:23:43 2014
+++ src/sys/arch/hppa/include/intrdefs.h Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: intrdefs.h,v 1.1 2014/02/24 07:23:43 skrll Exp $ */
+/* $NetBSD: intrdefs.h,v 1.2 2014/05/19 22:47:53 rmind Exp $ */
#ifndef _HPPA_INTRDEFS_H_
#define _HPPA_INTRDEFS_H_
@@ -24,7 +24,8 @@
#define HPPA_IPI_NOP 0
#define HPPA_IPI_HALT 1
#define HPPA_IPI_XCALL 2
-#define HPPA_NIPI 3
+#define HPPA_IPI_GENERIC 3
+#define HPPA_NIPI 4
#endif
#endif
Index: src/sys/arch/mips/include/intr.h
diff -u src/sys/arch/mips/include/intr.h:1.7 src/sys/arch/mips/include/intr.h:1.8
--- src/sys/arch/mips/include/intr.h:1.7 Sun Mar 11 00:02:05 2012
+++ src/sys/arch/mips/include/intr.h Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.7 2012/03/11 00:02:05 mrg Exp $ */
+/* $NetBSD: intr.h,v 1.8 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2009, 2010 The NetBSD Foundation, Inc.
@@ -72,7 +72,8 @@
#define IPI_SUSPEND 5 /* DDB suspend signaling */
#define IPI_HALT 6 /* halt cpu */
#define IPI_XCALL 7 /* xcall */
-#define NIPIS 8
+#define IPI_GENERIC 8 /* generic IPI */
+#define NIPIS 9
#ifdef __INTR_PRIVATE
struct splsw {
Index: src/sys/arch/mips/mips/cpu_subr.c
diff -u src/sys/arch/mips/mips/cpu_subr.c:1.16 src/sys/arch/mips/mips/cpu_subr.c:1.17
--- src/sys/arch/mips/mips/cpu_subr.c:1.16 Mon May 21 14:15:18 2012
+++ src/sys/arch/mips/mips/cpu_subr.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu_subr.c,v 1.16 2012/05/21 14:15:18 martin Exp $ */
+/* $NetBSD: cpu_subr.c,v 1.17 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.16 2012/05/21 14:15:18 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.17 2014/05/19 22:47:53 rmind Exp $");
#include "opt_ddb.h"
#include "opt_multiprocessor.h"
@@ -46,6 +46,7 @@ __KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v
#include <sys/bitops.h>
#include <sys/idle.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <uvm/uvm.h>
@@ -928,6 +929,13 @@ xc_send_ipi(struct cpu_info *ci)
(*mips_locoresw.lsw_send_ipi)(ci, IPI_XCALL);
}
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+ (*mips_locoresw.lsw_send_ipi)(ci, IPI_GENERIC);
+}
+
#endif /* MULTIPROCESSOR */
void
Index: src/sys/arch/mips/mips/ipifuncs.c
diff -u src/sys/arch/mips/mips/ipifuncs.c:1.6 src/sys/arch/mips/mips/ipifuncs.c:1.7
--- src/sys/arch/mips/mips/ipifuncs.c:1.6 Mon May 2 00:17:35 2011
+++ src/sys/arch/mips/mips/ipifuncs.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipifuncs.c,v 1.6 2011/05/02 00:17:35 matt Exp $ */
+/* $NetBSD: ipifuncs.c,v 1.7 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -32,13 +32,14 @@
#include "opt_ddb.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.6 2011/05/02 00:17:35 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.7 2014/05/19 22:47:53 rmind Exp $");
#include <sys/param.h>
#include <sys/cpu.h>
#include <sys/device.h>
#include <sys/intr.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <uvm/uvm_extern.h>
@@ -59,6 +60,7 @@ static const char * const ipi_names[] =
[IPI_SUSPEND] = "ipi suspend",
[IPI_HALT] = "ipi halt",
[IPI_XCALL] = "ipi xcall",
+ [IPI_GENERIC] = "ipi generic",
};
static void
@@ -139,6 +141,10 @@ ipi_process(struct cpu_info *ci, uint64_
ci->ci_evcnt_per_ipi[IPI_XCALL].ev_count++;
xc_ipi_handler();
}
+ if (ipi_mask & __BIT(IPI_GENERIC)) {
+ ci->ci_evcnt_per_ipi[IPI_GENERIC].ev_count++;
+ ipi_cpu_handler();
+ }
}
void
Index: src/sys/arch/powerpc/booke/e500_intr.c
diff -u src/sys/arch/powerpc/booke/e500_intr.c:1.23 src/sys/arch/powerpc/booke/e500_intr.c:1.24
--- src/sys/arch/powerpc/booke/e500_intr.c:1.23 Sat Mar 29 19:28:29 2014
+++ src/sys/arch/powerpc/booke/e500_intr.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: e500_intr.c,v 1.23 2014/03/29 19:28:29 christos Exp $ */
+/* $NetBSD: e500_intr.c,v 1.24 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -39,7 +39,7 @@
#define __INTR_PRIVATE
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.23 2014/03/29 19:28:29 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: e500_intr.c,v 1.24 2014/05/19 22:47:53 rmind Exp $");
#include <sys/param.h>
#include <sys/proc.h>
@@ -49,6 +49,7 @@ __KERNEL_RCSID(0, "$NetBSD: e500_intr.c,
#include <sys/atomic.h>
#include <sys/bus.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <sys/bitops.h>
#include <uvm/uvm_extern.h>
@@ -1217,6 +1218,7 @@ e500_ipi_kpreempt(void)
static const ipifunc_t e500_ipifuncs[] = {
[ilog2(IPI_XCALL)] = xc_ipi_handler,
+ [ilog2(IPI_GENERIC)] = ipi_cpu_handler,
[ilog2(IPI_HALT)] = e500_ipi_halt,
#ifdef __HAVE_PREEMPTION
[ilog2(IPI_KPREEMPT)] = e500_ipi_kpreempt,
Index: src/sys/arch/powerpc/include/booke/intr.h
diff -u src/sys/arch/powerpc/include/booke/intr.h:1.7 src/sys/arch/powerpc/include/booke/intr.h:1.8
--- src/sys/arch/powerpc/include/booke/intr.h:1.7 Sat Mar 29 19:28:29 2014
+++ src/sys/arch/powerpc/include/booke/intr.h Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.h,v 1.7 2014/03/29 19:28:29 christos Exp $ */
+/* $NetBSD: intr.h,v 1.8 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -73,6 +73,7 @@
#define IPI_XCALL 0x0002
#define IPI_KPREEMPT 0x0004
#define IPI_TLB1SYNC 0x0008
+#define IPI_GENERIC 0x0010
#define __HAVE_FAST_SOFTINTS 1
#define SOFTINT_KPREEMPT SOFTINT_COUNT
Index: src/sys/arch/powerpc/pic/ipi.c
diff -u src/sys/arch/powerpc/pic/ipi.c:1.10 src/sys/arch/powerpc/pic/ipi.c:1.11
--- src/sys/arch/powerpc/pic/ipi.c:1.10 Mon Jun 20 06:23:52 2011
+++ src/sys/arch/powerpc/pic/ipi.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipi.c,v 1.10 2011/06/20 06:23:52 matt Exp $ */
+/* $NetBSD: ipi.c,v 1.11 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.10 2011/06/20 06:23:52 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.11 2014/05/19 22:47:53 rmind Exp $");
#include "opt_multiprocessor.h"
#include "opt_pic.h"
@@ -39,6 +39,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.10
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <sys/atomic.h>
#include <sys/cpu.h>
@@ -71,6 +72,9 @@ ipi_intr(void *v)
if (ipi & IPI_XCALL)
xc_ipi_handler();
+ if (ipi & IPI_GENERIC)
+ ipi_cpu_handler();
+
if (ipi & IPI_HALT) {
aprint_normal("halting CPU %d\n", cpu_id);
msr = (mfmsr() & ~PSL_EE) | PSL_POW;
Index: src/sys/arch/powerpc/pic/ipivar.h
diff -u src/sys/arch/powerpc/pic/ipivar.h:1.6 src/sys/arch/powerpc/pic/ipivar.h:1.7
--- src/sys/arch/powerpc/pic/ipivar.h:1.6 Thu Oct 13 19:49:50 2011
+++ src/sys/arch/powerpc/pic/ipivar.h Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipivar.h,v 1.6 2011/10/13 19:49:50 matt Exp $ */
+/* $NetBSD: ipivar.h,v 1.7 2014/05/19 22:47:53 rmind Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
* All rights reserved.
@@ -29,7 +29,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipivar.h,v 1.6 2011/10/13 19:49:50 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipivar.h,v 1.7 2014/05/19 22:47:53 rmind Exp $");
#ifndef _IPI_VAR_H_
#define _IPI_VAR_H_
@@ -54,6 +54,7 @@ struct ipi_ops {
#define IPI_HALT 0x0001
#define IPI_XCALL 0x0002
#define IPI_KPREEMPT 0x0004
+#define IPI_GENERIC 0x0008
/* OpenPIC */
void setup_openpic_ipi(void);
Index: src/sys/arch/powerpc/powerpc/powerpc_machdep.c
diff -u src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.69 src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.70
--- src/sys/arch/powerpc/powerpc/powerpc_machdep.c:1.69 Mon Mar 24 19:14:31 2014
+++ src/sys/arch/powerpc/powerpc/powerpc_machdep.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: powerpc_machdep.c,v 1.69 2014/03/24 19:14:31 christos Exp $ */
+/* $NetBSD: powerpc_machdep.c,v 1.70 2014/05/19 22:47:53 rmind Exp $ */
/*
* Copyright (C) 1995, 1996 Wolfgang Solfrank.
@@ -32,7 +32,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.69 2014/03/24 19:14:31 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: powerpc_machdep.c,v 1.70 2014/05/19 22:47:53 rmind Exp $");
#include "opt_altivec.h"
#include "opt_modular.h"
@@ -56,6 +56,7 @@ __KERNEL_RCSID(0, "$NetBSD: powerpc_mach
#include <sys/atomic.h>
#include <sys/kmem.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <dev/mm.h>
@@ -488,6 +489,20 @@ xc_send_ipi(struct cpu_info *ci)
/* Broadcast: all, but local CPU (caller will handle it). */
cpu_send_ipi(target, IPI_XCALL);
}
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+ KASSERT(kpreempt_disabled());
+ KASSERT(curcpu() != ci);
+
+ cpuid_t target = (ci != NULL ? cpu_index(ci) : IPI_DST_NOTME);
+
+ /* Unicast: remote CPU. */
+ /* Broadcast: all, but local CPU (caller will handle it). */
+ cpu_send_ipi(target, IPI_GENERIC);
+}
+
#endif /* MULTIPROCESSOR */
#ifdef MODULAR
Index: src/sys/arch/sparc/sparc/cpu.c
diff -u src/sys/arch/sparc/sparc/cpu.c:1.244 src/sys/arch/sparc/sparc/cpu.c:1.245
--- src/sys/arch/sparc/sparc/cpu.c:1.244 Tue Apr 15 10:39:44 2014
+++ src/sys/arch/sparc/sparc/cpu.c Mon May 19 22:47:53 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.244 2014/04/15 10:39:44 macallan Exp $ */
+/* $NetBSD: cpu.c,v 1.245 2014/05/19 22:47:53 rmind Exp $ */
/*
* Copyright (c) 1996
@@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.244 2014/04/15 10:39:44 macallan Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.245 2014/05/19 22:47:53 rmind Exp $");
#include "opt_multiprocessor.h"
#include "opt_lockdebug.h"
@@ -62,10 +62,10 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.24
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/device.h>
-#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/evcnt.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <sys/cpu.h>
#include <uvm/uvm.h>
@@ -814,6 +814,21 @@ xc_send_ipi(struct cpu_info *target)
XCALL0(xc_ipi_handler, cpuset);
}
+void
+cpu_ipi(struct cpu_info *target)
+{
+ u_int cpuset;
+
+ KASSERT(kpreempt_disabled());
+ KASSERT(curcpu() != target);
+
+ if (target)
+ cpuset = 1 << target->ci_cpuid;
+ else
+ cpuset = CPUSET_ALL & ~(1 << cpuinfo.ci_cpuid);
+ XCALL0(ipi_cpu_handler, cpuset);
+}
+
/*
* Tell all CPUs other than the current one to enter the PROM idle loop.
*/
Index: src/sys/arch/sparc64/sparc64/ipifuncs.c
diff -u src/sys/arch/sparc64/sparc64/ipifuncs.c:1.47 src/sys/arch/sparc64/sparc64/ipifuncs.c:1.48
--- src/sys/arch/sparc64/sparc64/ipifuncs.c:1.47 Thu Nov 8 16:36:53 2012
+++ src/sys/arch/sparc64/sparc64/ipifuncs.c Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipifuncs.c,v 1.47 2012/11/08 16:36:53 nakayama Exp $ */
+/* $NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:54 rmind Exp $ */
/*-
* Copyright (c) 2004 The NetBSD Foundation, Inc.
@@ -27,14 +27,14 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.47 2012/11/08 16:36:53 nakayama Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipifuncs.c,v 1.48 2014/05/19 22:47:54 rmind Exp $");
#include "opt_ddb.h"
#include <sys/param.h>
#include <sys/systm.h>
-#include <sys/malloc.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <machine/db_machdep.h>
@@ -507,3 +507,10 @@ xc_send_ipi(struct cpu_info *target)
sparc64_generic_xcall(target, (ipi_c_call_func_t)xc_ipi_handler, NULL);
}
+
+void
+cpu_send_ipi(struct cpu_info *target)
+{
+
+ sparc64_generic_xcall(target, (ipi_c_call_func_t)ipi_cpu_handler, NULL);
+}
Index: src/sys/arch/vax/include/cpu.h
diff -u src/sys/arch/vax/include/cpu.h:1.98 src/sys/arch/vax/include/cpu.h:1.99
--- src/sys/arch/vax/include/cpu.h:1.98 Sun Nov 10 00:50:13 2013
+++ src/sys/arch/vax/include/cpu.h Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.98 2013/11/10 00:50:13 christos Exp $ */
+/* $NetBSD: cpu.h,v 1.99 2014/05/19 22:47:54 rmind Exp $ */
/*
* Copyright (c) 1994 Ludd, University of Lule}, Sweden
@@ -101,6 +101,7 @@ struct cpu_mp_dep {
#define IPI_TBIA 4 /* Flush the TLB */
#define IPI_DDB 5 /* Jump into the DDB loop */
#define IPI_XCALL 6 /* Helper for xcall(9) */
+#define IPI_GENERIC 7 /* Generic ipi(9) call */
#define IPI_DEST_MASTER -1 /* Destination is mastercpu */
#define IPI_DEST_ALL -2 /* Broadcast */
Index: src/sys/arch/vax/vax/multicpu.c
diff -u src/sys/arch/vax/vax/multicpu.c:1.32 src/sys/arch/vax/vax/multicpu.c:1.33
--- src/sys/arch/vax/vax/multicpu.c:1.32 Sun Jun 5 16:59:21 2011
+++ src/sys/arch/vax/vax/multicpu.c Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: multicpu.c,v 1.32 2011/06/05 16:59:21 matt Exp $ */
+/* $NetBSD: multicpu.c,v 1.33 2014/05/19 22:47:54 rmind Exp $ */
/*
* Copyright (c) 2000 Ludd, University of Lule}, Sweden. All rights reserved.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: multicpu.c,v 1.32 2011/06/05 16:59:21 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: multicpu.c,v 1.33 2014/05/19 22:47:54 rmind Exp $");
#include "opt_multiprocessor.h"
@@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: multicpu.c,v
#include <sys/malloc.h>
#include <sys/proc.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <uvm/uvm_extern.h>
@@ -198,6 +199,9 @@ cpu_handle_ipi(void)
case IPI_XCALL:
xc_ipi_handler();
break;
+ case IPI_GENERIC:
+ ipi_cpu_handler();
+ break;
default:
panic("cpu_handle_ipi: bad bit %x", bitno);
}
@@ -212,7 +216,6 @@ cpu_handle_ipi(void)
void
xc_send_ipi(struct cpu_info *ci)
{
-
KASSERT(kpreempt_disabled());
KASSERT(curcpu() != ci);
@@ -224,3 +227,18 @@ xc_send_ipi(struct cpu_info *ci)
cpu_send_ipi(IPI_DEST_ALL, IPI_XCALL);
}
}
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+ KASSERT(kpreempt_disabled());
+ KASSERT(curcpu() != ci);
+
+ if (ci) {
+ /* Unicast: remote CPU. */
+ cpu_send_ipi(ci->ci_cpuid, IPI_GENERIC);
+ } else {
+ /* Broadcast: all, but local CPU (caller will handle it). */
+ cpu_send_ipi(IPI_DEST_ALL, IPI_GENERIC);
+ }
+}
Index: src/sys/arch/x86/include/intrdefs.h
diff -u src/sys/arch/x86/include/intrdefs.h:1.19 src/sys/arch/x86/include/intrdefs.h:1.20
--- src/sys/arch/x86/include/intrdefs.h:1.19 Sun Dec 1 01:05:16 2013
+++ src/sys/arch/x86/include/intrdefs.h Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: intrdefs.h,v 1.19 2013/12/01 01:05:16 christos Exp $ */
+/* $NetBSD: intrdefs.h,v 1.20 2014/05/19 22:47:54 rmind Exp $ */
#ifndef _X86_INTRDEFS_H_
#define _X86_INTRDEFS_H_
@@ -60,7 +60,7 @@
#define X86_IPI_HALT 0x00000001
#define X86_IPI_MICROSET 0x00000002
-#define X86_IPI__UNUSED1 0x00000004
+#define X86_IPI_GENERIC 0x00000004
#define X86_IPI_SYNCH_FPU 0x00000008
#define X86_IPI_MTRR 0x00000010
#define X86_IPI_GDT 0x00000020
@@ -70,7 +70,7 @@
#define X86_NIPI 9
-#define X86_IPI_NAMES { "halt IPI", "timeset IPI", "unused", \
+#define X86_IPI_NAMES { "halt IPI", "timeset IPI", "generic IPI", \
"FPU synch IPI", "MTRR update IPI", \
"GDT update IPI", "xcall IPI", \
"ACPI CPU sleep IPI", "kpreempt IPI" }
Index: src/sys/arch/x86/x86/ipi.c
diff -u src/sys/arch/x86/x86/ipi.c:1.23 src/sys/arch/x86/x86/ipi.c:1.24
--- src/sys/arch/x86/x86/ipi.c:1.23 Wed Feb 19 21:23:02 2014
+++ src/sys/arch/x86/x86/ipi.c Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: ipi.c,v 1.23 2014/02/19 21:23:02 dsl Exp $ */
+/* $NetBSD: ipi.c,v 1.24 2014/05/19 22:47:54 rmind Exp $ */
/*-
* Copyright (c) 2000, 2008, 2009 The NetBSD Foundation, Inc.
@@ -32,18 +32,19 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.23 2014/02/19 21:23:02 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.24 2014/05/19 22:47:54 rmind Exp $");
#include "opt_mtrr.h"
-#include <sys/param.h>
+#include <sys/param.h>
#include <sys/device.h>
#include <sys/systm.h>
#include <sys/atomic.h>
#include <sys/intr.h>
+#include <sys/ipi.h>
#include <sys/cpu.h>
#include <sys/xcall.h>
-
+
#ifdef MULTIPROCESSOR
#include <machine/cpufunc.h>
@@ -61,6 +62,7 @@ __KERNEL_RCSID(0, "$NetBSD: ipi.c,v 1.23
static void x86_ipi_halt(struct cpu_info *);
static void x86_ipi_kpreempt(struct cpu_info *);
static void x86_ipi_xcall(struct cpu_info *);
+static void x86_ipi_generic(struct cpu_info *);
#ifdef MTRR
static void x86_ipi_reload_mtrr(struct cpu_info *);
@@ -80,7 +82,7 @@ void (*ipifunc[X86_NIPI])(struct cpu_inf
{
x86_ipi_halt,
NULL,
- NULL,
+ x86_ipi_generic,
x86_ipi_synch_fpu,
x86_ipi_reload_mtrr,
gdt_reload_cpu,
@@ -206,10 +208,15 @@ x86_ipi_kpreempt(struct cpu_info *ci)
static void
x86_ipi_xcall(struct cpu_info *ci)
{
-
xc_ipi_handler();
}
+static void
+x86_ipi_generic(struct cpu_info *ci)
+{
+ ipi_cpu_handler();
+}
+
void
xc_send_ipi(struct cpu_info *ci)
{
@@ -226,6 +233,21 @@ xc_send_ipi(struct cpu_info *ci)
}
}
+void
+cpu_ipi(struct cpu_info *ci)
+{
+ KASSERT(kpreempt_disabled());
+ KASSERT(curcpu() != ci);
+
+ if (ci) {
+ /* Unicast: remote CPU. */
+ x86_send_ipi(ci, X86_IPI_GENERIC);
+ } else {
+ /* Broadcast: all, but local CPU (caller will handle it). */
+ x86_broadcast_ipi(X86_IPI_GENERIC);
+ }
+}
+
#else
int
@@ -241,4 +263,9 @@ x86_broadcast_ipi(int ipimask)
}
+void
+cpu_ipi(struct cpu_info *ci)
+{
+}
+
#endif
Index: src/sys/arch/xen/include/intrdefs.h
diff -u src/sys/arch/xen/include/intrdefs.h:1.11 src/sys/arch/xen/include/intrdefs.h:1.12
--- src/sys/arch/xen/include/intrdefs.h:1.11 Mon Nov 7 15:51:31 2011
+++ src/sys/arch/xen/include/intrdefs.h Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: intrdefs.h,v 1.11 2011/11/07 15:51:31 cherry Exp $ */
+/* $NetBSD: intrdefs.h,v 1.12 2014/05/19 22:47:54 rmind Exp $ */
/* This file co-exists, and is included via machine/intrdefs.h */
@@ -12,7 +12,9 @@
#define XEN_IPI_DDB 0x00000004
#define XEN_IPI_XCALL 0x00000008
#define XEN_IPI_HVCB 0x00000010
+#define XEN_IPI_GENERIC 0x00000020
-#define XEN_NIPIS 5 /* IPI_KICK doesn't have a handler */
+/* Note: IPI_KICK does not have a handler. */
+#define XEN_NIPIS 6
#endif /* _XEN_INTRDEFS_H_ */
Index: src/sys/arch/xen/x86/xen_ipi.c
diff -u src/sys/arch/xen/x86/xen_ipi.c:1.17 src/sys/arch/xen/x86/xen_ipi.c:1.18
--- src/sys/arch/xen/x86/xen_ipi.c:1.17 Wed Feb 12 23:24:09 2014
+++ src/sys/arch/xen/x86/xen_ipi.c Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: xen_ipi.c,v 1.17 2014/02/12 23:24:09 dsl Exp $ */
+/* $NetBSD: xen_ipi.c,v 1.18 2014/05/19 22:47:54 rmind Exp $ */
/*-
* Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -33,10 +33,10 @@
/*
* Based on: x86/ipi.c
- * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.17 2014/02/12 23:24:09 dsl Exp $");
+ * __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.18 2014/05/19 22:47:54 rmind Exp $");
*/
-__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.17 2014/02/12 23:24:09 dsl Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v 1.18 2014/05/19 22:47:54 rmind Exp $");
#include <sys/types.h>
@@ -45,6 +45,7 @@ __KERNEL_RCSID(0, "$NetBSD: xen_ipi.c,v
#include <sys/mutex.h>
#include <sys/device.h>
#include <sys/xcall.h>
+#include <sys/ipi.h>
#include <sys/errno.h>
#include <sys/systm.h>
@@ -69,6 +70,7 @@ static void xen_ipi_synch_fpu(struct cpu
static void xen_ipi_ddb(struct cpu_info *, struct intrframe *);
static void xen_ipi_xcall(struct cpu_info *, struct intrframe *);
static void xen_ipi_hvcb(struct cpu_info *, struct intrframe *);
+static void xen_ipi_generic(struct cpu_info *, struct intrframe *);
static void (*ipifunc[XEN_NIPIS])(struct cpu_info *, struct intrframe *) =
{ /* In order of priority (see: xen/include/intrdefs.h */
@@ -76,7 +78,8 @@ static void (*ipifunc[XEN_NIPIS])(struct
xen_ipi_synch_fpu,
xen_ipi_ddb,
xen_ipi_xcall,
- xen_ipi_hvcb
+ xen_ipi_hvcb,
+ xen_ipi_generic,
};
static void
@@ -131,7 +134,7 @@ xen_ipi_init(void)
static inline bool /* helper */
valid_ipimask(uint32_t ipimask)
{
- uint32_t masks = XEN_IPI_HVCB | XEN_IPI_XCALL |
+ uint32_t masks = XEN_IPI_GENERIC | XEN_IPI_HVCB | XEN_IPI_XCALL |
XEN_IPI_DDB | XEN_IPI_SYNCH_FPU |
XEN_IPI_HALT | XEN_IPI_KICK;
@@ -285,6 +288,29 @@ xc_send_ipi(struct cpu_info *ci)
}
static void
+xen_ipi_generic(struct cpu_info *ci, struct intrframe *intrf)
+{
+ KASSERT(ci != NULL);
+ KASSERT(intrf != NULL);
+
+ ipi_cpu_handler();
+}
+
+void
+cpu_ipi(struct cpu_info *ci)
+{
+ KASSERT(kpreempt_disabled());
+ KASSERT(curcpu() != ci);
+ if (ci) {
+ if (0 != xen_send_ipi(ci, XEN_IPI_GENERIC)) {
+ panic("xen_send_ipi(XEN_IPI_GENERIC) failed\n");
+ }
+ } else {
+ xen_broadcast_ipi(XEN_IPI_GENERIC);
+ }
+}
+
+static void
xen_ipi_hvcb(struct cpu_info *ci, struct intrframe *intrf)
{
KASSERT(ci != NULL);
Index: src/sys/conf/files
diff -u src/sys/conf/files:1.1090 src/sys/conf/files:1.1091
--- src/sys/conf/files:1.1090 Tue Apr 1 17:49:30 2014
+++ src/sys/conf/files Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-# $NetBSD: files,v 1.1090 2014/04/01 17:49:30 riastradh Exp $
+# $NetBSD: files,v 1.1091 2014/05/19 22:47:54 rmind Exp $
# @(#)files.newconf 7.5 (Berkeley) 5/10/93
version 20100430
@@ -1598,6 +1598,7 @@ file kern/subr_extent.c
file kern/subr_hash.c
file kern/subr_humanize.c
file kern/subr_iostat.c
+file kern/subr_ipi.c
file kern/subr_kcpuset.c
file kern/subr_kmem.c
file kern/subr_kobj.c
Index: src/sys/kern/init_main.c
diff -u src/sys/kern/init_main.c:1.454 src/sys/kern/init_main.c:1.455
--- src/sys/kern/init_main.c:1.454 Wed Oct 2 21:38:55 2013
+++ src/sys/kern/init_main.c Mon May 19 22:47:54 2014
@@ -1,4 +1,4 @@
-/* $NetBSD: init_main.c,v 1.454 2013/10/02 21:38:55 apb Exp $ */
+/* $NetBSD: init_main.c,v 1.455 2014/05/19 22:47:54 rmind Exp $ */
/*-
* Copyright (c) 2008, 2009 The NetBSD Foundation, Inc.
@@ -97,7 +97,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.454 2013/10/02 21:38:55 apb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.455 2014/05/19 22:47:54 rmind Exp $");
#include "opt_ddb.h"
#include "opt_ipsec.h"
@@ -157,6 +157,7 @@ __KERNEL_RCSID(0, "$NetBSD: init_main.c,
#include <sys/mbuf.h>
#include <sys/sched.h>
#include <sys/sleepq.h>
+#include <sys/ipi.h>
#include <sys/iostat.h>
#include <sys/vmem.h>
#include <sys/uuid.h>
@@ -307,6 +308,7 @@ main(void)
uvm_init();
kcpuset_sysinit();
+ ipi_sysinit();
prop_kern_init();
Added files:
Index: src/sys/kern/subr_ipi.c
diff -u /dev/null src/sys/kern/subr_ipi.c:1.1
--- /dev/null Mon May 19 22:47:54 2014
+++ src/sys/kern/subr_ipi.c Mon May 19 22:47:54 2014
@@ -0,0 +1,238 @@
+/* $NetBSD: subr_ipi.c,v 1.1 2014/05/19 22:47:54 rmind Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mindaugas Rasiukevicius.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+/*
+ * Inter-processor interrupt (IPI) interface with cross-call support.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: subr_ipi.c,v 1.1 2014/05/19 22:47:54 rmind Exp $");
+
+#include <sys/param.h>
+#include <sys/types.h>
+
+#include <sys/atomic.h>
+#include <sys/evcnt.h>
+#include <sys/cpu.h>
+#include <sys/ipi.h>
+#include <sys/kcpuset.h>
+#include <sys/kmem.h>
+#include <sys/lock.h>
+
+/*
+ * Per-CPU mailbox for IPI messages: it is a single cache line storing
+ * up to IPI_MSG_MAX messages.
+ */
+
+#define IPI_MSG_SLOTS (CACHE_LINE_SIZE / sizeof(ipi_msg_t *))
+#define IPI_MSG_MAX IPI_MSG_SLOTS
+
+typedef struct {
+ ipi_msg_t * msg[IPI_MSG_SLOTS];
+} ipi_mbox_t;
+
+static ipi_mbox_t * ipi_mboxes __read_mostly;
+static struct evcnt ipi_mboxfull_ev __cacheline_aligned;
+
+#ifndef MULTIPROCESSOR
+#define cpu_ipi(ci) KASSERT(ci == NULL)
+#endif
+
+void
+ipi_sysinit(void)
+{
+ const size_t len = ncpu * sizeof(ipi_mbox_t);
+
+ /* Allocate per-CPU IPI mailboxes. */
+ ipi_mboxes = kmem_zalloc(len, KM_SLEEP);
+ KASSERT(ipi_mboxes != NULL);
+
+ evcnt_attach_dynamic(&ipi_mboxfull_ev, EVCNT_TYPE_MISC, NULL,
+ "ipi", "full");
+}
+
+/*
+ * put_msg: insert message into the mailbox.
+ */
+static inline void
+put_msg(ipi_mbox_t *mbox, ipi_msg_t *msg)
+{
+ int count = SPINLOCK_BACKOFF_MIN;
+again:
+ for (u_int i = 0; i < IPI_MSG_MAX; i++) {
+ if (__predict_true(mbox->msg[i] == NULL) &&
+ atomic_cas_ptr(&mbox->msg[i], NULL, msg) == NULL) {
+ return;
+ }
+ }
+
+ /* All slots are full: we have to spin-wait. */
+ ipi_mboxfull_ev.ev_count++;
+ SPINLOCK_BACKOFF(count);
+ goto again;
+}
+
+/*
+ * ipi_cpu_handler: the IPI handler.
+ */
+void
+ipi_cpu_handler(void)
+{
+ const struct cpu_info * const ci = curcpu();
+ ipi_mbox_t *mbox = &ipi_mboxes[cpu_index(ci)];
+
+ KASSERT(curcpu() == ci);
+
+ for (u_int i = 0; i < IPI_MSG_MAX; i++) {
+ ipi_msg_t *msg;
+
+ /* Get the message. */
+ if ((msg = mbox->msg[i]) == NULL) {
+ continue;
+ }
+ mbox->msg[i] = NULL;
+
+ /* Execute the handler. */
+ KASSERT(msg->func);
+ msg->func(msg->arg);
+
+ /* Ack the request. */
+ atomic_dec_uint(&msg->_pending);
+ }
+}
+
+/*
+ * ipi_unicast: send an IPI to a single CPU.
+ *
+ * => The CPU must be remote; must not be local.
+ * => The caller must ipi_wait() on the message for completion.
+ */
+void
+ipi_unicast(ipi_msg_t *msg, struct cpu_info *ci)
+{
+ const cpuid_t id = cpu_index(ci);
+
+ KASSERT(msg->func != NULL);
+ KASSERT(kpreempt_disabled());
+ KASSERT(curcpu() != ci);
+
+ msg->_pending = 1;
+ membar_producer();
+
+ put_msg(&ipi_mboxes[id], msg);
+ cpu_ipi(ci);
+}
+
+/*
+ * ipi_multicast: send an IPI to each CPU in the specified set.
+ *
+ * => The caller must ipi_wait() on the message for completion.
+ */
+void
+ipi_multicast(ipi_msg_t *msg, const kcpuset_t *target)
+{
+ const struct cpu_info * const self = curcpu();
+ CPU_INFO_ITERATOR cii;
+ struct cpu_info *ci;
+ u_int local;
+
+ KASSERT(msg->func != NULL);
+ KASSERT(kpreempt_disabled());
+
+ local = !!kcpuset_isset(target, cpu_index(self));
+ msg->_pending = kcpuset_countset(target) - local;
+ membar_producer();
+
+ for (CPU_INFO_FOREACH(cii, ci)) {
+ cpuid_t id;
+
+ if (__predict_false(ci == self)) {
+ continue;
+ }
+ id = cpu_index(ci);
+ if (!kcpuset_isset(target, id)) {
+ continue;
+ }
+ put_msg(&ipi_mboxes[id], msg);
+ cpu_ipi(ci);
+ }
+ if (local) {
+ msg->func(msg->arg);
+ }
+}
+
+/*
+ * ipi_broadcast: send an IPI to all CPUs.
+ *
+ * => The caller must ipi_wait() on the message for completion.
+ */
+void
+ipi_broadcast(ipi_msg_t *msg)
+{
+ const struct cpu_info * const self = curcpu();
+ CPU_INFO_ITERATOR cii;
+ struct cpu_info *ci;
+
+ KASSERT(msg->func != NULL);
+ KASSERT(kpreempt_disabled());
+
+ msg->_pending = ncpu - 1;
+ membar_producer();
+
+ /* Broadcast IPIs for remote CPUs. */
+ for (CPU_INFO_FOREACH(cii, ci)) {
+ cpuid_t id;
+
+ if (__predict_false(ci == self)) {
+ continue;
+ }
+ id = cpu_index(ci);
+ put_msg(&ipi_mboxes[id], msg);
+ }
+ cpu_ipi(NULL);
+
+ /* Finally, execute locally. */
+ msg->func(msg->arg);
+}
+
+/*
+ * ipi_wait: spin-wait until the message is processed.
+ */
+void
+ipi_wait(ipi_msg_t *msg)
+{
+ int count = SPINLOCK_BACKOFF_MIN;
+
+ while (msg->_pending) {
+ KASSERT(msg->_pending < ncpu);
+ SPINLOCK_BACKOFF(count);
+ }
+}
Index: src/sys/sys/ipi.h
diff -u /dev/null src/sys/sys/ipi.h:1.1
--- /dev/null Mon May 19 22:47:54 2014
+++ src/sys/sys/ipi.h Mon May 19 22:47:54 2014
@@ -0,0 +1,62 @@
+/* $NetBSD: ipi.h,v 1.1 2014/05/19 22:47:54 rmind Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Mindaugas Rasiukevicius.
+ *
+ * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 _SYS_IPI_H_
+#define _SYS_IPI_H_
+
+#if !defined(_KERNEL) && !defined(_KMEMUSER)
+#error "not supposed to be exposed to userland"
+#endif
+
+typedef void (*ipi_func_t)(void *);
+
+typedef struct {
+ /* Public: function handler and an argument. */
+ ipi_func_t func;
+ void * arg;
+
+ /* Private (internal) elements. */
+ volatile u_int _pending;
+} ipi_msg_t;
+
+void ipi_sysinit(void);
+void ipi_cpu_handler(void);
+void cpu_ipi(struct cpu_info *);
+
+/*
+ * Public ipi(9) API.
+ */
+void ipi_unicast(ipi_msg_t *, struct cpu_info *);
+void ipi_multicast(ipi_msg_t *, const kcpuset_t *);
+void ipi_broadcast(ipi_msg_t *);
+void ipi_wait(ipi_msg_t *);
+
+#endif