📄 ka6400.c
字号:
* set up vector processing system wide variables. record * which scalar cpu's have an attached vector processor * note: the console may be used to disable the vector * processor. In this case the VP would show up as present, * but not enabled. Therefore, for our purposes here, we * need to look at the enabled field. */ vpmask = ccabase.cca_rev_dependent.cca_rev4.cca_vec_enabled1; vpfree = 1; for (i=0; i<=(sizeof(int)*8); i++) { if (vpfree & vpmask) { printf ("xrv attached to cpu #%d is enabled\n", i); vptotal++; } vpfree <<=1; } vpfree = vpmask; num_vec_procs = 0; /* * vector processors are attached to scalar cpu's only after * cca rev #3 */ KM_ALLOC (( CURRENT_CPUDATA-> cpu_vpdata), struct vpdata *, sizeof(struct vpdata), KM_VECTOR , KM_CLEAR | KM_CONTIG); if (vpmask & CURRENT_CPUDATA->cpu_mask ) { /* enable VP on boot processor * note: This routine always runs on the boot cpu. * vp_reset must be called while running on * the cpu whose vp is being reset. * Therefore, the call to vp_reset for a * secondary cpu is done in _slavestart in * locore.s */ vp_reset (CURRENT_CPUDATA->cpu_num); } else { /* disable VP on boot processor */ mtpr (ACCS, mfpr(ACCS) & ~1); } } else { /* disable VP on boot processor */ mtpr (ACCS, mfpr(ACCS) & ~1); } } /* make sure the vector processor is disabled. * take advantage of the fact that (according to section 13.2.3 * of the VAX Architecture Reference Manual) neither a mtpr(VPSR) * nor a mfpr(VPSR) will cause a reserved operand fault on a * vector absent VAX. */ mtpr (VPSR, 0); return(0);}/* * Make the processor's XMI private space accessible by * initialising the PTEs allocated in spt.s to point to * the physical XMI private space addresses. */ka6400mapcsr() { nxaccess(RSSCADDR,RSSCmap,RSSCSIZE);}/* * ka6400harderr --- Hard errors are reported through SCB vector * 0x60, at IPL 0x1d. This routine runs on the interrupt stack. * These errors include the following: * . XBER-notfied errors * . RCSR<WDPE> (DAL write data parity error) * . Vector unit errors * * None of the hard errors can be retried. We simply log the * error and panic. * * NOTE: Due to a bug in 2nd pass XRP, extraneous hard error interrupt * must be checked for and ignored. * Also, at boot time, we may get an extraneous error interrupt. * Since at boot time we haven't set up our XMI data structures yet, * we can't access the XMI registers, so we can't tell if the error was * real or extraneous. We can either panic (and therefore * never boot), or we can ignore the error and pretend nothing has happened. * Here we ignore the error until we are fully booted. */ka6400harderr(){register int cpunum;register struct el_rec *elrp;register struct el_xrp *ptr;register xrp_node;register struct xrp_reg *nxv;register struct xmidata *xmidata;int rcsr, xber;extern int cold; /* Cold start flag */if (cpu_sub_subtype == MARIAH_VARIANT) return(ka6500harderr());else {if (cold) { /* booting, may not be able to access XMI yet */ if (head_xmidata) { /* We can access XMI */ clear_xrperr(); } return(0);}/* * Check if this is an extraneous error, if it is, ignore and return. */xmidata = get_xmi(0); /* get pointer to XMI data structure */nxv = (struct xrp_reg *)xmidata->xmivirt + (rssc->s_iport & 0xf);rcsr = (int)nxv->xrp_rcsr; /* read RCSR */xber = (int)nxv->xrp_xbe; /* read XBER */if (((rcsr & 0xf8000000) == 0) && ((xber & 0x8ffff000) == 0)) { /* No error bits set in RCSR or in XBER */ return(0);}if ((rcsr & 0xf8000010) == 0x10) { /* RCSR<4> set, no other error bits set */ if ((xber & 0x0377a000) == 0) { /* No error other than bits 27,23,19,14 */ clear_xrperr(); return(0); }}if ((rcsr & 0xf8000010) == 0x08000010) { /* RCSR<4> and RCSR<27> set, no other error bits set */ if ((xber & 0x03708000) == 0) { /* No error other than bits 27,23,19,18,17,16,14,13 */ clear_xrperr(); return(0); }}if ((xber & 0x0000000f) == 0x00000009) { /* If RER, RSE, or TTO occurred during IDENT, retry transaction */ if ((xber & (XMI_RER | XMI_RSE | XMI_TTO)) != 0) { /* RSE, RER, or TTO are set */ clear_xrperr(); return(0); }} cpunum=CURRENT_CPUDATA->cpu_num;/* Test for Vector Errors. If vector error occured in kernel mode, * then we must panic. If the error occured in user mode, then disable * the vector unit and kill the user process. In any case, make up an * error packet. */#define VINTSR_HARD_ERROR (VINTSR_VECTOR_UNIT_HERR | \ VINTSR_VECTL_VIB_HERR | \ VINTSR_CCHIP_VIB_HERR | \ VINTSR_BUS_TIMEOUT )/* if (error_data[cpunum].s_vintsr & VINTSR_HARD_ERROR) { * printf ("ka6400harderr(): error packet to be made up here\n"); * if (CURRENT_CPUDATA->cpu_vpdata->vpd_in_kernel != VPD_IN_KERNEL) { * vp_remove(); * return (0); * } * } */snapshot_registers(cpunum); /* Read in all relevent registers */ka6400_disable_cache(); /* Disable caches */xrp_node = rssc->s_iport & 0xf; /* Node ID of processor */elrp = ealloc(sizeof(struct el_xrp), EL_PRISEVERE);if (elrp) { LSUBID(elrp,ELCT_6400_INT60,EL_UNDEF,EL_UNDEF,EL_UNDEF, EL_UNDEF,EL_UNDEF); ptr = &elrp->el_body.el_xrp; ptr->s_rcsr = error_data[cpunum].s_rcsr; ptr->s_xber = error_data[cpunum].s_xber; ptr->s_xfadr = error_data[cpunum].s_xfadr; ptr->s_sscbtr = error_data[cpunum].s_sscbtr; ptr->s_bcctl = error_data[cpunum].s_bcctl; ptr->s_bcsts = error_data[cpunum].s_bcsts; ptr->s_bcerr = error_data[cpunum].s_bcerr; ptr->s_pcsts = error_data[cpunum].s_pcsts; ptr->s_pcerr = error_data[cpunum].s_pcerr; ptr->s_vintsr = error_data[cpunum].s_vintsr; EVALID(elrp); cprintf("Hard error logged in error log buffer.\n"); }else { cprintf("Can't log hard error. (no buffer)\n"); }/* * We are crashing, print something on the console */cprintf("Fatal hard error detected by processor at node %d\n", xrp_node);cprintf("rcsr = %x\n",error_data[cpunum].s_rcsr);cprintf("xber = %x\n",error_data[cpunum].s_xber);cprintf("xfadr = %x\n",error_data[cpunum].s_xfadr);cprintf("sscbtr = %x\n",error_data[cpunum].s_sscbtr);cprintf("bcctl = %x\n",error_data[cpunum].s_bcctl);cprintf("bcsts = %x\n",error_data[cpunum].s_bcsts);cprintf("bcerr = %x\n",error_data[cpunum].s_bcerr);cprintf("pcsts = %x\n",error_data[cpunum].s_pcsts);cprintf("pcerr = %x\n",error_data[cpunum].s_pcerr);cprintf("vintsr = %x\n",error_data[cpunum].s_vintsr);/* * Go find any pending memory (XMA) errors and log them in the error log. */rxma_check_errors(EL_PRISEVERE);panic("Hard error");} /* END IF Mariah ELSE Rigel *//*NOTREACHED*/}/* * ka6400softerr() --- "Soft" errors are reported through SCB vector * 0x54, at IPL 0x1a. This routine runs on the interrupt stack. * These errors include the following: * . P-cache errors * . REXMI-detected errors * . C-chip tag store parity errors * . C-chip detected errors * . Vector unit errors * These errors do not affect instruction execution. * * Note: This routine will be entered whether cpu type is xrp or xmp. * Routine will check for cpu type, and if xmp, will dispatch to * xmp-specific soft error handler. * */ka6400softerr(){register int cpunum;register struct el_rec *elrp;register struct el_xrp *ptr;register xrp_node;if(cpu_sub_subtype == MARIAH_VARIANT) return(ka6500softerr());else {cpunum = CURRENT_CPUDATA->cpu_num;snapshot_registers(cpunum); /* Read in all relevent registers */xrp_node = rssc->s_iport & 0xf; /* Node ID of processor */ka6400_disable_cache(); /* Disable caches */#define VINTSR_SOFT_ERROR (VINTSR_VECTOR_UNIT_SERR | \ VINTSR_VECTL_VIB_SERR | \ VINTSR_CCHIP_VIB_SERR )/* * check to see if there really is an error. note: don't check for a CRD * (Corrected Read error) here, because it does not need an error packet. */if ( error_data[cpunum].s_pcsts & PCSTS_INTERRUPT || error_data[cpunum].s_rcsr & RCSR_CFE || error_data[cpunum].s_xber & XMI_PE || error_data[cpunum].s_xber & XMI_TE || error_data[cpunum].s_xber & XMI_CC || error_data[cpunum].s_bcsts & BCSTS_STATUS_LOCK) { elrp = ealloc(sizeof(struct el_xrp), EL_PRILOW); if (elrp) { LSUBID(elrp,ELCT_6400_INT54,EL_UNDEF,EL_UNDEF,EL_UNDEF, EL_UNDEF,EL_UNDEF); ptr = &elrp->el_body.el_xrp; ptr->s_rcsr = error_data[cpunum].s_rcsr; ptr->s_xber = error_data[cpunum].s_xber; ptr->s_xfadr = error_data[cpunum].s_xfadr; ptr->s_sscbtr = error_data[cpunum].s_sscbtr; ptr->s_bcctl = error_data[cpunum].s_bcctl; ptr->s_bcsts = error_data[cpunum].s_bcsts; ptr->s_bcerr = error_data[cpunum].s_bcerr; ptr->s_pcsts = error_data[cpunum].s_pcsts; ptr->s_pcerr = error_data[cpunum].s_pcerr; ptr->s_vintsr = error_data[cpunum].s_vintsr; EVALID(elrp); }}/* * Go find any memory (XMA) CRD errors and log them in the error log. * At the same time, disable CRD errors on the memory nodes. * note: this will be re-enabled at regular intervals by ka6400memenable (). * It is disabled to keep the number of corrected errors reported down to * a dull roar. */if (error_data[cpunum].s_xber & XMI_CRD) { rxma_check_crd(EL_PRILOW); recover_mem_error(); /* Do a full memory error recovery */}ka6400_init_cache();ka6400_enable_cache();return(0);} /* END IF Mariah ELSE Rigel */}/* * Routine to check each node in the XMI to see if it is a * memory node (device type register indicating an XMA). If * a node is an XMA, check for all error bits. If any of * the error bits is set, call rlog_mem_error to log the errors * in the error log. */rxma_check_errors(priority)int priority;{ register struct xmi_reg *nxv; register struct xma_reg *xma; register struct xmidata *xmidata; register int xminode; 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)) { /* The node is a memory node */ xma = (struct xma_reg *) nxv; if ((nxv->xmi_dtype & XMA2_MASK) == XMI_XMA) { 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))) { rlog_mem_error(xma,priority); } } else /* Must be XMA2 */ if (xma->xma_xbe & XMI_ES) rlog_mem_error(xma,priority); } }}/* * Routine to check each node in the XMI to see if it is a * memory node (device type register indicating an XMA). If * a node is an XMA, check for corrected read data (CRD). If * the error bit is set, call rlog_mem_error to log the errors * in the error log. * * Disable CRD on the board */rxma_check_crd(priority)int priority;{ register struct xmi_reg *nxv; register struct xma_reg *xma; register struct xmidata *xmidata; register int xminode; 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)) { /* The node is a memory node */ xma = (struct xma_reg *) nxv; if ((xma->xma_mecer&XMA_ECC_CRD_ERROR) && ((xma->xma_mctl1&XMA_CTL1_CRD_DISABLE)==0)) { /* CRD error, log it */ rlog_mem_error(xma,priority); /* * clear CRD request and disable * further CRDs. */ xma->xma_mecer = XMA_ECC_CRD_ERROR; xma->xma_mctl1 |= XMA_CTL1_CRD_DISABLE; } } }}/* * log XMA memory error. If priority is not LOW then print to * console. */rlog_mem_error(xma,priority)int priority;register struct xma_reg *xma;{ register struct el_xma *xma_pkg; register struct el_rec *elrp; /* If xma2, go to its handler */ if((xma->xma_type & XMA2_MASK) == XMI_XMA2) xma2_mem_error(xma,priority); else { /* 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; xma_pkg->xma_node = ((svtophy(xma))>>19)&0xf; 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("Memory error \n"); cprintf("xma_phys = %x\n",svtophy(xma)); 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); } } /* END BIG IF-ELSE */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -