Module Name: src
Committed By: riz
Date: Tue Mar 8 17:29:46 UTC 2011
Modified Files:
src/sys/arch/sparc/dev [netbsd-5]: zs.c
src/sys/arch/sparc/include [netbsd-5]: cpu.h z8530var.h
src/sys/arch/sparc/sparc [netbsd-5]: cpu.c cpuvar.h db_interface.c
genassym.cf intr.c locore.s machdep.c timer.c timer_sun4m.c
timervar.h trap.c vm_machdep.c
Log Message:
Apply patches (requested by mrg in ticket #1564):
sys/arch/sparc/dev/zs.c: patch
sys/arch/sparc/include/cpu.h: patch
sys/arch/sparc/include/z8530var.h: patch
sys/arch/sparc/sparc/cpu.c: patch
sys/arch/sparc/sparc/cpuvar.h: patch
sys/arch/sparc/sparc/db_interface.c: patch
sys/arch/sparc/sparc/genassym.cf: patch
sys/arch/sparc/sparc/intr.c: patch
sys/arch/sparc/sparc/locore.s: patch
sys/arch/sparc/sparc/machdep.c: patch
sys/arch/sparc/sparc/timer.c: patch
sys/arch/sparc/sparc/timer_sun4m.c: patch
sys/arch/sparc/sparc/timervar.h: patch
sys/arch/sparc/sparc/trap.c: patch
sys/arch/sparc/sparc/vm_machdep.c: patch
- fix a panic in savefpstate. idea, and code suggestions from uwe
- convert xpmsg_lock to IPL_SCHED. the old spl/simple_lock code ran at
splsched(), and this significantly helps with stability under load when
running with multiple active CPUs
- in strayintr() don't print about stray zs inters in MP case
- fix a deadlock in xcall()
- consolidate the interrupt evcnt(9) into a full set of per-IPL per-CPU
soft/hard counters
- fix xcall() failure messages in some cases
- addd new ddb command "mach xcall"
- use schedintr() (not schedintr_4m()) on MP or single CPU configurations
- call hardclock() the same way on cpu0 in MP and !MP cases
- request the appropriate stack space for nmi_sun4m, in particular,
make sure we have space for %g2...%g5. now entering ddb via eg,
serial break no longer causes cpu1 to fault.
- give memfault_sun*() some entry points that both gdb and ddb will find.
from tsutsui:
- fix panic in interrupt handlers in zs
To generate a diff of this commit:
cvs rdiff -u -r1.111.6.3 -r1.111.6.4 src/sys/arch/sparc/dev/zs.c
cvs rdiff -u -r1.84.14.1 -r1.84.14.2 src/sys/arch/sparc/include/cpu.h
cvs rdiff -u -r1.9 -r1.9.14.1 src/sys/arch/sparc/include/z8530var.h
cvs rdiff -u -r1.211.8.4 -r1.211.8.5 src/sys/arch/sparc/sparc/cpu.c
cvs rdiff -u -r1.75.10.4 -r1.75.10.5 src/sys/arch/sparc/sparc/cpuvar.h
cvs rdiff -u -r1.79.4.2 -r1.79.4.3 src/sys/arch/sparc/sparc/db_interface.c
cvs rdiff -u -r1.56.4.1 -r1.56.4.2 src/sys/arch/sparc/sparc/genassym.cf
cvs rdiff -u -r1.100.20.2 -r1.100.20.3 src/sys/arch/sparc/sparc/intr.c
cvs rdiff -u -r1.244.8.3 -r1.244.8.4 src/sys/arch/sparc/sparc/locore.s
cvs rdiff -u -r1.282.4.3 -r1.282.4.4 src/sys/arch/sparc/sparc/machdep.c
cvs rdiff -u -r1.23 -r1.23.28.1 src/sys/arch/sparc/sparc/timer.c
cvs rdiff -u -r1.16.56.2 -r1.16.56.3 src/sys/arch/sparc/sparc/timer_sun4m.c
cvs rdiff -u -r1.8 -r1.8.74.1 src/sys/arch/sparc/sparc/timervar.h
cvs rdiff -u -r1.176 -r1.176.4.1 src/sys/arch/sparc/sparc/trap.c
cvs rdiff -u -r1.95.4.2 -r1.95.4.3 src/sys/arch/sparc/sparc/vm_machdep.c
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/sparc/dev/zs.c
diff -u src/sys/arch/sparc/dev/zs.c:1.111.6.3 src/sys/arch/sparc/dev/zs.c:1.111.6.4
--- src/sys/arch/sparc/dev/zs.c:1.111.6.3 Sun Jan 16 12:54:42 2011
+++ src/sys/arch/sparc/dev/zs.c Tue Mar 8 17:29:45 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: zs.c,v 1.111.6.3 2011/01/16 12:54:42 bouyer Exp $ */
+/* $NetBSD: zs.c,v 1.111.6.4 2011/03/08 17:29:45 riz Exp $ */
/*-
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.111.6.3 2011/01/16 12:54:42 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: zs.c,v 1.111.6.4 2011/03/08 17:29:45 riz Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -171,12 +171,8 @@
extern struct cfdriver zs_cd;
-/* softintr(9) cookie, shared by all instances of this driver */
-static void *zs_sicookie;
-
/* Interrupt handlers. */
static int zshard(void *);
-static void zssoft(void *);
static int zs_get_speed(struct zs_chanstate *);
@@ -396,7 +392,6 @@
struct zsc_attach_args zsc_args;
struct zs_chanstate *cs;
int channel;
- static int didintr, prevpri;
#if (NKBD > 0) || (NMS > 0)
int ch0_is_cons = 0;
#endif
@@ -407,12 +402,11 @@
return;
}
- if (!didintr) {
- zs_sicookie = softint_establish(SOFTINT_SERIAL, zssoft, NULL);
- if (zs_sicookie == NULL) {
- aprint_error(": cannot establish soft int handler\n");
- return;
- }
+ zsc->zsc_sicookie = softint_establish(SOFTINT_SERIAL,
+ (void (*)(void *))zsc_intr_soft, zsc);
+ if (zsc->zsc_sicookie == NULL) {
+ aprint_error(": cannot establish soft int handler\n");
+ return;
}
aprint_normal(" softpri %d\n", IPL_SOFTSERIAL);
@@ -551,17 +545,9 @@
}
/*
- * Now safe to install interrupt handlers. Note the arguments
- * to the interrupt handlers aren't used. Note, we only do this
- * once since both SCCs interrupt at the same level and vector.
+ * Now safe to install interrupt handlers.
*/
- if (!didintr) {
- didintr = 1;
- prevpri = pri;
- bus_intr_establish(zsc->zsc_bustag, pri, IPL_SERIAL,
- zshard, NULL);
- } else if (pri != prevpri)
- panic("broken zs interrupt scheme");
+ bus_intr_establish(zsc->zsc_bustag, pri, IPL_SERIAL, zshard, zsc);
evcnt_attach_dynamic(&zsc->zsc_intrcnt, EVCNT_TYPE_INTR, NULL,
device_xname(zsc->zsc_dev), "intr");
@@ -610,81 +596,29 @@
static volatile int zssoftpending;
/*
- * Our ZS chips all share a common, autovectored interrupt,
- * so we have to look at all of them on each interrupt.
+ * Our ZS chips all share a common interrupt level,
+ * but we establish zshard handler per each ZS chips
+ * to avoid holding unnecessary locks in interrupt context.
*/
static int
zshard(void *arg)
{
- struct zsc_softc *zsc;
- int unit, rr3, rval, softreq;
+ struct zsc_softc *zsc = arg;
+ int rr3, rval;
- rval = softreq = 0;
- for (unit = 0; unit < zs_cd.cd_ndevs; unit++) {
- struct zs_chanstate *cs;
-
- zsc = device_lookup_private(&zs_cd, unit);
- if (zsc == NULL)
- continue;
- rr3 = zsc_intr_hard(zsc);
- /* Count up the interrupts. */
- if (rr3) {
- rval |= rr3;
- zsc->zsc_intrcnt.ev_count++;
- }
- if ((cs = zsc->zsc_cs[0]) != NULL)
- softreq |= cs->cs_softreq;
- if ((cs = zsc->zsc_cs[1]) != NULL)
- softreq |= cs->cs_softreq;
- }
-
- /* We are at splzs here, so no need to lock. */
- if (softreq && (zssoftpending == 0)) {
- zssoftpending = 1;
- softint_schedule(zs_sicookie);
+ rval = 0;
+ rr3 = zsc_intr_hard(zsc);
+ /* Count up the interrupts. */
+ if (rr3) {
+ rval = rr3;
+ zsc->zsc_intrcnt.ev_count++;
}
+ if (zsc->zsc_cs[0]->cs_softreq || zsc->zsc_cs[1]->cs_softreq)
+ softint_schedule(zsc->zsc_sicookie);
return (rval);
}
/*
- * Similar scheme as for zshard (look at all of them)
- */
-static void
-zssoft(void *arg)
-{
- struct zsc_softc *zsc;
- int unit;
-
- /* This is not the only ISR on this IPL. */
- if (zssoftpending == 0)
- return;
-
- /*
- * The soft intr. bit will be set by zshard only if
- * the variable zssoftpending is zero. The order of
- * these next two statements prevents our clearing
- * the soft intr bit just after zshard has set it.
- */
- /* ienab_bic(IE_ZSSOFT); */
- zssoftpending = 0;
-
-#if 0 /* not yet */
- /* Make sure we call the tty layer with tty_lock held. */
- mutex_spin_enter(&tty_lock);
-#endif
- for (unit = 0; unit < zs_cd.cd_ndevs; unit++) {
- zsc = device_lookup_private(&zs_cd, unit);
- if (zsc == NULL)
- continue;
- (void)zsc_intr_soft(zsc);
- }
-#if 0 /* not yet */
- mutex_spin_exit(&tty_lock);
-#endif
-}
-
-
-/*
* Compute the current baud rate given a ZS channel.
*/
static int
Index: src/sys/arch/sparc/include/cpu.h
diff -u src/sys/arch/sparc/include/cpu.h:1.84.14.1 src/sys/arch/sparc/include/cpu.h:1.84.14.2
--- src/sys/arch/sparc/include/cpu.h:1.84.14.1 Sat Jan 9 01:43:51 2010
+++ src/sys/arch/sparc/include/cpu.h Tue Mar 8 17:29:45 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.h,v 1.84.14.1 2010/01/09 01:43:51 snj Exp $ */
+/* $NetBSD: cpu.h,v 1.84.14.2 2011/03/08 17:29:45 riz Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -191,6 +191,7 @@
/* locore.s */
struct fpstate;
+void ipi_savefpstate(struct fpstate *);
void savefpstate(struct fpstate *);
void loadfpstate(struct fpstate *);
int probeget(void *, int);
Index: src/sys/arch/sparc/include/z8530var.h
diff -u src/sys/arch/sparc/include/z8530var.h:1.9 src/sys/arch/sparc/include/z8530var.h:1.9.14.1
--- src/sys/arch/sparc/include/z8530var.h:1.9 Sat Mar 29 19:15:35 2008
+++ src/sys/arch/sparc/include/z8530var.h Tue Mar 8 17:29:45 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: z8530var.h,v 1.9 2008/03/29 19:15:35 tsutsui Exp $ */
+/* $NetBSD: z8530var.h,v 1.9.14.1 2011/03/08 17:29:45 riz Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -54,6 +54,7 @@
int zsc_node; /* PROM node, if any */
struct evcnt zsc_intrcnt; /* count interrupts */
struct zs_chanstate zsc_cs_store[2];
+ void *zsc_sicookie; /* softint(9) cookie */
};
/*
Index: src/sys/arch/sparc/sparc/cpu.c
diff -u src/sys/arch/sparc/sparc/cpu.c:1.211.8.4 src/sys/arch/sparc/sparc/cpu.c:1.211.8.5
--- src/sys/arch/sparc/sparc/cpu.c:1.211.8.4 Wed Feb 16 21:33:25 2011
+++ src/sys/arch/sparc/sparc/cpu.c Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: cpu.c,v 1.211.8.4 2011/02/16 21:33:25 bouyer Exp $ */
+/* $NetBSD: cpu.c,v 1.211.8.5 2011/03/08 17:29:46 riz Exp $ */
/*
* Copyright (c) 1996
@@ -52,7 +52,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.211.8.4 2011/02/16 21:33:25 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.211.8.5 2011/03/08 17:29:46 riz Exp $");
#include "opt_multiprocessor.h"
#include "opt_lockdebug.h"
@@ -65,6 +65,8 @@
#include <sys/malloc.h>
#include <sys/simplelock.h>
#include <sys/kernel.h>
+#include <sys/evcnt.h>
+#include <sys/cpu.h>
#include <uvm/uvm.h>
@@ -78,6 +80,7 @@
#include <machine/pmap.h>
#if defined(MULTIPROCESSOR) && defined(DDB)
+#include <ddb/db_output.h>
#include <machine/db_machdep.h>
#endif
@@ -119,6 +122,7 @@
cpu_cpuunit_match, cpu_cpuunit_attach, NULL, NULL);
#endif /* SUN4D */
+static void cpu_init_evcnt(struct cpu_info *cpi);
static void cpu_attach(struct cpu_softc *, int, int);
static const char *fsrtoname(int, int, int);
@@ -293,6 +297,71 @@
}
#endif /* SUN4D */
+static const char * const hard_intr_names[] = {
+ "spur hard",
+ "lev1 hard",
+ "lev2 hard",
+ "lev3 hard",
+ "lev4 hard",
+ "lev5 hard",
+ "lev6 hard",
+ "lev7 hard",
+ "lev8 hard",
+ "lev9 hard",
+ "clock hard",
+ "lev11 hard",
+ "lev12 hard",
+ "lev13 hard",
+ "prof hard",
+ "nmi hard",
+};
+
+static const char * const soft_intr_names[] = {
+ "spur soft",
+ "lev1 soft",
+ "lev2 soft",
+ "lev3 soft",
+ "lev4 soft",
+ "lev5 soft",
+ "lev6 soft",
+ "lev7 soft",
+ "lev8 soft",
+ "lev9 soft",
+ "lev10 soft",
+ "lev11 soft",
+ "lev12 soft",
+ "xcall std",
+ "xcall fast",
+ "nmi soft",
+};
+
+static void
+cpu_init_evcnt(struct cpu_info *cpi)
+{
+ int i;
+
+ /*
+ * Setup the per-cpu counters.
+ */
+ snprintf(cpi->ci_cpuname, sizeof(cpi->ci_cpuname), "cpu/%d", cpi->ci_cpuid);
+ evcnt_attach_dynamic(&cpi->ci_savefpstate, EVCNT_TYPE_MISC,
+ NULL, cpi->ci_cpuname, "savefp ipi");
+ evcnt_attach_dynamic(&cpi->ci_xpmsg_mutex_fail, EVCNT_TYPE_MISC,
+ NULL, cpi->ci_cpuname, "IPI mutex_trylock fail");
+ evcnt_attach_dynamic(&cpi->ci_xpmsg_mutex_fail_call, EVCNT_TYPE_MISC,
+ NULL, cpi->ci_cpuname, "IPI mutex_trylock fail/call");
+
+ /*
+ * These are the per-cpu per-IPL hard & soft interrupt counters.
+ */
+ for (i = 0; i < 16; i++) {
+ evcnt_attach_dynamic(&cpi->ci_intrcnt[i], EVCNT_TYPE_INTR,
+ NULL, cpi->ci_cpuname, hard_intr_names[i]);
+ evcnt_attach_dynamic(&cpi->ci_sintrcnt[i], EVCNT_TYPE_INTR,
+ NULL, cpi->ci_cpuname, soft_intr_names[i]);
+ }
+}
+
/*
* Attach the CPU.
* Discover interesting goop about the virtual address cache
@@ -341,10 +410,13 @@
#if defined(MULTIPROCESSOR)
if (cpu_attach_count > 1) {
cpu_attach_non_boot(sc, cpi, node);
+ cpu_init_evcnt(cpi);
return;
}
#endif /* MULTIPROCESSOR */
+ cpu_init_evcnt(cpi);
+
/* Stuff to only run on the boot CPU */
cpu_setup();
snprintf(buf, sizeof buf, "%s @ %s MHz, %s FPU",
@@ -500,7 +572,7 @@
cpu_init_system(void)
{
- mutex_init(&xpmsg_mutex, MUTEX_SPIN, IPL_VM);
+ mutex_init(&xpmsg_mutex, MUTEX_SPIN, IPL_SCHED);
}
/*
@@ -560,8 +632,12 @@
struct cpu_info *cpi;
int n, i, done, callself, mybit;
volatile struct xpmsg_func *p;
+ u_int pil;
int fasttrap;
int is_noop = func == (xcall_func_t)sparc_noop;
+ static char errbuf[160];
+ char *bufp = errbuf;
+ size_t bufsz = sizeof errbuf, wrsz;
mybit = (1 << cpuinfo.ci_cpuid);
callself = func && (cpuset & mybit) != 0;
@@ -571,7 +647,34 @@
cpuset &= cpu_ready_mask;
/* prevent interrupts that grab the kernel lock */
+#if 0
mutex_spin_enter(&xpmsg_mutex);
+#else
+ /*
+ * There's a deadlock potential between multiple CPUs trying
+ * to xcall() at the same time, and the thread that loses the
+ * race to get xpmsg_lock is at an IPL above the incoming IPI
+ * IPL level, so it sits around waiting to take the lock while
+ * the other CPU is waiting for this CPU to handle the IPI and
+ * mark it as completed.
+ *
+ * If we fail to get the mutex, and we're at high enough IPL,
+ * call xcallintr() if there is a valid msg.tag.
+ */
+ pil = (getpsr() & PSR_PIL) >> 8;
+
+ if (cold || pil < 13)
+ mutex_spin_enter(&xpmsg_mutex);
+ else {
+ while (mutex_tryenter(&xpmsg_mutex) == 0) {
+ cpuinfo.ci_xpmsg_mutex_fail.ev_count++;
+ if (cpuinfo.msg.tag) {
+ cpuinfo.ci_xpmsg_mutex_fail_call.ev_count++;
+ xcallintr(xcallintr);
+ }
+ }
+ }
+#endif
/*
* Firstly, call each CPU. We do this so that they might have
@@ -599,7 +702,6 @@
/*
* Second, call ourselves.
*/
- p = &cpuinfo.msg.u.xpmsg_func;
if (callself)
(*func)(arg0, arg1, arg2);
@@ -612,8 +714,11 @@
i = 100000; /* time-out, not too long, but still an _AGE_ */
while (!done) {
if (--i < 0) {
- printf_nolog("xcall(cpu%d,%p): couldn't ping cpus:",
+ wrsz = snprintf(bufp, bufsz,
+ "xcall(cpu%d,%p): couldn't ping cpus:",
cpu_number(), func);
+ bufsz -= wrsz;
+ bufp += wrsz;
}
done = 1;
@@ -623,7 +728,13 @@
if (cpi->msg.complete == 0) {
if (i < 0) {
- printf_nolog(" cpu%d", cpi->ci_cpuid);
+ wrsz = snprintf(bufp, bufsz,
+ " cpu%d", cpi->ci_cpuid);
+ bufsz -= wrsz;
+ bufp += wrsz;
+ /* insanity */
+ if (bufsz < 0)
+ break;
} else {
done = 0;
break;
@@ -632,8 +743,7 @@
}
}
if (i < 0)
- printf_nolog("\n");
-
+ printf_nolog("%s\n", errbuf);
mutex_spin_exit(&xpmsg_mutex);
}
@@ -2033,8 +2143,6 @@
#include "ioconf.h"
-void cpu_debug_dump(void);
-
/*
* Dump CPU information from ddb.
*/
@@ -2057,4 +2165,35 @@
ci->curpcb);
}
}
+
+#if defined(MULTIPROCESSOR)
+/*
+ * Dump CPU xcall from ddb.
+ */
+void
+cpu_xcall_dump(void)
+{
+ struct cpu_info *ci;
+ CPU_INFO_ITERATOR cii;
+
+ db_printf("%-4s %-10s %-10s %-10s %-10s %-10s "
+ "%-4s %-4s %-4s\n",
+ "CPU#", "FUNC", "TRAP", "ARG0", "ARG1", "ARG2",
+ "TAG", "RECV", "COMPL");
+ for (CPU_INFO_FOREACH(cii, ci)) {
+ db_printf("%-4d %-10p %-10p 0x%-8x 0x%-8x 0x%-8x "
+ "%-4d %-4d %-4d\n",
+ ci->ci_cpuid,
+ ci->msg.u.xpmsg_func.func,
+ ci->msg.u.xpmsg_func.trap,
+ ci->msg.u.xpmsg_func.arg0,
+ ci->msg.u.xpmsg_func.arg1,
+ ci->msg.u.xpmsg_func.arg2,
+ ci->msg.tag,
+ ci->msg.received,
+ ci->msg.complete);
+ }
+}
+#endif
+
#endif
Index: src/sys/arch/sparc/sparc/cpuvar.h
diff -u src/sys/arch/sparc/sparc/cpuvar.h:1.75.10.4 src/sys/arch/sparc/sparc/cpuvar.h:1.75.10.5
--- src/sys/arch/sparc/sparc/cpuvar.h:1.75.10.4 Wed Feb 16 21:33:25 2011
+++ src/sys/arch/sparc/sparc/cpuvar.h Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: cpuvar.h,v 1.75.10.4 2011/02/16 21:33:25 bouyer Exp $ */
+/* $NetBSD: cpuvar.h,v 1.75.10.5 2011/03/08 17:29:46 riz Exp $ */
/*
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@@ -127,6 +127,13 @@
struct cpu_info {
struct cpu_data ci_data; /* MI per-cpu data */
+ /*
+ * Primary Inter-processor message area. Keep this aligned
+ * to a cache line boundary if possible, as the structure
+ * itself is one (normal 32 byte) cache-line.
+ */
+ struct xpmsg msg __aligned(32);
+
/* Scheduler flags */
int ci_want_ast;
int ci_want_resched;
@@ -142,9 +149,6 @@
*/
struct cpu_info * volatile ci_self;
- /* Primary Inter-processor message area */
- struct xpmsg msg;
-
int ci_cpuid; /* CPU index (see cpus[] array) */
/* Context administration */
@@ -333,8 +337,11 @@
vaddr_t ci_free_sva1, ci_free_eva1, ci_free_sva2, ci_free_eva2;
char ci_cpuname[8]; /* "cpu/0", etc. */
- struct evcnt ci_lev10;
- struct evcnt ci_lev14;
+ struct evcnt ci_savefpstate;
+ struct evcnt ci_xpmsg_mutex_fail;
+ struct evcnt ci_xpmsg_mutex_fail_call;
+ struct evcnt ci_intrcnt[16];
+ struct evcnt ci_sintrcnt[16];
};
/*
@@ -448,6 +455,8 @@
typedef void (*xcall_func_t)(int, int, int);
typedef void (*xcall_trap_t)(int, int, int);
void xcall(xcall_func_t, xcall_trap_t, int, int, int, u_int);
+/* from intr.c */
+void xcallintr(void *);
/* Shorthand */
#define XCALL0(f,cpuset) \
xcall((xcall_func_t)f, NULL, 0, 0, 0, cpuset)
@@ -487,5 +496,12 @@
#define cpuinfo (*(struct cpu_info *)CPUINFO_VA)
+#if defined(DDB) || defined(MULTIPROCESSOR)
+/*
+ * These are called by ddb mach functions.
+ */
+void cpu_debug_dump(void);
+void cpu_xcall_dump(void);
+#endif
#endif /* _sparc_cpuvar_h */
Index: src/sys/arch/sparc/sparc/db_interface.c
diff -u src/sys/arch/sparc/sparc/db_interface.c:1.79.4.2 src/sys/arch/sparc/sparc/db_interface.c:1.79.4.3
--- src/sys/arch/sparc/sparc/db_interface.c:1.79.4.2 Sun Jan 16 12:58:24 2011
+++ src/sys/arch/sparc/sparc/db_interface.c Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: db_interface.c,v 1.79.4.2 2011/01/16 12:58:24 bouyer Exp $ */
+/* $NetBSD: db_interface.c,v 1.79.4.3 2011/03/08 17:29:46 riz Exp $ */
/*
* Mach Operating System
@@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.79.4.2 2011/01/16 12:58:24 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_interface.c,v 1.79.4.3 2011/03/08 17:29:46 riz Exp $");
#include "opt_ddb.h"
#include "opt_kgdb.h"
@@ -202,6 +202,7 @@
void db_uvmhistdump(db_expr_t, bool, db_expr_t, const char *);
#ifdef MULTIPROCESSOR
void db_cpu_cmd(db_expr_t, bool, db_expr_t, const char *);
+void db_xcall_cmd(db_expr_t, bool, db_expr_t, const char *);
#endif
void db_page_cmd(db_expr_t, bool, db_expr_t, const char *);
@@ -448,7 +449,6 @@
}
#if defined(MULTIPROCESSOR)
-extern void cpu_debug_dump(void); /* XXX */
void
db_cpu_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
@@ -483,6 +483,12 @@
ddb_cpuinfo = ci;
}
+void
+db_xcall_cmd(db_expr_t addr, bool have_addr, db_expr_t count, const char *modif)
+{
+ cpu_xcall_dump();
+}
+
#endif /* MULTIPROCESSOR */
const struct db_command db_machine_command_table[] = {
@@ -492,6 +498,7 @@
{ DDB_ADD_CMD("page", db_page_cmd, 0, NULL,NULL,NULL) },
#ifdef MULTIPROCESSOR
{ DDB_ADD_CMD("cpu", db_cpu_cmd, 0, NULL,NULL,NULL) },
+ { DDB_ADD_CMD("xcall", db_xcall_cmd, 0, NULL,NULL,NULL) },
#endif
{ DDB_ADD_CMD(NULL, NULL, 0,NULL,NULL,NULL) }
};
Index: src/sys/arch/sparc/sparc/genassym.cf
diff -u src/sys/arch/sparc/sparc/genassym.cf:1.56.4.1 src/sys/arch/sparc/sparc/genassym.cf:1.56.4.2
--- src/sys/arch/sparc/sparc/genassym.cf:1.56.4.1 Fri Jan 28 07:16:13 2011
+++ src/sys/arch/sparc/sparc/genassym.cf Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-# $NetBSD: genassym.cf,v 1.56.4.1 2011/01/28 07:16:13 snj Exp $
+# $NetBSD: genassym.cf,v 1.56.4.2 2011/03/08 17:29:46 riz Exp $
#
# Copyright (c) 1998 The NetBSD Foundation, Inc.
@@ -128,6 +128,9 @@
define V_INTR offsetof(struct uvmexp, intrs)
define V_SOFT offsetof(struct uvmexp, softs)
define V_FAULTS offsetof(struct uvmexp, faults)
+define CPUINFO_LEV14 offsetof(struct cpu_info, ci_sintrcnt[14])
+define CPUINFO_INTRCNT offsetof(struct cpu_info, ci_intrcnt)
+define CPUINFO_SINTRCNT offsetof(struct cpu_info, ci_sintrcnt)
define EV_COUNT offsetof(struct evcnt, ev_count)
define EV_STRUCTSIZE sizeof(struct evcnt)
@@ -161,6 +164,7 @@
define CPUINFO_MTX_COUNT offsetof(struct cpu_info, ci_mtx_count)
define CPUINFO_MTX_OLDSPL offsetof(struct cpu_info, ci_mtx_oldspl)
define CPUINFO_IDEPTH offsetof(struct cpu_info, ci_idepth)
+define CPUINFO_SAVEFPSTATE offsetof(struct cpu_info, ci_savefpstate)
# PTE bits and related information
define PG_W PG_W
Index: src/sys/arch/sparc/sparc/intr.c
diff -u src/sys/arch/sparc/sparc/intr.c:1.100.20.2 src/sys/arch/sparc/sparc/intr.c:1.100.20.3
--- src/sys/arch/sparc/sparc/intr.c:1.100.20.2 Fri Jan 28 07:16:13 2011
+++ src/sys/arch/sparc/sparc/intr.c Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: intr.c,v 1.100.20.2 2011/01/28 07:16:13 snj Exp $ */
+/* $NetBSD: intr.c,v 1.100.20.3 2011/03/08 17:29:46 riz Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.100.20.2 2011/01/28 07:16:13 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: intr.c,v 1.100.20.3 2011/03/08 17:29:46 riz Exp $");
#include "opt_multiprocessor.h"
#include "opt_sparc_arch.h"
@@ -72,47 +72,7 @@
#if defined(MULTIPROCESSOR)
void *xcall_cookie;
-
-/* Stats */
-struct evcnt lev13_evcnt = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,0,"xcall","std");
-struct evcnt lev14_evcnt = EVCNT_INITIALIZER(EVCNT_TYPE_INTR,0,"xcall","fast");
-EVCNT_ATTACH_STATIC(lev13_evcnt);
-EVCNT_ATTACH_STATIC(lev14_evcnt);
-#endif
-
-struct evcnt intrcnt[15] = {
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "spur", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev1", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev2", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev3", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev4", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev5", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev6", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev7", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev8", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev9", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "clock", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev11", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev12", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "lev13", "hard"),
- EVCNT_INITIALIZER(EVCNT_TYPE_INTR, 0, "prof", "hard"),
-};
-
-EVCNT_ATTACH_STATIC2(intrcnt, 0);
-EVCNT_ATTACH_STATIC2(intrcnt, 1);
-EVCNT_ATTACH_STATIC2(intrcnt, 2);
-EVCNT_ATTACH_STATIC2(intrcnt, 3);
-EVCNT_ATTACH_STATIC2(intrcnt, 4);
-EVCNT_ATTACH_STATIC2(intrcnt, 5);
-EVCNT_ATTACH_STATIC2(intrcnt, 6);
-EVCNT_ATTACH_STATIC2(intrcnt, 7);
-EVCNT_ATTACH_STATIC2(intrcnt, 8);
-EVCNT_ATTACH_STATIC2(intrcnt, 9);
-EVCNT_ATTACH_STATIC2(intrcnt, 10);
-EVCNT_ATTACH_STATIC2(intrcnt, 11);
-EVCNT_ATTACH_STATIC2(intrcnt, 12);
-EVCNT_ATTACH_STATIC2(intrcnt, 13);
-EVCNT_ATTACH_STATIC2(intrcnt, 14);
+#endif
void strayintr(struct clockframe *);
#ifdef DIAGNOSTIC
@@ -130,6 +90,19 @@
static int straytime, nstray;
char bits[64];
int timesince;
+
+#if defined(MULTIPROCESSOR)
+ /*
+ * XXX
+ *
+ * Don't whine about zs interrupts on MP. We sometimes get
+ * stray interrupts when polled kernel output on cpu>0 eats
+ * the interrupt and cpu0 sees it.
+ */
+#define ZS_INTR_IPL 12
+ if (fp->ipl == ZS_INTR_IPL)
+ return;
+#endif
printf("stray interrupt cpu%d ipl 0x%x pc=0x%x npc=0x%x psr=%s\n",
cpu_number(), fp->ipl, fp->pc, fp->npc,
@@ -229,6 +202,9 @@
char bits[64];
u_int afsr, afva;
+ /* Tally */
+ cpuinfo.ci_intrcnt[15].ev_count++;
+
afsr = afva = 0;
if ((*cpuinfo.get_asyncflt)(&afsr, &afva) == 0) {
printf("Async registers (mid %d): afsr=%s; afva=0x%x%x\n",
@@ -315,6 +291,10 @@
void
nmi_soft(struct trapframe *tf)
{
+
+ /* Tally */
+ cpuinfo.ci_sintrcnt[15].ev_count++;
+
if (cpuinfo.mailbox) {
/* Check PROM messages */
uint8_t msg = *(uint8_t *)cpuinfo.mailbox;
@@ -362,13 +342,19 @@
#if defined(MULTIPROCESSOR)
/*
* Respond to an xcall() request from another CPU.
+ *
+ * This is also called directly from xcall() if we notice an
+ * incoming message while we're waiting to grab the xpmsg_lock.
+ * We pass the address of xcallintr() itself to indicate that
+ * this is not a real interrupt.
*/
-static void
+void
xcallintr(void *v)
{
/* Tally */
- lev13_evcnt.ev_count++;
+ if (v != xcallintr)
+ cpuinfo.ci_sintrcnt[13].ev_count++;
/* notyet - cpuinfo.msg.received = 1; */
switch (cpuinfo.msg.tag) {
Index: src/sys/arch/sparc/sparc/locore.s
diff -u src/sys/arch/sparc/sparc/locore.s:1.244.8.3 src/sys/arch/sparc/sparc/locore.s:1.244.8.4
--- src/sys/arch/sparc/sparc/locore.s:1.244.8.3 Fri Jan 28 07:16:13 2011
+++ src/sys/arch/sparc/sparc/locore.s Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: locore.s,v 1.244.8.3 2011/01/28 07:16:13 snj Exp $ */
+/* $NetBSD: locore.s,v 1.244.8.4 2011/03/08 17:29:46 riz Exp $ */
/*
* Copyright (c) 1996 Paul Kranenburg
@@ -1812,6 +1812,7 @@
*/
#if defined(SUN4)
+_ENTRY(memfault_sun4)
memfault_sun4:
TRAP_SETUP(-CCFSZ-80)
INCR(_C_LABEL(uvmexp)+V_FAULTS) ! cnt.v_faults++ (clobbers %o0,%o1)
@@ -1876,8 +1877,9 @@
#endif /* SUN4C || SUN4M */
#endif /* SUN4 */
-memfault_sun4c:
#if defined(SUN4C)
+_ENTRY(memfault_sun4c)
+memfault_sun4c:
TRAP_SETUP(-CCFSZ-80)
INCR(_C_LABEL(uvmexp)+V_FAULTS) ! cnt.v_faults++ (clobbers %o0,%o1)
@@ -1975,6 +1977,7 @@
#endif /* SUN4C */
#if defined(SUN4M)
+_ENTRY(memfault_sun4m)
memfault_sun4m:
sethi %hi(CPUINFO_VA), %l4
ld [%l4 + %lo(CPUINFO_VA+CPUINFO_GETSYNCFLT)], %l5
@@ -2527,13 +2530,15 @@
wr %l4, PSR_ET, %psr ! song and dance is necessary
std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe
sll %l3, 2, %l5
- set intrcnt, %l4 ! intrcnt[intlev].ev_count++;
+
+ set CPUINFO_VA + CPUINFO_SINTRCNT, %l4 ! sintrcnt[intlev].ev_count++;
sll %l3, EV_STRUCTSHIFT, %o2
ldd [%l4 + %o2], %o0
- std %l2, [%sp + CCFSZ + 8]
+ std %l2, [%sp + CCFSZ + 8] ! set up intrframe/clockframe
inccc %o1
addx %o0, 0, %o0
std %o0, [%l4 + %o2]
+
set _C_LABEL(sintrhand), %l4! %l4 = sintrhand[intlev];
ld [%l4 + %l5], %l4
@@ -2681,7 +2686,8 @@
wr %l4, PSR_ET, %psr ! song and dance is necessary
std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe
sll %l3, 2, %l5
- set intrcnt, %l4 ! intrcnt[intlev].ev_count++;
+
+ set CPUINFO_VA + CPUINFO_INTRCNT, %l4 ! intrcnt[intlev].ev_count++;
sll %l3, EV_STRUCTSHIFT, %o2
ldd [%l4 + %o2], %o0
std %l2, [%sp + CCFSZ + 8] ! set up intrframe/clockframe
@@ -2728,13 +2734,15 @@
wr %l4, PSR_ET, %psr ! song and dance is necessary
std %l0, [%sp + CCFSZ + 0] ! set up intrframe/clockframe
sll %l3, 2, %l5
- set intrcnt, %l4 ! intrcnt[intlev].ev_count++;
+
+ set CPUINFO_VA + CPUINFO_INTRCNT, %l4 ! intrcnt[intlev].ev_count++;
sll %l3, EV_STRUCTSHIFT, %o2
ldd [%l4 + %o2], %o0
std %l2, [%sp + CCFSZ + 8] ! set up intrframe/clockframe
inccc %o1
addx %o0, 0, %o0
std %o0, [%l4 + %o2]
+
set _C_LABEL(intrhand), %l4 ! %l4 = intrhand[intlev];
ld [%l4 + %l5], %l4
@@ -2813,11 +2821,11 @@
* %l6 = &cpuinfo
*/
lev14_softint:
- set _C_LABEL(lev14_evcnt), %l7 ! lev14_evcnt.ev_count++;
- ldd [%l7 + EV_COUNT], %l4
+ sethi %hi(CPUINFO_VA), %l7
+ ldd [%l7 + CPUINFO_LEV14], %l4
inccc %l5
addx %l4, %g0, %l4
- std %l4, [%l7 + EV_COUNT]
+ std %l4, [%l7 + CPUINFO_LEV14]
ld [%l6 + CPUINFO_XMSG_TRAP], %l7
#ifdef DIAGNOSTIC
@@ -3112,7 +3120,7 @@
#if defined(SUN4M)
_ENTRY(_C_LABEL(nmi_sun4m))
- INTR_SETUP(-CCFSZ-80)
+ INTR_SETUP(-CCFSZ-80-8-8) ! normal frame, plus g2..g5
INCR(_C_LABEL(uvmexp)+V_INTR) ! cnt.v_intr++; (clobbers %o0,%o1)
#if !defined(MSIIEP) /* normal sun4m */
@@ -5904,12 +5912,29 @@
/* NOTREACHED */
/*
- * savefpstate(f) struct fpstate *f;
+ * savefpstate(struct fpstate *f);
+ * ipi_savefpstate(struct fpstate *f);
*
* Store the current FPU state. The first `st %fsr' may cause a trap;
* our trap handler knows how to recover (by `returning' to savefpcont).
+ *
+ * The IPI version just deals with updating event counters first.
*/
+Lpanic_savefpstate:
+ .asciz "cpu%d: NULL fpstate"
+ _ALIGN
+
+ENTRY(ipi_savefpstate)
+ sethi %hi(CPUINFO_VA), %o5
+ ldd [%o5 + CPUINFO_SAVEFPSTATE], %o2
+ inccc %o3
+ addx %o2, 0, %o2
+ std %o2, [%o5 + CPUINFO_SAVEFPSTATE]
+
ENTRY(savefpstate)
+ cmp %o0, 0
+ bz Lfp_null_fpstate
+ nop
rd %psr, %o1 ! enable FP before we begin
set PSR_EF, %o2
or %o1, %o2, %o1
@@ -5928,8 +5953,8 @@
* So we still have to check the blasted QNE bit.
* With any luck it will usually not be set.
*/
- ld [%o0 + FS_FSR], %o4 ! if (f->fs_fsr & QNE)
- btst %o5, %o4
+ ld [%o0 + FS_FSR], %o2 ! if (f->fs_fsr & QNE)
+ btst %o5, %o2
bnz Lfp_storeq ! goto storeq;
std %f0, [%o0 + FS_REGS + (4*0)] ! f->fs_f0 = etc;
Lfp_finish:
@@ -5952,6 +5977,15 @@
std %f30, [%o0 + FS_REGS + (4*30)]
/*
+ * We got a NULL struct fpstate * on the IPI. We panic.
+ */
+Lfp_null_fpstate:
+ ld [%o5 + CPUINFO_CPUNO], %o1
+ sethi %hi(Lpanic_savefpstate), %o0
+ call _C_LABEL(panic)
+ or %o0, %lo(Lpanic_savefpstate), %o0
+
+/*
* Store the (now known nonempty) FP queue.
* We have to reread the fsr each time in order to get the new QNE bit.
*/
@@ -5964,6 +5998,7 @@
btst %o5, %o4
bnz 1b
inc 8, %o3
+ st %o2, [%o0 + FS_FSR] ! fs->fs_fsr = original_fsr
b Lfp_finish ! set qsize and finish storing fregs
srl %o3, 3, %o3 ! (but first fix qsize)
Index: src/sys/arch/sparc/sparc/machdep.c
diff -u src/sys/arch/sparc/sparc/machdep.c:1.282.4.3 src/sys/arch/sparc/sparc/machdep.c:1.282.4.4
--- src/sys/arch/sparc/sparc/machdep.c:1.282.4.3 Sun Oct 18 14:40:40 2009
+++ src/sys/arch/sparc/sparc/machdep.c Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: machdep.c,v 1.282.4.3 2009/10/18 14:40:40 bouyer Exp $ */
+/* $NetBSD: machdep.c,v 1.282.4.4 2011/03/08 17:29:46 riz Exp $ */
/*-
* Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.282.4.3 2009/10/18 14:40:40 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.282.4.4 2011/03/08 17:29:46 riz Exp $");
#include "opt_compat_netbsd.h"
#include "opt_compat_sunos.h"
@@ -377,7 +377,7 @@
savefpstate(fs);
#if defined(MULTIPROCESSOR)
else
- XCALL1(savefpstate, fs, 1 << cpi->ci_cpuid);
+ XCALL1(ipi_savefpstate, fs, 1 << cpi->ci_cpuid);
#endif
cpi->fplwp = NULL;
}
Index: src/sys/arch/sparc/sparc/timer.c
diff -u src/sys/arch/sparc/sparc/timer.c:1.23 src/sys/arch/sparc/sparc/timer.c:1.23.28.1
--- src/sys/arch/sparc/sparc/timer.c:1.23 Mon Dec 3 15:34:22 2007
+++ src/sys/arch/sparc/sparc/timer.c Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: timer.c,v 1.23 2007/12/03 15:34:22 ad Exp $ */
+/* $NetBSD: timer.c,v 1.23.28.1 2011/03/08 17:29:46 riz Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -60,7 +60,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: timer.c,v 1.23 2007/12/03 15:34:22 ad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: timer.c,v 1.23.28.1 2011/03/08 17:29:46 riz Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -153,6 +153,7 @@
timerattach(volatile int *cntreg, volatile int *limreg)
{
u_int prec = 0, t0;
+ void (*sched_intr_fn)(void *);
/*
* Calibrate delay() by tweaking the magic constant
@@ -192,11 +193,13 @@
cntr.mask = (1 << (31-t0))-1;
counter_timecounter.tc_frequency = 1000000 * (TMR_SHIFT - t0 + 1);
- printf(": delay constant %d, frequency = %" PRIu64 " Hz\n", timerblurb, counter_timecounter.tc_frequency);
+ printf(": delay constant %d, frequency = %" PRIu64 " Hz\n",
+ timerblurb, counter_timecounter.tc_frequency);
#if defined(SUN4) || defined(SUN4C)
if (CPU_ISSUN4 || CPU_ISSUN4C) {
timer_init = timer_init_4;
+ sched_intr_fn = schedintr;
level10.ih_fun = clockintr_4;
level14.ih_fun = statintr_4;
cntr.limit = tmr_ustolim(tick);
@@ -205,6 +208,12 @@
#if defined(SUN4M)
if (CPU_ISSUN4M) {
timer_init = timer_init_4m;
+#if defined(MULTIPROCESSOR)
+ if (sparc_ncpus > 1)
+ sched_intr_fn = schedintr_4m;
+ else
+#endif
+ sched_intr_fn = schedintr;
level10.ih_fun = clockintr_4m;
level14.ih_fun = statintr_4m;
cntr.limit = tmr_ustolim4m(tick);
@@ -215,7 +224,7 @@
intr_establish(14, 0, &level14, NULL);
/* Establish a soft interrupt at a lower level for schedclock */
- sched_cookie = sparc_softintr_establish(IPL_SCHED, schedintr, NULL);
+ sched_cookie = sparc_softintr_establish(IPL_SCHED, sched_intr_fn, NULL);
if (sched_cookie == NULL)
panic("timerattach: cannot establish schedintr");
Index: src/sys/arch/sparc/sparc/timer_sun4m.c
diff -u src/sys/arch/sparc/sparc/timer_sun4m.c:1.16.56.2 src/sys/arch/sparc/sparc/timer_sun4m.c:1.16.56.3
--- src/sys/arch/sparc/sparc/timer_sun4m.c:1.16.56.2 Wed Feb 16 21:33:25 2011
+++ src/sys/arch/sparc/sparc/timer_sun4m.c Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: timer_sun4m.c,v 1.16.56.2 2011/02/16 21:33:25 bouyer Exp $ */
+/* $NetBSD: timer_sun4m.c,v 1.16.56.3 2011/03/08 17:29:46 riz Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -58,7 +58,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: timer_sun4m.c,v 1.16.56.2 2011/02/16 21:33:25 bouyer Exp $");
+__KERNEL_RCSID(0, "$NetBSD: timer_sun4m.c,v 1.16.56.3 2011/03/08 17:29:46 riz Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -95,6 +95,29 @@
icr_si_bic(SINTR_T);
}
+void
+schedintr_4m(void *v)
+{
+
+#ifdef MULTIPROCESSOR
+ /*
+ * We call hardclock() here so that we make sure it is called on
+ * all CPUs. This function ends up being called on sun4m systems
+ * every tick, so we have avoid
+ */
+ if (!CPU_IS_PRIMARY(curcpu()))
+ hardclock(v);
+
+ /*
+ * The factor 8 is only valid for stathz==100.
+ * See also clock.c
+ */
+ if ((++cpuinfo.ci_schedstate.spc_schedticks & 7) == 0 && schedhz != 0)
+#endif
+ schedclock(curlwp);
+}
+
+
/*
* Level 10 (clock) interrupts from system counter.
*/
@@ -102,6 +125,7 @@
clockintr_4m(void *cap)
{
+ KASSERT(CPU_IS_PRIMARY(curcpu()));
/*
* XXX this needs to be fixed in a more general way
* problem is that the kernel enables interrupts and THEN
@@ -109,8 +133,10 @@
* a timer interrupt - if we call hardclock() at that point we'll
* panic
* so for now just bail when cold
+ *
+ * For MP, we defer calling hardclock() to the schedintr so
+ * that we call it on all cpus.
*/
- cpuinfo.ci_lev10.ev_count++;
if (cold)
return 0;
/* read the limit register to clear the interrupt */
@@ -129,8 +155,6 @@
struct clockframe *frame = cap;
u_long newint;
- cpuinfo.ci_lev14.ev_count++;
-
/* read the limit register to clear the interrupt */
*((volatile int *)&counterreg4m->t_limit);
@@ -152,19 +176,23 @@
* The factor 8 is only valid for stathz==100.
* See also clock.c
*/
- if (curlwp && (++cpuinfo.ci_schedstate.spc_schedticks & 7) == 0) {
+#if !defined(MULTIPROCESSOR)
+ if ((++cpuinfo.ci_schedstate.spc_schedticks & 7) == 0 && schedhz != 0) {
+#endif
if (CLKF_LOPRI(frame, IPL_SCHED)) {
/* No need to schedule a soft interrupt */
spllowerschedclock();
- schedintr(cap);
+ schedintr_4m(cap);
} else {
/*
* We're interrupting a thread that may have the
- * scheduler lock; run schedintr() on this CPU later.
+ * scheduler lock; run schedintr_4m() on this CPU later.
*/
raise_ipi(&cpuinfo, IPL_SCHED); /* sched_cookie->pil */
}
+#if !defined(MULTIPROCESSOR)
}
+#endif
return (1);
}
@@ -224,13 +252,6 @@
cpi->counterreg_4m = (struct counter_4m *)bh;
}
- /* Install timer/statclock event counters, per cpu */
- for (CPU_INFO_FOREACH(n, cpi)) {
- snprintf(cpi->ci_cpuname, sizeof(cpi->ci_cpuname), "cpu/%d", n);
- evcnt_attach_dynamic(&cpi->ci_lev10, EVCNT_TYPE_INTR, NULL, cpi->ci_cpuname, "lev10");
- evcnt_attach_dynamic(&cpi->ci_lev14, EVCNT_TYPE_INTR, NULL, cpi->ci_cpuname, "lev14");
- }
-
/* Put processor counter in "timer" mode */
timerreg4m->t_cfg = 0;
Index: src/sys/arch/sparc/sparc/timervar.h
diff -u src/sys/arch/sparc/sparc/timervar.h:1.8 src/sys/arch/sparc/sparc/timervar.h:1.8.74.1
--- src/sys/arch/sparc/sparc/timervar.h:1.8 Wed Jun 7 22:38:50 2006
+++ src/sys/arch/sparc/sparc/timervar.h Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: timervar.h,v 1.8 2006/06/07 22:38:50 kardel Exp $ */
+/* $NetBSD: timervar.h,v 1.8.74.1 2011/03/08 17:29:46 riz Exp $ */
/*
* Copyright (c) 1992, 1993
@@ -50,6 +50,7 @@
#endif /* SUN4 || SUN4C */
#if defined(SUN4M)
+void schedintr_4m(void *);
int clockintr_4m(void *);
int statintr_4m(void *);
void timer_init_4m(void);
Index: src/sys/arch/sparc/sparc/trap.c
diff -u src/sys/arch/sparc/sparc/trap.c:1.176 src/sys/arch/sparc/sparc/trap.c:1.176.4.1
--- src/sys/arch/sparc/sparc/trap.c:1.176 Wed Oct 15 06:51:18 2008
+++ src/sys/arch/sparc/sparc/trap.c Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: trap.c,v 1.176 2008/10/15 06:51:18 wrstuden Exp $ */
+/* $NetBSD: trap.c,v 1.176.4.1 2011/03/08 17:29:46 riz Exp $ */
/*
* Copyright (c) 1996
@@ -49,7 +49,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.176 2008/10/15 06:51:18 wrstuden Exp $");
+__KERNEL_RCSID(0, "$NetBSD: trap.c,v 1.176.4.1 2011/03/08 17:29:46 riz Exp $");
#include "opt_ddb.h"
#include "opt_compat_svr4.h"
@@ -479,7 +479,7 @@
panic("FPU(%d): state for %p",
cpi->ci_cpuid, l);
#if defined(MULTIPROCESSOR)
- XCALL1(savefpstate, fs, 1 << cpi->ci_cpuid);
+ XCALL1(ipi_savefpstate, fs, 1 << cpi->ci_cpuid);
#endif
cpi->fplwp = NULL;
}
Index: src/sys/arch/sparc/sparc/vm_machdep.c
diff -u src/sys/arch/sparc/sparc/vm_machdep.c:1.95.4.2 src/sys/arch/sparc/sparc/vm_machdep.c:1.95.4.3
--- src/sys/arch/sparc/sparc/vm_machdep.c:1.95.4.2 Sat Jan 9 01:43:51 2010
+++ src/sys/arch/sparc/sparc/vm_machdep.c Tue Mar 8 17:29:46 2011
@@ -1,4 +1,4 @@
-/* $NetBSD: vm_machdep.c,v 1.95.4.2 2010/01/09 01:43:51 snj Exp $ */
+/* $NetBSD: vm_machdep.c,v 1.95.4.3 2011/03/08 17:29:46 riz Exp $ */
/*
* Copyright (c) 1996
@@ -49,7 +49,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.95.4.2 2010/01/09 01:43:51 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vm_machdep.c,v 1.95.4.3 2011/03/08 17:29:46 riz Exp $");
#include "opt_multiprocessor.h"
#include "opt_coredump.h"
@@ -230,7 +230,7 @@
savefpstate(l1->l_md.md_fpstate);
#if defined(MULTIPROCESSOR)
else
- XCALL1(savefpstate, l1->l_md.md_fpstate,
+ XCALL1(ipi_savefpstate, l1->l_md.md_fpstate,
1 << cpi->ci_cpuid);
#endif
}
@@ -308,7 +308,7 @@
savefpstate(fs);
#if defined(MULTIPROCESSOR)
else
- XCALL1(savefpstate, fs, 1 << cpi->ci_cpuid);
+ XCALL1(ipi_savefpstate, fs, 1 << cpi->ci_cpuid);
#endif
cpi->fplwp = NULL;
}