📄 ka6400.c
字号:
/* * log XMA2 memory error. If priority is not LOW then print to * console. */xma2_mem_error(xma2,priority)int priority;register struct xma_reg *xma2;{ register struct el_xma2 *xma_pkg; register struct el_rec *elrp; /* log the XMA2 error */ elrp = ealloc(sizeof(struct el_xma2),priority); if (elrp) { LSUBID(elrp,ELCT_MEM,EL_UNDEF,ELMCNTR_XMA2,EL_UNDEF,EL_UNDEF,EL_UNDEF); xma_pkg = &elrp->el_body.el_xma2; xma_pkg->xma_node = ((svtophy(xma2))>>19)&0xf; xma_pkg->xma_dtype = xma2->xma_type; xma_pkg->xma_xbe = xma2->xma_xbe; xma_pkg->xma_seadr = xma2->xma_seadr; xma_pkg->xma_mctl1 = xma2->xma_mctl1; xma_pkg->xma_mecer = xma2->xma_mecer; xma_pkg->xma_mecea = xma2->xma_mecea; xma_pkg->xma_mctl2 = xma2->xma_mctl2; xma_pkg->xma_becer = xma2->xma_becer; xma_pkg->xma_becea = xma2->xma_becea; xma_pkg->xma_stadr = xma2->xma_stadr; xma_pkg->xma_enadr = xma2->xma_enadr; xma_pkg->xma_intlv = xma2->xma_intlv; xma_pkg->xma_mctl3 = xma2->xma_mctl3; xma_pkg->xma_mctl4 = xma2->xma_mctl4; xma_pkg->xma_bsctl = xma2->xma_bsctl; xma_pkg->xma_bsadr = xma2->xma_bsadr; xma_pkg->xma_eectl = xma2->xma_eectl; xma_pkg->xma_tmoer = xma2->xma_tmoer; EVALID(elrp); } /* print to console if HIGH priority */ if (priority < EL_PRILOW) { cprintf("Memory error \n"); cprintf("xma_phys = %x\n",svtophy(xma2)); cprintf("xma_type = %x\n",xma2->xma_type); cprintf("xma_xbe = %x\n",xma2->xma_xbe); cprintf("xma_seadr = %x\n",xma2->xma_seadr); cprintf("xma_mctl1 = %x\n",xma2->xma_mctl1); cprintf("xma_mecer = %x\n",xma2->xma_mecer); cprintf("xma_mecea = %x\n",xma2->xma_mecea); cprintf("xma_mctl2 = %x\n",xma2->xma_mctl2); cprintf("xma_becer = %x\n", xma2->xma_becer); cprintf("xma_becea = %x\n", xma2->xma_becea); cprintf("xma_stadr = %x\n", xma2->xma_stadr); cprintf("xma_enadr = %x\n", xma2->xma_enadr); cprintf("xma_intlv = %x\n", xma2->xma_intlv); cprintf("xma_mctl3 = %x\n", xma2->xma_mctl3); cprintf("xma_mctl4 = %x\n", xma2->xma_mctl4); cprintf("xma_bsctl = %x\n", xma2->xma_bsctl); cprintf("xma_bsadr = %x\n", xma2->xma_bsadr); cprintf("xma_eectl = %x\n", xma2->xma_eectl); cprintf("xma_tmoer = %x\n", xma2->xma_tmoer); }}/* * 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. */ka6400memenable (){ 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, enable CRD */ xma = (struct xma_reg *) nxv; xma->xma_mctl1 &= ~XMA_CTL1_CRD_DISABLE; } }}/* * this routine sets the cache to the state passed. enabled/disabled */ka6400setcache(state)int state;{ if (state) { /* enable the cache */ ka6400_enable_cache(); return(0); } return(-1);}ka6400cachenbl(){ cache_state = 0x1; return(0);}ka6400tocons(c)register int c;{ register int timeo; timeo = 100000; while ((mfpr (TXCS) & TXCS_RDY) == 0) { if (timeo-- <= 0) { return(0); } } mtpr (TXDB, c); return(0);}/* * Routine to determine if memory of given virtual address and given * length in bytes can be accessed without causing a machine check. * It calls "bbadaddr" in locore.s check. However, for * some addresses on the UNIBUS, the access does not cause a machine * check, but the error is reported to the BIIC of the BUA, * so bbadaddr can't detect it. In this case we clear all BIIC * error bits, access the address, and check for the setting of any * BIIC error. */int ka6400badaddr(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; } } splx(s); return(foo);}/* reboot VAX64xx/VAX65xx machine */ka6400reboot() { struct xmidata *xmidata; struct xrp_reg *xrp_node; /* set O/S reboot flag so reboot happens */ ccabase.cca_hflag |=CCA_V_REBOOT; /* get pointer to xcp node to reboot*/ xmidata = get_xmi(0); xrp_node =(struct xrp_reg *)xmidata->xmivirt + (rssc->s_iport & 0xf); /* hit the halt bit... so long */ xrp_node->xrp_xbe = (xrp_node->xrp_xbe & ~XMI_XBAD) | XMI_NHALT; DELAY(10000); /* give time for the "XMI_NHALT" to work */ /* just in case "XMI_NHALT" doesn't work. We should never reach the halt */ asm("halt"); }/* halt VAX64xx/VAX65xx machine */ka6400halt() { struct xmidata *xmidata; struct xrp_reg *xrp_node; /* get pointer to xcp node to reboot*/ xmidata = get_xmi(0); xrp_node =(struct xrp_reg *)xmidata->xmivirt + (rssc->s_iport & 0xf); /* hit the halt bit... so long */ xrp_node->xrp_xbe = (xrp_node->xrp_xbe & ~XMI_XBAD) | XMI_NHALT; DELAY(10000); /* give time for the "XMI_NHALT" to work */ /* just in case "XMI_NHALT" doesn't work. We should never reach the halt */ asm("halt"); }xrpinit(nxv,nxp,xminumber,xminode)char *nxv;char *nxp;int xminumber,xminode;{#ifdef lint nxv=nxv; nxp=nxp; xminumber=xminumber; xminode = xminode;#endif lint}/* * Return the physical address of the node space of * an XMI node given the node ID. * * Parameters: * xminumber Ignored * xminode Node ID (0 to 15) */ka6400nexaddr(xminumber,xminode) int xminode,xminumber;{ /* Each node space is 512Kb (0x80000) in length */ return((XMI_START_PHYS+(xminode * 0x80000))); }ka6400umaddr(binumber,binode) int binumber,binode;{ return(((int) bidata[binumber].biphys) + 0x400000 + (0x40000 * binode));}ka6400udevaddr(binumber,binode) int binumber,binode;{ return(((int) bidata[binumber].biphys) + 0x400000 + 0x3e000 + (0x40000 * binode));}/* * Routine to initialise the primary and the backup caches. * The caches need to be initialised after a power up, and * after a tag parity error has been detected. * * Note: Both primary and backup caches are disabled when * this routine returns. */ka6400_init_cache(){register int i;register int oldipl;oldipl = spl7(); /* Raise to highest IPL *//* * Enable refresh, clear errors, disable primary cache * should be 0xec, this is workaround bug 1st pass chip bug * 2nd pass can flush the cache and needs not use a loop. Howvever, * we do the same for both types. This code works for both * 1st and 2nd pass machines. */if(cpu_sub_subtype != MARIAH_VARIANT) { mtpr(PCSTS, 0xe8); /* non-functional Pcache, don't set flush bit */ /* Write invalid tags with good parity to the primary cache */ for (i=0; i<0x800; i+=8) { mtpr(PCIDX, i); mtpr(PCTAG, 0x40000000); } /* Enable refresh, clear errors, disable backup cache */ mtpr(BCCTL,0x8); mtpr(BCSTS,1); /* Write all backup cache tag with valid bit clear and good parity */ for (i=0; i<20000; i+=0x40) { mtpr(BCIDX,i); mtpr(BCBTS,0x20000000); } /* Write all backup PTS tag entries with clear V bit and good parity */ for (i=0; i<0x800; i+=0x10) { mtpr(BCIDX,i); mtpr(BCP1TS, 0x20000000); mtpr(BCP2TS, 0x20000000); }}else { /* Mariah support */ mtpr(PCSTS, 0xe4); /* clear errors and turn off primary cache */ /* Write invalid tags with good parity to the primary cache */ for (i=0; i<0x100; i+=8) { mtpr(PCIDX, i); mtpr(PCTAG, 0x80000000); } /* Clear errors, disable backup cache */ mtpr(XMP_BCCTL,0x0); mtpr(XMP_BCSTS,0x000001f6); /* Write all backup cache tag with valid bit clear and good parity */ for (i=0; i<0x1000; i+=0x80) { mtpr(XMP_BCIDX,i); mtpr(XMP_BCBTS,0x00000300); }}splx(oldipl); /* Restore to old IPL */}/* * Routine to enable the primary and backup caches. */ka6400_enable_cache(){ union cpusid cpusid; int s;if(cpu_sub_subtype != MARIAH_VARIANT) { cpusid.cpusid = mfpr(SID); /* * To ensure cache coherency, always enable shadow primary tag in * the backup cache first before enabling the primary cache. * * Note: when writing PCSTS, always clear out the trap and * interrupt bits to ensure that the primary cache is enabled * properly. */ if (cpusid.cpuRIGEL.cp_urev == 1) { /* Can't set FLUSH bit in Pass 1 XRP PCSTS */ s = spl7(); mtpr(PCSTS,0xe8); /* enable refresh */ mtpr(BCFBTS,0); /* flush backup tag store */ mtpr(BCFPTS,0); /* flush shadown primary tag store*/ mtpr(BCCTL,0xe); /* enable backup cache, refresh, */ /* and shadow primary tag */ mtpr(BCFBTS,0); /* flush backup tag store */ mtpr(PCSTS,0xea); /* enable primary cache, enable refresh */ } else { /* fully functional P cache */ s = spl7(); mtpr(PCSTS,0xec); /* enable refresh, flush cache before */ /* enabling backup Ptag*/ mtpr(BCFBTS,0); /* flush backup tag store */ mtpr(BCFPTS,0); /* flush shadown primary tag store*/ mtpr(BCCTL,0xe); /* enable backup cache, refresh, and */ /* shadow primary tag */ mtpr(BCFBTS,0); /* flush backup tag store */ mtpr(PCSTS,0xee); /* enable primary cache, enable refresh,*/ /* flush cache*/ }}else { /* Mariah support */ s = spl7(); mtpr(PCSTS,0xe4); /* flush cache before enabling primary cache*/ mtpr(XMP_BCCTL,0x2); /* enable backup cache */ mtpr(PCSTS,0xe6); /* enable primary cache, flush cache */} splx(s);}/* * Routine to enable caches while in error handling code. This code is * for XMP machines only. */error_enable_cache(){ register int i; register int cpunum; cpunum=CURRENT_CPUDATA->cpu_num; bc_enable[cpunum] = bc_enable[cpunum] | 0x2 & ~0x5;/*Set bcache flags*/ pc_enable[cpunum] = pc_enable[cpunum] | (PCSTS_ENABLE_PTS | PCSTS_FLUSH_CASHE) & ~PCSTS_FORCE_HIT; if (bcache_disable[cpunum]) { bc_enable[cpunum] = 0x0; /* Disable bcache */ if(error_data[cpunum].s_bcctl & 0x2) printf("Backup cache is being disabled on cpu %x\n",cpunum); } if (pcache_disable[cpunum]) { pc_enable[cpunum] &= ~PCSTS_ENABLE_PTS; /* Disable pcache */ if(error_data[cpunum].s_pcsts & PCSTS_ENABLE_PTS) printf("Primary cache is being disabled on cpu %x\n",cpunum); } if(error_data[cpunum].s_bcctl & 0x2) { /* deallocate only if enabled */ for(i=0;i<=4095;i++) { mtpr(XMP_BCIDX,i*128);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -