1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <sys/types.h> 29 #include <sys/stat.h> 30 #include <sys/sunndi.h> 31 #include <sys/pci.h> 32 #include <sys/pci_impl.h> 33 #include <sys/pci_cfgspace.h> 34 #include <sys/memlist.h> 35 #include <sys/bootconf.h> 36 #include <io/pci/mps_table.h> 37 #include <sys/pci_cfgspace.h> 38 #include <sys/pci_cfgspace_impl.h> 39 #include <sys/psw.h> 40 #include "../../../../common/pci/pci_strings.h" 41 #include <io/pciex/pcie_ck804_boot.h> 42 #include <sys/acpi/acpi.h> 43 #include <sys/acpica.h> 44 45 #define pci_getb (*pci_getb_func) 46 #define pci_getw (*pci_getw_func) 47 #define pci_getl (*pci_getl_func) 48 #define pci_putb (*pci_putb_func) 49 #define pci_putw (*pci_putw_func) 50 #define pci_putl (*pci_putl_func) 51 #define dcmn_err if (pci_boot_debug) cmn_err 52 53 #define CONFIG_INFO 0 54 #define CONFIG_UPDATE 1 55 #define CONFIG_NEW 2 56 #define COMPAT_BUFSIZE 512 57 58 extern int pci_bios_nbus; 59 static uchar_t max_dev_pci = 32; /* PCI standard */ 60 int pci_boot_debug = 0; 61 extern struct memlist *find_bus_res(int, int); 62 63 /* 64 * Module prototypes 65 */ 66 static void enumerate_bus_devs(uchar_t bus, int config_op); 67 static void create_root_bus_dip(uchar_t bus); 68 static dev_info_t *new_func_pci(uchar_t, uchar_t, uchar_t, uchar_t, 69 ushort_t, int); 70 static void add_compatible(dev_info_t *, ushort_t, ushort_t, 71 ushort_t, ushort_t, uchar_t, uint_t, int); 72 static int add_reg_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int, int); 73 static void add_ppb_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int); 74 static void add_model_prop(dev_info_t *, uint_t); 75 static void add_bus_range_prop(int); 76 static void add_bus_slot_names_prop(int); 77 static void add_ppb_ranges_prop(int); 78 static void add_bus_available_prop(int); 79 static void alloc_res_array(); 80 81 extern int pci_slot_names_prop(int, char *, int); 82 83 /* set non-zero to force PCI peer-bus renumbering */ 84 int pci_bus_always_renumber = 0; 85 86 /* 87 * Enumerate all PCI devices 88 */ 89 void 90 pci_setup_tree() 91 { 92 uchar_t i, root_bus_addr = 0; 93 94 alloc_res_array(); 95 for (i = 0; i <= pci_bios_nbus; i++) { 96 pci_bus_res[i].par_bus = (uchar_t)-1; 97 pci_bus_res[i].root_addr = (uchar_t)-1; 98 pci_bus_res[i].sub_bus = i; 99 } 100 101 pci_bus_res[0].root_addr = root_bus_addr++; 102 create_root_bus_dip(0); 103 enumerate_bus_devs(0, CONFIG_INFO); 104 105 /* 106 * Now enumerate peer busses 107 * 108 * We loop till pci_bios_nbus. On most systems, there is 109 * one more bus at the high end, which implements the ISA 110 * compatibility bus. We don't care about that. 111 * 112 * Note: In the old (bootconf) enumeration, the peer bus 113 * address did not use the bus number, and there were 114 * too many peer busses created. The root_bus_addr is 115 * used to maintain the old peer bus address assignment. 116 * However, we stop enumerating phantom peers with no 117 * device below. 118 */ 119 for (i = 1; i <= pci_bios_nbus; i++) { 120 if (pci_bus_res[i].dip == NULL) { 121 pci_bus_res[i].root_addr = root_bus_addr++; 122 } 123 enumerate_bus_devs(i, CONFIG_INFO); 124 125 /* add slot-names property for named pci hot-plug slots */ 126 add_bus_slot_names_prop(i); 127 } 128 129 /* add bus-range property for root/peer bus nodes */ 130 for (i = 0; i <= pci_bios_nbus; i++) { 131 if (pci_bus_res[i].par_bus == (uchar_t)-1) 132 add_bus_range_prop(i); 133 } 134 } 135 136 /* 137 * >0 = present, 0 = not present, <0 = error 138 */ 139 static int 140 pci_bbn_present(int bus) 141 { 142 ACPI_HANDLE hdl; 143 ACPI_BUFFER rb; 144 int rv; 145 146 /* no dip means no _BBN */ 147 if (pci_bus_res[bus].dip == NULL) 148 return (0); 149 150 rv = acpica_find_pciobj(pci_bus_res[bus].dip, &hdl); 151 if (rv != AE_OK) 152 return (-1); 153 154 rb.Length = ACPI_ALLOCATE_BUFFER; 155 156 rv = AcpiEvaluateObject(hdl, "_BBN", NULL, &rb); 157 158 if (rb.Length > 0) 159 AcpiOsFree(rb.Pointer); 160 161 if (rv == AE_OK) 162 return (1); 163 else if (rv == AE_NOT_FOUND) 164 return (0); 165 else 166 return (-1); 167 } 168 169 /* 170 * Return non-zero if any PCI bus in the system has an associated 171 * _BBN object, 0 otherwise. 172 */ 173 static int 174 pci_roots_have_bbn(void) 175 { 176 int i; 177 178 /* 179 * Scan the PCI busses and look for at least 1 _BBN 180 */ 181 for (i = 0; i <= pci_bios_nbus; i++) { 182 /* skip non-root (peer) PCI busses */ 183 if (pci_bus_res[i].par_bus != (uchar_t)-1) 184 continue; 185 186 if (pci_bbn_present(i) > 0) 187 return (1); 188 } 189 return (0); 190 191 } 192 193 /* 194 * return non-zero if the machine is one on which we renumber 195 * the internal pci unit-addresses 196 */ 197 static int 198 pci_bus_renumber() 199 { 200 ACPI_TABLE_HEADER *fadt; 201 202 if (pci_bus_always_renumber) 203 return (1); 204 205 /* get the FADT */ 206 if (AcpiGetFirmwareTable(FADT_SIG, 1, ACPI_LOGICAL_ADDRESSING, 207 (ACPI_TABLE_HEADER **)&fadt) != AE_OK) 208 return (0); 209 210 /* compare OEM Table ID to "SUNm31" */ 211 if (strncmp("SUNm31", fadt->OemId, 6)) 212 return (0); 213 else 214 return (1); 215 } 216 217 /* 218 * Initial enumeration of the physical PCI bus hierarchy can 219 * leave 'gaps' in the order of peer PCI bus unit-addresses. 220 * Systems with more than one peer PCI bus *must* have an ACPI 221 * _BBN object associated with each peer bus; use the presence 222 * of this object to remove gaps in the numbering of the peer 223 * PCI bus unit-addresses - only peer busses with an associated 224 * _BBN are counted. 225 */ 226 static void 227 pci_renumber_root_busses(void) 228 { 229 int pci_regs[] = {0, 0, 0}; 230 int i, root_addr = 0; 231 232 /* 233 * Currently, we only enable the re-numbering on specific 234 * Sun machines; this is a work-around for the more complicated 235 * issue of upgrade changing physical device paths 236 */ 237 if (!pci_bus_renumber()) 238 return; 239 240 /* 241 * If we find no _BBN objects at all, we either don't need 242 * to do anything or can't do anything anyway 243 */ 244 if (!pci_roots_have_bbn()) 245 return; 246 247 for (i = 0; i <= pci_bios_nbus; i++) { 248 /* skip non-root (peer) PCI busses */ 249 if (pci_bus_res[i].par_bus != (uchar_t)-1) 250 continue; 251 252 if (pci_bbn_present(i) < 1) { 253 pci_bus_res[i].root_addr = (uchar_t)-1; 254 continue; 255 } 256 257 ASSERT(pci_bus_res[i].dip != NULL); 258 if (pci_bus_res[i].root_addr != root_addr) { 259 /* update reg property for node */ 260 pci_bus_res[i].root_addr = root_addr; 261 pci_regs[0] = pci_bus_res[i].root_addr; 262 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, 263 pci_bus_res[i].dip, "reg", (int *)pci_regs, 3); 264 } 265 root_addr++; 266 } 267 } 268 269 void 270 pci_reprogram(void) 271 { 272 int i, pci_reconfig = 1; 273 char *onoff; 274 275 /* 276 * Excise phantom roots if possible 277 */ 278 pci_renumber_root_busses(); 279 280 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(), 281 DDI_PROP_DONTPASS, "pci-reprog", &onoff) == DDI_SUCCESS) { 282 if (strcmp(onoff, "off") == 0) { 283 pci_reconfig = 0; 284 cmn_err(CE_NOTE, "pci device reprogramming disabled"); 285 } 286 ddi_prop_free(onoff); 287 } 288 289 for (i = 0; i <= pci_bios_nbus; i++) { 290 /* configure devices not configured by bios */ 291 if (pci_reconfig) 292 enumerate_bus_devs(i, CONFIG_NEW); 293 /* All dev programmed, so we can create available prop */ 294 add_bus_available_prop(i); 295 } 296 } 297 298 /* 299 * Create top-level bus dips, i.e. /pci@0,0, /pci@1,0... 300 */ 301 static void 302 create_root_bus_dip(uchar_t bus) 303 { 304 int pci_regs[] = {0, 0, 0}; 305 dev_info_t *dip; 306 307 ASSERT(pci_bus_res[bus].par_bus == (uchar_t)-1); 308 309 ndi_devi_alloc_sleep(ddi_root_node(), "pci", 310 (pnode_t)DEVI_SID_NODEID, &dip); 311 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 312 "#address-cells", 3); 313 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 314 "#size-cells", 2); 315 pci_regs[0] = pci_bus_res[bus].root_addr; 316 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, 317 "reg", (int *)pci_regs, 3); 318 319 /* 320 * If system has PCIe bus, then create different properties 321 */ 322 if (create_pcie_root_bus(bus, dip) == B_FALSE) 323 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 324 "device_type", "pci"); 325 326 (void) ndi_devi_bind_driver(dip, 0); 327 pci_bus_res[bus].dip = dip; 328 pci_bus_res[bus].pmem_space = find_bus_res(bus, PREFETCH_TYPE); 329 pci_bus_res[bus].mem_space = find_bus_res(bus, MEM_TYPE); 330 pci_bus_res[bus].io_ports = find_bus_res(bus, IO_TYPE); 331 332 if (bus != 0) 333 return; 334 335 /* 336 * Special treatment of bus 0: 337 * If no resource from MPSPEC/HRT, copy pcimem from boot 338 * and make io space the entire range. There is no difference 339 * between prefetchable memory or not. 340 */ 341 if (pci_bus_res[0].mem_space == NULL) 342 pci_bus_res[0].mem_space = 343 memlist_dup(bootops->boot_mem->pcimem); 344 if (pci_bus_res[0].io_ports == NULL) 345 memlist_insert(&pci_bus_res[0].io_ports, 0, 0x10000); 346 } 347 348 /* 349 * For any fixed configuration (often compatability) pci devices 350 * and those with their own expansion rom, create device nodes 351 * to hold the already configured device details. 352 */ 353 void 354 enumerate_bus_devs(uchar_t bus, int config_op) 355 { 356 uchar_t dev, func, nfunc, header; 357 ushort_t venid; 358 dev_info_t *dip; 359 struct pci_devfunc { 360 struct pci_devfunc *next; 361 dev_info_t *dip; 362 uchar_t bus; 363 uchar_t dev; 364 uchar_t func; 365 } *devlist = NULL, *entry; 366 367 if (config_op == CONFIG_NEW) { 368 dcmn_err(CE_NOTE, "configuring pci bus 0x%x", bus); 369 } else 370 dcmn_err(CE_NOTE, "enumerating pci bus 0x%x", bus); 371 372 for (dev = 0; dev < max_dev_pci; dev++) { 373 nfunc = 1; 374 for (func = 0; func < nfunc; func++) { 375 376 dcmn_err(CE_NOTE, "probing dev 0x%x, func 0x%x", 377 dev, func); 378 379 venid = pci_getw(bus, dev, func, PCI_CONF_VENID); 380 if ((venid == 0xffff) || (venid == 0)) { 381 /* no function at this address */ 382 continue; 383 } 384 385 header = pci_getb(bus, dev, func, PCI_CONF_HEADER); 386 if (header == 0xff) { 387 continue; /* illegal value */ 388 } 389 390 /* 391 * according to some mail from Microsoft posted 392 * to the pci-drivers alias, their only requirement 393 * for a multifunction device is for the 1st 394 * function to have to PCI_HEADER_MULTI bit set. 395 */ 396 if ((func == 0) && (header & PCI_HEADER_MULTI)) { 397 nfunc = 8; 398 } 399 400 if (config_op == CONFIG_INFO) { 401 /* 402 * Create the node, unconditionally, on the 403 * first pass only. It may still need 404 * resource assignment, which will be 405 * done on the second, CONFIG_NEW, pass. 406 */ 407 dip = new_func_pci(bus, dev, func, header, 408 venid, config_op); 409 /* 410 * If dip isn't null, put on a list to 411 * save for reprogramming when config_op 412 * is CONFIG_NEW. 413 */ 414 415 if (dip) { 416 entry = kmem_alloc(sizeof (*entry), 417 KM_SLEEP); 418 entry->dip = dip; 419 entry->dev = dev; 420 entry->func = func; 421 entry->next = devlist; 422 devlist = entry; 423 } 424 } 425 } 426 } 427 428 if (config_op == CONFIG_NEW) { 429 devlist = (struct pci_devfunc *)pci_bus_res[bus].privdata; 430 while (devlist) { 431 entry = devlist; 432 devlist = entry->next; 433 cmn_err(CE_NOTE, 434 "!reprogram pci device [%d/%d/%d] (%s)", 435 bus, entry->dev, entry->func, 436 ddi_driver_name(entry->dip)); 437 (void) add_reg_props(entry->dip, bus, entry->dev, 438 entry->func, CONFIG_UPDATE, 0); 439 kmem_free(entry, sizeof (*entry)); 440 } 441 pci_bus_res[bus].privdata = NULL; 442 } else { 443 pci_bus_res[bus].privdata = devlist; 444 } 445 } 446 447 static int 448 check_pciide_prop(uchar_t revid, ushort_t venid, ushort_t devid, 449 ushort_t subvenid, ushort_t subdevid) 450 { 451 static int prop_exist = -1; 452 static char *pciide_str; 453 char compat[32]; 454 455 if (prop_exist == -1) { 456 prop_exist = (ddi_prop_lookup_string(DDI_DEV_T_ANY, 457 ddi_root_node(), DDI_PROP_DONTPASS, "pci-ide", 458 &pciide_str) == DDI_SUCCESS); 459 } 460 461 if (!prop_exist) 462 return (0); 463 464 /* compare property value against various forms of compatible */ 465 if (subvenid) { 466 (void) snprintf(compat, sizeof (compat), "pci%x,%x.%x.%x.%x", 467 venid, devid, subvenid, subdevid, revid); 468 if (strcmp(pciide_str, compat) == 0) 469 return (1); 470 471 (void) snprintf(compat, sizeof (compat), "pci%x,%x.%x.%x", 472 venid, devid, subvenid, subdevid); 473 if (strcmp(pciide_str, compat) == 0) 474 return (1); 475 476 (void) snprintf(compat, sizeof (compat), "pci%x,%x", 477 subvenid, subdevid); 478 if (strcmp(pciide_str, compat) == 0) 479 return (1); 480 } 481 (void) snprintf(compat, sizeof (compat), "pci%x,%x.%x", 482 venid, devid, revid); 483 if (strcmp(pciide_str, compat) == 0) 484 return (1); 485 486 (void) snprintf(compat, sizeof (compat), "pci%x,%x", venid, devid); 487 if (strcmp(pciide_str, compat) == 0) 488 return (1); 489 490 return (0); 491 } 492 493 static int 494 is_pciide(uchar_t basecl, uchar_t subcl, uchar_t revid, 495 ushort_t venid, ushort_t devid, ushort_t subvenid, ushort_t subdevid) 496 { 497 struct ide_table { /* table for PCI_MASS_OTHER */ 498 ushort_t venid; 499 ushort_t devid; 500 } *entry; 501 502 /* XXX SATA devices: need a way to add dynamically */ 503 static struct ide_table ide_other[] = { 504 {0x1095, 0x3112}, 505 {0x1095, 0x3114}, 506 {0x1095, 0x3512}, 507 {0, 0} 508 }; 509 510 if (basecl != PCI_CLASS_MASS) 511 return (0); 512 513 if (subcl == PCI_MASS_IDE) { 514 return (1); 515 } 516 517 if (subcl != PCI_MASS_OTHER && subcl != PCI_MASS_SATA) { 518 return (0); 519 } 520 521 entry = &ide_other[0]; 522 while (entry->venid) { 523 if (entry->venid == venid && entry->devid == devid) 524 return (1); 525 entry++; 526 } 527 return (check_pciide_prop(revid, venid, devid, subvenid, subdevid)); 528 } 529 530 static int 531 is_display(uint_t classcode) 532 { 533 static uint_t disp_classes[] = { 534 0x000100, 535 0x030000, 536 0x030001 537 }; 538 int i, nclasses = sizeof (disp_classes) / sizeof (uint_t); 539 540 for (i = 0; i < nclasses; i++) { 541 if (classcode == disp_classes[i]) 542 return (1); 543 } 544 return (0); 545 } 546 547 static dev_info_t * 548 new_func_pci(uchar_t bus, uchar_t dev, uchar_t func, uchar_t header, 549 ushort_t vendorid, int config_op) 550 { 551 char nodename[32], unitaddr[5]; 552 dev_info_t *dip; 553 uchar_t basecl, subcl, intr, revid; 554 ushort_t subvenid, subdevid, status; 555 ushort_t slot_num; 556 uint_t classcode, revclass; 557 int reprogram = 0, pciide; 558 int power[2] = {1, 1}; 559 int pciex = 0; 560 ushort_t is_pci_bridge = 0; 561 562 ushort_t deviceid = pci_getw(bus, dev, func, PCI_CONF_DEVID); 563 564 switch (header & PCI_HEADER_TYPE_M) { 565 case PCI_HEADER_ZERO: 566 subvenid = pci_getw(bus, dev, func, PCI_CONF_SUBVENID); 567 subdevid = pci_getw(bus, dev, func, PCI_CONF_SUBSYSID); 568 break; 569 case PCI_HEADER_CARDBUS: 570 subvenid = pci_getw(bus, dev, func, PCI_CBUS_SUBVENID); 571 subdevid = pci_getw(bus, dev, func, PCI_CBUS_SUBSYSID); 572 break; 573 default: 574 subvenid = 0; 575 subdevid = 0; 576 break; 577 } 578 579 /* XXX should be use generic names? derive from class? */ 580 revclass = pci_getl(bus, dev, func, PCI_CONF_REVID); 581 classcode = revclass >> 8; 582 revid = revclass & 0xff; 583 584 /* figure out if this is pci-ide */ 585 basecl = classcode >> 16; 586 subcl = (classcode >> 8) & 0xff; 587 pciide = is_pciide(basecl, subcl, revid, vendorid, deviceid, 588 subvenid, subdevid); 589 if (check_if_device_is_pciex(bus, dev, func, &slot_num, 590 &is_pci_bridge) == B_TRUE) 591 pciex = 1; 592 593 if (pciide) 594 (void) snprintf(nodename, sizeof (nodename), "pci-ide"); 595 else if (is_display(classcode)) 596 (void) snprintf(nodename, sizeof (nodename), "display"); 597 else if (subvenid != 0) 598 (void) snprintf(nodename, sizeof (nodename), 599 "pci%x,%x", subvenid, subdevid); 600 else 601 (void) snprintf(nodename, sizeof (nodename), 602 "pci%x,%x", vendorid, deviceid); 603 604 /* make sure parent bus dip has been created */ 605 if (pci_bus_res[bus].dip == NULL) { 606 create_root_bus_dip(bus); 607 } 608 609 ndi_devi_alloc_sleep(pci_bus_res[bus].dip, nodename, 610 DEVI_SID_NODEID, &dip); 611 612 /* add properties */ 613 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "device-id", deviceid); 614 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "vendor-id", vendorid); 615 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "revision-id", revid); 616 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 617 "class-code", classcode); 618 if (func == 0) 619 (void) snprintf(unitaddr, sizeof (unitaddr), "%x", dev); 620 else 621 (void) snprintf(unitaddr, sizeof (unitaddr), 622 "%x,%x", dev, func); 623 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 624 "unit-address", unitaddr); 625 626 /* add device_type for display nodes */ 627 if (is_display(classcode)) { 628 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 629 "device_type", "display"); 630 } 631 /* add special stuff for header type */ 632 if ((header & PCI_HEADER_TYPE_M) == PCI_HEADER_ZERO) { 633 uchar_t mingrant = pci_getb(bus, dev, func, PCI_CONF_MIN_G); 634 uchar_t maxlatency = pci_getb(bus, dev, func, PCI_CONF_MAX_L); 635 636 if (subvenid != 0) { 637 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 638 "subsystem-id", subdevid); 639 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 640 "subsystem-vendor-id", subvenid); 641 } 642 if (!pciex) 643 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 644 "min-grant", mingrant); 645 if (!pciex) 646 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 647 "max-latency", maxlatency); 648 } 649 650 /* interrupt, record if not 0 */ 651 intr = pci_getb(bus, dev, func, PCI_CONF_IPIN); 652 if (intr != 0) 653 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 654 "interrupts", intr); 655 656 /* 657 * Add support for 133 mhz pci eventually 658 */ 659 status = pci_getw(bus, dev, func, PCI_CONF_STAT); 660 661 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 662 "devsel-speed", (status & PCI_STAT_DEVSELT) >> 9); 663 if (!pciex && (status & PCI_STAT_FBBC)) 664 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip, 665 "fast-back-to-back"); 666 if (!pciex && (status & PCI_STAT_66MHZ)) 667 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip, 668 "66mhz-capable"); 669 if (status & PCI_STAT_UDF) 670 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip, 671 "udf-supported"); 672 if (pciex && slot_num) 673 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 674 "physical-slot#", slot_num); 675 676 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, 677 "power-consumption", power, 2); 678 679 if ((basecl == PCI_CLASS_BRIDGE) && (subcl == PCI_BRIDGE_PCI)) 680 add_ppb_props(dip, bus, dev, func, pciex); 681 682 /* check for ck8-04 based PCI ISA bridge only */ 683 if (NVIDIA_IS_LPC_BRIDGE(vendorid, deviceid) && (dev == 1) && 684 (func == 0)) 685 add_ck804_isa_bridge_props(dip, bus, dev, func); 686 687 if (pciex && is_pci_bridge) 688 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "model", 689 (char *)"PCIe-PCI bridge"); 690 else 691 add_model_prop(dip, classcode); 692 693 add_compatible(dip, subvenid, subdevid, vendorid, deviceid, 694 revid, classcode, pciex); 695 reprogram = add_reg_props(dip, bus, dev, func, config_op, pciide); 696 (void) ndi_devi_bind_driver(dip, 0); 697 698 /* special handling for pci-ide */ 699 if (pciide) { 700 dev_info_t *cdip; 701 702 /* 703 * Create properties specified by P1275 Working Group 704 * Proposal #414 Version 1 705 */ 706 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 707 "device_type", "pci-ide"); 708 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 709 "#address-cells", 1); 710 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 711 "#size-cells", 0); 712 713 /* allocate two child nodes */ 714 ndi_devi_alloc_sleep(dip, "ide", 715 (pnode_t)DEVI_SID_NODEID, &cdip); 716 (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip, 717 "reg", 0); 718 (void) ndi_devi_bind_driver(cdip, 0); 719 ndi_devi_alloc_sleep(dip, "ide", 720 (pnode_t)DEVI_SID_NODEID, &cdip); 721 (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip, 722 "reg", 1); 723 (void) ndi_devi_bind_driver(cdip, 0); 724 725 reprogram = 0; /* don't reprogram pci-ide bridge */ 726 } 727 728 729 if (reprogram) 730 return (dip); 731 return (NULL); 732 } 733 734 /* 735 * Set the compatible property to a value compliant with 736 * rev 2.1 of the IEEE1275 PCI binding. 737 * (Also used for PCI-Express devices). 738 * 739 * pciVVVV,DDDD.SSSS.ssss.RR (0) 740 * pciVVVV,DDDD.SSSS.ssss (1) 741 * pciSSSS,ssss (2) 742 * pciVVVV,DDDD.RR (3) 743 * pciVVVV,DDDD (4) 744 * pciclass,CCSSPP (5) 745 * pciclass,CCSS (6) 746 * 747 * The Subsystem (SSSS) forms are not inserted if 748 * subsystem-vendor-id is 0. 749 * 750 * NOTE: For PCI-Express devices "pci" is replaced with "pciex" in 0-6 above 751 * property 2 is not created as per "1275 bindings for PCI Express Interconnect" 752 * 753 * Set with setprop and \x00 between each 754 * to generate the encoded string array form. 755 */ 756 void 757 add_compatible(dev_info_t *dip, ushort_t subvenid, ushort_t subdevid, 758 ushort_t vendorid, ushort_t deviceid, uchar_t revid, uint_t classcode, 759 int pciex) 760 { 761 int i = 0; 762 int size = COMPAT_BUFSIZE; 763 char *compat[13]; 764 char *buf, *curr; 765 766 curr = buf = kmem_alloc(size, KM_SLEEP); 767 768 if (pciex) { 769 if (subvenid) { 770 compat[i++] = curr; /* form 0 */ 771 (void) snprintf(curr, size, "pciex%x,%x.%x.%x.%x", 772 vendorid, deviceid, subvenid, subdevid, revid); 773 size -= strlen(curr) + 1; 774 curr += strlen(curr) + 1; 775 776 compat[i++] = curr; /* form 1 */ 777 (void) snprintf(curr, size, "pciex%x,%x.%x.%x", 778 vendorid, deviceid, subvenid, subdevid); 779 size -= strlen(curr) + 1; 780 curr += strlen(curr) + 1; 781 782 } 783 compat[i++] = curr; /* form 3 */ 784 (void) snprintf(curr, size, "pciex%x,%x.%x", 785 vendorid, deviceid, revid); 786 size -= strlen(curr) + 1; 787 curr += strlen(curr) + 1; 788 789 compat[i++] = curr; /* form 4 */ 790 (void) snprintf(curr, size, "pciex%x,%x", vendorid, deviceid); 791 size -= strlen(curr) + 1; 792 curr += strlen(curr) + 1; 793 794 compat[i++] = curr; /* form 5 */ 795 (void) snprintf(curr, size, "pciexclass,%06x", classcode); 796 size -= strlen(curr) + 1; 797 curr += strlen(curr) + 1; 798 799 compat[i++] = curr; /* form 6 */ 800 (void) snprintf(curr, size, "pciexclass,%04x", 801 (classcode >> 8)); 802 size -= strlen(curr) + 1; 803 curr += strlen(curr) + 1; 804 } 805 806 if (subvenid) { 807 compat[i++] = curr; /* form 0 */ 808 (void) snprintf(curr, size, "pci%x,%x.%x.%x.%x", 809 vendorid, deviceid, subvenid, subdevid, revid); 810 size -= strlen(curr) + 1; 811 curr += strlen(curr) + 1; 812 813 compat[i++] = curr; /* form 1 */ 814 (void) snprintf(curr, size, "pci%x,%x.%x.%x", 815 vendorid, deviceid, subvenid, subdevid); 816 size -= strlen(curr) + 1; 817 curr += strlen(curr) + 1; 818 819 compat[i++] = curr; /* form 2 */ 820 (void) snprintf(curr, size, "pci%x,%x", subvenid, subdevid); 821 size -= strlen(curr) + 1; 822 curr += strlen(curr) + 1; 823 } 824 compat[i++] = curr; /* form 3 */ 825 (void) snprintf(curr, size, "pci%x,%x.%x", vendorid, deviceid, revid); 826 size -= strlen(curr) + 1; 827 curr += strlen(curr) + 1; 828 829 compat[i++] = curr; /* form 4 */ 830 (void) snprintf(curr, size, "pci%x,%x", vendorid, deviceid); 831 size -= strlen(curr) + 1; 832 curr += strlen(curr) + 1; 833 834 compat[i++] = curr; /* form 5 */ 835 (void) snprintf(curr, size, "pciclass,%06x", classcode); 836 size -= strlen(curr) + 1; 837 curr += strlen(curr) + 1; 838 839 compat[i++] = curr; /* form 6 */ 840 (void) snprintf(curr, size, "pciclass,%04x", (classcode >> 8)); 841 size -= strlen(curr) + 1; 842 curr += strlen(curr) + 1; 843 844 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, dip, 845 "compatible", compat, i); 846 kmem_free(buf, COMPAT_BUFSIZE); 847 } 848 849 /* 850 * Adjust the reg properties for a dual channel PCI-IDE device. 851 * 852 * NOTE: don't do anything that changes the order of the hard-decodes 853 * and programmed BARs. The kernel driver depends on these values 854 * being in this order regardless of whether they're for a 'native' 855 * mode BAR or not. 856 */ 857 /* 858 * config info for pci-ide devices 859 */ 860 static struct { 861 uchar_t native_mask; /* 0 == 'compatibility' mode, 1 == native */ 862 uchar_t bar_offset; /* offset for alt status register */ 863 ushort_t addr; /* compatibility mode base address */ 864 ushort_t length; /* number of ports for this BAR */ 865 } pciide_bar[] = { 866 { 0x01, 0, 0x1f0, 8 }, /* primary lower BAR */ 867 { 0x01, 2, 0x3f6, 1 }, /* primary upper BAR */ 868 { 0x04, 0, 0x170, 8 }, /* secondary lower BAR */ 869 { 0x04, 2, 0x376, 1 } /* secondary upper BAR */ 870 }; 871 872 static int 873 pciIdeAdjustBAR(uchar_t progcl, int index, uint_t *basep, uint_t *lenp) 874 { 875 int hard_decode = 0; 876 877 /* 878 * Adjust the base and len for the BARs of the PCI-IDE 879 * device's primary and secondary controllers. The first 880 * two BARs are for the primary controller and the next 881 * two BARs are for the secondary controller. The fifth 882 * and sixth bars are never adjusted. 883 */ 884 if (index >= 0 && index <= 3) { 885 *lenp = pciide_bar[index].length; 886 887 if (progcl & pciide_bar[index].native_mask) { 888 *basep += pciide_bar[index].bar_offset; 889 } else { 890 *basep = pciide_bar[index].addr; 891 hard_decode = 1; 892 } 893 } 894 895 /* 896 * if either base or len is zero make certain both are zero 897 */ 898 if (*basep == 0 || *lenp == 0) { 899 *basep = 0; 900 *lenp = 0; 901 hard_decode = 0; 902 } 903 904 return (hard_decode); 905 } 906 907 908 /* 909 * Add the "reg" and "assigned-addresses" property 910 */ 911 static int 912 add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, 913 int config_op, int pciide) 914 { 915 uchar_t baseclass, subclass, progclass, header; 916 ushort_t bar_sz; 917 uint_t value = 0, len, devloc; 918 uint_t base, base_hi, type; 919 ushort_t offset, end; 920 int max_basereg, j, reprogram = 0; 921 uint_t phys_hi; 922 struct memlist **io_res, **mres, **mem_res, **pmem_res; 923 uint16_t cmd_reg; 924 925 pci_regspec_t regs[16] = {{0}}; 926 pci_regspec_t assigned[15] = {{0}}; 927 int nreg, nasgn, enable = 0; 928 929 io_res = &pci_bus_res[bus].io_ports; 930 mem_res = &pci_bus_res[bus].mem_space; 931 if (bus == 0) /* for bus 0, there is only mem_space */ 932 pmem_res = mem_res; 933 else 934 pmem_res = &pci_bus_res[bus].pmem_space; 935 936 devloc = (uint_t)bus << 16 | (uint_t)dev << 11 | (uint_t)func << 8; 937 regs[0].pci_phys_hi = devloc; 938 nreg = 1; /* rest of regs[0] is all zero */ 939 nasgn = 0; 940 941 baseclass = pci_getb(bus, dev, func, PCI_CONF_BASCLASS); 942 subclass = pci_getb(bus, dev, func, PCI_CONF_SUBCLASS); 943 progclass = pci_getb(bus, dev, func, PCI_CONF_PROGCLASS); 944 header = pci_getb(bus, dev, func, PCI_CONF_HEADER) & PCI_HEADER_TYPE_M; 945 /* Fetch PCI command, disable I/O and memory */ 946 cmd_reg = pci_getw(bus, dev, func, PCI_CONF_COMM); 947 pci_putw(bus, dev, func, PCI_CONF_COMM, 948 cmd_reg & ~(PCI_COMM_IO | PCI_COMM_MAE)); 949 950 switch (header) { 951 case PCI_HEADER_ZERO: 952 max_basereg = PCI_BASE_NUM; 953 break; 954 case PCI_HEADER_PPB: 955 max_basereg = PCI_BCNF_BASE_NUM; 956 break; 957 case PCI_HEADER_CARDBUS: 958 max_basereg = PCI_CBUS_BASE_NUM; 959 break; 960 default: 961 max_basereg = 0; 962 break; 963 } 964 965 /* 966 * Create the register property by saving the current 967 * value of the base register. Disable memory/io, then 968 * write 0xffffffff to the base register. Read the 969 * value back to determine the required size of the 970 * address space. Restore the base register 971 * contents. 972 */ 973 end = PCI_CONF_BASE0 + max_basereg * sizeof (uint_t); 974 for (j = 0, offset = PCI_CONF_BASE0; offset < end; 975 j++, offset += bar_sz) { 976 int hard_decode = 0; 977 978 /* determine the size of the address space */ 979 base = pci_getl(bus, dev, func, offset); 980 pci_putl(bus, dev, func, offset, 0xffffffff); 981 value = pci_getl(bus, dev, func, offset); 982 pci_putl(bus, dev, func, offset, base); 983 984 /* construct phys hi,med.lo, size hi, lo */ 985 if ((pciide && j < 4) || (base & PCI_BASE_SPACE_IO)) { 986 /* i/o space */ 987 bar_sz = PCI_BAR_SZ_32; 988 value &= PCI_BASE_IO_ADDR_M; 989 len = ((value ^ (value-1)) + 1) >> 1; 990 991 /* XXX Adjust first 4 IDE registers */ 992 if (pciide) { 993 if (subclass != PCI_MASS_IDE) 994 progclass = (PCI_IDE_IF_NATIVE_PRI | 995 PCI_IDE_IF_NATIVE_SEC); 996 hard_decode = pciIdeAdjustBAR(progclass, j, 997 &base, &len); 998 } else if (value == 0) { 999 /* skip base regs with size of 0 */ 1000 continue; 1001 } 1002 1003 regs[nreg].pci_size_low = 1004 assigned[nasgn].pci_size_low = len; 1005 if (!hard_decode) { 1006 regs[nreg].pci_phys_hi = 1007 (PCI_ADDR_IO | devloc) + offset; 1008 } else { 1009 regs[nreg].pci_phys_hi = 1010 (PCI_RELOCAT_B | PCI_ADDR_IO | devloc) + 1011 offset; 1012 regs[nreg].pci_phys_low = 1013 base & PCI_BASE_IO_ADDR_M; 1014 } 1015 assigned[nasgn].pci_phys_hi = 1016 (PCI_RELOCAT_B | PCI_ADDR_IO | devloc) + offset; 1017 type = base & (~PCI_BASE_IO_ADDR_M); 1018 base &= PCI_BASE_IO_ADDR_M; 1019 1020 /* 1021 * first pass - gather what's there 1022 * update/second pass - adjust/allocate regions 1023 * config - allocate regions 1024 */ 1025 if (config_op == CONFIG_INFO) { /* first pass */ 1026 /* take out of the resource map of the bus */ 1027 if (*io_res && base != 0) 1028 (void) memlist_remove(io_res, 1029 (uint64_t)base, (uint64_t)len); 1030 else if (*io_res) 1031 reprogram = 1; 1032 } else if (*io_res && base == 0) { 1033 base = (uint_t)memlist_find(io_res, 1034 (uint64_t)len, (uint64_t)0x4); 1035 if (base != 0) { 1036 /* XXX need to worry about 64-bit? */ 1037 pci_putl(bus, dev, func, offset, 1038 base | type); 1039 base = pci_getl(bus, dev, func, offset); 1040 base &= PCI_BASE_IO_ADDR_M; 1041 } 1042 if (base == 0) { 1043 cmn_err(CE_WARN, "failed to program" 1044 " IO space [%d/%d/%d] BAR@0x%x" 1045 " length 0x%x", 1046 bus, dev, func, offset, len); 1047 } else 1048 enable |= PCI_COMM_IO; 1049 } 1050 assigned[nasgn].pci_phys_low = base; 1051 nreg++, nasgn++; 1052 1053 } else { 1054 /* memory space */ 1055 if ((base & PCI_BASE_TYPE_M) == PCI_BASE_TYPE_ALL) { 1056 bar_sz = PCI_BAR_SZ_64; 1057 base_hi = pci_getl(bus, dev, func, offset + 4); 1058 phys_hi = PCI_ADDR_MEM64; 1059 } else { 1060 bar_sz = PCI_BAR_SZ_32; 1061 base_hi = 0; 1062 phys_hi = PCI_ADDR_MEM32; 1063 } 1064 1065 /* skip base regs with size of 0 */ 1066 value &= PCI_BASE_M_ADDR_M; 1067 1068 if (value == 0) { 1069 continue; 1070 } 1071 len = ((value ^ (value-1)) + 1) >> 1; 1072 regs[nreg].pci_size_low = 1073 assigned[nasgn].pci_size_low = len; 1074 1075 phys_hi |= (devloc | offset); 1076 if (base & PCI_BASE_PREF_M) { 1077 mres = pmem_res; 1078 phys_hi |= PCI_PREFETCH_B; 1079 } else { 1080 mres = mem_res; 1081 } 1082 regs[nreg].pci_phys_hi = 1083 assigned[nasgn].pci_phys_hi = phys_hi; 1084 assigned[nasgn].pci_phys_hi |= PCI_RELOCAT_B; 1085 assigned[nasgn].pci_phys_mid = base_hi; 1086 type = base & ~PCI_BASE_M_ADDR_M; 1087 base &= PCI_BASE_M_ADDR_M; 1088 1089 if (config_op == CONFIG_INFO) { 1090 /* take out of the resource map of the bus */ 1091 if (*mres && base != 0) { 1092 (void) memlist_remove(mres, 1093 (uint64_t)base, (uint64_t)len); 1094 } else if (*mres) 1095 reprogram = 1; 1096 } else if (*mres && base == 0) { 1097 base = (uint_t)memlist_find(mres, 1098 (uint64_t)len, (uint64_t)0x1000); 1099 if (base != NULL) { 1100 pci_putl(bus, dev, func, offset, 1101 base | type); 1102 base = pci_getl(bus, dev, func, offset); 1103 base &= PCI_BASE_M_ADDR_M; 1104 } 1105 1106 if (base == 0) { 1107 cmn_err(CE_WARN, "failed to program " 1108 "mem space [%d/%d/%d] BAR@0x%x" 1109 " length 0x%x", 1110 bus, dev, func, offset, len); 1111 } else 1112 enable |= PCI_COMM_MAE; 1113 } 1114 assigned[nasgn].pci_phys_low = base; 1115 nreg++, nasgn++; 1116 } 1117 } 1118 switch (header) { 1119 case PCI_HEADER_ZERO: 1120 offset = PCI_CONF_ROM; 1121 break; 1122 case PCI_HEADER_PPB: 1123 offset = PCI_BCNF_ROM; 1124 break; 1125 default: /* including PCI_HEADER_CARDBUS */ 1126 goto done; 1127 } 1128 1129 /* 1130 * Add the expansion rom memory space 1131 * Determine the size of the ROM base reg; don't write reserved bits 1132 * ROM isn't in the PCI memory space. 1133 */ 1134 base = pci_getl(bus, dev, func, offset); 1135 pci_putl(bus, dev, func, offset, PCI_BASE_ROM_ADDR_M); 1136 value = pci_getl(bus, dev, func, offset); 1137 pci_putl(bus, dev, func, offset, base); 1138 if (value & PCI_BASE_ROM_ENABLE) 1139 value &= PCI_BASE_ROM_ADDR_M; 1140 else 1141 value = 0; 1142 1143 if (value != 0) { 1144 regs[nreg].pci_phys_hi = (PCI_ADDR_MEM32 | devloc) + offset; 1145 assigned[nasgn].pci_phys_hi = (PCI_RELOCAT_B | 1146 PCI_ADDR_MEM32 | devloc) + offset; 1147 base &= PCI_BASE_ROM_ADDR_M; 1148 assigned[nasgn].pci_phys_low = base; 1149 len = ((value ^ (value-1)) + 1) >> 1; 1150 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = len; 1151 nreg++, nasgn++; 1152 /* take it out of the memory resource */ 1153 if (*mem_res && base != 0) 1154 (void) memlist_remove(mem_res, 1155 (uint64_t)base, (uint64_t)len); 1156 } 1157 1158 /* 1159 * The following are ISA resources. There are not part 1160 * of the PCI local bus resources. So don't attempt to 1161 * do resource accounting against PCI. 1162 */ 1163 1164 /* add the three hard-decode, aliased address spaces for VGA */ 1165 if ((baseclass == PCI_CLASS_DISPLAY && subclass == PCI_DISPLAY_VGA) || 1166 (baseclass == PCI_CLASS_NONE && subclass == PCI_NONE_VGA)) { 1167 1168 /* VGA hard decode 0x3b0-0x3bb */ 1169 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi = 1170 (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc); 1171 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x3b0; 1172 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0xc; 1173 nreg++, nasgn++; 1174 1175 /* VGA hard decode 0x3c0-0x3df */ 1176 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi = 1177 (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc); 1178 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x3c0; 1179 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0x20; 1180 nreg++, nasgn++; 1181 1182 /* Video memory */ 1183 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi = 1184 (PCI_RELOCAT_B | PCI_ADDR_MEM32 | devloc); 1185 regs[nreg].pci_phys_low = 1186 assigned[nasgn].pci_phys_low = 0xa0000; 1187 regs[nreg].pci_size_low = 1188 assigned[nasgn].pci_size_low = 0x20000; 1189 nreg++, nasgn++; 1190 } 1191 1192 /* add the hard-decode, aliased address spaces for 8514 */ 1193 if ((baseclass == PCI_CLASS_DISPLAY) && 1194 (subclass == PCI_DISPLAY_VGA) && 1195 (progclass & PCI_DISPLAY_IF_8514)) { 1196 1197 /* hard decode 0x2e8 */ 1198 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi = 1199 (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc); 1200 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x2e8; 1201 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0x1; 1202 nreg++, nasgn++; 1203 1204 /* hard decode 0x2ea-0x2ef */ 1205 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi = 1206 (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc); 1207 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x2ea; 1208 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0x6; 1209 nreg++, nasgn++; 1210 } 1211 1212 done: 1213 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "reg", 1214 (int *)regs, nreg * sizeof (pci_regspec_t) / sizeof (int)); 1215 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, 1216 "assigned-addresses", 1217 (int *)assigned, nasgn * sizeof (pci_regspec_t) / sizeof (int)); 1218 if (config_op == CONFIG_NEW && enable) { 1219 cmn_err(CE_NOTE, 1220 "!enable PCI device [%d/%d/%d]", bus, dev, func); 1221 cmd_reg |= (enable | PCI_COMM_ME); 1222 } 1223 /* restore device enables */ 1224 pci_putw(bus, dev, func, PCI_CONF_COMM, cmd_reg); 1225 return (reprogram); 1226 } 1227 1228 static void 1229 add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, 1230 int pciex) 1231 { 1232 char *dev_type; 1233 int i; 1234 uint_t val, io_range[2], mem_range[2], pmem_range[2]; 1235 uchar_t secbus = pci_getb(bus, dev, func, PCI_BCNF_SECBUS); 1236 uchar_t subbus = pci_getb(bus, dev, func, PCI_BCNF_SUBBUS); 1237 ASSERT(secbus <= subbus); 1238 1239 /* 1240 * Some BIOSes lie about max pci busses, we allow for 1241 * such mistakes here 1242 */ 1243 if (subbus > pci_bios_nbus) { 1244 pci_bios_nbus = subbus; 1245 alloc_res_array(); 1246 } 1247 1248 ASSERT(pci_bus_res[secbus].dip == NULL); 1249 pci_bus_res[secbus].dip = dip; 1250 pci_bus_res[secbus].par_bus = bus; 1251 1252 dev_type = pciex ? "pciex" : "pci"; 1253 1254 /* setup bus number hierarchy */ 1255 pci_bus_res[secbus].sub_bus = subbus; 1256 if (subbus > pci_bus_res[bus].sub_bus) 1257 pci_bus_res[bus].sub_bus = subbus; 1258 for (i = secbus + 1; i <= subbus; i++) 1259 pci_bus_res[i].par_bus = bus; 1260 1261 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, 1262 "device_type", dev_type); 1263 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 1264 "#address-cells", 3); 1265 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, 1266 "#size-cells", 2); 1267 1268 /* 1269 * According to PPB spec, the base register should be programmed 1270 * with a value bigger than the limit register when there are 1271 * no resources available. This applies to io, memory, and 1272 * prefetchable memory. 1273 */ 1274 /* io range */ 1275 val = (uint_t)pci_getb(bus, dev, func, PCI_BCNF_IO_BASE_LOW); 1276 io_range[0] = ((val & 0xf0) << 8); 1277 val = (uint_t)pci_getb(bus, dev, func, PCI_BCNF_IO_LIMIT_LOW); 1278 io_range[1] = ((val & 0xf0) << 8) | 0xFFF; 1279 if (io_range[0] != 0 && io_range[0] < io_range[1]) { 1280 memlist_insert(&pci_bus_res[secbus].io_ports, 1281 (uint64_t)io_range[0], 1282 (uint64_t)(io_range[1] - io_range[0] + 1)); 1283 if (pci_bus_res[bus].io_ports != NULL) { 1284 (void) memlist_remove(&pci_bus_res[bus].io_ports, 1285 (uint64_t)io_range[0], 1286 (uint64_t)(io_range[1] - io_range[0] + 1)); 1287 } 1288 dcmn_err(CE_NOTE, "bus %d io-range: 0x%x-%x", 1289 secbus, io_range[0], io_range[1]); 1290 /* if 32-bit supported, make sure upper bits are not set */ 1291 if ((val & 0xf) == 1 && 1292 pci_getw(bus, dev, func, PCI_BCNF_IO_BASE_HI)) { 1293 cmn_err(CE_NOTE, "unsupported 32-bit IO address on" 1294 " pci-pci bridge [%d/%d/%d]", bus, dev, func); 1295 } 1296 } 1297 1298 /* mem range */ 1299 val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_MEM_BASE); 1300 mem_range[0] = ((val & 0xFFF0) << 16); 1301 val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_MEM_LIMIT); 1302 mem_range[1] = ((val & 0xFFF0) << 16) | 0xFFFFF; 1303 if (mem_range[0] != 0 && mem_range[0] < mem_range[1]) { 1304 memlist_insert(&pci_bus_res[secbus].mem_space, 1305 (uint64_t)mem_range[0], 1306 (uint64_t)(mem_range[1] - mem_range[0] + 1)); 1307 /* remove from parent resouce list */ 1308 if (pci_bus_res[bus].mem_space != NULL) { 1309 (void) memlist_remove(&pci_bus_res[bus].mem_space, 1310 (uint64_t)mem_range[0], 1311 (uint64_t)(mem_range[1] - mem_range[0] + 1)); 1312 } 1313 dcmn_err(CE_NOTE, "bus %d mem-range: 0x%x-%x", 1314 secbus, mem_range[0], mem_range[1]); 1315 } 1316 1317 /* prefetchable memory range */ 1318 val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_BASE_LOW); 1319 pmem_range[0] = ((val & 0xFFF0) << 16); 1320 val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_LIMIT_LOW); 1321 pmem_range[1] = ((val & 0xFFF0) << 16) | 0xFFFFF; 1322 if (pmem_range[0] != 0 && pmem_range[0] < pmem_range[1]) { 1323 memlist_insert(&pci_bus_res[secbus].pmem_space, 1324 (uint64_t)pmem_range[0], 1325 (uint64_t)(pmem_range[1] - pmem_range[0] + 1)); 1326 if (pci_bus_res[bus].pmem_space != NULL) { 1327 (void) memlist_remove(&pci_bus_res[bus].pmem_space, 1328 (uint64_t)pmem_range[0], 1329 (uint64_t)(pmem_range[1] - pmem_range[0] + 1)); 1330 } 1331 dcmn_err(CE_NOTE, "bus %d pmem-range: 0x%x-%x", 1332 secbus, pmem_range[0], pmem_range[1]); 1333 /* if 64-bit supported, make sure upper bits are not set */ 1334 if ((val & 0xf) == 1 && 1335 pci_getl(bus, dev, func, PCI_BCNF_PF_BASE_HIGH)) { 1336 cmn_err(CE_NOTE, "unsupported 64-bit prefetch memory on" 1337 " pci-pci bridge [%d/%d/%d]", bus, dev, func); 1338 } 1339 } 1340 1341 add_bus_range_prop(secbus); 1342 add_ppb_ranges_prop(secbus); 1343 } 1344 1345 extern const struct pci_class_strings_s class_pci[]; 1346 extern int class_pci_items; 1347 1348 static void 1349 add_model_prop(dev_info_t *dip, uint_t classcode) 1350 { 1351 const char *desc; 1352 int i; 1353 uchar_t baseclass = classcode >> 16; 1354 uchar_t subclass = (classcode >> 8) & 0xff; 1355 uchar_t progclass = classcode & 0xff; 1356 1357 if ((baseclass == PCI_CLASS_MASS) && (subclass == PCI_MASS_IDE)) { 1358 desc = "IDE controller"; 1359 } else { 1360 for (desc = 0, i = 0; i < class_pci_items; i++) { 1361 if ((baseclass == class_pci[i].base_class) && 1362 (subclass == class_pci[i].sub_class) && 1363 (progclass == class_pci[i].prog_class)) { 1364 desc = class_pci[i].actual_desc; 1365 break; 1366 } 1367 } 1368 if (i == class_pci_items) 1369 desc = "Unknown class of pci/pnpbios device"; 1370 } 1371 1372 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "model", 1373 (char *)desc); 1374 } 1375 1376 static void 1377 add_bus_range_prop(int bus) 1378 { 1379 int bus_range[2]; 1380 1381 if (pci_bus_res[bus].dip == NULL) 1382 return; 1383 bus_range[0] = bus; 1384 bus_range[1] = pci_bus_res[bus].sub_bus; 1385 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, pci_bus_res[bus].dip, 1386 "bus-range", (int *)bus_range, 2); 1387 } 1388 1389 /* 1390 * Add slot-names property for any named pci hot-plug slots 1391 */ 1392 static void 1393 add_bus_slot_names_prop(int bus) 1394 { 1395 char slotprop[256]; 1396 int len; 1397 1398 len = pci_slot_names_prop(bus, slotprop, sizeof (slotprop)); 1399 if (len > 0) { 1400 if (pci_bus_res[bus].dip == NULL) 1401 create_root_bus_dip(bus); 1402 ASSERT(pci_bus_res[bus].dip); 1403 ASSERT((len % sizeof (int)) == 0); 1404 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, 1405 pci_bus_res[bus].dip, "slot-names", 1406 (int *)slotprop, len / sizeof (int)); 1407 } 1408 } 1409 1410 /* this should be in some header file, shared with pcicfg */ 1411 struct pcicfg_range { 1412 uint32_t child_hi; 1413 uint32_t child_mid; 1414 uint32_t child_lo; 1415 uint32_t parent_hi; 1416 uint32_t parent_mid; 1417 uint32_t parent_lo; 1418 uint32_t size_hi; 1419 uint32_t size_lo; 1420 }; 1421 1422 static int 1423 memlist_to_range(struct pcicfg_range *rp, struct memlist *entry, int type) 1424 { 1425 if (entry == NULL) 1426 return (0); 1427 1428 /* assume 32-bit addresses */ 1429 rp->child_hi = rp->parent_hi = type; 1430 rp->child_mid = rp->parent_mid = 0; 1431 rp->child_lo = rp->parent_lo = (uint32_t)entry->address; 1432 rp->size_hi = 0; 1433 rp->size_lo = (uint32_t)entry->size; 1434 return (1); 1435 } 1436 1437 static void 1438 add_ppb_ranges_prop(int bus) 1439 { 1440 int i = 0; 1441 struct pcicfg_range *rp; 1442 1443 rp = kmem_alloc(3 * sizeof (*rp), KM_SLEEP); 1444 1445 i = memlist_to_range(&rp[0], pci_bus_res[bus].io_ports, 1446 PCI_ADDR_IO | PCI_REG_REL_M); 1447 i += memlist_to_range(&rp[i], pci_bus_res[bus].mem_space, 1448 PCI_ADDR_MEM32 | PCI_REG_REL_M); 1449 i += memlist_to_range(&rp[i], pci_bus_res[bus].pmem_space, 1450 PCI_ADDR_MEM32 | PCI_REG_REL_M | PCI_REG_PF_M); 1451 1452 if (i != 0) 1453 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, 1454 pci_bus_res[bus].dip, "ranges", (int *)rp, 1455 i * sizeof (struct pcicfg_range) / sizeof (int)); 1456 kmem_free(rp, 3 * sizeof (*rp)); 1457 } 1458 1459 static int 1460 memlist_to_spec(struct pci_phys_spec *sp, struct memlist *list, int type) 1461 { 1462 int i = 0; 1463 1464 while (list) { 1465 /* assume 32-bit addresses */ 1466 sp->pci_phys_hi = type; 1467 sp->pci_phys_mid = 0; 1468 sp->pci_phys_low = (uint32_t)list->address; 1469 sp->pci_size_hi = 0; 1470 sp->pci_size_low = (uint32_t)list->size; 1471 1472 list = list->next; 1473 sp++, i++; 1474 } 1475 return (i); 1476 } 1477 1478 static void 1479 add_bus_available_prop(int bus) 1480 { 1481 int i, count; 1482 struct pci_phys_spec *sp; 1483 1484 count = memlist_count(pci_bus_res[bus].io_ports) + 1485 memlist_count(pci_bus_res[bus].mem_space) + 1486 memlist_count(pci_bus_res[bus].pmem_space); 1487 1488 if (count == 0) /* nothing available */ 1489 return; 1490 1491 sp = kmem_alloc(count * sizeof (*sp), KM_SLEEP); 1492 i = memlist_to_spec(&sp[0], pci_bus_res[bus].io_ports, 1493 PCI_ADDR_IO | PCI_REG_REL_M); 1494 i += memlist_to_spec(&sp[i], pci_bus_res[bus].mem_space, 1495 PCI_ADDR_MEM32 | PCI_REG_REL_M); 1496 i += memlist_to_spec(&sp[i], pci_bus_res[bus].pmem_space, 1497 PCI_ADDR_MEM32 | PCI_REG_REL_M | PCI_REG_PF_M); 1498 ASSERT(i == count); 1499 1500 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, pci_bus_res[bus].dip, 1501 "available", (int *)sp, 1502 i * sizeof (struct pci_phys_spec) / sizeof (int)); 1503 kmem_free(sp, count * sizeof (*sp)); 1504 } 1505 1506 static void 1507 alloc_res_array(void) 1508 { 1509 static int array_max = 0; 1510 int old_max; 1511 void *old_res; 1512 1513 if (array_max > pci_bios_nbus + 1) 1514 return; /* array is big enough */ 1515 1516 old_max = array_max; 1517 old_res = pci_bus_res; 1518 1519 if (array_max == 0) 1520 array_max = 16; /* start with a reasonable number */ 1521 1522 while (array_max < pci_bios_nbus + 1) 1523 array_max <<= 1; 1524 pci_bus_res = (struct pci_bus_resource *)kmem_zalloc( 1525 array_max * sizeof (struct pci_bus_resource), KM_SLEEP); 1526 1527 if (old_res) { /* copy content and free old array */ 1528 bcopy(old_res, pci_bus_res, 1529 old_max * sizeof (struct pci_bus_resource)); 1530 kmem_free(old_res, old_max * sizeof (struct pci_bus_resource)); 1531 } 1532 } 1533