V10/lsys/md/mcrcomet.c
/*
* comet memory controller
*/
#include "sys/param.h"
#include "sys/systm.h"
#include "sys/nxaddr.h"
/*
* intentional overlays:
* if no memory controller configured,
* mcrcnt will be 0
* but there will be no undefined symbols
*/
int mcrcnt;
struct nxaddr mcraddr[1]; /* one or more */
caddr_t mcrregs[1]; /* one or more */
time_t mcrtime[1]; /* one or more */
int mcrtimeout = 60; /* seconds between soft error reports */
struct device {
long csr0;
long csr1;
long csr2;
};
/*
* csr0
*/
#define HARDERR 0x80000000 /* uncorrectable error */
#define HARDLST 0x40000000 /* nested hard error */
#define SOFTERR 0x20000000 /* corrected error */
/*
* csr1
*/
#define CRDENB 0x10000000 /* enable reporting soft errors */
mcrinit()
{
register int i;
register struct device *m;
for (i = 0; i < mcrcnt; i++)
if ((m = (struct device *)nxaddr(&mcraddr[i])) == NULL
|| badaddr(&m->csr0, sizeof(long)))
printf("mcr%d absent\n", i);
else {
mcrregs[i] = (caddr_t)m;
mcrenable((caddr_t)m);
}
}
mcrenable(mm)
caddr_t mm;
{
((struct device *)mm)->csr1 = CRDENB;
}
memerr()
{
register int i;
register struct device *m;
long csr[3];
if (mcrcnt == 0) {
printf("mem err, no controllers configured\n");
return; /* and hope */
}
for (i = 0; i < mcrcnt; i++) {
if ((m = (struct device *)mcrregs[i]) == NULL)
continue;
if (m->csr0 & (HARDERR|SOFTERR)) {
csr[0] = m->csr0;
csr[1] = m->csr1;
csr[2] = m->csr2;
m->csr0 = m->csr0;
if (mcrtime[i] != time)
mcrtime[i] = time;
else {
m->csr1 = 0;
timeout(mcrenable, (caddr_t)m, mcrtimeout*HZ);
}
printf("mcr%d: mem %s error %x %x %x\n", i,
csr[0]&HARDERR?"hard":"soft", csr[0], csr[1], csr[2]);
if (csr[0]&HARDERR)
panic("memerr");
}
}
}