📄 biinit.c
字号:
} else { /* this case checks that the adapter structure has not been used. */ if (p_adpt->c_ptr == 0) return(um); } } } } return(0);} struct uba_device *bifindui(); bi_config_dev(nxv,nxp,binumber,binode) struct bi_nodespace *nxv;char *nxp;register int binumber;register int binode;{ register struct uba_device *ui; register int found = 0; register int (**biprobe)(); register struct bisw *pbisw = bidata[binumber].bierr[binode].pbisw; for ( biprobe = pbisw->probes; *biprobe; biprobe++) { if ((ui = bifindui(binumber,binode,biprobe)) == 0) if ((ui = bifindui(binumber,'?',biprobe))==0) if ((ui = bifindui('?','?',biprobe))==0) continue; found =1; if (((*biprobe)(nxv,nxp,binumber,binode,ui)) == 0){ continue; } ui->ui_adpt = binumber; ui->ui_nexus = binode; config_fillin(ui); printf("\n"); ui->ui_dk = -1; ui->ui_alive = 1; ui->ui_addr=(char *)nxv; ui->ui_driver->ud_dinfo[ui->ui_unit] = ui; (*ui->ui_driver->ud_attach)(ui); } return(found);}struct uba_device *bifindui(binumber,binode,biprobe) register int binumber;register int binode;register int (**biprobe)();{ struct uba_driver *udp; register struct uba_device *ui; register struct config_adpt *p_adpt; for (ui=ubdinit; udp =ui->ui_driver; ui++) { if ((udp->ud_probe != *biprobe) || (ui->ui_adpt != binumber) || (ui->ui_nexus != binode) || (ui->ui_alive) || (ui->ui_slave != -1)) continue; /* check that the adapter structure that is associated with this device has not been used. It could have been used in the case of a DEBNK/DEBNT. */ if (is_adapt_alive(ui)) continue; if (strcmp(ui->ui_devname,"bvpni")==0) return(ui); for(p_adpt = &config_adpt[0];p_adpt->p_name; p_adpt++) { if (((char *) ui->ui_driver == p_adpt->c_name) && (p_adpt->c_type == 'D') && (ui->ui_unit == p_adpt->c_num) && (strcmp(p_adpt->p_name,"vaxbi")==0) && ((p_adpt->p_num == binumber) || (p_adpt->p_num == '?'))) return(ui); } } return(0);} #define BI_HARDERR 0x7fff0000#define BI_THRESHOLD 2 /* 2 sec */int nignorebi = 0;unsigned lastbierr = 0;vaxbierrors(binumber,pcpsl)int binumber;int *pcpsl;{ extern int cpu; /* global cpu value from machine/common/cpuconf.c */ int nbi_num; int i; extern int nNXMI; /* provide escape exit if excessive errors during autoconf */ if (ignorebi) { if (nignorebi++ > 0x10000) panic("Too many VAXBI errors"); return; } /* log_bierrors routine will scan and log any VAXBI errors. It will return zero if no recovery should be attempted */ if ( log_bierrors(binumber,pcpsl) == 0 ) {#ifdef vax /* ISIS needs a call here .... TODO */ /* * log more info to get a complete picture of the state * of the machine before we panic. * */ switch (cpu) { case VAX_8200: memerr(); break; case VAX_8800: for (nbi_num=0;nbi_num<MAX_NNBIA;nbi_num++) nbia_log_err(nbi_num); log_ka8800memerrs(); break; case VAX_6200: log_ka6200memerrs(); log_xmierrors(0,pcpsl); break; case VAX_6400: rxma_check_errors(EL_PRILOW); log_xmierrors(0,pcpsl); break; case VAX_9000: /* 9000 has no memories on busses to check. */ /* Just check adapters on xmi for errors. */ for(i = 0; i<nNXMI; i++){ if(mfpr(CPUCNF) & (1 << (CPUCNF_XJA_PRESENT+i))) log_xmierrors(i,pcpsl); } break; default: break; }#endif vax panic("VAXBI error"); }}log_bierrors(binumber,pcpsl)int binumber; /* VAXBI number */int *pcpsl; /* pointer to error pc and psl *//*---------------------------------------------------------------* * function: scan VAXBI nodes for hard errors and log BI error * * info if found. If no errors found, get out. * * return zero if no recovery should be attempted * * by the calling error handler routine. * *---------------------------------------------------------------*/{ register struct bi_regs *biregp; register struct bidata *bid; register struct el_rec *elrp; register struct el_bier *elbierp; register struct bi_nodespace *nxv; int node; int nodecnt = 0; int *intp; struct bisw *pbisw; int priority; int recover_status = 1; bid = &bidata[binumber]; /* need to loop through BI nodes to determine if there is a hard error on a node with "BIF_SET_HEIE" enabled. It is assumed that all other boards will handle the error in there own way. */ nxv = bid->bivirt; for(node=0; node < NBINODES; node++,nxv++) { if (bid->binodes_alive & (1 << node)) { /*count number of active BI nodes */ nodecnt++; pbisw = bid->bierr[node].pbisw; if ((pbisw->bi_flags & BIF_SET_HEIE) && (nxv->biic.biic_err & BI_HARDERR)) { priority = EL_PRISEVERE; recover_status =0; } if ( (pbisw->bi_type == BI_BUA) || (pbisw->bi_type == BI_BLA)) { /* hard error on bua csr if an error bit is set */ if (((struct bua_regs *)nxv)->bua_ctrl & BUACR_MASK) { priority = EL_PRISEVERE; recover_status =0; } } } } /* if recover_status still 1, no hard errors were found. Assume error was handled elsewhere and log no error. */ if (recover_status == 1) { return(recover_status); } /* provide time-out escape for repeat offenders */ if ((time.tv_sec - bid->bilast_err_time) < BI_THRESHOLD){ priority = EL_PRISEVERE; recover_status =0; } else priority = EL_PRIHIGH; bid->bilast_err_time = time.tv_sec; bid->bi_err_cnt++; /* get error log packet and fill in header. */ elrp = ealloc(sizeof(struct bi_regs) * nodecnt + 12, priority); if (elrp != NULL) { LSUBID(elrp,ELCT_BUS,ELBUS_BIER,EL_UNDEF,binumber,EL_UNDEF,EL_UNDEF); elbierp = &elrp->el_body.elbier; biregp = elbierp->biregs; } if (recover_status == 0) cprintf("hard error VAXBI%d\n",binumber); nxv = bid->bivirt; for(node=0; node < NBINODES; node++,nxv++) { if (bid->binodes_alive & (1<<node)) { pbisw = bid->bierr[node].pbisw; bid->bierr[node].bierr1 = bid->bierr[node].bierr; bid->bierr[node].bierr=nxv->biic.biic_err&(~BIERR_UPEN); if (recover_status == 0) { cprintf("%s at node %d error %b ", pbisw->bi_name, node, bid->bierr[node].bierr, BIERR_BITS); } /* reset error bits on proper nodes */ if (pbisw->bi_flags & BIF_SET_HEIE) nxv->biic.biic_err = nxv->biic.biic_err; if ( (pbisw->bi_type == BI_BUA) || (pbisw->bi_type == BI_BLA)) { /* log bua csr if an error bit is set */ if (((struct bua_regs *)nxv)->bua_ctrl & BUACR_MASK) { bid->bierr[node].bierr = ((struct bua_regs *)nxv)->bua_ctrl; logbigen(binumber,pcpsl,nxv); if (recover_status == 0) cprintf(" cr %b ", (((struct bua_regs *)nxv)->bua_ctrl), BUAERR_BITS); } } if (recover_status == 0) cprintf("\n"); if (elrp != NULL) { /* log the node status */ biregp->bi_typ = nxv->biic.biic_typ; biregp->bi_ctrl = nxv->biic.biic_ctrl; biregp->bi_err = bid->bierr[node].bierr; biregp->bi_err_int = nxv->biic.biic_err_int; biregp->bi_int_dst = nxv->biic.biic_int_dst; biregp++; } } } /* finish logging error */ if (elrp != NULL) { intp = (int *)biregp; elbierp->bier_nument = (short)nodecnt; *intp++ = *pcpsl++; *intp = *pcpsl; EVALID(elrp); } /* loop back through nodes and call reset routines if preset */ nxv = bid->bivirt; for(node=0; node < NBINODES; node++,nxv++) { if (bid->binodes_alive & (1<<node)) { pbisw= bid->bierr[node].pbisw; (*(pbisw->bi_reset))(binumber,node,nxv); } } return(recover_status);}logbigen(binum,pcpsl,nxv)int binum;int *pcpsl;register struct bi_nodespace *nxv;{ register int class; register int type; register struct el_rec *elrp; register struct el_bigen *elbp; elrp = ealloc(sizeof(struct el_bigen), EL_PRIHIGH); if (elrp != NULL) { elbp = &elrp->el_body.elbigen; elbp->bigen_dev = nxv->biic.biic_typ; elbp->bigen_bicsr = nxv->biic.biic_ctrl; elbp->bigen_ber = nxv->biic.biic_err; elbp->bigen_csr = ((struct bua_regs *)nxv)->bua_ctrl; switch (elbp->bigen_dev & BITYP_TYPE) { case BI_BUA: class = ELCT_ADPTR; type = ELADP_BUA; break; case BI_BLA: class = ELCT_DCNTL; type = ELBI_BLA; break; default: class = EL_UNDEF; type = EL_UNDEF; break; } if (type == ELADP_BUA) elbp->bigen_fubar = ((struct bua_regs *)nxv)->bua_fubar & BUAFUBAR; else elbp->bigen_fubar = 0; elbp->bigen_pc = *pcpsl++; elbp->bigen_psl = *pcpsl; LSUBID(elrp,class,type,EL_UNDEF,binum,EL_UNDEF,EL_UNDEF); EVALID(elrp); }}extern int nNVAXBI;biclrint(){int binumber,binode;struct bisw *pbisw;struct bi_nodespace *nxv; for (binumber= 0; binumber<nNVAXBI; binumber++) { nxv = bidata[binumber].bivirt; if (bidata[binumber].binodes_alive) for(binode=0; binode < 16; binode++,nxv++){ pbisw = bidata[binumber].bierr[binode].pbisw; if ((bidata[binumber].binodes_alive & 1<<binode) && (pbisw->bi_flags & BIF_SET_HEIE)){ nxv->biic.biic_ctrl &= ~(BICTRL_HEIE); if ((pbisw->bi_type == BI_BUA) || (pbisw->bi_type == BI_BLA)) ((struct bua_regs *)nxv)->bua_ctrl &= ~(BUACR_BUAEIE); } } }}bisetint(){int binumber,binode;struct bisw *pbisw;struct bi_nodespace *nxv; for (binumber= 0; binumber<nNVAXBI; binumber++) { nxv = bidata[binumber].bivirt; if (bidata[binumber].binodes_alive) for(binode=0; binode < 16; binode++,nxv++){ pbisw = bidata[binumber].bierr[binode].pbisw; if ((bidata[binumber].binodes_alive & 1<<binode) && (pbisw->bi_flags & BIF_SET_HEIE)){ nxv->biic.biic_err = nxv->biic.biic_err; nxv->biic.biic_ctrl |= (BICTRL_HEIE); if ((pbisw->bi_type == BI_BUA) || (pbisw->bi_type == BI_BLA)){ ((struct bua_regs *)nxv)->bua_ctrl = ((struct bua_regs *)nxv)->bua_ctrl; ((struct bua_regs *)nxv)->bua_ctrl |= (BUACR_BUAEIE); } } } }}/* * bidev_vec(): To set up BI device interrupt vectors. * It is called with 4 parameters: * binum: the BI number that the device is on * binode: the BI node number of the device * level: the offset corresponding to the interrupt priority level * to start at. See ../vaxbi/bireg.h: LEVEL{14,15,16,17}. * ui: the device structure (for names of interrupt routines) */bidev_vec(binum, binode, level, ui) int binum, binode, level; struct uba_device *ui;{ register int (**ivec)(); register int (**addr)(); /* double indirection neccessary to keep the C compiler happy */ for (ivec = ui->ui_intr; *ivec; ivec++) { addr = (int (**)())(SCB_BI_VEC_ADDR(binum,binode,level)); *addr = scbentry(*ivec,SCB_ISTACK); level += BIVECSIZE; }}bicon_vec(binum, binode, level, um) int binum, binode, level; struct uba_ctlr *um;{ register int (**ivec)(); register int (**addr)(); /* double indirection neccessary to keep the C compiler happy */ for (ivec = um->um_intr; *ivec; ivec++) { addr = (int (**)())(SCB_BI_VEC_ADDR(binum,binode,level)); *addr = scbentry(*ivec,SCB_ISTACK); level += BIVECSIZE; }}#ifdef mips/* * bisst -- BI Start Self Test * * locore routine for vax. Done for mips in C since we don't have to deal with * funny BI stuff from VAX 8200s. */int ignorebi;bisst(address)volatile int *address;{ int save, retval, i; retval = 1; save = ignorebi; ignorebi = 1; *address |= BICTRL_NOARB; wbflush(); DELAY (10); *address |= BICTRL_STS|BICTRL_SST; wbflush(); DELAY (100); /* * Pound sand for quite a while (10 seconds). */ for (i = 0; i < 100; i++) { DELAY(100000); if (!(*address & BICTRL_BROKE)) { retval = 0; break; } } ignorebi = save; return (retval); }#endif mips
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -