📄 ka8200.c
字号:
* Wait for interval is character not available. * Return character if possible, else -1 if timeout occurs * before character arrives. * */ka820nxtchr(){ register int s; register int timeout; register result; /* wait a decent interval */ timeout = 30000; while (--timeout > 0) { /* take from buffer if possible */ if (talkin != talkout) { s = spl5(); result = *talkout++; if ((talkout - talkbuf) >= TLKBUF) { talkout = talkbuf; } splx(s); return(result & 0xff); } } return(-1);}/* * ka820txstr - * * Send string to remote bi node (usually secondary processor) * * Return char count if successful or 0 if timeout exceeded * */ka820txstr(node, string)register int node;char *string;{ register char *current; register int timeout; register int sendvalue; /* loop for entire send string */ current = string; while ((sendvalue = *current++) != 0) { /* destination is part of value */ sendvalue |= (node << 8); timeout = 30000; /* the following is a perverted while statement since c has no clean way of checking the 'v' bit */ asm("txloop:"); if (--timeout > 0) { mtpr(RXCD, sendvalue); asm("bvs txloop"); } /* secondary did not come ready in time, send is assumed to have failed */ if (timeout <= 0) { return(0); } } return(current - string);}unsigned dparity8200 = 0;unsigned bierr8200 = 0;unsigned bparity8200 = 0;unsigned cparity8200 = 0;int errcnt8200=0;ka8200machcheck(cmcf)caddr_t cmcf;{ struct bi_nodespace *nxv; int type; int recover; register struct mc8200frame *mcf = (struct mc8200frame *) cmcf; int index=3; /* index to mc8200[] for recoverable error msg */ nxv = (struct bi_nodespace *) nexus; nxv += (mfpr(BINID)); type = ((struct mcframe *) cmcf)->mc_summary; recover = 1; cache_state = 0; /* unexpected interrupt when booting system */ if (cold == 1) { errcnt8200++; if (errcnt8200 > 1000) recover=0; } else { /* BAD ipl is fatal error (microcode lost) */ if ((type & MC8200_BADIPL) != 0) { cprintf("%s\n", mc8200[0]); recover = 0; } /* MICROCODE error is fatal (microcode lost) */ if ((type & MC8200_UERR) != 0) { cprintf("%s\n", mc8200[1]); recover = 0; } /* MICROCODE parity error is fatal (microcode lost) */ if ((type & MC8200_UPARITY) != 0) { cprintf("%s\n", mc8200[2]); recover = 0; } /* Cache parity...can be soft error. Recover if no state has been changed and another one hasn't happened in last 1 sec. */ if ((type & MC8200_DPARITY) != 0) { /* check to see if VAX state changed. */ if (((mcf->mc8200_stat & VCR8200) != 0) && ((mcf->mc8200_summary & PFE8200) == 0)) { recover = 0; cprintf("%s\n", mc8200[3]); } /* is this happening often??? */ if ((time.tv_sec - dparity8200) < MCHK_THRESHOLD) { recover = 0; cprintf("%s\n", mc8200[3]); } dparity8200 = time.tv_sec; index = 3; /* to report error if recoverable */ } /* Can't recover from writes (PC will be past instruction). try to recover if VAX CAN'T retry bit is clear. */ if ((type & MC8200_BIERR) != 0) { if ((mcf->mc8200_summary & PFE8200) == 0) { /* check to see if VAX state changed. */ if ((mcf->mc8200_stat & MEMWRITE) != 0 || (mcf->mc8200_stat & VCR8200) != 0) { recover = 0; cprintf("%s\n", mc8200[4]); } } /* is this happening often??? */ if ((time.tv_sec - bierr8200) < MCHK_THRESHOLD) { recover = 0; cprintf("%s\n", mc8200[4]); } nxv->biic.biic_err = nxv->biic.biic_err; bierr8200 = time.tv_sec; index = 4; /* to report error if recoverable */ } /* BTB tag parity error...can be soft error. Recover if no state has been changed and another one hasn't happened in last 1 sec. */ if ((type & MC8200_BPARITY) != 0) { mtpr(TBIA, 0); /* clear bad TB entries! */ /* check to see if VAX state changed. */ if (((mcf->mc8200_stat & VCR8200) != 0) && ((mcf->mc8200_summary & PFE8200) == 0)) { recover = 0; cprintf("%s\n", mc8200[5]); } /* is this happening often??? */ if ((time.tv_sec - bparity8200) < MCHK_THRESHOLD) { recover = 0; cprintf("%s\n", mc8200[5]); } bparity8200 = time.tv_sec; index = 5; /* to report error if recoverable */ } /* Cache tag parity error...can be soft error. Recover if no state has been changed and another one hasn't happened in last 1 sec. */ if ((type & MC8200_CPARITY) != 0) { /* check to see if VAX state changed. */ if (((mcf->mc8200_stat & VCR8200) != 0) && ((mcf->mc8200_summary & PFE8200) == 0)) { recover = 0; cprintf("%s\n", mc8200[6]); } /* is this happening often??? */ if ((time.tv_sec - cparity8200) < MCHK_THRESHOLD) { recover = 0; cprintf("%s\n", mc8200[6]); } cparity8200 = time.tv_sec; index = 6; /* to report error if recoverable */ } v8200port = v8200port; /* clear portcontroller bits */ logmck((int *)cmcf, ELMCKT_8200, mfpr(BINID), recover); if (recover == 0) { cprintf("\tsumpar\t= %x\n", mcf->mc8200_summary); cprintf("\tparm1\t= %x\n", mcf->mc8200_parm1); cprintf("\tva\t= %x\n", mcf->mc8200_va); cprintf("\tvap\t= %x\n", mcf->mc8200_vap); cprintf("\tmar\t= %x\n", mcf->mc8200_mar); cprintf("\tstatus\t= %x\n", mcf->mc8200_stat); cprintf("\tpc at failure\t= %x\n", mcf->mc8200_pcfail); cprintf("\tupc at failure\t= %x\n",mcf->mc8200_upcfail); cprintf("\ttrap pc\t= %x\n", mcf->mc8200_pc); cprintf("\ttrap psl\t= %x\n\n", mcf->mc8200_psl); } /* scan memory for additional errors and log */ ka8200memerr(); /* scan VAXBI for additional errors and log */ log_bierrors(0, &mcf->mc8200_pc); } mtpr(MCESR,0); /* clear condition flag */ if (recover) mprintf("MACHINE-CHECK RECOVERY OCCURED\ntype: %s",mc8200[index]); else panic("mchk"); return(0);}ka8200memerr (){ int m; int merrtype = EL_UNDEF; struct bimem *mcr; struct el_rec *elrp; struct el_mem *mrp; for (m = 0; m < nmcr; m++) { mcr = (struct bimem *)mcrdata[m].mcraddr; if (((mcr->bimem_csr1 & (BI1_MERR|BI1_CNTLERR)) != 0) || ((mcr->bimem_csr2 & (BI1_RDS|BI1_CRDERR)) != 0)) { elrp = ealloc(EL_MEMSIZE,EL_PRILOW); if (elrp != NULL) { LSUBID(elrp,ELCT_MEM,cpu_subtype,ELMCNTR_BI,EL_UNDEF,EL_UNDEF,EL_UNDEF); if (mcr->bimem_csr2 & BI1_CRDERR) merrtype = 1; else if (mcr->bimem_csr2 & BI1_RDS) merrtype = 2; else if (mcr->bimem_csr1 & BI1_CNTLERR) merrtype = 3; else if (mcr->bimem_csr1 & BI1_MERR) merrtype = 4; mrp = &elrp->el_body.elmem; mrp->elmem_cnt = 1; mrp->elmemerr.cntl = mcr->bimem_biic.biic_ctrl & BICTRL_ID; mrp->elmemerr.type = merrtype; mrp->elmemerr.numerr = 1; mrp->elmemerr.regs[0] = mcr->bimem_csr1; mrp->elmemerr.regs[1] = mcr->bimem_csr2; mrp->elmemerr.regs[2] = EL_UNDEF; mrp->elmemerr.regs[3] = EL_UNDEF; EVALID(elrp); } mcr->bimem_csr1 = BI1_ICRD|BI1_MERR|BI1_CNTLERR; mcr->bimem_csr2 = mcr->bimem_csr2; } v8200port = (v8200port | V8200_CRDEN | V8200_CRDCLR ); } return(0);}ka8200tocons(c) register int c;{ while ((mfpr (TXCS) & TXCS_RDY) == 0) continue; mtpr (TXDB, c); return(0);}/* * this routine sets the cache to the state passed. enabled/disabled */ka8200setcache(state)int state;{ mtpr (CADR, state); return(0);}ka8200cachenbl(){ cache_state = 0; return(0);}/* * 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. */ka8200memenable (){ register struct bimem *mcr; register int m; for (m = 0; m < nmcr; m++) { mcr = (struct bimem *)mcrdata[m].mcraddr; bimemenable(mcr); } return(0);}ka8200nexaddr(ioadpt,nexnum) int ioadpt,nexnum;{ return((int)NEX8200(nexnum));}u_short *ka8200umaddr(ioadpt,ubanumber) int ubanumber,ioadpt;{ return(UMEM8200(ubanumber));}u_short *ka8200udevaddr(ioadpt,ubanumber) int ioadpt,ubanumber;{ return(UDEVADDR8200(ubanumber));}ka8200readtodr(){ u_int todr; char *v8200_lcl; struct tm tm; int s; /* * Copy the toy register contents into tm so that we can * work with. The toy must be completely read in 2.5 millisecs. * * * Wait for update in progress to be done. */ v8200_lcl = (char *) v8200watch; s = spl7(); while( ((struct v8200watch *) v8200_lcl)->v8200_acsr & V8200_BUSY) ; tm.tm_sec = ((struct v8200watch *) v8200_lcl)->v8200_secs; tm.tm_min = ((struct v8200watch *) v8200_lcl)->v8200_mins; tm.tm_hour = ((struct v8200watch *) v8200_lcl)->v8200_hours; tm.tm_mday = ((struct v8200watch *) v8200_lcl)->v8200_mdays; tm.tm_mon = ((struct v8200watch *) v8200_lcl)->v8200_months; tm.tm_year = ((struct v8200watch *) v8200_lcl)->v8200_years; splx( s ); tm.tm_sec = 0x0ff & ((tm.tm_sec << 7) | (tm.tm_sec >> 1)); tm.tm_min = 0x0ff & ((tm.tm_min << 7) | (tm.tm_min >> 1)); tm.tm_hour = 0x0ff & ((tm.tm_hour << 7) | (tm.tm_hour >> 1)); tm.tm_mday = 0x0ff & ((tm.tm_mday << 7) | (tm.tm_mday >> 1)); tm.tm_mon = 0x0ff & ((tm.tm_mon << 7) | (tm.tm_mon >> 1)); tm.tm_year = 0x0ff & ((tm.tm_year << 7) | (tm.tm_year >> 1)); todr = toyread_convert(tm); return(todr);}ka8200writetodr(yrtime)u_int yrtime;{ char *v8200_lcl; struct tm xtime; int s; toywrite_convert(&xtime,yrtime); v8200_lcl = (char *) v8200watch; ((struct v8200watch *) v8200_lcl)->v8200_bcsr = V8200_SETUP; s = spl7(); ((struct v8200watch *) v8200_lcl)->v8200_secs = 0x0ff & (xtime.tm_sec << 1 | xtime.tm_sec >>7); ((struct v8200watch *) v8200_lcl)->v8200_mins = 0x0ff & (xtime.tm_min << 1 | xtime.tm_min >>7); ((struct v8200watch *) v8200_lcl)->v8200_hours = 0x0ff & (xtime.tm_hour << 1 | xtime.tm_hour >>7); ((struct v8200watch *) v8200_lcl)->v8200_mdays = 0x0ff & (xtime.tm_mday << 1 | xtime.tm_mday >>7); ((struct v8200watch *) v8200_lcl)->v8200_months = 0x0ff & (xtime.tm_mon << 1 | xtime.tm_mon >>7); ((struct v8200watch *) v8200_lcl)->v8200_years = 0x0ff & (xtime.tm_year << 1 | xtime.tm_year >>7); /* * Start the clock again. */ ((struct v8200watch *) v8200_lcl)->v8200_acsr = V8200_ASET; ((struct v8200watch *) v8200_lcl)->v8200_bcsr = V8200_BSET; splx( s );}struct v8200rx50 v8200rx50[1];extern struct rx5tab rx5tab;ka8200rxopen(unit)int unit;{ if (BADADDR(&v8200rx50->rx5cs0,1)) { return(1); } return(0);}ka8200startrx() {register u_short sector, track, command, dn, junk; /* drive is interleved */ track = rx5tab.rx5blk/ 10 ; sector = (((rx5tab.rx5blk % 10)/5) + ((rx5tab.rx5blk+track)*2)) % 10; sector++ ; if( ++track > 79 ) track = 0 ; dn = (minor(rx5tab.rx5_buf->b_dev)>>3) & 07; dn=dn-1; command = (dn & 01) << 1 ; if (rx5tab.rx5_buf->b_flags & B_READ ) { command |= READ ; junk = v8200rx50->rx5ca; } else { command |= WRITE; cs_transfer(rx5tab.rx5addr,FILL); } v8200rx50->rx5cs1 = track; v8200rx50->rx5cs2 = sector; v8200rx50->rx5cs0 = command&0x7f; junk = v8200rx50->rx5go; }rx5_intr(){ int junk; /* if not busy...why did we interrupt */ if((rx5tab.rx5_state & RX5BUSY) == 0 ) return; if((v8200rx50->rx5cs0 & RX50_DONE) ==0 ) return; if(v8200rx50->rx5cs0 & ERROR ) { printf("hard error cs%x\n",(rx5_unit+1)); mprintf("cs* = %x, %x, %x, %x, %x\n", v8200rx50->rx5cs0,v8200rx50->rx5cs1, v8200rx50->rx5cs2,v8200rx50->rx5cs3, v8200rx50->rx5cs4); mprintf("Reset drive\n"); v8200rx50->rx5cs0 = RESTORE ; junk = v8200rx50->rx5go; rx5tab.rx5_buf->b_error = EIO; rx5tab.rx5_buf->b_flags |= B_ERROR; rx5tab.rx5_state &= ~ RX5BUSY; iodone(rx5tab.rx5_buf); wakeup((caddr_t)&rx5tab); return; } /* store data */ if (rx5tab.rx5_buf->b_flags & B_READ) cs_transfer(rx5tab.rx5addr,EMPTY); if ( rx5tab.rx5resid > 512) rx5tab.rx5resid -= 512; else rx5tab.rx5resid = 0; rx5tab.rx5addr += 512; rx5tab.rx5blk++; if (rx5tab.rx5resid > 0) cs_start(); /* more to do */ else { iodone(rx5tab.rx5_buf); /* all done */ rx5tab.rx5_state &= ~ RX5BUSY; wakeup((caddr_t)&rx5tab);/* wakeup anyone waiting for drive */ }} cs_transfer(bpp,op) char *bpp; short op;{ register short nbytes; register char *buf, *buf1; int junk,s; nbytes = v8200rx50->rx5ca; buf = bpp; if (rx5tab.rx5resid >=512) nbytes = 512; else nbytes=rx5tab.rx5resid; if (op == FILL ) { /* FILL for floppy write */ buf1 = (char *)&v8200rx50->rx5fdb; while(nbytes) { *buf1 = *buf++ ; --nbytes; } } else { /* Empty for floppy read */ buf1 = (char *)&v8200rx50->rx5edb; while(nbytes){ *buf++ = *buf1; --nbytes; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -