Home | History | Annotate | Line # | Download | only in dev
pcc.c revision 1.2
      1 /* $Id: pcc.c,v 1.2 1996/03/17 01:35:03 thorpej Exp $ */
      2 
      3 /*
      4  *
      5  * Copyright (c) 1995 Charles D. Cranor
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  * 2. Redistributions in binary form must reproduce the above copyright
     14  *    notice, this list of conditions and the following disclaimer in the
     15  *    documentation and/or other materials provided with the distribution.
     16  * 3. All advertising materials mentioning features or use of this software
     17  *    must display the following acknowledgement:
     18  *      This product includes software developed by Charles D. Cranor.
     19  * 4. The name of the author may not be used to endorse or promote products
     20  *    derived from this software without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 
     34 /*
     35  * peripheral channel controller
     36  */
     37 
     38 #include <sys/param.h>
     39 #include <sys/conf.h>
     40 #include <sys/ioctl.h>
     41 #include <sys/proc.h>
     42 #include <sys/user.h>
     43 #include <sys/tty.h>
     44 #include <sys/uio.h>
     45 #include <sys/callout.h>
     46 #include <sys/systm.h>
     47 #include <sys/kernel.h>
     48 #include <sys/syslog.h>
     49 #include <sys/fcntl.h>
     50 #include <sys/device.h>
     51 #include <machine/cpu.h>
     52 #include <dev/cons.h>
     53 #include <mvme68k/mvme68k/isr.h>
     54 #include <mvme68k/dev/iio.h>
     55 #include <mvme68k/dev/pccreg.h>
     56 
     57 /*
     58  * Autoconfiguration stuff.
     59  */
     60 
     61 struct pccsoftc {
     62 	struct device	sc_dev;
     63 	struct pcc	*sc_pcc;
     64 };
     65 
     66 
     67 void pccattach __P((struct device *, struct device *, void *));
     68 int  pccmatch __P((struct device *, void *, void *));
     69 
     70 struct cfattach pcc_ca = {
     71 	sizeof(struct pccsoftc), pccmatch, pccattach
     72 };
     73 
     74 struct cfdriver pcc_cd = {
     75 	NULL, "pcc", DV_DULL, 0
     76 };
     77 
     78 /*
     79  * globals
     80  */
     81 
     82 struct pcc *sys_pcc = NULL;
     83 
     84 struct {
     85 	int	(*pcc_fn)();
     86 	void	*arg;
     87 	int	lvl;
     88 } pcc_vecs[PCC_NVEC];
     89 
     90 int
     91 pccmatch(parent, vcf, args)
     92 	struct device *parent;
     93 	void *vcf, *args;
     94 {
     95 	struct cfdata *cf = vcf;
     96 
     97 	return !badbaddr((caddr_t) IIO_CFLOC_ADDR(cf));
     98 }
     99 
    100 void
    101 pccattach(parent, self, args)
    102 	struct device *parent, *self;
    103 	void *args;
    104 {
    105 	struct pccsoftc *pccsc;
    106 
    107 	if (sys_pcc)
    108 		panic("pcc already attached!");
    109 
    110 	iio_print(self->dv_cfdata);
    111 
    112 	/*
    113 	 * link into softc and set up interrupt vector base
    114 	 */
    115 	pccsc = (struct pccsoftc *) self;
    116 	sys_pcc = pccsc->sc_pcc = (struct pcc *)IIO_CFLOC_ADDR(self->dv_cfdata);
    117 	pccsc->sc_pcc->int_vectr = PCC_VECBASE;
    118 	bzero(pcc_vecs, sizeof(pcc_vecs));
    119 
    120 	printf(" rev %d intbvr 0x%x\n", pccsc->sc_pcc->pcc_rev,
    121 	    pccsc->sc_pcc->int_vectr);
    122 }
    123 
    124 
    125 /*
    126  * pccintr: called from locore with the PC and evec from the trap frame.
    127  */
    128 int
    129 pccintr(pc, evec, frame)
    130 	int pc;
    131 	int evec;
    132 	void *frame;
    133 {
    134 	int vec = (evec & 0xfff) >> 2; /* XXX should be m68k macro? */
    135 	extern u_long intrcnt[]; /* XXX from locore */
    136 
    137 	vec = vec & 0xf; /* XXX mask out */
    138 	if (vec >= PCC_NVEC || pcc_vecs[vec].pcc_fn == NULL)
    139 		return(straytrap(pc, evec));
    140 
    141 	cnt.v_intr++;
    142 	intrcnt[pcc_vecs[vec].lvl]++;
    143 
    144 	/* arg override?  only timer1 gets access to frame */
    145 	if (vec != PCCV_TIMER1)
    146 		frame = pcc_vecs[vec].arg;
    147 	return((*pcc_vecs[vec].pcc_fn)(frame));
    148 }
    149 
    150 
    151 /*
    152  * pccintr_establish: establish pcc interrupt
    153  */
    154 int
    155 pccintr_establish(vec, hand, lvl, arg)
    156 	u_long vec;
    157 	int (*hand)(), lvl;
    158 	void *arg;
    159 {
    160 	if (vec >= PCC_NVEC) {
    161 		printf("pcc: illegal vector: 0x%x\n", vec);
    162 		panic("pccintr_establish");
    163 	}
    164 
    165 	if (pcc_vecs[vec].pcc_fn) {
    166 		printf("pcc: vector 0x%x in use: (0x%x,0x%x) (0x%x,0x%x)\n",
    167 		    hand, arg, pcc_vecs[vec].pcc_fn, pcc_vecs[vec].arg);
    168 		panic("pccintr_establish");
    169 	}
    170 
    171 	pcc_vecs[vec].pcc_fn = hand;
    172 	pcc_vecs[vec].lvl = lvl;
    173 	pcc_vecs[vec].arg = arg;
    174 }
    175