Split 3max (kn02) and 3maxplus (kn03, kn05) memory-error handling out
dec_3max.c into a shared file. These models have compatible memory subsystems, the same memory slots, and (apparently) the same error reporting. Add markers for where MNN probes for configurations with a mixture of RAM sizes and for Prestoserve NVRAM (in normal RAM slots) should go.
This commit is contained in:
parent
3ef999a19b
commit
0e0d7a04aa
@ -1,4 +1,4 @@
|
||||
# $NetBSD: files.pmax,v 1.51 1998/03/25 04:17:09 jonathan Exp $
|
||||
# $NetBSD: files.pmax,v 1.52 1998/03/29 01:12:14 jonathan Exp $
|
||||
# DECstation-specific configuration info
|
||||
|
||||
# maxpartitions must be first item in files.${ARCH}.
|
||||
@ -41,10 +41,9 @@ file arch/pmax/pmax/dec_maxine.c dec_maxine # DS5000/1xx, maxine
|
||||
#file arch/pmax/pmax/dec_5100.c dec_5100 # kn230, mipsmate
|
||||
#file arch/pmax/pmax/dec_5800.c dec_5800 # 5800, isis
|
||||
|
||||
# handlers for memory subsystems shared across models..
|
||||
file arch/pmax/pmax/dec_kn02_subr.c dec_3min|dec_maxine
|
||||
|
||||
#
|
||||
#
|
||||
file arch/pmax/pmax/dec_3max_subr.c dec_3max|dec_3maxplus
|
||||
|
||||
#
|
||||
# Bus-independent support for DEC devices
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dec_3max.c,v 1.3 1998/03/26 12:46:34 jonathan Exp $ */
|
||||
/* $NetBSD: dec_3max.c,v 1.4 1998/03/29 01:12:15 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Jonathan Stone. All rights reserved.
|
||||
@ -73,7 +73,7 @@
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_3max.c,v 1.3 1998/03/26 12:46:34 jonathan Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_3max.c,v 1.4 1998/03/29 01:12:15 jonathan Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
@ -96,7 +96,7 @@ __KERNEL_RCSID(0, "$NetBSD: dec_3max.c,v 1.3 1998/03/26 12:46:34 jonathan Exp $"
|
||||
#include <pmax/pmax/machdep.h> /* XXXjrs replace with vectors */
|
||||
|
||||
#include <pmax/pmax/kn02.h>
|
||||
|
||||
#include <pmax/pmax/dec_3max_subr.h>
|
||||
|
||||
|
||||
/*
|
||||
@ -328,49 +328,21 @@ dec_3max_intr(mask, pc, statusReg, causeReg)
|
||||
|
||||
|
||||
/*
|
||||
* Handle Memory error.
|
||||
* 3max has ECC, correct single-bit error, panic on
|
||||
* double-bit error.
|
||||
* Handle Memory error. 3max, 3maxplus has ECC.
|
||||
* Correct single-bit error, panic on double-bit error.
|
||||
* XXX on double-error on clean user page, mark bad and reload frame?
|
||||
*/
|
||||
static void
|
||||
dec_3max_errintr()
|
||||
{
|
||||
u_int erradr, chksyn, physadr;
|
||||
u_int erradr, errsyn;
|
||||
|
||||
/* Fetch error address, ECC chk/syn bits, clear interrupt */
|
||||
erradr = *(u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR);
|
||||
chksyn = *(u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN);
|
||||
errsyn = *(u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN);
|
||||
*(u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0;
|
||||
wbflush();
|
||||
|
||||
if (!(erradr & KN02_ERR_VALID))
|
||||
return;
|
||||
/* extract the physical word address and compensate for pipelining */
|
||||
physadr = erradr & KN02_ERR_ADDRESS;
|
||||
if (!(erradr & KN02_ERR_WRITE))
|
||||
physadr = (physadr & ~0xfff) | ((physadr & 0xfff) - 5);
|
||||
physadr <<= 2;
|
||||
printf("%s memory %s %s error at 0x%08x\n",
|
||||
(erradr & KN02_ERR_CPU) ? "CPU" : "DMA",
|
||||
(erradr & KN02_ERR_WRITE) ? "write" : "read",
|
||||
(erradr & KN02_ERR_ECCERR) ? "ECC" : "timeout",
|
||||
physadr);
|
||||
if (erradr & KN02_ERR_ECCERR) {
|
||||
*(u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN) = 0;
|
||||
wbflush();
|
||||
printf("ECC 0x%08x\n", chksyn);
|
||||
|
||||
/* check for a corrected, single bit, read error */
|
||||
if (!(erradr & KN02_ERR_WRITE)) {
|
||||
if (physadr & 0x4) {
|
||||
/* check high word */
|
||||
if (chksyn & KN02_ECC_SNGHI)
|
||||
return;
|
||||
} else {
|
||||
/* check low word */
|
||||
if (chksyn & KN02_ECC_SNGLO)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
panic("Mem error interrupt");
|
||||
/* Send to kn02/kn03 memory subsystem handler */
|
||||
dec_mtasic_err(erradr, errsyn);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dec_3max_subr.c,v 1.3 1998/03/26 12:46:34 jonathan Exp $ */
|
||||
/* $NetBSD: dec_3max_subr.c,v 1.4 1998/03/29 01:12:15 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Jonathan Stone. All rights reserved.
|
||||
@ -30,317 +30,29 @@
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* the Systems Programming Group of the University of Utah Computer
|
||||
* Science Department, The Mach Operating System project at
|
||||
* Carnegie-Mellon University and Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)machdep.c 8.3 (Berkeley) 1/12/94
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_3max_subr.c,v 1.3 1998/03/26 12:46:34 jonathan Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_3max_subr.c,v 1.4 1998/03/29 01:12:15 jonathan Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/intr.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/psl.h>
|
||||
#include <machine/locore.h> /* wbflush() */
|
||||
#include <machine/autoconf.h> /* intr_arg_t */
|
||||
#include <machine/sysconf.h>
|
||||
|
||||
#include <mips/mips_param.h> /* hokey spl()s */
|
||||
#include <mips/mips/mips_mcclock.h> /* mcclock CPUspeed estimation */
|
||||
|
||||
#include <pmax/pmax/clockreg.h>
|
||||
#include <pmax/pmax/asic.h>
|
||||
#include <pmax/pmax/turbochannel.h>
|
||||
#include <pmax/pmax/pmaxtype.h>
|
||||
#include <pmax/pmax/machdep.h> /* XXXjrs replace with vectors */
|
||||
|
||||
#include <pmax/pmax/kn02.h>
|
||||
|
||||
|
||||
#include <pmax/pmax/kn02.h> /* error-register defs copied into kn03.h */
|
||||
#include <pmax/pmax/dec_3max_subr.h>
|
||||
|
||||
/*
|
||||
* forward declarations
|
||||
* the 3max and 3maxplus have compatible memory subsystems;
|
||||
* we handle them both here.
|
||||
*/
|
||||
void dec_3max_init __P((void));
|
||||
void dec_3max_os_init __P((void));
|
||||
void dec_3max_bus_reset __P((void));
|
||||
|
||||
void dec_3max_enable_intr
|
||||
__P ((u_int slotno, int (*handler) __P((intr_arg_t sc)),
|
||||
intr_arg_t sc, int onoff));
|
||||
int dec_3max_intr __P((u_int mask, u_int pc,
|
||||
u_int statusReg, u_int causeReg));
|
||||
void dec_3max_cons_init __P((void));
|
||||
void dec_3max_device_register __P((struct device *, void *));
|
||||
|
||||
static void dec_3max_errintr __P((void));
|
||||
|
||||
|
||||
/*
|
||||
* Fill in platform struct.
|
||||
*/
|
||||
void
|
||||
dec_3max_init()
|
||||
{
|
||||
|
||||
platform.iobus = "tcbus";
|
||||
|
||||
platform.os_init = dec_3max_os_init;
|
||||
platform.bus_reset = dec_3max_bus_reset;
|
||||
platform.cons_init = dec_3max_cons_init;
|
||||
platform.device_register = dec_3max_device_register;
|
||||
|
||||
strcpy(cpu_model, "DECstation 5000/200 (3MAX)");
|
||||
|
||||
dec_3max_os_init();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dec_3max_os_init()
|
||||
dec_mtasic_err(erradr, errsyn)
|
||||
u_int erradr, errsyn;
|
||||
{
|
||||
register int i;
|
||||
|
||||
volatile int *csr_addr =
|
||||
(volatile int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
|
||||
|
||||
/* clear any memory errors from new-config probes */
|
||||
*(volatile u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0;
|
||||
wbflush();
|
||||
|
||||
/*
|
||||
* Enable ECC memory correction, turn off LEDs, and
|
||||
* disable all TURBOchannel interrupts.
|
||||
*/
|
||||
i = *csr_addr;
|
||||
*csr_addr = (i & ~(KN02_CSR_WRESERVED | KN02_CSR_IOINTEN)) |
|
||||
KN02_CSR_CORRECT | 0xff;
|
||||
mips_hardware_intr = dec_3max_intr;
|
||||
tc_enable_interrupt = dec_3max_enable_intr;
|
||||
Mach_splbio = Mach_spl0;
|
||||
Mach_splnet = Mach_spl0;
|
||||
Mach_spltty = Mach_spl0;
|
||||
Mach_splimp = Mach_spl0;
|
||||
Mach_splclock = cpu_spl1;
|
||||
Mach_splstatclock = cpu_spl1;
|
||||
mcclock_addr = (volatile struct chiptime *)
|
||||
MIPS_PHYS_TO_KSEG1(KN02_SYS_CLOCK);
|
||||
|
||||
mc_cpuspeed(mcclock_addr, MIPS_INT_MASK_1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Initalize the memory system and I/O buses.
|
||||
*/
|
||||
void
|
||||
dec_3max_bus_reset()
|
||||
{
|
||||
/*
|
||||
* Reset interrupts, clear any errors from newconf probes
|
||||
*/
|
||||
|
||||
*(volatile u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0;
|
||||
wbflush();
|
||||
|
||||
*(u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN) = 0;
|
||||
wbflush();
|
||||
}
|
||||
|
||||
void
|
||||
dec_3max_cons_init()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
dec_3max_device_register(dev, aux)
|
||||
struct device *dev;
|
||||
void *aux;
|
||||
{
|
||||
panic("dec_3max_device_register unimplemented");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Enable/Disable interrupts for a TURBOchannel slot on the 3MAX.
|
||||
*/
|
||||
void
|
||||
dec_3max_enable_intr(slotno, handler, sc, on)
|
||||
register u_int slotno;
|
||||
int (*handler) __P((void* softc));
|
||||
void *sc;
|
||||
int on;
|
||||
{
|
||||
register volatile int *p_csr =
|
||||
(volatile int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
|
||||
int csr;
|
||||
int s;
|
||||
|
||||
#if 0
|
||||
printf("3MAX enable_intr: imask %x, %sabling slot %d, sc %p\n",
|
||||
kn03_tc3_imask, (on? "en" : "dis"), slotno, sc);
|
||||
#endif
|
||||
|
||||
if (slotno > TC_MAX_LOGICAL_SLOTS)
|
||||
panic("kn02_enable_intr: bogus slot %d\n", slotno);
|
||||
|
||||
if (on) {
|
||||
/*printf("kn02: slot %d handler 0x%x\n", slotno, handler);*/
|
||||
tc_slot_info[slotno].intr = handler;
|
||||
tc_slot_info[slotno].sc = sc;
|
||||
} else {
|
||||
tc_slot_info[slotno].intr = 0;
|
||||
tc_slot_info[slotno].sc = 0;
|
||||
}
|
||||
|
||||
slotno = 1 << (slotno + KN02_CSR_IOINTEN_SHIFT);
|
||||
s = Mach_spl0();
|
||||
csr = *p_csr & ~(KN02_CSR_WRESERVED | 0xFF);
|
||||
if (on)
|
||||
*p_csr = csr | slotno;
|
||||
else
|
||||
*p_csr = csr & ~slotno;
|
||||
splx(s);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Handle hardware interrupts for the KN02. (DECstation 5000/200)
|
||||
* Returns spl value.
|
||||
*/
|
||||
int
|
||||
dec_3max_intr(mask, pc, statusReg, causeReg)
|
||||
unsigned mask;
|
||||
unsigned pc;
|
||||
unsigned statusReg;
|
||||
unsigned causeReg;
|
||||
{
|
||||
register unsigned i, m;
|
||||
register volatile struct chiptime *c =
|
||||
(volatile struct chiptime *) MIPS_PHYS_TO_KSEG1(KN02_SYS_CLOCK);
|
||||
register unsigned csr;
|
||||
int temp;
|
||||
struct clockframe cf;
|
||||
static int warned = 0;
|
||||
|
||||
/* handle clock interrupts ASAP */
|
||||
if (mask & MIPS_INT_MASK_1) {
|
||||
csr = *(unsigned *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
|
||||
if ((csr & KN02_CSR_PSWARN) && !warned) {
|
||||
warned = 1;
|
||||
printf("WARNING: power supply is overheating!\n");
|
||||
} else if (warned && !(csr & KN02_CSR_PSWARN)) {
|
||||
warned = 0;
|
||||
printf("WARNING: power supply is OK again\n");
|
||||
}
|
||||
|
||||
temp = c->regc; /* XXX clear interrupt bits */
|
||||
cf.pc = pc;
|
||||
cf.sr = statusReg;
|
||||
hardclock(&cf);
|
||||
intrcnt[HARDCLOCK]++;
|
||||
|
||||
/* keep clock interrupts enabled when we return */
|
||||
causeReg &= ~MIPS_INT_MASK_1;
|
||||
}
|
||||
|
||||
/* If clock interrups were enabled, re-enable them ASAP. */
|
||||
splx(MIPS_SR_INT_ENA_CUR | (statusReg & MIPS_INT_MASK_1));
|
||||
|
||||
if (mask & MIPS_INT_MASK_0) {
|
||||
static int intr_map[8] = { SLOT0_INTR, SLOT1_INTR, SLOT2_INTR,
|
||||
/* these two bits reserved */
|
||||
STRAY_INTR, STRAY_INTR,
|
||||
SCSI_INTR, LANCE_INTR,
|
||||
SERIAL0_INTR };
|
||||
|
||||
csr = *(unsigned *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR);
|
||||
m = csr & (csr >> KN02_CSR_IOINTEN_SHIFT) & KN02_CSR_IOINT;
|
||||
#if 0
|
||||
*(unsigned *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) =
|
||||
(csr & ~(KN02_CSR_WRESERVED | 0xFF)) |
|
||||
(m << KN02_CSR_IOINTEN_SHIFT);
|
||||
#endif
|
||||
for (i = 0; m; i++, m >>= 1) {
|
||||
if (!(m & 1))
|
||||
continue;
|
||||
intrcnt[intr_map[i]]++;
|
||||
if (tc_slot_info[i].intr)
|
||||
(*tc_slot_info[i].intr)(tc_slot_info[i].sc);
|
||||
else
|
||||
printf("spurious interrupt %d\n", i);
|
||||
}
|
||||
#if 0
|
||||
*(unsigned *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CSR) =
|
||||
csr & ~(KN02_CSR_WRESERVED | 0xFF);
|
||||
#endif
|
||||
}
|
||||
if (mask & MIPS_INT_MASK_3) {
|
||||
intrcnt[ERROR_INTR]++;
|
||||
dec_3max_errintr();
|
||||
}
|
||||
|
||||
return ((statusReg & ~causeReg & MIPS_HARD_INT_MASK) |
|
||||
MIPS_SR_INT_ENA_CUR);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Handle Memory error.
|
||||
* 3max has ECC, correct single-bit error, panic on
|
||||
* double-bit error.
|
||||
*/
|
||||
static void
|
||||
dec_3max_errintr()
|
||||
{
|
||||
u_int erradr, chksyn, physadr;
|
||||
|
||||
erradr = *(u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR);
|
||||
chksyn = *(u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN);
|
||||
*(u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_ERRADR) = 0;
|
||||
wbflush();
|
||||
u_int physadr;
|
||||
|
||||
if (!(erradr & KN02_ERR_VALID))
|
||||
return;
|
||||
@ -355,22 +67,36 @@ dec_3max_errintr()
|
||||
(erradr & KN02_ERR_ECCERR) ? "ECC" : "timeout",
|
||||
physadr);
|
||||
if (erradr & KN02_ERR_ECCERR) {
|
||||
*(u_int *)MIPS_PHYS_TO_KSEG1(KN02_SYS_CHKSYN) = 0;
|
||||
*(u_int *)errsyn = 0;
|
||||
wbflush();
|
||||
printf("ECC 0x%08x\n", chksyn);
|
||||
printf(" ECC 0x%08x\n", errsyn);
|
||||
|
||||
/* check for a corrected, single bit, read error */
|
||||
if (!(erradr & KN02_ERR_WRITE)) {
|
||||
if (physadr & 0x4) {
|
||||
/* check high word */
|
||||
if (chksyn & KN02_ECC_SNGHI)
|
||||
if (errsyn & KN02_ECC_SNGHI)
|
||||
return;
|
||||
} else {
|
||||
/* check low word */
|
||||
if (chksyn & KN02_ECC_SNGLO)
|
||||
if (errsyn & KN02_ECC_SNGLO)
|
||||
return;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
panic("Mem error interrupt");
|
||||
else
|
||||
printf("\n");
|
||||
panic("panic(\"Mem error interrupt\");\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Xxx noncontig memory probing with mixed-sized memory boards
|
||||
* XXX on 3max (kn02) or 3maxplus (kn03) belongs here.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Xxx any support for NVRAM (PrestoServe) modules in
|
||||
* XXX on 3max (kn02) or 3maxplus (kn03) memory slots probably belongs here,
|
||||
* since we need to not probe it as normal RAM.
|
||||
*/
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: dec_3maxplus.c,v 1.5 1998/03/26 12:46:34 jonathan Exp $ */
|
||||
/* $NetBSD: dec_3maxplus.c,v 1.6 1998/03/29 01:12:15 jonathan Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Jonathan Stone. All rights reserved.
|
||||
@ -73,7 +73,7 @@
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_3maxplus.c,v 1.5 1998/03/26 12:46:34 jonathan Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: dec_3maxplus.c,v 1.6 1998/03/29 01:12:15 jonathan Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/systm.h>
|
||||
@ -102,6 +102,7 @@ __KERNEL_RCSID(0, "$NetBSD: dec_3maxplus.c,v 1.5 1998/03/26 12:46:34 jonathan Ex
|
||||
|
||||
#include <pmax/pmax/kn03.h>
|
||||
#include <pmax/pmax/asic.h>
|
||||
#include <pmax/pmax/dec_3max_subr.h>
|
||||
|
||||
|
||||
/*
|
||||
@ -474,52 +475,23 @@ dec_3maxplus_intr(mask, pc, statusReg, causeReg)
|
||||
MIPS_SR_INT_ENA_CUR);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX share with 5000/200
|
||||
*/
|
||||
|
||||
/*
|
||||
* Handle Memory error. 3max, 3maxplus has ECC.
|
||||
* Correct single-bit error, panic on double-bit error.
|
||||
* XXX on double-error on clean user page, mark bad and reload frame?
|
||||
*/
|
||||
static void
|
||||
dec_3maxplus_errintr()
|
||||
{
|
||||
u_int erradr, errsyn, physadr;
|
||||
register u_int erradr, errsyn;
|
||||
|
||||
/* Fetch error address, ECC chk/syn bits, clear interrupt */
|
||||
erradr = *(u_int *)MIPS_PHYS_TO_KSEG1(KN03_SYS_ERRADR);
|
||||
errsyn = *(u_int *)MIPS_PHYS_TO_KSEG1(KN03_SYS_ERRSYN);
|
||||
*(u_int *)MIPS_PHYS_TO_KSEG1(KN03_SYS_ERRADR) = 0;
|
||||
wbflush();
|
||||
|
||||
if (!(erradr & KN03_ERR_VALID))
|
||||
return;
|
||||
/* extract the physical word address and compensate for pipelining */
|
||||
physadr = erradr & KN03_ERR_ADDRESS;
|
||||
if (!(erradr & KN03_ERR_WRITE))
|
||||
physadr = (physadr & ~0xfff) | ((physadr & 0xfff) - 5);
|
||||
physadr <<= 2;
|
||||
printf("%s memory %s %s error at 0x%08x",
|
||||
(erradr & KN03_ERR_CPU) ? "CPU" : "DMA",
|
||||
(erradr & KN03_ERR_WRITE) ? "write" : "read",
|
||||
(erradr & KN03_ERR_ECCERR) ? "ECC" : "timeout",
|
||||
physadr);
|
||||
if (erradr & KN03_ERR_ECCERR) {
|
||||
*(u_int *)MIPS_PHYS_TO_KSEG1(KN03_SYS_ERRSYN) = 0;
|
||||
wbflush();
|
||||
printf(" ECC 0x%08x\n", errsyn);
|
||||
|
||||
/* check for a corrected, single bit, read error */
|
||||
if (!(erradr & KN03_ERR_WRITE)) {
|
||||
if (physadr & 0x4) {
|
||||
/* check high word */
|
||||
if (errsyn & KN03_ECC_SNGHI)
|
||||
return;
|
||||
} else {
|
||||
/* check low word */
|
||||
if (errsyn & KN03_ECC_SNGLO)
|
||||
return;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
else
|
||||
printf("\n");
|
||||
printf("panic(\"Mem error interrupt\");\n");
|
||||
/* Send to kn02/kn03 memory subsystem handler */
|
||||
dec_mtasic_err(erradr, errsyn);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user