* map the PROM CPU mailbox if available.

* map MXCC error/status registers if available.
* add MXCC-specific module error interrupt handler.
* use high priority interrupt level in mp_pause_cpus()
This commit is contained in:
pk 2002-12-31 15:10:28 +00:00
parent 2b59d26892
commit 83dae8a821
2 changed files with 118 additions and 14 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.c,v 1.144 2002/12/28 02:35:56 mrg Exp $ */
/* $NetBSD: cpu.c,v 1.145 2002/12/31 15:10:28 pk Exp $ */
/*
* Copyright (c) 1996
@ -226,8 +226,13 @@ alloc_cpuinfo()
pmap_update(pmap_kernel());
bzero((void *)cpi, sz);
#if 0
cpi->eintstack = (void *)((vaddr_t)cpi + sz);
cpi->idle_u = (void *)((vaddr_t)cpi + sz - INT_STACK_SIZE - USPACE);
#else
cpi->eintstack = (void *)((vaddr_t)cpi + sz - USPACE);
cpi->idle_u = (void *)((vaddr_t)cpi + sz - USPACE);
#endif
return (cpi);
}
@ -290,10 +295,64 @@ cpu_mainbus_attach(parent, self, aux)
void *aux;
{
struct mainbus_attach_args *ma = aux;
int mid;
struct openprom_addr *rrp = NULL;
struct cpu_info *cpi;
int mid, node;
int error, n;
mid = (ma->ma_node != 0) ? PROM_getpropint(ma->ma_node, "mid", 0) : 0;
cpu_attach((struct cpu_softc *)self, ma->ma_node, mid);
node = ma->ma_node;
mid = (node != 0) ? PROM_getpropint(node, "mid", 0) : 0;
cpu_attach((struct cpu_softc *)self, node, mid);
cpi = ((struct cpu_softc *)self)->sc_cpuinfo;
/*
* Map CPU mailbox if available
*/
if (node != 0 && (error = PROM_getprop(node, "mailbox",
sizeof(struct openprom_addr),
&n, (void **)&rrp)) == 0) {
if (bus_space_map(ma->ma_bustag,
BUS_ADDR(rrp[0].oa_space, rrp[0].oa_base),
rrp[0].oa_size,
BUS_SPACE_MAP_LINEAR,
&cpi->mailbox) != 0)
panic("%s: can't map cpu mailbox", self->dv_xname);
free(rrp, M_DEVBUF);
}
/*
* Map Module Control Space if available
*/
if (cpi->mxcc == 0)
/* We only know what it means on MXCCs */
return;
rrp = NULL;
if (node == 0 || (error = PROM_getprop(node, "reg",
sizeof(struct openprom_addr),
&n, (void **)&rrp)) != 0)
return;
/* register set #0 is the MBus port register */
if (bus_space_map(ma->ma_bustag,
BUS_ADDR(rrp[0].oa_space, rrp[0].oa_base),
rrp[0].oa_size,
BUS_SPACE_MAP_LINEAR,
&cpi->ci_mbusport) != 0) {
panic("%s: can't map cpu regs", self->dv_xname);
}
/* register set #1: MCXX control */
if (bus_space_map(ma->ma_bustag,
BUS_ADDR(rrp[1].oa_space, rrp[1].oa_base),
rrp[1].oa_size,
BUS_SPACE_MAP_LINEAR,
&cpi->ci_mxccregs) != 0) {
panic("%s: can't map cpu regs", self->dv_xname);
}
/* register sets #3 and #4 are E$ cache data and tags */
free(rrp, M_DEVBUF);
}
#if defined(SUN4D)
@ -612,8 +671,7 @@ xcall(func, arg0, arg1, arg2, arg3, cpuset)
p->arg1 = arg1;
p->arg2 = arg2;
p->arg3 = arg3;
cpi->intreg_4m->pi_set = PINTR_SINTRLEV(13);/*xcall_cookie->pil*/
/*was: raise_ipi(cpi);*/
raise_ipi(cpi,13);/*xcall_cookie->pil*/
}
/*
@ -682,10 +740,9 @@ mp_pause_cpus()
if (CPU_NOTREADY(cpi))
continue;
simple_lock(&cpi->msg.lock);
cpi->msg.tag = XPMSG_PAUSECPU;
cpi->flags &= ~CPUFLG_GOTMSG;
cpi->intreg_4m->pi_set = PINTR_SINTRLEV(13);/*xcall_cookie->pil*/
raise_ipi(cpi,15); /* high priority intr */
}
UNLOCK_XPMSG();
}
@ -838,6 +895,9 @@ int hypersparc_get_asyncflt __P((u_int *, u_int *));
int cypress_get_asyncflt __P((u_int *, u_int *));
int no_asyncflt_regs __P((u_int *, u_int *));
int (*moduleerr_handler) __P((void));
int viking_module_error(void);
struct module_info module_unknown = {
CPUTYP_UNKNOWN,
VAC_UNKNOWN,
@ -1514,6 +1574,8 @@ viking_hotfix(sc)
sc->flags |= CPUFLG_CACHE_MANDATORY;
sc->zero_page = pmap_zero_page_viking_mxcc;
sc->copy_page = pmap_copy_page_viking_mxcc;
moduleerr_handler = viking_module_error;
/*
* Ok to cache PTEs; set the flag here, so we don't
* uncache in pmap_bootstrap().
@ -1550,6 +1612,37 @@ viking_mmu_enable()
pcr &= ~VIKING_PCR_TC;
sta(SRMMU_PCR, ASI_SRMMU, pcr);
}
int
viking_module_error(void)
{
u_int64_t v;
int n, fatal = 0;
/* Report on MXCC error registers in each module */
for (n = 0; n < ncpu; n++) {
struct cpu_info *cpi = cpus[n];
if (cpi->ci_mxccregs == 0) {
printf("\tMXCC registers not mapped\n");
continue;
}
printf("module%d:\n", cpi->ci_cpuid);
v = *((u_int64_t *)(cpi->ci_mxccregs + 0xe00));
printf("\tmxcc error 0x%llx\n", v);
v = *((u_int64_t *)(cpi->ci_mxccregs + 0xb00));
printf("\tmxcc status 0x%llx\n", v);
v = *((u_int64_t *)(cpi->ci_mxccregs + 0xc00));
printf("\tmxcc reset 0x%llx", v);
if (v & MXCC_MRST_WD)
printf(" (WATCHDOG RESET)"), fatal = 1;
if (v & MXCC_MRST_SI)
printf(" (SOFTWARE RESET)"), fatal = 1;
printf("\n");
}
return (fatal);
}
#endif /* SUN4M || SUN4D */
#if defined(SUN4D)

View File

@ -1,4 +1,4 @@
/* $NetBSD: intr.c,v 1.69 2002/12/23 00:55:18 pk Exp $ */
/* $NetBSD: intr.c,v 1.70 2002/12/31 15:10:28 pk Exp $ */
/*
* Copyright (c) 1992, 1993
@ -168,6 +168,7 @@ int (*moduleerr_handler) __P((void));
#if defined(MULTIPROCESSOR)
volatile int nmi_hard_wait = 0;
struct simplelock nmihard_lock = SIMPLELOCK_INITIALIZER;
int drop_into_rom_on_fatal = 1;
#endif
void
@ -204,11 +205,15 @@ nmi_hard()
;
return;
} else {
int n = 0;
int n = 100000;
while (nmi_hard_wait < ncpu)
if (n++ > 100000)
panic("nmi_hard: SMP botch.");
while (nmi_hard_wait < ncpu) {
DELAY(1);
if (n-- > 0)
continue;
printf("nmi_hard: SMP botch.");
break;
}
}
#endif
@ -247,6 +252,10 @@ nmi_hard()
simple_lock(&nmihard_lock);
nmi_hard_wait = 0;
simple_unlock(&nmihard_lock);
if (fatal && drop_into_rom_on_fatal) {
callrom();
return;
}
#endif
if (fatal)
@ -262,7 +271,7 @@ nmi_soft(tf)
{
/* XXX - Most of this is superseded by xcallintr() below */
#ifdef MULTIPROCESSOR
#if defined(MULTIPROCESSOR)
switch (cpuinfo.msg.tag) {
case XPMSG_SAVEFPU:
savefpstate(cpuinfo.fpproc->p_md.md_fpstate);
@ -286,6 +295,7 @@ nmi_soft(tf)
break;
}
}
cpuinfo.msg.tag = 0;
cpuinfo.flags |= CPUFLG_GOTMSG;
#endif
}
@ -316,6 +326,7 @@ static void xcallintr(void *v)
break;
}
}
cpuinfo.msg.tag = 0;
cpuinfo.flags |= CPUFLG_GOTMSG;
}
#endif /* MULTIPROCESSOR */