📄 kn02ba.c
字号:
} else { kn02ba_logesrpkt(EL_PRISEVERE, ep, ssr, sir, sirm); kn02ba_consprint(KN02BA_ESRPKT, ep, 0, 0, ssr, sir, sirm); panic("bus timeout"); } break; case EXC_CPU: kn02ba_logesrpkt(EL_PRISEVERE, ep, ssr, sir, sirm); kn02ba_consprint(KN02BA_ESRPKT, ep, 0, 0, ssr, sir, sirm); panic("coprocessor unusable"); break; case EXC_RADE: case EXC_WADE: kn02ba_logesrpkt(EL_PRISEVERE, ep, ssr, sir, sirm); kn02ba_consprint(KN02BA_ESRPKT, ep, 0, 0, ssr, sir, sirm); panic("unaligned access"); break; default: kn02ba_logesrpkt(EL_PRISEVERE, ep, ssr, sir, sirm); kn02ba_consprint(KN02BA_ESRPKT, ep, 0, 0, ssr, sir, sirm); panic("trap"); break; } } /* * Default user-mode action is to terminate the process */ *signo = SIGBUS; return(0);}kn02ba_intr(ep, code, sr, cause)u_int *ep;u_int code, sr, cause;{ register u_int req, sir, tmp_cause; register int nintr = 1, current_ipl; extern int nstrays; u_int current_sirm = *(u_int *)PHYS_TO_K1(KN02BA_SIRM_ADDR); CURRENT_CPUDATA->cpu_inisr++; /* remove any pending intr's that are masked */ tmp_cause = cause & sr; req = ffintr(tmp_cause); switch (req) { case CR_HALT: /* loop until the halt button is released */ while (get_cause() & SR_IBIT7) ; kn02ba_halt(ep); break; case CR_FPU: splx(SPLFPU); fpuintr(ep); break; case CR_SYSTEM: sir = *(u_int *)PHYS_TO_K1(KN02BA_SIR_ADDR); /* mask out bits that we don't want */ sir &= current_sirm; if (sir & CPU_IO_TIMEOUT) { splx(SPLMEM); kn02ba_errintr(ep); } else if (sir & TOY_INTR) { splx(SPLCLOCK); hardclock(ep); } else if (sir & SLU_INTR) { splx(SPLIO); (*(tc_slot[KN02BA_SCC_INDEX].intr))(); } else if (sir & LANCE_INTR) { splx(SPLIO); (*(tc_slot[KN02BA_LN_INDEX].intr))(); } else if (sir & SCSI_INTR) { splx(SPLIO); (*(tc_slot[KN02BA_SCSI_INDEX].intr))(); } else { nintr--; nstrays++; /* rpbfix: downgrade to a printf after debugging */ cprintf("Stray interrupt from System Interrupt Register"); } break; case CR_OPTION_2: splx(SPLIO); (*(tc_slot[2].intr))(tc_slot[2].unit); break; case CR_OPTION_1: splx(SPLIO); (*(tc_slot[1].intr))(tc_slot[1].unit); break; case CR_OPTION_0: splx(SPLIO); (*(tc_slot[0].intr))(tc_slot[0].unit); break; case CR_SOFTNET: splx(SPLNET); softnet(ep); break; case CR_SOFTCLOCK: splx(SPLSOFTC); softclock(ep); break; case CR_NONE: /* rpbfix: downgrade to printf later */ nintr--; nstrays++; /* panic("no interrupt pending");*/ cprintf("no interrupt pending, cause = %x, sr = %x\n", cause, sr); break; } CURRENT_CPUDATA->cpu_intr += nintr; CURRENT_CPUDATA->cpu_inisr--;}kn02ba_getspl(){ return (ipllevel);}/* On 3min, the value returned by getspl is the actual ipllevel */kn02ba_whatspl(ipl)u_int ipl;{ return (ipl);}kn02ba_errintr(ep) register u_int *ep; /* exception frame ptr */{ register unsigned cpu_addr_err; register unsigned ssr; register unsigned sir; register unsigned sirm; struct kn02ba_consinfo_t kn02ba_consinfo, *p; ssr = *(u_int *)(PHYS_TO_K1(KN02BA_SSR_ADDR)); sir = *(u_int *)(PHYS_TO_K1(KN02BA_SIR_ADDR)); sirm = *(u_int *)(PHYS_TO_K1(KN02BA_SIRM_ADDR)); cpu_addr_err = *(u_int *)PHYS_TO_K1(KN02BA_ADDR_ERR); ep[EF_BADVADDR] = cpu_addr_err; /* * if we are still processing an previous interrupt * then simply crash. we don't queue these interrupts. */ if (CURRENT_CPUDATA->cpu_wto_event) { kn02ba_logesrpkt(EL_PRISEVERE, ep, ssr, sir, sirm); kn02ba_consprint(KN02BA_ESRPKT, ep, 0, 0, ssr, sir, sirm); *(u_int *)PHYS_TO_K1(KN02BA_INTR_REG) = 0; wbflush(); panic("CPU write timeout"); } else { /* * capture error information in kn02consinfo. * softnet() interrupt will print this info * if panicing on the console. */ p = &kn02ba_consinfo; /* * capture log information in kn02log_errinfo. * softnet() interrupt will log this info * if panicing in the error log buffer. */ p->pkt_type = KN02BA_ESRPKT; p->pkt.esrp.cause = ep[EF_CAUSE]; p->pkt.esrp.epc = ep[EF_EPC]; p->pkt.esrp.status = ep[EF_SR]; p->pkt.esrp.badva = ep[EF_BADVADDR]; p->pkt.esrp.sp = ep[EF_SP]; p->pkt.esrp.ssr = ssr; p->pkt.esrp.sir = sir; p->pkt.esrp.sirm = sirm; CURRENT_CPUDATA->cpu_consinfo = (char *) &kn02ba_consinfo; CURRENT_CPUDATA->cpu_log_errinfo = (char *) &kn02ba_consinfo; CURRENT_CPUDATA->cpu_wto_pfn = btop(cpu_addr_err); CURRENT_CPUDATA->cpu_wto_event = 1; *(u_int *)PHYS_TO_K1(KN02BA_INTR_REG) = 0; wbflush(); setsoftnet(); }}/* * * Tested from 5 seconds down to 4,000 usecs (4 mSec clock accuracy). * */kn02ba_delay(n) int n;{ register int N = kn02ba_delay_mult*(n); while (--N > 0); return(0);}kn02ba_stray(){ /* rpbfix: downgrade to printf */ panic("Received stray interrupt");}halt_cnt = 0;kn02ba_halt(ep)u_int *ep;{ /* print out value of PC, SP, and EP with labels */ rex_printf("\nPC:\t0x%x\nSP:\t0x%x\nEP:\t0x%x\n\n", ep[EF_EPC], ep[EF_SP], ep); rex_halt(0,0);}kn02ba_enable_option(index) register int index;{ register int i; switch (index) { case KN02BA_SCC_INDEX: for (i = 0; i < SPLIO; i++) kn02ba_sim[i] |= (SLU_INTR); break; case KN02BA_LN_INDEX: for (i = 0; i < SPLIO; i++) kn02ba_sim[i] |= (LANCE_INTR); break; case KN02BA_SCSI_INDEX: /* rpbfix: reenable when scsi is really turned on */ for (i = 0; i < SPLIO; i++) kn02ba_sim[i] |= (SCSI_INTR); break; case TC_OPTION_SLOT_0: for (i = 0; i < SPLIO; i++) splm[i] |= SR_IBIT3; sr_usermask |= SR_IBIT3; break; case TC_OPTION_SLOT_1: for (i = 0; i < SPLIO; i++) splm[i] |= SR_IBIT4; sr_usermask |= SR_IBIT4; break; case TC_OPTION_SLOT_2: for (i = 0; i < SPLIO; i++) splm[i] |= SR_IBIT5; sr_usermask |= SR_IBIT5; break; default: /* rpbfix: downgrade to printf */ panic("Enable_option call to non existent slot"); break; } /* load the registers with the new values */ splx(ipllevel);}kn02ba_disable_option(index) register int index;{ register int i; switch (index) { case KN02BA_SCC_INDEX: for (i = 0; i < SPLIO; i++) kn02ba_sim[i] &= ~(SLU_INTR); break; case KN02BA_LN_INDEX: for (i = 0; i < SPLIO; i++) kn02ba_sim[i] &= ~(LANCE_INTR); break; case KN02BA_SCSI_INDEX: for (i = 0; i < SPLIO; i++) kn02ba_sim[i] &= ~(SCSI_INTR); break; case TC_OPTION_SLOT_0: for (i = 0; i < SPLIO; i++) splm[i] &= ~(SR_IBIT3); sr_usermask &= ~(SR_IBIT3); break; case TC_OPTION_SLOT_1: for (i = 0; i < SPLIO; i++) splm[i] &= ~(SR_IBIT4); sr_usermask &= ~(SR_IBIT4); break; case TC_OPTION_SLOT_2: for (i = 0; i < SPLIO; i++) splm[i] &= ~(SR_IBIT5); sr_usermask &= ~(SR_IBIT5); break; default: /* rpbfix: downgrade to printf */ panic("disable_option call to non existent slot"); break; } /* load the registers with the new values */ splx(ipllevel);}kn02ba_clear_errors(){}#define KN02BA_LOG_ESRPKT(elrp, cause,epc,sr,badva,sp,ssr,sir,sirm) \ elrp->el_body.elesr.elesr.el_esrkn02ba.esr_cause = cause; \ elrp->el_body.elesr.elesr.el_esrkn02ba.esr_epc = epc; \ elrp->el_body.elesr.elesr.el_esrkn02ba.esr_status = sr; \ elrp->el_body.elesr.elesr.el_esrkn02ba.esr_badva = badva; \ elrp->el_body.elesr.elesr.el_esrkn02ba.esr_sp = sp; \ elrp->el_body.elesr.elesr.el_esrkn02ba.esr_ssr = ssr; \ elrp->el_body.elesr.elesr.el_esrkn02ba.esr_sir = sir; \ elrp->el_body.elesr.elesr.el_esrkn02ba.esr_sirm = sirm; \/* * Log Error & Status Registers to the error log buffer */kn02ba_logesrpkt(priority, ep, ssr, sir, sirm) int priority; /* for pkt priority */ register u_int *ep; /* exception frame ptr */ u_int ssr; u_int sir; u_int sirm;{ struct el_rec *elrp; elrp = ealloc(sizeof(struct el_esr), priority); if (elrp != NULL) { LSUBID(elrp,ELCT_ESR,ELESR_KN02BA,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF); KN02BA_LOG_ESRPKT(elrp, ep[EF_CAUSE], ep[EF_EPC], ep[EF_SR], ep[EF_BADVADDR], ep[EF_SP], ssr, sir, sirm); EVALID(elrp); }}/* * Log a memory error packet, so uerf can find it as a main memory error. */kn02ba_logmempkt(priority, ep, memreg, pa) int priority; /* pkt priority: panic: severe; else: high */ register u_int *ep; /* exception frame ptr */ unsigned memreg; /* assorted parity error info */ int pa; /* physical addr where memory err occured */{ struct el_rec *elrp; register struct el_mem *mrp; elrp = ealloc(EL_MEMSIZE, priority); if (elrp != NULL) { LSUBID(elrp,ELCT_MEM,EL_UNDEF,ELMCNTR_KN02BA,EL_UNDEF,EL_UNDEF,EL_UNDEF); mrp = &elrp->el_body.elmem; mrp->elmem_cnt = 1; mrp->elmemerr.cntl = 1; mrp->elmemerr.type = ELMETYP_PAR; mrp->elmemerr.numerr = 1; mrp->elmemerr.regs[0] = memreg; mrp->elmemerr.regs[1] = pa; mrp->elmemerr.regs[2] = ep[EF_EPC];; mrp->elmemerr.regs[3] = ep[EF_BADVADDR];; EVALID(elrp); }}/* * Logs error information to the error log buffer. * Exported through the cpu switch. */kn02ba_log_errinfo(p)struct kn02ba_consinfo_t *p;{ struct el_rec *elrp; struct kn02ba_consinfo_esr_t *esrp; switch (p->pkt_type) { case KN02BA_ESRPKT: esrp = &(p->pkt.esrp); elrp = ealloc(sizeof(struct el_esr), EL_PRISEVERE); if (elrp != NULL) { LSUBID(elrp,ELCT_ESR,ELESR_KN02BA,EL_UNDEF,EL_UNDEF,EL_UNDEF,EL_UNDEF); KN02BA_LOG_ESRPKT(elrp, esrp->cause, esrp->epc, esrp->status, esrp->badva, esrp->sp, esrp->ssr, esrp->sir, esrp->sirm); EVALID(elrp); } break; default: cprintf("bad pkt type\n"); return; }}/* * Print error packet to the console. * This is only done when we are about to panic on the error. * It calls kn02_print_consinfo to actually print the information. * */kn02ba_consprint(pkt, ep, memreg, pa, ssr, sir, sirm) int pkt; /* error pkt: Error & Stat Regs / memory pkt */ register u_int *ep; /* exception frame ptr */ unsigned memreg; /* For MEMPKT: assorted parity error info */ unsigned pa; /* For MEMPKT: physical addr of error */ unsigned ssr; unsigned sir; unsigned sirm;{ register int i; struct kn02ba_consinfo_t p; p.pkt_type = pkt; switch (pkt) { case KN02BA_ESRPKT: p.pkt.esrp.cause = ep[EF_CAUSE]; p.pkt.esrp.epc = ep[EF_EPC]; p.pkt.esrp.status = ep[EF_SR]; p.pkt.esrp.badva = ep[EF_BADVADDR]; p.pkt.esrp.sp = ep[EF_SP]; p.pkt.esrp.ssr = ssr; p.pkt.esrp.sir = sir; p.pkt.esrp.sirm = sirm; break; case KN02BA_MEMPKT: p.pkt.memp.epc = ep[EF_EPC]; p.pkt.memp.badva = ep[EF_BADVADDR]; p.pkt.memp.memreg = memreg; p.pkt.memp.pa = pa; break; default: cprintf("bad consprint\n"); return; } kn02ba_print_consinfo(&p); }/* * This routine is similar to kn02consprint(). * This is exported through the cpusw structure. *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -