Home | History | Annotate | Line # | Download | only in vsa
vsbus.c revision 1.2
      1  1.2    cgd /*	$NetBSD: vsbus.c,v 1.2 1996/08/27 21:58:51 cgd Exp $ */
      2  1.1  ragge /*
      3  1.1  ragge  * Copyright (c) 1996 Ludd, University of Lule}, Sweden.
      4  1.1  ragge  * All rights reserved.
      5  1.1  ragge  *
      6  1.1  ragge  * This code is derived from software contributed to Ludd by Bertram Barth.
      7  1.1  ragge  *
      8  1.1  ragge  * Redistribution and use in source and binary forms, with or without
      9  1.1  ragge  * modification, are permitted provided that the following conditions
     10  1.1  ragge  * are met:
     11  1.1  ragge  * 1. Redistributions of source code must retain the above copyright
     12  1.1  ragge  *    notice, this list of conditions and the following disclaimer.
     13  1.1  ragge  * 2. Redistributions in binary form must reproduce the above copyright
     14  1.1  ragge  *    notice, this list of conditions and the following disclaimer in the
     15  1.1  ragge  *    documentation and/or other materials provided with the distribution.
     16  1.1  ragge  * 3. All advertising materials mentioning features or use of this software
     17  1.1  ragge  *    must display the following acknowledgement:
     18  1.1  ragge  *	This product includes software developed at Ludd, University of
     19  1.1  ragge  *	Lule}, Sweden and its contributors.
     20  1.1  ragge  * 4. The name of the author may not be used to endorse or promote products
     21  1.1  ragge  *    derived from this software without specific prior written permission
     22  1.1  ragge  *
     23  1.1  ragge  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     24  1.1  ragge  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     25  1.1  ragge  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26  1.1  ragge  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     27  1.1  ragge  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     28  1.1  ragge  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     29  1.1  ragge  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     30  1.1  ragge  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     31  1.1  ragge  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     32  1.1  ragge  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33  1.1  ragge  */
     34  1.1  ragge 
     35  1.1  ragge #include <sys/param.h>
     36  1.1  ragge #include <sys/systm.h>
     37  1.1  ragge #include <sys/buf.h>
     38  1.1  ragge #include <sys/conf.h>
     39  1.1  ragge #include <sys/file.h>
     40  1.1  ragge #include <sys/ioctl.h>
     41  1.1  ragge #include <sys/proc.h>
     42  1.1  ragge #include <sys/user.h>
     43  1.1  ragge #include <sys/map.h>
     44  1.1  ragge #include <sys/device.h>
     45  1.1  ragge #include <sys/dkstat.h>
     46  1.1  ragge #include <sys/disklabel.h>
     47  1.1  ragge #include <sys/syslog.h>
     48  1.1  ragge #include <sys/stat.h>
     49  1.1  ragge 
     50  1.1  ragge #include <machine/pte.h>
     51  1.1  ragge #include <machine/sid.h>
     52  1.1  ragge #include <machine/scb.h>
     53  1.1  ragge #include <machine/cpu.h>
     54  1.1  ragge #include <machine/trap.h>
     55  1.1  ragge #include <machine/nexus.h>
     56  1.1  ragge 
     57  1.1  ragge #include <machine/uvax.h>
     58  1.1  ragge #include <machine/ka410.h>
     59  1.1  ragge #include <machine/ka43.h>
     60  1.1  ragge 
     61  1.1  ragge #include <machine/vsbus.h>
     62  1.1  ragge 
     63  1.1  ragge #define trace(x)
     64  1.1  ragge #define debug(x)
     65  1.1  ragge 
     66  1.1  ragge int	vsbus_match	__P((struct device *, void *, void *));
     67  1.1  ragge void	vsbus_attach	__P((struct device *, struct device *, void *));
     68  1.2    cgd int	vsbus_print	__P((void *, const char *));
     69  1.1  ragge 
     70  1.1  ragge void	ka410_attach	__P((struct device *, struct device *, void *));
     71  1.1  ragge void	ka43_attach	__P((struct device *, struct device *, void *));
     72  1.1  ragge 
     73  1.1  ragge struct	cfdriver vsbus_cd = {
     74  1.1  ragge 	NULL, "vsbus", DV_DULL
     75  1.1  ragge };
     76  1.1  ragge struct	cfattach vsbus_ca = {
     77  1.1  ragge 	sizeof(struct device), vsbus_match, vsbus_attach
     78  1.1  ragge };
     79  1.1  ragge 
     80  1.1  ragge /*
     81  1.1  ragge void	vsbus_intr_register __P((struct confargs *ca, int (*)(void*), void*));
     82  1.1  ragge void	vsbus_intr_unregister __P((struct confargs *));
     83  1.1  ragge */
     84  1.1  ragge 
     85  1.1  ragge void	vsbus_intr_dispatch __P((int i));
     86  1.1  ragge 
     87  1.1  ragge #define VSBUS_MAXDEVS	8
     88  1.1  ragge #define VSBUS_MAXINTR	8
     89  1.1  ragge 
     90  1.1  ragge struct confargs *vsbus_devs = NULL;
     91  1.1  ragge 
     92  1.1  ragge #ifdef VAX410	/* also: KA420 */
     93  1.1  ragge struct confargs ka410_devs[] = {
     94  1.1  ragge 	/* name		intslot intpri intvec	intbit	ioaddr	*/
     95  1.1  ragge 	{ "dc",		7,	7,	0x2C0,	(1<<7), KA410_SER_BASE,
     96  1.1  ragge 			6,	6,	0x2C4,	(1<<6), 0x01,		},
     97  1.1  ragge 	{ "dc (xmit)",	6,	6,	0x2C4,	(1<<6), KA410_SER_BASE, },
     98  1.1  ragge 	{ "le",		5,	5,	0x250,	(1<<5), KA410_LAN_BASE,
     99  1.1  ragge 			KA410_NWA_BASE, 0x00,				},
    100  1.1  ragge 	{ "ncr",	1,	1,	0x3F8,	(1<<1), KA410_SCS_BASE,
    101  1.1  ragge 			KA410_SCS_DADR, KA410_SCS_DCNT, KA410_SCS_DDIR,
    102  1.1  ragge 			KA410_DMA_BASE, KA410_DMA_SIZE, 0x00,	0x07,	},
    103  1.1  ragge 	{ "hdc",	0,	0,	0x3FC,	(1<<0), KA410_DKC_BASE,
    104  1.1  ragge 			0, 0, 0,
    105  1.1  ragge 			KA410_DMA_BASE, KA410_DMA_SIZE, 0x00,		},
    106  1.1  ragge #if 0
    107  1.1  ragge 	{ "dc (recv)",	7,	7,	0x2C0,	(1<<7), KA410_SER_BASE, },
    108  1.1  ragge 	{ "dc (xmit)",	6,	6,	0x2C4,	(1<<6), KA410_SER_BASE, },
    109  1.1  ragge 	{ "hdc9224",	0,	0,	0x3FC,	(1<<0), KA410_DKC_BASE, },
    110  1.1  ragge 	{ "ncr5380",	1,	1,	0x3F8,	(1<<1), KA410_SCS_BASE, },
    111  1.1  ragge 	{ "am7990",	5,	5,	0x250,	(1<<5), KA410_LAN_BASE, },
    112  1.1  ragge 	{ "NETOPT",	4,	4,	0x254,	(1<<4), KA410_LAN_BASE, },
    113  1.1  ragge #endif
    114  1.1  ragge 	{ "" },
    115  1.1  ragge };
    116  1.1  ragge #endif
    117  1.1  ragge 
    118  1.1  ragge #ifdef VAX43
    119  1.1  ragge struct confargs ka43_devs[] = {
    120  1.1  ragge 	/* name		intslot intpri intvec	intbit	ioaddr	*/
    121  1.1  ragge 	{ "dc",		7,	7,	0x2C0,	(1<<7), KA43_SER_BASE,
    122  1.1  ragge 			6,	6,	0x2C4,	(1<<6), 0x01,		},
    123  1.1  ragge 	{ "dc (xmit)",	6,	6,	0x2C4,	(1<<6), KA43_SER_BASE,	},
    124  1.1  ragge 	{ "le",		5,	5,	0x250,	(1<<5), KA43_LAN_BASE,
    125  1.1  ragge 			KA43_NWA_BASE,	0x00,				},
    126  1.1  ragge 	{ "ncr",	1,	1,	0x3F8,	(1<<1), KA43_SC1_BASE,
    127  1.1  ragge 			KA43_SC1_DADR,	KA43_SC1_DCNT,	KA43_SC1_DDIR,
    128  1.1  ragge 			KA43_DMA_BASE,	KA43_DMA_SIZE,	0x01,	0x06,	},
    129  1.1  ragge 	{ "ncr",	0,	0,	0x3FC,	(1<<0), KA43_SC2_BASE,
    130  1.1  ragge 			KA43_SC2_DADR,	KA43_SC2_DCNT,	KA43_SC2_DDIR,
    131  1.1  ragge 			KA43_DMA_BASE,	KA43_DMA_SIZE,	0x01,	0x06,	},
    132  1.1  ragge #if 0
    133  1.1  ragge 	{ "le (2nd)",	4,	4,	0x254,	(1<<4), 0x???,		},
    134  1.1  ragge 	{ "NETOPT",	4,	4,	0x254,	(1<<4), 0x???,		},
    135  1.1  ragge #endif
    136  1.1  ragge 	{ "" },
    137  1.1  ragge };
    138  1.1  ragge #endif
    139  1.1  ragge 
    140  1.1  ragge int
    141  1.1  ragge vsbus_print(aux, name)
    142  1.1  ragge 	void *aux;
    143  1.2    cgd 	const char *name;
    144  1.1  ragge {
    145  1.1  ragge 	struct confargs *ca = aux;
    146  1.1  ragge 
    147  1.1  ragge 	trace(("vsbus_print(%x, %s)\n", ca->ca_name, name));
    148  1.1  ragge 
    149  1.1  ragge 	if (name) {
    150  1.1  ragge 		printf ("device %s at %s", ca->ca_name, name);
    151  1.1  ragge 		return (UNSUPP);
    152  1.1  ragge 	}
    153  1.1  ragge 	return (UNCONF);
    154  1.1  ragge }
    155  1.1  ragge 
    156  1.1  ragge int
    157  1.1  ragge vsbus_match(parent, cf, aux)
    158  1.1  ragge 	struct	device	*parent;
    159  1.1  ragge 	void	*cf;
    160  1.1  ragge 	void	*aux;
    161  1.1  ragge {
    162  1.1  ragge 	struct bp_conf *bp = aux;
    163  1.1  ragge 
    164  1.1  ragge 	trace(("vsbus_match: bp->type = \"%s\"\n", bp->type));
    165  1.1  ragge 
    166  1.1  ragge 	if (strcmp(bp->type, "vsbus"))
    167  1.1  ragge 		return 0;
    168  1.1  ragge 	/*
    169  1.1  ragge 	 * on machines which can have it, the vsbus is always there
    170  1.1  ragge 	 */
    171  1.1  ragge 	if ((vax_bustype & VAX_VSBUS) == 0)
    172  1.1  ragge 		return (0);
    173  1.1  ragge 
    174  1.1  ragge 	return (1);
    175  1.1  ragge }
    176  1.1  ragge 
    177  1.1  ragge #if 1	/*------------------------------------------------------------*/
    178  1.1  ragge #if 1
    179  1.1  ragge #define REG(name)	short name; short X##name##X;
    180  1.1  ragge #else
    181  1.1  ragge #define REG(name)	int name;
    182  1.1  ragge #endif
    183  1.1  ragge static volatile struct {/* base address of DZ-controller: 0x200A0000 */
    184  1.1  ragge   REG(csr);		/* 00 Csr: control/status register */
    185  1.1  ragge   REG(rbuf);		/* 04 Rbuf/Lpr: receive buffer/line param reg. */
    186  1.1  ragge   REG(tcr);		/* 08 Tcr: transmit console register */
    187  1.1  ragge   REG(tdr);		/* 0C Msr/Tdr: modem status reg/transmit data reg */
    188  1.1  ragge   REG(lpr0);		/* 10 Lpr0: */
    189  1.1  ragge   REG(lpr1);		/* 14 Lpr0: */
    190  1.1  ragge   REG(lpr2);		/* 18 Lpr0: */
    191  1.1  ragge   REG(lpr3);		/* 1C Lpr0: */
    192  1.1  ragge } *dz = (void*)0x200A0000;
    193  1.1  ragge extern int dzcnrint();
    194  1.1  ragge extern int dzcntint();
    195  1.1  ragge int hardclock_count = 0;
    196  1.1  ragge int
    197  1.1  ragge ka410_consintr_enable()
    198  1.1  ragge {
    199  1.1  ragge 	vsbus_intr_enable(&ka410_devs[0]);
    200  1.1  ragge 	vsbus_intr_enable(&ka410_devs[1]);
    201  1.1  ragge }
    202  1.1  ragge 
    203  1.1  ragge int
    204  1.1  ragge ka410_consRecv_intr(p)
    205  1.1  ragge 	void *p;
    206  1.1  ragge {
    207  1.1  ragge   /* printf("ka410_consRecv_intr: hc-count=%d\n", hardclock_count); */
    208  1.1  ragge   dzcnrint();
    209  1.1  ragge   /* printf("gencnrint() returned.\n"); */
    210  1.1  ragge   return(0);
    211  1.1  ragge }
    212  1.1  ragge 
    213  1.1  ragge int
    214  1.1  ragge ka410_consXmit_intr(p)
    215  1.1  ragge 	void *p;
    216  1.1  ragge {
    217  1.1  ragge   /* printf("ka410_consXmit_intr: hc-count=%d\n", hardclock_count); */
    218  1.1  ragge   dzcntint();
    219  1.1  ragge   /* printf("gencntint() returned.\n"); */
    220  1.1  ragge   return(0);
    221  1.1  ragge }
    222  1.1  ragge #endif	/*------------------------------------------------------------*/
    223  1.1  ragge 
    224  1.1  ragge void
    225  1.1  ragge vsbus_attach(parent, self, aux)
    226  1.1  ragge 	struct	device	*parent, *self;
    227  1.1  ragge 	void	*aux;
    228  1.1  ragge {
    229  1.1  ragge 	struct confargs *ca;
    230  1.1  ragge 	int i;
    231  1.1  ragge 
    232  1.1  ragge 	printf("\n");
    233  1.1  ragge 	trace (("vsbus_attach()\n"));
    234  1.1  ragge 
    235  1.1  ragge 	printf("vsbus_attach: boardtype = %x\n", vax_boardtype);
    236  1.1  ragge 
    237  1.1  ragge 	switch (vax_boardtype) {
    238  1.1  ragge 	case VAX_BTYP_410:
    239  1.1  ragge 	case VAX_BTYP_420:
    240  1.1  ragge 		vsbus_devs = ka410_devs;
    241  1.1  ragge 		break;
    242  1.1  ragge 
    243  1.1  ragge 	case VAX_BTYP_43:
    244  1.1  ragge 	case VAX_BTYP_46:
    245  1.1  ragge 	case VAX_BTYP_49:
    246  1.1  ragge 		vsbus_devs = ka43_devs;
    247  1.1  ragge 		break;
    248  1.1  ragge 
    249  1.1  ragge 	default:
    250  1.1  ragge 		printf ("unsupported boardtype 0x%x in vsbus_attach()\n",
    251  1.1  ragge 			vax_boardtype);
    252  1.1  ragge 		return;
    253  1.1  ragge 	}
    254  1.1  ragge 
    255  1.1  ragge 	/*
    256  1.1  ragge 	 * first setup interrupt-table, so that devices can register
    257  1.1  ragge 	 * their interrupt-routines...
    258  1.1  ragge 	 */
    259  1.1  ragge 	vsbus_intr_setup();
    260  1.1  ragge 
    261  1.1  ragge 	/*
    262  1.1  ragge 	 * now check for all possible devices on this "bus"
    263  1.1  ragge 	 */
    264  1.1  ragge 	for (i=0; i<VSBUS_MAXDEVS; i++) {
    265  1.1  ragge 		ca = &vsbus_devs[i];
    266  1.1  ragge 		if (*ca->ca_name == '\0')
    267  1.1  ragge 			break;
    268  1.1  ragge 		config_found(self, (void*)ca, vsbus_print);
    269  1.1  ragge 	}
    270  1.1  ragge 
    271  1.1  ragge 	/*
    272  1.1  ragge 	 * as long as there's no working DZ-driver, we use this dummy
    273  1.1  ragge 	 */
    274  1.1  ragge 	vsbus_intr_register(&ka410_devs[0], ka410_consRecv_intr, NULL);
    275  1.1  ragge 	vsbus_intr_register(&ka410_devs[1], ka410_consXmit_intr, NULL);
    276  1.1  ragge }
    277  1.1  ragge 
    278  1.1  ragge #define VSBUS_MAX_INTR	8	/* 64? */
    279  1.1  ragge /*
    280  1.1  ragge  * interrupt service routines are given an int as argument, which is
    281  1.1  ragge  * pushed onto stack as LITERAL. Thus the value is between 0-63.
    282  1.1  ragge  * This array of 64 might be oversized for now, but it's all which
    283  1.1  ragge  * ever will be possible.
    284  1.1  ragge  */
    285  1.1  ragge struct vsbus_ivec {
    286  1.1  ragge 	struct ivec_dsp intr_vec;		/* this is referenced in SCB */
    287  1.1  ragge 	int		intr_count;		/* keep track of interrupts */
    288  1.1  ragge 	int		intr_flags;		/* valid, etc. */
    289  1.1  ragge 	void		(*enab)(int);		/* enable interrupt */
    290  1.1  ragge 	void		(*disab)(int);		/* disable interrupt */
    291  1.1  ragge 	void		(*prep)(int);		/* need pre-processing? */
    292  1.1  ragge 	int		(*handler)(void*);	/* isr-routine to call */
    293  1.1  ragge 	void		*hndlarg;		/* args to this routine */
    294  1.1  ragge 	void		(*postp)(int);		/* need post-processing? */
    295  1.1  ragge } vsbus_ivtab[VSBUS_MAX_INTR];
    296  1.1  ragge 
    297  1.1  ragge /*
    298  1.1  ragge  *
    299  1.1  ragge  */
    300  1.1  ragge int
    301  1.1  ragge vsbus_intr_setup()
    302  1.1  ragge {
    303  1.1  ragge 	int i;
    304  1.1  ragge 	struct vsbus_ivec *ip;
    305  1.1  ragge 	extern struct ivec_dsp idsptch;		/* subr.s */
    306  1.1  ragge 
    307  1.1  ragge 	for (i=0; i<VSBUS_MAX_INTR; i++) {
    308  1.1  ragge 		ip = &vsbus_ivtab[i];
    309  1.1  ragge 		bcopy(&idsptch, &ip->intr_vec, sizeof(struct ivec_dsp));
    310  1.1  ragge 		ip->intr_vec.pushlarg = i;
    311  1.1  ragge 		ip->intr_vec.hoppaddr = vsbus_intr_dispatch;
    312  1.1  ragge 		ip->intr_count = 0;
    313  1.1  ragge 		ip->intr_flags = 0;
    314  1.1  ragge 		ip->enab = NULL;
    315  1.1  ragge 		ip->disab = NULL;
    316  1.1  ragge 		ip->postp = NULL;
    317  1.1  ragge 	}
    318  1.1  ragge 	switch (vax_boardtype) {
    319  1.1  ragge 	case VAX_BTYP_410:
    320  1.1  ragge 	case VAX_BTYP_420:
    321  1.1  ragge 	case VAX_BTYP_43:
    322  1.1  ragge 	case VAX_BTYP_46:
    323  1.1  ragge 	case VAX_BTYP_49:
    324  1.1  ragge 		ka410_intr_setup();
    325  1.1  ragge 		return(0);
    326  1.1  ragge 	default:
    327  1.1  ragge 		printf("unsupported board-type 0x%x in vsbus_intr_setup()\n",
    328  1.1  ragge 			vax_boardtype);
    329  1.1  ragge 		return(1);
    330  1.1  ragge 	}
    331  1.1  ragge }
    332  1.1  ragge 
    333  1.1  ragge int
    334  1.1  ragge vsbus_intr_register(ca, handler, arg)
    335  1.1  ragge 	struct confargs *ca;
    336  1.1  ragge 	int (*handler)(void*);
    337  1.1  ragge 	void *arg;
    338  1.1  ragge {
    339  1.1  ragge 	/* struct device *dev = arg; */
    340  1.1  ragge 	int i = ca->ca_intslot;
    341  1.1  ragge 	struct vsbus_ivec *ip = &vsbus_ivtab[i];
    342  1.1  ragge 
    343  1.1  ragge 	trace (("vsbus_intr_register(%s/%d)\n", ca->ca_name, ca->ca_intslot));
    344  1.1  ragge 
    345  1.1  ragge 	ip->handler = handler;
    346  1.1  ragge 	ip->hndlarg = arg;
    347  1.1  ragge }
    348  1.1  ragge 
    349  1.1  ragge int
    350  1.1  ragge vsbus_intr_enable(ca)
    351  1.1  ragge 	struct confargs *ca;
    352  1.1  ragge {
    353  1.1  ragge 	int i = ca->ca_intslot;
    354  1.1  ragge 	struct vsbus_ivec *ip = &vsbus_ivtab[i];
    355  1.1  ragge 
    356  1.1  ragge 	trace (("vsbus_intr_enable(%s/%d)\n", ca->ca_name, ca->ca_intslot));
    357  1.1  ragge 
    358  1.1  ragge 	/* XXX check for valid handler etc. !!! */
    359  1.1  ragge 	if (ip->handler == NULL) {
    360  1.1  ragge 		printf("interrupts for \"%s\"(%d) not enabled: null-handler\n",
    361  1.1  ragge 		      ca->ca_name, ca->ca_intslot);
    362  1.1  ragge 		return;
    363  1.1  ragge 	}
    364  1.1  ragge 
    365  1.1  ragge 	ip->enab(i);
    366  1.1  ragge }
    367  1.1  ragge 
    368  1.1  ragge int
    369  1.1  ragge vsbus_intr_disable(ca)
    370  1.1  ragge 	struct confargs *ca;
    371  1.1  ragge {
    372  1.1  ragge 	int i = ca->ca_intslot;
    373  1.1  ragge 	struct vsbus_ivec *ip = &vsbus_ivtab[i];
    374  1.1  ragge 
    375  1.1  ragge 	trace (("vsbus_intr_disable(%s/%d)\n", ca->ca_name, i));
    376  1.1  ragge 
    377  1.1  ragge 	ip->disab(i);
    378  1.1  ragge }
    379  1.1  ragge 
    380  1.1  ragge int
    381  1.1  ragge vsbus_intr_unregister(ca)
    382  1.1  ragge 	struct confargs *ca;
    383  1.1  ragge {
    384  1.1  ragge 	int i = ca->ca_intslot;
    385  1.1  ragge 	struct vsbus_ivec *ip = &vsbus_ivtab[i];
    386  1.1  ragge 
    387  1.1  ragge 	trace (("vsbus_intr_unregister(%s/%d)\n", ca->ca_name, i));
    388  1.1  ragge 
    389  1.1  ragge 	ip->handler = NULL;
    390  1.1  ragge 	ip->hndlarg = NULL;
    391  1.1  ragge }
    392  1.1  ragge 
    393  1.1  ragge void
    394  1.1  ragge vsbus_intr_dispatch(i)
    395  1.1  ragge 	register int i;
    396  1.1  ragge {
    397  1.1  ragge 	register struct vsbus_ivec *ip = &vsbus_ivtab[i];
    398  1.1  ragge 
    399  1.1  ragge 	trace (("vsbus_intr_dispatch(%d)", i));
    400  1.1  ragge 
    401  1.1  ragge 	if (i < VSBUS_MAX_INTR && ip->handler != NULL) {
    402  1.1  ragge 		ip->intr_count++;
    403  1.1  ragge 		debug (("intr-count[%d] = %d\n", i, ip->intr_count));
    404  1.1  ragge 		(ip->handler)(ip->hndlarg);
    405  1.1  ragge 		if (ip->postp)
    406  1.1  ragge 			(ip->postp)(i);
    407  1.1  ragge 		return;
    408  1.1  ragge 	}
    409  1.1  ragge 
    410  1.1  ragge 	if (i < 0 || i >= VSBUS_MAX_INTR) {
    411  1.1  ragge 		printf ("stray interrupt %d on vsbus.\n", i);
    412  1.1  ragge 		return;
    413  1.1  ragge 	}
    414  1.1  ragge 
    415  1.1  ragge 	if (!ip->handler) {
    416  1.1  ragge 		printf ("unhandled interrupt %d on vsbus.\n", i);
    417  1.1  ragge 		return;
    418  1.1  ragge 	}
    419  1.1  ragge }
    420  1.1  ragge 
    421  1.1  ragge /*
    422  1.1  ragge  * These addresses are invalid and will be updated/corrected by
    423  1.1  ragge  * ka410_intr_setup(), but having them this way helps debugging
    424  1.1  ragge  */
    425  1.1  ragge static volatile u_char *ka410_intmsk = (void*)KA410_INTMSK;
    426  1.1  ragge static volatile u_char *ka410_intreq = (void*)KA410_INTREQ;
    427  1.1  ragge static volatile u_char *ka410_intclr = (void*)KA410_INTCLR;
    428  1.1  ragge 
    429  1.1  ragge static void
    430  1.1  ragge ka410_intr_enable(i)
    431  1.1  ragge 	int i;
    432  1.1  ragge {
    433  1.1  ragge 	trace (("ka410_intr_enable(%d)\n", i));
    434  1.1  ragge 	*ka410_intmsk |= (1<<i);
    435  1.1  ragge }
    436  1.1  ragge 
    437  1.1  ragge static void
    438  1.1  ragge ka410_intr_disable(i)
    439  1.1  ragge 	int i;
    440  1.1  ragge {
    441  1.1  ragge 	trace (("ka410_intr_disable(%d)\n", i));
    442  1.1  ragge 	*ka410_intmsk &= ~(1<<i);
    443  1.1  ragge }
    444  1.1  ragge 
    445  1.1  ragge static void
    446  1.1  ragge ka410_intr_clear(i)
    447  1.1  ragge 	int i;
    448  1.1  ragge {
    449  1.1  ragge 	trace (("ka410_intr_clear(%d)\n", i));
    450  1.1  ragge 	*ka410_intclr = (1<<i);
    451  1.1  ragge }
    452  1.1  ragge 
    453  1.1  ragge ka410_intr_setup()
    454  1.1  ragge {
    455  1.1  ragge 	int i;
    456  1.1  ragge 	struct vsbus_ivec *ip;
    457  1.1  ragge 	void **scbP = (void*)scb;
    458  1.1  ragge 
    459  1.1  ragge 	trace (("ka410_intr_setup()\n"));
    460  1.1  ragge 
    461  1.1  ragge 	ka410_intmsk = (void*)uvax_phys2virt(KA410_INTMSK);
    462  1.1  ragge 	ka410_intreq = (void*)uvax_phys2virt(KA410_INTREQ);
    463  1.1  ragge 	ka410_intclr = (void*)uvax_phys2virt(KA410_INTCLR);
    464  1.1  ragge 
    465  1.1  ragge 	*ka410_intmsk = 0;		/* disable all interrupts */
    466  1.1  ragge 	*ka410_intclr = 0xFF;		/* clear all old interrupts */
    467  1.1  ragge 
    468  1.1  ragge 	/*
    469  1.1  ragge 	 * insert the VS2000-specific routines into ivec-table...
    470  1.1  ragge 	 */
    471  1.1  ragge 	for (i=0; i<8; i++) {
    472  1.1  ragge 		ip = &vsbus_ivtab[i];
    473  1.1  ragge 		ip->enab  = ka410_intr_enable;
    474  1.1  ragge 		ip->disab = ka410_intr_disable;
    475  1.1  ragge 		/* ip->postp = ka410_intr_clear; bertram XXX */
    476  1.1  ragge 	}
    477  1.1  ragge 	/*
    478  1.1  ragge 	 * ...and register the interrupt-vectors in SCB
    479  1.1  ragge 	 */
    480  1.1  ragge 	scbP[IVEC_DC/4] = &vsbus_ivtab[0].intr_vec;
    481  1.1  ragge 	scbP[IVEC_SC/4] = &vsbus_ivtab[1].intr_vec;
    482  1.1  ragge 	scbP[IVEC_VS/4] = &vsbus_ivtab[2].intr_vec;
    483  1.1  ragge 	scbP[IVEC_VF/4] = &vsbus_ivtab[3].intr_vec;
    484  1.1  ragge 	scbP[IVEC_NS/4] = &vsbus_ivtab[4].intr_vec;
    485  1.1  ragge 	scbP[IVEC_NP/4] = &vsbus_ivtab[5].intr_vec;
    486  1.1  ragge 	scbP[IVEC_ST/4] = &vsbus_ivtab[6].intr_vec;
    487  1.1  ragge 	scbP[IVEC_SR/4] = &vsbus_ivtab[7].intr_vec;
    488  1.1  ragge }
    489  1.1  ragge 
    490  1.1  ragge /*
    491  1.1  ragge  *
    492  1.1  ragge  *
    493  1.1  ragge  */
    494  1.1  ragge 
    495  1.1  ragge static volatile struct dma_lock {
    496  1.1  ragge 	int	dl_locked;
    497  1.1  ragge 	int	dl_wanted;
    498  1.1  ragge 	void	*dl_owner;
    499  1.1  ragge 	int	dl_count;
    500  1.1  ragge } dmalock = { 0, 0, NULL, 0 };
    501  1.1  ragge 
    502  1.1  ragge int
    503  1.1  ragge vsbus_lockDMA(ca)
    504  1.1  ragge 	struct confargs *ca;
    505  1.1  ragge {
    506  1.1  ragge 	while (dmalock.dl_locked) {
    507  1.1  ragge 		dmalock.dl_wanted++;
    508  1.1  ragge 		sleep((caddr_t)&dmalock, PRIBIO);	/* PLOCK or PRIBIO ? */
    509  1.1  ragge 		dmalock.dl_wanted--;
    510  1.1  ragge 	}
    511  1.1  ragge 	dmalock.dl_locked++;
    512  1.1  ragge 	dmalock.dl_owner = ca;
    513  1.1  ragge 
    514  1.1  ragge 	/*
    515  1.1  ragge 	 * no checks yet, no timeouts, nothing...
    516  1.1  ragge 	 */
    517  1.1  ragge 
    518  1.1  ragge #ifdef DEBUG
    519  1.1  ragge 	if ((++dmalock.dl_count % 1000) == 0)
    520  1.1  ragge 		printf("%d locks, owner: %s\n", dmalock.dl_count, ca->ca_name);
    521  1.1  ragge #endif
    522  1.1  ragge 	return (0);
    523  1.1  ragge }
    524  1.1  ragge 
    525  1.1  ragge int
    526  1.1  ragge vsbus_unlockDMA(ca)
    527  1.1  ragge 	struct confargs *ca;
    528  1.1  ragge {
    529  1.1  ragge 	if (dmalock.dl_locked != 1 || dmalock.dl_owner != ca) {
    530  1.1  ragge 		printf("locking-problem: %d, %s\n", dmalock.dl_locked,
    531  1.1  ragge 		       (dmalock.dl_owner ? dmalock.dl_owner : "null"));
    532  1.1  ragge 		dmalock.dl_locked = 0;
    533  1.1  ragge 		return (-1);
    534  1.1  ragge 	}
    535  1.1  ragge 	dmalock.dl_owner = NULL;
    536  1.1  ragge 	dmalock.dl_locked = 0;
    537  1.1  ragge 	if (dmalock.dl_wanted) {
    538  1.1  ragge 		wakeup((caddr_t)&dmalock);
    539  1.1  ragge 	}
    540  1.1  ragge 	return (0);
    541  1.1  ragge }
    542  1.1  ragge 
    543  1.1  ragge /*----------------------------------------------------------------------*/
    544  1.1  ragge #if 0
    545  1.1  ragge /*
    546  1.1  ragge  * small set of routines needed for mapping when doing pseudo-DMA,
    547  1.1  ragge  * quasi-DMA or virtual-DMA (choose whatever name you like).
    548  1.1  ragge  *
    549  1.1  ragge  * Once I know how VS3100 is doing real DMA (I hope it does), this
    550  1.1  ragge  * should be rewritten to present a general interface...
    551  1.1  ragge  *
    552  1.1  ragge  */
    553  1.1  ragge 
    554  1.1  ragge extern u_long uVAX_physmap;
    555  1.1  ragge 
    556  1.1  ragge u_long
    557  1.1  ragge vsdma_mapin(bp, len)
    558  1.1  ragge 	struct buf *bp;
    559  1.1  ragge 	int len;
    560  1.1  ragge {
    561  1.1  ragge 	pt_entry_t *pte;	/* pointer to Page-Table-Entry */
    562  1.1  ragge 	struct pcb *pcb;	/* pointer to Process-Controll-Block */
    563  1.1  ragge 	pt_entry_t *xpte;
    564  1.1  ragge 	caddr_t addr;
    565  1.1  ragge 	int pgoff;		/* offset into 1st page */
    566  1.1  ragge 	int pgcnt;		/* number of pages needed */
    567  1.1  ragge 	int pfnum;
    568  1.1  ragge 	int i;
    569  1.1  ragge 
    570  1.1  ragge 	trace(("mapin(bp=%x, bp->data=%x)\n", bp, bp->b_data));
    571  1.1  ragge 
    572  1.1  ragge 	addr = bp->b_data;
    573  1.1  ragge 	pgoff = (int)bp->b_data & PGOFSET;	/* get starting offset */
    574  1.1  ragge 	pgcnt = btoc(bp->b_bcount + pgoff) + 1; /* one more than needed */
    575  1.1  ragge 
    576  1.1  ragge 	/*
    577  1.1  ragge 	 * Get a pointer to the pte pointing out the first virtual address.
    578  1.1  ragge 	 * Use different ways in kernel and user space.
    579  1.1  ragge 	 */
    580  1.1  ragge 	if ((bp->b_flags & B_PHYS) == 0) {
    581  1.1  ragge 		pte = kvtopte(addr);
    582  1.1  ragge 	} else {
    583  1.1  ragge 		pcb = bp->b_proc->p_vmspace->vm_pmap.pm_pcb;
    584  1.1  ragge 		pte = uvtopte(addr, pcb);
    585  1.1  ragge 	}
    586  1.1  ragge 
    587  1.1  ragge 	/*
    588  1.1  ragge 	 * When we are doing DMA to user space, be sure that all pages
    589  1.1  ragge 	 * we want to transfer to are mapped. WHY DO WE NEED THIS???
    590  1.1  ragge 	 * SHOULDN'T THEY ALWAYS BE MAPPED WHEN DOING THIS???
    591  1.1  ragge 	 */
    592  1.1  ragge 	for (i=0; i<(pgcnt-1); i++) {
    593  1.1  ragge 		if ((pte + i)->pg_pfn == 0) {
    594  1.1  ragge 			int rv;
    595  1.1  ragge 			rv = vm_fault(&bp->b_proc->p_vmspace->vm_map,
    596  1.1  ragge 				      (unsigned)addr + i * NBPG,
    597  1.1  ragge 				      VM_PROT_READ|VM_PROT_WRITE, FALSE);
    598  1.1  ragge 			if (rv)
    599  1.1  ragge 				panic("vs-DMA to nonexistent page, %d", rv);
    600  1.1  ragge 		}
    601  1.1  ragge 	}
    602  1.1  ragge 
    603  1.1  ragge 	/*
    604  1.1  ragge 	 * now insert new mappings for this memory area into kernel's
    605  1.1  ragge 	 * mapping-table
    606  1.1  ragge 	 */
    607  1.1  ragge 	xpte = kvtopte(uVAX_physmap);
    608  1.1  ragge 	while (--pgcnt > 0) {
    609  1.1  ragge 		pfnum = pte->pg_pfn;
    610  1.1  ragge 		if (pfnum == 0)
    611  1.1  ragge 			panic("vsbus: zero entry");
    612  1.1  ragge 		*(int *)xpte++ = *(int *)pte++;
    613  1.1  ragge 	}
    614  1.1  ragge 	*(int *)xpte = 0;	/* mark last mapped page as invalid! */
    615  1.1  ragge 
    616  1.1  ragge 	debug(("uVAX: 0x%x\n", uVAX_physmap + pgoff));
    617  1.1  ragge 
    618  1.1  ragge 	return (uVAX_physmap + pgoff);	/* ??? */
    619  1.1  ragge }
    620  1.1  ragge #endif
    621  1.1  ragge /*----------------------------------------------------------------------*/
    622  1.1  ragge /*
    623  1.1  ragge  * Here follows some currently(?) unused stuff. Someday this should be removed
    624  1.1  ragge  */
    625  1.1  ragge 
    626  1.1  ragge #if 0
    627  1.1  ragge /*
    628  1.1  ragge  * Configure devices on VS2000/KA410 directly attached to vsbus
    629  1.1  ragge  */
    630  1.1  ragge void
    631  1.1  ragge ka410_attach(parent, self, aux)
    632  1.1  ragge 	struct device *parent;
    633  1.1  ragge 	struct device *self;
    634  1.1  ragge 	void *aux;
    635  1.1  ragge {
    636  1.1  ragge 	struct confargs *ca;
    637  1.1  ragge 	int i;
    638  1.1  ragge 
    639  1.1  ragge 	for (i=0; i<KA410_MAXDEVS; i++) {
    640  1.1  ragge 		ca = &ka410_devs[i];
    641  1.1  ragge 		if (*ca->ca_name == '\0')
    642  1.1  ragge 			break;
    643  1.1  ragge 		config_found(self, (void*)ca, vsbus_print);
    644  1.1  ragge 	}
    645  1.1  ragge 	/*
    646  1.1  ragge 	 * as long as there's no real DZ-driver, we used this dummy
    647  1.1  ragge 	 */
    648  1.1  ragge 	vsbus_intr_register(&ka410_devs[0], ka410_consRecv_intr, NULL);
    649  1.1  ragge 	vsbus_intr_register(&ka410_devs[1], ka410_consXmit_intr, NULL);
    650  1.1  ragge }
    651  1.1  ragge 
    652  1.1  ragge #endif
    653