📄 ka9000.c
字号:
int ka9000badaddr(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);}ka9000reboot() { int timeout; struct xmi_reg *nxv; /* virtual pointer to XMI node */ struct xja_regs *xja; register int i; register int xja_node;/* * Clear warm restart */ timeout = 20000000; while((mfpr(TXFCT) & TXFCT_RDY) == 0) { if(--timeout == 0) { panic("ka9000reboot: TXFCT not ready"); } } mtpr (TXFCT, TXFCT_CLEAR_WS | (boot_cpu_num << TXFCT_SPARAM_SHIFT)); timeout = 20000000; while((mfpr(TXFCT) & TXFCT_RDY) == 0) { if(--timeout == 0) { panic("ka9000reboot: TXFCT not ready"); } }/* * Clear cold restart */ timeout = 20000000; while((mfpr(TXFCT) & TXFCT_RDY) == 0) { if(--timeout == 0) { panic("ka9000reboot: TXFCT not ready"); } } mtpr (TXFCT, TXFCT_CLEAR_CS | (boot_cpu_num << TXFCT_SPARAM_SHIFT)); timeout = 20000000; while((mfpr(TXFCT) & TXFCT_RDY) == 0) { if(--timeout == 0) { panic("ka9000reboot: TXFCT not ready"); } } timeout = 20000000; while((mfpr(TXFCT) & TXFCT_RDY) == 0) { if(--timeout == 0) { panic("ka9000reboot: TXFCT not ready"); } } mtpr (TXFCT, TXFCT_REBOOT_SYSTEM); timeout = 20000000; while((mfpr(TXFCT) & TXFCT_RDY) == 0) { if(--timeout == 0) { panic("ka9000reboot: TXFCT not ready"); } } /* Execute instructions until we're halted by SPU */ for(;;);}ka9000halt() { int i; long cpucnf; cpucnf = mfpr(CPUCNF); /* Explicitly halt each non-boot CPU */ for(i = 0; i < 4; i++) { if((i != boot_cpu_num) && (cpucnf & (1 << i))) { ka9000_spu_request(TXFCT_HALT_AND_KEEP, i, 0, 1); } } /* Finally, halt ourselves... */ asm("halt");}xjainit(nxv,nxp,xminumber,xminode,xmidata)char *nxv;char *nxp;int xminumber,xminode;register struct xmidata *xmidata;{#ifdef lint nxv=nxv; nxp=nxp; xminumber=xminumber; xminode = xminode;#endif lint}ka9000stopcpu(cpu_num)int cpu_num;{ int timeout;/* * Test for valid cpu. VAX9000 supports up to 4 cpu's */ if(cpu_num < 0 || cpu_num > 3) return(0);/* * Test to see if requested cpu is configured */ if((mfpr(CPUCNF) & (1 << cpu_num)) == 0) return(0); timeout = 20000000; while((mfpr(TXFCT) & TXFCT_RDY) == 0) { if(--timeout == 0) { panic("ka9000stopcpu: TXFCT not ready"); } }/* * Halt the cpu but keep it in the list of available cpus */ mtpr (TXFCT, TXFCT_HALT_AND_KEEP | (cpu_num << TXFCT_SPARAM_SHIFT)); return(1);}ka9000startcpu(cpu_num)int cpu_num;{ int timeout;/* * Test for valid cpu. VAX9000 supports up to 4 cpu's */ if(cpu_num < 0 || cpu_num > 3) return(0);/* * Test to see if requested cpu is configured */ if((mfpr(CPUCNF) & (1 << cpu_num)) == 0) return(0);/* Get a cpudata structure */ get_cpudata(cpu_num); timeout = 20000000; while((mfpr(TXFCT) & TXFCT_RDY) == 0) { if(--timeout == 0) { panic("ka9000startcpu: TXFCT not ready"); } } if (max_vec_procs > 0) { /* allocate memory for the vpdata structure */ KM_ALLOC (( CPUDATA ( cpu_num)-> cpu_vpdata), struct vpdata *, sizeof(struct vpdata), KM_VECTOR, KM_CLEAR | KM_CONTIG); } mtpr (TXPRM, CPU_START_ADDR); /* set the starting address for the secondary cpu */ mtpr (TXFCT, TXFCT_BOOT_CPU | (cpu_num << TXFCT_SPARAM_SHIFT)); /* start it */ timeout = 20000000; while((mfpr(TXFCT) & TXFCT_RDY) == 0) { if(--timeout == 0) { panic("ka9000startcpu: TXFCT not ready"); } } /* Wait for this processor to declare itself runnable */ timeout=1500; while(timeout-->0) { DELAY(10000); /* 1/100 of sec */ /* if running then success */ if (CPUDATA(cpu_num)->cpu_state&CPU_RUN) { DELAY(1000000); return(1); } }/* If we get here, then the addition of this cpu failed... */ return(0);/* asm("halt");*/}ka9000machcheck (cmcf) caddr_t cmcf;{ register struct el_rec *elp; register struct el_mc9000frame *mcp; int cpu_num; mcp = (struct el_mc9000frame *)cmcf; /* If this is in fact an EBOX machine check, handle * it differently... */ if(mcp->mc_type == MCHK_9000_TYPE_EBOX) { ka9000eboxmcheck(cmcf); return(0); } /* This is an SPU-reported error. Find out exactly * which error occurred and deal with it appropriately. */ cpu_num = CURRENT_CPUDATA->cpu_num; if(mcp->mc_err_summ & MCHK_9K_ERR_REG_PE) { /* Register parity error. See if we can kill * the process that was running */ if(USERMODE(mcp->mc_psl) && (u.u_procp->p_pid != 1) && (cpu_num != boot_cpu_num)) { /* Yes we can. Do so & treat this as a soft * CPU error. */ swkill(u.u_procp, "Machine check: Register parity error"); if(!ka9000softerr(&cpu_softerrs[cpu_num])) { /* Too many soft errors. Disable the CPU */ ka9000discpu(mcp, cpu_num); } } else { /* Can't kill the process. Have to panic */ ka9000badmchk(mcp, "Register parity error"); } } else if(mcp->mc_err_summ & MCHK_9K_ERR_MB_ADDR_FLT) { /* This one is unrecoverable */ ka9000badmchk(mcp, "MBOX address fault"); } else if(mcp->mc_err_summ & MCHK_9K_ERR_MB_DATA_FLT) { int addr_type = CSYS; /* MBOX data fault. If the address is a kernel * address or we can't tell what kind it is, * then crash the system. */ addr_type = ka9000mckaddrtype(mcp); if((addr_type != CTEXT) && (addr_type != CDATA) && (addr_type != CSTACK) && (addr_type != CSMEM)) { ka9000badmchk(mcp, "MBOX data fault"); } else { /* If we can't gracefully kill the proc * that's currently running, then crash * the system. */ if(!ka9000addrkill(mcp, addr_type, "MBOX data fault")) { ka9000badmchk(mcp, "MBOX data fault"); } else if(!ka9000softerr(&cpu_softerrs[cpu_num])) { /* Too many soft errors. Disable the CPU */ ka9000discpu(mcp, cpu_num); } } } else if(mcp->mc_err_summ & MCHK_9K_ERR_MB_WRBK_FLT) { /* This one is unrecoverable */ ka9000badmchk(mcp, "MBOX writeback fault"); } else if(mcp->mc_err_summ & MCHK_9K_ERR_IB_PEND_GPR) { /* IBOX pending GPR write failed. * See if we can kill the process that was running */ if(USERMODE(mcp->mc_psl) && (u.u_procp->p_pid != 1) && (cpu_num != boot_cpu_num)) { /* Yes we can. Do so & treat this as a soft * CPU error. */ swkill(u.u_procp, "Machine check: IBOX pending GPR wrt failed"); if(!ka9000softerr(&cpu_softerrs[cpu_num])) { /* Too many soft errors. Disable the CPU */ ka9000discpu(mcp, cpu_num); } } else { /* Can't kill the process. Have to panic */ ka9000badmchk(mcp, "IBOX pending GPR wrt failed"); } } else if(mcp->mc_err_summ & MCHK_9K_ERR_IB_LOST_PC) { /* IBOX lost PC. * See if we can kill the process that was running */ if(USERMODE(mcp->mc_psl) && (u.u_procp->p_pid != 1) && (cpu_num != boot_cpu_num)) { /* Yes we can. Do so & treat this as a soft * CPU error. */ swkill(u.u_procp, "Machine check: IBOX lost PC"); if(!ka9000softerr(&cpu_softerrs[cpu_num])) { /* Too many soft errors. Disable the CPU */ ka9000discpu(mcp, cpu_num); } } else { /* Can't kill the process. Have to panic */ ka9000badmchk(mcp, "IBOX lost PC"); } } else if(mcp->mc_err_summ & MCHK_9K_ERR_RDS) { int addr_type = CSYS; /* Double-bit memory error. If the address is a kernel * address or we can't tell what kind it is, * then crash the system. */ addr_type = ka9000mckaddrtype(mcp); if((addr_type != CTEXT) && (addr_type != CDATA) && (addr_type != CSTACK) && (addr_type != CSMEM)) { ka9000badmchk(mcp, "Dbl-bit memory error"); } else { /* If we can't gracefully kill the proc * that's currently running, then crash * the system. */ if(!ka9000addrkill(mcp, addr_type, "Dbl-bit mem err")) { ka9000badmchk(mcp, "Dbl-bit mem err"); } else if(!ka9000softerr(&mem_softerrs)) { /* Too many soft errors. Crash the system*/ ka9000badmchk(mcp, "Too many mem errs"); } } } else if(mcp->mc_err_summ & MCHK_9K_ERR_BAD_DATA) { int addr_type = CSYS; /* Bad data. If the address is a kernel * address or we can't tell what kind it is, * then crash the system. */ addr_type = ka9000mckaddrtype(mcp); if((addr_type != CTEXT) && (addr_type != CDATA) && (addr_type != CSTACK) && (addr_type != CSMEM)) { ka9000badmchk(mcp, "Bad data"); } else { /* If we can't gracefully kill the proc * that's currently running, then crash * the system. */ if(!ka9000addrkill(mcp, addr_type, "Mchk: Bad data")) { ka9000badmchk(mcp, "Bad data"); } else if(!ka9000softerr(&mem_softerrs)) { /* Too many soft errors. Crash the system*/ ka9000badmchk(mcp, "Bad data"); } } } else if(mcp->mc_err_summ & MCHK_9K_ERR_VBOX_ABORT) { /* VBOX abort. * See if we can kill the process that was running */ if(USERMODE(mcp->mc_psl) && (u.u_procp->p_pid != 1) && (cpu_num != boot_cpu_num)) { /* Yes we can. Do so & treat this as a soft * CPU error. */ swkill(u.u_procp, "Machine check: VBOX abort"); if(!ka9000softerr(&vbox_softerrs[cpu_num]) || (mcp->mc_err_summ & MCHK_9K_ERR_SOLID)) { /* Hard error, or too many soft errors. * Disable the VBOX */ vp_remove(); } } else { /* Can't kill the process. Have to panic */ ka9000badmchk(mcp, "VBOX abort"); } } else if(mcp->mc_err_summ & MCHK_9K_ERR_VBOX_REG_PE) { /* VBOX register parity error. * See if we can kill the process that was running */ if(USERMODE(mcp->mc_psl) && (u.u_procp->p_pid != 1) && (cpu_num != boot_cpu_num)) { /* Yes we can. Do so & treat this as a soft * CPU error. */ swkill(u.u_procp, "Machine check: VBOX register parity error"); if(!ka9000softerr(&vbox_softerrs[cpu_num]) || (mcp->mc_err_summ & MCHK_9K_ERR_SOLID)) { /* Hard error, or too many soft errors. * Disable the VBOX */ vp_remove(); } } else { /* Can't kill the process. Have to panic */ ka9000badmchk(mcp, "VBOX register parity error"); } } else { /* Unknown machine check type */ ka9000badmchk(mcp, "Unknown machine check type"); } /* The machine check did not cause a panic. */ /* So, log at priority EL_PRIHIGH, not EL_PRISEVERE */ if( (elp=ealloc(sizeof(struct el_mck), EL_PRIHIGH)) != EL_FULL ) { LSUBID(elp, ELCT_MCK, ELMCKT_9000, EL_UNDEF, EL_UNDEF, EL_UNDEF, EL_UNDEF);#define ELP_ELMCK elp->el_body.elmck.elmck_frame.el9000mcf ELP_ELMCK.mc_length = mcp->mc_length; ELP_ELMCK.mc_type = mcp->mc_type; ELP_ELMCK.mc_id = mcp->mc_id; ELP_ELMCK.mc_err_summ = mcp->mc_err_summ; ELP_ELMCK.mc_sys_summ = mcp->mc_sys_summ; ELP_ELMCK.mc_vaddr = mcp->mc_vaddr; ELP_ELMCK.mc_paddr = mcp->mc_paddr; ELP_ELMCK.mc_misc_info = mcp->mc_misc_info; ELP_ELMCK.mc_pc = mcp->mc_pc; ELP_ELMCK.mc_psl = mcp->mc_psl; if(((mfpr(CPUCNF) >> 8) & 0xf) == (1 << cpu_num)) { /* VBOX present */ ELP_ELMCK.mc_vpsr = mfpr(VPSR); } else { /* VBOX absent */ ELP_ELMCK.mc_vpsr = 0; } EVALID(elp); }}/* Routine to handle an EBOX-generated machine check... */ka9000eboxmcheck(emcp)caddr_t emcp;{ register struct el_rec *elp; register struct el_mc9000eboxframe *eemcp = (struct el_mc9000eboxframe *) emcp; if( (elp=ealloc(sizeof(struct el_mck), EL_PRISEVERE)) != EL_FULL ) { LSUBID(elp, ELCT_MCK, ELMCKT_9000, EL_UNDEF, EL_UNDEF, EL_UNDEF, EL_UNDEF);#define ELP_ELMCK_E elp->el_body.elmck.elmck_frame.el9000eboxmcf ELP_ELMCK_E.mc_length = eemcp->mc_length; ELP_ELMCK_E.mc_type = eemcp->mc_type; ELP_ELMCK_E.mc_pc = eemcp->mc_pc; ELP_ELMCK_E.mc_psl = eemcp->mc_psl; EVALID(elp); } /* We should never get this! */ ka9000badmchk((struct el_mc9000eboxframe *)emcp, "EBOX machine check");}/* Disable the specified CPU */ka9000discpu(mcp, cpu_num)struct el_mc9000frame *mcp;int cpu_num;{ if(cpu_num != CURRENT_CPUDATA->cpu_num) { ka9000badmchk(mcp, "ka9000 mchk not on faulting CPU"); } /* Disable ourselves, unless we already stopped * ourselves for a machine check... */ if(CURRENT_CPUDATA->cpu_stops & IPIMSK_MCHK) { ka9000badmchk(mcp, "Multiple fatal machine checks on CPU"); } else if(cpu_num == boot_cpu_num) { /* Can't disable the boot CPU... */ ka9000badmchk(mcp, "Fatal machine check on boot CPU"); } else { printf("Machine check: Disabling cpu %d\n", cpu_num); hold_cpu(IPI_MCHK); }}/* On a MBOX or memory machine check, figure out what the memory * is being used for (text, data, stack, shared mem...) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -