1 /* $OpenBSD: ppb.c,v 1.52 2011/06/26 23:00:28 deraadt Exp $ */ 2 /* $NetBSD: ppb.c,v 1.16 1997/06/06 23:48:05 thorpej Exp $ */ 3 4 /* 5 * Copyright (c) 1996 Christopher G. Demetriou. 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 by Christopher G. Demetriou 18 * for the NetBSD Project. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/device.h> 38 #include <sys/timeout.h> 39 #include <sys/workq.h> 40 41 #include <dev/pci/pcireg.h> 42 #include <dev/pci/pcivar.h> 43 #include <dev/pci/pcidevs.h> 44 #include <dev/pci/ppbreg.h> 45 46 #ifndef PCI_IO_START 47 #define PCI_IO_START 0 48 #endif 49 50 #ifndef PCI_IO_END 51 #define PCI_IO_END 0xffffffff 52 #endif 53 54 #ifndef PCI_MEM_START 55 #define PCI_MEM_START 0 56 #endif 57 58 #ifndef PCI_MEM_END 59 #define PCI_MEM_END 0xffffffff 60 #endif 61 62 struct ppb_softc { 63 struct device sc_dev; /* generic device glue */ 64 pci_chipset_tag_t sc_pc; /* our PCI chipset... */ 65 pcitag_t sc_tag; /* ...and tag. */ 66 pci_intr_handle_t sc_ih[4]; 67 void *sc_intrhand; 68 struct extent *sc_ioex; 69 struct extent *sc_memex; 70 struct extent *sc_pmemex; 71 struct device *sc_psc; 72 int sc_cap_off; 73 struct timeout sc_to; 74 75 bus_addr_t sc_iobase, sc_iolimit; 76 bus_addr_t sc_membase, sc_memlimit; 77 bus_addr_t sc_pmembase, sc_pmemlimit; 78 79 pcireg_t sc_csr; 80 pcireg_t sc_bhlcr; 81 pcireg_t sc_bir; 82 pcireg_t sc_bcr; 83 pcireg_t sc_int; 84 pcireg_t sc_slcsr; 85 int sc_pmcsr_state; 86 }; 87 88 int ppbmatch(struct device *, void *, void *); 89 void ppbattach(struct device *, struct device *, void *); 90 int ppbdetach(struct device *self, int flags); 91 int ppbactivate(struct device *self, int act); 92 93 struct cfattach ppb_ca = { 94 sizeof(struct ppb_softc), ppbmatch, ppbattach, ppbdetach, ppbactivate 95 }; 96 97 struct cfdriver ppb_cd = { 98 NULL, "ppb", DV_DULL 99 }; 100 101 void ppb_alloc_resources(struct ppb_softc *, struct pci_attach_args *); 102 int ppb_intr(void *); 103 void ppb_hotplug_insert(void *, void *); 104 void ppb_hotplug_insert_finish(void *); 105 int ppb_hotplug_fixup(struct pci_attach_args *); 106 int ppb_hotplug_fixup_type0(pci_chipset_tag_t, pcitag_t, pcitag_t); 107 int ppb_hotplug_fixup_type1(pci_chipset_tag_t, pcitag_t, pcitag_t); 108 void ppb_hotplug_rescan(void *, void *); 109 void ppb_hotplug_remove(void *, void *); 110 int ppbprint(void *, const char *pnp); 111 112 int 113 ppbmatch(struct device *parent, void *match, void *aux) 114 { 115 struct pci_attach_args *pa = aux; 116 117 /* 118 * This device is mislabeled. It is not a PCI bridge. 119 */ 120 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VIATECH && 121 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_VIATECH_VT82C586_PWR) 122 return (0); 123 /* 124 * Check the ID register to see that it's a PCI bridge. 125 * If it is, we assume that we can deal with it; it _should_ 126 * work in a standardized way... 127 */ 128 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_BRIDGE && 129 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_BRIDGE_PCI) 130 return (1); 131 132 return (0); 133 } 134 135 void 136 ppbattach(struct device *parent, struct device *self, void *aux) 137 { 138 struct ppb_softc *sc = (struct ppb_softc *)self; 139 struct pci_attach_args *pa = aux; 140 pci_chipset_tag_t pc = pa->pa_pc; 141 struct pcibus_attach_args pba; 142 pci_intr_handle_t ih; 143 pcireg_t busdata, reg, blr; 144 char *name; 145 int pin; 146 147 sc->sc_pc = pc; 148 sc->sc_tag = pa->pa_tag; 149 150 busdata = pci_conf_read(pc, pa->pa_tag, PPB_REG_BUSINFO); 151 152 if (PPB_BUSINFO_SECONDARY(busdata) == 0) { 153 printf(": not configured by system firmware\n"); 154 return; 155 } 156 157 #if 0 158 /* 159 * XXX can't do this, because we're not given our bus number 160 * (we shouldn't need it), and because we've no way to 161 * decompose our tag. 162 */ 163 /* sanity check. */ 164 if (pa->pa_bus != PPB_BUSINFO_PRIMARY(busdata)) 165 panic("ppbattach: bus in tag (%d) != bus in reg (%d)", 166 pa->pa_bus, PPB_BUSINFO_PRIMARY(busdata)); 167 #endif 168 169 /* Check for PCI Express capabilities and setup hotplug support. */ 170 if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PCIEXPRESS, 171 &sc->sc_cap_off, ®) && (reg & PCI_PCIE_XCAP_SI)) { 172 #ifdef __i386__ 173 if (pci_intr_map(pa, &ih) == 0) 174 sc->sc_intrhand = pci_intr_establish(pc, ih, IPL_BIO, 175 ppb_intr, sc, self->dv_xname); 176 #else 177 if (pci_intr_map_msi(pa, &ih) == 0 || 178 pci_intr_map(pa, &ih) == 0) 179 sc->sc_intrhand = pci_intr_establish(pc, ih, IPL_BIO, 180 ppb_intr, sc, self->dv_xname); 181 #endif 182 183 if (sc->sc_intrhand) { 184 printf(": %s", pci_intr_string(pc, ih)); 185 186 /* Enable hotplug interrupt. */ 187 reg = pci_conf_read(pc, pa->pa_tag, 188 sc->sc_cap_off + PCI_PCIE_SLCSR); 189 reg |= (PCI_PCIE_SLCSR_HPE | PCI_PCIE_SLCSR_PDE); 190 pci_conf_write(pc, pa->pa_tag, 191 sc->sc_cap_off + PCI_PCIE_SLCSR, reg); 192 193 timeout_set(&sc->sc_to, ppb_hotplug_insert_finish, sc); 194 } 195 } 196 197 printf("\n"); 198 199 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL || 200 (PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82801BA_HPB && 201 PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_82801BAM_HPB)) 202 ppb_alloc_resources(sc, pa); 203 204 for (pin = PCI_INTERRUPT_PIN_A; pin <= PCI_INTERRUPT_PIN_D; pin++) { 205 pa->pa_intrpin = pa->pa_rawintrpin = pin; 206 pa->pa_intrline = 0; 207 pci_intr_map(pa, &sc->sc_ih[pin - PCI_INTERRUPT_PIN_A]); 208 } 209 210 /* 211 * The UltraSPARC-IIi APB doesn't implement the standard 212 * address range registers. 213 */ 214 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SUN && 215 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_SUN_SIMBA) 216 goto attach; 217 218 /* Figure out the I/O address range of the bridge. */ 219 blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_IOSTATUS); 220 sc->sc_iobase = (blr & 0x000000f0) << 8; 221 sc->sc_iolimit = (blr & 0x000f000) | 0x00000fff; 222 blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_IO_HI); 223 sc->sc_iobase |= (blr & 0x0000ffff) << 16; 224 sc->sc_iolimit |= (blr & 0xffff0000); 225 if (sc->sc_iolimit > sc->sc_iobase) { 226 name = malloc(32, M_DEVBUF, M_NOWAIT); 227 if (name) { 228 snprintf(name, 32, "%s pciio", sc->sc_dev.dv_xname); 229 sc->sc_ioex = extent_create(name, 0, 0xffffffff, 230 M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); 231 extent_free(sc->sc_ioex, sc->sc_iobase, 232 sc->sc_iolimit - sc->sc_iobase + 1, EX_NOWAIT); 233 } 234 } 235 236 /* Figure out the memory mapped I/O address range of the bridge. */ 237 blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_MEM); 238 sc->sc_membase = (blr & 0x0000fff0) << 16; 239 sc->sc_memlimit = (blr & 0xfff00000) | 0x000fffff; 240 if (sc->sc_memlimit > sc->sc_membase) { 241 name = malloc(32, M_DEVBUF, M_NOWAIT); 242 if (name) { 243 snprintf(name, 32, "%s pcimem", sc->sc_dev.dv_xname); 244 sc->sc_memex = extent_create(name, 0, 0xffffffff, 245 M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); 246 extent_free(sc->sc_memex, sc->sc_membase, 247 sc->sc_memlimit - sc->sc_membase + 1, 248 EX_NOWAIT); 249 } 250 } 251 252 /* Figure out the prefetchable MMI/O address range of the bridge. */ 253 blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_PREFMEM); 254 sc->sc_pmembase = (blr & 0x0000fff0) << 16; 255 sc->sc_pmemlimit = (blr & 0xfff00000) | 0x000fffff; 256 #ifdef __LP64__ /* XXX because extents use long... */ 257 blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_PREFBASE_HI32); 258 sc->sc_pmembase |= ((uint64_t)blr) << 32; 259 blr = pci_conf_read(pc, pa->pa_tag, PPB_REG_PREFLIM_HI32); 260 sc->sc_pmemlimit |= ((uint64_t)blr) << 32; 261 #endif 262 if (sc->sc_pmemlimit > sc->sc_pmembase) { 263 name = malloc(32, M_DEVBUF, M_NOWAIT); 264 if (name) { 265 snprintf(name, 32, "%s pcipmem", sc->sc_dev.dv_xname); 266 sc->sc_pmemex = extent_create(name, 0, (u_long)-1L, 267 M_DEVBUF, NULL, 0, EX_NOWAIT | EX_FILLED); 268 extent_free(sc->sc_pmemex, sc->sc_pmembase, 269 sc->sc_pmemlimit - sc->sc_pmembase + 1, 270 EX_NOWAIT); 271 } 272 } 273 274 /* 275 * The Intel 82801BAM Hub-to-PCI can decode subtractively. 276 * XXX We probably should handle subtractive decode bridges 277 * in general. 278 */ 279 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL && 280 (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BA_HPB || 281 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_82801BAM_HPB)) { 282 if (sc->sc_ioex == NULL) 283 sc->sc_ioex = pa->pa_ioex; 284 if (sc->sc_memex == NULL) 285 sc->sc_memex = pa->pa_memex; 286 } 287 288 attach: 289 /* 290 * Attach the PCI bus that hangs off of it. 291 * 292 * XXX Don't pass-through Memory Read Multiple. Should we? 293 * XXX Consult the spec... 294 */ 295 bzero(&pba, sizeof(pba)); 296 pba.pba_busname = "pci"; 297 pba.pba_iot = pa->pa_iot; 298 pba.pba_memt = pa->pa_memt; 299 pba.pba_dmat = pa->pa_dmat; 300 pba.pba_pc = pc; 301 pba.pba_flags = pa->pa_flags & ~PCI_FLAGS_MRM_OKAY; 302 pba.pba_ioex = sc->sc_ioex; 303 pba.pba_memex = sc->sc_memex; 304 pba.pba_pmemex = sc->sc_pmemex; 305 pba.pba_domain = pa->pa_domain; 306 pba.pba_bus = PPB_BUSINFO_SECONDARY(busdata); 307 pba.pba_bridgeih = sc->sc_ih; 308 pba.pba_bridgetag = &sc->sc_tag; 309 pba.pba_intrswiz = pa->pa_intrswiz; 310 pba.pba_intrtag = pa->pa_intrtag; 311 312 sc->sc_psc = config_found(self, &pba, ppbprint); 313 } 314 315 int 316 ppbdetach(struct device *self, int flags) 317 { 318 struct ppb_softc *sc = (struct ppb_softc *)self; 319 char *name; 320 int rv; 321 322 if (sc->sc_intrhand) 323 pci_intr_disestablish(sc->sc_pc, sc->sc_intrhand); 324 325 rv = config_detach_children(self, flags); 326 327 if (sc->sc_ioex) { 328 name = sc->sc_ioex->ex_name; 329 extent_destroy(sc->sc_ioex); 330 free(name, M_DEVBUF); 331 } 332 333 if (sc->sc_memex) { 334 name = sc->sc_memex->ex_name; 335 extent_destroy(sc->sc_memex); 336 free(name, M_DEVBUF); 337 } 338 339 if (sc->sc_pmemex) { 340 name = sc->sc_pmemex->ex_name; 341 extent_destroy(sc->sc_pmemex); 342 free(name, M_DEVBUF); 343 } 344 345 return (rv); 346 } 347 348 int 349 ppbactivate(struct device *self, int act) 350 { 351 struct ppb_softc *sc = (void *)self; 352 pci_chipset_tag_t pc = sc->sc_pc; 353 pcitag_t tag = sc->sc_tag; 354 pcireg_t blr, reg; 355 int rv = 0; 356 357 switch (act) { 358 case DVACT_QUIESCE: 359 rv = config_activate_children(self, act); 360 break; 361 case DVACT_SUSPEND: 362 rv = config_activate_children(self, act); 363 364 /* Save registers that may get lost. */ 365 sc->sc_csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 366 sc->sc_bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); 367 sc->sc_bir = pci_conf_read(pc, tag, PPB_REG_BUSINFO); 368 sc->sc_bcr = pci_conf_read(pc, tag, PPB_REG_BRIDGECONTROL); 369 sc->sc_int = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); 370 if (sc->sc_cap_off) 371 sc->sc_slcsr = pci_conf_read(pc, tag, 372 sc->sc_cap_off + PCI_PCIE_SLCSR); 373 374 if (pci_dopm) { 375 /* Place the bridge into D3. */ 376 sc->sc_pmcsr_state = pci_get_powerstate(pc, tag); 377 pci_set_powerstate(pc, tag, PCI_PMCSR_STATE_D3); 378 } 379 break; 380 case DVACT_RESUME: 381 if (pci_dopm) { 382 /* Restore power. */ 383 pci_set_powerstate(pc, tag, sc->sc_pmcsr_state); 384 } 385 386 /* Restore the registers saved above. */ 387 pci_conf_write(pc, tag, PCI_BHLC_REG, sc->sc_bhlcr); 388 pci_conf_write(pc, tag, PPB_REG_BUSINFO, sc->sc_bir); 389 pci_conf_write(pc, tag, PPB_REG_BRIDGECONTROL, sc->sc_bcr); 390 pci_conf_write(pc, tag, PCI_INTERRUPT_REG, sc->sc_int); 391 if (sc->sc_cap_off) 392 pci_conf_write(pc, tag, 393 sc->sc_cap_off + PCI_PCIE_SLCSR, sc->sc_slcsr); 394 395 /* Restore I/O window. */ 396 blr = pci_conf_read(pc, tag, PPB_REG_IOSTATUS); 397 blr &= 0xffff0000; 398 blr |= sc->sc_iolimit & PPB_IO_MASK; 399 blr |= (sc->sc_iobase >> PPB_IO_SHIFT); 400 pci_conf_write(pc, tag, PPB_REG_IOSTATUS, blr); 401 blr = (sc->sc_iobase & 0xffff0000) >> 16; 402 blr |= sc->sc_iolimit & 0xffff0000; 403 pci_conf_write(pc, tag, PPB_REG_IO_HI, blr); 404 405 /* Restore memory mapped I/O window. */ 406 blr = sc->sc_memlimit & PPB_MEM_MASK; 407 blr |= (sc->sc_membase >> PPB_MEM_SHIFT); 408 pci_conf_write(pc, tag, PPB_REG_MEM, blr); 409 410 /* Restore prefetchable MMI/O window. */ 411 blr = sc->sc_pmemlimit & PPB_MEM_MASK; 412 blr |= (sc->sc_pmembase >> PPB_MEM_SHIFT); 413 pci_conf_write(pc, tag, PPB_REG_PREFMEM, blr); 414 #ifdef __LP64__ 415 pci_conf_write(pc, tag, PPB_REG_PREFBASE_HI32, 416 sc->sc_pmembase >> 32); 417 pci_conf_write(pc, tag, PPB_REG_PREFLIM_HI32, 418 sc->sc_pmemlimit >> 32); 419 #endif 420 421 /* 422 * Restore command register last to avoid exposing 423 * uninitialised windows. 424 */ 425 reg = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 426 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, 427 (reg & 0xffff0000) | (sc->sc_csr & 0x0000ffff)); 428 429 rv = config_activate_children(self, act); 430 break; 431 } 432 return (rv); 433 } 434 435 void 436 ppb_alloc_resources(struct ppb_softc *sc, struct pci_attach_args *pa) 437 { 438 pci_chipset_tag_t pc = sc->sc_pc; 439 pcireg_t id, busdata, blr, bhlcr, type, csr; 440 pcireg_t addr, mask; 441 pcitag_t tag; 442 int bus, dev; 443 int reg, reg_start, reg_end, reg_rom; 444 int io_count = 0; 445 int mem_count = 0; 446 bus_addr_t start, end; 447 u_long base, size; 448 449 if (pa->pa_memex == NULL) 450 return; 451 452 busdata = pci_conf_read(pc, sc->sc_tag, PPB_REG_BUSINFO); 453 bus = PPB_BUSINFO_SECONDARY(busdata); 454 if (bus == 0) 455 return; 456 457 /* 458 * Count number of devices. If there are no devices behind 459 * this bridge, there's no point in allocating any address 460 * space. 461 */ 462 for (dev = 0; dev < pci_bus_maxdevs(pc, bus); dev++) { 463 tag = pci_make_tag(pc, bus, dev, 0); 464 id = pci_conf_read(pc, tag, PCI_ID_REG); 465 466 if (PCI_VENDOR(id) == PCI_VENDOR_INVALID || 467 PCI_VENDOR(id) == 0) 468 continue; 469 470 bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); 471 switch (PCI_HDRTYPE_TYPE(bhlcr)) { 472 case 0: 473 reg_start = PCI_MAPREG_START; 474 reg_end = PCI_MAPREG_END; 475 reg_rom = PCI_ROM_REG; 476 break; 477 case 1: /* PCI-PCI bridge */ 478 reg_start = PCI_MAPREG_START; 479 reg_end = PCI_MAPREG_PPB_END; 480 reg_rom = 0; /* 0x38 */ 481 break; 482 case 2: /* PCI-Cardbus bridge */ 483 reg_start = PCI_MAPREG_START; 484 reg_end = PCI_MAPREG_PCB_END; 485 reg_rom = 0; 486 break; 487 default: 488 return; 489 } 490 491 for (reg = reg_start; reg < reg_end; reg += 4) { 492 if (pci_mapreg_probe(pc, tag, reg, &type) == 0) 493 continue; 494 495 if (type == PCI_MAPREG_TYPE_IO) 496 io_count++; 497 else 498 mem_count++; 499 } 500 501 if (reg_rom != 0) { 502 addr = pci_conf_read(pc, tag, reg_rom); 503 pci_conf_write(pc, tag, reg_rom, ~PCI_ROM_ENABLE); 504 mask = pci_conf_read(pc, tag, reg_rom); 505 pci_conf_write(pc, tag, reg_rom, addr); 506 if (PCI_ROM_SIZE(mask)) 507 mem_count++; 508 } 509 } 510 511 csr = pci_conf_read(pc, sc->sc_tag, PCI_COMMAND_STATUS_REG); 512 513 /* 514 * Get the bridge in a consistent state. If memory mapped I/O 515 * is disabled, disabled the associated windows as well. 516 */ 517 if ((csr & PCI_COMMAND_MEM_ENABLE) == 0) { 518 pci_conf_write(pc, sc->sc_tag, PPB_REG_MEM, 0x0000ffff); 519 pci_conf_write(pc, sc->sc_tag, PPB_REG_PREFMEM, 0x0000ffff); 520 pci_conf_write(pc, sc->sc_tag, PPB_REG_PREFBASE_HI32, 0); 521 pci_conf_write(pc, sc->sc_tag, PPB_REG_PREFLIM_HI32, 0); 522 } 523 524 /* Allocate I/O address space if necessary. */ 525 if (io_count > 0 && pa->pa_ioex) { 526 blr = pci_conf_read(pc, sc->sc_tag, PPB_REG_IOSTATUS); 527 sc->sc_iobase = (blr << PPB_IO_SHIFT) & PPB_IO_MASK; 528 sc->sc_iolimit = (blr & PPB_IO_MASK) | 0x00000fff; 529 blr = pci_conf_read(pc, sc->sc_tag, PPB_REG_IO_HI); 530 sc->sc_iobase |= (blr & 0x0000ffff) << 16; 531 sc->sc_iolimit |= (blr & 0xffff0000); 532 if (sc->sc_iolimit < sc->sc_iobase || sc->sc_iobase == 0) { 533 start = max(PCI_IO_START, pa->pa_ioex->ex_start); 534 end = min(PCI_IO_END, pa->pa_ioex->ex_end); 535 for (size = 0x2000; size >= PPB_IO_MIN; size >>= 1) 536 if (extent_alloc_subregion(pa->pa_ioex, start, 537 end, size, size, 0, 0, 0, &base) == 0) 538 break; 539 if (size >= PPB_IO_MIN) { 540 sc->sc_iobase = base; 541 sc->sc_iolimit = base + size - 1; 542 blr = pci_conf_read(pc, sc->sc_tag, 543 PPB_REG_IOSTATUS); 544 blr &= 0xffff0000; 545 blr |= sc->sc_iolimit & PPB_IO_MASK; 546 blr |= (sc->sc_iobase >> PPB_IO_SHIFT); 547 pci_conf_write(pc, sc->sc_tag, 548 PPB_REG_IOSTATUS, blr); 549 blr = (sc->sc_iobase & 0xffff0000) >> 16; 550 blr |= sc->sc_iolimit & 0xffff0000; 551 pci_conf_write(pc, sc->sc_tag, 552 PPB_REG_IO_HI, blr); 553 554 csr |= PCI_COMMAND_IO_ENABLE; 555 } 556 } 557 } 558 559 /* Allocate memory mapped I/O address space if necessary. */ 560 if (mem_count > 0 && pa->pa_memex) { 561 blr = pci_conf_read(pc, sc->sc_tag, PPB_REG_MEM); 562 sc->sc_membase = (blr << PPB_MEM_SHIFT) & PPB_MEM_MASK; 563 sc->sc_memlimit = (blr & PPB_MEM_MASK) | 0x000fffff; 564 if (sc->sc_memlimit < sc->sc_membase || sc->sc_membase == 0) { 565 start = max(PCI_MEM_START, pa->pa_memex->ex_start); 566 end = min(PCI_MEM_END, pa->pa_memex->ex_end); 567 for (size = 0x2000000; size >= PPB_MEM_MIN; size >>= 1) 568 if (extent_alloc_subregion(pa->pa_memex, start, 569 end, size, size, 0, 0, 0, &base) == 0) 570 break; 571 if (size >= PPB_MEM_MIN) { 572 sc->sc_membase = base; 573 sc->sc_memlimit = base + size - 1; 574 blr = sc->sc_memlimit & PPB_MEM_MASK; 575 blr |= (sc->sc_membase >> PPB_MEM_SHIFT); 576 pci_conf_write(pc, sc->sc_tag, 577 PPB_REG_MEM, blr); 578 579 csr |= PCI_COMMAND_MEM_ENABLE; 580 } 581 } 582 } 583 584 pci_conf_write(pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, csr); 585 } 586 587 int 588 ppb_intr(void *arg) 589 { 590 struct ppb_softc *sc = arg; 591 pcireg_t reg; 592 593 /* 594 * XXX ignore hotplug events while in autoconf. On some 595 * machines with onboard re(4), we get a bogus hotplug remove 596 * event when we reset that device. Ignoring that event makes 597 * sure we will not try to forcibly detach re(4) when it isn't 598 * ready to deal with that. 599 */ 600 if (cold) 601 return (0); 602 603 reg = pci_conf_read(sc->sc_pc, sc->sc_tag, 604 sc->sc_cap_off + PCI_PCIE_SLCSR); 605 if (reg & PCI_PCIE_SLCSR_PDC) { 606 if (reg & PCI_PCIE_SLCSR_PDS) 607 workq_add_task(NULL, 0, ppb_hotplug_insert, sc, NULL); 608 else 609 workq_add_task(NULL, 0, ppb_hotplug_remove, sc, NULL); 610 611 /* Clear interrupts. */ 612 pci_conf_write(sc->sc_pc, sc->sc_tag, 613 sc->sc_cap_off + PCI_PCIE_SLCSR, reg); 614 return (1); 615 } 616 617 return (0); 618 } 619 620 #ifdef PCI_MACHDEP_ENUMERATE_BUS 621 #define pci_enumerate_bus PCI_MACHDEP_ENUMERATE_BUS 622 #else 623 extern int pci_enumerate_bus(struct pci_softc *, 624 int (*)(struct pci_attach_args *), struct pci_attach_args *); 625 #endif 626 627 void 628 ppb_hotplug_insert(void *arg1, void *arg2) 629 { 630 struct ppb_softc *sc = arg1; 631 struct pci_softc *psc = (struct pci_softc *)sc->sc_psc; 632 633 if (!LIST_EMPTY(&psc->sc_devs)) 634 return; 635 636 /* XXX Powerup the card. */ 637 638 /* XXX Turn on LEDs. */ 639 640 /* Wait a second for things to settle. */ 641 timeout_add_sec(&sc->sc_to, 1); 642 } 643 644 void 645 ppb_hotplug_insert_finish(void *arg) 646 { 647 workq_add_task(NULL, 0, ppb_hotplug_rescan, arg, NULL); 648 } 649 650 int 651 ppb_hotplug_fixup(struct pci_attach_args *pa) 652 { 653 pcireg_t bhlcr; 654 655 bhlcr = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG); 656 switch (PCI_HDRTYPE_TYPE(bhlcr)) { 657 case 0: 658 return ppb_hotplug_fixup_type0(pa->pa_pc, 659 pa->pa_tag, *pa->pa_bridgetag); 660 case 1: 661 return ppb_hotplug_fixup_type1(pa->pa_pc, 662 pa->pa_tag, *pa->pa_bridgetag); 663 default: 664 return (0); 665 } 666 } 667 668 int 669 ppb_hotplug_fixup_type0(pci_chipset_tag_t pc, pcitag_t tag, pcitag_t bridgetag) 670 { 671 pcireg_t intr; 672 int line; 673 674 /* 675 * Fill in the interrupt line for platforms that need it. 676 * 677 * XXX We assume that the interrupt line matches the line used 678 * by the PCI Express bridge. This may not be true. 679 */ 680 intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); 681 if (PCI_INTERRUPT_PIN(intr) != PCI_INTERRUPT_PIN_NONE && 682 PCI_INTERRUPT_LINE(intr) == 0) { 683 /* Get the interrupt line from our parent. */ 684 intr = pci_conf_read(pc, bridgetag, PCI_INTERRUPT_REG); 685 line = PCI_INTERRUPT_LINE(intr); 686 687 intr = pci_conf_read(pc, tag, PCI_INTERRUPT_REG); 688 intr &= ~(PCI_INTERRUPT_LINE_MASK << PCI_INTERRUPT_LINE_SHIFT); 689 intr |= line << PCI_INTERRUPT_LINE_SHIFT; 690 pci_conf_write(pc, tag, PCI_INTERRUPT_REG, intr); 691 } 692 693 return (0); 694 } 695 696 int 697 ppb_hotplug_fixup_type1(pci_chipset_tag_t pc, pcitag_t tag, pcitag_t bridgetag) 698 { 699 pcireg_t bhlcr, bir, csr, val; 700 int bus, dev, reg; 701 702 bir = pci_conf_read(pc, bridgetag, PPB_REG_BUSINFO); 703 if (PPB_BUSINFO_SUBORDINATE(bir) <= PPB_BUSINFO_SECONDARY(bir)) 704 return (0); 705 706 bus = PPB_BUSINFO_SECONDARY(bir); 707 bir = pci_conf_read(pc, tag, PPB_REG_BUSINFO); 708 bir &= (0xff << 24); 709 bir |= bus++; 710 bir |= (bus << 8); 711 bir |= (bus << 16); 712 pci_conf_write(pc, tag, PPB_REG_BUSINFO, bir); 713 714 for (reg = PPB_REG_IOSTATUS; reg < PPB_REG_BRIDGECONTROL; reg += 4) { 715 val = pci_conf_read(pc, bridgetag, reg); 716 pci_conf_write(pc, tag, reg, val); 717 } 718 719 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 720 csr |= PCI_COMMAND_IO_ENABLE | PCI_COMMAND_MEM_ENABLE; 721 csr |= PCI_COMMAND_MASTER_ENABLE; 722 csr |= PCI_COMMAND_INVALIDATE_ENABLE; 723 csr |= PCI_COMMAND_SERR_ENABLE; 724 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, csr); 725 726 for (dev = 0; dev < pci_bus_maxdevs(pc, bus); dev++) { 727 tag = pci_make_tag(pc, bus, dev, 0); 728 729 bhlcr = pci_conf_read(pc, tag, PCI_BHLC_REG); 730 if (PCI_HDRTYPE_TYPE(bhlcr) != 0) 731 continue; 732 733 ppb_hotplug_fixup_type0(pc, tag, bridgetag); 734 } 735 736 return (0); 737 } 738 739 void 740 ppb_hotplug_rescan(void *arg1, void *arg2) 741 { 742 struct ppb_softc *sc = arg1; 743 struct pci_softc *psc = (struct pci_softc *)sc->sc_psc; 744 745 if (psc) { 746 /* Assign resources. */ 747 pci_enumerate_bus(psc, ppb_hotplug_fixup, NULL); 748 749 /* Attach devices. */ 750 pci_enumerate_bus(psc, NULL, NULL); 751 } 752 } 753 754 void 755 ppb_hotplug_remove(void *arg1, void *arg2) 756 { 757 struct ppb_softc *sc = arg1; 758 struct pci_softc *psc = (struct pci_softc *)sc->sc_psc; 759 760 if (psc) { 761 pci_detach_devices(psc, DETACH_FORCE); 762 763 /* 764 * XXX Allocate the entire window with EX_CONFLICTOK 765 * such that we can easily free it. 766 */ 767 if (sc->sc_ioex != NULL) { 768 extent_alloc_region(sc->sc_ioex, sc->sc_iobase, 769 sc->sc_iolimit - sc->sc_iobase + 1, 770 EX_NOWAIT | EX_CONFLICTOK); 771 extent_free(sc->sc_ioex, sc->sc_iobase, 772 sc->sc_iolimit - sc->sc_iobase + 1, EX_NOWAIT); 773 } 774 775 if (sc->sc_memex != NULL) { 776 extent_alloc_region(sc->sc_memex, sc->sc_membase, 777 sc->sc_memlimit - sc->sc_membase + 1, 778 EX_NOWAIT | EX_CONFLICTOK); 779 extent_free(sc->sc_memex, sc->sc_membase, 780 sc->sc_memlimit - sc->sc_membase + 1, EX_NOWAIT); 781 } 782 783 if (sc->sc_pmemex != NULL) { 784 extent_alloc_region(sc->sc_pmemex, sc->sc_pmembase, 785 sc->sc_pmemlimit - sc->sc_pmembase + 1, 786 EX_NOWAIT | EX_CONFLICTOK); 787 extent_free(sc->sc_pmemex, sc->sc_pmembase, 788 sc->sc_pmemlimit - sc->sc_pmembase + 1, EX_NOWAIT); 789 } 790 } 791 } 792 793 int 794 ppbprint(void *aux, const char *pnp) 795 { 796 struct pcibus_attach_args *pba = aux; 797 798 /* only PCIs can attach to PPBs; easy. */ 799 if (pnp) 800 printf("pci at %s", pnp); 801 printf(" bus %d", pba->pba_bus); 802 return (UNCONF); 803 } 804