📄 ka8600.c
字号:
#ifndef lintstatic char *sccsid = "@(#)ka8600.c 4.1 ULTRIX 7/2/90";#endif lint/************************************************************************ * * * Copyright (c) 1984,85,86 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//*********************************************************************** * * Modification History: * * 27-Nov-89 Paul Grist * added frame_type argument to logmck() call. * * 31-May-89 darrell * Changed the call to tocons to call cons_putc. * * 24-May-89 darrell * Changed the #include for cpuconf.h to find it in it's new home -- * sys/machine/common/cpuconf.h * * 24-May-89 darrell * Removed the v_ prefix from all cpusw fields, removed cpup from any * arguments being passed in function args. cpup is now defined * globally -- as part of the new cpusw. * * 13-Jun-86 bjg * Initialize genp in genserver(); also change treshhold checking * * 11-Jun-86 bjg * add sbi# to cprintf string * * 16-Apr-86 darrell * moved structure and header file type things into ka8600.h * * 12-Apr-86 bjg * Check that ioav is mapped before accessing (ka8600logsbi). * * 15-Mar-86 Darrell Dunnuck * Moved ka8600 specific parts of configure() here into ka8600conf. * * 12-Mar-86 -- bjg * moved sbi logging routines to ka8600.c from kern_errlog.c * * 05-Mar-86 -- pmk * added arg recover to logmck and replaced display with cprintf * * 18-Mar-86 -- jaw add routines to cpu switch for nexus/unibus addreses * also got rid of some globals like nexnum. * * 12-Feb-86 Darrell Dunnuck * Removed the routines memerr, memenable, setcache, and tocons * from machdep.c and put them here for this processor type. * Added a new routine cachenbl. * * 12-Dec-85 Darrell Dunnuck * Created this file to as part of machdep restructuring. * **********************************************************************/#include "../../machine/common/cpuconf.h"#include "../h/types.h"#include "../h/time.h"#include "../h/param.h"#include "../machine/cons.h"#include "../h/errlog.h"#include "../machine/mtpr.h"#include "../machine/cpu.h"#include "../machine/mem.h"#include "../machine/pte.h"#include "../machine/nexus.h"#include "../io/uba/ubareg.h"#include "../machine/ioa.h"#include "../machine/ka8600.h"extern long sbi_there; /* defined in autoconf.c */extern int nexusinfo(); /* defined in errlog.c */extern struct cpusw *cpup; /* pointer to cpusw entry */int mem_err_report; /* state of memory error reporting */int memerrs = 0; /* number of times memerr has been entered */struct ibox_errcnt ibox_errcnt;struct fbox_errcnt fbox_errcnt;struct ebox_errcnt ebox_errcnt;struct mbox_errcnt mbox_errcnt;struct tb_errcnt tb_errcnt;struct csh_errcnt csh_errcnt;struct mbox_1d_errcnt mbox_1d_errcnt;struct generic_errcnt generic_errcnt;ka8600machcheck (cmcf)caddr_t cmcf;{ register struct mc8600frame *mcf = (struct mc8600frame *) cmcf; int dbl = 0; /* * Due to write back cache, cache SHOULD NOT be disabled * on an 8600. */ if(mcf->mc8600_ebcs & M_MBOX_FE) mcf->mc8600_ehm_sts |= C_MBOX; if(mcf->mc8600_ehm_sts & M_FBOX) if ((mcf->mc8600_ehm_sts & 0xf) == 0) mcf->mc8600_ehm_sts |= C_FBOX; else dbl++; if(mcf->mc8600_ebcs & EBOX_ERR_MASK) if ((mcf->mc8600_ehm_sts & 0xf) == 0) if(mcf->mc8600_ebcs & M_EDP_PE) mcf->mc8600_ehm_sts |= C_MBOX; else mcf->mc8600_ehm_sts |= C_EBOX; else dbl++; if(mcf->mc8600_ehm_sts & M_IBOX_ERR) if ((mcf->mc8600_ehm_sts & 0xf) == 0) mcf->mc8600_ehm_sts |= C_IBOX; else dbl++; if((mcf->mc8600_cslint & M_MBOX_1D) == M_MBOX_1D) if ((mcf->mc8600_ehm_sts & 0xf) == 0) mcf->mc8600_ehm_sts |= C_MBOX_1D; else dbl++; if (dbl) { badmchk(mcf); panic("Too many machine check errors to recover... \n"); } else { switch(mcf->mc8600_ehm_sts & C_MCHK_MASK) { case C_FBOX: fboxserv(mcf); break; case C_EBOX: eboxserv(mcf); break; case C_IBOX: iboxserv(mcf); break; case C_MBOX: mboxserv(mcf); break; case C_TB_ERR: case C_MBOX_1D: genericserv(mcf); break; default: cprintf("unknown machine check type %x\n", (mcf->mc8600_ehm_sts & C_MCHK_MASK)); badmchk(mcf); panic("mchk"); } } if(mcf->mc8600_ebcs & M_ABORT_MASK) { badmchk(mcf); panic("VAX state lost...not recoverable\n"); } logmck((int *)cmcf, ELMCKT_8600, 0, 1); mtpr (EHSR, 0); /* Clear EHSR - resets the VMS entered bit */ return(0);}/* * badmchk is called when we have an unrecoverable machine check, * and we need to log the machine check stack frame to the console */badmchk(mcf)register struct mc8600frame *mcf;{ logmck((int *)mcf, ELMCKT_8600, 0, 0); cprintf("\nmachine check %x: %s\n",(mcf->mc8600_ehm_sts & 0xf), mc8600[(mcf->mc8600_ehm_sts & 0xf)]); cprintf("\tehm.sts\t= %x\n", mcf->mc8600_ehm_sts); cprintf("\tevmqsav\t= %x\n", mcf->mc8600_evmqsav); cprintf("\tebcs\t= %x\n", mcf->mc8600_ebcs); cprintf("\tedpsr\t= %x\n", mcf->mc8600_edpsr); cprintf("\tcslint\t= %x\n", mcf->mc8600_cslint); cprintf("\tibesr\t= %x\n", mcf->mc8600_ibesr); cprintf("\tebxwd1\t= %x\n", mcf->mc8600_ebxwd1); cprintf("\tebxwd2\t= %x\n", mcf->mc8600_ebxwd2); cprintf("\tivasav\t= %x\n", mcf->mc8600_ivasav); cprintf("\tvibasav\t= %x\n", mcf->mc8600_vibasav); cprintf("\tesasav\t= %x\n", mcf->mc8600_esasav); cprintf("\tisasav\t= %x\n", mcf->mc8600_isasav); cprintf("\tcpc\t= %x\n", mcf->mc8600_cpc); cprintf("\tmstat1\t= %x\n", mcf->mc8600_mstat1); cprintf("\tmstat2\t= %x\n", mcf->mc8600_mstat2); cprintf("\tmdecc\t= %x\n", mcf->mc8600_mdecc); cprintf("\tmerg\t= %x\n", mcf->mc8600_merg); cprintf("\tcshctl\t= %x\n", mcf->mc8600_cshctl); cprintf("\tmear\t= %x\n", mcf->mc8600_mear); cprintf("\tmedr\t= %x\n", mcf->mc8600_medr); cprintf("\taccs\t= %x\n", mcf->mc8600_accs); cprintf("\tcses\t= %x\n", mcf->mc8600_cses); cprintf("\tpc\t= %x\n", mcf->mc8600_pc); cprintf("\tpsl\t= %x\n", mcf->mc8600_psl);}/* iboxserv is used to service ibox errors as part of machine check * recovery. If there are three ibox errors within IBOX_THRESH * we panic and die. */iboxserv(mcf)register struct mc8600frame *mcf;{ struct ibox_errcnt *iboxp; int time; iboxp = &ibox_errcnt; time = mfpr(TODR); iboxp->ibox_total++; if((time - iboxp->ibox_prev) <= IBOX_THRESH) { badmchk(mcf); panic("Too many IBOX errors to recover...\n"); } else { iboxp->ibox_prev = iboxp->ibox_last; iboxp->ibox_last = time; }}/* * mboxserv is used to service mbox fatal errors. We will panic and * die on all mbox fatal errors for now. */mboxserv(mcf)register struct mc8600frame *mcf;{ struct mbox_errcnt *mboxp; int time; mboxp = &mbox_errcnt; time = mfpr(TODR); /* always panic on MBOX_FE for now */ badmchk(mcf); panic("Too many MBOX errors to recover...\n");}/* * fboxserv turns off the FBOX if there are three errors within * the time of FBOX_THRESH. */fboxserv(mcf)register struct mc8600frame *mcf;{ struct fbox_errcnt *fboxp; int time; fboxp = &fbox_errcnt; time = mfpr(TODR); fboxp->fbox_total++; if((time - fboxp->fbox_prev) <= FBOX_THRESH) { mtpr(ACCS, 0); printf("FBOX turned off due to errors\n"); } else { fboxp->fbox_prev = fboxp->fbox_last; fboxp->fbox_last = time; }}/* * eboxserv services ebox errors. First check to see of this is * really an MBOX problem. If three EBOX errors occur during * the time of EBOX_THRESH, panic. */eboxserv(mcf)register struct mc8600frame *mcf;{ struct ebox_errcnt *eboxp; int time; eboxp = &ebox_errcnt; time = mfpr(TODR); if(mcf->mc8600_ebcs & M_EDP_PE) mboxserv(); else { eboxp->ebox_total++; if ((time - eboxp->ebox_prev) <= EBOX_THRESH) { badmchk(mcf); panic("Too many EBOX errors to recover...\n"); } else { eboxp->ebox_prev = eboxp->ebox_last; eboxp->ebox_last = time; } }}/* * genericserv services all other types of machinechecks for now. * We will check the abort bits, log the error and rei. If we find * ourselves back here twice within GENERIC_THRESH, panic. */genericserv(mcf)register struct mc8600frame *mcf;{ struct generic_errcnt *genp; int time; genp = &generic_errcnt; time = mfpr(TODR); genp->gen_total++; if ((time - genp->gen_prev) <= GENERIC_THRESH) { badmchk(mcf); panic("Too many generic machine checks to recover\n"); } else { genp->gen_prev = genp->gen_last; genp->gen_last = time; }}/* * Function: * ka8600memerr() * * Description: * log memory errors in kernel buffer * * Arguments: * none * * Return value: * none * * Side effects: * none */u_long pammdata = 0;ka8600memerr(){ /* * PLEASE NOTE!!!! * * DO NOT put any register definitions in front of the * definition for "reg_11". The definition for "reg_11" MUST * be the FIRST register defined in this routine!!! * "reg_11" is in fact general register 11, * and must remain as such so that we know where the data * returned from the mfpr in the following is going to be put */ /* * At the time of a single bit error the * memory registers are written into scratch pad
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -