1 /*- 2 * Copyright (c) 2011 Nathan Whitehorn 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27 #include <sys/param.h> 28 #include <sys/systm.h> 29 #include <sys/module.h> 30 #include <sys/bus.h> 31 #include <sys/conf.h> 32 #include <sys/kernel.h> 33 #include <sys/rman.h> 34 35 #include <dev/ofw/openfirm.h> 36 #include <dev/ofw/ofw_pci.h> 37 #include <dev/ofw/ofw_bus.h> 38 #include <dev/ofw/ofw_bus_subr.h> 39 #include <dev/ofw/ofwpci.h> 40 41 #include <dev/pci/pcivar.h> 42 #include <dev/pci/pcireg.h> 43 #include <dev/pci/pcib_private.h> 44 45 #include <machine/bus.h> 46 #include <machine/md_var.h> 47 #include <machine/resource.h> 48 49 #include <vm/vm.h> 50 #include <vm/pmap.h> 51 52 #include "pcib_if.h" 53 54 /* 55 * If it is necessary to set another value of this for 56 * some platforms it should be set at fdt.h file 57 */ 58 #ifndef PCI_MAP_INTR 59 #define PCI_MAP_INTR 4 60 #endif 61 62 #define PCI_INTR_PINS 4 63 64 /* 65 * bus interface. 66 */ 67 static struct rman *ofw_pcib_get_rman(device_t, int, u_int); 68 static struct resource * ofw_pcib_alloc_resource(device_t, device_t, 69 int, int *, rman_res_t, rman_res_t, rman_res_t, u_int); 70 static int ofw_pcib_release_resource(device_t, device_t, struct resource *); 71 static int ofw_pcib_activate_resource(device_t, device_t, struct resource *); 72 static int ofw_pcib_deactivate_resource(device_t, device_t, struct resource *); 73 static int ofw_pcib_adjust_resource(device_t, device_t, 74 struct resource *, rman_res_t, rman_res_t); 75 static int ofw_pcib_map_resource(device_t, device_t, struct resource *, 76 struct resource_map_request *, struct resource_map *); 77 static int ofw_pcib_unmap_resource(device_t, device_t, struct resource *, 78 struct resource_map *); 79 static int ofw_pcib_translate_resource(device_t bus, int type, 80 rman_res_t start, rman_res_t *newstart); 81 82 #ifdef __powerpc__ 83 static bus_space_tag_t ofw_pcib_bus_get_bus_tag(device_t, device_t); 84 #endif 85 86 /* 87 * pcib interface 88 */ 89 static int ofw_pcib_maxslots(device_t); 90 91 /* 92 * ofw_bus interface 93 */ 94 static phandle_t ofw_pcib_get_node(device_t, device_t); 95 96 /* 97 * local methods 98 */ 99 static int ofw_pcib_fill_ranges(phandle_t, struct ofw_pci_range *); 100 101 /* 102 * Driver methods. 103 */ 104 static device_method_t ofw_pcib_methods[] = { 105 /* Device interface */ 106 DEVMETHOD(device_attach, ofw_pcib_attach), 107 108 /* Bus interface */ 109 DEVMETHOD(bus_print_child, bus_generic_print_child), 110 DEVMETHOD(bus_read_ivar, ofw_pcib_read_ivar), 111 DEVMETHOD(bus_write_ivar, ofw_pcib_write_ivar), 112 DEVMETHOD(bus_setup_intr, bus_generic_setup_intr), 113 DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr), 114 DEVMETHOD(bus_get_rman, ofw_pcib_get_rman), 115 DEVMETHOD(bus_alloc_resource, ofw_pcib_alloc_resource), 116 DEVMETHOD(bus_release_resource, ofw_pcib_release_resource), 117 DEVMETHOD(bus_activate_resource, ofw_pcib_activate_resource), 118 DEVMETHOD(bus_deactivate_resource, ofw_pcib_deactivate_resource), 119 DEVMETHOD(bus_adjust_resource, ofw_pcib_adjust_resource), 120 DEVMETHOD(bus_map_resource, ofw_pcib_map_resource), 121 DEVMETHOD(bus_unmap_resource, ofw_pcib_unmap_resource), 122 DEVMETHOD(bus_translate_resource, ofw_pcib_translate_resource), 123 #ifdef __powerpc__ 124 DEVMETHOD(bus_get_bus_tag, ofw_pcib_bus_get_bus_tag), 125 #endif 126 127 /* pcib interface */ 128 DEVMETHOD(pcib_maxslots, ofw_pcib_maxslots), 129 DEVMETHOD(pcib_route_interrupt, ofw_pcib_route_interrupt), 130 DEVMETHOD(pcib_request_feature, pcib_request_feature_allow), 131 132 /* ofw_bus interface */ 133 DEVMETHOD(ofw_bus_get_node, ofw_pcib_get_node), 134 135 DEVMETHOD_END 136 }; 137 138 DEFINE_CLASS_0(ofw_pcib, ofw_pcib_driver, ofw_pcib_methods, 0); 139 140 int 141 ofw_pcib_init(device_t dev) 142 { 143 struct ofw_pci_softc *sc; 144 phandle_t node; 145 u_int32_t busrange[2]; 146 struct ofw_pci_range *rp; 147 int i, error; 148 struct ofw_pci_cell_info *cell_info; 149 150 node = ofw_bus_get_node(dev); 151 sc = device_get_softc(dev); 152 sc->sc_initialized = 1; 153 sc->sc_range = NULL; 154 sc->sc_pci_domain = device_get_unit(dev); 155 156 cell_info = (struct ofw_pci_cell_info *)malloc(sizeof(*cell_info), 157 M_DEVBUF, M_WAITOK | M_ZERO); 158 159 sc->sc_cell_info = cell_info; 160 161 if (OF_getencprop(node, "bus-range", busrange, sizeof(busrange)) != 8) 162 busrange[0] = 0; 163 164 sc->sc_dev = dev; 165 sc->sc_node = node; 166 sc->sc_bus = busrange[0]; 167 168 if (sc->sc_quirks & OFW_PCI_QUIRK_RANGES_ON_CHILDREN) { 169 phandle_t c; 170 int n, i; 171 172 sc->sc_nrange = 0; 173 for (c = OF_child(node); c != 0; c = OF_peer(c)) { 174 n = ofw_pcib_nranges(c, cell_info); 175 if (n > 0) 176 sc->sc_nrange += n; 177 } 178 if (sc->sc_nrange == 0) { 179 error = ENXIO; 180 goto out; 181 } 182 sc->sc_range = malloc(sc->sc_nrange * sizeof(sc->sc_range[0]), 183 M_DEVBUF, M_WAITOK); 184 i = 0; 185 for (c = OF_child(node); c != 0; c = OF_peer(c)) { 186 n = ofw_pcib_fill_ranges(c, &sc->sc_range[i]); 187 if (n > 0) 188 i += n; 189 } 190 KASSERT(i == sc->sc_nrange, ("range count mismatch")); 191 } else { 192 sc->sc_nrange = ofw_pcib_nranges(node, cell_info); 193 if (sc->sc_nrange <= 0) { 194 device_printf(dev, "could not getranges\n"); 195 error = ENXIO; 196 goto out; 197 } 198 sc->sc_range = malloc(sc->sc_nrange * sizeof(sc->sc_range[0]), 199 M_DEVBUF, M_WAITOK); 200 ofw_pcib_fill_ranges(node, sc->sc_range); 201 } 202 203 sc->sc_io_rman.rm_type = RMAN_ARRAY; 204 sc->sc_io_rman.rm_descr = "PCI I/O Ports"; 205 error = rman_init(&sc->sc_io_rman); 206 if (error != 0) { 207 device_printf(dev, "rman_init() failed. error = %d\n", error); 208 goto out; 209 } 210 211 sc->sc_mem_rman.rm_type = RMAN_ARRAY; 212 sc->sc_mem_rman.rm_descr = "PCI Non Prefetchable Memory"; 213 error = rman_init(&sc->sc_mem_rman); 214 if (error != 0) { 215 device_printf(dev, "rman_init() failed. error = %d\n", error); 216 goto out_mem_rman; 217 } 218 219 sc->sc_pmem_rman.rm_type = RMAN_ARRAY; 220 sc->sc_pmem_rman.rm_descr = "PCI Prefetchable Memory"; 221 error = rman_init(&sc->sc_pmem_rman); 222 if (error != 0) { 223 device_printf(dev, "rman_init() failed. error = %d\n", error); 224 goto out_pmem_rman; 225 } 226 227 for (i = 0; i < sc->sc_nrange; i++) { 228 error = 0; 229 rp = sc->sc_range + i; 230 231 if (sc->sc_range_mask & ((uint64_t)1 << i)) 232 continue; 233 switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { 234 case OFW_PCI_PHYS_HI_SPACE_CONFIG: 235 break; 236 case OFW_PCI_PHYS_HI_SPACE_IO: 237 error = rman_manage_region(&sc->sc_io_rman, rp->pci, 238 rp->pci + rp->size - 1); 239 break; 240 case OFW_PCI_PHYS_HI_SPACE_MEM32: 241 case OFW_PCI_PHYS_HI_SPACE_MEM64: 242 if (rp->pci_hi & OFW_PCI_PHYS_HI_PREFETCHABLE) { 243 sc->sc_have_pmem = 1; 244 error = rman_manage_region(&sc->sc_pmem_rman, 245 rp->pci, rp->pci + rp->size - 1); 246 } else { 247 error = rman_manage_region(&sc->sc_mem_rman, 248 rp->pci, rp->pci + rp->size - 1); 249 } 250 break; 251 } 252 253 if (error != 0) { 254 device_printf(dev, 255 "rman_manage_region(%x, %#jx, %#jx) failed. " 256 "error = %d\n", rp->pci_hi & 257 OFW_PCI_PHYS_HI_SPACEMASK, rp->pci, 258 rp->pci + rp->size - 1, error); 259 goto out_full; 260 } 261 } 262 263 ofw_bus_setup_iinfo(node, &sc->sc_pci_iinfo, sizeof(cell_t)); 264 return (0); 265 266 out_full: 267 rman_fini(&sc->sc_pmem_rman); 268 out_pmem_rman: 269 rman_fini(&sc->sc_mem_rman); 270 out_mem_rman: 271 rman_fini(&sc->sc_io_rman); 272 out: 273 free(sc->sc_cell_info, M_DEVBUF); 274 free(sc->sc_range, M_DEVBUF); 275 276 return (error); 277 } 278 279 void 280 ofw_pcib_fini(device_t dev) 281 { 282 struct ofw_pci_softc *sc; 283 284 sc = device_get_softc(dev); 285 free(sc->sc_cell_info, M_DEVBUF); 286 free(sc->sc_range, M_DEVBUF); 287 rman_fini(&sc->sc_io_rman); 288 rman_fini(&sc->sc_mem_rman); 289 rman_fini(&sc->sc_pmem_rman); 290 } 291 292 int 293 ofw_pcib_attach(device_t dev) 294 { 295 struct ofw_pci_softc *sc; 296 int error; 297 298 sc = device_get_softc(dev); 299 if (!sc->sc_initialized) { 300 error = ofw_pcib_init(dev); 301 if (error != 0) 302 return (error); 303 } 304 305 device_add_child(dev, "pci", -1); 306 return (bus_generic_attach(dev)); 307 } 308 309 static int 310 ofw_pcib_maxslots(device_t dev) 311 { 312 313 return (PCI_SLOTMAX); 314 } 315 316 int 317 ofw_pcib_route_interrupt(device_t bus, device_t dev, int pin) 318 { 319 struct ofw_pci_softc *sc; 320 struct ofw_pci_register reg; 321 uint32_t pintr, mintr[PCI_MAP_INTR]; 322 int intrcells; 323 phandle_t iparent; 324 325 sc = device_get_softc(bus); 326 pintr = pin; 327 328 /* Fabricate imap information in case this isn't an OFW device */ 329 bzero(®, sizeof(reg)); 330 reg.phys_hi = (pci_get_bus(dev) << OFW_PCI_PHYS_HI_BUSSHIFT) | 331 (pci_get_slot(dev) << OFW_PCI_PHYS_HI_DEVICESHIFT) | 332 (pci_get_function(dev) << OFW_PCI_PHYS_HI_FUNCTIONSHIFT); 333 334 intrcells = ofw_bus_lookup_imap(ofw_bus_get_node(dev), 335 &sc->sc_pci_iinfo, ®, sizeof(reg), &pintr, sizeof(pintr), 336 mintr, sizeof(mintr), &iparent); 337 if (intrcells != 0) { 338 pintr = ofw_bus_map_intr(dev, iparent, intrcells, mintr); 339 return (pintr); 340 } 341 342 /* 343 * Maybe it's a real interrupt, not an intpin 344 */ 345 if (pin > PCI_INTR_PINS) 346 return (pin); 347 348 device_printf(bus, "could not route pin %d for device %d.%d\n", 349 pin, pci_get_slot(dev), pci_get_function(dev)); 350 return (PCI_INVALID_IRQ); 351 } 352 353 int 354 ofw_pcib_read_ivar(device_t dev, device_t child, int which, uintptr_t *result) 355 { 356 struct ofw_pci_softc *sc; 357 358 sc = device_get_softc(dev); 359 360 switch (which) { 361 case PCIB_IVAR_DOMAIN: 362 *result = sc->sc_pci_domain; 363 return (0); 364 case PCIB_IVAR_BUS: 365 *result = sc->sc_bus; 366 return (0); 367 default: 368 break; 369 } 370 371 return (ENOENT); 372 } 373 374 int 375 ofw_pcib_write_ivar(device_t dev, device_t child, int which, uintptr_t value) 376 { 377 struct ofw_pci_softc *sc; 378 379 sc = device_get_softc(dev); 380 381 switch (which) { 382 case PCIB_IVAR_BUS: 383 sc->sc_bus = value; 384 return (0); 385 default: 386 break; 387 } 388 389 return (ENOENT); 390 } 391 392 int 393 ofw_pcib_nranges(phandle_t node, struct ofw_pci_cell_info *info) 394 { 395 ssize_t nbase_ranges; 396 397 if (info == NULL) 398 return (-1); 399 400 info->host_address_cells = 1; 401 info->size_cells = 2; 402 info->pci_address_cell = 3; 403 404 OF_getencprop(OF_parent(node), "#address-cells", 405 &(info->host_address_cells), sizeof(info->host_address_cells)); 406 OF_getencprop(node, "#address-cells", 407 &(info->pci_address_cell), sizeof(info->pci_address_cell)); 408 OF_getencprop(node, "#size-cells", &(info->size_cells), 409 sizeof(info->size_cells)); 410 411 nbase_ranges = OF_getproplen(node, "ranges"); 412 if (nbase_ranges <= 0) 413 return (-1); 414 415 return (nbase_ranges / sizeof(cell_t) / 416 (info->pci_address_cell + info->host_address_cells + 417 info->size_cells)); 418 } 419 420 static struct resource * 421 ofw_pcib_alloc_resource(device_t bus, device_t child, int type, int *rid, 422 rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) 423 { 424 #if defined(NEW_PCIB) && defined(PCI_RES_BUS) 425 struct ofw_pci_softc *sc; 426 427 sc = device_get_softc(bus); 428 #endif 429 switch (type) { 430 #if defined(NEW_PCIB) && defined(PCI_RES_BUS) 431 case PCI_RES_BUS: 432 return (pci_domain_alloc_bus(sc->sc_pci_domain, child, rid, 433 start, end, count, flags)); 434 #endif 435 case SYS_RES_MEMORY: 436 case SYS_RES_IOPORT: 437 return (bus_generic_rman_alloc_resource(bus, child, type, rid, 438 start, end, count, flags)); 439 default: 440 return (bus_generic_alloc_resource(bus, child, type, rid, 441 start, end, count, flags)); 442 } 443 } 444 445 static int 446 ofw_pcib_release_resource(device_t bus, device_t child, struct resource *res) 447 { 448 #if defined(NEW_PCIB) && defined(PCI_RES_BUS) 449 struct ofw_pci_softc *sc; 450 451 sc = device_get_softc(bus); 452 #endif 453 switch (rman_get_type(res)) { 454 #if defined(NEW_PCIB) && defined(PCI_RES_BUS) 455 case PCI_RES_BUS: 456 return (pci_domain_release_bus(sc->sc_pci_domain, child, res)); 457 #endif 458 case SYS_RES_MEMORY: 459 case SYS_RES_IOPORT: 460 return (bus_generic_rman_release_resource(bus, child, res)); 461 default: 462 return (bus_generic_release_resource(bus, child, res)); 463 } 464 } 465 466 static int 467 ofw_pcib_translate_resource(device_t bus, int type, rman_res_t start, 468 rman_res_t *newstart) 469 { 470 struct ofw_pci_softc *sc; 471 struct ofw_pci_range *rp; 472 int space; 473 474 sc = device_get_softc(bus); 475 476 /* 477 * Map this through the ranges list 478 */ 479 for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange && 480 rp->pci_hi != 0; rp++) { 481 if (start < rp->pci || start >= rp->pci + rp->size) 482 continue; 483 484 switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { 485 case OFW_PCI_PHYS_HI_SPACE_IO: 486 space = SYS_RES_IOPORT; 487 break; 488 case OFW_PCI_PHYS_HI_SPACE_MEM32: 489 case OFW_PCI_PHYS_HI_SPACE_MEM64: 490 space = SYS_RES_MEMORY; 491 break; 492 default: 493 space = -1; 494 } 495 496 if (type == space) { 497 start += (rp->host - rp->pci); 498 *newstart = start; 499 return (0); 500 } 501 } 502 return (ENOENT); 503 } 504 505 static int 506 ofw_pcib_activate_resource(device_t bus, device_t child, struct resource *res) 507 { 508 #if defined(NEW_PCIB) && defined(PCI_RES_BUS) 509 struct ofw_pci_softc *sc; 510 511 sc = device_get_softc(bus); 512 #endif 513 switch (rman_get_type(res)) { 514 #if defined(NEW_PCIB) && defined(PCI_RES_BUS) 515 case PCI_RES_BUS: 516 return (pci_domain_activate_bus(sc->sc_pci_domain, child, res)); 517 #endif 518 case SYS_RES_MEMORY: 519 case SYS_RES_IOPORT: 520 return (bus_generic_rman_activate_resource(bus, child, res)); 521 default: 522 return (bus_generic_activate_resource(bus, child, res)); 523 } 524 } 525 526 static int 527 ofw_pcib_map_resource(device_t dev, device_t child, struct resource *r, 528 struct resource_map_request *argsp, struct resource_map *map) 529 { 530 struct resource_map_request args; 531 struct ofw_pci_softc *sc; 532 struct ofw_pci_range *rp; 533 rman_res_t length, start; 534 int error, space; 535 536 /* Resources must be active to be mapped. */ 537 if (!(rman_get_flags(r) & RF_ACTIVE)) 538 return (ENXIO); 539 540 switch (rman_get_type(r)) { 541 case SYS_RES_MEMORY: 542 case SYS_RES_IOPORT: 543 break; 544 default: 545 return (EINVAL); 546 } 547 548 resource_init_map_request(&args); 549 error = resource_validate_map_request(r, argsp, &args, &start, &length); 550 if (error) 551 return (error); 552 553 /* 554 * Map this through the ranges list 555 */ 556 sc = device_get_softc(dev); 557 for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange && 558 rp->pci_hi != 0; rp++) { 559 if (start < rp->pci || start >= rp->pci + rp->size) 560 continue; 561 562 switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) { 563 case OFW_PCI_PHYS_HI_SPACE_IO: 564 space = SYS_RES_IOPORT; 565 break; 566 case OFW_PCI_PHYS_HI_SPACE_MEM32: 567 case OFW_PCI_PHYS_HI_SPACE_MEM64: 568 space = SYS_RES_MEMORY; 569 break; 570 default: 571 space = -1; 572 } 573 574 if (rman_get_type(r) == space) { 575 start += (rp->host - rp->pci); 576 break; 577 } 578 } 579 580 if (bootverbose) 581 printf("ofw_pci mapdev: start %jx, len %jd\n", start, length); 582 583 map->r_bustag = BUS_GET_BUS_TAG(child, child); 584 if (map->r_bustag == NULL) 585 return (ENOMEM); 586 587 error = bus_space_map(map->r_bustag, start, length, 0, 588 &map->r_bushandle); 589 if (error != 0) 590 return (error); 591 592 /* XXX for powerpc only? */ 593 map->r_vaddr = (void *)map->r_bushandle; 594 map->r_size = length; 595 return (0); 596 } 597 598 static int 599 ofw_pcib_unmap_resource(device_t dev, device_t child, struct resource *r, 600 struct resource_map *map) 601 { 602 switch (rman_get_type(r)) { 603 case SYS_RES_MEMORY: 604 case SYS_RES_IOPORT: 605 bus_space_unmap(map->r_bustag, map->r_bushandle, map->r_size); 606 return (0); 607 default: 608 return (EINVAL); 609 } 610 } 611 612 #ifdef __powerpc__ 613 static bus_space_tag_t 614 ofw_pcib_bus_get_bus_tag(device_t bus, device_t child) 615 { 616 617 return (&bs_le_tag); 618 } 619 #endif 620 621 static int 622 ofw_pcib_deactivate_resource(device_t bus, device_t child, struct resource *res) 623 { 624 #if defined(NEW_PCIB) && defined(PCI_RES_BUS) 625 struct ofw_pci_softc *sc; 626 627 sc = device_get_softc(bus); 628 #endif 629 switch (rman_get_type(res)) { 630 #if defined(NEW_PCIB) && defined(PCI_RES_BUS) 631 case PCI_RES_BUS: 632 return (pci_domain_deactivate_bus(sc->sc_pci_domain, child, 633 res)); 634 #endif 635 case SYS_RES_MEMORY: 636 case SYS_RES_IOPORT: 637 return (bus_generic_rman_deactivate_resource(bus, child, res)); 638 default: 639 return (bus_generic_deactivate_resource(bus, child, res)); 640 } 641 } 642 643 static int 644 ofw_pcib_adjust_resource(device_t bus, device_t child, 645 struct resource *res, rman_res_t start, rman_res_t end) 646 { 647 #if defined(NEW_PCIB) && defined(PCI_RES_BUS) 648 struct ofw_pci_softc *sc; 649 650 sc = device_get_softc(bus); 651 #endif 652 switch (rman_get_type(res)) { 653 #if defined(NEW_PCIB) && defined(PCI_RES_BUS) 654 case PCI_RES_BUS: 655 return (pci_domain_adjust_bus(sc->sc_pci_domain, child, res, 656 start, end)); 657 #endif 658 case SYS_RES_MEMORY: 659 case SYS_RES_IOPORT: 660 return (bus_generic_rman_adjust_resource(bus, child, res, 661 start, end)); 662 default: 663 return (bus_generic_adjust_resource(bus, child, res, start, 664 end)); 665 } 666 } 667 668 static phandle_t 669 ofw_pcib_get_node(device_t bus, device_t dev) 670 { 671 struct ofw_pci_softc *sc; 672 673 sc = device_get_softc(bus); 674 /* We only have one child, the PCI bus, which needs our own node. */ 675 676 return (sc->sc_node); 677 } 678 679 static int 680 ofw_pcib_fill_ranges(phandle_t node, struct ofw_pci_range *ranges) 681 { 682 int host_address_cells = 1, pci_address_cells = 3, size_cells = 2; 683 cell_t *base_ranges; 684 ssize_t nbase_ranges; 685 int nranges; 686 int i, j, k; 687 688 OF_getencprop(OF_parent(node), "#address-cells", &host_address_cells, 689 sizeof(host_address_cells)); 690 OF_getencprop(node, "#address-cells", &pci_address_cells, 691 sizeof(pci_address_cells)); 692 OF_getencprop(node, "#size-cells", &size_cells, sizeof(size_cells)); 693 694 nbase_ranges = OF_getproplen(node, "ranges"); 695 if (nbase_ranges <= 0) 696 return (-1); 697 nranges = nbase_ranges / sizeof(cell_t) / 698 (pci_address_cells + host_address_cells + size_cells); 699 700 base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK); 701 OF_getencprop(node, "ranges", base_ranges, nbase_ranges); 702 703 for (i = 0, j = 0; i < nranges; i++) { 704 ranges[i].pci_hi = base_ranges[j++]; 705 ranges[i].pci = 0; 706 for (k = 0; k < pci_address_cells - 1; k++) { 707 ranges[i].pci <<= 32; 708 ranges[i].pci |= base_ranges[j++]; 709 } 710 ranges[i].host = 0; 711 for (k = 0; k < host_address_cells; k++) { 712 ranges[i].host <<= 32; 713 ranges[i].host |= base_ranges[j++]; 714 } 715 ranges[i].size = 0; 716 for (k = 0; k < size_cells; k++) { 717 ranges[i].size <<= 32; 718 ranges[i].size |= base_ranges[j++]; 719 } 720 } 721 722 free(base_ranges, M_DEVBUF); 723 return (nranges); 724 } 725 726 static struct rman * 727 ofw_pcib_get_rman(device_t bus, int type, u_int flags) 728 { 729 struct ofw_pci_softc *sc; 730 731 sc = device_get_softc(bus); 732 switch (type) { 733 case SYS_RES_IOPORT: 734 return (&sc->sc_io_rman); 735 case SYS_RES_MEMORY: 736 if (sc->sc_have_pmem && (flags & RF_PREFETCHABLE)) 737 return (&sc->sc_pmem_rman); 738 else 739 return (&sc->sc_mem_rman); 740 default: 741 break; 742 } 743 744 return (NULL); 745 } 746