1 /* $NetBSD: ioasic.c,v 1.13 2000/06/04 19:14:55 cgd Exp $ */ 2 3 /* 4 * Copyright (c) 1994, 1995 Carnegie-Mellon University. 5 * All rights reserved. 6 * 7 * Author: Keith Bostic, Chris G. Demetriou, Jonathan Stone 8 * 9 * Permission to use, copy, modify and distribute this software and 10 * its documentation is hereby granted, provided that both the copyright 11 * notice and this permission notice appear in all copies of the 12 * software, derivative works or modified versions, and any portions 13 * thereof, and that both notices appear in supporting documentation. 14 * 15 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 16 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 17 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 18 * 19 * Carnegie Mellon requests users of this software to return to 20 * 21 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 22 * School of Computer Science 23 * Carnegie Mellon University 24 * Pittsburgh PA 15213-3890 25 * 26 * any improvements or extensions that they make and grant Carnegie the 27 * rights to redistribute these changes. 28 */ 29 30 #include <sys/cdefs.h> /* RCS ID & Copyright macro defns */ 31 __KERNEL_RCSID(0, "$NetBSD: ioasic.c,v 1.13 2000/06/04 19:14:55 cgd Exp $"); 32 33 #include <sys/param.h> 34 #include <sys/systm.h> 35 #include <sys/device.h> 36 37 #include <dev/tc/tcvar.h> 38 #include <dev/tc/ioasicreg.h> 39 #include <dev/tc/ioasicvar.h> 40 41 #include <machine/sysconf.h> 42 43 #include <pmax/pmax/pmaxtype.h> 44 #include <pmax/pmax/kmin.h> 45 #include <pmax/pmax/maxine.h> 46 #include <pmax/pmax/kn03.h> 47 48 #include "opt_dec_3min.h" 49 #include "opt_dec_maxine.h" 50 #include "opt_dec_3maxplus.h" 51 52 #define ARRAY_SIZEOF(x) (sizeof((x)) / sizeof((x)[0])) 53 54 #if defined(DEC_3MIN) 55 static struct ioasic_dev kmin_ioasic_devs[] = { 56 { "lance", 0x0C0000, C(SYS_DEV_LANCE), IOASIC_INTR_LANCE, }, 57 { "scc", 0x100000, C(SYS_DEV_SCC0), IOASIC_INTR_SCC_0, }, 58 { "scc", 0x180000, C(SYS_DEV_SCC1), IOASIC_INTR_SCC_1, }, 59 { "mc146818", 0x200000, C(SYS_DEV_BOGUS), 0 }, 60 { "asc", 0x300000, C(SYS_DEV_SCSI), IOASIC_INTR_SCSI, }, 61 }; 62 static int kmin_builtin_ndevs = ARRAY_SIZEOF(kmin_ioasic_devs); 63 static int kmin_ioasic_ndevs = ARRAY_SIZEOF(kmin_ioasic_devs); 64 #endif 65 66 #if defined(DEC_MAXINE) 67 static struct ioasic_dev xine_ioasic_devs[] = { 68 { "lance", 0x0C0000, C(SYS_DEV_LANCE), IOASIC_INTR_LANCE }, 69 { "scc", 0x100000, C(SYS_DEV_SCC0), IOASIC_INTR_SCC_0 }, 70 { "mc146818", 0x200000, C(SYS_DEV_BOGUS), 0 }, 71 { "isdn", 0x240000, C(SYS_DEV_ISDN), XINE_INTR_ISDN, }, 72 { "dtop", 0x280000, C(SYS_DEV_DTOP), XINE_INTR_DTOP, }, 73 { "fdc", 0x2C0000, C(SYS_DEV_FDC), 0 }, 74 { "asc", 0x300000, C(SYS_DEV_SCSI), IOASIC_INTR_SCSI, }, 75 { "(TC0)", 0x0, C(SYS_DEV_OPT0), XINE_INTR_TC_0, }, 76 { "(TC1)", 0x0, C(SYS_DEV_OPT1), XINE_INTR_TC_1, }, 77 { "(TC2)", 0x0, C(SYS_DEV_OPT2), XINE_INTR_VINT, }, 78 }; 79 static int xine_builtin_ndevs = ARRAY_SIZEOF(xine_ioasic_devs) - 3; 80 static int xine_ioasic_ndevs = ARRAY_SIZEOF(xine_ioasic_devs); 81 #endif 82 83 #if defined(DEC_3MAXPLUS) 84 static struct ioasic_dev kn03_ioasic_devs[] = { 85 { "lance", 0x0C0000, C(SYS_DEV_LANCE), IOASIC_INTR_LANCE, }, 86 { "z8530 ", 0x100000, C(SYS_DEV_SCC0), IOASIC_INTR_SCC_0, }, 87 { "z8530 ", 0x180000, C(SYS_DEV_SCC1), IOASIC_INTR_SCC_1, }, 88 { "mc146818", 0x200000, C(SYS_DEV_BOGUS), 0, }, 89 { "asc", 0x300000, C(SYS_DEV_SCSI), IOASIC_INTR_SCSI, }, 90 { "(TC0)", 0x0, C(SYS_DEV_OPT0), KN03_INTR_TC_0, }, 91 { "(TC1)", 0x0, C(SYS_DEV_OPT1), KN03_INTR_TC_1, }, 92 { "(TC2)", 0x0, C(SYS_DEV_OPT2), KN03_INTR_TC_2, }, 93 }; 94 static int kn03_builtin_ndevs = ARRAY_SIZEOF(kn03_ioasic_devs) - 3; 95 static int kn03_ioasic_ndevs = ARRAY_SIZEOF(kn03_ioasic_devs); 96 #endif 97 98 static int ioasicmatch __P((struct device *, struct cfdata *, void *)); 99 static void ioasicattach __P((struct device *, struct device *, void *)); 100 101 const struct cfattach ioasic_ca = { 102 sizeof(struct ioasic_softc), ioasicmatch, ioasicattach 103 }; 104 105 tc_addr_t ioasic_base; /* XXX XXX XXX */ 106 107 /* There can be only one. */ 108 int ioasicfound; 109 110 static int 111 ioasicmatch(parent, cfdata, aux) 112 struct device *parent; 113 struct cfdata *cfdata; 114 void *aux; 115 { 116 struct tc_attach_args *ta = aux; 117 118 /* Make sure that we're looking for this type of device. */ 119 if (strncmp("IOCTL ", ta->ta_modname, TC_ROM_LLEN)) 120 return (0); 121 122 if (ioasicfound) 123 return (0); 124 125 return (1); 126 } 127 128 static void 129 ioasicattach(parent, self, aux) 130 struct device *parent, *self; 131 void *aux; 132 { 133 struct ioasic_softc *sc = (struct ioasic_softc *)self; 134 struct tc_attach_args *ta = aux; 135 struct ioasic_dev *ioasic_devs; 136 int ioasic_ndevs, builtin_ndevs; 137 int i, imsk; 138 139 ioasicfound = 1; 140 141 sc->sc_bst = ta->ta_memt; 142 if (bus_space_map(ta->ta_memt, ta->ta_addr, 143 0x400000, 0, &sc->sc_bsh)) { 144 printf("%s: unable to map device\n", sc->sc_dv.dv_xname); 145 return; 146 } 147 sc->sc_dmat = ta->ta_dmat; 148 149 sc->sc_base = ta->ta_addr; /* XXX XXX XXX */ 150 151 printf("\n"); 152 153 switch (systype) { 154 #if defined(DEC_3MIN) 155 case DS_3MIN: 156 ioasic_devs = kmin_ioasic_devs; 157 ioasic_ndevs = kmin_ioasic_ndevs; 158 builtin_ndevs = kmin_builtin_ndevs; 159 break; 160 #endif 161 #if defined(DEC_MAXINE) 162 case DS_MAXINE: 163 ioasic_devs = xine_ioasic_devs; 164 ioasic_ndevs = xine_ioasic_ndevs; 165 builtin_ndevs = xine_builtin_ndevs; 166 break; 167 #endif 168 #if defined(DEC_3MAXPLUS) 169 case DS_3MAXPLUS: 170 ioasic_devs = kn03_ioasic_devs; 171 ioasic_ndevs = kn03_ioasic_ndevs; 172 builtin_ndevs = kn03_builtin_ndevs; 173 break; 174 #endif 175 default: 176 panic("ioasicmatch: how did we get here?"); 177 } 178 179 /* 180 * Turn off all device interrupt bits. 181 * (This _does_ include TC option slot bits. 182 */ 183 imsk = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK); 184 for (i = 0; i < ioasic_ndevs; i++) 185 imsk &= ~ioasic_devs[i].iad_intrbits; 186 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, imsk); 187 188 /* 189 * Try to configure each device. 190 */ 191 ioasic_attach_devs(sc, ioasic_devs, builtin_ndevs); 192 } 193 194 const struct evcnt * 195 ioasic_intr_evcnt(dev, cookie) 196 struct device *dev; 197 void *cookie; 198 { 199 200 /* XXX for now, no evcnt parent reported */ 201 return NULL; 202 } 203 204 #if 1 /* XXX for now XXX */ 205 void 206 ioasic_intr_establish(dev, cookie, level, handler, val) 207 struct device *dev; 208 void *cookie; 209 int level; 210 int (*handler) __P((void *)); 211 void *val; 212 { 213 (*platform.intr_establish)(dev, cookie, level, handler, val); 214 } 215 216 #else /* XXX eventually XXX */ 217 218 void 219 ioasic_intr_establish(ioa, cookie, level, func, arg) 220 struct device *ioa; 221 void *cookie, *arg; 222 int level; 223 int (*func) __P((void *)); 224 { 225 struct ioasic_softc *sc = (void *)ioasic_cd.cd_devs[0]; 226 int i, intrbits; 227 228 for (i = 0; i < ioasic_ndevs; i++) { 229 if (ioasic_devs[i].iad_cookie == cookie) 230 goto found; 231 } 232 panic("ioasic_intr_establish: invalid cookie %d", (int)cookie); 233 found: 234 235 intrtab[(int)cookie].ih_func = func; 236 intrtab[(int)cookie].ih_arg = arg; 237 238 intrbits = ioasic_devs[i].iad_intrbits; 239 i = bus_space_read_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK); 240 i |= intrbits; 241 bus_space_write_4(sc->sc_bst, sc->sc_bsh, IOASIC_IMSK, i); 242 } 243 #endif 244