- add a new message tag for level15 software NMI, and switch ddb to use this

rather than the level13 software intr xpmsg area.  now DDB IPI's don't lock
the xpmsg_lock and we avoid recursion and more.
- don't actually use cpuinfo.msg.lock yet, xpmsg_lock suffices.
- reread the pending register on mbus hypersparc cpus to avoid bugs in the
h/w that cause IPI's to be missed.
This commit is contained in:
mrg 2003-01-07 16:20:13 +00:00
parent 02d686d112
commit 88f08d9ac1
4 changed files with 41 additions and 48 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.c,v 1.152 2003/01/07 13:12:59 pk Exp $ */
/* $NetBSD: cpu.c,v 1.153 2003/01/07 16:20:13 mrg Exp $ */
/*
* Copyright (c) 1996
@ -142,6 +142,7 @@ struct cpu_info *alloc_cpuinfo_global_va __P((int, vsize_t *));
struct cpu_info *alloc_cpuinfo __P((void));
int go_smp_cpus = 0; /* non-primary cpu's wait for this to go */
int ross_pend; /* work around the hypersparc xcall bug */
/* lock this to send IPI's */
struct simplelock xpmsg_lock = SIMPLELOCK_INITIALIZER;
@ -467,7 +468,9 @@ static struct cpu_softc *bootcpu;
cpi->ci_cpuid = cpu_instance++;
cpi->mid = mid;
cpi->node = node;
#if 0
simple_lock_init(&cpi->msg.lock);
#endif
if (ncpu > 1) {
printf(": mid %d", mid);
@ -643,7 +646,8 @@ extern void cpu_hatch __P((void)); /* in locore.s */
}
/*
* Call a function on every CPU.
* Call a function on some CPUs. `cpuset' can be set to CPUSET_ALL
* to call every CPU, or `1 << cpi->ci_cpuid' for each CPU to call.
*/
void
xcall(func, arg0, arg1, arg2, arg3, cpuset)
@ -693,7 +697,9 @@ xcall(func, arg0, arg1, arg2, arg3, cpuset)
if ((cpuset & (1 << cpi->ci_cpuid)) == 0)
continue;
#if 0
simple_lock(&cpi->msg.lock);
#endif
cpi->msg.tag = XPMSG_FUNC;
cpi->flags &= ~CPUFLG_GOTMSG;
p = &cpi->msg.u.xpmsg_func;
@ -718,7 +724,7 @@ xcall(func, arg0, arg1, arg2, arg3, cpuset)
* this in the process).
*/
done = 0;
i = 100000; /* time-out */
i = 10000; /* time-out, not too long, but still an _AGE_ */
while (!done) {
if (--i < 0) {
printf("xcall(cpu%d,%p): couldn't ping cpus:",
@ -749,7 +755,9 @@ xcall(func, arg0, arg1, arg2, arg3, cpuset)
if ((cpuset & (1 << cpi->ci_cpuid)) == 0)
continue;
#if 0
simple_unlock(&cpi->msg.lock);
#endif
if ((cpi->flags & CPUFLG_GOTMSG) == 0)
printf(" cpu%d", cpi->ci_cpuid);
}
@ -768,19 +776,15 @@ mp_pause_cpus()
if (cpus == NULL)
return;
/* XXX - can currently be called at a high IPL level */
LOCK_XPMSG();
for (n = 0; n < ncpu; n++) {
struct cpu_info *cpi = cpus[n];
if (CPU_NOTREADY(cpi))
continue;
cpi->msg.tag = XPMSG_PAUSECPU;
cpi->flags &= ~CPUFLG_GOTMSG;
cpi->msg_lev15.tag = XPMSG11_PAUSECPU;
raise_ipi(cpi,15); /* high priority intr */
}
UNLOCK_XPMSG();
}
void
@ -1857,16 +1861,6 @@ getcpuinfo(sc, node)
mmu_impl = ANY;
mmu_vers = ANY;
}
#if 0
/*
* Get sparc architecture version
* NOTE: This is now done much earlier in autoconf.c:find_cpus()
*/
cpu_arch = (node == 0)
? 7
: PROM_getpropint(node, "sparc-version", 7);
#endif
} else {
/*
* Get CPU version/implementation from ROM. If not
@ -1983,6 +1977,7 @@ struct info {
char *name;
};
/* XXX trim this table on a per-ARCH basis */
/* NB: table order matters here; specific numbers must appear before ANY. */
static struct info fpu_types[] = {
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpuvar.h,v 1.48 2003/01/04 18:54:45 pk Exp $ */
/* $NetBSD: cpuvar.h,v 1.49 2003/01/07 16:20:14 mrg Exp $ */
/*
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -138,6 +138,11 @@ struct xpmsg {
} u;
};
struct xpmsg_lev15 {
__volatile int tag;
#define XPMSG11_PAUSECPU 1
};
/*
* This must be locked around all message transactions to ensure only
* one CPU is generating them.
@ -170,8 +175,9 @@ struct cpu_info {
*/
struct cpu_info * __volatile ci_self;
/* Inter-processor message area */
/* Inter-processor message areas */
struct xpmsg msg;
struct xpmsg_lev15 msg_lev15;
int ci_cpuid; /* CPU index (see cpus[] array) */
@ -190,8 +196,16 @@ struct cpu_info {
/* Per processor interrupt mask register (sun4m only) */
__volatile struct icr_pi *intreg_4m;
/*
* Send a IPI to (cpi). For Ross cpus we need to read
* the pending register to avoid a hardware bug.
*/
#define raise_ipi(cpi,lvl) do { \
(cpi)->intreg_4m->pi_set = PINTR_SINTRLEV(lvl); \
if ((cpi)->cpu_type == CPUTYP_HS_MBUS) { \
extern int ross_pend; \
ross_pend = (cpi)->intreg_4m->pi_pend; \
} \
} while (0)
int sun4_mmu3l; /* [4]: 3-level MMU present */

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.c,v 1.71 2003/01/03 16:20:21 mrg Exp $ */
/* $NetBSD: intr.c,v 1.72 2003/01/07 16:20:14 mrg Exp $ */
/*
* Copyright (c) 1992, 1993
@ -270,28 +270,21 @@ nmi_soft(tf)
struct trapframe *tf;
{
/* XXX - Most of this is superseded by xcallintr() below */
#if defined(MULTIPROCESSOR)
switch (cpuinfo.msg.tag) {
case XPMSG_PAUSECPU:
switch (cpuinfo.msg_lev15.tag) {
case XPMSG11_PAUSECPU:
/* XXX - assumes DDB is the only user of mp_pause_cpu() */
cpuinfo.flags |= CPUFLG_PAUSED|CPUFLG_GOTMSG;
cpuinfo.flags |= CPUFLG_PAUSED;
#if defined(DDB)
__asm("ta 0x8b"); /* trap(T_DBPAUSE) */
/* trap(T_DBPAUSE) */
__asm("ta 0x8b");
#else
while (cpuinfo.flags & CPUFLG_PAUSED) /**/;
while (cpuinfo.flags & CPUFLG_PAUSED)
/* spin */;
#endif
return;
case XPMSG_FUNC:
{
volatile struct xpmsg_func *p = &cpuinfo.msg.u.xpmsg_func;
p->retval = (*p->func)(p->arg0, p->arg1, p->arg2, p->arg3);
break;
}
}
cpuinfo.msg.tag = 0;
cpuinfo.flags |= CPUFLG_GOTMSG;
cpuinfo.msg_lev15.tag = 0;
#endif
}
@ -303,15 +296,6 @@ static void xcallintr(void *v)
{
switch (cpuinfo.msg.tag) {
case XPMSG_PAUSECPU:
/* XXX - assumes DDB is the only user of mp_pause_cpu() */
cpuinfo.flags |= CPUFLG_PAUSED|CPUFLG_GOTMSG;
#if defined(DDB)
__asm("ta 0x8b"); /* trap(T_DBPAUSE) */
#else
while (cpuinfo.flags & CPUFLG_PAUSED) /**/;
#endif
return;
case XPMSG_FUNC:
{
volatile struct xpmsg_func *p = &cpuinfo.msg.u.xpmsg_func;
@ -321,8 +305,8 @@ static void xcallintr(void *v)
break;
}
}
cpuinfo.msg.tag = 0;
cpuinfo.flags |= CPUFLG_GOTMSG;
cpuinfo.msg.tag = 0;
}
#endif /* MULTIPROCESSOR */
#endif /* SUN4M || SUN4D */

View File

@ -1,4 +1,4 @@
/* $NetBSD: trap.c,v 1.124 2003/01/06 18:32:31 pk Exp $ */
/* $NetBSD: trap.c,v 1.125 2003/01/07 16:20:14 mrg Exp $ */
/*
* Copyright (c) 1996
@ -292,7 +292,7 @@ trap(type, psr, pc, tf)
return;
}
}
#ifdef MULTIPROCESSOR
#if defined(MULTIPROCESSOR)
if (type == T_DBPAUSE) {
/* XXX - deal with kgdb too */
extern void ddb_suspend(struct trapframe *tf);