📄 ka60.c
字号:
elrp->el_body.elesr650.esr_dser = ffqregs->cq_dser; elrp->el_body.elesr650.esr_qbear = ffqregs->cq_mear; elrp->el_body.elesr650.esr_dear = ffqregs->cq_sear; } if ((mbp->mb_vaddr->f_cpuid & 0x3) == FCPU_PROCA) { /* FQAM */ /* Log FQAM data here */ ; } } EVALID(elrp); }}/* * Log Memory CSRs (packet 4 of KA650 error spec) * * Note: side-effect. * logmempkt sets the global var ka650_module to a coded number, * thus logmempkt must be called before consprint() for pkt 4. */ka60logmempkt(recover) int recover; /* for pkt priority */{ register struct mb_node *mbp; register struct fmdc_regs *fmp; struct el_rec *elrp; struct el_mem *mrp; int merrtype = EL_UNDEF; for (mbp = mbus_nodes; mbp->mb_flags & FBIC_MAPPED; mbp++) { if ((mbp->mb_modtype & FMOD_CLASS) == FMOD_FMDC) { fmp = (struct fmdc_regs *)mbp->mb_vaddr; if (fmp->fm_fmdcsr & FMDC_ERROR) { elrp = ealloc(EL_MEMSIZE,recover ? EL_PRIHIGH : EL_PRISEVERE); if (elrp != NULL) { LSUBID(elrp,ELCT_MEM, EL_UNDEF,ELMCNTR_60,EL_UNDEF, EL_UNDEF,EL_UNDEF); if ((fmp->fm_eccsynd0 & FMDC_MBE) || (fmp->fm_eccsynd1 & FMDC_MBE)) { merrtype = FF_MEM_RDS; } else if ((fmp->fm_eccsynd0 & FMDC_SBE) || (fmp->fm_eccsynd1 & FMDC_SBE)) { merrtype = FF_MEM_CRD; } mrp = &elrp->el_body.elmem; mrp->elmem_cnt = 1; mrp->elmemerr.cntl = ((mbp->mb_flags & FMDC_CNTLR) >> 28); mrp->elmemerr.type = merrtype; mrp->elmemerr.numerr = 1; mrp->elmemerr.regs[0] = fmp->fm_eccaddr0; mrp->elmemerr.regs[1] = fmp->fm_eccaddr1; mrp->elmemerr.regs[2] = fmp->fm_eccsynd0; mrp->elmemerr.regs[3] = fmp->fm_eccsynd1; EVALID(elrp); ka60_module = MBUS_SLOT(mbp->mb_physaddr); } } } else { /* should have a case for FMCM, but is obsolete */ ; } }}/* * The toy clock register on the SSC chip is in TODR * format, but cannot be accessed as a IPR in Firefox. * It is in I/O space. */ka60readtodr(){ register struct ssc_regs *ssc = (struct ssc_regs *)cvqssc; return(ssc->ssc_toy);}/* * The toy clock register on the SSC chip is in TODR * format, but cannot be accessed as a IPR in Firefox. * It is in I/O space. */ka60writetodr(yrtime)u_int yrtime;{ register struct ssc_regs *ssc = (struct ssc_regs *)cvqssc; ssc->ssc_toy = TODRZERO + (100 * yrtime);}/* * Clear the FBCSR_FRZN bit and any other error bits in the FBIC and * enable FBIC error logging. */intenafbiclog(){ register struct mb_node *mbp; register struct fbic_regs *fbaddr; for(mbp = mbus_nodes; mbp->mb_flags & FBIC_MAPPED; mbp++) { fbaddr = mbp->mb_vaddr; /* * Firestarter memory does not have busaddr or busctl * registers. */ if ((mbp->mb_modtype & (FMOD_CLASS | FMOD_INTERFACE)) != (FMOD_MEM | FMOD_FIRESTARTER)) { fbaddr->f_busaddr = 0; fbaddr->f_busctl = 0; } fbaddr->f_buscsr = FBCSR_CLEAR; }}/* * Dump the interesting (frozen) FBIC registers to * the console and error logger. */intka60fbicdump(){ register struct mb_node *mbp; register struct fbic_regs *fbaddr; register struct fmdc_regs *fmaddr; int frozen = 0; for(mbp=mbus_nodes; ((mbp->mb_flags&FBIC_MAPPED)&&(frozen==0)); mbp++) { fbaddr = mbp->mb_vaddr; /* * NOTE: f_buscsr register bits are active low. */ if(!(~fbaddr->f_buscsr & FBCSR_FRZN)) continue; else frozen++; } if(frozen) { printf("FBIC register dump\n"); for(mbp = mbus_nodes; mbp->mb_flags & FBIC_MAPPED; mbp++) { fbaddr = mbp->mb_vaddr; /* * NOTE: f_buscsr register bits are active low. */ if(!(~fbaddr->f_buscsr & FBCSR_FRZN)) continue; printf("\tmodtype = 0x%x\n", fbaddr->f_modtype); printf("\tbuscsr = 0x%x\n", fbaddr->f_buscsr); if ((mbp->mb_modtype & (FMOD_CLASS | FMOD_INTERFACE)) == (FMOD_MEM | FMOD_FIRESTARTER)) { printf("\tfmdcsr = 0x%x\n", fbaddr->f_busctl); printf("\tbaseaddr = 0x%x\n", fbaddr->f_busaddr); } else if ((mbp->mb_modtype & FMOD_CLASS) == FMOD_MEM) { fmaddr = (struct fmdc_regs *)fbaddr; printf("\tbusctl = 0x%x\n", fmaddr->fm_busctl); printf("\tbusadr = 0x%x\n", fmaddr->fm_busaddr); printf("\tbusdat = 0x%x\n", fmaddr->fm_busdat); printf("\tfmdcsr = 0x%x\n", fmaddr->fm_fmdcsr); printf("\tbaseaddr = 0x%x\n", fmaddr->fm_baseaddr); printf("\teccaddr0 = 0x%x\n", fmaddr->fm_eccaddr0); printf("\teccaddr1 = 0x%x\n", fmaddr->fm_eccaddr1); printf("\teccsynd0 = 0x%x\n", fmaddr->fm_eccsynd0); printf("\teccsynd1 = 0x%x\n", fmaddr->fm_eccsynd1); } else { printf("\tbusctl = 0x%x\n", fbaddr->f_busctl); printf("\tbusadr = 0x%x\n", fbaddr->f_busaddr); printf("\tbusdat = 0x%x\n", fbaddr->f_busdat); printf("\tfbicsr = 0x%x\n", fbaddr->f_fbicsr); printf("\trange = 0x%x\n", fbaddr->f_range); printf("\tipdvint = 0x%x\n", fbaddr->f_ipdvint); printf("\tcpuid = 0x%x\n", fbaddr->f_cpuid); printf("\tiadr1 = 0x%x\n", fbaddr->f_iadr1); printf("\tiadr2 = 0x%x\n", fbaddr->f_iadr2); } } }}/* * Name: ka60getmbnode * * Args: addr - The physical address of the I/O space page * containing the FBIC registers * * modtype - The contents of the FBIC Modtype register * * Returns: A pointer to the first unused mbus_nodes structure or * if the FBIC was already mapped, a pointer to the mbus_nodes * structure that was initialized at the time the FBIC regs * were mapped. */intka60getmbnode(addr, modtype)u_long addr;u_long modtype;{ register struct mb_node *mbp; for(mbp = mbus_nodes; mbp->mb_flags & FBIC_MAPPED; mbp++) { if((mbp->mb_modtype == modtype) && (mbp->mb_physaddr == addr)) { if(mbp->mb_modtype != FMOD_CPU) break; else if(mbp->mb_flags & FF_WHICH_PROC(addr)) break; } } return((int)mbp);}ka60_mbfillin(mptr, fptr, addr, memctlr)struct mb_node *mptr;struct fbic_regs *fptr;char *addr;int memctlr;{ mptr->mb_modtype = fptr->f_modtype; mptr->mb_physaddr = (u_long)addr; mptr->mb_vaddr = fptr; mptr->mb_flags = FBIC_MAPPED | FBIC_ALIVE | (memctlr << 28); mptr->mb_slot = MBUS_SLOT(addr);}ka60_initcpufbic(fptr)struct fbic_regs *fptr;{ register int (**addr)(); /* double indirection neccessary to keep the C compiler happy */ int base = (int)scb.scb_ipl14; int cpuid; int scbaddr; cpuid = fptr->f_cpuid; fptr->f_busaddr = 0; fptr->f_busctl = 0; fptr->f_buscsr = FBCSR_CLEAR; fptr->f_fbicsr |= FFCSR_EXCAEN | FFCSR_LEDS_OFF | FFCSR_PRI0EN | FFCSR_HALTEN | FFCSR_NORMAL; /* calculate the IP interrupt vector */ scbaddr = (base + ((cpuid >> 2) * 0x20) + 0x08); fptr->f_ipdvint = FIPD_IPUNIT | (scbaddr & 0x1ff); addr = (int (**)())scbaddr; /* * Fill in the address of the f_ipdvint register to be * used for generating IP interrupts. */ ka60_ip[(cpuid >> 1) & 0xf] = (u_long *)&fptr->f_ipdvint; /* * Plug the IP interrupt vector into the SCB */ *addr = scbentry(&Xipintr,SCB_ISTACK);}/* * Initialization code that the slave processor must run * before starting up */ka60initslave(){ ka60cachenbl(); ka60setcache(cache_state);}ka60setscbvec(fptr, ipl, address, stack)struct fbic_regs *fptr;int ipl; /* in hex */int address;int stack;{ register int (**addr)(); /* double indirection neccessary to keep the C compiler happy */ int base = (int)scb.scb_ipl14; int cpuid; int scbaddr; cpuid = fptr->f_cpuid; scbaddr = (base + ((cpuid >> 2) * 0x20) + ((ipl - 0x14) * 4)); addr = (int (**)())scbaddr; *addr = scbentry(address, stack);}/* * Log FBIC registers */ka60logfbicpkt(priority) int priority; /* for pkt priority */{ register struct mb_node *mbp; register struct fbic_regs *fbp; struct el_fmdc *fmdcp; struct el_fbic *fbicp; struct el_fmcm *fmcmp; struct fmdc_regs *fmp; struct el_rec *elrp; int i, j, end; u_long *elrp_tmp; switch (priority) { case 0: /* non-recoverable mchecks & memory errs */ priority = EL_PRISEVERE; break; case 1: /* recoverable mchecks */ priority = EL_PRIHIGH; break; case 2: /* recoverable CRDs */ priority = EL_PRILOW; break; } elrp = ealloc(sizeof(struct el_mbus), priority); if (elrp != NULL) { /* * zero the allocated buffer as we won't write all entries */ for (i = 0; i < 14; i++) { for (j = 0; j < 12; j++) elrp->el_body.elmbus.elmb_module_log[i][j] = 0; } LSUBID(elrp,ELCT_MBUS,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF); /* * Log all of the FBICs, FMDCs, and FMCMs in the * system whether or not they are frozen */ for (mbp = mbus_nodes, i = 0; mbp->mb_flags & FBIC_MAPPED; mbp++,i++) { fbp = mbp->mb_vaddr; switch(mbp->mb_modtype & FMOD_INTERFACE) { case FMOD_FBIC: fbicp = (struct el_fbic *)&elrp->el_body.elmbus.elmb_module_log[i][0]; fbicp->fbic_size = 0x2c; fbicp->fbic_cpuid = (u_char)(fbp->f_cpuid & 0x1f); fbicp->fbic_modtype = fbp->f_modtype; fbicp->fbic_buscsr = fbp->f_buscsr; fbicp->fbic_busctl = fbp->f_busctl; fbicp->fbic_busaddr = fbp->f_busaddr; fbicp->fbic_busdat = fbp->f_busdat; fbicp->fbic_fbicsr = fbp->f_fbicsr; fbicp->fbic_range = fbp->f_range; fbicp->fbic_ipdvint = fbp->f_ipdvint; fbicp->fbic_iadr1 = fbp->f_iadr1; fbicp->fbic_iadr2 = fbp->f_iadr2; if (fbicp->fbic_buscsr & FBCSR_FRZN) fbicp->fbic_valid = FBIC_VALID | FBIC_ANALYZE; else fbicp->fbic_valid = FBIC_VALID; break; case FMOD_FMDC: fmdcp = (struct el_fmdc *)&elrp->el_body.elmbus.elmb_module_log[i][0]; fmp = (struct fmdc_regs *)fbp; fmdcp->fmdc_size = 0x30; fmdcp->fmdc_cpuid = (u_char)(MBUS_SLOT(mbp->mb_physaddr) << 2); fmdcp->fmdc_modtype = fmp->fm_modtype; fmdcp->fmdc_buscsr = fmp->fm_buscsr; fmdcp->fmdc_busctl = fmp->fm_busctl; fmdcp->fmdc_busaddr = fmp->fm_busaddr; fmdcp->fmdc_busctl = fmp->fm_busctl; fmdcp->fmdc_fmdcsr = fmp->fm_fmdcsr; fmdcp->fmdc_baseaddr = fmp->fm_baseaddr; fmdcp->fmdc_eccaddr0 = fmp->fm_eccaddr0; fmdcp->fmdc_eccaddr1 = fmp->fm_eccaddr1; fmdcp->fmdc_eccsynd0 = fmp->fm_eccsynd0; fmdcp->fmdc_eccsynd1 = fmp->fm_eccsynd1; if (fmdcp->fmdc_buscsr & FBCSR_FRZN) fmdcp->fmdc_valid = FBIC_VALID | FBIC_ANALYZE; else fmdcp->fmdc_valid = FBIC_VALID; break; case FMOD_FMCM: fmcmp = (struct el_fmcm *)&elrp->el_body.elmbus.elmb_module_log[i][0]; fmp = (struct fmdc_regs *)fbp; fmcmp->fmcm_size = 0x14; fmcmp->fmcm_cpuid = (u_char)(MBUS_SLOT(mbp->mb_physaddr) << 2); fmcmp->fmcm_modtype = fmp->fm_modtype; fmcmp->fmcm_buscsr = fmp->fm_buscsr; fmcmp->fmcm_busctl = fmp->fm_busctl; fmcmp->fmcm_baseaddr = fmp->fm_busaddr; /* * Error entry is valid, but there aren't enough * error bits in Firestarter memory to include * it in the error analysis */ fmcmp->fmcm_valid = FBIC_VALID; break; default: break; } /* * elmb_size is the number of module_logs plus the size * of each module log plus the three long words at the * top of the el_mbus structure. */ elrp->el_body.elmbus.elmb_size = (i * 14) + 12; elrp->el_body.elmbus.elmb_count = i + 1; /* * If time permits to do some error analysis * it can be put here. For now set these * error summary fields to -1; */ elrp->el_body.elmbus.elmb_dominant = -1; elrp->el_body.elmbus.elmb_flags = -1; elrp->el_body.elmbus.elmb_mod_err = -1; EVALID(elrp); } }}/* * Disable IPL 17 interrupts from the MBUS */ka60clrmbint(){ register struct fbic_regs *fbaddr; fbaddr = ((struct mb_node *)ka60getmbnode(cpu_fbic_addr, 0x01010108))->mb_vaddr; fbaddr->f_fbicsr &= ~FFCSR_IRQE_3;}/* * Enable IPL 17 interrupts from the MBUS */ka60setmbint(){ register struct fbic_regs *fbaddr; fbaddr = ((struct mb_node *)ka60getmbnode(cpu_fbic_addr, 0x01010108))->mb_vaddr; enafbiclog(); fbaddr->f_fbicsr |= FFCSR_IRQE_3;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -