Home | History | Annotate | Line # | Download | only in isa
isabus.c revision 1.13.2.3
      1  1.13.2.3  bouyer /*	$NetBSD: isabus.c,v 1.13.2.3 2001/01/05 17:33:56 bouyer Exp $	*/
      2  1.13.2.2  bouyer /*	$OpenBSD: isabus.c,v 1.15 1998/03/16 09:38:46 pefo Exp $	*/
      3  1.13.2.2  bouyer /*	NetBSD: isa.c,v 1.33 1995/06/28 04:30:51 cgd Exp 	*/
      4  1.13.2.2  bouyer 
      5  1.13.2.2  bouyer /*-
      6  1.13.2.2  bouyer  * Copyright (c) 1995 Per Fogelstrom
      7  1.13.2.2  bouyer  * Copyright (c) 1993, 1994 Charles M. Hannum.
      8  1.13.2.2  bouyer  * Copyright (c) 1990 The Regents of the University of California.
      9  1.13.2.2  bouyer  * All rights reserved.
     10  1.13.2.2  bouyer  *
     11  1.13.2.2  bouyer  * This code is derived from software contributed to Berkeley by
     12  1.13.2.2  bouyer  * William Jolitz and Don Ahn.
     13  1.13.2.2  bouyer  *
     14  1.13.2.2  bouyer  * Redistribution and use in source and binary forms, with or without
     15  1.13.2.2  bouyer  * modification, are permitted provided that the following conditions
     16  1.13.2.2  bouyer  * are met:
     17  1.13.2.2  bouyer  * 1. Redistributions of source code must retain the above copyright
     18  1.13.2.2  bouyer  *    notice, this list of conditions and the following disclaimer.
     19  1.13.2.2  bouyer  * 2. Redistributions in binary form must reproduce the above copyright
     20  1.13.2.2  bouyer  *    notice, this list of conditions and the following disclaimer in the
     21  1.13.2.2  bouyer  *    documentation and/or other materials provided with the distribution.
     22  1.13.2.2  bouyer  * 3. All advertising materials mentioning features or use of this software
     23  1.13.2.2  bouyer  *    must display the following acknowledgement:
     24  1.13.2.2  bouyer  *	This product includes software developed by the University of
     25  1.13.2.2  bouyer  *	California, Berkeley and its contributors.
     26  1.13.2.2  bouyer  * 4. Neither the name of the University nor the names of its contributors
     27  1.13.2.2  bouyer  *    may be used to endorse or promote products derived from this software
     28  1.13.2.2  bouyer  *    without specific prior written permission.
     29  1.13.2.2  bouyer  *
     30  1.13.2.2  bouyer  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
     31  1.13.2.2  bouyer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     32  1.13.2.2  bouyer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     33  1.13.2.2  bouyer  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
     34  1.13.2.2  bouyer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     35  1.13.2.2  bouyer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     36  1.13.2.2  bouyer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     37  1.13.2.2  bouyer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     38  1.13.2.2  bouyer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     39  1.13.2.2  bouyer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     40  1.13.2.2  bouyer  * SUCH DAMAGE.
     41  1.13.2.2  bouyer  *
     42  1.13.2.2  bouyer  *	@(#)isa.c	7.2 (Berkeley) 5/12/91
     43  1.13.2.2  bouyer  */
     44  1.13.2.2  bouyer /*
     45  1.13.2.2  bouyer  * Mach Operating System
     46  1.13.2.2  bouyer  * Copyright (c) 1991,1990,1989 Carnegie Mellon University
     47  1.13.2.2  bouyer  * All Rights Reserved.
     48  1.13.2.2  bouyer  *
     49  1.13.2.2  bouyer  * Permission to use, copy, modify and distribute this software and its
     50  1.13.2.2  bouyer  * documentation is hereby granted, provided that both the copyright
     51  1.13.2.2  bouyer  * notice and this permission notice appear in all copies of the
     52  1.13.2.2  bouyer  * software, derivative works or modified versions, and any portions
     53  1.13.2.2  bouyer  * thereof, and that both notices appear in supporting documentation.
     54  1.13.2.2  bouyer  *
     55  1.13.2.2  bouyer  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     56  1.13.2.2  bouyer  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
     57  1.13.2.2  bouyer  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     58  1.13.2.2  bouyer  *
     59  1.13.2.2  bouyer  * Carnegie Mellon requests users of this software to return to
     60  1.13.2.2  bouyer  *
     61  1.13.2.2  bouyer  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     62  1.13.2.2  bouyer  *  School of Computer Science
     63  1.13.2.2  bouyer  *  Carnegie Mellon University
     64  1.13.2.2  bouyer  *  Pittsburgh PA 15213-3890
     65  1.13.2.2  bouyer  *
     66  1.13.2.2  bouyer  * any improvements or extensions that they make and grant Carnegie Mellon
     67  1.13.2.2  bouyer  * the rights to redistribute these changes.
     68  1.13.2.2  bouyer  */
     69  1.13.2.2  bouyer /*
     70  1.13.2.2  bouyer   Copyright 1988, 1989 by Intel Corporation, Santa Clara, California.
     71  1.13.2.2  bouyer 
     72  1.13.2.2  bouyer 		All Rights Reserved
     73  1.13.2.2  bouyer 
     74  1.13.2.2  bouyer Permission to use, copy, modify, and distribute this software and
     75  1.13.2.2  bouyer its documentation for any purpose and without fee is hereby
     76  1.13.2.2  bouyer granted, provided that the above copyright notice appears in all
     77  1.13.2.2  bouyer copies and that both the copyright notice and this permission notice
     78  1.13.2.2  bouyer appear in supporting documentation, and that the name of Intel
     79  1.13.2.2  bouyer not be used in advertising or publicity pertaining to distribution
     80  1.13.2.2  bouyer of the software without specific, written prior permission.
     81  1.13.2.2  bouyer 
     82  1.13.2.2  bouyer INTEL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
     83  1.13.2.2  bouyer INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
     84  1.13.2.2  bouyer IN NO EVENT SHALL INTEL BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
     85  1.13.2.2  bouyer CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
     86  1.13.2.2  bouyer LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
     87  1.13.2.2  bouyer NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
     88  1.13.2.2  bouyer WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     89  1.13.2.2  bouyer */
     90  1.13.2.2  bouyer 
     91  1.13.2.2  bouyer #include <sys/param.h>
     92  1.13.2.2  bouyer #include <sys/proc.h>
     93  1.13.2.2  bouyer #include <sys/user.h>
     94  1.13.2.2  bouyer #include <sys/systm.h>
     95  1.13.2.2  bouyer #include <sys/callout.h>
     96  1.13.2.2  bouyer #include <sys/time.h>
     97  1.13.2.2  bouyer #include <sys/kernel.h>
     98  1.13.2.2  bouyer #include <sys/device.h>
     99  1.13.2.2  bouyer #include <sys/malloc.h>
    100  1.13.2.2  bouyer 
    101  1.13.2.2  bouyer #include <uvm/uvm_extern.h>
    102  1.13.2.2  bouyer 
    103  1.13.2.2  bouyer #include <machine/cpu.h>
    104  1.13.2.2  bouyer #include <machine/pio.h>
    105  1.13.2.2  bouyer #include <machine/autoconf.h>
    106  1.13.2.2  bouyer #include <machine/intr.h>
    107  1.13.2.2  bouyer 
    108  1.13.2.2  bouyer #include <arc/arc/arctype.h>
    109  1.13.2.3  bouyer #include <arc/jazz/pica.h>
    110  1.13.2.3  bouyer #include <arc/jazz/rd94.h>
    111  1.13.2.2  bouyer 
    112  1.13.2.2  bouyer #include <dev/isa/isareg.h>
    113  1.13.2.2  bouyer #include <dev/isa/isavar.h>
    114  1.13.2.2  bouyer #include <arc/isa/timerreg.h>
    115  1.13.2.2  bouyer #include <arc/isa/spkrreg.h>
    116  1.13.2.2  bouyer #include <machine/isa_machdep.h>
    117  1.13.2.2  bouyer 
    118  1.13.2.2  bouyer static int beeping;
    119  1.13.2.2  bouyer static struct callout sysbeep_ch = CALLOUT_INITIALIZER;
    120  1.13.2.2  bouyer 
    121  1.13.2.2  bouyer #define	IRQ_SLAVE	2
    122  1.13.2.2  bouyer #define ICU_LEN		16
    123  1.13.2.2  bouyer 
    124  1.13.2.2  bouyer struct isabr_softc {
    125  1.13.2.2  bouyer 	struct	device sc_dv;
    126  1.13.2.2  bouyer 	struct	arc_isa_bus arc_isa_cs;
    127  1.13.2.2  bouyer 	struct	abus sc_bus;
    128  1.13.2.2  bouyer 	struct arc_bus_dma_tag sc_dmat;
    129  1.13.2.2  bouyer };
    130  1.13.2.2  bouyer 
    131  1.13.2.2  bouyer /* Definition of the driver for autoconfig. */
    132  1.13.2.2  bouyer int	isabrmatch(struct device *, struct cfdata *, void *);
    133  1.13.2.2  bouyer void	isabrattach(struct device *, struct device *, void *);
    134  1.13.2.2  bouyer int	isabrprint(void *, const char *);
    135  1.13.2.2  bouyer 
    136  1.13.2.2  bouyer struct cfattach isabr_ca = {
    137  1.13.2.2  bouyer 	sizeof(struct isabr_softc), isabrmatch, isabrattach
    138  1.13.2.2  bouyer };
    139  1.13.2.2  bouyer extern struct cfdriver isabr_cd;
    140  1.13.2.2  bouyer 
    141  1.13.2.2  bouyer extern struct arc_bus_space arc_bus_io, arc_bus_mem;
    142  1.13.2.2  bouyer 
    143  1.13.2.2  bouyer void	isabr_attach_hook __P((struct device *, struct device *,
    144  1.13.2.2  bouyer 			struct isabus_attach_args *));
    145  1.13.2.2  bouyer const struct evcnt *isabr_intr_evcnt __P((isa_chipset_tag_t, int));
    146  1.13.2.2  bouyer void	*isabr_intr_establish __P((isa_chipset_tag_t, int, int, int,
    147  1.13.2.2  bouyer 			int (*)(void *), void *));
    148  1.13.2.2  bouyer void	isabr_intr_disestablish __P((isa_chipset_tag_t, void*));
    149  1.13.2.2  bouyer int	isabr_iointr __P((unsigned int, struct clockframe *));
    150  1.13.2.2  bouyer void	isabr_initicu __P((void));
    151  1.13.2.2  bouyer void	intr_calculatemasks __P((void));
    152  1.13.2.2  bouyer int	fakeintr __P((void *a));
    153  1.13.2.2  bouyer 
    154  1.13.2.2  bouyer int
    155  1.13.2.2  bouyer isabrmatch(parent, match, aux)
    156  1.13.2.2  bouyer 	struct device *parent;
    157  1.13.2.2  bouyer 	struct cfdata *match;
    158  1.13.2.2  bouyer 	void *aux;
    159  1.13.2.2  bouyer {
    160  1.13.2.2  bouyer 	struct confargs *ca = aux;
    161  1.13.2.2  bouyer 
    162  1.13.2.2  bouyer         /* Make sure that we're looking for a ISABR. */
    163  1.13.2.2  bouyer         if (strcmp(ca->ca_name, isabr_cd.cd_name) != 0)
    164  1.13.2.2  bouyer                 return (0);
    165  1.13.2.2  bouyer 
    166  1.13.2.2  bouyer 	return (1);
    167  1.13.2.2  bouyer }
    168  1.13.2.2  bouyer 
    169  1.13.2.2  bouyer void
    170  1.13.2.2  bouyer isabrattach(parent, self, aux)
    171  1.13.2.2  bouyer 	struct device *parent;
    172  1.13.2.2  bouyer 	struct device *self;
    173  1.13.2.2  bouyer 	void *aux;
    174  1.13.2.2  bouyer {
    175  1.13.2.2  bouyer 	struct isabr_softc *sc = (struct isabr_softc *)self;
    176  1.13.2.2  bouyer 	struct isabus_attach_args iba;
    177  1.13.2.2  bouyer 
    178  1.13.2.2  bouyer 	printf("\n");
    179  1.13.2.2  bouyer 
    180  1.13.2.2  bouyer 	/* Initialize interrupt controller */
    181  1.13.2.2  bouyer 	isabr_initicu();
    182  1.13.2.2  bouyer 
    183  1.13.2.2  bouyer 	/* set up interrupt handlers */
    184  1.13.2.2  bouyer 	switch(cputype) {
    185  1.13.2.2  bouyer 	case ACER_PICA_61:
    186  1.13.2.2  bouyer 	case MAGNUM:
    187  1.13.2.2  bouyer 	case NEC_R94:
    188  1.13.2.2  bouyer 	case NEC_R96:
    189  1.13.2.2  bouyer 		jazz_bus_dma_tag_init(&sc->sc_dmat);
    190  1.13.2.2  bouyer 		set_intr(MIPS_INT_MASK_2, isabr_iointr, 3);
    191  1.13.2.2  bouyer 		break;
    192  1.13.2.2  bouyer 	case DESKSTATION_TYNE:
    193  1.13.2.2  bouyer 		_bus_dma_tag_init(&sc->sc_dmat); /* XXX dedicated bounce mem */
    194  1.13.2.2  bouyer 		set_intr(MIPS_INT_MASK_2, isabr_iointr, 2);
    195  1.13.2.2  bouyer 		break;
    196  1.13.2.2  bouyer 	case DESKSTATION_RPC44:
    197  1.13.2.2  bouyer 		isadma_bounce_tag_init(&sc->sc_dmat);
    198  1.13.2.2  bouyer 		set_intr(MIPS_INT_MASK_2, isabr_iointr, 2);
    199  1.13.2.2  bouyer 		break;
    200  1.13.2.2  bouyer 	default:
    201  1.13.2.2  bouyer 		panic("isabrattach: unkown cputype!");
    202  1.13.2.2  bouyer 	}
    203  1.13.2.2  bouyer 
    204  1.13.2.2  bouyer /*XXX we may remove the abus part of the softc struct... */
    205  1.13.2.2  bouyer 	sc->sc_bus.ab_dv = (struct device *)sc;
    206  1.13.2.2  bouyer 	sc->sc_bus.ab_type = BUS_ISABR;
    207  1.13.2.2  bouyer 
    208  1.13.2.2  bouyer 	sc->arc_isa_cs.ic_attach_hook = isabr_attach_hook;
    209  1.13.2.2  bouyer 	sc->arc_isa_cs.ic_intr_evcnt = isabr_intr_evcnt;
    210  1.13.2.2  bouyer 	sc->arc_isa_cs.ic_intr_establish = isabr_intr_establish;
    211  1.13.2.2  bouyer 	sc->arc_isa_cs.ic_intr_disestablish = isabr_intr_disestablish;
    212  1.13.2.2  bouyer 
    213  1.13.2.2  bouyer 	iba.iba_busname = "isa";
    214  1.13.2.2  bouyer 	iba.iba_iot = &arc_bus_io;
    215  1.13.2.2  bouyer 	iba.iba_memt = &arc_bus_mem;
    216  1.13.2.2  bouyer 	iba.iba_dmat = &sc->sc_dmat;
    217  1.13.2.2  bouyer 	iba.iba_ic = &sc->arc_isa_cs;
    218  1.13.2.2  bouyer 	config_found(self, &iba, isabrprint);
    219  1.13.2.2  bouyer }
    220  1.13.2.2  bouyer 
    221  1.13.2.2  bouyer int
    222  1.13.2.2  bouyer isabrprint(aux, pnp)
    223  1.13.2.2  bouyer 	void *aux;
    224  1.13.2.2  bouyer 	const char *pnp;
    225  1.13.2.2  bouyer {
    226  1.13.2.2  bouyer 	struct confargs *ca = aux;
    227  1.13.2.2  bouyer 
    228  1.13.2.2  bouyer         if (pnp)
    229  1.13.2.2  bouyer                 printf("%s at %s", ca->ca_name, pnp);
    230  1.13.2.2  bouyer         printf(" isa_io_base 0x%lx isa_mem_base 0x%lx",
    231  1.13.2.2  bouyer 		arc_bus_io.bs_vbase, arc_bus_mem.bs_vbase);
    232  1.13.2.2  bouyer         return (UNCONF);
    233  1.13.2.2  bouyer }
    234  1.13.2.2  bouyer 
    235  1.13.2.2  bouyer 
    236  1.13.2.2  bouyer /*
    237  1.13.2.2  bouyer  *	Interrupt system driver code
    238  1.13.2.2  bouyer  *	============================
    239  1.13.2.2  bouyer  */
    240  1.13.2.2  bouyer #define LEGAL_IRQ(x)    ((x) >= 0 && (x) < ICU_LEN && (x) != 2)
    241  1.13.2.2  bouyer 
    242  1.13.2.2  bouyer int	imen;
    243  1.13.2.2  bouyer int	intrtype[ICU_LEN], intrmask[ICU_LEN], intrlevel[ICU_LEN];
    244  1.13.2.2  bouyer struct intrhand *intrhand[ICU_LEN];
    245  1.13.2.2  bouyer 
    246  1.13.2.2  bouyer int fakeintr(a)
    247  1.13.2.2  bouyer 	void *a;
    248  1.13.2.2  bouyer {
    249  1.13.2.2  bouyer 	return 0;
    250  1.13.2.2  bouyer }
    251  1.13.2.2  bouyer 
    252  1.13.2.2  bouyer /*
    253  1.13.2.2  bouyer  * Recalculate the interrupt masks from scratch.
    254  1.13.2.2  bouyer  * We could code special registry and deregistry versions of this function that
    255  1.13.2.2  bouyer  * would be faster, but the code would be nastier, and we don't expect this to
    256  1.13.2.2  bouyer  * happen very much anyway.
    257  1.13.2.2  bouyer  */
    258  1.13.2.2  bouyer void
    259  1.13.2.2  bouyer intr_calculatemasks()
    260  1.13.2.2  bouyer {
    261  1.13.2.2  bouyer 	int irq, level;
    262  1.13.2.2  bouyer 	struct intrhand *q;
    263  1.13.2.2  bouyer 
    264  1.13.2.2  bouyer 	/* First, figure out which levels each IRQ uses. */
    265  1.13.2.2  bouyer 	for (irq = 0; irq < ICU_LEN; irq++) {
    266  1.13.2.2  bouyer 		register int levels = 0;
    267  1.13.2.2  bouyer 		for (q = intrhand[irq]; q; q = q->ih_next)
    268  1.13.2.2  bouyer 			levels |= 1 << q->ih_level;
    269  1.13.2.2  bouyer 		intrlevel[irq] = levels;
    270  1.13.2.2  bouyer 	}
    271  1.13.2.2  bouyer 
    272  1.13.2.2  bouyer 	/* Then figure out which IRQs use each level. */
    273  1.13.2.2  bouyer 	for (level = 0; level < 5; level++) {
    274  1.13.2.2  bouyer 		register int irqs = 0;
    275  1.13.2.2  bouyer 		for (irq = 0; irq < ICU_LEN; irq++)
    276  1.13.2.2  bouyer 			if (intrlevel[irq] & (1 << level))
    277  1.13.2.2  bouyer 				irqs |= 1 << irq;
    278  1.13.2.2  bouyer 		imask[level] = irqs | SIR_ALLMASK;
    279  1.13.2.2  bouyer 	}
    280  1.13.2.2  bouyer 
    281  1.13.2.2  bouyer 	/*
    282  1.13.2.2  bouyer 	 * There are tty, network and disk drivers that use free() at interrupt
    283  1.13.2.2  bouyer 	 * time, so imp > (tty | net | bio).
    284  1.13.2.2  bouyer 	 */
    285  1.13.2.2  bouyer 	imask[IPL_IMP] |= imask[IPL_TTY] | imask[IPL_NET] | imask[IPL_BIO];
    286  1.13.2.2  bouyer 
    287  1.13.2.2  bouyer 	/*
    288  1.13.2.2  bouyer 	 * Enforce a hierarchy that gives slow devices a better chance at not
    289  1.13.2.2  bouyer 	 * dropping data.
    290  1.13.2.2  bouyer 	 */
    291  1.13.2.2  bouyer 	imask[IPL_TTY] |= imask[IPL_NET] | imask[IPL_BIO];
    292  1.13.2.2  bouyer 	imask[IPL_NET] |= imask[IPL_BIO];
    293  1.13.2.2  bouyer 
    294  1.13.2.2  bouyer 	/*
    295  1.13.2.2  bouyer 	 * These are pseudo-levels.
    296  1.13.2.2  bouyer 	 */
    297  1.13.2.2  bouyer 	imask[IPL_NONE] = 0x00000000;
    298  1.13.2.2  bouyer 	imask[IPL_HIGH] = 0xffffffff;
    299  1.13.2.2  bouyer 
    300  1.13.2.2  bouyer 	/* And eventually calculate the complete masks. */
    301  1.13.2.2  bouyer 	for (irq = 0; irq < ICU_LEN; irq++) {
    302  1.13.2.2  bouyer 		register int irqs = 1 << irq;
    303  1.13.2.2  bouyer 		for (q = intrhand[irq]; q; q = q->ih_next)
    304  1.13.2.2  bouyer 			irqs |= imask[q->ih_level];
    305  1.13.2.2  bouyer 		intrmask[irq] = irqs | SIR_ALLMASK;
    306  1.13.2.2  bouyer 	}
    307  1.13.2.2  bouyer 
    308  1.13.2.2  bouyer 	/* Lastly, determine which IRQs are actually in use. */
    309  1.13.2.2  bouyer 	{
    310  1.13.2.2  bouyer 		register int irqs = 0;
    311  1.13.2.2  bouyer 		for (irq = 0; irq < ICU_LEN; irq++)
    312  1.13.2.2  bouyer 			if (intrhand[irq])
    313  1.13.2.2  bouyer 				irqs |= 1 << irq;
    314  1.13.2.2  bouyer 		if (irqs >= 0x100) /* any IRQs >= 8 in use */
    315  1.13.2.2  bouyer 			irqs |= 1 << IRQ_SLAVE;
    316  1.13.2.2  bouyer 		imen = ~irqs;
    317  1.13.2.2  bouyer 		isa_outb(IO_ICU1 + 1, imen);
    318  1.13.2.2  bouyer 		isa_outb(IO_ICU2 + 1, imen >> 8);
    319  1.13.2.2  bouyer 	}
    320  1.13.2.2  bouyer }
    321  1.13.2.2  bouyer 
    322  1.13.2.2  bouyer void
    323  1.13.2.2  bouyer isabr_attach_hook(parent, self, iba)
    324  1.13.2.2  bouyer 	struct device *parent, *self;
    325  1.13.2.2  bouyer 	struct isabus_attach_args *iba;
    326  1.13.2.2  bouyer {
    327  1.13.2.2  bouyer 
    328  1.13.2.2  bouyer 	/* Nothing to do. */
    329  1.13.2.2  bouyer }
    330  1.13.2.2  bouyer 
    331  1.13.2.2  bouyer const struct evcnt *
    332  1.13.2.2  bouyer isabr_intr_evcnt(ic, irq)
    333  1.13.2.2  bouyer 	isa_chipset_tag_t ic;
    334  1.13.2.2  bouyer 	int irq;
    335  1.13.2.2  bouyer {
    336  1.13.2.2  bouyer 
    337  1.13.2.2  bouyer 	/* XXX for now, no evcnt parent reported */
    338  1.13.2.2  bouyer 	return NULL;
    339  1.13.2.2  bouyer }
    340  1.13.2.2  bouyer 
    341  1.13.2.2  bouyer /*
    342  1.13.2.2  bouyer  *	Establish a ISA bus interrupt.
    343  1.13.2.2  bouyer  */
    344  1.13.2.2  bouyer void *
    345  1.13.2.2  bouyer isabr_intr_establish(ic, irq, type, level, ih_fun, ih_arg)
    346  1.13.2.2  bouyer         isa_chipset_tag_t ic;
    347  1.13.2.2  bouyer         int irq;
    348  1.13.2.2  bouyer         int type;
    349  1.13.2.2  bouyer         int level;
    350  1.13.2.2  bouyer         int (*ih_fun) __P((void *));
    351  1.13.2.2  bouyer         void *ih_arg;
    352  1.13.2.2  bouyer {
    353  1.13.2.2  bouyer 	struct intrhand **p, *q, *ih;
    354  1.13.2.2  bouyer 	static struct intrhand fakehand = {NULL, fakeintr};
    355  1.13.2.2  bouyer 	extern int cold;
    356  1.13.2.2  bouyer 
    357  1.13.2.2  bouyer 	/* no point in sleeping unless someone can free memory. */
    358  1.13.2.2  bouyer 	ih = malloc(sizeof *ih, M_DEVBUF, cold ? M_NOWAIT : M_WAITOK);
    359  1.13.2.2  bouyer 	if (ih == NULL)
    360  1.13.2.2  bouyer 		panic("isa_intr_establish: can't malloc handler info");
    361  1.13.2.2  bouyer 
    362  1.13.2.2  bouyer 	if (!LEGAL_IRQ(irq) || type == IST_NONE)
    363  1.13.2.2  bouyer 		panic("intr_establish: bogus irq or type");
    364  1.13.2.2  bouyer 
    365  1.13.2.2  bouyer 	switch (intrtype[irq]) {
    366  1.13.2.2  bouyer 	case IST_EDGE:
    367  1.13.2.2  bouyer 	case IST_LEVEL:
    368  1.13.2.2  bouyer 		if (type == intrtype[irq])
    369  1.13.2.2  bouyer 			break;
    370  1.13.2.2  bouyer 	case IST_PULSE:
    371  1.13.2.2  bouyer 		if (type != IST_NONE)
    372  1.13.2.2  bouyer 			panic("intr_establish: can't share %s with %s",
    373  1.13.2.2  bouyer 			    isa_intr_typename(intrtype[irq]),
    374  1.13.2.2  bouyer 			    isa_intr_typename(type));
    375  1.13.2.2  bouyer 		break;
    376  1.13.2.2  bouyer 	}
    377  1.13.2.2  bouyer 
    378  1.13.2.2  bouyer 	/*
    379  1.13.2.2  bouyer 	 * Figure out where to put the handler.
    380  1.13.2.2  bouyer 	 * This is O(N^2), but we want to preserve the order, and N is
    381  1.13.2.2  bouyer 	 * generally small.
    382  1.13.2.2  bouyer 	 */
    383  1.13.2.2  bouyer 	for (p = &intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
    384  1.13.2.2  bouyer 		;
    385  1.13.2.2  bouyer 
    386  1.13.2.2  bouyer 	/*
    387  1.13.2.2  bouyer 	 * Actually install a fake handler momentarily, since we might be doing
    388  1.13.2.2  bouyer 	 * this with interrupts enabled and don't want the real routine called
    389  1.13.2.2  bouyer 	 * until masking is set up.
    390  1.13.2.2  bouyer 	 */
    391  1.13.2.2  bouyer 	fakehand.ih_level = level;
    392  1.13.2.2  bouyer 	*p = &fakehand;
    393  1.13.2.2  bouyer 
    394  1.13.2.2  bouyer 	intr_calculatemasks();
    395  1.13.2.2  bouyer 
    396  1.13.2.2  bouyer 	/*
    397  1.13.2.2  bouyer 	 * Poke the real handler in now.
    398  1.13.2.2  bouyer 	 */
    399  1.13.2.2  bouyer 	ih->ih_fun = ih_fun;
    400  1.13.2.2  bouyer 	ih->ih_arg = ih_arg;
    401  1.13.2.2  bouyer 	ih->ih_count = 0;
    402  1.13.2.2  bouyer 	ih->ih_next = NULL;
    403  1.13.2.2  bouyer 	ih->ih_level = level;
    404  1.13.2.2  bouyer 	ih->ih_irq = irq;
    405  1.13.2.2  bouyer 	ih->ih_what = ""; /* XXX - should be eliminated */
    406  1.13.2.2  bouyer 	*p = ih;
    407  1.13.2.2  bouyer 
    408  1.13.2.2  bouyer 	return (ih);
    409  1.13.2.2  bouyer }
    410  1.13.2.2  bouyer 
    411  1.13.2.2  bouyer void
    412  1.13.2.2  bouyer isabr_intr_disestablish(ic, arg)
    413  1.13.2.2  bouyer         isa_chipset_tag_t ic;
    414  1.13.2.2  bouyer         void *arg;
    415  1.13.2.2  bouyer {
    416  1.13.2.2  bouyer 
    417  1.13.2.2  bouyer }
    418  1.13.2.2  bouyer 
    419  1.13.2.2  bouyer /*
    420  1.13.2.2  bouyer  *	Process an interrupt from the ISA bus.
    421  1.13.2.2  bouyer  */
    422  1.13.2.2  bouyer int
    423  1.13.2.2  bouyer isabr_iointr(mask, cf)
    424  1.13.2.2  bouyer         unsigned mask;
    425  1.13.2.2  bouyer         struct clockframe *cf;
    426  1.13.2.2  bouyer {
    427  1.13.2.2  bouyer 	struct intrhand *ih;
    428  1.13.2.2  bouyer 	int isa_vector;
    429  1.13.2.2  bouyer 	int o_imen;
    430  1.13.2.2  bouyer 	char vector;
    431  1.13.2.2  bouyer 
    432  1.13.2.2  bouyer 	(void) &isa_vector;	/* shut off gcc unused-variable warnings */
    433  1.13.2.2  bouyer 
    434  1.13.2.2  bouyer 	switch(cputype) {
    435  1.13.2.2  bouyer 	case ACER_PICA_61:
    436  1.13.2.2  bouyer 	case MAGNUM:
    437  1.13.2.2  bouyer 		isa_vector = in32(R4030_SYS_ISA_VECTOR) & (ICU_LEN - 1);
    438  1.13.2.2  bouyer 		break;
    439  1.13.2.2  bouyer 
    440  1.13.2.2  bouyer 	case NEC_R94:
    441  1.13.2.2  bouyer 	case NEC_R96:
    442  1.13.2.2  bouyer 		isa_vector = in32(RD94_SYS_INTSTAT2) & (ICU_LEN - 1);
    443  1.13.2.2  bouyer 		break;
    444  1.13.2.2  bouyer 
    445  1.13.2.2  bouyer 	case DESKSTATION_TYNE:
    446  1.13.2.2  bouyer 		isa_outb(IO_ICU1, 0x0f);	/* Poll */
    447  1.13.2.2  bouyer 		vector = isa_inb(IO_ICU1);
    448  1.13.2.2  bouyer 		if(vector > 0 || (isa_vector = vector & 7) == 2) {
    449  1.13.2.2  bouyer 			isa_outb(IO_ICU2, 0x0f);
    450  1.13.2.2  bouyer 			vector = isa_inb(IO_ICU2);
    451  1.13.2.2  bouyer 			if(vector > 0) {
    452  1.13.2.2  bouyer 				printf("isa: spurious interrupt.\n");
    453  1.13.2.2  bouyer 				return(~0);
    454  1.13.2.2  bouyer 			}
    455  1.13.2.2  bouyer 			isa_vector = (vector & 7) | 8;
    456  1.13.2.2  bouyer 		}
    457  1.13.2.2  bouyer 		break;
    458  1.13.2.2  bouyer 
    459  1.13.2.2  bouyer 	case DESKSTATION_RPC44:
    460  1.13.2.2  bouyer 		isa_outb(IO_ICU1, 0x0f);	/* Poll */
    461  1.13.2.2  bouyer 		vector = isa_inb(IO_ICU1);
    462  1.13.2.2  bouyer 		if(vector > 0 || (isa_vector = vector & 7) == 2) {
    463  1.13.2.2  bouyer 			isa_outb(IO_ICU2, 0x0f);
    464  1.13.2.2  bouyer 			vector = isa_inb(IO_ICU2);
    465  1.13.2.2  bouyer 			if(vector > 0) {
    466  1.13.2.2  bouyer 				printf("isa: spurious interrupt.\n");
    467  1.13.2.2  bouyer 				return(~0);
    468  1.13.2.2  bouyer 			}
    469  1.13.2.2  bouyer 			isa_vector = (vector & 7) | 8;
    470  1.13.2.2  bouyer 		}
    471  1.13.2.2  bouyer 		break;
    472  1.13.2.2  bouyer 	}
    473  1.13.2.2  bouyer 
    474  1.13.2.2  bouyer 	o_imen = imen;
    475  1.13.2.2  bouyer 	imen |= 1 << (isa_vector & (ICU_LEN - 1));
    476  1.13.2.2  bouyer 	if(isa_vector & 0x08) {
    477  1.13.2.2  bouyer 		isa_inb(IO_ICU2 + 1);
    478  1.13.2.2  bouyer 		isa_outb(IO_ICU2 + 1, imen >> 8);
    479  1.13.2.2  bouyer 		isa_outb(IO_ICU2, 0x60 + (isa_vector & 7));
    480  1.13.2.2  bouyer 		isa_outb(IO_ICU1, 0x60 + IRQ_SLAVE);
    481  1.13.2.2  bouyer 	}
    482  1.13.2.2  bouyer 	else {
    483  1.13.2.2  bouyer 		isa_inb(IO_ICU1 + 1);
    484  1.13.2.2  bouyer 		isa_outb(IO_ICU1 + 1, imen);
    485  1.13.2.2  bouyer 		isa_outb(IO_ICU1, 0x60 + isa_vector);
    486  1.13.2.2  bouyer 	}
    487  1.13.2.2  bouyer 	ih = intrhand[isa_vector];
    488  1.13.2.2  bouyer 	if(isa_vector == 0) {	/* Clock */	/*XXX*/
    489  1.13.2.2  bouyer 		(*ih->ih_fun)(cf);
    490  1.13.2.2  bouyer 		ih = ih->ih_next;
    491  1.13.2.2  bouyer 	}
    492  1.13.2.2  bouyer 	while(ih) {
    493  1.13.2.2  bouyer 		(*ih->ih_fun)(ih->ih_arg);
    494  1.13.2.2  bouyer 		ih = ih->ih_next;
    495  1.13.2.2  bouyer 	}
    496  1.13.2.2  bouyer 	imen = o_imen;
    497  1.13.2.2  bouyer 	isa_inb(IO_ICU1 + 1);
    498  1.13.2.2  bouyer 	isa_inb(IO_ICU2 + 1);
    499  1.13.2.2  bouyer 	isa_outb(IO_ICU1 + 1, imen);
    500  1.13.2.2  bouyer 	isa_outb(IO_ICU2 + 1, imen >> 8);
    501  1.13.2.2  bouyer 
    502  1.13.2.2  bouyer 	return(~0);  /* Dont reenable */
    503  1.13.2.2  bouyer }
    504  1.13.2.2  bouyer 
    505  1.13.2.2  bouyer 
    506  1.13.2.2  bouyer /*
    507  1.13.2.2  bouyer  * Initialize the Interrupt controller logic.
    508  1.13.2.2  bouyer  */
    509  1.13.2.2  bouyer void
    510  1.13.2.2  bouyer isabr_initicu()
    511  1.13.2.2  bouyer {
    512  1.13.2.2  bouyer 
    513  1.13.2.2  bouyer 	isa_outb(IO_ICU1, 0x11);		/* reset; program device, four bytes */
    514  1.13.2.2  bouyer 	isa_outb(IO_ICU1+1, 0);			/* starting at this vector index */
    515  1.13.2.2  bouyer 	isa_outb(IO_ICU1+1, 1 << IRQ_SLAVE);	/* slave on line 2 */
    516  1.13.2.2  bouyer 	isa_outb(IO_ICU1+1, 1);			/* 8086 mode */
    517  1.13.2.2  bouyer 	isa_outb(IO_ICU1+1, 0xff);		/* leave interrupts masked */
    518  1.13.2.2  bouyer 	isa_outb(IO_ICU1, 0x68);		/* special mask mode (if available) */
    519  1.13.2.2  bouyer 	isa_outb(IO_ICU1, 0x0a);		/* Read IRR by default. */
    520  1.13.2.2  bouyer #ifdef REORDER_IRQ
    521  1.13.2.2  bouyer 	isa_outb(IO_ICU1, 0xc0 | (3 - 1));	/* pri order 3-7, 0-2 (com2 first) */
    522  1.13.2.2  bouyer #endif
    523  1.13.2.2  bouyer 
    524  1.13.2.2  bouyer 	isa_outb(IO_ICU2, 0x11);		/* reset; program device, four bytes */
    525  1.13.2.2  bouyer 	isa_outb(IO_ICU2+1, 8);			/* staring at this vector index */
    526  1.13.2.2  bouyer 	isa_outb(IO_ICU2+1, IRQ_SLAVE);
    527  1.13.2.2  bouyer 	isa_outb(IO_ICU2+1, 1);			/* 8086 mode */
    528  1.13.2.2  bouyer 	isa_outb(IO_ICU2+1, 0xff);		/* leave interrupts masked */
    529  1.13.2.2  bouyer 	isa_outb(IO_ICU2, 0x68);		/* special mask mode (if available) */
    530  1.13.2.2  bouyer 	isa_outb(IO_ICU2, 0x0a);		/* Read IRR by default. */
    531  1.13.2.2  bouyer }
    532  1.13.2.2  bouyer 
    533  1.13.2.2  bouyer 
    534  1.13.2.2  bouyer /*
    535  1.13.2.2  bouyer  *	SPEAKER BEEPER...
    536  1.13.2.2  bouyer  */
    537  1.13.2.2  bouyer void
    538  1.13.2.2  bouyer sysbeepstop(arg)
    539  1.13.2.2  bouyer 	void *arg;
    540  1.13.2.2  bouyer {
    541  1.13.2.2  bouyer 	int s;
    542  1.13.2.2  bouyer 
    543  1.13.2.2  bouyer 	/* disable counter 2 */
    544  1.13.2.2  bouyer 	s = splhigh();
    545  1.13.2.2  bouyer 	isa_outb(PITAUX_PORT, isa_inb(PITAUX_PORT) & ~PIT_SPKR);
    546  1.13.2.2  bouyer 	splx(s);
    547  1.13.2.2  bouyer 	beeping = 0;
    548  1.13.2.2  bouyer }
    549  1.13.2.2  bouyer 
    550  1.13.2.2  bouyer void
    551  1.13.2.2  bouyer sysbeep(pitch, period)
    552  1.13.2.2  bouyer 	int pitch, period;
    553  1.13.2.2  bouyer {
    554  1.13.2.2  bouyer 	static int last_pitch, last_period;
    555  1.13.2.2  bouyer 	int s;
    556  1.13.2.2  bouyer 	extern int cold;
    557  1.13.2.2  bouyer 
    558  1.13.2.2  bouyer 	if (cold)
    559  1.13.2.2  bouyer 		return;		/* Can't beep yet. */
    560  1.13.2.2  bouyer 
    561  1.13.2.2  bouyer 	if (beeping)
    562  1.13.2.2  bouyer 		callout_stop(&sysbeep_ch);
    563  1.13.2.2  bouyer 	if (!beeping || last_pitch != pitch) {
    564  1.13.2.2  bouyer 		s = splhigh();
    565  1.13.2.2  bouyer 		isa_outb(IO_TIMER1 + TIMER_MODE,
    566  1.13.2.2  bouyer 		    TIMER_SEL2 | TIMER_16BIT | TIMER_SQWAVE);
    567  1.13.2.2  bouyer 		isa_outb(IO_TIMER1 + TIMER_CNTR2, TIMER_DIV(pitch) % 256);
    568  1.13.2.2  bouyer 		isa_outb(IO_TIMER1 + TIMER_CNTR2, TIMER_DIV(pitch) / 256);
    569  1.13.2.2  bouyer 		isa_outb(PITAUX_PORT, isa_inb(PITAUX_PORT) | PIT_SPKR);
    570  1.13.2.2  bouyer 		splx(s);
    571  1.13.2.2  bouyer 	}
    572  1.13.2.2  bouyer 	last_pitch = pitch;
    573  1.13.2.2  bouyer 	beeping = last_period = period;
    574  1.13.2.2  bouyer 	callout_reset(&sysbeep_ch, period, sysbeepstop, NULL);
    575  1.13.2.2  bouyer }
    576