Home | History | Annotate | Line # | Download | only in dev
crime.c revision 1.16
      1 /*	$NetBSD: crime.c,v 1.16 2004/01/13 14:31:37 sekiya 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.16 2004/01/13 14:31:37 sekiya 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 #include <machine/sysconf.h>
     53 
     54 #include <sgimips/dev/crimevar.h>
     55 #include <sgimips/dev/crimereg.h>
     56 
     57 #include "locators.h"
     58 
     59 static int	crime_match(struct device *, struct cfdata *, void *);
     60 static void	crime_attach(struct device *, struct device *, void *);
     61 void		crime_watchdog_tickle(void);
     62 
     63 struct crime_softc *crime_sc; /* only one per machine, okay to be global */
     64 
     65 CFATTACH_DECL(crime, sizeof(struct crime_softc),
     66     crime_match, crime_attach, NULL, NULL);
     67 
     68 #define CRIME_NINTR 32 	/* XXX */
     69 
     70 struct {
     71 	int	(*func)(void *);
     72 	void	*arg;
     73 } crime[CRIME_NINTR];
     74 
     75 static int
     76 crime_match(parent, match, aux)
     77 	struct device *parent;
     78 	struct cfdata *match;
     79 	void *aux;
     80 {
     81 
     82 	/*
     83 	 * The CRIME is in the O2.
     84 	 */
     85 	if (mach_type == MACH_SGI_IP32)
     86 		return (1);
     87 
     88 	return (0);
     89 }
     90 
     91 static void
     92 crime_attach(parent, self, aux)
     93 	struct device *parent;
     94 	struct device *self;
     95 	void *aux;
     96 {
     97 	struct crime_softc *sc = (struct crime_softc *)self;
     98 	struct mainbus_attach_args *ma = aux;
     99 	u_int64_t crm_id;
    100 
    101 	crime_sc = sc;
    102 
    103 	sc->iot = SGIMIPS_BUS_SPACE_CRIME;
    104 
    105 	if (bus_space_map(sc->iot, ma->ma_addr, 0 /* XXX */,
    106 	    BUS_SPACE_MAP_LINEAR, &sc->ioh))
    107 		panic("crime_attach: can't map I/O space");
    108 
    109 	crm_id = bus_space_read_8(sc->iot, sc->ioh, CRIME_REV);
    110 
    111 	aprint_naive(": system ASIC");
    112 
    113 	switch ((crm_id & CRIME_ID_IDBITS) >> CRIME_ID_IDSHIFT) {
    114 	case 0x0b:
    115 		aprint_normal(": rev 1.5");
    116 		break;
    117 
    118 	case 0x0a:
    119 		if ((crm_id >> 32) == 0)
    120 			aprint_normal(": rev 1.1");
    121 		else if ((crm_id >> 32) == 1)
    122 			aprint_normal(": rev 1.3");
    123 		else
    124 			aprint_normal(": rev 1.4");
    125 		break;
    126 
    127 	case 0x00:
    128 		aprint_normal(": Petty CRIME");
    129 		break;
    130 
    131 	default:
    132 		aprint_normal(": Unknown CRIME");
    133 		break;
    134 	}
    135 
    136 	aprint_normal(" (CRIME_ID: %llx)\n", crm_id);
    137 
    138 	/* Turn on memory error and crime error interrupts.
    139 	   All others turned on as devices are registered. */
    140 	bus_space_write_8(sc->iot, sc->ioh, CRIME_INTMASK,
    141 	    CRIME_INT_MEMERR |
    142 	    CRIME_INT_CRMERR |
    143 	    CRIME_INT_VICE |
    144 	    CRIME_INT_VID_OUT |
    145 	    CRIME_INT_VID_IN2 |
    146 	    CRIME_INT_VID_IN1);
    147 	bus_space_write_8(sc->iot, sc->ioh, CRIME_INTSTAT, 0);
    148 	bus_space_write_8(sc->iot, sc->ioh, CRIME_SOFTINT, 0);
    149 	bus_space_write_8(sc->iot, sc->ioh, CRIME_HARDINT, 0);
    150 
    151 	platform.watchdog_reset = crime_watchdog_tickle;
    152 }
    153 
    154 /*
    155  * XXX: sharing interrupts?
    156  */
    157 
    158 void *
    159 crime_intr_establish(irq, type, level, func, arg)
    160 	int irq;
    161 	int type;
    162 	int level;
    163 	int (*func)(void *);
    164 	void *arg;
    165 {
    166 	if (crime[irq].func != NULL)
    167 		return NULL;	/* panic("Cannot share CRIME interrupts!"); */
    168 
    169 	crime[irq].func = func;
    170 	crime[irq].arg = arg;
    171 
    172 	crime_intr_mask(irq);
    173 
    174 	return (void *)&crime[irq];
    175 }
    176 
    177 void
    178 crime_intr(pendmask)
    179 	u_int pendmask;
    180 {
    181 	int i;
    182 
    183 	for (i = 0; i < CRIME_NINTR; i++) {
    184 		if ((pendmask & (1 << i)) && crime[i].func != NULL)
    185 			(*crime[i].func)(crime[i].arg);
    186 	}
    187 }
    188 
    189 void
    190 crime_intr_mask(unsigned int intr)
    191 {
    192 	u_int64_t mask;
    193 
    194 	mask = bus_space_read_8(crime_sc->iot, crime_sc->ioh, CRIME_INTMASK);
    195 	mask |= (1 << intr);
    196 	bus_space_write_8(crime_sc->iot, crime_sc->ioh, CRIME_INTMASK, mask);
    197 }
    198 
    199 void
    200 crime_watchdog_tickle(void)
    201 {
    202 	/* enable watchdog timer, clear it */
    203 	bus_space_write_8(crime_sc->iot, crime_sc->ioh,
    204 		CRIME_CONTROL, CRIME_CONTROL_DOG_ENABLE);
    205 	bus_space_write_8(crime_sc->iot, crime_sc->ioh, CRIME_WATCHDOG, 0);
    206 }
    207 
    208