⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 kn02ba.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
 */kn02ba_print_consinfo(p)struct kn02ba_consinfo_t *p;{        int simm, byte;	u_int memreg;		/*	 * If console is a graphics device,	 * force printf messages directly to screen.	 */	printstate |= PANICPRINT;		switch (p->pkt_type) {	  case KN02BA_ESRPKT:	    cprintf("\nException condition\n");	    cprintf("\tCause reg\t= 0x%x\n", p->pkt.esrp.cause);	    cprintf("\tException PC\t= 0x%x\n", p->pkt.esrp.epc);	    cprintf("\tStatus reg\t= 0x%x\n", p->pkt.esrp.status);	    cprintf("\tBad virt addr\t= 0x%x\n", p->pkt.esrp.badva);	    cprintf("\tStack ptr\t= 0x%x\n", p->pkt.esrp.sp);	    cprintf("\tSystem Support reg = 0x%x\n", p->pkt.esrp.ssr);	    cprintf("\tSystem Interrupt reg = 0x%x\n", p->pkt.esrp.sir);	    cprintf("\tSystem Interrupt Mask reg = 0x%x\n", p->pkt.esrp.sirm);	    break;	    	  case KN02BA_MEMPKT:	    memreg = p->pkt.memp.memreg;	    cprintf("\nMemory Parity Error\n");	    simm =  (memreg >> SIMMOFF) & 0xf;	    cprintf("\tSIMM (module number)\t= BANK %d, %s\n", 		    simm/2, ((simm & 0x1) ? "D16-31" : "D0-15"));	    if (((memreg >> TYPEOFF) & HARDPAR) == HARDPAR)		cprintf("\tHard error\t\n");	    else if (((memreg >> TYPEOFF) & SOFTPAR) == SOFTPAR)		cprintf("\tSoft error\t\n");	    else cprintf("\tTransient error\t\n");	    if (simm & 0x1) {		/* D16-31(high) simm: high half word */		if ((memreg >> BYTEOFF) & 0x1)		    byte = 3;		else		    byte = 2;	    } else {		/* D0-15(low) simm: low half word */		if ((memreg >> BYTEOFF) & 0x1)		    byte = 1;		else		    byte = 0;	    }	    cprintf("\tByte in error (0-3)\t= %d\n", byte);	    cprintf("\t%s bit error\n", ((memreg >> DPOFF) & 0x1) ? "Parity" : "Data");	    cprintf("\tTransient errors for this SIMM\t= %d\n", kn02ba_tcount[simm]);	    cprintf("\tSoft errors for this SIMM\t= %d\n", kn02ba_scount[simm]);	    cprintf("\tHard errors for this SIMM\t= %d\n", kn02ba_hcount[simm]);	    cprintf("\tPhysical address of error\t= 0x%x\n", p->pkt.memp.pa);	    cprintf("\tException PC\t\t\t= 0x%x\n", p->pkt.memp.epc);	    cprintf("\tVirtual address of error\t= 0x%x\n", p->pkt.memp.badva);	    break;	    	  default:	    cprintf("bad print_consinfo \n");	    break;	}}kn02ba_isolate_memerr(memerr_status)	struct tc_memerr_status *memerr_status;{        unsigned memreg;	int ep[EF_SIZE/4];	if (btop((int)memerr_status->pa) >= physmem)	    return (-1);	/* zero out these since they are not pertinent 	*/	/* for this type of error			*/	ep[EF_EPC] = 0;	ep[EF_BADVADDR] = 0;		memreg = kn02ba_isolatepar(memerr_status->pa, memerr_status->va, memerr_status->blocksize);	memerr_status->errtype = TC_MEMERR_NOERROR;	if (((memreg >> TYPEOFF) & HARDPAR) == HARDPAR)	    memerr_status->errtype = TC_MEMERR_HARD;	else if (((memreg >> TYPEOFF) & SOFTPAR) == SOFTPAR)	    memerr_status->errtype = TC_MEMERR_SOFT;	else if (((memreg >> TYPEOFF) & TRANSPAR) == TRANSPAR)	    memerr_status->errtype = TC_MEMERR_TRANS;	if (memerr_status->log == TC_LOG_MEMERR) {	    kn02ba_logmempkt(EL_PRISEVERE, ep, memreg, memerr_status->pa);	    kn02ba_consprint(KN02BA_MEMPKT, ep, memreg, memerr_status->pa, 0, 0, 0);	}}/* * Isolate a memory parity error to which SIMM is in error. * This routine is machine specific, in that it "knows" how the memory * is laid out, i.e. how to convert a physical address to a module number. * * Block faults from occuring while we isolate the parity error by using * "nofault" facility thru the bbadaddr routine. */unsignedkn02ba_isolatepar(pa, va, blocksize)	register caddr_t pa;	/* the phys addr to convert to a SIMM */		caddr_t va;		/* the virtual addr of the error */		int blocksize;		/* the size of the block error occured in */{	register int i;		/* loop index */		register int *blockaddr;/* address of the beginning of block in error */	register int *addr;	/* increment thru the block w/ parity error */	register char *baddr;	/* increment thru the word w/ parity error */	unsigned memreg;	/* collection of memory error info */	int low;		/* true if its the D0-15(low) SIMM */	int simm;		/* which simm had the error */	register int allzeros;	/* true if parity err occurs on all 0's write */	register int allones;	/* true if parity err occurs on all 1's write */	register int oneone;	/* true if parity err occurs on 1 1 write */	int dp;			/* 0 for data bit, 1 for parity bit */	int type;		/* error type: transient, soft, hard */	int byte;		/* 0 for low byte; 1 for high byte in word */	int bank;	int banksize;	int parityerr;	int blockcnt;	/* 	 * Round physical address to beginning of block	 */	blockaddr = (int *)(PHYS_TO_K1((int)pa & ~((blocksize << 2) - 1)));	addr = blockaddr;	for (blockcnt = 0; blockcnt < blocksize; blockcnt++, addr++) {		    type = 0;	    dp = 0;	    /*	     * Do badaddr probe on addr (a few times),	     * to see if it was only a transient.	     */	    parityerr = 0;	    for (i = 0; i < 4; i++) {		if (bbadaddr(addr, 4)) {		    parityerr = 1;		    break;		}	    }	    if (!parityerr) {		/* if no error, try the next word */		continue;	    }	    /*	     * Isolate the parity error to which SIMM is in error (which byte in	     * the word) and isolate the type of error: soft or hard, data bit	     * or parity bit.	     *	     * This is done by writing (& reading) each byte in the word first	     * with all 0's then with all 1's (0xff) then with one 1 (0x1).	     *	     * Use k1 address in order not to get TLBMOD exception when writing	     * shared memory space.	     */	    for (i = 0, baddr = (char *)addr; i < 4; i++, baddr += 1) {		allzeros = 0;		*baddr = 0x00;		if (bbadaddr(baddr, 1))		    allzeros = 1;		allones = 0;		*baddr = 0xff;		if (bbadaddr(baddr, 1))		    allones = 1;		oneone = 0;		*baddr = 0x1;		if (bbadaddr(baddr, 1))		    oneone = 1;		/*		 * If all 3 reads caused the error then this is the wrong		 * byte, go on to the next byte		 */		if (allzeros && allones && oneone)		    continue;		/*		 * If only one of the allones/allzeros patterns caused a		 * parity error, then we have a hard data bit stuck to		 * zero or one.		 */		if ((allzeros && !allones && !oneone) ||		    (allones && !allzeros && !oneone)) {		    type = HARDPAR;		    break;		}		/*		 * If only the "oneone" (0x1) pattern caused a parity error,		 *   then we have a parity bit stuck to zero.		 * If only the "oneone" (0x1) pattern did NOT cause a parity		 *   error then we have a parity bit stuck to one.		 */		if ((oneone && !allzeros && !allones) ||		    (allzeros && allones && !oneone)) {		    type = HARDPAR;		    dp = 1;		    break;		}		/*		 * If no parity error on all 3 patterns then we had a soft		 * parity error in one of the data bits or in the parity bit		 * of this byte.		 */		if (!allzeros && !allones && !oneone) {		    type = SOFTPAR;		    break;		}	    }	    /*	     * If i is 0 or 1, parity error is on the D0-15(low) SIMM.	     * If i is 2 or 3, parity error is on the D16-31(high) SIMM.	     * Also record high or low byte position in half-word.	     */	    switch (i) {	      case 0:		byte = 0;		low = 1;		break;	      case 1:		byte = 1;		low = 1;		break;	      case 2:		byte = 0;		low = 0;		break;	      case 3:	      default:		byte = 1;		low = 0;		break;	    }	    /* we found the bad word, now determine which simm */	    break;	}		/* if none of the words checked found an error, the error must */	/* have been a transient parity error. */	if (!parityerr) {	    unsigned int mer;	    type = TRANSPAR;	    mer = *(u_int *)(PHYS_TO_K1(KN02BA_MEM_ERR));	    mer &= LAST_BYTE_ERR_MASK;	    if (mer & 0x800) {		byte = 1;		low = 0;	    } else if (mer & 0x400) {		byte = 0;		low = 0;	    } else if (mer & 0x200) {		byte = 1;		low = 1;	    } else {		byte = 0;		low = 1;	    }	    /* clear error bits */	    *(u_int *)(PHYS_TO_K1(KN02BA_MEM_ERR)) = 0;	    baddr = (char *)blockaddr;	}	if (*((u_int *)PHYS_TO_K1(KN02BA_MEM_SIZE)) & KN02BA_16MB_MEM) 	    banksize = 16 * 1024 * 1024;	else	    banksize = 4 * 1024 * 1024;		/* There are 8 banks, numbered 0 - 7 */		bank = (int)svtophy(baddr) / banksize;		/* There are 16 simms, numbered 0 - 15 */	if (low)	    simm = (bank * 2);	else	    simm = (bank * 2) + 1;	/*	 * Increment error counts	 */	switch (type) {	  case TRANSPAR:	  default:	    kn02ba_tcount[simm]++;	    if (kn02ba_tcount[simm] > 255) {		mprintf("Transient parity error count on simm in BANK # %d, %s reached 255, reset to zero.\n", bank, (low ? "D0-15" : "D16-31"));		kn02ba_tcount[simm] = 0;	    }	    break;	  case SOFTPAR:	    kn02ba_scount[simm]++;	    break;	  case HARDPAR:	    kn02ba_hcount[simm]++;	    break;	}	memreg = MEMREGFMT(simm, type, byte, dp, kn02ba_tcount[simm], 			   kn02ba_scount[simm], kn02ba_hcount[simm]);	return(memreg);}#ifdef ERRLOG_DEBUG#define NO_TEST		0#define HARD_PAR_TEST	1#define SOFT_PAR_TEST	2#define TRANS_PAR_TEST	3#define WTO_TEST	4#define TRAP_TEST	5#define UNALIGNED_TEST	6#define RTMO_TEST	7int kn02ba_errlog; u_int dummy;kn02ba_errlog_testing(){    u_char *addr;    int	i, cnt;    switch (kn02ba_errlog) {      case NO_TEST:	break;      case HARD_PAR_TEST:	cprintf("value of MER = 0x%x\n", *(u_int *)(PHYS_TO_K1(KN02BA_MEM_ERR)));	cprintf("executing HARD_PAR_TEST (cached)\n");	/* read all of the last 4 meg trying to find 	*/	/* bad memory					*/	addr = (u_char *)(0x81c00000);	for (i = 0; i < 0x400000; i++, addr++) {	    *addr = 0x0;	    dummy = *addr;	    if (dummy != 0x0) cprintf("dummy (%d) != 0x0, addr = 0x%x\n", dummy, addr);	    *addr = 0xff;	    dummy = *addr;	    if (dummy != 0xff) cprintf("dummy (%d) != 0xff, addr = 0x%x\n", dummy, addr);	    *addr = 0x1;	    dummy = *addr;	    if (dummy != 0x1) cprintf("dummy (%d) != 0x1, addr = 0x%x\n", dummy, addr);	    *addr = 0xaa;	    dummy = *addr;	    if (dummy != 0xaa) cprintf("dummy (%d) != 0xaa, addr = 0x%x\n", dummy, addr);	    *addr = 0x55;	    dummy = *addr;	    if (dummy != 0x55) cprintf("dummy (%d) != 0x55, addr = 0x%x\n", dummy, addr);	}	cprintf("executing HARD_PAR_TEST (uncached)\n");	addr = (u_char *)(0xa1c00000);	for (i = 0; i < 0x400000; i++, addr++) {	    *addr = 0x0;	    dummy = *addr;	    if (dummy != 0x0) cprintf("dummy (%d) != 0x0, addr = 0x%x\n", dummy, addr);	    *addr = 0xff;	    dummy = *addr;	    if (dummy != 0xff) cprintf("dummy (%d) != 0xff, addr = 0x%x\n", dummy, addr);	    *addr = 0x1;	    dummy = *addr;	    if (dummy != 0x1) cprintf("dummy (%d) != 0x1, addr = 0x%x\n", dummy, addr);	    *addr = 0xaa;	    dummy = *addr;	    if (dummy != 0xaa) cprintf("dummy (%d) != 0xaa, addr = 0x%x\n", dummy, addr);	    *addr = 0x55;	    dummy = *addr;	    if (dummy != 0x55) cprintf("dummy (%d) != 0x55, addr = 0x%x\n", dummy, addr);	}	cprintf("executing HARD_PAR_TEST (addr bit)\n");	addr = (u_char *)(0xa1c00000);	cnt = 0;	while (cnt < 0x400000) {	    for (i = 0; ((i < 254) && (cnt < 0x400000)); i++, cnt++)		*addr++ = i;	}	addr = (u_char *)(0xa1c00000);        cnt = 0;	while (cnt < 0x400000) {	    for (i = 0; ((i < 254) && (cnt < 0x400000)); i++, cnt++) {		dummy = *addr++;		if (dummy != i) {		    cprintf("dummy (%x) != i (%x), addr = %x\n", dummy, i, addr);		}	    }	}	cprintf("done\n");	break;      case SOFT_PAR_TEST:	break;      case TRANS_PAR_TEST:	printf("isolatepar returns %x\n", kn02ba_isolatepar(0x010205f8, 0, 4));	break;      case WTO_TEST:	cprintf("executing WTO_TEST\n");	/* write to turbo slot 0 */	*(u_int *)(0xb0000000) = 0;	break;      case TRAP_TEST:	cprintf("executing TRAP_TEST\n");	dummy = *(u_int *) 0;	break;      case UNALIGNED_TEST:	cprintf("executing UNALIGNED_TEST\n");	dummy = *(u_int *)(0x80000002);	break;      case RTMO_TEST:	cprintf("executing RTMO_TEST\n");	dummy = *(u_int *)(0xb0000000);	break;      default:	break;    }    kn02ba_errlog = 0;    timeout(kn02ba_errlog_testing, (caddr_t) 0, 5 * hz);}#endif /* ERRLOG_DEBUG */kn02ba_conf_clk_speed(){    register volatile struct rt_clock *rt =(struct rt_clock *)rt_clock_addr;    register volatile int dummy;    register int s, counter = 0;    int save_rega, save_regb;    s = splextreme();    /* allow TOY interrupt to get to the CPU */    *(u_int *)(PHYS_TO_K1(KN02BA_SIRM_ADDR)) = TOY_INTR;    /* enable periodic interrupt */    save_rega = rt->rt_rega;    save_regb = rt->rt_regb;    rt->rt_rega = RTA_DV32K|RTA_4ms;    rt->rt_regb = RTB_DMBINARY|RTB_24HR|RTB_PIE;    /* clear any old interrupts */    dummy = rt->rt_regc;    /* wait for start */    while ((get_cause() & SR_IBIT6) == 0);    dummy = rt->rt_regc;    /* wait for finish and count */    while ((get_cause() & SR_IBIT6) == 0)	counter++;    dummy = rt->rt_regc;    rt->rt_rega = save_rega;    rt->rt_regb = save_regb;    splx(s);    return (counter);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -