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