1 1.38 thorpej /* $NetBSD: gio.c,v 1.38 2021/08/07 16:19:04 thorpej Exp $ */ 2 1.1 soren 3 1.1 soren /* 4 1.1 soren * Copyright (c) 2000 Soren S. Jorvang 5 1.1 soren * All rights reserved. 6 1.2 simonb * 7 1.1 soren * Redistribution and use in source and binary forms, with or without 8 1.1 soren * modification, are permitted provided that the following conditions 9 1.1 soren * are met: 10 1.1 soren * 1. Redistributions of source code must retain the above copyright 11 1.1 soren * notice, this list of conditions and the following disclaimer. 12 1.1 soren * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 soren * notice, this list of conditions and the following disclaimer in the 14 1.1 soren * documentation and/or other materials provided with the distribution. 15 1.1 soren * 3. All advertising materials mentioning features or use of this software 16 1.1 soren * must display the following acknowledgement: 17 1.1 soren * This product includes software developed for the 18 1.11 keihan * NetBSD Project. See http://www.NetBSD.org/ for 19 1.1 soren * information about NetBSD. 20 1.1 soren * 4. The name of the author may not be used to endorse or promote products 21 1.1 soren * derived from this software without specific prior written permission. 22 1.2 simonb * 23 1.1 soren * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 1.1 soren * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 1.1 soren * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 1.1 soren * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 1.1 soren * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 1.1 soren * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 1.1 soren * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 1.1 soren * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 1.1 soren * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 1.1 soren * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 1.1 soren */ 34 1.10 lukem 35 1.10 lukem #include <sys/cdefs.h> 36 1.38 thorpej __KERNEL_RCSID(0, "$NetBSD: gio.c,v 1.38 2021/08/07 16:19:04 thorpej Exp $"); 37 1.1 soren 38 1.1 soren #include "opt_ddb.h" 39 1.1 soren 40 1.1 soren #include <sys/param.h> 41 1.1 soren #include <sys/systm.h> 42 1.1 soren #include <sys/device.h> 43 1.1 soren 44 1.32 dyoung #include <sys/bus.h> 45 1.22 rumble #include <machine/machtype.h> 46 1.26 rumble #include <machine/sysconf.h> 47 1.12 lonewolf 48 1.1 soren #include <sgimips/gio/gioreg.h> 49 1.1 soren #include <sgimips/gio/giovar.h> 50 1.14 sekiya #include <sgimips/gio/giodevs_data.h> 51 1.1 soren 52 1.1 soren #include "locators.h" 53 1.12 lonewolf #include "newport.h" 54 1.16 sekiya #include "grtwo.h" 55 1.24 rumble #include "light.h" 56 1.22 rumble #include "imc.h" 57 1.22 rumble #include "pic.h" 58 1.12 lonewolf 59 1.12 lonewolf #if (NNEWPORT > 0) 60 1.12 lonewolf #include <sgimips/gio/newportvar.h> 61 1.12 lonewolf #endif 62 1.1 soren 63 1.16 sekiya #if (NGRTWO > 0) 64 1.16 sekiya #include <sgimips/gio/grtwovar.h> 65 1.16 sekiya #endif 66 1.16 sekiya 67 1.25 rumble #if (NLIGHT > 0) 68 1.25 rumble #include <sgimips/gio/lightvar.h> 69 1.25 rumble #endif 70 1.25 rumble 71 1.22 rumble #if (NIMC > 0) 72 1.22 rumble extern int imc_gio64_arb_config(int, uint32_t); 73 1.22 rumble #endif 74 1.22 rumble 75 1.22 rumble #if (NPIC > 0) 76 1.22 rumble extern int pic_gio32_arb_config(int, uint32_t); 77 1.22 rumble #endif 78 1.22 rumble 79 1.22 rumble 80 1.33 chs static int gio_match(device_t, cfdata_t, void *); 81 1.33 chs static void gio_attach(device_t, device_t, void *); 82 1.1 soren static int gio_print(void *, const char *); 83 1.33 chs static int gio_search(device_t, cfdata_t, const int *, void *); 84 1.33 chs static int gio_submatch(device_t, cfdata_t, const int *, void *); 85 1.1 soren 86 1.33 chs CFATTACH_DECL_NEW(gio, 0, 87 1.7 thorpej gio_match, gio_attach, NULL, NULL); 88 1.1 soren 89 1.24 rumble struct gio_probe { 90 1.24 rumble uint32_t slot; 91 1.24 rumble uint32_t base; 92 1.24 rumble uint32_t mach_type; 93 1.24 rumble uint32_t mach_subtype; 94 1.12 lonewolf }; 95 1.12 lonewolf 96 1.24 rumble /* 97 1.24 rumble * Expansion Slot Base Addresses 98 1.24 rumble * 99 1.24 rumble * IP12, IP20 and IP24 have two GIO connectors: GIO_SLOT_EXP0 and 100 1.24 rumble * GIO_SLOT_EXP1. 101 1.24 rumble * 102 1.24 rumble * On IP24 these slots exist on the graphics board or the IOPLUS 103 1.24 rumble * "mezzanine" on Indy and Challenge S, respectively. The IOPLUS or 104 1.24 rumble * graphics board connects to the mainboard via a single GIO64 connector. 105 1.24 rumble * 106 1.24 rumble * IP22 has either three or four physical connectors, but only two 107 1.24 rumble * electrically distinct slots: GIO_SLOT_GFX and GIO_SLOT_EXP0. 108 1.24 rumble * 109 1.24 rumble * It should also be noted that DMA is (mostly) not supported in Challenge 110 1.24 rumble * S's GIO_SLOT_EXP1. See gio(4) for the story. 111 1.24 rumble */ 112 1.24 rumble static const struct gio_probe slot_bases[] = { 113 1.24 rumble { GIO_SLOT_GFX, 0x1f000000, MACH_SGI_IP22, MACH_SGI_IP22_FULLHOUSE }, 114 1.24 rumble 115 1.24 rumble { GIO_SLOT_EXP0, 0x1f400000, MACH_SGI_IP12, -1 }, 116 1.24 rumble { GIO_SLOT_EXP0, 0x1f400000, MACH_SGI_IP20, -1 }, 117 1.24 rumble { GIO_SLOT_EXP0, 0x1f400000, MACH_SGI_IP22, -1 }, 118 1.24 rumble 119 1.24 rumble { GIO_SLOT_EXP1, 0x1f600000, MACH_SGI_IP12, -1 }, 120 1.24 rumble { GIO_SLOT_EXP1, 0x1f600000, MACH_SGI_IP20, -1 }, 121 1.24 rumble { GIO_SLOT_EXP1, 0x1f600000, MACH_SGI_IP22, MACH_SGI_IP22_GUINNESS }, 122 1.24 rumble 123 1.24 rumble { 0, 0, 0, 0 } 124 1.24 rumble }; 125 1.24 rumble 126 1.24 rumble /* 127 1.24 rumble * Graphic Board Base Addresses 128 1.24 rumble * 129 1.24 rumble * Graphics boards are not treated like expansion slot cards. Their base 130 1.24 rumble * addresses do not necessarily correspond to GIO slot addresses and they 131 1.24 rumble * do not contain product identification words. 132 1.24 rumble */ 133 1.24 rumble static const struct gio_probe gfx_bases[] = { 134 1.24 rumble /* grtwo, and newport on IP22 */ 135 1.24 rumble { -1, 0x1f000000, MACH_SGI_IP12, -1 }, 136 1.24 rumble { -1, 0x1f000000, MACH_SGI_IP20, -1 }, 137 1.24 rumble { -1, 0x1f000000, MACH_SGI_IP22, -1 }, 138 1.24 rumble 139 1.24 rumble /* light */ 140 1.24 rumble { -1, 0x1f3f0000, MACH_SGI_IP12, -1 }, 141 1.24 rumble { -1, 0x1f3f0000, MACH_SGI_IP20, -1 }, 142 1.24 rumble 143 1.24 rumble /* light (dual headed) */ 144 1.24 rumble { -1, 0x1f3f8000, MACH_SGI_IP12, -1 }, 145 1.24 rumble { -1, 0x1f3f8000, MACH_SGI_IP20, -1 }, 146 1.24 rumble 147 1.24 rumble /* grtwo, and newport on IP22 */ 148 1.24 rumble { -1, 0x1f400000, MACH_SGI_IP12, -1 }, 149 1.24 rumble { -1, 0x1f400000, MACH_SGI_IP20, -1 }, 150 1.24 rumble { -1, 0x1f400000, MACH_SGI_IP22, -1 }, 151 1.24 rumble 152 1.24 rumble /* grtwo */ 153 1.24 rumble { -1, 0x1f600000, MACH_SGI_IP12, -1 }, 154 1.24 rumble { -1, 0x1f600000, MACH_SGI_IP20, -1 }, 155 1.24 rumble { -1, 0x1f600000, MACH_SGI_IP22, -1 }, 156 1.24 rumble 157 1.24 rumble /* newport */ 158 1.24 rumble { -1, 0x1f800000, MACH_SGI_IP22, MACH_SGI_IP22_FULLHOUSE }, 159 1.24 rumble 160 1.24 rumble /* newport */ 161 1.24 rumble { -1, 0x1fc00000, MACH_SGI_IP22, MACH_SGI_IP22_FULLHOUSE }, 162 1.24 rumble 163 1.24 rumble { 0, 0, 0, 0 } 164 1.24 rumble }; 165 1.24 rumble 166 1.24 rumble /* maximum number of graphics boards possible (arbitrarily large estimate) */ 167 1.24 rumble #define MAXGFX 8 168 1.24 rumble 169 1.1 soren static int 170 1.33 chs gio_match(device_t parent, cfdata_t match, void *aux) 171 1.1 soren { 172 1.30 rumble if (mach_type == MACH_SGI_IP12 || mach_type == MACH_SGI_IP20 || 173 1.30 rumble mach_type == MACH_SGI_IP22) 174 1.30 rumble return 1; 175 1.30 rumble 176 1.30 rumble return 0; 177 1.1 soren } 178 1.1 soren 179 1.1 soren static void 180 1.33 chs gio_attach(device_t parent, device_t self, void *aux) 181 1.1 soren { 182 1.1 soren struct gio_attach_args ga; 183 1.24 rumble uint32_t gfx[MAXGFX]; 184 1.24 rumble int i, j, ngfx; 185 1.1 soren 186 1.1 soren printf("\n"); 187 1.1 soren 188 1.24 rumble ngfx = 0; 189 1.24 rumble memset(gfx, 0, sizeof(gfx)); 190 1.24 rumble 191 1.24 rumble /* 192 1.24 rumble * Attach graphics devices first. They do not contain a Product 193 1.24 rumble * Identification Word and have no slot number. 194 1.24 rumble * 195 1.24 rumble * Record addresses to which graphics devices attach so that 196 1.24 rumble * we do not confuse them with expansion slots, should the 197 1.24 rumble * addresses coincide. 198 1.24 rumble */ 199 1.24 rumble for (i = 0; gfx_bases[i].base != 0; i++) { 200 1.24 rumble /* skip slots that don't apply to us */ 201 1.24 rumble if (gfx_bases[i].mach_type != mach_type) 202 1.24 rumble continue; 203 1.24 rumble 204 1.24 rumble if (gfx_bases[i].mach_subtype != -1 && 205 1.24 rumble gfx_bases[i].mach_subtype != mach_subtype) 206 1.24 rumble continue; 207 1.24 rumble 208 1.24 rumble ga.ga_slot = -1; 209 1.24 rumble ga.ga_addr = gfx_bases[i].base; 210 1.35 macallan /* XXX */ 211 1.35 macallan if (platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ga.ga_addr), 212 1.35 macallan sizeof(uint32_t))) 213 1.35 macallan continue; 214 1.34 macallan ga.ga_iot = normal_memt; 215 1.35 macallan if (bus_space_map(normal_memt, ga.ga_addr, 0, 216 1.35 macallan BUS_SPACE_MAP_LINEAR, &ga.ga_ioh) != 0) 217 1.35 macallan continue; 218 1.22 rumble ga.ga_dmat = &sgimips_default_bus_dma_tag; 219 1.24 rumble ga.ga_product = -1; 220 1.24 rumble 221 1.12 lonewolf 222 1.37 thorpej if (config_found(self, &ga, gio_print, 223 1.38 thorpej CFARGS(.submatch = gio_submatch)) != NULL) { 224 1.24 rumble if (ngfx == MAXGFX) 225 1.24 rumble panic("gio_attach: MAXGFX"); 226 1.24 rumble gfx[ngfx++] = gfx_bases[i].base; 227 1.24 rumble } 228 1.24 rumble } 229 1.24 rumble 230 1.24 rumble /* 231 1.24 rumble * Now attach any GIO expansion cards. 232 1.24 rumble * 233 1.24 rumble * Be sure to skip any addresses to which a graphics device has 234 1.24 rumble * already been attached. 235 1.24 rumble */ 236 1.24 rumble for (i = 0; slot_bases[i].base != 0; i++) { 237 1.29 thorpej bool skip = false; 238 1.24 rumble 239 1.24 rumble /* skip slots that don't apply to us */ 240 1.24 rumble if (slot_bases[i].mach_type != mach_type) 241 1.12 lonewolf continue; 242 1.24 rumble 243 1.24 rumble if (slot_bases[i].mach_subtype != -1 && 244 1.24 rumble slot_bases[i].mach_subtype != mach_subtype) 245 1.24 rumble continue; 246 1.24 rumble 247 1.24 rumble for (j = 0; j < ngfx; j++) { 248 1.24 rumble if (slot_bases[i].base == gfx[j]) { 249 1.29 thorpej skip = true; 250 1.24 rumble break; 251 1.24 rumble } 252 1.24 rumble } 253 1.24 rumble if (skip) 254 1.24 rumble continue; 255 1.24 rumble 256 1.24 rumble ga.ga_slot = slot_bases[i].slot; 257 1.24 rumble ga.ga_addr = slot_bases[i].base; 258 1.35 macallan /* XXX */ 259 1.35 macallan if (platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ga.ga_addr), 260 1.35 macallan sizeof(uint32_t))) 261 1.35 macallan continue; 262 1.34 macallan ga.ga_iot = normal_memt; 263 1.35 macallan if (bus_space_map(normal_memt, ga.ga_addr, 0, 264 1.35 macallan BUS_SPACE_MAP_LINEAR, &ga.ga_ioh) != 0) 265 1.35 macallan continue; 266 1.24 rumble ga.ga_dmat = &sgimips_default_bus_dma_tag; 267 1.24 rumble 268 1.12 lonewolf ga.ga_product = bus_space_read_4(ga.ga_iot, ga.ga_ioh, 0); 269 1.12 lonewolf 270 1.37 thorpej config_found(self, &ga, gio_print, 271 1.38 thorpej CFARGS(.submatch = gio_submatch)); 272 1.12 lonewolf } 273 1.12 lonewolf 274 1.37 thorpej config_search(self, &ga, 275 1.38 thorpej CFARGS(.search = gio_search)); 276 1.1 soren } 277 1.1 soren 278 1.1 soren static int 279 1.12 lonewolf gio_print(void *aux, const char *pnp) 280 1.1 soren { 281 1.1 soren struct gio_attach_args *ga = aux; 282 1.13 sekiya int i = 0; 283 1.1 soren 284 1.24 rumble /* gfx probe */ 285 1.24 rumble if (ga->ga_product == -1) 286 1.24 rumble return (QUIET); 287 1.24 rumble 288 1.12 lonewolf if (pnp != NULL) { 289 1.12 lonewolf int product, revision; 290 1.12 lonewolf 291 1.12 lonewolf product = GIO_PRODUCT_PRODUCTID(ga->ga_product); 292 1.12 lonewolf 293 1.12 lonewolf if (GIO_PRODUCT_32BIT_ID(ga->ga_product)) 294 1.12 lonewolf revision = GIO_PRODUCT_REVISION(ga->ga_product); 295 1.12 lonewolf else 296 1.12 lonewolf revision = 0; 297 1.12 lonewolf 298 1.13 sekiya while (gio_knowndevs[i].productid != 0) { 299 1.13 sekiya if (gio_knowndevs[i].productid == product) { 300 1.13 sekiya aprint_normal("%s", gio_knowndevs[i].product); 301 1.13 sekiya break; 302 1.13 sekiya } 303 1.13 sekiya i++; 304 1.13 sekiya } 305 1.13 sekiya 306 1.13 sekiya if (gio_knowndevs[i].productid == 0) 307 1.13 sekiya aprint_normal("unknown GIO card"); 308 1.13 sekiya 309 1.13 sekiya aprint_normal(" (product 0x%02x revision 0x%02x) at %s", 310 1.12 lonewolf product, revision, pnp); 311 1.12 lonewolf } 312 1.1 soren 313 1.1 soren if (ga->ga_slot != GIOCF_SLOT_DEFAULT) 314 1.9 thorpej aprint_normal(" slot %d", ga->ga_slot); 315 1.8 thorpej if (ga->ga_addr != (uint32_t) GIOCF_ADDR_DEFAULT) 316 1.9 thorpej aprint_normal(" addr 0x%x", ga->ga_addr); 317 1.1 soren 318 1.1 soren return UNCONF; 319 1.1 soren } 320 1.1 soren 321 1.1 soren static int 322 1.33 chs gio_search(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 323 1.2 simonb { 324 1.1 soren struct gio_attach_args *ga = aux; 325 1.1 soren 326 1.1 soren do { 327 1.12 lonewolf /* Handled by direct configuration, so skip here */ 328 1.12 lonewolf if (cf->cf_loc[GIOCF_ADDR] == GIOCF_ADDR_DEFAULT) 329 1.12 lonewolf return 0; 330 1.12 lonewolf 331 1.1 soren ga->ga_slot = cf->cf_loc[GIOCF_SLOT]; 332 1.1 soren ga->ga_addr = cf->cf_loc[GIOCF_ADDR]; 333 1.36 macallan ga->ga_iot = normal_memt; 334 1.1 soren ga->ga_ioh = MIPS_PHYS_TO_KSEG1(ga->ga_addr); 335 1.12 lonewolf 336 1.37 thorpej if (config_probe(parent, cf, ga)) 337 1.38 thorpej config_attach(parent, cf, ga, gio_print, CFARGS_NONE); 338 1.1 soren } while (cf->cf_fstate == FSTATE_STAR); 339 1.1 soren 340 1.1 soren return 0; 341 1.12 lonewolf } 342 1.12 lonewolf 343 1.12 lonewolf static int 344 1.33 chs gio_submatch(device_t parent, cfdata_t cf, const int *ldesc, void *aux) 345 1.12 lonewolf { 346 1.12 lonewolf struct gio_attach_args *ga = aux; 347 1.12 lonewolf 348 1.12 lonewolf if (cf->cf_loc[GIOCF_SLOT] != GIOCF_SLOT_DEFAULT && 349 1.12 lonewolf cf->cf_loc[GIOCF_SLOT] != ga->ga_slot) 350 1.12 lonewolf return 0; 351 1.12 lonewolf 352 1.12 lonewolf if (cf->cf_loc[GIOCF_ADDR] != GIOCF_ADDR_DEFAULT && 353 1.12 lonewolf cf->cf_loc[GIOCF_ADDR] != ga->ga_addr) 354 1.12 lonewolf return 0; 355 1.12 lonewolf 356 1.12 lonewolf return config_match(parent, cf, aux); 357 1.12 lonewolf } 358 1.12 lonewolf 359 1.12 lonewolf int 360 1.31 cegger gio_cnattach(void) 361 1.12 lonewolf { 362 1.12 lonewolf struct gio_attach_args ga; 363 1.12 lonewolf int i; 364 1.24 rumble 365 1.24 rumble for (i = 0; gfx_bases[i].base != 0; i++) { 366 1.24 rumble /* skip bases that don't apply to us */ 367 1.24 rumble if (gfx_bases[i].mach_type != mach_type) 368 1.24 rumble continue; 369 1.24 rumble 370 1.24 rumble if (gfx_bases[i].mach_subtype != -1 && 371 1.24 rumble gfx_bases[i].mach_subtype != mach_subtype) 372 1.12 lonewolf continue; 373 1.12 lonewolf 374 1.24 rumble ga.ga_slot = -1; 375 1.24 rumble ga.ga_addr = gfx_bases[i].base; 376 1.35 macallan /* XXX */ 377 1.35 macallan if (platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ga.ga_addr), 378 1.35 macallan sizeof(uint32_t))) 379 1.35 macallan continue; 380 1.34 macallan ga.ga_iot = normal_memt; 381 1.35 macallan if (bus_space_map(normal_memt, ga.ga_addr, 0, 382 1.35 macallan BUS_SPACE_MAP_LINEAR, &ga.ga_ioh) != 0) 383 1.35 macallan continue; 384 1.24 rumble ga.ga_dmat = &sgimips_default_bus_dma_tag; 385 1.24 rumble ga.ga_product = -1; 386 1.24 rumble 387 1.15 sekiya #if (NGRTWO > 0) 388 1.15 sekiya if (grtwo_cnattach(&ga) == 0) 389 1.15 sekiya return 0; 390 1.15 sekiya #endif 391 1.15 sekiya 392 1.25 rumble #if (NLIGHT > 0) 393 1.25 rumble if (light_cnattach(&ga) == 0) 394 1.25 rumble return 0; 395 1.25 rumble #endif 396 1.25 rumble 397 1.12 lonewolf #if (NNEWPORT > 0) 398 1.12 lonewolf if (newport_cnattach(&ga) == 0) 399 1.12 lonewolf return 0; 400 1.12 lonewolf #endif 401 1.15 sekiya 402 1.12 lonewolf } 403 1.12 lonewolf 404 1.12 lonewolf return ENXIO; 405 1.1 soren } 406 1.22 rumble 407 1.22 rumble /* 408 1.22 rumble * Devices living in the expansion slots must enable or disable some 409 1.22 rumble * GIO arbiter settings. This is accomplished via imc(4) or pic(4) 410 1.22 rumble * registers, depending on the machine in question. 411 1.22 rumble */ 412 1.22 rumble int 413 1.22 rumble gio_arb_config(int slot, uint32_t flags) 414 1.22 rumble { 415 1.22 rumble 416 1.22 rumble if (flags == 0) 417 1.22 rumble return (EINVAL); 418 1.22 rumble 419 1.22 rumble if (flags & ~(GIO_ARB_RT | GIO_ARB_LB | GIO_ARB_MST | GIO_ARB_SLV | 420 1.27 rumble GIO_ARB_PIPE | GIO_ARB_NOPIPE | GIO_ARB_32BIT | GIO_ARB_64BIT | 421 1.27 rumble GIO_ARB_HPC2_32BIT | GIO_ARB_HPC2_64BIT)) 422 1.22 rumble return (EINVAL); 423 1.22 rumble 424 1.22 rumble if (((flags & GIO_ARB_RT) && (flags & GIO_ARB_LB)) || 425 1.22 rumble ((flags & GIO_ARB_MST) && (flags & GIO_ARB_SLV)) || 426 1.27 rumble ((flags & GIO_ARB_PIPE) && (flags & GIO_ARB_NOPIPE)) || 427 1.27 rumble ((flags & GIO_ARB_32BIT) && (flags & GIO_ARB_64BIT)) || 428 1.27 rumble ((flags & GIO_ARB_HPC2_32BIT) && (flags & GIO_ARB_HPC2_64BIT))) 429 1.22 rumble return (EINVAL); 430 1.22 rumble 431 1.22 rumble #if (NPIC > 0) 432 1.22 rumble if (mach_type == MACH_SGI_IP12) 433 1.22 rumble return (pic_gio32_arb_config(slot, flags)); 434 1.22 rumble #endif 435 1.22 rumble 436 1.22 rumble #if (NIMC > 0) 437 1.22 rumble if (mach_type == MACH_SGI_IP20 || mach_type == MACH_SGI_IP22) 438 1.22 rumble return (imc_gio64_arb_config(slot, flags)); 439 1.22 rumble #endif 440 1.22 rumble 441 1.22 rumble return (EINVAL); 442 1.22 rumble } 443 1.22 rumble 444 1.22 rumble /* 445 1.22 rumble * Establish an interrupt handler for the specified slot. 446 1.23 rumble * 447 1.23 rumble * Indy and Challenge S have an interrupt per GIO slot. Indigo and Indigo2 448 1.23 rumble * share a single interrupt, however. 449 1.22 rumble */ 450 1.22 rumble void * 451 1.22 rumble gio_intr_establish(int slot, int level, int (*func)(void *), void *arg) 452 1.22 rumble { 453 1.22 rumble int intr; 454 1.22 rumble 455 1.22 rumble switch (mach_type) { 456 1.22 rumble case MACH_SGI_IP12: 457 1.22 rumble case MACH_SGI_IP20: 458 1.22 rumble if (slot == GIO_SLOT_GFX) 459 1.22 rumble panic("gio_intr_establish: slot %d", slot); 460 1.23 rumble intr = 6; 461 1.22 rumble break; 462 1.22 rumble 463 1.22 rumble case MACH_SGI_IP22: 464 1.22 rumble if (mach_subtype == MACH_SGI_IP22_FULLHOUSE) { 465 1.22 rumble if (slot == GIO_SLOT_EXP1) 466 1.22 rumble panic("gio_intr_establish: slot %d", slot); 467 1.23 rumble intr = 6; 468 1.22 rumble } else { 469 1.22 rumble if (slot == GIO_SLOT_GFX) 470 1.22 rumble panic("gio_intr_establish: slot %d", slot); 471 1.22 rumble intr = (slot == GIO_SLOT_EXP0) ? 22 : 23; 472 1.22 rumble } 473 1.22 rumble break; 474 1.22 rumble 475 1.22 rumble default: 476 1.22 rumble panic("gio_intr_establish: mach_type"); 477 1.22 rumble } 478 1.22 rumble 479 1.22 rumble return (cpu_intr_establish(intr, level, func, arg)); 480 1.22 rumble } 481 1.22 rumble 482 1.22 rumble const char * 483 1.22 rumble gio_product_string(int prid) 484 1.22 rumble { 485 1.22 rumble int i; 486 1.22 rumble 487 1.22 rumble for (i = 0; gio_knowndevs[i].product != NULL; i++) 488 1.22 rumble if (gio_knowndevs[i].productid == prid) 489 1.22 rumble return (gio_knowndevs[i].product); 490 1.22 rumble 491 1.22 rumble return (NULL); 492 1.22 rumble } 493