- 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:
parent
02d686d112
commit
88f08d9ac1
@ -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[] = {
|
||||
/*
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user