* 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:
parent
2b59d26892
commit
83dae8a821
|
@ -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)
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue