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

📄 kn02ba.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic char *sccsid = "@(#)kn02ba.c	4.8      (ULTRIX)  3/7/91";#endif lint/************************************************************************ *									* *			Copyright (c) 1989 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//* * Modification History: * * 7-Mar-91	Randall Brown *	Fixed a bug in isolatepar().  Print out more information about *	which CPU card is in the system. * * 7-Mar-91	Jaw *	3min spl optimization. * * 21-Jan-91	Randall Brown  *	Modified kn02ba_isolate_memerr() to use tc_memerr_status struct. *	Modified kn02ba_isolate_par() to take the blocksize as *	a parameter. * * 06-Dec-90	Randall Brown *	Added isolate_memerr() routine for logging of memory errors *	that occur during I/O. * * 15-Oct-90	Randall Brown *	Added error handling code. * * 06-Sep-90 	Randall Brown  *	Changed slot_order to config_order. * * 23-Feb-90	Randall Brown *	Created file for support of 3MIN (DS5000_100). * */#include "../h/param.h"#include "../h/systm.h"#include "../h/types.h"#include "../h/cpudata.h"#include "../machine/cpu.h"#include "../h/user.h"#include "../h/proc.h"#include "../h/vm.h"#include "../h/errlog.h"#include "../h/cmap.h"#include "../machine/pte.h"#include "../../machine/common/cpuconf.h"#include "../io/tc/tc.h"#include "../machine/reg.h"#include "../machine/kn02ba.h"#include "../machine/mc146818clock.h"extern 	softclock(), softnet(), hardclock(), fpuintr();int	kn02ba_stray(), kn02ba_sysintr(), kn02ba_halt();int	kn02ba_enable_option(), kn02ba_disable_option();int	kn02ba_clear_errors(), kn02ba_isolate_memerr();extern u_int printstate;	/* how to print to the console */extern char *rt_clock_addr;	/* addr of the mc146818clock chip */extern struct timeval time;	/* the system time */extern int hz;extern int tick;extern int tickadj;extern int fixtick;		/* set to the number of microsec's that the				   clock looses per second *//* The SR reg masks for splxxx usage */int kn02ba_splm[SPLMSIZE] = {	KN02BA_SR_IMASK0,		/* 0 SPLNONE			*/	KN02BA_SR_IMASK1,		/* 1 SPLSOFTC			*/	KN02BA_SR_IMASK2,		/* 2 SPLNET			*/	0,				/* 3 NOT_USED 			*/	0,				/* 4 NOT_USED 			*/	KN02BA_SR_IMASK5,		/* 5 SPLBIO, SPLIMP, SPLTTY	*/	KN02BA_SR_IMASK6,		/* 6 SPLCLOCK			*/	KN02BA_SR_IMASK7,		/* 7 SPLMEM			*/	KN02BA_SR_IMASK8,		/* 8 SPLFPU			*/};/* The mask values for the system interrup mask */int kn02ba_sim[SPLMSIZE] = {	SPL0_MASK,			/* 0 SPLNONE			*/	SPL1_MASK,			/* 1 SPLSOFTC			*/	SPL2_MASK,			/* 2 SPLNET			*/	0,				/* 3 NOT_USED 			*/	0,				/* 4 NOT_USED 			*/	SPLIO_MASK,			/* 5 SPLBIO, SPLIMP, SPLTTY	*/	SPLCLOCK_MASK,			/* 6 SPLCLOCK			*/	SPLMEM_MASK,			/* 7 SPLMEM			*/	SPLFPU_MASK,			/* 8 SPLFPU			*/};u_int kn02ba_slotaddr[TC_IOSLOTS] = {KN02BA_SL_0_ADDR, KN02BA_SL_1_ADDR,	KN02BA_SL_2_ADDR, KN02BA_SL_3_ADDR, KN02BA_SL_4_ADDR,	KN02BA_SL_5_ADDR, KN02BA_SL_6_ADDR, KN02BA_SL_7_ADDR};/* * Program the order in which to probe the IO slots on the system. * This determines the order in which we assign unit numbers to like devices. * It also determines how many slots (and what slot numbers) there are to probe. * Terminate the list with a -1. * Note: this agrees with the console's idea of unit numbers */int kn02ba_config_order [] = { 3, 4, 5, 0, 1, 2, -1 };/* ipllevel describes the current interrupt level the processor is *//* running at.  The values that ipllevel can be are SPLNONE -> SPLEXTREME. *//* These values are defined in cpu.h */int ipllevel = SPLEXTREME;int clk_counter;int kn02ba_transintvl = KN02BA_TRANSINTVL;/* global var so we can change it */int kn02ba_translog = 1;		/* is trans logging currently enabled */struct trans_errcnt kn02ba_trans_errcnt = { 0, 0 };int kn02ba_tcount[MAXSIMM];		/* # of transient parity errs per simm*/int kn02ba_scount[MAXSIMM];		/* # of soft errs on each simm */int kn02ba_hcount[MAXSIMM];		/* # of hard errs on each simm */int kn02ba_pswarn;			/* set true if we had a ps-warning */int kn02ba_model_number;/* Initial value is worst case, real value is determined in kn02ba_init() */int kn02ba_delay_mult = 25; int kn02ba_psintvl = (60 * 1);	/* time delta to check pswarn bit */                                /* global var so we can change it */unsigned kn02ba_isolatepar();int kn02ba_transenable();int kn02ba_pscheck();caddr_t vatophys();kn02ba_init(){        int i;	extern int c0vec_tblsize;	extern int (*c0vec_tbl[])();	extern int splm[];	extern struct cpusw *cpup;	extern u_int sr_usermask;	/*	 * Initialize the interrupt dispatch table c0vec_tbl.	 * Initialize the spl table for the system we are running on.	 * Initialize the interrupt masks for the system we are running on.	 * This must be done very early on at boot time and must	 * be done before any interrupt is allowed.	 */	bcopy(kn02ba_splm, splm, (SPLMSIZE) * sizeof(int));	/* Initialize the spl dispatch table and the intr dispatch routine */	spl_init();	/* disable all DMA's, but don't reset the chips */	*(u_int *)(PHYS_TO_K1(KN02BA_SSR_ADDR)) = 0xf00;/* rpbfix: do we want to enable halt interrupt at this point */	splextreme();	/*	 * Set up the system specific value for "hz", the number of clock	 * interrupts per second; and corresponding tick and tickadj values.	 */	hz = cpup->HZ;	tick = 1000000 / hz;	tickadj = 240000 / (60 * hz);	fixtick = 1000000 - (tick * hz);	/*	 * Assign the rt_clock_addr for this processor	 */	rt_clock_addr = (char *)PHYS_TO_K1(KN02BA_CLOCK_ADDR);	clk_counter = kn02ba_conf_clk_speed();	if (clk_counter < 8775) {	    kn02ba_model_number = 120;	    kn02ba_delay_mult = 11;	} else if (clk_counter < 11311) {	    kn02ba_model_number = 125;	    kn02ba_delay_mult = 13;	} else if (clk_counter < 14000) {	    kn02ba_model_number = 133;	    kn02ba_delay_mult = 19;	} else {	    kn02ba_model_number = 0;	    kn02ba_delay_mult = 25;	}	/*	 *	 */	sr_usermask = (KN02BA_SR_IMASK0 | SR_IEP | SR_KUP );	sr_usermask &= ~(SR_IEC);	/* Initialize the TURBOchannel */	tc_init();	/* Fill in the TURBOchannel slot addresses */	for (i = 0; i < TC_IOSLOTS; i++)	    tc_slotaddr[i] = kn02ba_slotaddr[i];	/* Fill in the TURBOchannel switch table */	tc_sw.isolate_memerr = kn02ba_isolate_memerr;	tc_sw.enable_option = kn02ba_enable_option;	tc_sw.disable_option = kn02ba_disable_option;	tc_sw.clear_errors = kn02ba_clear_errors;	tc_sw.config_order = kn02ba_config_order;	/*	 * Fixed 3min IO devices	 */	strcpy(tc_slot[KN02BA_SCSI_INDEX].devname,"asc");	strcpy(tc_slot[KN02BA_SCSI_INDEX].modulename, "PMAZ-BA ");	tc_slot[KN02BA_SCSI_INDEX].slot = 3;	tc_slot[KN02BA_SCSI_INDEX].module_width = 1;	tc_slot[KN02BA_SCSI_INDEX].physaddr = KN02BA_SCSI_ADDR;	tc_slot[KN02BA_SCSI_INDEX].intr_b4_probe = 0;	tc_slot[KN02BA_SCSI_INDEX].intr_aft_attach = 1;	tc_slot[KN02BA_SCSI_INDEX].adpt_config = 0;	strcpy(tc_slot[KN02BA_LN_INDEX].devname,"ln");	strcpy(tc_slot[KN02BA_LN_INDEX].modulename, "PMAD-BA ");	tc_slot[KN02BA_LN_INDEX].slot = 3;	tc_slot[KN02BA_LN_INDEX].module_width = 1;	tc_slot[KN02BA_LN_INDEX].physaddr = KN02BA_LN_ADDR;	tc_slot[KN02BA_LN_INDEX].intr_b4_probe = 0;	tc_slot[KN02BA_LN_INDEX].intr_aft_attach = 1;	tc_slot[KN02BA_LN_INDEX].adpt_config = 0;	strcpy(tc_slot[KN02BA_SCC_INDEX].devname,"scc");	tc_slot[KN02BA_SCC_INDEX].slot = 3;	tc_slot[KN02BA_SCC_INDEX].module_width = 1;	tc_slot[KN02BA_SCC_INDEX].physaddr = KN02BA_SCC_ADDR;	tc_slot[KN02BA_SCC_INDEX].intr_b4_probe = 0;	tc_slot[KN02BA_SCC_INDEX].intr_aft_attach = 1;	tc_slot[KN02BA_SCC_INDEX].adpt_config = 0;	*(u_int *)PHYS_TO_K1(KN02BA_INTR_REG) = 0;/* rpbfix: these should go into their respective drivers */	*(u_int *)(0xbc040160) = 0x3;	*(u_int *)(0xbc040170) = 0xe;	*(u_int *)(0xbc040180) = 0x14;	*(u_int *)(0xbc040190) = 0x16;	return (0);}kn02ba_conf(){        extern int cold;	extern u_int cpu_systype;	extern int icache_size, dcache_size;#ifdef ERRLOG_DEBUG	int kn02ba_errlog_testing();#endif		cold = 1;		/*	 * Initialize PROM environment entries.	 */	hwconf_init();		/* 	 * Report what system we are on	 */	if (kn02ba_model_number != 0)	    printf("DECstation 5000 Model %d - system rev %d\n", 		   kn02ba_model_number,  (GETHRDREV(cpu_systype)));	else	    printf("DECstation 5000 Model 100 Series, Unknown Clock Speed\n");	printf("%dKb Instruction Cache, %dKb Data Cache\n", 	       icache_size/1024, dcache_size/1024);	coproc_find();		/* Turn off all interrupts in the SIRM */	*(u_int *)PHYS_TO_K1(KN02BA_SIRM_ADDR) = 0;		/*	 * Probe the TURBOchannel and find all devices	 */	splextreme();	tc_find();		timeout (kn02ba_pscheck, (caddr_t) 0, kn02ba_psintvl * hz);	timeout (kn02ba_transenable, (caddr_t) 0, kn02ba_transintvl * hz);#ifdef ERRLOG_DEBUG	timeout (kn02ba_errlog_testing, (caddr_t) 0, 5 * hz);#endif	cold = 0;	splnone();	return (0);	/* tell configure() we have configured */}/* * Check Power Supply over-heat Warning. * If its overheating, warn to shut down the system. * If its gone from overheat to OK, cancel the warning. */kn02ba_pscheck(){	register u_int sir;		/* a copy of the real csr */		sir = *(u_int *)PHYS_TO_K1(KN02BA_SIR_ADDR);		if (sir & PSWARN) {	    printf("System Overheating - suggest immediate shutdown and power-off\n");	    kn02ba_pswarn = 1;	} else {	    if (kn02ba_pswarn) {		printf("System OK - cancel overheat shutdown\n");		kn02ba_pswarn = 0;	    }	}	timeout (kn02ba_pscheck, (caddr_t) 0, kn02ba_psintvl * hz);}/* * Enable transient parity memory error logging */kn02ba_transenable(){	kn02ba_translog = 1;	timeout (kn02ba_transenable, (caddr_t) 0, kn02ba_transintvl * hz);}/* * Routine to handle trap errors: user-mode ibe & dbe, & all kernel mode traps. * We try to recover from user-mode errors and panic on kernel mode errors. */kn02ba_trap_error(ep, code, sr, cause, signo)	register u_int *ep;		/* exception frame ptr */	register u_int code;		/* trap code (trap type) */	u_int sr, cause;		/* status and cause regs */	int *signo;			/* set if we want to kill process */{	caddr_t pa;			/* the physical addr of the error */		int epc;			/* the EPC of the error */		unsigned memreg;		/* memory parity error info */	int vaddr;			/* virt addr of error */	register struct proc *p;	/* ptr to current proc struct */	long currtime;			/* current time value */	unsigned ssr;	unsigned sir;	unsigned sirm;		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));		p = u.u_procp;	if (USERMODE(sr)) {	    /*	     * If address of bus error is in physical memory, then its	     * a parity memory error.  Gather additional info in "memreg",	     * for the error log & to determine how to recover.	     * If its a transient error then continue the user process.	     * If its a hard or soft parity error:	     *    a) on a private process page, terminate the process	     *	 (by setting signo = SIGBUS)	     *    b) on a shared page, crash the system.	     * TBD: on a non-modified page, re-read the page (page fault),	     *	and continue the process.	     * TBD: on a shared page terminate all proc's sharing the page,	     *	instead of crash system.	     * TBD: on hard errors map out the page.	     */	    pa = vatophys(ep[EF_BADVADDR]);	    if ( (int)pa != -1 && (btop((int)pa) < physmem) ) {		memreg = kn02ba_isolatepar(pa, ep[EF_BADVADDR], 4);		/*		 * If we get 3 or more in 1 second then disable logging		 * them for 15 minutes.  The variable "kn02ba_translog"		 * is set by the kn02ba_transenable routine.		 */		if (((memreg >> TYPEOFF) & TRANSPAR) == TRANSPAR) {		    if (kn02ba_translog) {			currtime = time.tv_sec;			if (currtime == kn02ba_trans_errcnt.trans_prev) {			    kn02ba_translog = 0;			    mprintf("High rate of transient parity memory errors, logging disabled for 15 minutes\n");			    kn02ba_trans_errcnt.trans_last = 0;			    currtime = 0;			}			kn02ba_logmempkt(EL_PRIHIGH, ep, memreg, pa);			kn02ba_trans_errcnt.trans_prev = kn02ba_trans_errcnt.trans_last;			kn02ba_trans_errcnt.trans_last = currtime;		    }		    return(0);		}				if (SHAREDPG(pa)) {		    kn02ba_logmempkt(EL_PRISEVERE, ep, memreg, pa);		    kn02ba_consprint(KN02BA_MEMPKT, ep, memreg, pa, 0, 0, 0);		    panic("memory parity error in shared page");		} else {		    kn02ba_logmempkt(EL_PRIHIGH, ep, memreg, pa);		    printf("pid %d (%s) was killed on memory parity error\n",			   p->p_pid, u.u_comm);		    uprintf("pid %d (%s) was killed on memory parity error\n",			    p->p_pid, u.u_comm);		}	    } else {		uprintf("pid %d (%s) was killed on bus error\n",			p->p_pid, u.u_comm);	    }	} else {	    /*	     * Kernel mode errors.	     * They all panic, its just a matter of what we log	     * and what panic message we issue.	     */	    switch (code) {			      case EXC_DBE:	      case EXC_IBE:		/*		 * Figure out if its a memory parity error		 *     or a read bus timeout error		 */		pa = vatophys(ep[EF_BADVADDR]);		if ( (int)pa != -1 && (btop((int)pa) < physmem) ) {		    /*		     * Note that we must save anything "interesting"		     * from the exception frame, since isolatepar()		     * may cause additional bus errors which will		     * stomp on the exception frame in locore.		     */		    vaddr = ep[EF_BADVADDR];		    epc = ep[EF_EPC];		    memreg = kn02ba_isolatepar(pa, vaddr, 4);		    ep[EF_BADVADDR] = vaddr;		    ep[EF_EPC] = epc;		    kn02ba_logmempkt(EL_PRISEVERE, ep, memreg, pa);		    kn02ba_consprint(KN02BA_MEMPKT, ep, memreg, pa, 0, 0, 0);		    panic("memory parity error in kernel mode");

⌨️ 快捷键说明

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