📄 ka6200.c
字号:
#ifndef lintstatic char *sccsid = "@(#)ka6200.c 4.3 ULTRIX 2/28/91";#endif lint/************************************************************************ * * * Copyright (c) 1988 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: * * 26-Feb-91 jas * Mapped in XMI nodespace in ka6200conf(). Need to be able to * access nodespace. * * 18-Jun-90 jas * added support for XMA2 to xma routines. * * 30-Mar-90 jaw * recover from hard errors on ident command (passive release). * * 29-Nov-89 Paul Grist * modified ka6200machcheck() to call log_xmi_bierrors and log_xmierrors * to look for any pending XBI or VAXBI errors. Added log_ka6200memerrs * for outside callers to log xma errors (for log_bierrors). * * 10-Nov-89 jaw * move kmalloc of attach processors machdep structure to cca_startcpu. * * 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. * * 26-Jan-89 jaw * fix up start/stop cpu. * * 19-Aug-88 Tom Kong. * Changed ka6200machcheck so that instead of panicking, * we try to simply terminating the user process that * caused the machine check. For several cases of machine * checks, the instruction is simply retried and no process * is killed. Note that this only happens if KILL_USER is * defined. Otherwise the OS is killed. * * Took out "extern int (*vax8800bivec[])()" since it isn't * referenced in this file. * * 22-Jul-88 darrell Moved cca_send() and cca_setup() from this file * to cvax.c so that it can be shared by VAX60 * (Firefox) machine dependent code. * * 07-Jun-88 darrell Removed ka650.h from include files and added * cvax.h. * * 26-Apr-88 jaw fix to mcheck handler. * * 04-Feb-88 jaw work on soft error handling. * * 28-Jan-88 jaw Add logging for CRD's * **********************************************************************/#include "../machine/pte.h"#include "../h/param.h"#include "../h/conf.h"#include "../h/time.h"#include "../h/errno.h"#include "../h/systm.h"#include "../h/types.h"#include "../h/map.h"#include "../h/buf.h"#include "../h/errlog.h"#include "../h/ioctl.h"#include "../h/tty.h"#include "../h/cpudata.h"#include "../../machine/common/cpuconf.h"#include "../h/kmalloc.h"#include "../h/vmmac.h"#include "../machine/cons.h"#include "../machine/cons.h"#include "../machine/cpu.h"#include "../machine/clock.h"#include "../machine/mtpr.h"#include "../machine/mem.h"#include "../machine/nexus.h"#include "../machine/scb.h"#include "../io/uba/ubareg.h"#include "../io/uba/ubavar.h"#include "../io/bi/buareg.h"#include "../machine/sas/vmb.h"#include "../machine/ka6200.h"#include "../machine/cvax.h"#include "../io/xmi/xmireg.h"#include "../io/xmi/xmareg.h"/*#define KILL_USER */#ifdef KILL_USER/* * Need u symbols, ...etc to terminate user process */#include "../h/user.h" #include "../h/proc.h"#include "../machine/psl.h"#endifextern struct bidata bidata[];extern int cache_state;extern int nNVAXBI;extern char *ka6200_ip_addr;struct ssc_regs cvqssc[1]; /* SSC regs */struct v6200csr v6200csr[1];char *mccvax[] = { "unknown machine check type code", /* 0 */ "CFPA protocol error", /* 1 */ "CFPA reserved instruction", /* 2 */ "CFPA protocol error", /* 3 */ "CFPA protocol error", /* 4 */ "process PTE in P0 space during TB miss", /* 5 */ "process PTE in P1 space during TB miss", /* 6 */ "process PTE in P0 space during M = 0", /* 7 */ "process PTE in P1 space during M = 0", /* 8 */ "hardware interrupt at unused IPL", /* 9 */ "undefined MOVC3 or MOVC5 state", /* 10 */ "cache/memory/bus read error", /* 80 */ "SCB, PCB or SPTE read error", /* 81 */ "cache/memory/bus write error", /* 82 */ "PCB or SPTE write error", /* 83 */};/* * KA6200 machine check exception handler. * Environment: * IPL 0x1f * stack Interrupt stack * SCB vector <1:0> = 01. * * Parameter: * mcf Points to machine check frame. For Ka6200, the * frame format: * byte count (0x10) * mcheck code (1,2,3,4,5,6,7,8,9,a,80,81,82,or83) * internal state info 1 * internal state info 2 * PC * PSL * Returns: * 0 */ka6200machcheck (mcf)register struct el_mc6200frame *mcf;{ register int cpunum; register struct xcp_reg *xcp_node; int xminode, recover; struct xmidata *xmidata; register struct el_mc6200frame *framep; register struct el_rec *elrp; struct el_mck *elmckp; register unsigned int mcode; long time_now; struct xcp_machdep_data *mchk_data; /* Pointer to an array */ mchk_data =(struct xcp_machdep_data *) ( CURRENT_CPUDATA->cpu_machdep); time_now = mfpr(TODR); /* Log the current time */ recover = 0; /* Assume we have to panic */ cpunum=CURRENT_CPUDATA->cpu_num; if (mchk_data->mchk_in_progress == 0) { /* if no machine check in progress, we're ok */ mchk_data->mchk_in_progress++; } else { /* mcheck on another mcheck, we're in big trouble */ asm("halt"); } /* * Case of the type of machine check, we may be able * to recover from the machine check under certain conditions. */ mcode = ((struct mcframe *)mcf)->mc_summary; switch (mcode) { case 1: /* CFPA protocol error */ case 2: /* CFPA reserved instruction */ case 3: /* CFPA unknown error */ case 4: /* CFPA unknown error */ case 5: /* calculated virtual address of process PTE in P0 space */ /* TB miss flow */ case 6: /* calculated virtual address of process PTE in P1 space */ /* TB miss flow */ case 7: /* calculated virtual address of process PTE in P0 space */ /* M = 0 flow */ case 8: /* calculated virtual address of process PTE in P1 space */ /* M = 0 flow */ case 10:/* Impossible situations in microcode */#ifdef KILL_USER /* * The above errors are not recoverable. If we * are running a user process, the user process should * be killed. If we are running the OS, panic. * * Note: we assume we were running a user process during * the machine check if the saved PSL on the stack indicate * a current mode of USER, and that the process isn't "init". */ if (USERMODE(mcf->mc1_psl) && (u.u_procp->p_pid != 1)) { /* kill the user process */ swkill(u.u_procp, "ka6200machcheck"); recover = 1; /* don't have to panic */ }#endif break; case 0x80: /* read bus error, normal read */ case 0x81: /* read bus error, SPTE, PCB, or SCB read */ /* * The instruction is restartable for the above errors if: * 1) The saved PSL on the stack has FPD bit set, or * 2) The VAX CAN'T RESTART bit on the mcheck frame is clear. */ if (((mcf->mc1_psl & 0x08000000) == 0x08000000) || ((mcf->mc1_internal_state2 & 0x8000) == 0)) { /* * We can restart the instruction. * Decide to allow restart if one or more of the * following is satisfied: * 1) previous machine check was long ago. * 2) previous machine check was different. */ if (time_now - mchk_data->time > 1000) { /* last mcheck was at least 10 secs ago */ recover = 1; } if (mchk_data->code != mcf->mc1_summary) recover = 1; /* * if recover == 1 (we are retrying the instruction) * we should (in future) map out the bad physical * page here. */ } if (!recover) { /* * The instruction is not restartable, we * need to kill the user process or the operating * system. */#ifdef KILL_USER if (USERMODE(mcf->mc1_psl) && (u.u_procp->p_pid !=1)) { swkill(u.u_procp,"ka6200machcheck"); recover = 1; /* kill user, but don't panic */ /* * In addition to killing the user process, * we should map out the bad physical page in * the future. Do it here. */ }#endif } break; case 0x82: /* write bus error, normal write */ case 0x83: /* write bus error, SPTE or PCB write */ /* * The instruction is not restartable, we * need to kill the user process or the operating * system. */#ifdef KILL_USER if (USERMODE(mcf->mc1_psl) && (u.u_procp->p_pid !=1)) { swkill(u.u_procp,"ka6200machcheck"); recover = 1; /* kill user, but don't panic */ /* * In addition to killing the user process, * we should map out the bad physical page in * the future. Do it here. */ }#endif break; case 9: /* Interrupt controller requests an interrupt at an unused */ /* IPL (IPL 0x18,0x19,and 0x1b) */ default: /* Unknown machine check type code */ /* Panic on the above errors */ break; } /* * Log the machine check in the error log. */ xmidata = get_xmi(0);/* get pointer to xcp node that machine checked */ xcp_node =(struct xcp_reg *)xmidata->xmivirt+(v6200csr->csr1 & 0xf); /* allocate a error log packet */ elrp = ealloc((sizeof(struct el_mc6200frame)), recover ? EL_PRIHIGH:EL_PRISEVERE); if (elrp) { LSUBID(elrp,ELCT_MCK,ELMCKT_6200,cpu_subtype,cpunum,EL_UNDEF, mcf->mc1_summary); elmckp = &elrp->el_body.elmck; framep = (struct el_mc6200frame *) &elmckp->elmck_frame. el6200mcf.mc1_bcnt; framep->mc1_bcnt = mcf->mc1_bcnt; framep->mc1_summary = mcf->mc1_summary; framep->mc1_vap = mcf->mc1_vap; framep->mc1_internal_state1 = mcf->mc1_internal_state1; framep->mc1_internal_state2 = mcf->mc1_internal_state2; framep->mc1_pc = mcf->mc1_pc; framep->mc1_psl = mcf->mc1_psl; framep->xcp_dtype = xcp_node->xcp_dtype; framep->xcp_xbe = xcp_node->xcp_xbe; framep->xcp_csr2 = xcp_node->xcp_csr2; framep->xcp_csr1 = v6200csr->csr1; framep->xcp_mser = mfpr(MSER); EVALID(elrp); /* Make error log packet valid */ } /* look for any pending XMI errors */ log_xmierrors(0,mcf->mc1_pc); log_xmi_bierrors(0,mcf->mc1_pc); /* * if not recovering then we print the machine check frame to * console device, and then panic. */ if (!recover) { cprintf("cpu %x ",(v6200csr->csr1 & 0xf)); if ( mcode > 10) { mcode = mcode - 0x75; if (mcode >14) mcode = 0; } cprintf("%s\n", mccvax[mcode]); cprintf("\tcode\t\t= %x\n", mcf->mc1_summary); cprintf("\tmost recent virtual addr\t=%x\n", mcf->mc1_vap); cprintf("\tinternal state 1\t=%x\n", mcf->mc1_internal_state1); cprintf("\tinternal state 2\t=%x\n", mcf->mc1_internal_state2); cprintf("\tpc\t\t= %x\n", mcf->mc1_pc); cprintf("\tpsl\t\t= %x\n\n", mcf->mc1_psl); xma_check_errors(xcp_node,EL_PRISEVERE); panic("mchk"); } else { /* We are trying to recover */ ka6200_enable_cache(); /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -