Home | History | Annotate | Line # | Download | only in dev
crime.c revision 1.14
      1 /*	$NetBSD: crime.c,v 1.14 2003/11/17 10:07:58 keihan Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2000 Soren S. Jorvang
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  * 1. Redistributions of source code must retain the above copyright
     11  *    notice, this list of conditions and the following disclaimer.
     12  * 2. Redistributions in binary form must reproduce the above copyright
     13  *    notice, this list of conditions and the following disclaimer in the
     14  *    documentation and/or other materials provided with the distribution.
     15  * 3. All advertising materials mentioning features or use of this software
     16  *    must display the following acknowledgement:
     17  *          This product includes software developed for the
     18  *          NetBSD Project.  See http://www.NetBSD.org/ for
     19  *          information about NetBSD.
     20  * 4. The name of the author may not be used to endorse or promote products
     21  *    derived from this software without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     24  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     25  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     28  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     32  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33  */
     34 
     35 /*
     36  * O2 CRIME
     37  */
     38 
     39 #include <sys/cdefs.h>
     40 __KERNEL_RCSID(0, "$NetBSD: crime.c,v 1.14 2003/11/17 10:07:58 keihan Exp $");
     41 
     42 #include <sys/param.h>
     43 #include <sys/device.h>
     44 #include <sys/systm.h>
     45 
     46 #include <machine/cpu.h>
     47 #include <machine/locore.h>
     48 #include <machine/autoconf.h>
     49 #include <machine/bus.h>
     50 #include <machine/intr.h>
     51 #include <machine/machtype.h>
     52 
     53 #include <sgimips/dev/crimevar.h>
     54 #include <sgimips/dev/crimereg.h>
     55 
     56 #include "locators.h"
     57 
     58 static int	crime_match(struct device *, struct cfdata *, void *);
     59 static void	crime_attach(struct device *, struct device *, void *);
     60 
     61 struct crime_softc *crime_sc; /* only one per machine, okay to be global */
     62 
     63 CFATTACH_DECL(crime, sizeof(struct crime_softc),
     64     crime_match, crime_attach, NULL, NULL);
     65 
     66 #define CRIME_NINTR 32 	/* XXX */
     67 
     68 struct {
     69 	int	(*func)(void *);
     70 	void	*arg;
     71 } crime[CRIME_NINTR];
     72 
     73 static int
     74 crime_match(parent, match, aux)
     75 	struct device *parent;
     76 	struct cfdata *match;
     77 	void *aux;
     78 {
     79 
     80 	/*
     81 	 * The CRIME is in the O2.
     82 	 */
     83 	if (mach_type == MACH_SGI_IP32)
     84 		return (1);
     85 
     86 	return (0);
     87 }
     88 
     89 static void
     90 crime_attach(parent, self, aux)
     91 	struct device *parent;
     92 	struct device *self;
     93 	void *aux;
     94 {
     95 	struct crime_softc *sc = (struct crime_softc *)self;
     96 	struct mainbus_attach_args *ma = aux;
     97 	u_int64_t crm_id;
     98 
     99 	crime_sc = sc;
    100 
    101 	sc->iot = SGIMIPS_BUS_SPACE_HPC;
    102 
    103 	if (bus_space_map(sc->iot, ma->ma_addr, 0 /* XXX */,
    104 	    BUS_SPACE_MAP_LINEAR, &sc->ioh))
    105 		panic("crime_attach: can't map I/O space");
    106 
    107 	crm_id = bus_space_read_8(sc->iot, sc->ioh, CRIME_REV);
    108 
    109 	aprint_naive(": system ASIC");
    110 
    111 	switch ((crm_id & CRIME_ID_IDBITS) >> CRIME_ID_IDSHIFT) {
    112 	case 0x0b:
    113 		aprint_normal(": rev 1.5");
    114 		break;
    115 
    116 	case 0x0a:
    117 		if ((crm_id >> 32) == 0)
    118 			aprint_normal(": rev 1.1");
    119 		else if ((crm_id >> 32) == 1)
    120 			aprint_normal(": rev 1.3");
    121 		else
    122 			aprint_normal(": rev 1.4");
    123 		break;
    124 
    125 	case 0x00:
    126 		aprint_normal(": Petty CRIME");
    127 		break;
    128 
    129 	default:
    130 		aprint_normal(": Unknown CRIME");
    131 		break;
    132 	}
    133 
    134 	aprint_normal(" (CRIME_ID: %llx)\n", crm_id);
    135 
    136 	/* Turn on memory error and crime error interrupts.
    137 	   All others turned on as devices are registered. */
    138 	bus_space_write_8(sc->iot, sc->ioh, CRIME_INTMASK,
    139 	    CRIME_INT_MEMERR |
    140 	    CRIME_INT_CRMERR |
    141 	    CRIME_INT_VICE |
    142 	    CRIME_INT_VID_OUT |
    143 	    CRIME_INT_VID_IN2 |
    144 	    CRIME_INT_VID_IN1);
    145 	bus_space_write_8(sc->iot, sc->ioh, CRIME_INTSTAT, 0);
    146 	bus_space_write_8(sc->iot, sc->ioh, CRIME_SOFTINT, 0);
    147 	bus_space_write_8(sc->iot, sc->ioh, CRIME_HARDINT, 0);
    148 }
    149 
    150 /*
    151  * XXX: sharing interrupts?
    152  */
    153 
    154 void *
    155 crime_intr_establish(irq, type, level, func, arg)
    156 	int irq;
    157 	int type;
    158 	int level;
    159 	int (*func)(void *);
    160 	void *arg;
    161 {
    162 	if (crime[irq].func != NULL)
    163 		return NULL;	/* panic("Cannot share CRIME interrupts!"); */
    164 
    165 	crime[irq].func = func;
    166 	crime[irq].arg = arg;
    167 
    168 	crime_intr_mask(irq);
    169 
    170 	return (void *)&crime[irq];
    171 }
    172 
    173 void
    174 crime_intr(pendmask)
    175 	u_int pendmask;
    176 {
    177 	int i;
    178 
    179 	for (i = 0; i < CRIME_NINTR; i++) {
    180 		if ((pendmask & (1 << i)) && crime[i].func != NULL)
    181 			(*crime[i].func)(crime[i].arg);
    182 	}
    183 }
    184 
    185 void
    186 crime_intr_mask(unsigned int intr)
    187 {
    188 	u_int64_t mask;
    189 
    190 	mask = bus_space_read_8(crime_sc->iot, crime_sc->ioh, CRIME_INTMASK);
    191 	mask |= (1 << intr);
    192 	bus_space_write_8(crime_sc->iot, crime_sc->ioh, CRIME_INTMASK, mask);
    193 }
    194