📄 ka60.c
字号:
char *ka60umaddr(ioadpt,nexnum) int ioadpt,nexnum;{ return(QMEMCVQ);}u_short *ka60udevaddr(ioadpt,nexnum) int ioadpt,nexnum;{ return(QDEVADDRCVQ);}/* * Machine check handler. * Called from locore thru the cpu switch in response to a trap at SCB 4 * We recover from any that we can if hardware "retry" is possible. */ka60machcheck (cmcf)caddr_t cmcf;{ register u_int type; register struct mcCVAXframe *mcf; register int *cacheptr; /* ptr to flush 2nd level cache */ register int *cacheend; /* ptr to end of 2nd level cache */ register int recover; /* set to 1 if we can recover from this error */ register u_int time; /* from TODR */ int cpunum; /* 0 for uniprocessor */ int retry; /* set to 1 if the hardware can retry the instr */ int ws_disp; /* type of work station display for ioctl call */ /* * Caches on Firefox are not disabled on a machine check. This is because * Firefox caches use a write back snoopy cache algorithm. */ /* * Do not allow recursive machine check. * Halt the processor, then a restart should get a dump. */ if (ka60_mchkprog == 0) ka60_mchkprog = 1; else { asm("halt"); } type = ((struct mcframe *) cmcf)->mc_summary; mcf = (struct mcCVAXframe *) cmcf; recover = 0; cpunum = 0; retry = 0; /* * First note the time; then determine if hardware retry is * possible, which will be used for the recoverable cases. */ time = ka60readtodr(); switch (type) { case 1: case 2: case 3: case 4: if (time - cfpa_errcnt.cfpa_prev > TIME_THRESH) { if (retry) recover = 1; } logmck((int *)cmcf, ELMCKT_CVAX, cpunum, recover); if (recover) { cfpa_errcnt.cfpa_prev = cfpa_errcnt.cfpa_last; cfpa_errcnt.cfpa_last = time; } else { ka60consprint(2,type,mcf); } break; case 5: case 6: case 7: case 8: case 9: case 10: logmck((int *)cmcf, ELMCKT_CVAX, cpunum, recover); ka60consprint(2,type,mcf); break; case 0x80: case 0x81: /* * There are several possible causes for this mcheck. * Check for which error caused the mcheck and take * appropriate action. */ if ((mfpr(MSER) & FF_MSER_MCD) != 0) { /* * If console is a graphics device, * force printf messages directly to screen. */ if (ws_display_type) { ws_disp = ws_display_type << 8; (*cdevsw[ws_display_type].d_ioctl)(ws_disp, QD_KERN_UNLOOP, 0, 0); } /* * Log the machine check, and the error status regs. * If we can recover update the times, * else print errors on the console. * Last, clear the error bits. */ logmck((int *)cmcf, ELMCKT_CVAX, cpunum, recover); ka60logesrpkt(recover); if (recover) { cdal_errcnt.cdal_prev = cdal_errcnt.cdal_last; cdal_errcnt.cdal_last = time; } else { ka60consprint(2,type,mcf); ka60consprint(3,0,0); } mtpr(MSER,1); } else if ((mfpr(MSER) & FF_MSER_MCC) != 0) { /* * 1st Level Cache Parity Err (CPU disables & flushes). * If recovery is possible, do so, else log and quit. */ if (retry) { recover = 1; logmck((int *)cmcf, ELMCKT_CVAX, cpunum, recover); mtpr(MSER,1); } else { logmck((int *)cmcf, ELMCKT_CVAX, cpunum, recover); ka60consprint(2,type,mcf); mtpr(MSER,1); break; /* out of switch */ } /* * Since we can recover update the times, */ cache_errcnt.cache_prev = cache_errcnt.cache_last; cache_errcnt.cache_last = time; } else { /* * Undefined Machine check 0x80, 0x81. * Log the mcheck, ESR Packet, & Mem Packet. * We can't recover so print errors on the console. */ logmck((int *)cmcf, ELMCKT_CVAX, cpunum, recover); mprintf("No primary error flag - unspecified error type\n"); ka60logesrpkt(recover); ka60logmempkt(recover); ka60consprint(2,type,mcf); cprintf("No primary error flag - unspecified error type\n"); ka60consprint(3,0,0); ka60consprint(4,0,0); } break; case 0x82: case 0x83: /* * What is logged & printed depends on the cause of the error. * If we can't recover print errors on the console. * Last, clear the error bits. */ /* * Unspecific mcheck 0x82 or 0x83: log everything. * We can't recover so print errors on console. */ logmck((int *)cmcf, ELMCKT_CVAX, cpunum, recover); mprintf("No primary error flag - unspecified error type\n"); ka60logesrpkt(recover); ka60logmempkt(recover); ka60consprint(2,type,mcf); printf("No primary error flag - unspecified error type\n"); ka60consprint(3,0,0); ka60consprint(4,0,0); break; default: /* * Unrecognized mcheck: these are non-recoverable. * Log the mcheck, err status regs & memerr packets * Also print to the console. */ logmck((int *)cmcf, ELMCKT_CVAX, cpunum, recover); ka60logesrpkt(recover); ka60logmempkt(recover); type = 0; ka60consprint(2,type,mcf); ka60consprint(3,0,0); ka60consprint(4,0,0); break; } if (!recover) { /* might want to log FBICs here */ panic ("mchk"); } ka60_mchkprog = 0; return(0);}/* * Firefox memerrs are Mbus I/O errors. They come in at ipl 1d * from the cpu fbic, and ipl 17 from all the other fbics in the system. * CQBIC errors will come in at ipl 16, and come here also. */extern int cold;ka60memerr(){ register struct mb_node *mbp; register struct fbic_regs *fbp; int frozen = 0; if (!cold) { /* * Need to check for CQBIC errors * and report them */ mbp = mbus_nodes; if ((mbp->mb_flags & FBIC_MAPPED) && (mbp->mb_vaddr->f_modtype & FMOD_QBUS)) { if ((mbp->mb_vaddr->f_cpuid & 0x3) == FCPU_PROCB) { /* * Handle FTAM errors */ if(ffqregs->cq_dser) { /* * log the CQBIC error */ ka60logesrpkt(EL_PRIHIGH); /* * Clear the CQBIC error bits */ ffqregs->cq_dser = 0xffffffff; } } else { /* * Must be a FQAM */ /* * If the Dump Error bit is set, the error is * fatal. */ if(fqamcsr & FQCSR_DUMP_ERR) { panic("Qbus Adapter Dump Error"); } } } /* * Make a quick pass through the FBICs to see if * any of the BUSCSR registers are frozen. If the * frozen bit is cleared, the FBIC error information * is frozen. Only log errors if the error information * is frozen.. */ for (mbp = mbus_nodes; mbp->mb_flags & FBIC_MAPPED; mbp++) { if(~mbp->mb_vaddr->f_buscsr & FBCSR_FRZN) frozen++; } if (frozen) { ka60logfbicpkt(EL_PRIHIGH); mprintf("Mbus I/O error\n"); panic("Mbus I/O Error"); } } enafbiclog();}/* * Log CRD memory errors in kernel buffer: * * Traps through SCB vector 54: correctable memory errors. * * These errors are recoverable. */ka60crderr(){ register struct mb_node *mbp; register u_int time; /* from TOY clock */ struct fmdc_regs *fmp; time = ka60readtodr(); mprintf("Corrected Read Data interrupt\n"); ka60logfbicpkt(EL_PRILOW); if(time - crd_errcnt.crd_prev <= TIME_THRESH) { /* * disable SBE reporting on all modules */ mprintf("Hi-Rate CRD log\n"); for (mbp = mbus_nodes; mbp->mb_flags & FBIC_MAPPED; mbp++) { if ((mbp->mb_modtype & FMOD_INTERFACE) != FMOD_FMDC) continue; fmp = (struct fmdc_regs *)mbp->mb_vaddr; fmp->fm_fmdcsr |= FMDCSR_INH_SBE_REPORT; } } crd_errcnt.crd_prev = crd_errcnt.crd_last; crd_errcnt.crd_last = time; /* * clear syndrome bits and error address */ for (mbp = mbus_nodes; mbp->mb_flags & FBIC_MAPPED; mbp++) { if ((mbp->mb_modtype & FMOD_INTERFACE) != FMOD_FMDC) continue; fmp = (struct fmdc_regs *)mbp->mb_vaddr; fmp->fm_eccsynd0 = 0; fmp->fm_eccaddr0 = 0; fmp->fm_eccsynd1 = 0; fmp->fm_eccaddr1 = 0; }}/* * Print error packet to the console. * This is only done when we are about to panic on the error. * * Note: side-effect. * If console is a graphics device, ioctl is done to force kernel printfs * directly to the screen. */ka60consprint(pkt, type, mcf) int pkt; /* error pkt desired: 2 = mcheck frame 3 = error status registers 4 = memory CSRs */ int type; /* machine check type (for pkt type 2) */ register struct mcCVAXframe *mcf; /* mcheck frame pointer (for type 2)*/{ register int i; register struct mb_node *mbp = mbus_nodes; register struct fmdc_regs *fmdcp; int ws_disp; /* * If console is a graphics device, * force printf messages directly to screen. */ if (ws_display_type) { ws_disp = ws_display_type << 8; (*cdevsw[ws_display_type].d_ioctl)(ws_disp, FG_KERN_UNLOOP, 0, 0); } switch (pkt) { case 2: printf("\nmachine check %x: ", type); /* * Types are disjoint. Have to convert some to linear range. */ if (type >= 0x80) type = type - 0x80 + MCcVAXDISJ; printf("%s\n", mcCVAX[type]); printf("\tcode\t= %x\n", mcf->mc1_summary); printf("\tmost recent virtual addr\t=%x\n", mcf->mc1_vap); printf("\tinternal state 1\t=%x\n", mcf->mc1_internal_state1); printf("\tinternal state 2\t=%x\n", mcf->mc1_internal_state2); printf("\tpc\t= %x\n", mcf->mc1_pc); printf("\tpsl\t= %x\n\n", mcf->mc1_psl); break; case 3: if((mbp->mb_modtype & FMOD_QBUS) == FMOD_QBUS) { if ((mbp->mb_vaddr->f_cpuid & 0x3) == FCPU_PROCB) { /* FTAM */ printf("\tdser\t= %x\n",ffqregs->cq_dser); printf("\tmear\t= %x\n", ffqregs->cq_mear); printf("\tsear\t= %x\n", ffqregs->cq_sear); } if ((mbp->mb_vaddr->f_cpuid & 0x3) == FCPU_PROCA) { /* FQAM */ /* Log FQAM data here */ ; } } printf("\tcadr\t= %x\n", mfpr(CADR)); printf("\tmser\t= xx\n", mfpr(MSER)); break; case 4: for (mbp = mbus_nodes; mbp->mb_flags & FBIC_MAPPED; mbp++) { if ((mbp->mb_modtype & FMOD_CLASS) == FMOD_FMDC) { fmdcp = (struct fmdc_regs *)mbp->mb_vaddr; if (fmdcp->fm_fmdcsr & FMDC_ERROR) { if ((fmdcp->fm_eccsynd0 & FMDC_MBE) || (fmdcp->fm_eccsynd1 & FMDC_MBE)) { printf("Multiple Bit Error, Mbus Slot %d\n", MBUS_SLOT(mbp->mb_physaddr)); } else if ((fmdcp->fm_eccsynd0 & FMDC_SBE) || (fmdcp->fm_eccsynd1 & FMDC_SBE)) { printf("Multiple Bit Error, Mbus Slot %d\n", MBUS_SLOT(mbp->mb_physaddr)); } printf("\tmodtype \t = 0x%x\n", fmdcp->fm_modtype); printf("\tbuscsr \t = 0x%x\n", fmdcp->fm_buscsr); printf("\tbusctl \t = 0x%x\n", fmdcp->fm_busctl); printf("\tbusaddr \t = 0x%x\n", fmdcp->fm_busaddr); printf("\tbusdat \t = 0x%x\n", fmdcp->fm_busdat); printf("\tfmdcsr \t = 0x%x\n", fmdcp->fm_fmdcsr); printf("\tbaseaddr\t = 0x%x\n", fmdcp->fm_baseaddr); printf("\teccaddr0\t = 0x%x\n", fmdcp->fm_eccaddr0); printf("\teccaddr1\t = 0x%x\n", fmdcp->fm_eccaddr1); printf("\teccsynd0\t = 0x%x\n", fmdcp->fm_eccsynd0); printf("\teccsynd1\t = 0x%x\n", fmdcp->fm_eccsynd1); } } } break; default: printf("\nCase %d not implemented\n", pkt); break; }}/* * Log Error & Status Registers (packets 3 & 5 of KA650 error spec) */ka60logesrpkt(priority) int priority; /* for pkt priority */{ register struct mb_node *mbp = mbus_nodes; struct el_rec *elrp; switch (priority) { case 0: /* non-recoverable mchecks & memory errs */ priority = EL_PRISEVERE; break; case 1: /* recoverable mchecks */ priority = EL_PRIHIGH; break; case 2: /* recoverable CRDs */ priority = EL_PRILOW; break; } elrp = ealloc(sizeof(struct el_esr650), priority); if (elrp != NULL) { LSUBID(elrp,ELCT_ESR650,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF); elrp->el_body.elesr650.esr_cacr = -1; elrp->el_body.elesr650.esr_dser = -1; elrp->el_body.elesr650.esr_qbear = -1; elrp->el_body.elesr650.esr_dear = -1; elrp->el_body.elesr650.esr_cbtcr = -1; elrp->el_body.elesr650.esr_ipcr0 = -1; elrp->el_body.elesr650.esr_cadr = mfpr(CADR); elrp->el_body.elesr650.esr_mser = mfpr(MSER); /* if an FTAM is present */ if((mbp->mb_modtype & FMOD_QBUS) == FMOD_QBUS) { if ((mbp->mb_vaddr->f_cpuid & 0x3) == FCPU_PROCB) { /* FTAM */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -