Start of the platform specific (RAWHIDE) machine check handler. This

is not really needed for this platform, except that we might want to
handle PCI errors which get reported through here. In any case, this
prints out more info than is usual. Will probably need to detune
this to be based upon DIAGNOSTIC defines.
This commit is contained in:
mjacob 1998-07-08 00:44:32 +00:00
parent 57190a7be7
commit 6f87cdce00

View File

@ -1,4 +1,4 @@
/* $NetBSD: dec_kn300.c,v 1.4 1998/05/05 20:10:05 mjacob Exp $ */
/* $NetBSD: dec_kn300.c,v 1.5 1998/07/08 00:44:32 mjacob Exp $ */
/*
* Copyright (c) 1998 by Matthew Jacob
@ -32,7 +32,7 @@
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
__KERNEL_RCSID(0, "$NetBSD: dec_kn300.c,v 1.4 1998/05/05 20:10:05 mjacob Exp $");
__KERNEL_RCSID(0, "$NetBSD: dec_kn300.c,v 1.5 1998/07/08 00:44:32 mjacob Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -44,6 +44,8 @@ __KERNEL_RCSID(0, "$NetBSD: dec_kn300.c,v 1.4 1998/05/05 20:10:05 mjacob Exp $")
#include <machine/autoconf.h>
#include <machine/conf.h>
#include <machine/bus.h>
#include <machine/frame.h>
#include <machine/cpuconf.h>
#include <dev/ic/comreg.h>
#include <dev/ic/comvar.h>
@ -53,13 +55,18 @@ __KERNEL_RCSID(0, "$NetBSD: dec_kn300.c,v 1.4 1998/05/05 20:10:05 mjacob Exp $")
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <alpha/mcbus/mcbusreg.h>
#include <alpha/mcbus/mcbusvar.h>
#include <alpha/pci/mcpciareg.h>
#include <alpha/pci/mcpciavar.h>
#include <alpha/pci/pci_kn300.h>
#include <machine/logout.h>
#include <dev/scsipi/scsi_all.h>
#include <dev/scsipi/scsipi_all.h>
#include <dev/scsipi/scsiconf.h>
#include "pckbd.h"
#ifndef CONSPEED
@ -70,6 +77,9 @@ static int comcnrate = CONSPEED;
void dec_kn300_init __P((void));
void dec_kn300_cons_init __P((void));
static void dec_kn300_device_register __P((struct device *, void *));
static void dec_kn300_mcheck_handler
__P((unsigned long, struct trapframe *, unsigned long, unsigned long));
#define ALPHASERVER_4100 "AlphaServer 4100"
const struct alpha_variation_table dec_kn300_variations[] = {
@ -94,6 +104,7 @@ dec_kn300_init()
platform.iobus = "mcbus";
platform.cons_init = NULL;
platform.device_register = dec_kn300_device_register;
platform.mcheck_handler = dec_kn300_mcheck_handler;
}
@ -292,3 +303,200 @@ dec_kn300_device_register(dev, aux)
}
}
}
/*
* KN300 Machine Check Handlers.
*/
static void kn300_softerr __P((unsigned long, unsigned long,
unsigned long, struct trapframe *));
static void kn300_mcheck __P((unsigned long, unsigned long,
unsigned long, struct trapframe *));
/*
* "soft" error structure in system area for KN300 processor.
* It differs from the EV5 'common' structure in a minor but
* exceedingly stupid and annoying fashion.
*/
typedef struct {
/*
* Should be mc_cc_ev5 structure. Contents are the same,
* just in different places.
*/
u_int64_t ei_stat;
u_int64_t ei_addr;
u_int64_t fill_syndrome;
u_int64_t isr;
/*
* Platform Specific Area
*/
u_int32_t whami;
u_int32_t sys_env;
u_int64_t mcpcia_regs;
u_int32_t pci_rev;
u_int32_t mc_err0;
u_int32_t mc_err1;
u_int32_t cap_err;
u_int32_t mdpa_stat;
u_int32_t mdpa_syn;
u_int32_t mdpb_stat;
u_int32_t mdpb_syn;
u_int64_t end_rsvd;
} mc_soft300;
#define CAP_ERR_CRDX 204
static void
kn300_softerr(mces, type, logout, framep)
unsigned long mces;
unsigned long type;
unsigned long logout;
struct trapframe *framep;
{
static const char *sys = "system";
static const char *proc = "processor";
int whami;
mc_hdr_ev5 *hdr;
mc_soft300 *ptr;
static const char *fmt1 = " %-25s = 0x%l016x\n";
hdr = (mc_hdr_ev5 *) logout;
ptr = (mc_soft300 *) (logout + sizeof (*hdr));
whami = alpha_pal_whami();
printf("kn300: CPU ID %d %s correctable error corrected by %s\n", whami,
(type == ALPHA_SYS_ERROR)? sys : proc,
((hdr->mcheck_code & 0xff00) == (EV5_CORRECTED << 16))? proc :
(((hdr->mcheck_code & 0xff00) == (CAP_ERR_CRDX << 16)) ?
"I/O Bridge Module" : sys));
printf(" Machine Check Code 0x%lx\n", hdr->mcheck_code);
printf(" Physical Addess of error %0xl016x", ptr->ei_addr);
if (ptr->ei_stat & 0x80000000L)
printf("Corrected ECC Error ");
if (ptr->ei_stat & 0x40000000L)
printf("in Memory ");
else
printf("in B-Cache ");
if (ptr->ei_stat & 0x400000000L)
printf("during I-Cache fill\n");
else
printf("during D-Cache fill\n");
printf(fmt1, "EI Status", ptr->ei_stat);
printf(fmt1, "Fill Syndrome", ptr->fill_syndrome);
printf(fmt1, "Interrupt Status Reg.", ptr->isr);
printf("\n");
printf(fmt1, "Whami Reg.", ptr->whami);
printf(fmt1, "Sys. Env. Reg.", ptr->sys_env);
printf(fmt1, "MCPCIA Regs.", ptr->mcpcia_regs);
printf(fmt1, "PCI Rev. Reg.", ptr->pci_rev);
printf(fmt1, "MC_ERR0 Reg.", ptr->mc_err0);
printf(fmt1, "MC_ERR1 Reg.", ptr->mc_err1);
printf(fmt1, "CAP_ERR Reg.", ptr->cap_err);
printf(fmt1, "MDPA_STAT Reg.", ptr->mdpa_stat);
printf(fmt1, "MDPA_SYN Reg.", ptr->mdpa_syn);
printf(fmt1, "MDPB_STAT Reg.", ptr->mdpb_stat);
printf(fmt1, "MDPB_SYN Reg.", ptr->mdpb_syn);
/*
* Clear error by rewriting register.
*/
alpha_pal_wrmces(mces);
}
/*
* KN300 specific machine check handler
*/
static void
kn300_mcheck(mces, type, logout, framep)
unsigned long mces;
unsigned long type;
unsigned long logout;
struct trapframe *framep;
{
struct mchkinfo *mcp;
static const char *fmt1 = " %-25s = 0x%l016x\n";
int i;
mc_hdr_ev5 *hdr;
mc_uc_ev5 *ptr;
struct mcpcia_iodsnap *iodsnp;
/*
* If we expected a machine check, just go handle it in common code.
*/
mcp = &mchkinfo[alpha_pal_whami()];
if (mcp->mc_expected) {
machine_check(mces, framep, type, logout);
return;
}
hdr = (mc_hdr_ev5 *) logout;
ptr = (mc_uc_ev5 *) (logout + sizeof (*hdr));
ev5_logout_print(hdr, ptr);
iodsnp = (struct mcpcia_iodsnap *) ((unsigned long) hdr +
(unsigned long) hdr->la_system_offset);
for (i = 0; i < MCPCIA_PER_MCBUS; i++, iodsnp++) {
if (!IS_MCPCIA_MAGIC(iodsnp->pci_rev)) {
continue;
}
printf(" IOD %d register dump:\n", i);
printf(fmt1, "Base Addr of PCI bridge", iodsnp->base_addr);
printf(fmt1, "Whami Reg.", iodsnp->whami);
printf(fmt1, "Sys. Env. Reg.", iodsnp->sys_env);
printf(fmt1, "PCI Rev. Reg.", iodsnp->pci_rev);
printf(fmt1, "CAP_CTL Reg.", iodsnp->cap_ctrl);
printf(fmt1, "HAE_MEM Reg.", iodsnp->hae_mem);
printf(fmt1, "HAE_IO Reg.", iodsnp->hae_io);
printf(fmt1, "INT_CTL Reg.", iodsnp->int_ctl);
printf(fmt1, "INT_REG Reg.", iodsnp->int_reg);
printf(fmt1, "INT_MASK0 Reg.", iodsnp->int_mask0);
printf(fmt1, "INT_MASK1 Reg.", iodsnp->int_mask1);
printf(fmt1, "MC_ERR0 Reg.", iodsnp->mc_err0);
printf(fmt1, "MC_ERR1 Reg.", iodsnp->mc_err1);
printf(fmt1, "CAP_ERR Reg.", iodsnp->cap_err);
printf(fmt1, "PCI_ERR1 Reg.", iodsnp->pci_err1);
printf(fmt1, "MDPA_STAT Reg.", iodsnp->mdpa_stat);
printf(fmt1, "MDPA_SYN Reg.", iodsnp->mdpa_syn);
printf(fmt1, "MDPB_STAT Reg.", iodsnp->mdpb_stat);
printf(fmt1, "MDPB_SYN Reg.", iodsnp->mdpb_syn);
}
/*
* Now that we've printed all sorts of useful information
* and have decided that we really can't do any more to
* respond to the error, go on to the common code for
* final disposition. Usually this means that we die.
*/
/*
* XXX: HANDLE PCI ERRORS HERE?
*/
machine_check(mces, framep, type, logout);
}
static void
dec_kn300_mcheck_handler(mces, framep, vector, param)
unsigned long mces;
struct trapframe *framep;
unsigned long vector;
unsigned long param;
{
switch (vector) {
case ALPHA_SYS_ERROR:
case ALPHA_PROC_ERROR:
kn300_softerr(mces, vector, param, framep);
break;
case ALPHA_SYS_MCHECK:
case ALPHA_PROC_MCHECK:
kn300_mcheck(mces, vector, param, framep);
break;
default:
printf("KN300_MCHECK: unknown check vector %x\n", vector);
machine_check(mces, framep, vector, param);
break;
}
}