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