📄 ka8800.c
字号:
/* was BI configured */ if (is_adapt_configured("vaxbi",binumber) ==0){ printf("vaxbi %d not configured\n",binumber); continue; } vor = (SCB_BI_OFFSET(0)) + (numnbia * 0x400); if ((binumber&1) == 0) { printf("nbia%x adapter at address %x\n",numnbia,nxp); } /* initialize info about the BI we are going to autoconfigure */ bidata[binumber].bivirt = ((struct bi_nodespace *)(nexus)); bidata[binumber].bivirt += (bifound*16); bidata[binumber].biphys = (struct bi_nodespace *) (ka8800nexaddr(binumber,0)); bidata[binumber].bivec_page = bidata[0].bivec_page+(binumber*128); (void) spl6(); /* No interrupts while loopback is on*/ /* turn on loopback so we can get nbib node number */ nbia->nbi_csr1 = nbia->nbi_csr1; nbia->nbi_csr0 |= (vor|NBIC0_INTREN|NBIC0_LOOPBACK); /* see if BI is present (is nbib present? ) */ if ((nbia->nbi_csr1 & (NBIC1_BI0<<(binumber&1))) == 0) { nbia->nbi_csr0 &= ~(NBIC0_LOOPBACK); bifound++; (void) spl0(); /* allow interrupts... loopback is off */ continue; } nbia_info[numnbia].nbib_alive[binumber&1] = 1; /* map nbib loopback address into virtual memory */ nbib = (struct nbib_regs *) adpt_loopback; nxp = (char *) (ka8800nexaddr(binumber,0)); nxaccess(nxp,ADPT_loopback[0],NBPG); printf("vaxbi%x at address %x\n",binumber,nxp); /* initialize that nbib */ nbib->nbi_biic.biic_typ = BI_NBI; nbib->nbi_biic.biic_bci_ctrl |=(BCI_INTREN|BCI_RTOEVEN); /* initialize nbib so it can see all of NMI memory that is good */ nbib->nbi_biic.biic_strt = 0; /* note...must be mod 256k */ nbib->nbi_biic.biic_end = (vmb_info.memsiz + 0x3ffff) & (~0x3ffff); /* clear any pending errors */ nbib->nbi_biic.biic_err = nbib->nbi_biic.biic_err; nbib->nbi_biic.biic_ctrl |= BICTRL_BROKE; /* map nbib into virtual memory */ bicpunode = nbib->nbi_biic.biic_ctrl & BICTRL_ID; bidata[binumber].cpu_biic_addr = (struct bi_nodespace *) nexus; bidata[binumber].cpu_biic_addr += ((bifound*16) +bicpunode); nxp = (char *) (ka8800nexaddr(binumber,bicpunode)); nxaccess(nxp,Nexmap[((bifound*16)+bicpunode)],BINODE_SIZE); /* turn off loopback so nbia works normally */ nbia->nbi_csr0 &= ~(NBIC0_LOOPBACK); (void) spl0(); /* allow interrupts.... loopback is now off */ bidata[binumber].biintr_dst = 1 << bicpunode; bifound++; /* go autoconfigure the BI */ probebi(binumber); } return(0);}ka8800stopcpu() { asm("halt");}ka8800startcpu(cpunum) int cpunum;{ int timeout; int retry=2; int newconf; if (cpu == VAX_8820) { if (cpunum > 3) return(0); } else if (cpunum > 1) return(0); /* get new configuration if console will listen */ if (newconf=ka8800getconf()) { ka8800_config_info = newconf; } /* try to get second cpu started... sometimes console doesn't listen */ while(retry--){ if (cpu == VAX_8820) { /* if polar star */ /* see if cpu requested is alive according to console */ if (ka8800_config_info & (P_CPU0_AVAIL<<cpunum)) { get_cpudata(cpunum); /* send console magic cookie to start secondary cpu*/ cons_putc(N_COMM | (P_BOOT_CPU0+cpunum)); } else return(0); } else { /* nautilus type */ /* see if cpu requesed is alive */ if ((ka8800_config_info & (N_SCND_ENABLE | N_SINGLE_CPU)) == N_SCND_ENABLE) { get_cpudata(cpunum); /* send console magic cookie to start secondary cpu*/ cons_putc(N_COMM | N_BOOT_OTHER); } else return(0); } /* need to wait for the processor to declare itself runnable. This must be done to pervent a user from issuing 2 startcpu commands at once */ timeout=1500; while(timeout-->0) { DELAY(10000); /* 1/100 of sec */ /* if running then success */ if (CPUDATA(cpunum)->cpu_state&CPU_RUN) { return(1); } } } return(0);}extern int cold;/* this routine request status information form the PRO console to determine what type of Nautilus cpu we are on */ka8800getconf() { register int timeo,info,response; /* to see if slave exists, we must ask console for configuration information */ cons_putc(N_COMM | N_GET_CONF); /* now wait for reply */ for (info = 0, timeo = 1000000; timeo > 0 && info == 0; --timeo) { /* wait for console to have something to say */ if (mfpr(RXCS) & RXCS_DONE) { timeo = 1000000; response = mfpr(RXDB); if ((response & N_MASK_ID) == N_CONF_DATA) { /* the console replied, record what we got */ info = response & N_MASK_DATA; return(info); } else if (!cold) ka8800requeue(response); } } return(0);}int ka8800badaddr(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 = *(short *)addr; foo = 0; 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; } } /* clear any nmi faults generated by the read. */ nmifaultclear(); splx(s); return(foo);}nmifaultclear() { register int junk; register struct nmi_reg *mcr;#ifdef lint junk=junk;#endif lint if (cpu == VAX_8820) { junk = star_csr.csr3; star_csr.csr1 = NBW_ENABLE_TIMEOUT_INT; junk = nemo_csr.csr3; nemo_csr.csr1 = NBW_ENABLE_TIMEOUT_INT; } mcr = (struct nmi_reg *) mcrdata[0].mcraddr; junk = mcr->memcsr5; junk = mcr->memcsr0; mcr->memcsr0 = 0x04000000; mtpr(CLRTOSTS,1);}ka8800nmifault(pcpsl)caddr_t pcpsl; /* pointer to error pc/psl */{ int donot_recover = 0; int i; if (cpu == VAX_8820) { /* log errors from the nautilus bus window on polarstar */ donot_recover |= nwb_log_err(); } for(i=0; i< MAX_NNBIA; i++) { /* check and log any nbia/nbib adapter errors. Routine will return info on whether to atempt to recover. Also log any VAXBI errors */ log_ka8800bierrors(i,pcpsl); donot_recover |= nbia_log_err(i); } /* check for any nmi faults. Rountine will return info on whether to attempt to recover. */ donot_recover |= nmifault_log(); if (donot_recover) panic("nmi fault"); nmifaultclear(); }#define NBW_CSR0_ERR 0xf7002400nwb_log_err() { register struct el_rec *elrp; register struct el_nbwadp *nbwadp; /* check for any errors on STAR or NEMO sides of bus window */ if (((star_csr.csr0 & NBW_CSR0_ERR) == 0) && ((nemo_csr.csr0 & NBW_CSR0_ERR) == 0)) return(0); /*no errors */ /* log the nbia err */ elrp = ealloc(sizeof(struct el_nbwadp),EL_PRISEVERE); if (elrp != NULL) { LSUBID(elrp,ELCT_ADPTR,ELADP_NBW,EL_UNDEF,0,0,EL_UNDEF); nbwadp = &elrp->el_body.el_nbwadp; /* log star CSR's */ nbwadp->star_csr0 = star_csr.csr0; nbwadp->star_csr1 = star_csr.csr1; /* log nemo CSR's */ nbwadp->nemo_csr0 = nemo_csr.csr0; nbwadp->nemo_csr1 = nemo_csr.csr1; nbwadp->nemo_csr6 = nemo_csr.csr6; EVALID(elrp); } return(1);}nbia_log_err(nbianum) int nbianum;{ register struct el_rec *elrp; register struct el_nmiadp *nmiadp; register struct nbib_regs *nbib; register int binumber; /* return if this NBIA not present */ if (nbia_info[nbianum].alive == 0) return(0); /* check for an adapter error */ if ((nbia_info[nbianum].nbia->nbi_csr1 & NBIC1_ERR) == 0) /* no error */ return(0); /* log the nbia err */ elrp = ealloc(sizeof(struct el_nmiadp),EL_PRISEVERE); if (elrp != NULL) { LSUBID(elrp,ELCT_ADPTR,ELADP_NBI,EL_UNDEF,0,nbianum,EL_UNDEF); nmiadp = (struct el_nmiadp *) &elrp->el_body.elnmiadp; nmiadp->nmiadp_nbiacsr0 = nbia_info[nbianum].nbia->nbi_csr0; nmiadp->nmiadp_nbiacsr1 = nbia_info[nbianum].nbia->nbi_csr1; binumber = nbianum << 1; if (nbia_info[nbianum].nbib_alive[0]) { nbib = (struct nbib_regs *)bidata[binumber].cpu_biic_addr; nmiadp->nmiadp_nbib0err = nbib->nbi_biic.biic_err; } if (nbia_info[nbianum].nbib_alive[1]) { nbib = (struct nbib_regs *)bidata[binumber+1].cpu_biic_addr; nmiadp->nmiadp_nbib0err = nbib->nbi_biic.biic_err; } EVALID(elrp); } /* currently donot recover */ return(1);}nmifault_log() { register struct nmi_reg *mcr; register struct el_rec *elrp; register struct el_nmiflt *nmiflt; register int i; int nmifsr,memcsr0,nbia0csr0,nbia1csr0; nmifsr = mfpr(NMIFSR); mcr = (struct nmi_reg *) mcrdata[0].mcraddr; memcsr0 = mcr->memcsr0; if (nbia_info[0].alive) nbia0csr0 = nbia_info[0].nbia->nbi_csr0; else nbia0csr0 = 0; if (nbia_info[1].alive) nbia1csr0 = nbia_info[1].nbia->nbi_csr0; else nbia1csr0 = 0; if (!((nmifsr != 0) || ((memcsr0 & NMI_C0_ERR) != 0) || ((nbia1csr0 & NBIC0_ERR) != 0) || ((nbia0csr0 & NBIC0_ERR) != 0))) /* no nmifault */ return(0); /* log nmi fault */ elrp = ealloc(sizeof(struct el_nmiflt),EL_PRISEVERE); if (elrp != NULL) { LSUBID(elrp,ELCT_BUS,ELBUS_NMIFLT,EL_UNDEF,0,EL_UNDEF,EL_UNDEF); nmiflt = (struct el_nmiflt *) &elrp->el_body.elnmiflt; nmiflt->nmiflt_nmifsr = nmifsr; nmiflt->nmiflt_nmiear = mfpr(NMIEAR); nmiflt->nmiflt_nbia0 = nbia0csr0; nmiflt->nmiflt_nbia1 = nbia1csr0; nmiflt->nmiflt_memcsr0 = memcsr0; for (i=0 ; i < EL_SIZE256; i++) { nmiflt->nmiflt_nmisilo[i] = mfpr(NMISILO); } EVALID(elrp); } return(1);}log_ka8800bierrors(nbianum,pcpsl)int nbianum; /* NBIA number */int *pcpsl; /* pointer to error pc/psl pair *//*---------------------------------------------------------* * function: to call log_bierrors for each existing VAXBI * * on each exsiting NBIA. It will scan and log * * any VAXBI errors. * *---------------------------------------------------------*/{ register int binumber; /* check if this NBIA is present */ if (nbia_info[nbianum].alive) { binumber = nbianum << 1; /* check if left VAXBI present */ if (nbia_info[nbianum].nbib_alive[0]) log_bierrors(binumber,pcpsl); /* check if right VAXBI present */ if (nbia_info[nbianum].nbib_alive[1]) log_bierrors(binumber+1,pcpsl); } }nbiinit(nxv,nxp,binumber,binode)char *nxv;char *nxp;int binumber,binode;{#ifdef lint nxv=nxv; nxp=nxp; binumber=binumber; binode = binode;#endif lint /* nothing to do */}ka8800nexaddr(binumber,binode) int binode,binumber;{ return((int)NEX8800(binumber,binode));}u_short *ka8800umaddr(binumber,binode) int binumber,binode;{ return(UMEM8800(binumber,binode));}u_short *ka8800udevaddr(binumber,binode) int binumber,binode;{ return(UDEVADDR8800(binumber,binode));}/* * 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -