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

📄 kn5800.c

📁 <B>Digital的Unix操作系统VAX 4.2源码</B>
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifndef lintstatic char *sccsid = "@(#)kn5800.c	4.3      (ULTRIX)  10/9/90";#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.	* *									* ************************************************************************//* * Revision History: * * 30-Apr-90	Randall Brown *	Added call to spl_init() to intialize spl function pointers and *      the intr() function pointer. * * 29-Mar-90	gmm *	enable CRDID in secondary_init() * * 06-Mar-90	gmm *	Log soft error on cache FIFO overflow. Also do the extra write even *	if lock bit set/clear in bbssi/bbcci * * 08-Dec-89	gmm *	Soft error logging changes merged from v3.1C. A workaround for the *	console bug to find the number of processors with both 3.1 and 4.0 *	console ROMs. Bug fix to map the correct IP interrupt address for *	all valid slots (was using VAX page size before). * * 14-Nov-89    gmm *	Change to start a secondary processor, changes to bbssi() and bbcci() *	to flush cache(). This should get fixed in hardware soon. * * 13-Nov-89	burns *	Fixed nxaccess to deal properly with I/O address space, made *	interrupt vectors reads handle passive releases. * * 09-Nov-89	bp *	Optimized Vaxmap to use mips KSEG0 space to minimize tblmiss hits. * * 26-Oct-89    gmm *	Moved bbssi() and bbcci() from interlock.c to this file. * * 13-Oct-89	gmm *	SMP changes. Error log buffer gets allocated on per cpu basis. Added *	routines like kn5800_init_secondary() and modified cca_setup() etc. * * 12-Sep-89	burns *	New way of doing a write buffer flush that is much faster. *	Removed printfs that were used for debug. *	Removed hack code for "erroneous interrupts". * * 11-Sep-89	Pete Keilty *	Change alloc_vaxmap() to use a define Maxvax_dbpte which *	is defined in scamachmac.h * * 27-Jan-89	Bill Burns *	Created the file.  This file contains routines specific *	to ISIS systems. */#include "../machine/pte.h"#include "../h/param.h"#include "../h/user.h"			/* gets time.h and debug.h too */#include "../h/proc.h"#include "../h/conf.h"#include "../h/errno.h"#include "../h/systm.h"#include "../h/types.h"#include "../h/errlog.h"#include "../h/cmap.h"#include "../h/ioctl.h"#include "../h/tty.h"#include "../h/cpudata.h"#include "../h/kmalloc.h"#include "../h/vmmac.h"#include "../io/uba/ubareg.h"#include "../machine/cpu.h"#include "../machine/reg.h"#include "../../machine/common/cpuconf.h"#include "../machine/ssc.h"#include "../machine/cons.h"#include "../machine/cca.h"#include "../machine/clock.h"#include "../machine/hwconf.h"#include "../machine/param.h"#include "../machine/kn5800.h"#include "../io/xmi/xmireg.h"#include "../io/xmi/xmareg.h"#include "../io/scs/scamachmac.h"#define ESRPKT 1#define MEMPKT 2struct xmidata	*head_xmidata;extern int (*(scb[]))();extern caddr_t	vatophys();extern struct bidata bidata[];extern int cache_state;extern int nNVAXBI;struct kn5800_regs *kn5800_regp;int	powerfail;int	cache_state;		/* in autoconf for vax */int	*kn5800_wbflush_addr;	/* Holds the address to read to trigger				   a write buffer flush */int	wbflush_dummy;		/* target destination for a write buffer				   flush - its external to prevent compiler				   from getting too smart and optimizing out				   a write buffer flush */struct	cca	*ccabase;	/* console communications area */extern	char	*kn5800_ip_addr[];/* struct ssc_regs cvqssc[1];		/* SSC regs */struct v5800csr *v5800csr = (struct v5800csr *)CSR5800;struct vaxpte *vax_map;extern struct pte eSysmap[];extern struct vaxpte *Vaxmap;	/* pointer to the base of Vaxmap */extern int Vaxmap_size;		/* size of the entire Vaxmap in pages */int Vax_page_factor;		/* Vax pages per mips page */extern	int gvp_max_bds;	/* Number of data structs that need 128 ptes */#define VAX_PAGE_SIZE 512/* * Interrupt handlers for the 6 hardware interrupts and 2 software * interrupts for ISIS */extern softclock(), softnet(), kn5800_intr0(), kn5800_intr1(),	kn5800_intr2(), kn5800_intr3(), kn5800_halt(), fpuintr();int (*kn5800_intr_vec[8])() = {	softclock,		/* softint 0	       		    */	softnet,		/* softint 1	       		    */	kn5800_intr0,		/* hardint 0 - XMI level 4/5 and SSC*/	kn5800_intr1,		/* hardint 1 - XMI level 6, IP and Cloc */	kn5800_intr2,		/* hardint 2 - XMI level 7	     */	kn5800_intr3,		/* hardint 3 - Hard and soft errors  */	kn5800_halt,		/* hardint 4 - Halt interrupt	     */	fpuintr			/* hardint 5 - FPU interrupt	     */};#ifndef SR_HALT#define SR_HALT	SR_IBIT7#endif	SR_HALTint kn5800_iplmask[8] = {	SR_IMASK1|SR_IEC|SR_HALT,	/* soft clock		*/	SR_IMASK2|SR_IEC|SR_HALT,	/* soft net		*/	SR_IMASK3|SR_IEC|SR_HALT,	/* XMI 4/5 and SSC	*/	SR_IMASK4|SR_IEC|SR_HALT,	/* XMI 6, IP and clock	*/	SR_IMASK5|SR_IEC|SR_HALT,	/* XMI 7		*/	SR_IMASK6|SR_IEC|SR_HALT,	/* Hard and soft errors	*/	SR_IMASK7|SR_IEC,		/* Halt			*/	SR_IMASK8|SR_IEC|SR_HALT	/* FPU			*/};/* * This array conatins the interrupt mask to use for spl calls. Indexed * by the defines in cpu.h (SPLBIO, etc). */int kn5800_splm[SPLMSIZE] = {	SR_IEC | SR_IMASK0 | SR_HALT,	/* 0 SPLNONE			*/	SR_IEC | SR_IMASK1 | SR_HALT,	/* 1 SPLSOFTC			*/	SR_IEC | SR_IMASK2 | SR_HALT,	/* 2 SPLNET			*/	0,				/* 3 NOT_USED 			*/	0,				/* 4 NOT_USED 			*/	SR_IEC | SR_IMASK3 | SR_HALT,	/* 5 SPLBIO, SPLIMP, SPLTTY	*/	SR_IEC | SR_IMASK4 | SR_HALT,	/* 6 SPLCLOCK			*/	SR_IEC | SR_IMASK6 | SR_HALT,	/* 7 SPLMEM			*/	SR_IEC | SR_IMASK8 | SR_HALT,	/* 8 SPLFPU, EXTREME, HIGH, 7, 6*/};/* * alloc_vaxmap -- allocate space for a "vax" page table. This table consists * of two parts. First a VAX version of the kernel "sysmap". This is required * for the relative queues that are used by the devices that requires vax * virtual support. The queue heads and elements are kmalloc'ed and use * virtual indexes, thus the Vaxmap and sysmap must coincide virtually. * TODO: This first part of Vaxmap may only need to correspond to kmalloc * space. * * The second part of Vaxmap (indcated by Vaxdbpte) is space reserved to * hold Vax pte's that are used for actual data transfer operations. 128 + 8 * ptes per "gvp_max_bds" give us enough room for the 64kb data transfer * for every device that is configured that needs Vax virtual support. */alloc_vaxmap(){	register int base_size, dbpte_size;	register int map_size, i,  pfn;	register struct vaxpte *pte;	/* HACK - needs to be fixed for mips page sizes other than 4k */	Vax_page_factor = (NBPG/VAX_PAGE_SIZE);	/* End HACK */	/*	 * Calculate Vaxmap_size which is the size of the Vaxmap in vax pages.	 */	base_size = ((eSysmap - Sysmap) * Vax_page_factor);	/*	 * Calculate the size map for db	 */	dbpte_size = (gvp_max_bds * Maxvax_dbpte);	/*	 * VAX pte space required for map.	 */	map_size = (((base_size + dbpte_size) * sizeof (struct vaxpte)) + 			VAX_PAGE_SIZE - 1) / VAX_PAGE_SIZE; 	Vaxmap_size = base_size + map_size + dbpte_size;	if ((vax_map = (struct vaxpte *) kseg0_alloc(				(Vaxmap_size * sizeof (struct vaxpte)))));	else panic("alloc_vaxmap: allocate failed");	Vaxmap = (struct vaxpte *)vax_map;	/*	 * 	 */	Dbptemap = (struct vaxpte *) (Vaxmap + base_size);	/*	 * Map the map itself	 */	for (pfn = btoc(K0_TO_PHYS(Vaxmap)) << 3, 		pte = Vaxmap + base_size + dbpte_size, i = 0; i < map_size; 			i++, pte++, pfn++) * (int *) pte = pfn | VAX_PG_V;	/*	 * Vax virtual sysmap	 */	VSysmap = (struct vaxpte *)(VAX_SYSVA +  			(base_size + dbpte_size) * VAX_PGSIZE);	/*	 * Need a VAX virtual address in VSysmap for dbpte.	 */	Vaxdbpte = (struct pte *) (VSysmap + base_size);}#define	SSC_INTR_LEVEL	0x00000000extern	int cnrint(), cnxint();extern 	int cpu_ip_intr();	/* IPI handler *//* * Configuration routine. */kn5800_conf(){	extern int cold;	extern unsigned cpu_systype;	extern int cpu;			/* Ultrix internal System type */	extern struct cpusw *cpup;extern struct pte eSysmap[];extern struct vaxpte *Vaxmap;	char *nxv;	int 	nxp;	register int i;	register int xcp_node;	register struct xmidata *xmidata;	struct xcp_reg *xcp;	char *start;	struct pte *pte;	int cpu_subtype;	struct kn5800_regs *x3p_regs;	cold = 1;	hwconf_init();	powerfail = 0;		/* reset count of powerfail interrupts */	/* Report what system we are on */	switch (cpu) {	case DS_5800:		printf("KN5800 processor - system rev %d\n", (GETHRDREV(cpu_systype)));		break;	default:		panic("kn5800_conf called, wrong system");		break;	}	/*	 * Begin "calypso-ish" initialization	 */	/* 	 * coproc_find will cause the system's first write buffer flush in	 * dealing with the floating point unit. So we must set up the	 * the write_buffer flush address first. The write buffer flush	 * address is the external (io) address of the boot processor's	 * gpr register.	 */	/* allocate up 1 xmi structure */	KM_ALLOC(xmidata,struct xmidata *,sizeof(struct xmidata ),KM_DEVBUF,KM_NOW_CL_CO_CA);	head_xmidata = xmidata;	xmidata->next = 0;	xmidata->xminum = 0;	xmidata->xmivirt = (struct xmi_reg *)PHYS_TO_K1(XMI_START_PHYS);	xcp_node = v5800csr->csr1 & XMI_NODE_ID;	xcp = ((struct xcp_reg *)PHYS_TO_K1(XMI_START_PHYS) + xcp_node);	kn5800_wbflush_addr = (int *)&(xcp->xcp_gpr);	coproc_find();			/* Deal with FPU */	/*	 * set up mapping for interrupt vector locations.	 */	mapin (btop(kn5800_vectors), btop(KN5800_VEC_REG_BASE),						(PG_KW|PG_N|PG_V|PG_G));	scb[0xf8/4] = cnrint;	scb[0xfc/4] = cnxint;	scb[0x80/4] = cpu_ip_intr;  /* put the ipi handler */	init_ssc();	/*	 * allocate Vaxmap - a vax system page table for use by devices that need	 * vax virutal address: CI, BVP.	 */	alloc_vaxmap();	KM_ALLOC(x3p_regs, struct kn5800_regs *, (sizeof(struct kn5800_regs) * MAXCPU),		                 KM_DEVBUF, KM_NOW_CL_CO_CA);	kn5800_regp = x3p_regs;	/*	 * fill in table of IP interrupt addresses.  Addresses 	 * are of the form:	 *	 *  vax	 2101nnnn	 *  mips b101nnnn	 *          where nnnn is the decoded XMI node number	 *		 */#define	IP_INTR_ADDRESS_BASE	0x11010000	start = (char *) PHYS_TO_K1(IP_INTR_ADDRESS_BASE);	for (i=0 ; i< MAX_XMI_NODE ; i++ ) {		nxp = IP_INTR_ADDRESS_BASE + (1<<i);		if (i < 12) /* for the 4k page size */			nxv =  start + (1<<i);		else {			nxv = start + ((i-11) * NBPG);		}		kn5800_ip[i] = nxv;	}	xcp_node = v5800csr->csr1 & XMI_NODE_ID;	xmidata->xmiintr_dst = (1 << xcp_node);	kn5800_enable_cache() ;	#ifdef mips	xmidata->xmiphys = (struct xmi_reg *) XMI_START_PHYS;	xmidata->xmivec_page = &scb[0];#endif mips	spl0();  			/* Ready for interrupts */	cpu_avail  = cca_setup() ; /* due to a console bug, the processor 				      always shown to be in cosole mode */		/* allocate space for machine specific error packets */	KM_ALLOC(CURRENT_CPUDATA->cpu_machdep,char *,sizeof(struct el_xcpsoft),KM_DEVBUF,KM_NOW_CL_CO_CA);	printf("DECsystem 58%d0 server\n",cpu_avail);	/*	 * configure the I/O system 	 */	xmiconf(0,cpup);	/* clear warm and cold boot flags */	ccabase->cca_hflag &= ~(CCA_V_BOOTIP|CCA_V_WARMIP);	/*	 * Configure swap area and related system	 * parameter based on device(s) used.	 */#ifndef ultrix	setconf();	swapconf();#endif not ultrix	cold = 0;	kn5800_memenable();	return (0);}/* below define is from machine/vax/mem.h - needs to be put somewhere more portable. */#define	MEMINTVL	(60 * 15)	/* 15 minutes */int	memintvl = MEMINTVL;kn5800_memenable(){	int xminode;	struct xmi_reg	*nxv;	/* virtual pointer to XMI node */	struct xmidata *xmidata;	int i;	extern int hz;	xmidata = get_xmi(0);	/*	 * Enable XMAs crd interrupts	 */	nxv = xmidata->xmivirt;	for(xminode = 0; xminode < MAX_XMI_NODE; xminode++,nxv++) {		if ((xmidata->xminodes_alive & (1<<xminode)) &&		    ((short) (nxv->xmi_dtype) == XMI_XMA)) {				/* clear disable CRD flag in memory controller */			((struct xma_reg *)nxv)->xma_mctl1 					      &= ~(XMA_CTL1_CRD_DISABLE);		}	}	/*	 * Enable cache soft error logging	 */	CURRENT_CPUDATA->cpu_state &= ~(CPU_SOFT_DISABLE);	/*	 * Schedule next call to ourself for the primary cpu. Secondary cpus	 * should schedule their own	 */	if (memintvl > 0)		timeout (kn5800_memenable, (caddr_t) 0, memintvl * hz);	return(0);}/* * Initialization routine for kn5800 processor (ISIS). */kn5800_init(){	extern int c0vec_tblsize;	extern int (*c0vec_tbl[])();	extern int iplmask[];	extern int splm[];	extern int hz;	extern int tick;	extern int tickadj;	extern struct cpusw *cpup;	register int xcp_node;	struct xcp_reg *xcp;	/*	 * 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((int *)kn5800_intr_vec, c0vec_tbl, c0vec_tblsize);	bcopy(kn5800_iplmask, iplmask, IPLSIZE * sizeof(int));	bcopy(kn5800_splm, splm, (SPLMSIZE) * sizeof(int));	/* Initialize the spl dispatch table and the intr dispatch routine */	spl_init();	clear_bev();	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);	xcp_node = v5800csr->csr1 & XMI_NODE_ID;	xcp = ((struct xcp_reg *)PHYS_TO_K1(XMI_START_PHYS) + xcp_node);	kn5800_wbflush_addr = (int *)&(xcp->xcp_gpr);	return (0);}/* * kn5800_halt - R3000 interrupt pin 5 * *	Halt interrupt * *	Since mips doesn't have a halt instruction we just call the console. */int	haltflag;kn5800_halt (ep)u_int	*ep;{	panic ("kn5800_halt");}/* * intr3 - R3000 interrupt pin 3 - Hard and soft system errors. *	Possible causes: *		Powerfail *		Memory errors *		CRD - corrected read data and memory errors *		First level invalidate fifo overflow * * 	No vector * *	Since Ultrix doesn't support powerfail restarts we wait to see it *	it is a real powerfail or not. If not we just return, if so we... */kn5800_intr3 (ep)u_int	*ep;{	int	csr1, csr2, xbe;	int	tmp;	struct xcp_reg *xcp_node;	register struct xmidata *xmidata;	register struct kn5800_regs *reg;	register struct el_xcpsoft *sptr;	xmidata = get_xmi(0);	xcp_node =(struct xcp_reg *)xmidata->xmivirt +					(v5800csr->csr1 & XMI_NODE_ID);	sptr = (struct el_xcpsoft *)CURRENT_CPUDATA->cpu_machdep;	/*	 * Gather up X3P registers.	 */	reg = kn5800_regp;	reg->kn5800_csr1 = v5800csr->csr1;	reg->kn5800_dtype = xcp_node->xcp_dtype;	reg->kn5800_xbe = xcp_node->xcp_xbe;	reg->kn5800_fadr = xcp_node->xcp_fadr;	reg->kn5800_gpr = xcp_node->xcp_gpr;	reg->kn5800_csr2 = xcp_node->xcp_csr2;	/*	 * See if it's a powerfail	 */	if (!(reg->kn5800_csr1 & XMI_ACLO)) {		/* Powerfail - duck */		powerfail++;		/* Delay one second, if we are still alive, continue */		DELAY(1000000);	}	if (reg->kn5800_csr1 & IFIFOFL) {		if ((CURRENT_CPUDATA->cpu_state & CPU_SOFT_DISABLE) == 0)				kn5800_log_soft(reg,sptr);		kn5800_flush_cache();	}	/*	 * If we detect any fatal memory errors call kn5800_memerr to	 * report, crash and burn.	 */	if (reg->kn5800_xbe & (XBE_FATAL_BITS | XBE_RER | XBE_RIDNAK)) {		kn5800_memerr (ep, reg, EL_PRISEVERE);	}	if (reg->kn5800_csr2 & (CSR2_WDPE)) {		kn5800_memerr (ep, reg, EL_PRISEVERE);	}

⌨️ 快捷键说明

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