📄 kn5800.c
字号:
/* * Call routines that check for other errors, such as CRD's and * second level cache errors. */ kn5800_crderr (reg); return(0);}/* * intr2 - R3000 interrupt pin 2 * Possible causes: * XMI level 7 interrupt * Read register at 0x4000005c to get a vector. */kn5800_intr2 (ep, code)u_int *ep;int code;{ int vector; vector = read_nofault(&kn5800_vectors[VEC_LEVEL3 / 4]); vector &= 0xff; (*(scb[vector/4]))(ep, (vector % 512));}/* * intr1 - R3000 interrupt pin 1 * Possible causes: * Interval timer (hardclock timer). * XMI level 6 interrupt * IP interrupts * Read register at 0x30000058 to get a vector for xmi level 6. * * */kn5800_intr1 (ep, code)u_int *ep;int code;{ int vector; /* * Check for a clock interrupt, if not we check for a vectored * XMI level 6 interrupt. */ if (v5800csr->csr1 & INTMR) { hardclock(ep); } else { vector = read_nofault(&kn5800_vectors[VEC_LEVEL2 / 4]); (*(scb[vector/4]))(ep, (vector % 512)); }}/* * intr0 - R3000 interrupt pin 0 * Possible causes: * XMI level 5 interrupt * SSC chip (programmable timers and console). * XMI level 4 interrupt * * The SSC interrupts are grouped with level 4 by the INTR1 bit * in csr1. If INTR1 is asserted there is a XMI level 14 or SSC * interrupt. If INTR1 is deasserted there is an XMI level 15 * interrupt pending. * * Read register at 0x30000050 or 0x30000054 to get a vector. * */kn5800_intr0 (ep, code)u_int *ep;int code;{ register int vector; register int csr1; csr1 = v5800csr->csr1; if (csr1 & INTR1) { vector = read_nofault(&kn5800_vectors[VEC_LEVEL0 / 4]); } else { vector = read_nofault(&kn5800_vectors[VEC_LEVEL1 / 4]); } (*(scb[vector/4]))(ep, (vector % 512));}/* * Enable ISIS secondary cache */kn5800_enable_cache() { int save_led_val; /* enable the cache */ save_led_val = v5800csr->csr1; v5800csr->csr1 = (save_led_val | FMISS | FCI); v5800csr->csr1 = (save_led_val & ~(FMISS | FCI));}/* * kn5800_memerr -- Called from an interrupt or trap * * Here are the fatal error bits checked: * XBE:WDNAK -- write data noAck. * XBE:TE -- Transmit Error. * XBE:CNAK -- Command NoAck. * CSR2:WDPE -- DAL write Parity Error. * XBE:WEI -- XMI write Error IVINTR's. * XBE:XFAULT -- XMI fault assertion. * All forms of Ident errors (which bits?). */kn5800_memerr(ep, ptr, priority)register u_int *ep; /* Exception frame pointer */struct kn5800_regs *ptr; /* Pointer to saved processor regs */int priority; /* Priority for packet */{ int cpunum; struct xcp_reg *xcp_node; register struct xmidata *xmidata; /* * Get xmi node info. */ xmidata = get_xmi(0); xcp_node =(struct xcp_reg *)xmidata->xmivirt+(v5800csr->csr1 & 0xf); /* * Log a memory error packet and print processor info on console. */ kn5800_logmempkt(ep, ptr, priority); kn5800_consprint(MEMPKT, ep); /* * Handle case of a passive release on a interrupt vector read * due to resetting a device. */ if ( (xcp_node->xcp_xbe & (XMI_RER|XMI_NRR)) && ((xcp_node->xcp_xbe & 0xf)==9)) { kn5800_clear_xbe(); return(0); } /* * We are crashing so print out x3p specific stuff. */ cprintf("Fatal error detected by processor at node %x\n", v5800csr->csr1 & XMI_NODE_ID); cprintf("\tx3p_csr1\t= 0x%x\n", ptr->kn5800_csr1); cprintf("\tx3p_dtype\t= 0x%x\n", ptr->kn5800_dtype); cprintf("\tx3p_xbe\t= 0x%x\n", ptr->kn5800_xbe); cprintf("\tx3p_fadr\t= 0x%x\n", ptr->kn5800_fadr); cprintf("\tx3p_csr2\t= 0x%x\n", ptr->kn5800_csr2); /* * Print out any pending XMA errors. */ xma_check_errors(xcp_node,EL_PRIHIGH); /* * kill system */ panic("memory error"); /* no return */}kn5800_logmempkt(ep, ptr, priority)register u_int *ep; /* Exception frame pointer */struct kn5800_regs *ptr; /* Pointer to saved processor regs */int priority; /* Priority for packet */{ struct el_rec *elrp; elrp = ealloc(sizeof(struct el_esr), priority); if (elrp != NULL) { LSUBID(elrp,ELCT_ESR,ELESR_5800,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF); elrp->el_body.elesr.elesr.el_esr5800.esr_cause = ep[EF_CAUSE]; elrp->el_body.elesr.elesr.el_esr5800.esr_epc = ep[EF_EPC]; elrp->el_body.elesr.elesr.el_esr5800.esr_status = ep[EF_SR]; elrp->el_body.elesr.elesr.el_esr5800.esr_badva = ep[EF_BADVADDR]; elrp->el_body.elesr.elesr.el_esr5800.esr_sp = ep[EF_SP]; elrp->el_body.elesr.elesr.el_esr5800.x3p_csr1 = ptr->kn5800_csr1; elrp->el_body.elesr.elesr.el_esr5800.x3p_dtype = ptr->kn5800_dtype; elrp->el_body.elesr.elesr.el_esr5800.x3p_xbe = ptr->kn5800_xbe; elrp->el_body.elesr.elesr.el_esr5800.x3p_fadr = ptr->kn5800_fadr; elrp->el_body.elesr.elesr.el_esr5800.x3p_gpr = ptr->kn5800_gpr; elrp->el_body.elesr.elesr.el_esr5800.x3p_csr2 = ptr->kn5800_csr2; EVALID(elrp); }}/* * */xma_check_errors(xcp,priority)struct xcp_reg *xcp;int priority;{ struct el_xma *xma_pkg; struct xmi_reg *nxv; struct xma_reg *xma; struct xmidata *xmidata; int xminode; struct el_rec *elrp; xmidata = (struct xmidata *)get_xmi(0); nxv = xmidata->xmivirt; for(xminode = 0; xminode < MAX_XMI_NODE; xminode++,nxv++) { if ((xmidata->xminodes_alive & (1<<xminode)) && ((short) (nxv->xmi_dtype) == XMI_XMA)) { xma = (struct xma_reg *) nxv; if ((xma->xma_xbe & XMI_ES) || (xma->xma_mctl1 & (XMA_CTL1_LOCK_ERR| XMA_CTL1_UNLOCK_ERR|XMA_CTL1_RDS_WRITE)) || (xma->xma_mecer & (XMA_ECC_RDS_ERROR))) { log_mem_error(xcp,xma,priority); } } }}/* * */kn5800_clear_xbe(){ struct xmidata *xmidata; struct xcp_reg *xcp_node; /* get pointer to xcp node that machine checked */ xmidata = get_xmi(0); xcp_node = (struct xcp_reg *)xmidata->xmivirt + (v5800csr->csr1 & XMI_NODE_ID); xcp_node->xcp_xbe = xcp_node->xcp_xbe & ~XMI_XBAD; }/* log XMA memory error. If priority is not LOW then print to * console. */log_mem_error(xcp,xma,priority) int priority; struct xma_reg *xma; struct xcp_reg *xcp;{ struct el_xma *xma_pkg; struct xmidata *xmidata; struct el_rec *elrp; /* log the XMA error */ elrp = ealloc(sizeof(struct el_xma),priority); if (elrp) { LSUBID(elrp,ELCT_MEM,EL_UNDEF,ELMCNTR_6200,EL_UNDEF,EL_UNDEF,EL_UNDEF); xma_pkg = &elrp->el_body.el_xma;#ifdef vax xma_pkg->xma_node = ((svtophy(xma))>>19)&0xf;#endif vax xma_pkg->xma_dtype = xma->xma_type; xma_pkg->xma_xbe = xma->xma_xbe; xma_pkg->xma_seadr = xma->xma_seadr; xma_pkg->xma_mctl1 = xma->xma_mctl1; xma_pkg->xma_mecer = xma->xma_mecer; xma_pkg->xma_mecea = xma->xma_mecea; xma_pkg->xma_mctl2 = xma->xma_mctl2; EVALID(elrp); } /* print to console if HIGH priority */ if (priority < EL_PRILOW) { cprintf("Fatal memory error \n");#ifdef vax cprintf("xma_phys = %x\n",svtophy(xma));#endif vax cprintf("xma_type = %x\n",xma->xma_type); cprintf("xma_xbe = %x\n",xma->xma_xbe); cprintf("xma_seadr = %x\n",xma->xma_seadr); cprintf("xma_mctl1 = %x\n",xma->xma_mctl1); cprintf("xma_mecer = %x\n",xma->xma_mecer); cprintf("xma_mecea = %x\n",xma->xma_mecea); cprintf("xma_mctl2 = %x\n",xma->xma_mctl2); }}/* * kn5800_crderr() --- * * XBE:CRD - Correctable main memory errors. * * 2nd Level cache errors. * CSR2:VBPE - Valid bit parity error. * CSR2:TPE - Tag parity error. * CSR2:IQO - Invailidate Queue Overflow. * CSR2:DTPE - Duplicate Tag Store Parity Error. * CSR2:CFE - Cache Fill Error., * * XMI soft errors. * XBE:CC - Corrected conformation Errors. * XBE:IPE - Inconsistent Parity Error. * XBE:PE - Parity Error. */kn5800_crderr(ptr)struct kn5800_regs *ptr;{ struct xcp_reg *xcp_node; int save_led_val; register struct xmidata *xmidata ; int node; register struct el_xcpsoft *sptr; register int csr2_errs,xbe_errs, flush_the_cache=0; csr2_errs = ptr->kn5800_csr2; xbe_errs = ptr->kn5800_xbe; xmidata = get_xmi(0); node = v5800csr->csr1 & XMI_NODE_ID; sptr = (struct el_xcpsoft *)CURRENT_CPUDATA->cpu_machdep; xcp_node =(struct xcp_reg *)xmidata->xmivirt + (v5800csr->csr1 & XMI_NODE_ID); /* * clear the error indicators */ xcp_node->xcp_csr2 = xcp_node->xcp_csr2; xcp_node->xcp_xbe = xcp_node->xcp_xbe; /* * test for IQO error -- count and dismiss */ if (csr2_errs & CSR2_IQO) { if (sptr) sptr->xcp_iqo++; flush_the_cache++; } /* test for cache error */ if (csr2_errs & (CSR2_VBPE|CSR2_TPE|CSR2_CFE|CSR2_DTPE)) { if (sptr) { if (csr2_errs & CSR2_VBPE) sptr->xcp_vbpe++; if (csr2_errs & CSR2_TPE) sptr->xcp_tpe++; if (csr2_errs & CSR2_CFE) sptr->xcp_cfe++; if (csr2_errs & CSR2_DTPE) sptr->xcp_dtpe++; if ((CURRENT_CPUDATA->cpu_state & CPU_SOFT_DISABLE) == 0) kn5800_log_soft(ptr,sptr); } flush_the_cache++; } /* test for XMI error */ if (xbe_errs & (XMI_CC|XMI_IPE|XMI_PE)) { if (sptr) { if (xbe_errs & XMI_CC) sptr->xcp_cc++; if (xbe_errs & XMI_IPE) sptr->xcp_ipe++; if (xbe_errs & XMI_PE) sptr->xcp_pe++; if ((CURRENT_CPUDATA->cpu_state & CPU_SOFT_DISABLE) == 0) kn5800_log_soft(ptr,sptr); } flush_the_cache++; } /* test for CRD error */ if (xbe_errs & (XMI_CRD)) { xma_check_crd(xcp_node,xmidata); } if (flush_the_cache) { /* now enable cache by method specified in XCP spec */ save_led_val = v5800csr->csr1; v5800csr->csr1 = (FMISS | FCI | save_led_val); v5800csr->csr1 = (save_led_val & ~(FMISS | FCI)); flush_cache(); /* flush the first level cache also */ } return(0);}/* * Routine kn5800_log_soft * * Description: This routine logs a soft error for processor pointed * to by the pointer xcp_node. A maximum of 1 packet are logged every * 15 minutes. * */kn5800_log_soft(reg_ptr,sptr) struct kn5800_regs *reg_ptr; register struct el_xcpsoft *sptr;{ struct el_rec *elrp; register struct el_xcp54 *ptr; elrp = ealloc(sizeof(struct el_xcp54),EL_PRILOW); if (elrp) { LSUBID(elrp,ELCT_6200_INT54,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF); ptr = &elrp->el_body.el_xcp54; ptr->xcp_csr1 = v5800csr->csr1; ptr->xcp_dtype = reg_ptr->kn5800_dtype; ptr->xcp_xbe = reg_ptr->kn5800_xbe; ptr->xcp_fadr = reg_ptr->kn5800_fadr; ptr->xcp_gpr = reg_ptr->kn5800_gpr; ptr->xcp_csr2 = reg_ptr->kn5800_csr2; ptr->xcp_soft = *sptr; EVALID(elrp); } else mprintf("log failed\n"); CURRENT_CPUDATA->cpu_state|= CPU_SOFT_DISABLE;}/* * Routine: xma_check_crd * * Discription: This routine scans all of the Calypso arrays * looking for the board that signaled the CRD error. When found * the error is logged and CRD's are disabled from that board. */xma_check_crd(xcp,xmidata) struct xcp_reg *xcp; struct xmidata *xmidata;{ int xminode; struct xma_reg *xma; xma = (struct xma_reg *) xmidata->xmivirt; for(xminode = 0; xminode < MAX_XMI_NODE; xminode++,xma++) { /* if node present then check to see if it is an XMA */ if ((xmidata->xminodes_alive & (1<<xminode)) && ((short) (xma->xma_type) == XMI_XMA)) { /* check for CRD error and check that CRD logging for board has not been disabled */ if ((xma->xma_mecer&(XMA_ECC_CRD_ERROR)) && ((xma->xma_mctl1&XMA_CTL1_CRD_DISABLE)==0)){ /* log error */ log_mem_error(xcp,xma,EL_PRILOW); /* clear CRD request */ xma->xma_mecer = XMA_ECC_CRD_ERROR; /* disable further CRD's */ xma->xma_mctl1|=(XMA_CTL1_CRD_DISABLE); } } } }/* * Memenable enables the memory controller corrected data reporting. * This runs at regular intervals, turning on the interrupt. * The interrupt is turned off, per memory controller, when error * reporting occurs. Thus we report at most once per memintvl. */kn5800memenable (){ int xminode; struct xmi_reg *nxv; /* virtual pointer to XMI node */ struct xmidata *xmidata; xmidata = get_xmi(0); nxv = xmidata->xmivirt; for(xminode = 0; xminode < MAX_XMI_NODE; xminode++,nxv++) { if ((xmidata->xminodes_alive & (1<<xminode)) && ((short) (nxv->xmi_dtype) == XMI_XMA)) { /* clear disable CRD flag in memory controller */ ((struct xma_reg *)nxv)->xma_mctl1 &= ~(XMA_CTL1_CRD_DISABLE); } } return(0);}/* * this routine sets the cache to the state passed. enabled/disabled */kn5800setcache(state)int state;{ if (state) { /* enable the cache */ kn5800_enable_cache(); return(0); }}/* * */kn5800cachenbl(){ cache_state = 0x1; return(0);}/* * */kn5800tocons(c) register int c;{ register int timeo; timeo = ssc_console_timeout; while ((ssc_ptr->ssc_ctcs & TXCS_RDY) == 0) { if (timeo-- <= 0) { return(0); } } ssc_ptr->ssc_ctdb = c; return(0);}/* * */int kn5800badaddr(addr,len)caddr_t addr;int len;{ register int foo,s,i; register struct bi_nodespace *biptr; #ifdef lint len=len;#endif lint s = spl7(); for (i=0; i < nNVAXBI ; i++) { if (biptr = bidata[i].cpu_biic_addr) { biptr->biic.biic_err = biptr->biic.biic_err; foo = biptr->biic.biic_gpr0; } } foo = bbadaddr(addr,len); for (i=0; i < nNVAXBI ; i++) { if (biptr = bidata[i].cpu_biic_addr) { if ((biptr->biic.biic_err & ~BIERR_UPEN)!=0) foo=1; biptr->biic.biic_err = biptr->biic.biic_err; } } kn5800_clear_xbe(); splx(s); return(foo);}/* * */kn5800reboot() {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -