1 /* $NetBSD: pci_machdep.c,v 1.5 2003/06/15 23:09:08 fvdl Exp $ */ 2 3 /*- 4 * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 * NASA Ames Research Center. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 /* 41 * Copyright (c) 1996 Christopher G. Demetriou. All rights reserved. 42 * Copyright (c) 1994 Charles M. Hannum. All rights reserved. 43 * 44 * Redistribution and use in source and binary forms, with or without 45 * modification, are permitted provided that the following conditions 46 * are met: 47 * 1. Redistributions of source code must retain the above copyright 48 * notice, this list of conditions and the following disclaimer. 49 * 2. Redistributions in binary form must reproduce the above copyright 50 * notice, this list of conditions and the following disclaimer in the 51 * documentation and/or other materials provided with the distribution. 52 * 3. All advertising materials mentioning features or use of this software 53 * must display the following acknowledgement: 54 * This product includes software developed by Charles M. Hannum. 55 * 4. The name of the author may not be used to endorse or promote products 56 * derived from this software without specific prior written permission. 57 * 58 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 59 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 60 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 61 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 62 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 63 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 64 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 65 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 66 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 67 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 68 */ 69 70 /* 71 * Machine-specific functions for PCI autoconfiguration. 72 * 73 * On PCs, there are two methods of generating PCI configuration cycles. 74 * We try to detect the appropriate mechanism for this machine and set 75 * up a few function pointers to access the correct method directly. 76 * 77 * The configuration method can be hard-coded in the config file by 78 * using `options PCI_CONF_MODE=N', where `N' is the configuration mode 79 * as defined section 3.6.4.1, `Generating Configuration Cycles'. 80 */ 81 82 #include <sys/cdefs.h> 83 __KERNEL_RCSID(0, "$NetBSD: pci_machdep.c,v 1.5 2003/06/15 23:09:08 fvdl Exp $"); 84 85 #include <sys/types.h> 86 #include <sys/param.h> 87 #include <sys/time.h> 88 #include <sys/systm.h> 89 #include <sys/errno.h> 90 #include <sys/device.h> 91 #include <sys/lock.h> 92 93 #include <uvm/uvm_extern.h> 94 95 #define _X86_BUS_DMA_PRIVATE 96 #include <machine/bus.h> 97 98 #include <machine/pio.h> 99 #include <machine/intr.h> 100 101 #include <dev/isa/isareg.h> 102 #include <dev/isa/isavar.h> 103 #include <dev/pci/pcivar.h> 104 #include <dev/pci/pcireg.h> 105 #include <dev/pci/pcidevs.h> 106 107 #include "ioapic.h" 108 #include "eisa.h" 109 #include "opt_mpbios.h" 110 #include "opt_mpacpi.h" 111 112 #if NIOAPIC > 0 113 #include <machine/i82093var.h> 114 #include <machine/mpbiosvar.h> 115 #endif 116 117 #ifdef MPBIOS 118 #include <machine/mpbiosvar.h> 119 #endif 120 121 #ifdef MPACPI 122 #include <machine/mpacpi.h> 123 #endif 124 125 #include "opt_pci_conf_mode.h" 126 127 int pci_mode = -1; 128 129 struct simplelock pci_conf_slock = SIMPLELOCK_INITIALIZER; 130 131 #define PCI_CONF_LOCK(s) \ 132 do { \ 133 (s) = splhigh(); \ 134 simple_lock(&pci_conf_slock); \ 135 } while (0) 136 137 #define PCI_CONF_UNLOCK(s) \ 138 do { \ 139 simple_unlock(&pci_conf_slock); \ 140 splx((s)); \ 141 } while (0) 142 143 #define PCI_MODE1_ENABLE 0x80000000UL 144 #define PCI_MODE1_ADDRESS_REG 0x0cf8 145 #define PCI_MODE1_DATA_REG 0x0cfc 146 147 #define PCI_MODE2_ENABLE_REG 0x0cf8 148 #define PCI_MODE2_FORWARD_REG 0x0cfa 149 150 #define _m1tag(b, d, f) \ 151 (PCI_MODE1_ENABLE | ((b) << 16) | ((d) << 11) | ((f) << 8)) 152 #define _qe(bus, dev, fcn, vend, prod) \ 153 {_m1tag(bus, dev, fcn), PCI_ID_CODE(vend, prod)} 154 struct { 155 u_int32_t tag; 156 pcireg_t id; 157 } pcim1_quirk_tbl[] = { 158 _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX1), 159 /* XXX Triflex2 not tested */ 160 _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX2), 161 _qe(0, 0, 0, PCI_VENDOR_COMPAQ, PCI_PRODUCT_COMPAQ_TRIFLEX4), 162 /* Triton needed for Connectix Virtual PC */ 163 _qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82437FX), 164 /* Connectix Virtual PC 5 has a 440BX */ 165 _qe(0, 0, 0, PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_82443BX_NOAGP), 166 {0, 0xffffffff} /* patchable */ 167 }; 168 #undef _m1tag 169 #undef _id 170 #undef _qe 171 172 /* 173 * PCI doesn't have any special needs; just use the generic versions 174 * of these functions. 175 */ 176 struct x86_bus_dma_tag pci_bus_dma_tag = { 177 #if defined(_LP64) || defined(PAE) 178 PCI32_DMA_BOUNCE_THRESHOLD, /* bounce_thresh */ 179 ISA_DMA_BOUNCE_THRESHOLD, /* bounce_alloclo */ 180 PCI32_DMA_BOUNCE_THRESHOLD, /* bounce_allochi */ 181 #else 182 0, 183 0, 184 0, 185 #endif 186 NULL, /* _may_bounce */ 187 _bus_dmamap_create, 188 _bus_dmamap_destroy, 189 _bus_dmamap_load, 190 _bus_dmamap_load_mbuf, 191 _bus_dmamap_load_uio, 192 _bus_dmamap_load_raw, 193 _bus_dmamap_unload, 194 #if defined(_LP64) || defined(PAE) 195 _bus_dmamap_sync, 196 #else 197 NULL, 198 #endif 199 _bus_dmamem_alloc, 200 _bus_dmamem_free, 201 _bus_dmamem_map, 202 _bus_dmamem_unmap, 203 _bus_dmamem_mmap, 204 }; 205 206 #ifdef _LP64 207 struct x86_bus_dma_tag pci_bus_dma64_tag = { 208 0, 209 0, 210 0, 211 NULL, /* _may_bounce */ 212 _bus_dmamap_create, 213 _bus_dmamap_destroy, 214 _bus_dmamap_load, 215 _bus_dmamap_load_mbuf, 216 _bus_dmamap_load_uio, 217 _bus_dmamap_load_raw, 218 _bus_dmamap_unload, 219 NULL, 220 _bus_dmamem_alloc, 221 _bus_dmamem_free, 222 _bus_dmamem_map, 223 _bus_dmamem_unmap, 224 _bus_dmamem_mmap, 225 }; 226 #endif 227 228 void 229 pci_attach_hook(parent, self, pba) 230 struct device *parent, *self; 231 struct pcibus_attach_args *pba; 232 { 233 234 if (pba->pba_bus == 0) 235 printf(": configuration mode %d", pci_mode); 236 #ifdef MPBIOS 237 mpbios_pci_attach_hook(parent, self, pba); 238 #endif 239 #ifdef MPACPI 240 mpacpi_pci_attach_hook(parent, self, pba); 241 #endif 242 } 243 244 int 245 pci_bus_maxdevs(pc, busno) 246 pci_chipset_tag_t pc; 247 int busno; 248 { 249 250 /* 251 * Bus number is irrelevant. If Configuration Mechanism 2 is in 252 * use, can only have devices 0-15 on any bus. If Configuration 253 * Mechanism 1 is in use, can have devices 0-32 (i.e. the `normal' 254 * range). 255 */ 256 if (pci_mode == 2) 257 return (16); 258 else 259 return (32); 260 } 261 262 pcitag_t 263 pci_make_tag(pc, bus, device, function) 264 pci_chipset_tag_t pc; 265 int bus, device, function; 266 { 267 pcitag_t tag; 268 269 #ifndef PCI_CONF_MODE 270 switch (pci_mode) { 271 case 1: 272 goto mode1; 273 case 2: 274 goto mode2; 275 default: 276 panic("pci_make_tag: mode not configured"); 277 } 278 #endif 279 280 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 1) 281 #ifndef PCI_CONF_MODE 282 mode1: 283 #endif 284 if (bus >= 256 || device >= 32 || function >= 8) 285 panic("pci_make_tag: bad request"); 286 287 tag.mode1 = PCI_MODE1_ENABLE | 288 (bus << 16) | (device << 11) | (function << 8); 289 return tag; 290 #endif 291 292 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 2) 293 #ifndef PCI_CONF_MODE 294 mode2: 295 #endif 296 if (bus >= 256 || device >= 16 || function >= 8) 297 panic("pci_make_tag: bad request"); 298 299 tag.mode2.port = 0xc000 | (device << 8); 300 tag.mode2.enable = 0xf0 | (function << 1); 301 tag.mode2.forward = bus; 302 return tag; 303 #endif 304 } 305 306 void 307 pci_decompose_tag(pc, tag, bp, dp, fp) 308 pci_chipset_tag_t pc; 309 pcitag_t tag; 310 int *bp, *dp, *fp; 311 { 312 313 #ifndef PCI_CONF_MODE 314 switch (pci_mode) { 315 case 1: 316 goto mode1; 317 case 2: 318 goto mode2; 319 default: 320 panic("pci_decompose_tag: mode not configured"); 321 } 322 #endif 323 324 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 1) 325 #ifndef PCI_CONF_MODE 326 mode1: 327 #endif 328 if (bp != NULL) 329 *bp = (tag.mode1 >> 16) & 0xff; 330 if (dp != NULL) 331 *dp = (tag.mode1 >> 11) & 0x1f; 332 if (fp != NULL) 333 *fp = (tag.mode1 >> 8) & 0x7; 334 return; 335 #endif 336 337 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 2) 338 #ifndef PCI_CONF_MODE 339 mode2: 340 #endif 341 if (bp != NULL) 342 *bp = tag.mode2.forward & 0xff; 343 if (dp != NULL) 344 *dp = (tag.mode2.port >> 8) & 0xf; 345 if (fp != NULL) 346 *fp = (tag.mode2.enable >> 1) & 0x7; 347 #endif 348 } 349 350 pcireg_t 351 pci_conf_read(pc, tag, reg) 352 pci_chipset_tag_t pc; 353 pcitag_t tag; 354 int reg; 355 { 356 pcireg_t data; 357 int s; 358 359 #ifndef PCI_CONF_MODE 360 switch (pci_mode) { 361 case 1: 362 goto mode1; 363 case 2: 364 goto mode2; 365 default: 366 panic("pci_conf_read: mode not configured"); 367 } 368 #endif 369 370 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 1) 371 #ifndef PCI_CONF_MODE 372 mode1: 373 #endif 374 PCI_CONF_LOCK(s); 375 outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg); 376 data = inl(PCI_MODE1_DATA_REG); 377 outl(PCI_MODE1_ADDRESS_REG, 0); 378 PCI_CONF_UNLOCK(s); 379 return data; 380 #endif 381 382 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 2) 383 #ifndef PCI_CONF_MODE 384 mode2: 385 #endif 386 PCI_CONF_LOCK(s); 387 outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable); 388 outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward); 389 data = inl(tag.mode2.port | reg); 390 outb(PCI_MODE2_ENABLE_REG, 0); 391 PCI_CONF_UNLOCK(s); 392 return data; 393 #endif 394 } 395 396 void 397 pci_conf_write(pc, tag, reg, data) 398 pci_chipset_tag_t pc; 399 pcitag_t tag; 400 int reg; 401 pcireg_t data; 402 { 403 int s; 404 405 #ifndef PCI_CONF_MODE 406 switch (pci_mode) { 407 case 1: 408 goto mode1; 409 case 2: 410 goto mode2; 411 default: 412 panic("pci_conf_write: mode not configured"); 413 } 414 #endif 415 416 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 1) 417 #ifndef PCI_CONF_MODE 418 mode1: 419 #endif 420 PCI_CONF_LOCK(s); 421 outl(PCI_MODE1_ADDRESS_REG, tag.mode1 | reg); 422 outl(PCI_MODE1_DATA_REG, data); 423 outl(PCI_MODE1_ADDRESS_REG, 0); 424 PCI_CONF_UNLOCK(s); 425 return; 426 #endif 427 428 #if !defined(PCI_CONF_MODE) || (PCI_CONF_MODE == 2) 429 #ifndef PCI_CONF_MODE 430 mode2: 431 #endif 432 PCI_CONF_LOCK(s); 433 outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable); 434 outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward); 435 outl(tag.mode2.port | reg, data); 436 outb(PCI_MODE2_ENABLE_REG, 0); 437 PCI_CONF_UNLOCK(s); 438 #endif 439 } 440 441 int 442 pci_mode_detect() 443 { 444 445 #ifdef PCI_CONF_MODE 446 #if (PCI_CONF_MODE == 1) || (PCI_CONF_MODE == 2) 447 return (pci_mode = PCI_CONF_MODE); 448 #else 449 #error Invalid PCI configuration mode. 450 #endif 451 #else 452 u_int32_t sav, val; 453 int i; 454 pcireg_t idreg; 455 456 if (pci_mode != -1) 457 return pci_mode; 458 459 /* 460 * We try to divine which configuration mode the host bridge wants. 461 */ 462 463 sav = inl(PCI_MODE1_ADDRESS_REG); 464 465 pci_mode = 1; /* assume this for now */ 466 /* 467 * catch some known buggy implementations of mode 1 468 */ 469 for (i = 0; i < sizeof(pcim1_quirk_tbl) / sizeof(pcim1_quirk_tbl[0]); 470 i++) { 471 pcitag_t t; 472 473 if (!pcim1_quirk_tbl[i].tag) 474 break; 475 t.mode1 = pcim1_quirk_tbl[i].tag; 476 idreg = pci_conf_read(0, t, PCI_ID_REG); /* needs "pci_mode" */ 477 if (idreg == pcim1_quirk_tbl[i].id) { 478 #ifdef DEBUG 479 printf("known mode 1 PCI chipset (%08x)\n", 480 idreg); 481 #endif 482 return (pci_mode); 483 } 484 } 485 486 /* 487 * Strong check for standard compliant mode 1: 488 * 1. bit 31 ("enable") can be set 489 * 2. byte/word access does not affect register 490 */ 491 outl(PCI_MODE1_ADDRESS_REG, PCI_MODE1_ENABLE); 492 outb(PCI_MODE1_ADDRESS_REG + 3, 0); 493 outw(PCI_MODE1_ADDRESS_REG + 2, 0); 494 val = inl(PCI_MODE1_ADDRESS_REG); 495 if ((val & 0x80fffffc) != PCI_MODE1_ENABLE) { 496 #ifdef DEBUG 497 printf("pci_mode_detect: mode 1 enable failed (%x)\n", 498 val); 499 #endif 500 goto not1; 501 } 502 outl(PCI_MODE1_ADDRESS_REG, 0); 503 val = inl(PCI_MODE1_ADDRESS_REG); 504 if ((val & 0x80fffffc) != 0) 505 goto not1; 506 return (pci_mode); 507 not1: 508 outl(PCI_MODE1_ADDRESS_REG, sav); 509 510 /* 511 * This mode 2 check is quite weak (and known to give false 512 * positives on some Compaq machines). 513 * However, this doesn't matter, because this is the 514 * last test, and simply no PCI devices will be found if 515 * this happens. 516 */ 517 outb(PCI_MODE2_ENABLE_REG, 0); 518 outb(PCI_MODE2_FORWARD_REG, 0); 519 if (inb(PCI_MODE2_ENABLE_REG) != 0 || 520 inb(PCI_MODE2_FORWARD_REG) != 0) 521 goto not2; 522 return (pci_mode = 2); 523 not2: 524 525 return (pci_mode = 0); 526 #endif 527 } 528 529 int 530 pci_intr_map(pa, ihp) 531 struct pci_attach_args *pa; 532 pci_intr_handle_t *ihp; 533 { 534 int pin = pa->pa_intrpin; 535 int line = pa->pa_intrline; 536 #if NIOAPIC > 0 537 int rawpin = pa->pa_rawintrpin; 538 pci_chipset_tag_t pc = pa->pa_pc; 539 int bus, dev, func; 540 #endif 541 542 if (pin == 0) { 543 /* No IRQ used. */ 544 goto bad; 545 } 546 547 if (pin > PCI_INTERRUPT_PIN_MAX) { 548 printf("pci_intr_map: bad interrupt pin %d\n", pin); 549 goto bad; 550 } 551 552 #if NIOAPIC > 0 553 pci_decompose_tag(pc, pa->pa_tag, &bus, &dev, &func); 554 if (mp_busses != NULL) { 555 if (intr_find_mpmapping(bus, (dev<<2)|(rawpin-1), ihp) == 0) { 556 *ihp |= line; 557 return 0; 558 } 559 /* 560 * No explicit PCI mapping found. This is not fatal, 561 * we'll try the ISA (or possibly EISA) mappings next. 562 */ 563 } 564 #endif 565 566 /* 567 * Section 6.2.4, `Miscellaneous Functions', says that 255 means 568 * `unknown' or `no connection' on a PC. We assume that a device with 569 * `no connection' either doesn't have an interrupt (in which case the 570 * pin number should be 0, and would have been noticed above), or 571 * wasn't configured by the BIOS (in which case we punt, since there's 572 * no real way we can know how the interrupt lines are mapped in the 573 * hardware). 574 * 575 * XXX 576 * Since IRQ 0 is only used by the clock, and we can't actually be sure 577 * that the BIOS did its job, we also recognize that as meaning that 578 * the BIOS has not configured the device. 579 */ 580 if (line == 0 || line == X86_PCI_INTERRUPT_LINE_NO_CONNECTION) { 581 printf("pci_intr_map: no mapping for pin %c (line=%02x)\n", 582 '@' + pin, line); 583 goto bad; 584 } else { 585 if (line >= NUM_LEGACY_IRQS) { 586 printf("pci_intr_map: bad interrupt line %d\n", line); 587 goto bad; 588 } 589 if (line == 2) { 590 printf("pci_intr_map: changed line 2 to line 9\n"); 591 line = 9; 592 } 593 } 594 #if NIOAPIC > 0 595 if (mp_busses != NULL) { 596 if (intr_find_mpmapping(mp_isa_bus, line, ihp) == 0) { 597 *ihp |= line; 598 return 0; 599 } 600 #if NEISA > 0 601 if (intr_find_mpmapping(mp_eisa_bus, line, ihp) == 0) { 602 *ihp |= line; 603 return 0; 604 } 605 #endif 606 printf("pci_intr_map: bus %d dev %d func %d pin %d; line %d\n", 607 bus, dev, func, pin, line); 608 printf("pci_intr_map: no MP mapping found\n"); 609 } 610 #endif 611 612 *ihp = line; 613 return 0; 614 615 bad: 616 *ihp = -1; 617 return 1; 618 } 619 620 const char * 621 pci_intr_string(pc, ih) 622 pci_chipset_tag_t pc; 623 pci_intr_handle_t ih; 624 { 625 static char irqstr[64]; 626 627 if (ih == 0) 628 panic("pci_intr_string: bogus handle 0x%x", ih); 629 630 631 #if NIOAPIC > 0 632 if (ih & APIC_INT_VIA_APIC) 633 sprintf(irqstr, "apic %d int %d (irq %d)", 634 APIC_IRQ_APIC(ih), 635 APIC_IRQ_PIN(ih), 636 ih&0xff); 637 else 638 sprintf(irqstr, "irq %d", ih&0xff); 639 #else 640 641 sprintf(irqstr, "irq %d", ih&0xff); 642 #endif 643 return (irqstr); 644 645 } 646 647 const struct evcnt * 648 pci_intr_evcnt(pc, ih) 649 pci_chipset_tag_t pc; 650 pci_intr_handle_t ih; 651 { 652 653 /* XXX for now, no evcnt parent reported */ 654 return NULL; 655 } 656 657 void * 658 pci_intr_establish(pc, ih, level, func, arg) 659 pci_chipset_tag_t pc; 660 pci_intr_handle_t ih; 661 int level, (*func) __P((void *)); 662 void *arg; 663 { 664 int pin, irq; 665 struct pic *pic; 666 667 pic = &i8259_pic; 668 pin = irq = ih; 669 670 #if NIOAPIC > 0 671 if (ih & APIC_INT_VIA_APIC) { 672 pic = (struct pic *)ioapic_find(APIC_IRQ_APIC(ih)); 673 if (pic == NULL) { 674 printf("pci_intr_establish: bad ioapic %d\n", 675 APIC_IRQ_APIC(ih)); 676 return NULL; 677 } 678 pin = APIC_IRQ_PIN(ih); 679 irq = APIC_IRQ_LEGACY_IRQ(ih); 680 if (irq < 0 || irq >= NUM_LEGACY_IRQS) 681 irq = -1; 682 } 683 #endif 684 685 return intr_establish(irq, pic, pin, IST_LEVEL, level, func, arg); 686 } 687 688 void 689 pci_intr_disestablish(pc, cookie) 690 pci_chipset_tag_t pc; 691 void *cookie; 692 { 693 694 intr_disestablish(cookie); 695 } 696 697 /* 698 * Determine which flags should be passed to the primary PCI bus's 699 * autoconfiguration node. We use this to detect broken chipsets 700 * which cannot safely use memory-mapped device access. 701 */ 702 int 703 pci_bus_flags() 704 { 705 int rval = PCI_FLAGS_IO_ENABLED | PCI_FLAGS_MEM_ENABLED | 706 PCI_FLAGS_MRL_OKAY | PCI_FLAGS_MRM_OKAY | PCI_FLAGS_MWI_OKAY; 707 int device, maxndevs; 708 pcitag_t tag; 709 pcireg_t id; 710 711 maxndevs = pci_bus_maxdevs(NULL, 0); 712 713 for (device = 0; device < maxndevs; device++) { 714 tag = pci_make_tag(NULL, 0, device, 0); 715 id = pci_conf_read(NULL, tag, PCI_ID_REG); 716 717 /* Invalid vendor ID value? */ 718 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID) 719 continue; 720 /* XXX Not invalid, but we've done this ~forever. */ 721 if (PCI_VENDOR(id) == 0) 722 continue; 723 724 switch (PCI_VENDOR(id)) { 725 case PCI_VENDOR_SIS: 726 switch (PCI_PRODUCT(id)) { 727 case PCI_PRODUCT_SIS_85C496: 728 goto disable_mem; 729 } 730 break; 731 } 732 } 733 734 return (rval); 735 736 disable_mem: 737 printf("Warning: broken PCI-Host bridge detected; " 738 "disabling memory-mapped access\n"); 739 rval &= ~(PCI_FLAGS_MEM_ENABLED|PCI_FLAGS_MRL_OKAY|PCI_FLAGS_MRM_OKAY| 740 PCI_FLAGS_MWI_OKAY); 741 return (rval); 742 } 743