1 /* $OpenBSD: sio_pic.c,v 1.37 2014/04/04 20:00:12 miod Exp $ */ 2 /* $NetBSD: sio_pic.c,v 1.28 2000/06/06 03:10:13 thorpej Exp $ */ 3 4 /*- 5 * Copyright (c) 1998, 2000 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * This code is derived from software contributed to The NetBSD Foundation 9 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 10 * NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 31 * POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 /* 35 * Copyright (c) 1995, 1996 Carnegie-Mellon University. 36 * All rights reserved. 37 * 38 * Author: Chris G. Demetriou 39 * 40 * Permission to use, copy, modify and distribute this software and 41 * its documentation is hereby granted, provided that both the copyright 42 * notice and this permission notice appear in all copies of the 43 * software, derivative works or modified versions, and any portions 44 * thereof, and that both notices appear in supporting documentation. 45 * 46 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" 47 * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND 48 * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. 49 * 50 * Carnegie Mellon requests users of this software to return to 51 * 52 * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU 53 * School of Computer Science 54 * Carnegie Mellon University 55 * Pittsburgh PA 15213-3890 56 * 57 * any improvements or extensions that they make and grant Carnegie the 58 * rights to redistribute these changes. 59 */ 60 61 #include <sys/param.h> 62 #include <sys/systm.h> 63 64 #include <sys/device.h> 65 #include <sys/malloc.h> 66 #include <sys/syslog.h> 67 68 #include <machine/intr.h> 69 #include <machine/bus.h> 70 71 #include <dev/pci/pcireg.h> 72 #include <dev/pci/pcivar.h> 73 #include <dev/pci/pcidevs.h> 74 75 #include <dev/pci/cy82c693reg.h> 76 #include <dev/pci/cy82c693var.h> 77 78 #include <dev/isa/isareg.h> 79 #include <dev/isa/isavar.h> 80 #include <alpha/pci/siovar.h> 81 82 #include "sio.h" 83 84 /* 85 * To add to the long history of wonderful PROM console traits, 86 * AlphaStation PROMs don't reset themselves completely on boot! 87 * Therefore, if an interrupt was turned on when the kernel was 88 * started, we're not going to EVER turn it off... I don't know 89 * what will happen if new interrupts (that the PROM console doesn't 90 * want) are turned on. I'll burn that bridge when I come to it. 91 */ 92 #define BROKEN_PROM_CONSOLE 93 94 /* 95 * Private functions and variables. 96 */ 97 98 bus_space_tag_t sio_iot; 99 pci_chipset_tag_t sio_pc; 100 bus_space_handle_t sio_ioh_icu1, sio_ioh_icu2; 101 102 #define ICU_LEN 16 /* number of ISA IRQs */ 103 104 static struct alpha_shared_intr *sio_intr; 105 106 #ifndef STRAY_MAX 107 #define STRAY_MAX 5 108 #endif 109 110 #ifdef BROKEN_PROM_CONSOLE 111 /* 112 * If prom console is broken, must remember the initial interrupt 113 * settings and enforce them. WHEE! 114 */ 115 u_int8_t initial_ocw1[2]; 116 u_int8_t initial_elcr[2]; 117 #endif 118 119 /* 120 * Overrides for ELCR settings. 121 * These are used on ES40 and similar systems suffering from a PCI USB HCI 122 * interrupt being routed through the ISA logic with actual logic to 123 * make it behave an edge-triggered interrupt, although PCI interrupts are 124 * supposed to be level-triggered. 125 */ 126 u_int8_t elcr_override[2] = { 0x00, 0x00 }; 127 128 void sio_setirqstat(int, int, int); 129 int sio_intr_alloc(void *, int, int, int *); 130 int sio_intr_check(void *, int, int); 131 132 u_int8_t (*sio_read_elcr)(int); 133 void (*sio_write_elcr)(int, u_int8_t); 134 static void specific_eoi(int); 135 136 /******************** i82378 SIO ELCR functions ********************/ 137 138 int i82378_setup_elcr(void); 139 u_int8_t i82378_read_elcr(int); 140 void i82378_write_elcr(int, u_int8_t); 141 142 bus_space_handle_t sio_ioh_elcr; 143 144 int 145 i82378_setup_elcr() 146 { 147 int device, maxndevs; 148 pcitag_t tag; 149 pcireg_t id; 150 int rv; 151 152 /* 153 * We could probe configuration space to see that there's 154 * actually an SIO present, but we are using this as a 155 * fall-back in case nothing else matches. 156 */ 157 158 rv = bus_space_map(sio_iot, 0x4d0, 2, 0, &sio_ioh_elcr); 159 160 if (rv != 0) 161 return 0; 162 163 sio_read_elcr = i82378_read_elcr; 164 sio_write_elcr = i82378_write_elcr; 165 166 /* 167 * Search PCI configuration space for an ALI M5237 USB controller 168 * on the first bus. 169 */ 170 171 maxndevs = pci_bus_maxdevs(sio_pc, 0); 172 173 for (device = 0; device < maxndevs; device++) { 174 tag = pci_make_tag(sio_pc, 0, device, 0); 175 id = pci_conf_read(sio_pc, tag, PCI_ID_REG); 176 177 if (id == PCI_ID_CODE(PCI_VENDOR_ALI, PCI_PRODUCT_ALI_M5237)) { 178 elcr_override[10 / 8] |= 1 << (10 % 8); 179 break; 180 } 181 } 182 183 return (0); 184 } 185 186 u_int8_t 187 i82378_read_elcr(elcr) 188 int elcr; 189 { 190 191 return (bus_space_read_1(sio_iot, sio_ioh_elcr, elcr)); 192 } 193 194 void 195 i82378_write_elcr(elcr, val) 196 int elcr; 197 u_int8_t val; 198 { 199 200 bus_space_write_1(sio_iot, sio_ioh_elcr, elcr, val); 201 } 202 203 /******************** Cypress CY82C693 ELCR functions ********************/ 204 205 int cy82c693_setup_elcr(void); 206 u_int8_t cy82c693_read_elcr(int); 207 void cy82c693_write_elcr(int, u_int8_t); 208 209 const struct cy82c693_handle *sio_cy82c693_handle; 210 211 int 212 cy82c693_setup_elcr() 213 { 214 int device, maxndevs; 215 pcitag_t tag; 216 pcireg_t id; 217 218 /* 219 * Search PCI configuration space for a Cypress CY82C693. 220 * 221 * Note we can make some assumptions about our bus number 222 * here, because: 223 * 224 * (1) there can be at most one ISA/EISA bridge per PCI bus, and 225 * 226 * (2) any ISA/EISA bridges must be attached to primary PCI 227 * busses (i.e. bus zero). 228 */ 229 230 maxndevs = pci_bus_maxdevs(sio_pc, 0); 231 232 for (device = 0; device < maxndevs; device++) { 233 tag = pci_make_tag(sio_pc, 0, device, 0); 234 id = pci_conf_read(sio_pc, tag, PCI_ID_REG); 235 236 if (id == 237 PCI_ID_CODE(PCI_VENDOR_CONTAQ, PCI_PRODUCT_CONTAQ_82C693)) { 238 sio_cy82c693_handle = cy82c693_init(sio_iot); 239 sio_read_elcr = cy82c693_read_elcr; 240 sio_write_elcr = cy82c693_write_elcr; 241 return (0); 242 } 243 } 244 245 /* 246 * Didn't find a CY82C693. 247 */ 248 return (ENODEV); 249 } 250 251 u_int8_t 252 cy82c693_read_elcr(elcr) 253 int elcr; 254 { 255 256 return (cy82c693_read(sio_cy82c693_handle, CONFIG_ELCR1 + elcr)); 257 } 258 259 void 260 cy82c693_write_elcr(elcr, val) 261 int elcr; 262 u_int8_t val; 263 { 264 265 cy82c693_write(sio_cy82c693_handle, CONFIG_ELCR1 + elcr, val); 266 } 267 268 /******************** ELCR access function configuration ********************/ 269 270 /* 271 * Put the Intel SIO at the end, so we fall back on it if we don't 272 * find anything else. If any of the non-Intel functions find a 273 * matching device, but are unable to map it for whatever reason, 274 * they should panic. 275 */ 276 277 int (*sio_elcr_setup_funcs[])(void) = { 278 cy82c693_setup_elcr, 279 i82378_setup_elcr, 280 NULL, 281 }; 282 283 /******************** Shared SIO/Cypress functions ********************/ 284 285 void 286 sio_setirqstat(irq, enabled, type) 287 int irq, enabled; 288 int type; 289 { 290 u_int8_t ocw1[2], elcr[2]; 291 int icu, bit; 292 293 #if 0 294 printf("sio_setirqstat: irq %d: %s, %s\n", irq, 295 enabled ? "enabled" : "disabled", isa_intr_typename(type)); 296 #endif 297 298 icu = irq / 8; 299 bit = irq % 8; 300 301 ocw1[0] = bus_space_read_1(sio_iot, sio_ioh_icu1, 1); 302 ocw1[1] = bus_space_read_1(sio_iot, sio_ioh_icu2, 1); 303 elcr[0] = (*sio_read_elcr)(0); /* XXX */ 304 elcr[1] = (*sio_read_elcr)(1); /* XXX */ 305 306 /* 307 * interrupt enable: set bit to mask (disable) interrupt. 308 */ 309 if (enabled) 310 ocw1[icu] &= ~(1 << bit); 311 else 312 ocw1[icu] |= 1 << bit; 313 314 /* 315 * interrupt type select: set bit to get level-triggered... 316 */ 317 if (type == IST_LEVEL) 318 elcr[icu] |= 1 << bit; 319 else 320 elcr[icu] &= ~(1 << bit); 321 322 /* 323 * ...unless we pretend to know better. 324 */ 325 elcr[icu] &= ~elcr_override[icu]; 326 327 #ifdef not_here 328 /* see the init function... */ 329 ocw1[0] &= ~0x04; /* always enable IRQ2 on first PIC */ 330 elcr[0] &= ~0x07; /* IRQ[0-2] must be edge-triggered */ 331 elcr[1] &= ~0x21; /* IRQ[13,8] must be edge-triggered */ 332 #endif 333 334 bus_space_write_1(sio_iot, sio_ioh_icu1, 1, ocw1[0]); 335 bus_space_write_1(sio_iot, sio_ioh_icu2, 1, ocw1[1]); 336 (*sio_write_elcr)(0, elcr[0]); /* XXX */ 337 (*sio_write_elcr)(1, elcr[1]); /* XXX */ 338 } 339 340 void 341 sio_intr_setup(pc, iot) 342 pci_chipset_tag_t pc; 343 bus_space_tag_t iot; 344 { 345 int i; 346 347 sio_iot = iot; 348 sio_pc = pc; 349 350 if (bus_space_map(sio_iot, IO_ICU1, 2, 0, &sio_ioh_icu1) || 351 bus_space_map(sio_iot, IO_ICU2, 2, 0, &sio_ioh_icu2)) 352 panic("sio_intr_setup: can't map ICU I/O ports"); 353 354 for (i = 0; sio_elcr_setup_funcs[i] != NULL; i++) 355 if ((*sio_elcr_setup_funcs[i])() == 0) 356 break; 357 if (sio_elcr_setup_funcs[i] == NULL) 358 panic("sio_intr_setup: can't map ELCR"); 359 360 #ifdef BROKEN_PROM_CONSOLE 361 /* 362 * Remember the initial values, so we can restore them later. 363 */ 364 initial_ocw1[0] = bus_space_read_1(sio_iot, sio_ioh_icu1, 1); 365 initial_ocw1[1] = bus_space_read_1(sio_iot, sio_ioh_icu2, 1); 366 initial_elcr[0] = (*sio_read_elcr)(0); /* XXX */ 367 initial_elcr[1] = (*sio_read_elcr)(1); /* XXX */ 368 #endif 369 370 sio_intr = alpha_shared_intr_alloc(ICU_LEN); 371 372 /* 373 * set up initial values for interrupt enables. 374 */ 375 for (i = 0; i < ICU_LEN; i++) { 376 alpha_shared_intr_set_maxstrays(sio_intr, i, STRAY_MAX); 377 378 switch (i) { 379 case 0: 380 case 1: 381 case 8: 382 case 13: 383 /* 384 * IRQs 0, 1, 8, and 13 must always be 385 * edge-triggered. 386 */ 387 sio_setirqstat(i, 0, IST_EDGE); 388 alpha_shared_intr_set_dfltsharetype(sio_intr, i, 389 IST_EDGE); 390 specific_eoi(i); 391 break; 392 393 case 2: 394 /* 395 * IRQ 2 must be edge-triggered, and should be 396 * enabled (otherwise IRQs 8-15 are ignored). 397 */ 398 sio_setirqstat(i, 1, IST_EDGE); 399 alpha_shared_intr_set_dfltsharetype(sio_intr, i, 400 IST_UNUSABLE); 401 break; 402 403 default: 404 /* 405 * Otherwise, disable the IRQ and set its 406 * type to (effectively) "unknown." 407 */ 408 sio_setirqstat(i, 0, IST_NONE); 409 alpha_shared_intr_set_dfltsharetype(sio_intr, i, 410 IST_NONE); 411 specific_eoi(i); 412 break; 413 } 414 } 415 } 416 417 void 418 sio_intr_shutdown() 419 { 420 #ifdef BROKEN_PROM_CONSOLE 421 if (sio_write_elcr == NULL) 422 return; 423 424 /* 425 * Restore the initial values, to make the PROM happy. 426 */ 427 bus_space_write_1(sio_iot, sio_ioh_icu1, 1, initial_ocw1[0]); 428 bus_space_write_1(sio_iot, sio_ioh_icu2, 1, initial_ocw1[1]); 429 (*sio_write_elcr)(0, initial_elcr[0]); /* XXX */ 430 (*sio_write_elcr)(1, initial_elcr[1]); /* XXX */ 431 #endif 432 } 433 434 const char * 435 sio_intr_string(v, irq) 436 void *v; 437 int irq; 438 { 439 static char irqstr[12]; /* 8 + 2 + NULL + sanity */ 440 441 if (irq == 0 || irq >= ICU_LEN || irq == 2) 442 panic("sio_intr_string: bogus isa irq 0x%x", irq); 443 444 snprintf(irqstr, sizeof irqstr, "isa irq %d", irq); 445 return (irqstr); 446 } 447 448 int 449 sio_intr_line(v, irq) 450 void *v; 451 int irq; 452 { 453 return (irq); 454 } 455 456 void * 457 sio_intr_establish(v, irq, type, level, fn, arg, name) 458 void *v, *arg; 459 int irq; 460 int type; 461 int level; 462 int (*fn)(void *); 463 const char *name; 464 { 465 void *cookie; 466 467 if (irq >= ICU_LEN || type == IST_NONE) 468 panic("sio_intr_establish: bogus irq or type"); 469 470 cookie = alpha_shared_intr_establish(sio_intr, irq, type, level, fn, 471 arg, name); 472 473 if (cookie != NULL && 474 alpha_shared_intr_firstactive(sio_intr, irq)) { 475 scb_set(0x800 + SCB_IDXTOVEC(irq), sio_iointr, NULL); 476 sio_setirqstat(irq, 1, 477 alpha_shared_intr_get_sharetype(sio_intr, irq)); 478 } 479 480 return (cookie); 481 } 482 483 void 484 sio_intr_disestablish(v, cookie) 485 void *v; 486 void *cookie; 487 { 488 struct alpha_shared_intrhand *ih = cookie; 489 int s, ist, irq = ih->ih_num; 490 491 s = splhigh(); 492 493 /* Remove it from the link. */ 494 alpha_shared_intr_disestablish(sio_intr, cookie); 495 496 /* 497 * Decide if we should disable the interrupt. We must ensure 498 * that: 499 * 500 * - An initially-enabled interrupt is never disabled. 501 * - An initially-LT interrupt is never untyped. 502 */ 503 if (alpha_shared_intr_isactive(sio_intr, irq) == 0) { 504 /* 505 * IRQs 0, 1, 8, and 13 must always be edge-triggered 506 * (see setup). 507 */ 508 switch (irq) { 509 case 0: 510 case 1: 511 case 8: 512 case 13: 513 /* 514 * If the interrupt was initially level-triggered 515 * a warning was printed in setup. 516 */ 517 ist = IST_EDGE; 518 break; 519 520 default: 521 ist = IST_NONE; 522 break; 523 } 524 sio_setirqstat(irq, 0, ist); 525 alpha_shared_intr_set_dfltsharetype(sio_intr, irq, ist); 526 527 /* Release our SCB vector. */ 528 scb_free(0x800 + SCB_IDXTOVEC(irq)); 529 } 530 531 splx(s); 532 } 533 534 void 535 sio_iointr(arg, vec) 536 void *arg; 537 unsigned long vec; 538 { 539 int irq; 540 541 irq = SCB_VECTOIDX(vec - 0x800); 542 543 #ifdef DIAGNOSTIC 544 if (irq >= ICU_LEN || irq < 0) 545 panic("sio_iointr: irq out of range (%d)", irq); 546 #endif 547 548 if (!alpha_shared_intr_dispatch(sio_intr, irq)) 549 alpha_shared_intr_stray(sio_intr, irq, "isa irq"); 550 else 551 alpha_shared_intr_reset_strays(sio_intr, irq); 552 553 /* 554 * Some versions of the machines which use the SIO 555 * (or is it some PALcode revisions on those machines?) 556 * require the non-specific EOI to be fed to the PIC(s) 557 * by the interrupt handler. 558 */ 559 specific_eoi(irq); 560 } 561 562 #define LEGAL_IRQ(x) ((x) >= 0 && (x) < ICU_LEN && (x) != 2) 563 564 int 565 sio_intr_alloc(v, mask, type, irq) 566 void *v; 567 int mask; 568 int type; 569 int *irq; 570 { 571 int i, tmp, bestirq, count; 572 struct alpha_shared_intrhand **p, *q; 573 574 if (type == IST_NONE) 575 panic("intr_alloc: bogus type"); 576 577 bestirq = -1; 578 count = -1; 579 580 /* some interrupts should never be dynamically allocated */ 581 mask &= 0xffff; 582 mask &= ~((1 << 13) | (1 << 8) | (1 << 2) | (1 << 1) | (1 << 0)); 583 584 /* 585 * XXX some interrupts will be used later (6 for fdc, 12 for pms). 586 * the right answer is to do "breadth-first" searching of devices. 587 */ 588 mask &= ~((1 << 12) | (1 << 6)); 589 590 for (i = 0; i < ICU_LEN; i++) { 591 if (LEGAL_IRQ(i) == 0 || (mask & (1<<i)) == 0) 592 continue; 593 594 switch (sio_intr[i].intr_sharetype) { 595 case IST_NONE: 596 /* 597 * if nothing's using the irq, just return it 598 */ 599 *irq = i; 600 return (0); 601 602 case IST_EDGE: 603 intr_shared_edge = 1; 604 /* FALLTHROUGH */ 605 case IST_LEVEL: 606 if (type != sio_intr[i].intr_sharetype) 607 continue; 608 /* 609 * if the irq is shareable, count the number of other 610 * handlers, and if it's smaller than the last irq like 611 * this, remember it 612 * 613 * XXX We should probably also consider the 614 * interrupt level and stick IPL_TTY with other 615 * IPL_TTY, etc. 616 */ 617 for (p = &TAILQ_FIRST(&sio_intr[i].intr_q), tmp = 0; 618 (q = *p) != NULL; p = &TAILQ_NEXT(q, ih_q), tmp++) 619 ; 620 if ((bestirq == -1) || (count > tmp)) { 621 bestirq = i; 622 count = tmp; 623 } 624 break; 625 626 case IST_PULSE: 627 /* this just isn't shareable */ 628 continue; 629 } 630 } 631 632 if (bestirq == -1) 633 return (1); 634 635 *irq = bestirq; 636 637 return (0); 638 } 639 640 /* 641 * Just check to see if an IRQ is available/can be shared. 642 * 0 = interrupt not available 643 * 1 = interrupt shareable 644 * 2 = interrupt all to ourself 645 */ 646 int 647 sio_intr_check(void *v, int irq, int type) 648 { 649 if (type == IST_NONE) 650 return (0); 651 652 switch (sio_intr[irq].intr_sharetype) { 653 case IST_NONE: 654 return (2); 655 case IST_EDGE: 656 case IST_LEVEL: 657 if (type == sio_intr[irq].intr_sharetype) 658 return (1); 659 /* FALLTHROUGH */ 660 default: 661 case IST_PULSE: 662 return (0); 663 } 664 } 665 666 static void 667 specific_eoi(irq) 668 int irq; 669 { 670 if (irq > 7) { 671 bus_space_write_1(sio_iot, 672 sio_ioh_icu2, 0, 0x60 | (irq & 0x07)); /* XXX */ 673 irq = 2; 674 } 675 bus_space_write_1(sio_iot, sio_ioh_icu1, 0, 0x60 | irq); 676 } 677