📄 ka6400.c
字号:
case 0x14: /* Vector unit error */ /* * sanity check: systems with a low rev number should never * generate a vector unit machine check. */ if ((cpu != VAX_6400) || (ccabase.cca_b_revision <= 3)) { goto bad_vector_mchk; } /* look for the footprint of the load store bug */ /* note: this bug has been fixed in hardware, so if it * is ever encountered, there is a VERY old XRV in the * system. */ ls_bug = vp_ls_bug (error_data[cpunum].s_vintsr); if (ls_bug) { printf ("vector mchk is load store bug\n"); must_panic = 1; } /* * the following printf is a placehoder until I get the uerf * packets defined. */ if (CURRENT_CPUDATA->cpu_vpdata->vpd_in_kernel == VPD_IN_KERNEL) { must_panic = 1; printf ("VP mchk while in kernel mode\n"); } else { printf ("VP mchk while in user mode\n"); vp_remove (); if (CURRENT_CPUDATA->cpu_vpdata->vpd_proc) { u.u_code = TERM_VECT_HARD; psignal (CURRENT_CPUDATA->cpu_vpdata->vpd_proc, SIGKILL); } } break;bad_vector_mchk: /* * branch to here if this is a rev before vectors were * used. */ case 0x15: /* Error on I-stream read */ /* * This error is similar to the BUSERR_READ_DAL machine * check, but occurs on the instruction stream. Please * see the description above (0x11). This is an XMP * only error. */ if (cpu_sub_subtype == MARIAH_VARIANT) { if ((error_data[cpunum].s_pcsts & 0xa00)==0x200) { recover_mem_error(); if(((error_data[cpunum].s_pcsts & 0x1080) == 0x1080) && (cpu_sub_subtype == MARIAH_VARIANT)) { if(time_now - bcache_errtime[cpunum] < 500) { bcache_error[cpunum]++; } else { bcache_errtime[cpunum] = time_now; } } if ((r_bit | fpd) && (uwp==0) && ((error_data[cpunum].s_pcsts & PCSTS_TRAP2)==0)) restartable = 1; } else { /* inconsistent PCSTS, or BUS ERROR */ must_panic = 1; } break; } else { must_panic = 1; break; } default: /* Unknown machine check type code */ /* * Panic on above errors since bad things are * already done and the error may be system-wide */ must_panic = 1; break; } if ((restartable==0) && (must_panic==0)) { /* * Can't restart, but may not need to panic. We * see if we can't simply kill the user process and * continue. */#ifdef KILL_USER if (USERMODE(mcf->psl) && (u.u_procp->p_pid != 1) && (cpunum == 0)) { /* * We were a user process, not the "init" * process, and we are running on the master processor */ swkill(u.u_procp, "ka6400machcheck"); } else { /* Can't kill user or restart, so we must panic */ must_panic = 1; }#else must_panic = 1; #endif } /* * If we are not panicking, we will be recovering. However, * to avoid getting into a loop of error -> restart -> error -> * restart, we force a panic if we had an identical machine check * previously or we had a machine check less than 5 seconds ago. */ if (must_panic == 0) { if ((mchk_data[cpunum].mcode == mcf->mcode) || (time_now - mchk_data[cpunum].time < 500)) must_panic = 1; } /* allocate a error log packet */ if(cpu_sub_subtype != MARIAH_VARIANT) { elrp = ealloc((sizeof(struct el_mc6400frame)), must_panic ? EL_PRISEVERE:EL_PRIHIGH); if (elrp) { LSUBID(elrp,ELCT_MCK,ELMCKT_6400,cpu_subtype,cpunum,EL_UNDEF,mcf->mcode); elmckp = &elrp->el_body.elmck; framep = (struct el_mc6400frame *) &elmckp->elmck_frame. el6400mcf.bcnt; framep->bcnt = mcf->bcnt; framep->mcode = mcf->mcode; framep->vaddr = mcf->vaddr; framep->viba = mcf->viba; framep->iccs_sisr = mcf->iccs_sisr; framep->istate = mcf->istate; framep->sc = mcf->sc; framep->pc = mcf->pc; framep->psl = mcf->psl; framep->s_sscbtr = error_data[cpunum].s_sscbtr; framep->s_bcsts = error_data[cpunum].s_bcsts; framep->s_pcsts = error_data[cpunum].s_pcsts; framep->s_pcerr = error_data[cpunum].s_pcerr; framep->s_vintsr = error_data[cpunum].s_vintsr; framep->s_rcsr = error_data[cpunum].s_rcsr; framep->s_xber = error_data[cpunum].s_xber; framep->s_xfadr = error_data[cpunum].s_xfadr; framep->s_bcctl = error_data[cpunum].s_bcctl; framep->s_bcerr = error_data[cpunum].s_bcerr; EVALID(elrp); /* Make error log packet valid */ cprintf("Machine check data logged in error log buffer.\n"); } else cprintf("Can't log a machine check. (no buffer)\n"); } else { /* XMP-specific */ elrp = ealloc((sizeof(struct el_mc6500frame)), must_panic ? EL_PRISEVERE:EL_PRIHIGH); if (elrp) { LSUBID(elrp,ELCT_MCK,ELMCKT_6500,cpu_sub_subtype,cpunum,EL_UNDEF, mcf->mcode); elmckp = &elrp->el_body.elmck; xmp_framep = (struct el_mc6500frame *) &elmckp->elmck_frame. el6500mcf.bcnt; xmp_framep->bcnt = mcf->bcnt; xmp_framep->mcode = mcf->mcode; xmp_framep->vaddr = mcf->vaddr; xmp_framep->viba = mcf->viba; xmp_framep->iccs_sisr = mcf->iccs_sisr; xmp_framep->istate = mcf->istate; xmp_framep->sc = mcf->sc; xmp_framep->pc = mcf->pc; xmp_framep->psl = mcf->psl; xmp_framep->s_sscbtr = error_data[cpunum].s_sscbtr; xmp_framep->s_bcsts = error_data[cpunum].s_bcsts; xmp_framep->s_pcsts = error_data[cpunum].s_pcsts; xmp_framep->s_pcerr = error_data[cpunum].s_pcerr; xmp_framep->s_vintsr = error_data[cpunum].s_vintsr; xmp_framep->s_xbe0 = error_data[cpunum].s_xber; xmp_framep->s_xfadr0 = error_data[cpunum].s_xfadr; xmp_framep->s_xfaer0 = error_data[cpunum].s_xfaer0; xmp_framep->s_xbeer0 = error_data[cpunum].s_xbeer0; xmp_framep->s_wfadr0 = error_data[cpunum].s_wfadr0; xmp_framep->s_wfadr1 = error_data[cpunum].s_wfadr1; xmp_framep->s_fdal0 = error_data[cpunum].s_fdal0; xmp_framep->s_fdal1 = error_data[cpunum].s_fdal1; xmp_framep->s_fdal2 = error_data[cpunum].s_fdal2; xmp_framep->s_fdal3 = error_data[cpunum].s_fdal3; xmp_framep->s_bcera = error_data[cpunum].s_bcerr; xmp_framep->s_bcert = error_data[cpunum].s_bcert; EVALID(elrp); /* Make error log packet valid */ cprintf("Machine check data logged in error log buffer.\n"); } else cprintf("Can't log a machine check. (no buffer)\n"); } /* END ELSE */ /* look for any pending XMI errors */ log_xmierrors(0,mcf->pc); log_xmi_bierrors(0,mcf->pc); /* * If "must_panic" == 1, we will have to panic, otherwise * we have either killed the user process and can continue, * or we can simply restart the instruction that caused the * current machine check. */ if (must_panic) { cprintf("cpu %x ",rssc->s_iport & 0xf); cprintf("%s\n",mcrvax[mcode]); cprintf("iccs,sisr = 0x%x\t\t",mcf->iccs_sisr); cprintf("internal state = 0x%x\n",mcf->istate); cprintf("pc = 0x%x\t\t", mcf->pc); cprintf("psl = 0x%x\n",mcf->psl); /* Go check each XMI memory node for errors */ rxma_check_errors(EL_PRISEVERE); if(cpu_sub_subtype == MARIAH_VARIANT) { clear_xrperr(); } panic("mchk"); } /* * When we get here, we are not crashing the system. * clear flag to indicate we're done handling the machine check. */ mchk_data[cpunum].mchk_in_progress = 0; /* * check for memory errors and report the recovery */ rxma_check_errors(EL_PRILOW); printf("MACHINE CHECK RECOVERY occured\ntype: %s\n",mcrvax[mcode]); /* Save the mcheck info for later use */ mchk_data[cpunum].time = time_now; mchk_data[cpunum].mcode = mcf->mcode; mchk_data[cpunum].vaddr = mcf->vaddr; mchk_data[cpunum].viba = mcf->viba; mchk_data[cpunum].iccs_sisr = mcf->iccs_sisr; mchk_data[cpunum].istate = mcf->istate; mchk_data[cpunum].sc = mcf->sc; mchk_data[cpunum].pc = mcf->pc; mchk_data[cpunum].psl = mcf->psl; /* Clear RCSR and XBE error bits if XRP, * clear XBE0 and XBEER0 error bits if * XMP. */ clear_xrperr(); if(cpu_sub_subtype == MARIAH_VARIANT) error_enable_cache(); else ka6400_enable_cache(); /* Reenable cache and return */ return(0); }/* initialization code that the slave processor must run before starting up */ka6400initslave() {if(cpu_sub_subtype != MARIAH_VARIANT) ka6400_clear_xbe();else { ka6500_clear_xbe0(); ka6500_clear_xbeer0();}ka6400_init_cache();ka6400_enable_cache();/* 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);}/* * Initial configuration routine to bring up the system. * It is used for both ka6400 (xrp) and ka6500 (xmp). */extern int max_vec_procs;ka6400conf(){ extern struct xmi_reg xmi_start[]; register char *nxv; register int nxp; register int i; register int xrp_node; register struct xmidata *xmidata; register char *start; struct xrp_reg *nxvirt; int cpu_subtype; union cpusid cpusid; cpusid.cpusid = mfpr(SID); /* allocate up 1 xmi structure */ KM_ALLOC(xmidata,struct xmidata *,sizeof(struct xmidata ),KM_DEVBUF, KM_NOW_CL_CO_CA); head_xmidata = xmidata; xmidata->next = 0; xmidata->xminum = 0; /* * make processor's XMI private space accessible * Note: rssc (xrp) and mssc (xmp) are equivalent. * Usage: * rssc->xxx */ nxaccess(RSSCADDR,RSSCmap,RSSCSIZE); /* Make processor's XMI MDA private space accessible. * Note: mda (xmp only) * Usafe: * mda->xxx */ if(cpu_sub_subtype == MARIAH_VARIANT) nxaccess(MDAADDR,MDAmap,MDASIZE); /* * fill in table of IP interrupt addresses. Addresses * are of the form: * * 2101nnnn where nnnn is the decoded XMI node number */ start = (char *) &calypso_ip_addr; for (i=0 ; i< MAX_XMI_NODE ; i++ ) { nxp = 0x21010000 + (1<<i); if (i < 9) nxv = start + (1<<i); else { nxv = start + ((i-8)*NBPG); } calypso_ip[i]=nxv; nxaccess(nxp,&Sysmap[btop((int)(nxv) & ~VA_SYS)],512); } /* * Get node ID of the processor. (The node ID is stored * in bits<3:0> of the RSSC IPORT register.) */ xrp_node = rssc->s_iport & 0xf; cprintf("Node ID = %x\n",xrp_node); xmidata->xmiintr_dst = 1<<xrp_node; xmidata->xmiphys = (struct xmi_reg *) XMI_START_PHYS; xmidata->xmivec_page = &scb.scb_stray; cpu_avail = cca_setup() + 1; /* Allocate memory to store machine check information */ KM_ALLOC(mchk_data, struct mchk_data *, 16 * sizeof(struct mchk_data), KM_MBUF, KM_CLEAR | KM_CONTIG); /* Allocate memory to store snapshot of error registers */ KM_ALLOC(error_data, struct error_data *, 16 * sizeof(struct error_data), KM_MBUF, KM_CLEAR | KM_CONTIG); ka6400_init_cache(); /* Initialise the caches */ ka6400_enable_cache(); /* Enable them. */ if (cpu_sub_subtype != MARIAH_VARIANT) printf("VAX64%d0, ucode rev %d, ucode opts %d, system type 0x%8x.\n", cpu_avail, cpusid.cpuRIGEL.cp_urev, cpusid.cpuRIGEL.cp_uopt, cpu_systype); else printf("VAX6000-5%d0, ucode rev %d, ucode opts %d, system type 0x%8x.\n", cpu_avail, cpusid.cpuRIGEL.cp_urev, cpusid.cpuRIGEL.cp_uopt, cpu_systype); if (fl_ok) { printf("FPA is enabled\n"); } else { printf("FPA is disabled or not present\n"); } /* * Map the node space of the XRP (XMP) so that the processor * can get to its node space CSRs. */ xmidata = get_xmi(0); xmidata->xmivirt = xmi_start; nxp = ka6400nexaddr(0,xrp_node); nxvirt = (struct xrp_reg *)xmidata->xmivirt + (rssc->s_iport & 0xf); nxaccess(nxp,&Sysmap[btop((int)(nxvirt) & ~VA_SYS)],1024); spl0(); /* Ready for interrupts */ xmiconf(0); /* Config all XMI, BI, ..etc devices*/ /* clear warm and cold boot flags */ ccabase.cca_hflag &= ~(CCA_V_BOOTIP|CCA_V_WARMIP); vpmask = vpfree = vptotal = 0; if ((cpu == VAX_6400) && (ccabase.cca_b_revision > 3)) { if (max_vec_procs > 0) { /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -