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

📄 kn01.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef lintstatic char *sccsid = "@(#)kn01.c	4.5      (ULTRIX)  1/21/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.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   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: kn01.c * * 21-Jan-91	Randall Brown *	Modified kn01conf() when probing for the framebuffer device. *	The framebuffer address space always responds to a BADADDR(), *	therefore the memory needs to be written and then read to *	determine if there is a framebuffer present. * * 01-Nov-90	Donald Dutile *	Modified isolatepar() to use kseg1 addresses when writing *	parity test pattern(s) to suspected bad memory/parity location. *	Kseg1 addr used to prevent TLB MOD exception when page being *	written to is shared memory (not write enabled in TLB entry).  *	Using kseg1 works since main memory < 512MB. * * 17-Aug-90	Randall Brown *	Changed call to ib_config_dev() to configure "fb" device instead  *	of "pm" device.  * * 30-Apr-90	Randall Brown *	Added call to spl_init() to intialize spl function pointers and *      the intr() function pointer. * * 29-Mar-90 -- gmm *	Removed splhigh() and splx() from kn01memintr(). The routine gets *	entered at splmem() anyway. * * 02-Dec-89 -- afd *	Set fixtick to the number of microsec's that the clock looses per *	second.  This is used in hardclock() to fix the time. * *	Fix a few bugs in parity error handling. * * 13-Oct-89    gmm *	SMP changes - use nofault as a per cpu variable (in cpudata) * * 22-Sept-89   jls *      replaced the direct call to siiprobe will a call to ib_config_cont * * 21-Sept-89	burns (merge from ISIS pool) *    12-sep-89 afd *	Block network interrupts around lnprobe to avoid a race condition *	while we are switching network interrupts from kn01lnstray to netintr.  * *	Assign clock address in init routine (since 3max shares same clock *	routines but at a different address). * *	Call cnprobe with the virt address of the dc7085 chip.  Again, 3max *	shares the same driver but at a different address. * *    14-June-89	afd *	Add kn01init routine for splm, intr_vectors, iplmask and hz setup. *	Handle Lance "stray" interrupts that occur before lnprobe is done. *	(It is a pmax console firmware bug that allows early lance interrupts) * *    27-Apr-89	afd *	Change startup msg from "DECStation 3100" to "KN01 processor". * *    18-July-89 afd *	Handle Lance "stray" interrupts that occur before lnprobe is done. *	(It is a pmax console firmware bug that allows early lance interrupts) * * 14-Jun-89	darrell *	Added kn01init() -- called from startup(). * * 27-Apr-89	afd *	Change startup msg from "DECStation 3100" to "KN01 processor". * * 07-Apr-89	afd *	Created this file which contains routines specific to PMAX *	systems (KN01).  Much of this code came from autoconf.c & trap.c. */#include "../machine/pte.h"#include "../machine/cpu.h"#include "../h/param.h"#include "../h/systm.h"#include "../h/map.h"#include "../h/buf.h"#include "../h/dk.h"#include "../h/user.h"			/* gets time.h and debug.h too */#include "../h/proc.h"#include "../h/vm.h"#include "../h/conf.h"#include "../h/errlog.h"#include "../h/cmap.h"#include "../h/cpudata.h"#include "../machine/fpu.h"#include "../machine/hwconf.h"#include "../machine/reg.h"#include "../machine/mc146818clock.h"#include "../machine/entrypt.h"#include "../../machine/common/cpuconf.h"#define	KN01LANCE_ADDR 0x18000000	/* physical addr of lance registers */#define KN01SII_ADDR   0x1a000000       /* physical addr of sii registers */#define	KN01CLOCK_ADDR 0x1d000000		/* phys addr of clock chip */#define	KN01DC_ADDR 0x1c000000			/* phys addr of dc7085 (dz) */#define KN01FRAME_BUF_ADDR 0x0fc00000		/* phys addr of frame buffer */#define ESRPKT 1#define MEMPKT 2/* * These defines, macros, and variables are for memory parity errors. * Format of "memreg" for logging memory parity errors. */#define SIMMOFF 28#define TYPEOFF 26#define BYTEOFF 25#define DPOFF 24#define TCOUNTOFF 16#define SCOUNTOFF 8#define HCOUNTOFF 0#define MEMREGFMT(simm, type, byte, dp, tcount, scount, hcount) \(simm << SIMMOFF | type << TYPEOFF | byte << BYTEOFF | dp << DPOFF | \tcount << TCOUNTOFF | scount << SCOUNTOFF | hcount << HCOUNTOFF)#define TRANSINTVL (60*15)	/* time delta to enable parity log - 15 mins */int kn01transintvl = TRANSINTVL;/* global var so we can change it */int kn01translog = 1;		/* is trans logging currently enabled */struct trans_errcnt {             /* trans parity errors */        long   trans_last;	/* time of most recent trans err */        long   trans_prev;	/* time of previous trans err */} trans_errcnt = { 0, 0 };#define TRANSPAR 0x1#define SOFTPAR 0x2#define HARDPAR 0x3#define MAXSIMM 16int tcount[MAXSIMM];			/* # of transient parity errs per simm*/int scount[MAXSIMM];			/* # of soft errs on each simm */int hcount[MAXSIMM];			/* # of hard errs on each simm */int parityerr = 0;			/* flag for parity err isolation */caddr_t vatophys();			/* typedef of functions */unsigned isolatepar();int kn01transenable();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 *//* * Interrupt handlers for the 6 hardware interrupts and 2 software * interrupts for PMAX. */extern softclock(),softnet(),biointr(),netintr(),Xdcintr0(),	hardclock(), fpuintr(),memintr();kn01lnstray();/* The routines that correspond to each of the 8 interrupt lines */int (*kn01intr_vec[IPLSIZE])() = {	softclock,		/* softint 1	*/	softnet,		/* softint 2	*/	biointr,		/* hardint 1	*/	kn01lnstray,		/* hardint 2	*/	Xdcintr0,	        /* hardint 3	*/	hardclock,		/* hardint 4	*/	memintr,		/* hardint 5	*/	fpuintr			/* hardint 6	*/};/* * The masks to use to look at each of the 8 interrupt lines. * * Due to the different priorities of TTY, BIO and IMP on PMAX from * the norm all are effectivly wired into the same level. */int kn01iplmask[IPLSIZE] = {	SR_IMASK1|SR_IEC,	SR_IMASK2|SR_IEC,	SR_IMASK5|SR_IEC,	/* wire BIO, IMP and TTY to same level */	SR_IMASK5|SR_IEC,	/* wire BIO, IMP and TTY to same level */	SR_IMASK5|SR_IEC,	/* wire BIO, IMP and TTY to same level */	SR_IMASK6|SR_IEC,	SR_IMASK7|SR_IEC,	SR_IMASK8|SR_IEC};/* * The SR reg masks for splxxx usage. See the defines in cpu.h. */int kn01splm[SPLMSIZE] = {	SR_IEC | SR_IMASK0,		/* 0 SPLNONE			*/	SR_IEC | SR_IMASK1,		/* 1 SPLSOFTC			*/	SR_IEC | SR_IMASK2,		/* 2 SPLNET			*/	0,				/* 3 NOT_USED 			*/	0,				/* 4 NOT_USED 			*/	SR_IEC | SR_IMASK5,		/* 5 SPLBIO, SPLIMP, SPLTTY	*/	SR_IEC | SR_IMASK6,		/* 6 SPLCLOCK			*/	SR_IEC | SR_IMASK7,		/* 7 SPLMEM			*/	SR_IEC | SR_IMASK8,		/* 8 SPLFPU			*/};/* * Configuration routine for kn01 processor (pmax). */kn01conf(){	extern int cold;	extern unsigned cpu_systype;	extern int cpu;			/* Ultrix internal System type */	cold = 1;	/* 	 * Initialize PROM environment entries.	 */	hwconf_init();	/* 	 * Report what system we are on	 */	printf("KN01 processor - system rev %d\n", (GETHRDREV(cpu_systype)));	coproc_find();	/*	 * Safe to take interrupts now.	 */	splnone();	config_delay();	kn01config_devices();	timeout (kn01transenable, (caddr_t) 0, kn01transintvl * hz);	cold = 0;	return(0);}/* * Initialization routine for kn01 processor (pmax). */kn01init(){	extern int c0vec_tblsize;	extern int (*c0vec_tbl[])();	extern int iplmask[];	extern int splm[];	extern struct cpusw *cpup;	/*	 * 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 (or spl) is allowed.	 */	bcopy((int *)kn01intr_vec, c0vec_tbl, c0vec_tblsize);	bcopy(kn01iplmask, iplmask, IPLSIZE * sizeof(int));	bcopy(kn01splm, splm, (SPLMSIZE) * sizeof(int));	/* Initialize the spl dispatch table and the intr dispatch routine */	spl_init();	/*	 * 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(KN01CLOCK_ADDR);	return (0);}/* * Handle stray interrupts that occur before the lance is probed & attached. * This only occurs if the console doesn't initialize the lance properly.	the lance properly. */#define LN_CSR0 0x0000			/* CSR 0 */#define LN_STOP 0x0004			/* Reset firmware (stop) */kn01lnstray(){	volatile unsigned short *addr;	/* 16 bit lance registers */	addr = (volatile unsigned short *)PHYS_TO_K1(KN01LANCE_ADDR);	*addr = LN_CSR0;	/*	 * The lance registers are long word alligned, so increment by 2 shorts	 */	addr += 2;	*addr = LN_STOP;	return;}/* * Strategy here is to probe all I/O chips/controllers in one place *   and set the appropriate states/flags for further use. */kn01config_devices() {	extern int cnprobe();	extern int pmprobe();	extern int lnprobe();	int s;	config_set_alive("ibus",0,0,0);	/*	 * Probe the system console subsystem;	 *   set the printstate flag to CONSPRINT if successful.	 */	if (ib_config_dev(PHYS_TO_K1(KN01DC_ADDR), KN01DC_ADDR, 0, "dc", 0)) {	        printstate = printstate | CONSPRINT;	}	/*	 * Probe the frame buffer graphics driver;	 *   both color and mono bitmaps use the same driver	 */	if (kn01_fb_probe())	    ib_config_dev(PHYS_TO_K1(KN01FRAME_BUF_ADDR), KN01FRAME_BUF_ADDR, 0, "fb", 0);	/* 	 * Probe the sii based scsi bus.	 */	ib_config_cont(PHYS_TO_K1(KN01SII_ADDR),KN01SII_ADDR,0,"sii",0);	/*	 * Config the Lance.	 * Note: We must block Lance interrupts until after the lnprobe	 *       is done and interrupts are vectored to the "netintr" routine.	 *	 Otherwise there is a race condition: when lnprobe turns the	 *	 Lance on, the first interrupt could go to kn01lnstray and	 *	 turn the lance off!	 */	s = splimp();	config_set_alive("ibus",0,0,0);	if (ib_config_dev(PHYS_TO_K1(KN01LANCE_ADDR),KN01LANCE_ADDR,0,"ln",0))		c0vec_tbl[3] = netintr;	else		printf("ln0 not probed\n");	splx(s);	return(0);}kn01_fb_probe(){       u_char *addr, *addr1;       /* if MONO bit is clear a color SIMM is definitely installed 	*/       /* in the slot							*/       /* if MONO bit is set we need to probe frame buffer to determine	*/       /* if there is an actual SIMM in the slot			*/       if ((*((short *) PM_CSR_ADDR) & PM_CSR_MONO) == 0)	   return (1);       /* Use addresses that are not in the visible region of the frame	*/       /* buffer memory.  We need to write and read two addresses so	*/       /* we are not caught by any logic on the board that may return	*/       /* the byte just written						*/       addr = (u_char *)(PHYS_TO_K1(KN01FRAME_BUF_ADDR + 0x36100));       addr1 = (u_char *)((int)addr + 0x88);       *addr = 0xaa;       *addr1 = 0x55;       if ((*addr == 0xaa) && (*addr1 == 0x55))	   return (1);       return (0);}/* * pmax delay routine. */int delay_mult = 8;		/* multiplier for DELAY (optimized) */kn01delay(n)	int n;{	register int N = delay_mult*(n); 	while (--N > 0); 	return(0);}/* * Enable transient parity memory error logging */kn01transenable(){	kn01translog = 1;	timeout (kn01transenable, (caddr_t) 0, kn01transintvl * 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. */kn01trap_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 */	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.		 */

⌨️ 快捷键说明

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