6659 nvlist_free(NULL) is a no-op

   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 (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
  23  */
  24 
  25 #include <sys/types.h>
  26 #include <sys/stat.h>
  27 #include <sys/sysmacros.h>
  28 #include <sys/sunndi.h>
  29 #include <sys/pci.h>
  30 #include <sys/pci_impl.h>
  31 #include <sys/pcie_impl.h>
  32 #include <sys/memlist.h>
  33 #include <sys/bootconf.h>
  34 #include <io/pci/mps_table.h>
  35 #include <sys/pci_cfgacc.h>
  36 #include <sys/pci_cfgspace.h>
  37 #include <sys/pci_cfgspace_impl.h>
  38 #include <sys/psw.h>
  39 #include "../../../../common/pci/pci_strings.h"
  40 #include <sys/apic.h>
  41 #include <io/pciex/pcie_nvidia.h>
  42 #include <sys/hotplug/pci/pciehpc_acpi.h>
  43 #include <sys/acpi/acpi.h>
  44 #include <sys/acpica.h>
  45 #include <sys/iommulib.h>
  46 #include <sys/devcache.h>
  47 #include <sys/pci_cfgacc_x86.h>
  48 
  49 #define pci_getb        (*pci_getb_func)
  50 #define pci_getw        (*pci_getw_func)
  51 #define pci_getl        (*pci_getl_func)
  52 #define pci_putb        (*pci_putb_func)
  53 #define pci_putw        (*pci_putw_func)
  54 #define pci_putl        (*pci_putl_func)
  55 #define dcmn_err        if (pci_boot_debug) cmn_err
  56 
  57 #define CONFIG_INFO     0
  58 #define CONFIG_UPDATE   1
  59 #define CONFIG_NEW      2
  60 #define CONFIG_FIX      3
  61 #define COMPAT_BUFSIZE  512
  62 
  63 #define PPB_IO_ALIGNMENT        0x1000          /* 4K aligned */
  64 #define PPB_MEM_ALIGNMENT       0x100000        /* 1M aligned */
  65 /* round down to nearest power of two */
  66 #define P2LE(align)                                     \
  67         {                                               \
  68                 int i = 0;                              \
  69                 while (align >>= 1)                       \
  70                         i ++;                           \
  71                 align = 1 << i;                           \
  72         }                                               \
  73 
  74 /* for is_vga and list_is_vga_only */
  75 
  76 enum io_mem {
  77         IO,
  78         MEM
  79 };
  80 
  81 /* See AMD-8111 Datasheet Rev 3.03, Page 149: */
  82 #define LPC_IO_CONTROL_REG_1    0x40
  83 #define AMD8111_ENABLENMI       (uint8_t)0x80
  84 #define DEVID_AMD8111_LPC       0x7468
  85 
  86 struct pci_fixundo {
  87         uint8_t                 bus;
  88         uint8_t                 dev;
  89         uint8_t                 fn;
  90         void                    (*undofn)(uint8_t, uint8_t, uint8_t);
  91         struct pci_fixundo      *next;
  92 };
  93 
  94 struct pci_devfunc {
  95         struct pci_devfunc *next;
  96         dev_info_t *dip;
  97         uchar_t dev;
  98         uchar_t func;
  99         boolean_t reprogram;    /* this device needs to be reprogrammed */
 100 };
 101 
 102 extern int apic_nvidia_io_max;
 103 extern int pseudo_isa;
 104 extern int pci_bios_maxbus;
 105 static uchar_t max_dev_pci = 32;        /* PCI standard */
 106 int pci_boot_debug = 0;
 107 extern struct memlist *find_bus_res(int, int);
 108 static struct pci_fixundo *undolist = NULL;
 109 static int num_root_bus = 0;    /* count of root buses */
 110 extern volatile int acpi_resource_discovery;
 111 extern uint64_t mcfg_mem_base;
 112 extern void pci_cfgacc_add_workaround(uint16_t, uchar_t, uchar_t);
 113 extern dev_info_t *pcie_get_rc_dip(dev_info_t *);
 114 
 115 /*
 116  * Module prototypes
 117  */
 118 static void enumerate_bus_devs(uchar_t bus, int config_op);
 119 static void create_root_bus_dip(uchar_t bus);
 120 static void process_devfunc(uchar_t, uchar_t, uchar_t, uchar_t,
 121     ushort_t, int);
 122 static void add_compatible(dev_info_t *, ushort_t, ushort_t,
 123     ushort_t, ushort_t, uchar_t, uint_t, int);
 124 static int add_reg_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int, int);
 125 static void add_ppb_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int,
 126     ushort_t);
 127 static void add_model_prop(dev_info_t *, uint_t);
 128 static void add_bus_range_prop(int);
 129 static void add_bus_slot_names_prop(int);
 130 static void add_ranges_prop(int, int);
 131 static void add_bus_available_prop(int);
 132 static int get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id);
 133 static void fix_ppb_res(uchar_t, boolean_t);
 134 static void alloc_res_array();
 135 static void create_ioapic_node(int bus, int dev, int fn, ushort_t vendorid,
 136     ushort_t deviceid);
 137 static void pciex_slot_names_prop(dev_info_t *, ushort_t);
 138 static void populate_bus_res(uchar_t bus);
 139 static void memlist_remove_list(struct memlist **list,
 140     struct memlist *remove_list);
 141 static boolean_t is_pcie_platform(void);
 142 static void ck804_fix_aer_ptr(dev_info_t *, pcie_req_id_t);
 143 
 144 static void pci_scan_bbn(void);
 145 static int pci_unitaddr_cache_valid(void);
 146 static int pci_bus_unitaddr(int);
 147 static void pci_unitaddr_cache_create(void);
 148 
 149 static int pci_cache_unpack_nvlist(nvf_handle_t, nvlist_t *, char *);
 150 static int pci_cache_pack_nvlist(nvf_handle_t, nvlist_t **);
 151 static void pci_cache_free_list(nvf_handle_t);
 152 
 153 extern int pci_slot_names_prop(int, char *, int);
 154 
 155 /* set non-zero to force PCI peer-bus renumbering */
 156 int pci_bus_always_renumber = 0;
 157 
 158 /*
 159  * used to register ISA resource usage which must not be made
 160  * "available" from other PCI node' resource maps
 161  */
 162 static struct {
 163         struct memlist *io_used;
 164         struct memlist *mem_used;
 165 } isa_res;
 166 
 167 /*
 168  * PCI unit-address cache management
 169  */
 170 static nvf_ops_t pci_unitaddr_cache_ops = {
 171         "/etc/devices/pci_unitaddr_persistent", /* path to cache */
 172         pci_cache_unpack_nvlist,                /* read in nvlist form */
 173         pci_cache_pack_nvlist,                  /* convert to nvlist form */
 174         pci_cache_free_list,                    /* free data list */
 175         NULL                                    /* write complete callback */
 176 };
 177 
 178 typedef struct {
 179         list_node_t     pua_nodes;
 180         int             pua_index;
 181         int             pua_addr;
 182 } pua_node_t;
 183 
 184 nvf_handle_t    puafd_handle;
 185 int             pua_cache_valid = 0;
 186 
 187 
 188 /*ARGSUSED*/
 189 static ACPI_STATUS
 190 pci_process_acpi_device(ACPI_HANDLE hdl, UINT32 level, void *ctx, void **rv)
 191 {
 192         ACPI_BUFFER     rb;
 193         ACPI_OBJECT     ro;
 194         ACPI_DEVICE_INFO *adi;
 195         int             busnum;
 196 
 197         /*
 198          * Use AcpiGetObjectInfo() to find the device _HID
 199          * If not a PCI root-bus, ignore this device and continue
 200          * the walk
 201          */
 202         if (ACPI_FAILURE(AcpiGetObjectInfo(hdl, &adi)))
 203                 return (AE_OK);
 204 
 205         if (!(adi->Valid & ACPI_VALID_HID)) {
 206                 AcpiOsFree(adi);
 207                 return (AE_OK);
 208         }
 209 
 210         if (strncmp(adi->HardwareId.String, PCI_ROOT_HID_STRING,
 211             sizeof (PCI_ROOT_HID_STRING)) &&
 212             strncmp(adi->HardwareId.String, PCI_EXPRESS_ROOT_HID_STRING,
 213             sizeof (PCI_EXPRESS_ROOT_HID_STRING))) {
 214                 AcpiOsFree(adi);
 215                 return (AE_OK);
 216         }
 217 
 218         AcpiOsFree(adi);
 219 
 220         /*
 221          * XXX: ancient Big Bear broken _BBN will result in two
 222          * bus 0 _BBNs being found, so we need to handle duplicate
 223          * bus 0 gracefully.  However, broken _BBN does not
 224          * hide a childless root-bridge so no need to work-around it
 225          * here
 226          */
 227         rb.Pointer = &ro;
 228         rb.Length = sizeof (ro);
 229         if (ACPI_SUCCESS(AcpiEvaluateObjectTyped(hdl, "_BBN",
 230             NULL, &rb, ACPI_TYPE_INTEGER))) {
 231                 busnum = ro.Integer.Value;
 232 
 233                 /*
 234                  * Ignore invalid _BBN return values here (rather
 235                  * than panic) and emit a warning; something else
 236                  * may suffer failure as a result of the broken BIOS.
 237                  */
 238                 if ((busnum < 0) || (busnum > pci_bios_maxbus)) {
 239                         dcmn_err(CE_NOTE,
 240                             "pci_process_acpi_device: invalid _BBN 0x%x\n",
 241                             busnum);
 242                         return (AE_CTRL_DEPTH);
 243                 }
 244 
 245                 /* PCI with valid _BBN */
 246                 if (pci_bus_res[busnum].par_bus == (uchar_t)-1 &&
 247                     pci_bus_res[busnum].dip == NULL)
 248                         create_root_bus_dip((uchar_t)busnum);
 249                 return (AE_CTRL_DEPTH);
 250         }
 251 
 252         /* PCI and no _BBN, continue walk */
 253         return (AE_OK);
 254 }
 255 
 256 /*
 257  * Scan the ACPI namespace for all top-level instances of _BBN
 258  * in order to discover childless root-bridges (which enumeration
 259  * may not find; root-bridges are inferred by the existence of
 260  * children).  This scan should find all root-bridges that have
 261  * been enumerated, and any childless root-bridges not enumerated.
 262  * Root-bridge for bus 0 may not have a _BBN object.
 263  */
 264 static void
 265 pci_scan_bbn()
 266 {
 267         void *rv;
 268 
 269         (void) AcpiGetDevices(NULL, pci_process_acpi_device, NULL, &rv);
 270 }
 271 
 272 static void
 273 pci_unitaddr_cache_init(void)
 274 {
 275 
 276         puafd_handle = nvf_register_file(&pci_unitaddr_cache_ops);
 277         ASSERT(puafd_handle);
 278 
 279         list_create(nvf_list(puafd_handle), sizeof (pua_node_t),
 280             offsetof(pua_node_t, pua_nodes));
 281 
 282         rw_enter(nvf_lock(puafd_handle), RW_WRITER);
 283         (void) nvf_read_file(puafd_handle);
 284         rw_exit(nvf_lock(puafd_handle));
 285 }
 286 
 287 /*
 288  * Format of /etc/devices/pci_unitaddr_persistent:
 289  *
 290  * The persistent record of unit-address assignments contains
 291  * a list of name/value pairs, where name is a string representation
 292  * of the "index value" of the PCI root-bus and the value is
 293  * the assigned unit-address.
 294  *
 295  * The "index value" is simply the zero-based index of the PCI
 296  * root-buses ordered by physical bus number; first PCI bus is 0,
 297  * second is 1, and so on.
 298  */
 299 
 300 /*ARGSUSED*/
 301 static int
 302 pci_cache_unpack_nvlist(nvf_handle_t hdl, nvlist_t *nvl, char *name)
 303 {
 304         long            index;
 305         int32_t         value;
 306         nvpair_t        *np;
 307         pua_node_t      *node;
 308 
 309         np = NULL;
 310         while ((np = nvlist_next_nvpair(nvl, np)) != NULL) {
 311                 /* name of nvpair is index value */
 312                 if (ddi_strtol(nvpair_name(np), NULL, 10, &index) != 0)
 313                         continue;
 314 
 315                 if (nvpair_value_int32(np, &value) != 0)
 316                         continue;
 317 
 318                 node = kmem_zalloc(sizeof (pua_node_t), KM_SLEEP);
 319                 node->pua_index = index;
 320                 node->pua_addr = value;
 321                 list_insert_tail(nvf_list(hdl), node);
 322         }
 323 
 324         pua_cache_valid = 1;
 325         return (DDI_SUCCESS);
 326 }
 327 
 328 static int
 329 pci_cache_pack_nvlist(nvf_handle_t hdl, nvlist_t **ret_nvl)
 330 {
 331         int             rval;
 332         nvlist_t        *nvl, *sub_nvl;
 333         list_t          *listp;
 334         pua_node_t      *pua;
 335         char            buf[13];
 336 
 337         ASSERT(RW_WRITE_HELD(nvf_lock(hdl)));
 338 
 339         rval = nvlist_alloc(&nvl, NV_UNIQUE_NAME, KM_SLEEP);
 340         if (rval != DDI_SUCCESS) {
 341                 nvf_error("%s: nvlist alloc error %d\n",
 342                     nvf_cache_name(hdl), rval);
 343                 return (DDI_FAILURE);
 344         }
 345 
 346         sub_nvl = NULL;
 347         rval = nvlist_alloc(&sub_nvl, NV_UNIQUE_NAME, KM_SLEEP);
 348         if (rval != DDI_SUCCESS)
 349                 goto error;
 350 
 351         listp = nvf_list(hdl);
 352         for (pua = list_head(listp); pua != NULL;
 353             pua = list_next(listp, pua)) {
 354                 (void) snprintf(buf, sizeof (buf), "%d", pua->pua_index);
 355                 rval = nvlist_add_int32(sub_nvl, buf, pua->pua_addr);
 356                 if (rval != DDI_SUCCESS)
 357                         goto error;
 358         }
 359 
 360         rval = nvlist_add_nvlist(nvl, "table", sub_nvl);
 361         if (rval != DDI_SUCCESS)
 362                 goto error;
 363         nvlist_free(sub_nvl);
 364 
 365         *ret_nvl = nvl;
 366         return (DDI_SUCCESS);
 367 
 368 error:
 369         if (sub_nvl)
 370                 nvlist_free(sub_nvl);
 371         ASSERT(nvl);
 372         nvlist_free(nvl);
 373         *ret_nvl = NULL;
 374         return (DDI_FAILURE);
 375 }
 376 
 377 static void
 378 pci_cache_free_list(nvf_handle_t hdl)
 379 {
 380         list_t          *listp;
 381         pua_node_t      *pua;
 382 
 383         ASSERT(RW_WRITE_HELD(nvf_lock(hdl)));
 384 
 385         listp = nvf_list(hdl);
 386         for (pua = list_head(listp); pua != NULL;
 387             pua = list_next(listp, pua)) {
 388                 list_remove(listp, pua);
 389                 kmem_free(pua, sizeof (pua_node_t));
 390         }
 391 }
 392 
 393 
 394 static int
 395 pci_unitaddr_cache_valid(void)
 396 {
 397 
 398         /* read only, no need for rw lock */
 399         return (pua_cache_valid);
 400 }
 401 
 402 
 403 static int
 404 pci_bus_unitaddr(int index)
 405 {
 406         pua_node_t      *pua;
 407         list_t          *listp;
 408         int             addr;
 409 
 410         rw_enter(nvf_lock(puafd_handle), RW_READER);
 411 
 412         addr = -1;      /* default return if no match */
 413         listp = nvf_list(puafd_handle);
 414         for (pua = list_head(listp); pua != NULL;
 415             pua = list_next(listp, pua)) {
 416                 if (pua->pua_index == index) {
 417                         addr = pua->pua_addr;
 418                         break;
 419                 }
 420         }
 421 
 422         rw_exit(nvf_lock(puafd_handle));
 423         return (addr);
 424 }
 425 
 426 static void
 427 pci_unitaddr_cache_create(void)
 428 {
 429         int             i, index;
 430         pua_node_t      *node;
 431         list_t          *listp;
 432 
 433         rw_enter(nvf_lock(puafd_handle), RW_WRITER);
 434 
 435         index = 0;
 436         listp = nvf_list(puafd_handle);
 437         for (i = 0; i <= pci_bios_maxbus; i++) {
 438                 /* skip non-root (peer) PCI busses */
 439                 if ((pci_bus_res[i].par_bus != (uchar_t)-1) ||
 440                     (pci_bus_res[i].dip == NULL))
 441                         continue;
 442                 node = kmem_zalloc(sizeof (pua_node_t), KM_SLEEP);
 443                 node->pua_index = index++;
 444                 node->pua_addr = pci_bus_res[i].root_addr;
 445                 list_insert_tail(listp, node);
 446         }
 447 
 448         (void) nvf_mark_dirty(puafd_handle);
 449         rw_exit(nvf_lock(puafd_handle));
 450         nvf_wake_daemon();
 451 }
 452 
 453 
 454 /*
 455  * Enumerate all PCI devices
 456  */
 457 void
 458 pci_setup_tree(void)
 459 {
 460         uint_t i, root_bus_addr = 0;
 461 
 462         /*
 463          * enable mem-mapped pci config space accessing,
 464          * if failed to do so during early boot
 465          */
 466         if ((mcfg_mem_base == NULL) && is_pcie_platform())
 467                 mcfg_mem_base = 0xE0000000;
 468 
 469         alloc_res_array();
 470         for (i = 0; i <= pci_bios_maxbus; i++) {
 471                 pci_bus_res[i].par_bus = (uchar_t)-1;
 472                 pci_bus_res[i].root_addr = (uchar_t)-1;
 473                 pci_bus_res[i].sub_bus = i;
 474         }
 475 
 476         pci_bus_res[0].root_addr = root_bus_addr++;
 477         create_root_bus_dip(0);
 478         enumerate_bus_devs(0, CONFIG_INFO);
 479 
 480         /*
 481          * Now enumerate peer busses
 482          *
 483          * We loop till pci_bios_maxbus. On most systems, there is
 484          * one more bus at the high end, which implements the ISA
 485          * compatibility bus. We don't care about that.
 486          *
 487          * Note: In the old (bootconf) enumeration, the peer bus
 488          *      address did not use the bus number, and there were
 489          *      too many peer busses created. The root_bus_addr is
 490          *      used to maintain the old peer bus address assignment.
 491          *      However, we stop enumerating phantom peers with no
 492          *      device below.
 493          */
 494         for (i = 1; i <= pci_bios_maxbus; i++) {
 495                 if (pci_bus_res[i].dip == NULL) {
 496                         pci_bus_res[i].root_addr = root_bus_addr++;
 497                 }
 498                 enumerate_bus_devs(i, CONFIG_INFO);
 499 
 500                 /* add slot-names property for named pci hot-plug slots */
 501                 add_bus_slot_names_prop(i);
 502         }
 503 
 504 }
 505 
 506 /*
 507  * >0 = present, 0 = not present, <0 = error
 508  */
 509 static int
 510 pci_bbn_present(int bus)
 511 {
 512         ACPI_HANDLE     hdl;
 513         int     rv;
 514 
 515         /* no dip means no _BBN */
 516         if (pci_bus_res[bus].dip == NULL)
 517                 return (0);
 518 
 519         rv = -1;        /* default return value in case of error below */
 520         if (ACPI_SUCCESS(acpica_get_handle(pci_bus_res[bus].dip, &hdl))) {
 521                 switch (AcpiEvaluateObject(hdl, "_BBN", NULL, NULL)) {
 522                 case AE_OK:
 523                         rv = 1;
 524                         break;
 525                 case AE_NOT_FOUND:
 526                         rv = 0;
 527                         break;
 528                 default:
 529                         break;
 530                 }
 531         }
 532 
 533         return (rv);
 534 }
 535 
 536 /*
 537  * Return non-zero if any PCI bus in the system has an associated
 538  * _BBN object, 0 otherwise.
 539  */
 540 static int
 541 pci_roots_have_bbn(void)
 542 {
 543         int     i;
 544 
 545         /*
 546          * Scan the PCI busses and look for at least 1 _BBN
 547          */
 548         for (i = 0; i <= pci_bios_maxbus; i++) {
 549                 /* skip non-root (peer) PCI busses */
 550                 if (pci_bus_res[i].par_bus != (uchar_t)-1)
 551                         continue;
 552 
 553                 if (pci_bbn_present(i) > 0)
 554                         return (1);
 555         }
 556         return (0);
 557 
 558 }
 559 
 560 /*
 561  * return non-zero if the machine is one on which we renumber
 562  * the internal pci unit-addresses
 563  */
 564 static int
 565 pci_bus_renumber()
 566 {
 567         ACPI_TABLE_HEADER *fadt;
 568 
 569         if (pci_bus_always_renumber)
 570                 return (1);
 571 
 572         /* get the FADT */
 573         if (AcpiGetTable(ACPI_SIG_FADT, 1, (ACPI_TABLE_HEADER **)&fadt) !=
 574             AE_OK)
 575                 return (0);
 576 
 577         /* compare OEM Table ID to "SUNm31" */
 578         if (strncmp("SUNm31", fadt->OemId, 6))
 579                 return (0);
 580         else
 581                 return (1);
 582 }
 583 
 584 /*
 585  * Initial enumeration of the physical PCI bus hierarchy can
 586  * leave 'gaps' in the order of peer PCI bus unit-addresses.
 587  * Systems with more than one peer PCI bus *must* have an ACPI
 588  * _BBN object associated with each peer bus; use the presence
 589  * of this object to remove gaps in the numbering of the peer
 590  * PCI bus unit-addresses - only peer busses with an associated
 591  * _BBN are counted.
 592  */
 593 static void
 594 pci_renumber_root_busses(void)
 595 {
 596         int pci_regs[] = {0, 0, 0};
 597         int     i, root_addr = 0;
 598 
 599         /*
 600          * Currently, we only enable the re-numbering on specific
 601          * Sun machines; this is a work-around for the more complicated
 602          * issue of upgrade changing physical device paths
 603          */
 604         if (!pci_bus_renumber())
 605                 return;
 606 
 607         /*
 608          * If we find no _BBN objects at all, we either don't need
 609          * to do anything or can't do anything anyway
 610          */
 611         if (!pci_roots_have_bbn())
 612                 return;
 613 
 614         for (i = 0; i <= pci_bios_maxbus; i++) {
 615                 /* skip non-root (peer) PCI busses */
 616                 if (pci_bus_res[i].par_bus != (uchar_t)-1)
 617                         continue;
 618 
 619                 if (pci_bbn_present(i) < 1) {
 620                         pci_bus_res[i].root_addr = (uchar_t)-1;
 621                         continue;
 622                 }
 623 
 624                 ASSERT(pci_bus_res[i].dip != NULL);
 625                 if (pci_bus_res[i].root_addr != root_addr) {
 626                         /* update reg property for node */
 627                         pci_bus_res[i].root_addr = root_addr;
 628                         pci_regs[0] = pci_bus_res[i].root_addr;
 629                         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
 630                             pci_bus_res[i].dip, "reg", (int *)pci_regs, 3);
 631                 }
 632                 root_addr++;
 633         }
 634 }
 635 
 636 void
 637 pci_register_isa_resources(int type, uint32_t base, uint32_t size)
 638 {
 639         (void) memlist_insert(
 640             (type == 1) ?  &isa_res.io_used : &isa_res.mem_used,
 641             base, size);
 642 }
 643 
 644 /*
 645  * Remove the resources which are already used by devices under a subtractive
 646  * bridge from the bus's resources lists, because they're not available, and
 647  * shouldn't be allocated to other buses.  This is necessary because tracking
 648  * resources for subtractive bridges is not complete.  (Subtractive bridges only
 649  * track some of their claimed resources, not "the rest of the address space" as
 650  * they should, so that allocation to peer non-subtractive PPBs is easier.  We
 651  * need a fully-capable global resource allocator).
 652  */
 653 static void
 654 remove_subtractive_res()
 655 {
 656         int i, j;
 657         struct memlist *list;
 658 
 659         for (i = 0; i <= pci_bios_maxbus; i++) {
 660                 if (pci_bus_res[i].subtractive) {
 661                         /* remove used io ports */
 662                         list = pci_bus_res[i].io_used;
 663                         while (list) {
 664                                 for (j = 0; j <= pci_bios_maxbus; j++)
 665                                         (void) memlist_remove(
 666                                             &pci_bus_res[j].io_avail,
 667                                             list->ml_address, list->ml_size);
 668                                 list = list->ml_next;
 669                         }
 670                         /* remove used mem resource */
 671                         list = pci_bus_res[i].mem_used;
 672                         while (list) {
 673                                 for (j = 0; j <= pci_bios_maxbus; j++) {
 674                                         (void) memlist_remove(
 675                                             &pci_bus_res[j].mem_avail,
 676                                             list->ml_address, list->ml_size);
 677                                         (void) memlist_remove(
 678                                             &pci_bus_res[j].pmem_avail,
 679                                             list->ml_address, list->ml_size);
 680                                 }
 681                                 list = list->ml_next;
 682                         }
 683                         /* remove used prefetchable mem resource */
 684                         list = pci_bus_res[i].pmem_used;
 685                         while (list) {
 686                                 for (j = 0; j <= pci_bios_maxbus; j++) {
 687                                         (void) memlist_remove(
 688                                             &pci_bus_res[j].pmem_avail,
 689                                             list->ml_address, list->ml_size);
 690                                         (void) memlist_remove(
 691                                             &pci_bus_res[j].mem_avail,
 692                                             list->ml_address, list->ml_size);
 693                                 }
 694                                 list = list->ml_next;
 695                         }
 696                 }
 697         }
 698 }
 699 
 700 /*
 701  * Set up (or complete the setup of) the bus_avail resource list
 702  */
 703 static void
 704 setup_bus_res(int bus)
 705 {
 706         uchar_t par_bus;
 707 
 708         if (pci_bus_res[bus].dip == NULL)       /* unused bus */
 709                 return;
 710 
 711         /*
 712          * Set up bus_avail if not already filled in by populate_bus_res()
 713          */
 714         if (pci_bus_res[bus].bus_avail == NULL) {
 715                 ASSERT(pci_bus_res[bus].sub_bus >= bus);
 716                 memlist_insert(&pci_bus_res[bus].bus_avail, bus,
 717                     pci_bus_res[bus].sub_bus - bus + 1);
 718         }
 719 
 720         ASSERT(pci_bus_res[bus].bus_avail != NULL);
 721 
 722         /*
 723          * Remove resources from parent bus node if this is not a
 724          * root bus.
 725          */
 726         par_bus = pci_bus_res[bus].par_bus;
 727         if (par_bus != (uchar_t)-1) {
 728                 ASSERT(pci_bus_res[par_bus].bus_avail != NULL);
 729                 memlist_remove_list(&pci_bus_res[par_bus].bus_avail,
 730                     pci_bus_res[bus].bus_avail);
 731         }
 732 
 733         /* remove self from bus_avail */;
 734         (void) memlist_remove(&pci_bus_res[bus].bus_avail, bus, 1);
 735 }
 736 
 737 static uint64_t
 738 get_parbus_io_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align)
 739 {
 740         uint64_t addr = 0;
 741         uchar_t res_bus;
 742 
 743         /*
 744          * Skip root(peer) buses in multiple-root-bus systems when
 745          * ACPI resource discovery was not successfully done.
 746          */
 747         if ((pci_bus_res[parbus].par_bus == (uchar_t)-1) &&
 748             (num_root_bus > 1) && (acpi_resource_discovery <= 0))
 749                 return (0);
 750 
 751         res_bus = parbus;
 752         while (pci_bus_res[res_bus].subtractive) {
 753                 if (pci_bus_res[res_bus].io_avail)
 754                         break;
 755                 res_bus = pci_bus_res[res_bus].par_bus;
 756                 if (res_bus == (uchar_t)-1)
 757                         break; /* root bus already */
 758         }
 759 
 760         if (pci_bus_res[res_bus].io_avail) {
 761                 addr = memlist_find(&pci_bus_res[res_bus].io_avail,
 762                     size, align);
 763                 if (addr) {
 764                         memlist_insert(&pci_bus_res[res_bus].io_used,
 765                             addr, size);
 766 
 767                         /* free the old resource */
 768                         memlist_free_all(&pci_bus_res[bus].io_avail);
 769                         memlist_free_all(&pci_bus_res[bus].io_used);
 770 
 771                         /* add the new resource */
 772                         memlist_insert(&pci_bus_res[bus].io_avail, addr, size);
 773                 }
 774         }
 775 
 776         return (addr);
 777 }
 778 
 779 static uint64_t
 780 get_parbus_mem_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align)
 781 {
 782         uint64_t addr = 0;
 783         uchar_t res_bus;
 784 
 785         /*
 786          * Skip root(peer) buses in multiple-root-bus systems when
 787          * ACPI resource discovery was not successfully done.
 788          */
 789         if ((pci_bus_res[parbus].par_bus == (uchar_t)-1) &&
 790             (num_root_bus > 1) && (acpi_resource_discovery <= 0))
 791                 return (0);
 792 
 793         res_bus = parbus;
 794         while (pci_bus_res[res_bus].subtractive) {
 795                 if (pci_bus_res[res_bus].mem_avail)
 796                         break;
 797                 res_bus = pci_bus_res[res_bus].par_bus;
 798                 if (res_bus == (uchar_t)-1)
 799                         break; /* root bus already */
 800         }
 801 
 802         if (pci_bus_res[res_bus].mem_avail) {
 803                 addr = memlist_find(&pci_bus_res[res_bus].mem_avail,
 804                     size, align);
 805                 if (addr) {
 806                         memlist_insert(&pci_bus_res[res_bus].mem_used,
 807                             addr, size);
 808                         (void) memlist_remove(&pci_bus_res[res_bus].pmem_avail,
 809                             addr, size);
 810 
 811                         /* free the old resource */
 812                         memlist_free_all(&pci_bus_res[bus].mem_avail);
 813                         memlist_free_all(&pci_bus_res[bus].mem_used);
 814 
 815                         /* add the new resource */
 816                         memlist_insert(&pci_bus_res[bus].mem_avail, addr, size);
 817                 }
 818         }
 819 
 820         return (addr);
 821 }
 822 
 823 /*
 824  * given a cap_id, return its cap_id location in config space
 825  */
 826 static int
 827 get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id)
 828 {
 829         uint8_t curcap, cap_id_loc;
 830         uint16_t status;
 831         int location = -1;
 832 
 833         /*
 834          * Need to check the Status register for ECP support first.
 835          * Also please note that for type 1 devices, the
 836          * offset could change. Should support type 1 next.
 837          */
 838         status = pci_getw(bus, dev, func, PCI_CONF_STAT);
 839         if (!(status & PCI_STAT_CAP)) {
 840                 return (-1);
 841         }
 842         cap_id_loc = pci_getb(bus, dev, func, PCI_CONF_CAP_PTR);
 843 
 844         /* Walk the list of capabilities */
 845         while (cap_id_loc && cap_id_loc != (uint8_t)-1) {
 846                 curcap = pci_getb(bus, dev, func, cap_id_loc);
 847 
 848                 if (curcap == cap_id) {
 849                         location = cap_id_loc;
 850                         break;
 851                 }
 852                 cap_id_loc = pci_getb(bus, dev, func, cap_id_loc + 1);
 853         }
 854         return (location);
 855 }
 856 
 857 /*
 858  * Does this resource element live in the legacy VGA range?
 859  */
 860 
 861 int
 862 is_vga(struct memlist *elem, enum io_mem io)
 863 {
 864 
 865         if (io == IO) {
 866                 if ((elem->ml_address == 0x3b0 && elem->ml_size == 0xc) ||
 867                     (elem->ml_address == 0x3c0 && elem->ml_size == 0x20))
 868                         return (1);
 869         } else {
 870                 if (elem->ml_address == 0xa0000 && elem->ml_size == 0x20000)
 871                         return (1);
 872         }
 873         return (0);
 874 }
 875 
 876 /*
 877  * Does this entire resource list consist only of legacy VGA resources?
 878  */
 879 
 880 int
 881 list_is_vga_only(struct memlist *l, enum io_mem io)
 882 {
 883         do {
 884                 if (!is_vga(l, io))
 885                         return (0);
 886         } while ((l = l->ml_next) != NULL);
 887         return (1);
 888 }
 889 
 890 /*
 891  * Assign valid resources to unconfigured pci(e) bridges. We are trying
 892  * to reprogram the bridge when its
 893  *              i)   SECBUS == SUBBUS   ||
 894  *              ii)  IOBASE > IOLIM  ||
 895  *              iii) MEMBASE > MEMLIM
 896  * This must be done after one full pass through the PCI tree to collect
 897  * all BIOS-configured resources, so that we know what resources are
 898  * free and available to assign to the unconfigured PPBs.
 899  */
 900 static void
 901 fix_ppb_res(uchar_t secbus, boolean_t prog_sub)
 902 {
 903         uchar_t bus, dev, func;
 904         uchar_t parbus, subbus;
 905         uint_t io_base, io_limit, mem_base, mem_limit;
 906         uint_t io_size, mem_size, io_align, mem_align;
 907         uint64_t addr = 0;
 908         int *regp = NULL;
 909         uint_t reglen;
 910         int rv, cap_ptr, physhi;
 911         dev_info_t *dip;
 912         uint16_t cmd_reg;
 913         struct memlist *list, *scratch_list;
 914 
 915         /* skip root (peer) PCI busses */
 916         if (pci_bus_res[secbus].par_bus == (uchar_t)-1)
 917                 return;
 918 
 919         /* skip subtractive PPB when prog_sub is not TRUE */
 920         if (pci_bus_res[secbus].subtractive && !prog_sub)
 921                 return;
 922 
 923         /* some entries may be empty due to discontiguous bus numbering */
 924         dip = pci_bus_res[secbus].dip;
 925         if (dip == NULL)
 926                 return;
 927 
 928         rv = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
 929             "reg", &regp, &reglen);
 930         if (rv != DDI_PROP_SUCCESS || reglen == 0)
 931                 return;
 932         physhi = regp[0];
 933         ddi_prop_free(regp);
 934 
 935         func = (uchar_t)PCI_REG_FUNC_G(physhi);
 936         dev = (uchar_t)PCI_REG_DEV_G(physhi);
 937         bus = (uchar_t)PCI_REG_BUS_G(physhi);
 938 
 939         /*
 940          * If pcie bridge, check to see if link is enabled
 941          */
 942         cap_ptr = get_pci_cap(bus, dev, func, PCI_CAP_ID_PCI_E);
 943         if (cap_ptr != -1) {
 944                 cmd_reg = pci_getw(bus, dev, func,
 945                     (uint16_t)cap_ptr + PCIE_LINKCTL);
 946                 if (cmd_reg & PCIE_LINKCTL_LINK_DISABLE) {
 947                         dcmn_err(CE_NOTE,
 948                             "!fix_ppb_res: ppb[%x/%x/%x] link is disabled.\n",
 949                             bus, dev, func);
 950                         return;
 951                 }
 952         }
 953 
 954         subbus = pci_getb(bus, dev, func, PCI_BCNF_SUBBUS);
 955         parbus = pci_bus_res[secbus].par_bus;
 956         ASSERT(parbus == bus);
 957         cmd_reg = pci_getw(bus, dev, func, PCI_CONF_COMM);
 958 
 959         /*
 960          * If we have a Cardbus bridge, but no bus space
 961          */
 962         if (pci_bus_res[secbus].num_cbb != 0 &&
 963             pci_bus_res[secbus].bus_avail == NULL) {
 964                 uchar_t range;
 965 
 966                 /* normally there are 2 buses under a cardbus bridge */
 967                 range = pci_bus_res[secbus].num_cbb * 2;
 968 
 969                 /*
 970                  * Try to find and allocate a bus-range starting at subbus+1
 971                  * from the parent of the PPB.
 972                  */
 973                 for (; range != 0; range--) {
 974                         if (memlist_find_with_startaddr(
 975                             &pci_bus_res[parbus].bus_avail,
 976                             subbus + 1, range, 1) != NULL)
 977                                 break; /* find bus range resource at parent */
 978                 }
 979                 if (range != 0) {
 980                         memlist_insert(&pci_bus_res[secbus].bus_avail,
 981                             subbus + 1, range);
 982                         subbus = subbus + range;
 983                         pci_bus_res[secbus].sub_bus = subbus;
 984                         pci_putb(bus, dev, func, PCI_BCNF_SUBBUS, subbus);
 985                         add_bus_range_prop(secbus);
 986 
 987                         cmn_err(CE_NOTE, "!reprogram bus-range on ppb"
 988                             "[%x/%x/%x]: %x ~ %x\n", bus, dev, func,
 989                             secbus, subbus);
 990                 }
 991         }
 992 
 993         /*
 994          * Calculate required IO size and alignment
 995          * If bus io_size is zero, we are going to assign 512 bytes per bus,
 996          * otherwise, we'll choose the maximum value of such calculation and
 997          * bus io_size. The size needs to be 4K aligned.
 998          *
 999          * We calculate alignment as the largest power of two less than the
1000          * the sum of all children's IO size requirements, because this will
1001          * align to the size of the largest child request within that size
1002          * (which is always a power of two).
1003          */
1004         io_size = (subbus - secbus + 1) * 0x200;
1005         if (io_size <  pci_bus_res[secbus].io_size)
1006                 io_size = pci_bus_res[secbus].io_size;
1007         io_size = P2ROUNDUP(io_size, PPB_IO_ALIGNMENT);
1008         io_align = io_size;
1009         P2LE(io_align);
1010 
1011         /*
1012          * Calculate required MEM size and alignment
1013          * If bus mem_size is zero, we are going to assign 1M bytes per bus,
1014          * otherwise, we'll choose the maximum value of such calculation and
1015          * bus mem_size. The size needs to be 1M aligned.
1016          *
1017          * For the alignment, refer to the I/O comment above.
1018          */
1019         mem_size = (subbus - secbus + 1) * PPB_MEM_ALIGNMENT;
1020         if (mem_size < pci_bus_res[secbus].mem_size) {
1021                 mem_size = pci_bus_res[secbus].mem_size;
1022                 mem_size = P2ROUNDUP(mem_size, PPB_MEM_ALIGNMENT);
1023         }
1024         mem_align = mem_size;
1025         P2LE(mem_align);
1026 
1027         /* Subtractive bridge */
1028         if (pci_bus_res[secbus].subtractive && prog_sub) {
1029                 /*
1030                  * We program an arbitrary amount of I/O and memory resource
1031                  * for the subtractive bridge so that child dynamic-resource-
1032                  * allocating devices (such as Cardbus bridges) have a chance
1033                  * of success.  Until we have full-tree resource rebalancing,
1034                  * dynamic resource allocation (thru busra) only looks at the
1035                  * parent bridge, so all PPBs must have some allocatable
1036                  * resource.  For non-subtractive bridges, the resources come
1037                  * from the base/limit register "windows", but subtractive
1038                  * bridges often don't program those (since they don't need to).
1039                  * If we put all the remaining resources on the subtractive
1040                  * bridge, then peer non-subtractive bridges can't allocate
1041                  * more space (even though this is probably most correct).
1042                  * If we put the resources only on the parent, then allocations
1043                  * from children of subtractive bridges will fail without
1044                  * special-case code for bypassing the subtractive bridge.
1045                  * This solution is the middle-ground temporary solution until
1046                  * we have fully-capable resource allocation.
1047                  */
1048 
1049                 /*
1050                  * Add an arbitrary I/O resource to the subtractive PPB
1051                  */
1052                 if (pci_bus_res[secbus].io_avail == NULL) {
1053                         addr = get_parbus_io_res(parbus, secbus, io_size,
1054                             io_align);
1055                         if (addr) {
1056                                 add_ranges_prop(secbus, 1);
1057                                 pci_bus_res[secbus].io_reprogram =
1058                                     pci_bus_res[parbus].io_reprogram;
1059 
1060                                 cmn_err(CE_NOTE, "!add io-range on subtractive"
1061                                     " ppb[%x/%x/%x]: 0x%x ~ 0x%x\n",
1062                                     bus, dev, func, (uint32_t)addr,
1063                                     (uint32_t)addr + io_size - 1);
1064                         }
1065                 }
1066                 /*
1067                  * Add an arbitrary memory resource to the subtractive PPB
1068                  */
1069                 if (pci_bus_res[secbus].mem_avail == NULL) {
1070                         addr = get_parbus_mem_res(parbus, secbus, mem_size,
1071                             mem_align);
1072                         if (addr) {
1073                                 add_ranges_prop(secbus, 1);
1074                                 pci_bus_res[secbus].mem_reprogram =
1075                                     pci_bus_res[parbus].mem_reprogram;
1076 
1077                                 cmn_err(CE_NOTE, "!add mem-range on "
1078                                     "subtractive ppb[%x/%x/%x]: 0x%x ~ 0x%x\n",
1079                                     bus, dev, func, (uint32_t)addr,
1080                                     (uint32_t)addr + mem_size - 1);
1081                         }
1082                 }
1083 
1084                 goto cmd_enable;
1085         }
1086 
1087         /*
1088          * Check to see if we need to reprogram I/O space, either because the
1089          * parent bus needed reprogramming and so do we, or because I/O space is
1090          * disabled in base/limit or command register.
1091          */
1092         io_base = pci_getb(bus, dev, func, PCI_BCNF_IO_BASE_LOW);
1093         io_limit = pci_getb(bus, dev, func, PCI_BCNF_IO_LIMIT_LOW);
1094         io_base = (io_base & 0xf0) << 8;
1095         io_limit = ((io_limit & 0xf0) << 8) | 0xfff;
1096 
1097         /* Form list of all resources passed (avail + used) */
1098         scratch_list = memlist_dup(pci_bus_res[secbus].io_avail);
1099         memlist_merge(&pci_bus_res[secbus].io_used, &scratch_list);
1100 
1101         if ((pci_bus_res[parbus].io_reprogram ||
1102             (io_base > io_limit) ||
1103             (!(cmd_reg & PCI_COMM_IO))) &&
1104             !list_is_vga_only(scratch_list, IO)) {
1105                 if (pci_bus_res[secbus].io_used) {
1106                         memlist_subsume(&pci_bus_res[secbus].io_used,
1107                             &pci_bus_res[secbus].io_avail);
1108                 }
1109                 if (pci_bus_res[secbus].io_avail &&
1110                     (!pci_bus_res[parbus].io_reprogram) &&
1111                     (!pci_bus_res[parbus].subtractive)) {
1112                         /* rechoose old io ports info */
1113                         list = pci_bus_res[secbus].io_avail;
1114                         io_base = 0;
1115                         do {
1116                                 if (is_vga(list, IO))
1117                                         continue;
1118                                 if (!io_base) {
1119                                         io_base = (uint_t)list->ml_address;
1120                                         io_limit = (uint_t)list->ml_address +
1121                                             list->ml_size - 1;
1122                                         io_base =
1123                                             P2ALIGN(io_base, PPB_IO_ALIGNMENT);
1124                                 } else {
1125                                         if (list->ml_address + list->ml_size >
1126                                             io_limit) {
1127                                                 io_limit = (uint_t)
1128                                                     (list->ml_address +
1129                                                     list->ml_size - 1);
1130                                         }
1131                                 }
1132                         } while ((list = list->ml_next) != NULL);
1133                         /* 4K aligned */
1134                         io_limit = P2ROUNDUP(io_limit, PPB_IO_ALIGNMENT) - 1;
1135                         io_size = io_limit - io_base + 1;
1136                         ASSERT(io_base <= io_limit);
1137                         memlist_free_all(&pci_bus_res[secbus].io_avail);
1138                         memlist_insert(&pci_bus_res[secbus].io_avail,
1139                             io_base, io_size);
1140                         memlist_insert(&pci_bus_res[parbus].io_used,
1141                             io_base, io_size);
1142                         (void) memlist_remove(&pci_bus_res[parbus].io_avail,
1143                             io_base, io_size);
1144                         pci_bus_res[secbus].io_reprogram = B_TRUE;
1145                 } else {
1146                         /* get new io ports from parent bus */
1147                         addr = get_parbus_io_res(parbus, secbus, io_size,
1148                             io_align);
1149                         if (addr) {
1150                                 io_base = addr;
1151                                 io_limit = addr + io_size - 1;
1152                                 pci_bus_res[secbus].io_reprogram = B_TRUE;
1153                         }
1154                 }
1155                 if (pci_bus_res[secbus].io_reprogram) {
1156                         /* reprogram PPB regs */
1157                         pci_putb(bus, dev, func, PCI_BCNF_IO_BASE_LOW,
1158                             (uchar_t)((io_base>>8) & 0xf0));
1159                         pci_putb(bus, dev, func, PCI_BCNF_IO_LIMIT_LOW,
1160                             (uchar_t)((io_limit>>8) & 0xf0));
1161                         pci_putb(bus, dev, func, PCI_BCNF_IO_BASE_HI, 0);
1162                         pci_putb(bus, dev, func, PCI_BCNF_IO_LIMIT_HI, 0);
1163                         add_ranges_prop(secbus, 1);
1164 
1165                         cmn_err(CE_NOTE, "!reprogram io-range on"
1166                             " ppb[%x/%x/%x]: 0x%x ~ 0x%x\n",
1167                             bus, dev, func, io_base, io_limit);
1168                 }
1169         }
1170         memlist_free_all(&scratch_list);
1171 
1172         /*
1173          * Check memory space as we did I/O space.
1174          */
1175         mem_base = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_MEM_BASE);
1176         mem_base = (mem_base & 0xfff0) << 16;
1177         mem_limit = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_MEM_LIMIT);
1178         mem_limit = ((mem_limit & 0xfff0) << 16) | 0xfffff;
1179 
1180         scratch_list = memlist_dup(pci_bus_res[secbus].mem_avail);
1181         memlist_merge(&pci_bus_res[secbus].mem_used, &scratch_list);
1182 
1183         if ((pci_bus_res[parbus].mem_reprogram ||
1184             (mem_base > mem_limit) ||
1185             (!(cmd_reg & PCI_COMM_MAE))) &&
1186             !list_is_vga_only(scratch_list, MEM)) {
1187                 if (pci_bus_res[secbus].mem_used) {
1188                         memlist_subsume(&pci_bus_res[secbus].mem_used,
1189                             &pci_bus_res[secbus].mem_avail);
1190                 }
1191                 if (pci_bus_res[secbus].mem_avail &&
1192                     (!pci_bus_res[parbus].mem_reprogram) &&
1193                     (!pci_bus_res[parbus].subtractive)) {
1194                         /* rechoose old mem resource */
1195                         list = pci_bus_res[secbus].mem_avail;
1196                         mem_base = 0;
1197                         do {
1198                                 if (is_vga(list, MEM))
1199                                         continue;
1200                                 if (mem_base == 0) {
1201                                         mem_base = (uint_t)list->ml_address;
1202                                         mem_base = P2ALIGN(mem_base,
1203                                             PPB_MEM_ALIGNMENT);
1204                                         mem_limit = (uint_t)(list->ml_address +
1205                                             list->ml_size - 1);
1206                                 } else {
1207                                         if ((list->ml_address + list->ml_size) >
1208                                             mem_limit) {
1209                                                 mem_limit = (uint_t)
1210                                                     (list->ml_address +
1211                                                     list->ml_size - 1);
1212                                         }
1213                                 }
1214                         } while ((list = list->ml_next) != NULL);
1215                         mem_limit = P2ROUNDUP(mem_limit, PPB_MEM_ALIGNMENT) - 1;
1216                         mem_size = mem_limit + 1 - mem_base;
1217                         ASSERT(mem_base <= mem_limit);
1218                         memlist_free_all(&pci_bus_res[secbus].mem_avail);
1219                         memlist_insert(&pci_bus_res[secbus].mem_avail,
1220                             mem_base, mem_size);
1221                         memlist_insert(&pci_bus_res[parbus].mem_used,
1222                             mem_base, mem_size);
1223                         (void) memlist_remove(&pci_bus_res[parbus].mem_avail,
1224                             mem_base, mem_size);
1225                         pci_bus_res[secbus].mem_reprogram = B_TRUE;
1226                 } else {
1227                         /* get new mem resource from parent bus */
1228                         addr = get_parbus_mem_res(parbus, secbus, mem_size,
1229                             mem_align);
1230                         if (addr) {
1231                                 mem_base = addr;
1232                                 mem_limit = addr + mem_size - 1;
1233                                 pci_bus_res[secbus].mem_reprogram = B_TRUE;
1234                         }
1235                 }
1236 
1237                 if (pci_bus_res[secbus].mem_reprogram) {
1238                         /* reprogram PPB MEM regs */
1239                         pci_putw(bus, dev, func, PCI_BCNF_MEM_BASE,
1240                             (uint16_t)((mem_base>>16) & 0xfff0));
1241                         pci_putw(bus, dev, func, PCI_BCNF_MEM_LIMIT,
1242                             (uint16_t)((mem_limit>>16) & 0xfff0));
1243                         /*
1244                          * Disable PMEM window by setting base > limit.
1245                          * We currently don't reprogram the PMEM like we've
1246                          * done for I/O and MEM. (Devices that support prefetch
1247                          * can use non-prefetch MEM.) Anyway, if the MEM access
1248                          * bit is initially disabled by BIOS, we disable the
1249                          * PMEM window manually by setting PMEM base > PMEM
1250                          * limit here, in case there are incorrect values in
1251                          * them from BIOS, so that we won't get in trouble once
1252                          * the MEM access bit is enabled at the end of this
1253                          * function.
1254                          */
1255                         if (!(cmd_reg & PCI_COMM_MAE)) {
1256                                 pci_putw(bus, dev, func, PCI_BCNF_PF_BASE_LOW,
1257                                     0xfff0);
1258                                 pci_putw(bus, dev, func, PCI_BCNF_PF_LIMIT_LOW,
1259                                     0x0);
1260                                 pci_putl(bus, dev, func, PCI_BCNF_PF_BASE_HIGH,
1261                                     0xffffffff);
1262                                 pci_putl(bus, dev, func, PCI_BCNF_PF_LIMIT_HIGH,
1263                                     0x0);
1264                         }
1265 
1266                         add_ranges_prop(secbus, 1);
1267 
1268                         cmn_err(CE_NOTE, "!reprogram mem-range on"
1269                             " ppb[%x/%x/%x]: 0x%x ~ 0x%x\n",
1270                             bus, dev, func, mem_base, mem_limit);
1271                 }
1272         }
1273         memlist_free_all(&scratch_list);
1274 
1275 cmd_enable:
1276         if (pci_bus_res[secbus].io_avail)
1277                 cmd_reg |= PCI_COMM_IO | PCI_COMM_ME;
1278         if (pci_bus_res[secbus].mem_avail)
1279                 cmd_reg |= PCI_COMM_MAE | PCI_COMM_ME;
1280         pci_putw(bus, dev, func, PCI_CONF_COMM, cmd_reg);
1281 }
1282 
1283 void
1284 pci_reprogram(void)
1285 {
1286         int i, pci_reconfig = 1;
1287         char *onoff;
1288         int bus;
1289 
1290         /*
1291          * Scan ACPI namespace for _BBN objects, make sure that
1292          * childless root-bridges appear in devinfo tree
1293          */
1294         pci_scan_bbn();
1295         pci_unitaddr_cache_init();
1296 
1297         /*
1298          * Fix-up unit-address assignments if cache is available
1299          */
1300         if (pci_unitaddr_cache_valid()) {
1301                 int pci_regs[] = {0, 0, 0};
1302                 int     new_addr;
1303                 int     index = 0;
1304 
1305                 for (bus = 0; bus <= pci_bios_maxbus; bus++) {
1306                         /* skip non-root (peer) PCI busses */
1307                         if ((pci_bus_res[bus].par_bus != (uchar_t)-1) ||
1308                             (pci_bus_res[bus].dip == NULL))
1309                                 continue;
1310 
1311                         new_addr = pci_bus_unitaddr(index);
1312                         if (pci_bus_res[bus].root_addr != new_addr) {
1313                                 /* update reg property for node */
1314                                 pci_regs[0] = pci_bus_res[bus].root_addr =
1315                                     new_addr;
1316                                 (void) ndi_prop_update_int_array(
1317                                     DDI_DEV_T_NONE, pci_bus_res[bus].dip,
1318                                     "reg", (int *)pci_regs, 3);
1319                         }
1320                         index++;
1321                 }
1322         } else {
1323                 /* perform legacy processing */
1324                 pci_renumber_root_busses();
1325                 pci_unitaddr_cache_create();
1326         }
1327 
1328         /*
1329          * Do root-bus resource discovery
1330          */
1331         for (bus = 0; bus <= pci_bios_maxbus; bus++) {
1332                 /* skip non-root (peer) PCI busses */
1333                 if (pci_bus_res[bus].par_bus != (uchar_t)-1)
1334                         continue;
1335 
1336                 /*
1337                  * 1. find resources associated with this root bus
1338                  */
1339                 populate_bus_res(bus);
1340 
1341 
1342                 /*
1343                  * 2. Remove used PCI and ISA resources from bus resource map
1344                  */
1345 
1346                 memlist_remove_list(&pci_bus_res[bus].io_avail,
1347                     pci_bus_res[bus].io_used);
1348                 memlist_remove_list(&pci_bus_res[bus].mem_avail,
1349                     pci_bus_res[bus].mem_used);
1350                 memlist_remove_list(&pci_bus_res[bus].pmem_avail,
1351                     pci_bus_res[bus].pmem_used);
1352                 memlist_remove_list(&pci_bus_res[bus].mem_avail,
1353                     pci_bus_res[bus].pmem_used);
1354                 memlist_remove_list(&pci_bus_res[bus].pmem_avail,
1355                     pci_bus_res[bus].mem_used);
1356 
1357                 memlist_remove_list(&pci_bus_res[bus].io_avail,
1358                     isa_res.io_used);
1359                 memlist_remove_list(&pci_bus_res[bus].mem_avail,
1360                     isa_res.mem_used);
1361 
1362                 /*
1363                  * 3. Exclude <1M address range here in case below reserved
1364                  * ranges for BIOS data area, ROM area etc are wrongly reported
1365                  * in ACPI resource producer entries for PCI root bus.
1366                  *      00000000 - 000003FF     RAM
1367                  *      00000400 - 000004FF     BIOS data area
1368                  *      00000500 - 0009FFFF     RAM
1369                  *      000A0000 - 000BFFFF     VGA RAM
1370                  *      000C0000 - 000FFFFF     ROM area
1371                  */
1372                 (void) memlist_remove(&pci_bus_res[bus].mem_avail, 0, 0x100000);
1373                 (void) memlist_remove(&pci_bus_res[bus].pmem_avail,
1374                     0, 0x100000);
1375         }
1376 
1377         memlist_free_all(&isa_res.io_used);
1378         memlist_free_all(&isa_res.mem_used);
1379 
1380         /* add bus-range property for root/peer bus nodes */
1381         for (i = 0; i <= pci_bios_maxbus; i++) {
1382                 /* create bus-range property on root/peer buses */
1383                 if (pci_bus_res[i].par_bus == (uchar_t)-1)
1384                         add_bus_range_prop(i);
1385 
1386                 /* setup bus range resource on each bus */
1387                 setup_bus_res(i);
1388         }
1389 
1390         if (ddi_prop_lookup_string(DDI_DEV_T_ANY, ddi_root_node(),
1391             DDI_PROP_DONTPASS, "pci-reprog", &onoff) == DDI_SUCCESS) {
1392                 if (strcmp(onoff, "off") == 0) {
1393                         pci_reconfig = 0;
1394                         cmn_err(CE_NOTE, "pci device reprogramming disabled");
1395                 }
1396                 ddi_prop_free(onoff);
1397         }
1398 
1399         remove_subtractive_res();
1400 
1401         /* reprogram the non-subtractive PPB */
1402         if (pci_reconfig)
1403                 for (i = 0; i <= pci_bios_maxbus; i++)
1404                         fix_ppb_res(i, B_FALSE);
1405 
1406         for (i = 0; i <= pci_bios_maxbus; i++) {
1407                 /* configure devices not configured by BIOS */
1408                 if (pci_reconfig) {
1409                         /*
1410                          * Reprogram the subtractive PPB. At this time, all its
1411                          * siblings should have got their resources already.
1412                          */
1413                         if (pci_bus_res[i].subtractive)
1414                                 fix_ppb_res(i, B_TRUE);
1415                         enumerate_bus_devs(i, CONFIG_NEW);
1416                 }
1417         }
1418 
1419         /* All dev programmed, so we can create available prop */
1420         for (i = 0; i <= pci_bios_maxbus; i++)
1421                 add_bus_available_prop(i);
1422 }
1423 
1424 /*
1425  * populate bus resources
1426  */
1427 static void
1428 populate_bus_res(uchar_t bus)
1429 {
1430 
1431         /* scan BIOS structures */
1432         pci_bus_res[bus].pmem_avail = find_bus_res(bus, PREFETCH_TYPE);
1433         pci_bus_res[bus].mem_avail = find_bus_res(bus, MEM_TYPE);
1434         pci_bus_res[bus].io_avail = find_bus_res(bus, IO_TYPE);
1435         pci_bus_res[bus].bus_avail = find_bus_res(bus, BUSRANGE_TYPE);
1436 
1437         /*
1438          * attempt to initialize sub_bus from the largest range-end
1439          * in the bus_avail list
1440          */
1441         if (pci_bus_res[bus].bus_avail != NULL) {
1442                 struct memlist *entry;
1443                 int current;
1444 
1445                 entry = pci_bus_res[bus].bus_avail;
1446                 while (entry != NULL) {
1447                         current = entry->ml_address + entry->ml_size - 1;
1448                         if (current > pci_bus_res[bus].sub_bus)
1449                                 pci_bus_res[bus].sub_bus = current;
1450                         entry = entry->ml_next;
1451                 }
1452         }
1453 
1454         if (bus == 0) {
1455                 /*
1456                  * Special treatment of bus 0:
1457                  * If no IO/MEM resource from ACPI/MPSPEC/HRT, copy
1458                  * pcimem from boot and make I/O space the entire range
1459                  * starting at 0x100.
1460                  */
1461                 if (pci_bus_res[0].mem_avail == NULL)
1462                         pci_bus_res[0].mem_avail =
1463                             memlist_dup(bootops->boot_mem->pcimem);
1464                 /* Exclude 0x00 to 0xff of the I/O space, used by all PCs */
1465                 if (pci_bus_res[0].io_avail == NULL)
1466                         memlist_insert(&pci_bus_res[0].io_avail, 0x100, 0xffff);
1467         }
1468 
1469         /*
1470          * Create 'ranges' property here before any resources are
1471          * removed from the resource lists
1472          */
1473         add_ranges_prop(bus, 0);
1474 }
1475 
1476 
1477 /*
1478  * Create top-level bus dips, i.e. /pci@0,0, /pci@1,0...
1479  */
1480 static void
1481 create_root_bus_dip(uchar_t bus)
1482 {
1483         int pci_regs[] = {0, 0, 0};
1484         dev_info_t *dip;
1485 
1486         ASSERT(pci_bus_res[bus].par_bus == (uchar_t)-1);
1487 
1488         num_root_bus++;
1489         ndi_devi_alloc_sleep(ddi_root_node(), "pci",
1490             (pnode_t)DEVI_SID_NODEID, &dip);
1491         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
1492             "#address-cells", 3);
1493         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
1494             "#size-cells", 2);
1495         pci_regs[0] = pci_bus_res[bus].root_addr;
1496         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
1497             "reg", (int *)pci_regs, 3);
1498 
1499         /*
1500          * If system has PCIe bus, then create different properties
1501          */
1502         if (create_pcie_root_bus(bus, dip) == B_FALSE)
1503                 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
1504                     "device_type", "pci");
1505 
1506         (void) ndi_devi_bind_driver(dip, 0);
1507         pci_bus_res[bus].dip = dip;
1508 }
1509 
1510 /*
1511  * For any fixed configuration (often compatability) pci devices
1512  * and those with their own expansion rom, create device nodes
1513  * to hold the already configured device details.
1514  */
1515 void
1516 enumerate_bus_devs(uchar_t bus, int config_op)
1517 {
1518         uchar_t dev, func, nfunc, header;
1519         ushort_t venid;
1520         struct pci_devfunc *devlist = NULL, *entry;
1521 
1522         if (config_op == CONFIG_NEW) {
1523                 dcmn_err(CE_NOTE, "configuring pci bus 0x%x", bus);
1524         } else if (config_op == CONFIG_FIX) {
1525                 dcmn_err(CE_NOTE, "fixing devices on pci bus 0x%x", bus);
1526         } else
1527                 dcmn_err(CE_NOTE, "enumerating pci bus 0x%x", bus);
1528 
1529         if (config_op == CONFIG_NEW) {
1530                 devlist = (struct pci_devfunc *)pci_bus_res[bus].privdata;
1531                 while (devlist) {
1532                         entry = devlist;
1533                         devlist = entry->next;
1534                         if (entry->reprogram ||
1535                             pci_bus_res[bus].io_reprogram ||
1536                             pci_bus_res[bus].mem_reprogram) {
1537                                 /* reprogram device(s) */
1538                                 (void) add_reg_props(entry->dip, bus,
1539                                     entry->dev, entry->func, CONFIG_NEW, 0);
1540                         }
1541                         kmem_free(entry, sizeof (*entry));
1542                 }
1543                 pci_bus_res[bus].privdata = NULL;
1544                 return;
1545         }
1546 
1547         for (dev = 0; dev < max_dev_pci; dev++) {
1548                 nfunc = 1;
1549                 for (func = 0; func < nfunc; func++) {
1550 
1551                         dcmn_err(CE_NOTE, "probing dev 0x%x, func 0x%x",
1552                             dev, func);
1553 
1554                         venid = pci_getw(bus, dev, func, PCI_CONF_VENID);
1555 
1556                         if ((venid == 0xffff) || (venid == 0)) {
1557                                 /* no function at this address */
1558                                 continue;
1559                         }
1560 
1561                         header = pci_getb(bus, dev, func, PCI_CONF_HEADER);
1562                         if (header == 0xff) {
1563                                 continue; /* illegal value */
1564                         }
1565 
1566                         /*
1567                          * according to some mail from Microsoft posted
1568                          * to the pci-drivers alias, their only requirement
1569                          * for a multifunction device is for the 1st
1570                          * function to have to PCI_HEADER_MULTI bit set.
1571                          */
1572                         if ((func == 0) && (header & PCI_HEADER_MULTI)) {
1573                                 nfunc = 8;
1574                         }
1575 
1576                         if (config_op == CONFIG_FIX ||
1577                             config_op == CONFIG_INFO) {
1578                                 /*
1579                                  * Create the node, unconditionally, on the
1580                                  * first pass only.  It may still need
1581                                  * resource assignment, which will be
1582                                  * done on the second, CONFIG_NEW, pass.
1583                                  */
1584                                 process_devfunc(bus, dev, func, header,
1585                                     venid, config_op);
1586 
1587                         }
1588                 }
1589         }
1590 
1591         /* percolate bus used resources up through parents to root */
1592         if (config_op == CONFIG_INFO) {
1593                 int     par_bus;
1594 
1595                 par_bus = pci_bus_res[bus].par_bus;
1596                 while (par_bus != (uchar_t)-1) {
1597                         pci_bus_res[par_bus].io_size +=
1598                             pci_bus_res[bus].io_size;
1599                         pci_bus_res[par_bus].mem_size +=
1600                             pci_bus_res[bus].mem_size;
1601 
1602                         if (pci_bus_res[bus].io_used)
1603                                 memlist_merge(&pci_bus_res[bus].io_used,
1604                                     &pci_bus_res[par_bus].io_used);
1605 
1606                         if (pci_bus_res[bus].mem_used)
1607                                 memlist_merge(&pci_bus_res[bus].mem_used,
1608                                     &pci_bus_res[par_bus].mem_used);
1609 
1610                         if (pci_bus_res[bus].pmem_used)
1611                                 memlist_merge(&pci_bus_res[bus].pmem_used,
1612                                     &pci_bus_res[par_bus].pmem_used);
1613 
1614                         bus = par_bus;
1615                         par_bus = pci_bus_res[par_bus].par_bus;
1616                 }
1617         }
1618 }
1619 
1620 static int
1621 check_pciide_prop(uchar_t revid, ushort_t venid, ushort_t devid,
1622     ushort_t subvenid, ushort_t subdevid)
1623 {
1624         static int prop_exist = -1;
1625         static char *pciide_str;
1626         char compat[32];
1627 
1628         if (prop_exist == -1) {
1629                 prop_exist = (ddi_prop_lookup_string(DDI_DEV_T_ANY,
1630                     ddi_root_node(), DDI_PROP_DONTPASS, "pci-ide",
1631                     &pciide_str) == DDI_SUCCESS);
1632         }
1633 
1634         if (!prop_exist)
1635                 return (0);
1636 
1637         /* compare property value against various forms of compatible */
1638         if (subvenid) {
1639                 (void) snprintf(compat, sizeof (compat), "pci%x,%x.%x.%x.%x",
1640                     venid, devid, subvenid, subdevid, revid);
1641                 if (strcmp(pciide_str, compat) == 0)
1642                         return (1);
1643 
1644                 (void) snprintf(compat, sizeof (compat), "pci%x,%x.%x.%x",
1645                     venid, devid, subvenid, subdevid);
1646                 if (strcmp(pciide_str, compat) == 0)
1647                         return (1);
1648 
1649                 (void) snprintf(compat, sizeof (compat), "pci%x,%x",
1650                     subvenid, subdevid);
1651                 if (strcmp(pciide_str, compat) == 0)
1652                         return (1);
1653         }
1654         (void) snprintf(compat, sizeof (compat), "pci%x,%x.%x",
1655             venid, devid, revid);
1656         if (strcmp(pciide_str, compat) == 0)
1657                 return (1);
1658 
1659         (void) snprintf(compat, sizeof (compat), "pci%x,%x", venid, devid);
1660         if (strcmp(pciide_str, compat) == 0)
1661                 return (1);
1662 
1663         return (0);
1664 }
1665 
1666 static int
1667 is_pciide(uchar_t basecl, uchar_t subcl, uchar_t revid,
1668     ushort_t venid, ushort_t devid, ushort_t subvenid, ushort_t subdevid)
1669 {
1670         struct ide_table {      /* table for PCI_MASS_OTHER */
1671                 ushort_t venid;
1672                 ushort_t devid;
1673         } *entry;
1674 
1675         /* XXX SATA and other devices: need a way to add dynamically */
1676         static struct ide_table ide_other[] = {
1677                 {0x1095, 0x3112},
1678                 {0x1095, 0x3114},
1679                 {0x1095, 0x3512},
1680                 {0x1095, 0x680},        /* Sil0680 */
1681                 {0x1283, 0x8211},       /* ITE 8211F is subcl PCI_MASS_OTHER */
1682                 {0, 0}
1683         };
1684 
1685         if (basecl != PCI_CLASS_MASS)
1686                 return (0);
1687 
1688         if (subcl == PCI_MASS_IDE) {
1689                 return (1);
1690         }
1691 
1692         if (check_pciide_prop(revid, venid, devid, subvenid, subdevid))
1693                 return (1);
1694 
1695         if (subcl != PCI_MASS_OTHER && subcl != PCI_MASS_SATA) {
1696                 return (0);
1697         }
1698 
1699         entry = &ide_other[0];
1700         while (entry->venid) {
1701                 if (entry->venid == venid && entry->devid == devid)
1702                         return (1);
1703                 entry++;
1704         }
1705         return (0);
1706 }
1707 
1708 static int
1709 is_display(uint_t classcode)
1710 {
1711         static uint_t disp_classes[] = {
1712                 0x000100,
1713                 0x030000,
1714                 0x030001
1715         };
1716         int i, nclasses = sizeof (disp_classes) / sizeof (uint_t);
1717 
1718         for (i = 0; i < nclasses; i++) {
1719                 if (classcode == disp_classes[i])
1720                         return (1);
1721         }
1722         return (0);
1723 }
1724 
1725 static void
1726 add_undofix_entry(uint8_t bus, uint8_t dev, uint8_t fn,
1727     void (*undofn)(uint8_t, uint8_t, uint8_t))
1728 {
1729         struct pci_fixundo *newundo;
1730 
1731         newundo = kmem_alloc(sizeof (struct pci_fixundo), KM_SLEEP);
1732 
1733         /*
1734          * Adding an item to this list means that we must turn its NMIENABLE
1735          * bit back on at a later time.
1736          */
1737         newundo->bus = bus;
1738         newundo->dev = dev;
1739         newundo->fn = fn;
1740         newundo->undofn = undofn;
1741         newundo->next = undolist;
1742 
1743         /* add to the undo list in LIFO order */
1744         undolist = newundo;
1745 }
1746 
1747 void
1748 add_pci_fixes(void)
1749 {
1750         int i;
1751 
1752         for (i = 0; i <= pci_bios_maxbus; i++) {
1753                 /*
1754                  * For each bus, apply needed fixes to the appropriate devices.
1755                  * This must be done before the main enumeration loop because
1756                  * some fixes must be applied to devices normally encountered
1757                  * later in the pci scan (e.g. if a fix to device 7 must be
1758                  * applied before scanning device 6, applying fixes in the
1759                  * normal enumeration loop would obviously be too late).
1760                  */
1761                 enumerate_bus_devs(i, CONFIG_FIX);
1762         }
1763 }
1764 
1765 void
1766 undo_pci_fixes(void)
1767 {
1768         struct pci_fixundo *nextundo;
1769         uint8_t bus, dev, fn;
1770 
1771         /*
1772          * All fixes in the undo list are performed unconditionally.  Future
1773          * fixes may require selective undo.
1774          */
1775         while (undolist != NULL) {
1776 
1777                 bus = undolist->bus;
1778                 dev = undolist->dev;
1779                 fn = undolist->fn;
1780 
1781                 (*(undolist->undofn))(bus, dev, fn);
1782 
1783                 nextundo = undolist->next;
1784                 kmem_free(undolist, sizeof (struct pci_fixundo));
1785                 undolist = nextundo;
1786         }
1787 }
1788 
1789 static void
1790 undo_amd8111_pci_fix(uint8_t bus, uint8_t dev, uint8_t fn)
1791 {
1792         uint8_t val8;
1793 
1794         val8 = pci_getb(bus, dev, fn, LPC_IO_CONTROL_REG_1);
1795         /*
1796          * The NMIONERR bit is turned back on to allow the SMM BIOS
1797          * to handle more critical PCI errors (e.g. PERR#).
1798          */
1799         val8 |= AMD8111_ENABLENMI;
1800         pci_putb(bus, dev, fn, LPC_IO_CONTROL_REG_1, val8);
1801 }
1802 
1803 static void
1804 pci_fix_amd8111(uint8_t bus, uint8_t dev, uint8_t fn)
1805 {
1806         uint8_t val8;
1807 
1808         val8 = pci_getb(bus, dev, fn, LPC_IO_CONTROL_REG_1);
1809 
1810         if ((val8 & AMD8111_ENABLENMI) == 0)
1811                 return;
1812 
1813         /*
1814          * We reset NMIONERR in the LPC because master-abort on the PCI
1815          * bridge side of the 8111 will cause NMI, which might cause SMI,
1816          * which sometimes prevents all devices from being enumerated.
1817          */
1818         val8 &= ~AMD8111_ENABLENMI;
1819 
1820         pci_putb(bus, dev, fn, LPC_IO_CONTROL_REG_1, val8);
1821 
1822         add_undofix_entry(bus, dev, fn, undo_amd8111_pci_fix);
1823 }
1824 
1825 static void
1826 set_devpm_d0(uchar_t bus, uchar_t dev, uchar_t func)
1827 {
1828         uint16_t status;
1829         uint8_t header;
1830         uint8_t cap_ptr;
1831         uint8_t cap_id;
1832         uint16_t pmcsr;
1833 
1834         status = pci_getw(bus, dev, func, PCI_CONF_STAT);
1835         if (!(status & PCI_STAT_CAP))
1836                 return; /* No capabilities list */
1837 
1838         header = pci_getb(bus, dev, func, PCI_CONF_HEADER) & PCI_HEADER_TYPE_M;
1839         if (header == PCI_HEADER_CARDBUS)
1840                 cap_ptr = pci_getb(bus, dev, func, PCI_CBUS_CAP_PTR);
1841         else
1842                 cap_ptr = pci_getb(bus, dev, func, PCI_CONF_CAP_PTR);
1843         /*
1844          * Walk the capabilities list searching for a PM entry.
1845          */
1846         while (cap_ptr != PCI_CAP_NEXT_PTR_NULL && cap_ptr >= PCI_CAP_PTR_OFF) {
1847                 cap_ptr &= PCI_CAP_PTR_MASK;
1848                 cap_id = pci_getb(bus, dev, func, cap_ptr + PCI_CAP_ID);
1849                 if (cap_id == PCI_CAP_ID_PM) {
1850                         pmcsr = pci_getw(bus, dev, func, cap_ptr + PCI_PMCSR);
1851                         pmcsr &= ~(PCI_PMCSR_STATE_MASK);
1852                         pmcsr |= PCI_PMCSR_D0; /* D0 state */
1853                         pci_putw(bus, dev, func, cap_ptr + PCI_PMCSR, pmcsr);
1854                         break;
1855                 }
1856                 cap_ptr = pci_getb(bus, dev, func, cap_ptr + PCI_CAP_NEXT_PTR);
1857         }
1858 
1859 }
1860 
1861 #define is_isa(bc, sc)  \
1862         (((bc) == PCI_CLASS_BRIDGE) && ((sc) == PCI_BRIDGE_ISA))
1863 
1864 static void
1865 process_devfunc(uchar_t bus, uchar_t dev, uchar_t func, uchar_t header,
1866     ushort_t vendorid, int config_op)
1867 {
1868         char nodename[32], unitaddr[5];
1869         dev_info_t *dip;
1870         uchar_t basecl, subcl, progcl, intr, revid;
1871         ushort_t subvenid, subdevid, status;
1872         ushort_t slot_num;
1873         uint_t classcode, revclass;
1874         int reprogram = 0, pciide = 0;
1875         int power[2] = {1, 1};
1876         int pciex = 0;
1877         ushort_t is_pci_bridge = 0;
1878         struct pci_devfunc *devlist = NULL, *entry = NULL;
1879         boolean_t slot_valid;
1880         gfx_entry_t *gfxp;
1881         pcie_req_id_t bdf;
1882 
1883         ushort_t deviceid = pci_getw(bus, dev, func, PCI_CONF_DEVID);
1884 
1885         switch (header & PCI_HEADER_TYPE_M) {
1886         case PCI_HEADER_ZERO:
1887                 subvenid = pci_getw(bus, dev, func, PCI_CONF_SUBVENID);
1888                 subdevid = pci_getw(bus, dev, func, PCI_CONF_SUBSYSID);
1889                 break;
1890         case PCI_HEADER_CARDBUS:
1891                 subvenid = pci_getw(bus, dev, func, PCI_CBUS_SUBVENID);
1892                 subdevid = pci_getw(bus, dev, func, PCI_CBUS_SUBSYSID);
1893                 /* Record the # of cardbus bridges found on the bus */
1894                 if (config_op == CONFIG_INFO)
1895                         pci_bus_res[bus].num_cbb++;
1896                 break;
1897         default:
1898                 subvenid = 0;
1899                 subdevid = 0;
1900                 break;
1901         }
1902 
1903         if (config_op == CONFIG_FIX) {
1904                 if (vendorid == VENID_AMD && deviceid == DEVID_AMD8111_LPC) {
1905                         pci_fix_amd8111(bus, dev, func);
1906                 }
1907                 return;
1908         }
1909 
1910         /* XXX should be use generic names? derive from class? */
1911         revclass = pci_getl(bus, dev, func, PCI_CONF_REVID);
1912         classcode = revclass >> 8;
1913         revid = revclass & 0xff;
1914 
1915         /* figure out if this is pci-ide */
1916         basecl = classcode >> 16;
1917         subcl = (classcode >> 8) & 0xff;
1918         progcl = classcode & 0xff;
1919 
1920 
1921         if (is_display(classcode))
1922                 (void) snprintf(nodename, sizeof (nodename), "display");
1923         else if (!pseudo_isa && is_isa(basecl, subcl))
1924                 (void) snprintf(nodename, sizeof (nodename), "isa");
1925         else if (subvenid != 0)
1926                 (void) snprintf(nodename, sizeof (nodename),
1927                     "pci%x,%x", subvenid, subdevid);
1928         else
1929                 (void) snprintf(nodename, sizeof (nodename),
1930                     "pci%x,%x", vendorid, deviceid);
1931 
1932         /* make sure parent bus dip has been created */
1933         if (pci_bus_res[bus].dip == NULL)
1934                 create_root_bus_dip(bus);
1935 
1936         ndi_devi_alloc_sleep(pci_bus_res[bus].dip, nodename,
1937             DEVI_SID_NODEID, &dip);
1938 
1939         if (check_if_device_is_pciex(dip, bus, dev, func, &slot_valid,
1940             &slot_num, &is_pci_bridge) == B_TRUE)
1941                 pciex = 1;
1942 
1943         bdf = PCI_GETBDF(bus, dev, func);
1944         /*
1945          * Record BAD AMD bridges which don't support MMIO config access.
1946          */
1947         if (IS_BAD_AMD_NTBRIDGE(vendorid, deviceid) ||
1948             IS_AMD_8132_CHIP(vendorid, deviceid)) {
1949                 uchar_t secbus = 0;
1950                 uchar_t subbus = 0;
1951 
1952                 if ((basecl == PCI_CLASS_BRIDGE) &&
1953                     (subcl == PCI_BRIDGE_PCI)) {
1954                         secbus = pci_getb(bus, dev, func, PCI_BCNF_SECBUS);
1955                         subbus = pci_getb(bus, dev, func, PCI_BCNF_SUBBUS);
1956                 }
1957                 pci_cfgacc_add_workaround(bdf, secbus, subbus);
1958         }
1959 
1960         /*
1961          * Only populate bus_t if this is a PCIE platform, and
1962          * the device is sitting under a PCIE root complex(RC) .
1963          * Some particular machines have both PCIE RC and PCI
1964          * hostbridge, in which case only devices under PCIE RC
1965          * get their bus_t populated.
1966          */
1967         if ((mcfg_mem_base != NULL) && (pcie_get_rc_dip(dip) != NULL)) {
1968                 ck804_fix_aer_ptr(dip, bdf);
1969                 (void) pcie_init_bus(dip, bdf, PCIE_BUS_INITIAL);
1970         }
1971 
1972         /* add properties */
1973         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "device-id", deviceid);
1974         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "vendor-id", vendorid);
1975         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "revision-id", revid);
1976         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
1977             "class-code", classcode);
1978         if (func == 0)
1979                 (void) snprintf(unitaddr, sizeof (unitaddr), "%x", dev);
1980         else
1981                 (void) snprintf(unitaddr, sizeof (unitaddr),
1982                     "%x,%x", dev, func);
1983         (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
1984             "unit-address", unitaddr);
1985 
1986         /* add device_type for display nodes */
1987         if (is_display(classcode)) {
1988                 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
1989                     "device_type", "display");
1990         }
1991         /* add special stuff for header type */
1992         if ((header & PCI_HEADER_TYPE_M) == PCI_HEADER_ZERO) {
1993                 uchar_t mingrant = pci_getb(bus, dev, func, PCI_CONF_MIN_G);
1994                 uchar_t maxlatency = pci_getb(bus, dev, func, PCI_CONF_MAX_L);
1995 
1996                 if (subvenid != 0) {
1997                         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
1998                             "subsystem-id", subdevid);
1999                         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2000                             "subsystem-vendor-id", subvenid);
2001                 }
2002                 if (!pciex)
2003                         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2004                             "min-grant", mingrant);
2005                 if (!pciex)
2006                         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2007                             "max-latency", maxlatency);
2008         }
2009 
2010         /* interrupt, record if not 0 */
2011         intr = pci_getb(bus, dev, func, PCI_CONF_IPIN);
2012         if (intr != 0)
2013                 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2014                     "interrupts", intr);
2015 
2016         /*
2017          * Add support for 133 mhz pci eventually
2018          */
2019         status = pci_getw(bus, dev, func, PCI_CONF_STAT);
2020 
2021         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2022             "devsel-speed", (status & PCI_STAT_DEVSELT) >> 9);
2023         if (!pciex && (status & PCI_STAT_FBBC))
2024                 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
2025                     "fast-back-to-back");
2026         if (!pciex && (status & PCI_STAT_66MHZ))
2027                 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
2028                     "66mhz-capable");
2029         if (status & PCI_STAT_UDF)
2030                 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
2031                     "udf-supported");
2032         if (pciex && slot_valid) {
2033                 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2034                     "physical-slot#", slot_num);
2035                 if (!is_pci_bridge)
2036                         pciex_slot_names_prop(dip, slot_num);
2037         }
2038 
2039         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
2040             "power-consumption", power, 2);
2041 
2042         /* Set the device PM state to D0 */
2043         set_devpm_d0(bus, dev, func);
2044 
2045         if ((basecl == PCI_CLASS_BRIDGE) && (subcl == PCI_BRIDGE_PCI))
2046                 add_ppb_props(dip, bus, dev, func, pciex, is_pci_bridge);
2047         else {
2048                 /*
2049                  * Record the non-PPB devices on the bus for possible
2050                  * reprogramming at 2nd bus enumeration.
2051                  * Note: PPB reprogramming is done in fix_ppb_res()
2052                  */
2053                 devlist = (struct pci_devfunc *)pci_bus_res[bus].privdata;
2054                 entry = kmem_zalloc(sizeof (*entry), KM_SLEEP);
2055                 entry->dip = dip;
2056                 entry->dev = dev;
2057                 entry->func = func;
2058                 entry->next = devlist;
2059                 pci_bus_res[bus].privdata = entry;
2060         }
2061 
2062         if (IS_CLASS_IOAPIC(basecl, subcl, progcl)) {
2063                 create_ioapic_node(bus, dev, func, vendorid, deviceid);
2064         }
2065 
2066         /* check for NVIDIA CK8-04/MCP55 based LPC bridge */
2067         if (NVIDIA_IS_LPC_BRIDGE(vendorid, deviceid) && (dev == 1) &&
2068             (func == 0)) {
2069                 add_nvidia_isa_bridge_props(dip, bus, dev, func);
2070                 /* each LPC bridge has an integrated IOAPIC */
2071                 apic_nvidia_io_max++;
2072         }
2073 
2074         if (pciex && is_pci_bridge)
2075                 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "model",
2076                     (char *)"PCIe-PCI bridge");
2077         else
2078                 add_model_prop(dip, classcode);
2079 
2080         add_compatible(dip, subvenid, subdevid, vendorid, deviceid,
2081             revid, classcode, pciex);
2082 
2083         /*
2084          * See if this device is a controller that advertises
2085          * itself to be a standard ATA task file controller, or one that
2086          * has been hard coded.
2087          *
2088          * If it is, check if any other higher precedence driver listed in
2089          * driver_aliases will claim the node by calling
2090          * ddi_compatibile_driver_major.  If so, clear pciide and do not
2091          * create a pci-ide node or any other special handling.
2092          *
2093          * If another driver does not bind, set the node name to pci-ide
2094          * and then let the special pci-ide handling for registers and
2095          * child pci-ide nodes proceed below.
2096          */
2097         if (is_pciide(basecl, subcl, revid, vendorid, deviceid,
2098             subvenid, subdevid) == 1) {
2099                 if (ddi_compatible_driver_major(dip, NULL) == (major_t)-1) {
2100                         (void) ndi_devi_set_nodename(dip, "pci-ide", 0);
2101                         pciide = 1;
2102                 }
2103         }
2104 
2105         DEVI_SET_PCI(dip);
2106         reprogram = add_reg_props(dip, bus, dev, func, config_op, pciide);
2107         (void) ndi_devi_bind_driver(dip, 0);
2108 
2109         /* special handling for pci-ide */
2110         if (pciide) {
2111                 dev_info_t *cdip;
2112 
2113                 /*
2114                  * Create properties specified by P1275 Working Group
2115                  * Proposal #414 Version 1
2116                  */
2117                 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
2118                     "device_type", "pci-ide");
2119                 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2120                     "#address-cells", 1);
2121                 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2122                     "#size-cells", 0);
2123 
2124                 /* allocate two child nodes */
2125                 ndi_devi_alloc_sleep(dip, "ide",
2126                     (pnode_t)DEVI_SID_NODEID, &cdip);
2127                 (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
2128                     "reg", 0);
2129                 (void) ndi_devi_bind_driver(cdip, 0);
2130                 ndi_devi_alloc_sleep(dip, "ide",
2131                     (pnode_t)DEVI_SID_NODEID, &cdip);
2132                 (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
2133                     "reg", 1);
2134                 (void) ndi_devi_bind_driver(cdip, 0);
2135 
2136                 reprogram = 0;  /* don't reprogram pci-ide bridge */
2137         }
2138 
2139         if (is_display(classcode)) {
2140                 gfxp = kmem_zalloc(sizeof (*gfxp), KM_SLEEP);
2141                 gfxp->g_dip = dip;
2142                 gfxp->g_prev = NULL;
2143                 gfxp->g_next = gfx_devinfo_list;
2144                 gfx_devinfo_list = gfxp;
2145                 if (gfxp->g_next)
2146                         gfxp->g_next->g_prev = gfxp;
2147         }
2148 
2149         /* special handling for isa */
2150         if (!pseudo_isa && is_isa(basecl, subcl)) {
2151                 /* add device_type */
2152                 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
2153                     "device_type", "isa");
2154         }
2155 
2156         if (reprogram && (entry != NULL))
2157                 entry->reprogram = B_TRUE;
2158 
2159 }
2160 
2161 /*
2162  * Some vendors do not use unique subsystem IDs in their products, which
2163  * makes the use of form 2 compatible names (pciSSSS,ssss) inappropriate.
2164  * Allow for these compatible forms to be excluded on a per-device basis.
2165  */
2166 /*ARGSUSED*/
2167 static boolean_t
2168 subsys_compat_exclude(ushort_t venid, ushort_t devid, ushort_t subvenid,
2169     ushort_t subdevid, uchar_t revid, uint_t classcode)
2170 {
2171         /* Nvidia display adapters */
2172         if ((venid == 0x10de) && (is_display(classcode)))
2173                 return (B_TRUE);
2174 
2175         return (B_FALSE);
2176 }
2177 
2178 /*
2179  * Set the compatible property to a value compliant with
2180  * rev 2.1 of the IEEE1275 PCI binding.
2181  * (Also used for PCI-Express devices).
2182  *
2183  *   pciVVVV,DDDD.SSSS.ssss.RR  (0)
2184  *   pciVVVV,DDDD.SSSS.ssss     (1)
2185  *   pciSSSS,ssss               (2)
2186  *   pciVVVV,DDDD.RR            (3)
2187  *   pciVVVV,DDDD               (4)
2188  *   pciclass,CCSSPP            (5)
2189  *   pciclass,CCSS              (6)
2190  *
2191  * The Subsystem (SSSS) forms are not inserted if
2192  * subsystem-vendor-id is 0.
2193  *
2194  * NOTE: For PCI-Express devices "pci" is replaced with "pciex" in 0-6 above
2195  * property 2 is not created as per "1275 bindings for PCI Express Interconnect"
2196  *
2197  * Set with setprop and \x00 between each
2198  * to generate the encoded string array form.
2199  */
2200 void
2201 add_compatible(dev_info_t *dip, ushort_t subvenid, ushort_t subdevid,
2202     ushort_t vendorid, ushort_t deviceid, uchar_t revid, uint_t classcode,
2203     int pciex)
2204 {
2205         int i = 0;
2206         int size = COMPAT_BUFSIZE;
2207         char *compat[13];
2208         char *buf, *curr;
2209 
2210         curr = buf = kmem_alloc(size, KM_SLEEP);
2211 
2212         if (pciex) {
2213                 if (subvenid) {
2214                         compat[i++] = curr;     /* form 0 */
2215                         (void) snprintf(curr, size, "pciex%x,%x.%x.%x.%x",
2216                             vendorid, deviceid, subvenid, subdevid, revid);
2217                         size -= strlen(curr) + 1;
2218                         curr += strlen(curr) + 1;
2219 
2220                         compat[i++] = curr;     /* form 1 */
2221                         (void) snprintf(curr, size, "pciex%x,%x.%x.%x",
2222                             vendorid, deviceid, subvenid, subdevid);
2223                         size -= strlen(curr) + 1;
2224                         curr += strlen(curr) + 1;
2225 
2226                 }
2227                 compat[i++] = curr;     /* form 3 */
2228                 (void) snprintf(curr, size, "pciex%x,%x.%x",
2229                     vendorid, deviceid, revid);
2230                 size -= strlen(curr) + 1;
2231                 curr += strlen(curr) + 1;
2232 
2233                 compat[i++] = curr;     /* form 4 */
2234                 (void) snprintf(curr, size, "pciex%x,%x", vendorid, deviceid);
2235                 size -= strlen(curr) + 1;
2236                 curr += strlen(curr) + 1;
2237 
2238                 compat[i++] = curr;     /* form 5 */
2239                 (void) snprintf(curr, size, "pciexclass,%06x", classcode);
2240                 size -= strlen(curr) + 1;
2241                 curr += strlen(curr) + 1;
2242 
2243                 compat[i++] = curr;     /* form 6 */
2244                 (void) snprintf(curr, size, "pciexclass,%04x",
2245                     (classcode >> 8));
2246                 size -= strlen(curr) + 1;
2247                 curr += strlen(curr) + 1;
2248         }
2249 
2250         if (subvenid) {
2251                 compat[i++] = curr;     /* form 0 */
2252                 (void) snprintf(curr, size, "pci%x,%x.%x.%x.%x",
2253                     vendorid, deviceid, subvenid, subdevid, revid);
2254                 size -= strlen(curr) + 1;
2255                 curr += strlen(curr) + 1;
2256 
2257                 compat[i++] = curr;     /* form 1 */
2258                 (void) snprintf(curr, size, "pci%x,%x.%x.%x",
2259                     vendorid, deviceid, subvenid, subdevid);
2260                 size -= strlen(curr) + 1;
2261                 curr += strlen(curr) + 1;
2262 
2263                 if (subsys_compat_exclude(vendorid, deviceid, subvenid,
2264                     subdevid, revid, classcode) == B_FALSE) {
2265                         compat[i++] = curr;     /* form 2 */
2266                         (void) snprintf(curr, size, "pci%x,%x", subvenid,
2267                             subdevid);
2268                         size -= strlen(curr) + 1;
2269                         curr += strlen(curr) + 1;
2270                 }
2271         }
2272         compat[i++] = curr;     /* form 3 */
2273         (void) snprintf(curr, size, "pci%x,%x.%x", vendorid, deviceid, revid);
2274         size -= strlen(curr) + 1;
2275         curr += strlen(curr) + 1;
2276 
2277         compat[i++] = curr;     /* form 4 */
2278         (void) snprintf(curr, size, "pci%x,%x", vendorid, deviceid);
2279         size -= strlen(curr) + 1;
2280         curr += strlen(curr) + 1;
2281 
2282         compat[i++] = curr;     /* form 5 */
2283         (void) snprintf(curr, size, "pciclass,%06x", classcode);
2284         size -= strlen(curr) + 1;
2285         curr += strlen(curr) + 1;
2286 
2287         compat[i++] = curr;     /* form 6 */
2288         (void) snprintf(curr, size, "pciclass,%04x", (classcode >> 8));
2289         size -= strlen(curr) + 1;
2290         curr += strlen(curr) + 1;
2291 
2292         (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, dip,
2293             "compatible", compat, i);
2294         kmem_free(buf, COMPAT_BUFSIZE);
2295 }
2296 
2297 /*
2298  * Adjust the reg properties for a dual channel PCI-IDE device.
2299  *
2300  * NOTE: don't do anything that changes the order of the hard-decodes
2301  * and programmed BARs. The kernel driver depends on these values
2302  * being in this order regardless of whether they're for a 'native'
2303  * mode BAR or not.
2304  */
2305 /*
2306  * config info for pci-ide devices
2307  */
2308 static struct {
2309         uchar_t  native_mask;   /* 0 == 'compatibility' mode, 1 == native */
2310         uchar_t  bar_offset;    /* offset for alt status register */
2311         ushort_t addr;          /* compatibility mode base address */
2312         ushort_t length;        /* number of ports for this BAR */
2313 } pciide_bar[] = {
2314         { 0x01, 0, 0x1f0, 8 },  /* primary lower BAR */
2315         { 0x01, 2, 0x3f6, 1 },  /* primary upper BAR */
2316         { 0x04, 0, 0x170, 8 },  /* secondary lower BAR */
2317         { 0x04, 2, 0x376, 1 }   /* secondary upper BAR */
2318 };
2319 
2320 static int
2321 pciIdeAdjustBAR(uchar_t progcl, int index, uint_t *basep, uint_t *lenp)
2322 {
2323         int hard_decode = 0;
2324 
2325         /*
2326          * Adjust the base and len for the BARs of the PCI-IDE
2327          * device's primary and secondary controllers. The first
2328          * two BARs are for the primary controller and the next
2329          * two BARs are for the secondary controller. The fifth
2330          * and sixth bars are never adjusted.
2331          */
2332         if (index >= 0 && index <= 3) {
2333                 *lenp = pciide_bar[index].length;
2334 
2335                 if (progcl & pciide_bar[index].native_mask) {
2336                         *basep += pciide_bar[index].bar_offset;
2337                 } else {
2338                         *basep = pciide_bar[index].addr;
2339                         hard_decode = 1;
2340                 }
2341         }
2342 
2343         /*
2344          * if either base or len is zero make certain both are zero
2345          */
2346         if (*basep == 0 || *lenp == 0) {
2347                 *basep = 0;
2348                 *lenp = 0;
2349                 hard_decode = 0;
2350         }
2351 
2352         return (hard_decode);
2353 }
2354 
2355 
2356 /*
2357  * Add the "reg" and "assigned-addresses" property
2358  */
2359 static int
2360 add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
2361     int config_op, int pciide)
2362 {
2363         uchar_t baseclass, subclass, progclass, header;
2364         ushort_t bar_sz;
2365         uint_t value = 0, len, devloc;
2366         uint_t base, base_hi, type;
2367         ushort_t offset, end;
2368         int max_basereg, j, reprogram = 0;
2369         uint_t phys_hi;
2370         struct memlist **io_avail, **io_used;
2371         struct memlist **mem_avail, **mem_used;
2372         struct memlist **pmem_avail, **pmem_used;
2373         uchar_t res_bus;
2374 
2375         pci_regspec_t regs[16] = {{0}};
2376         pci_regspec_t assigned[15] = {{0}};
2377         int nreg, nasgn;
2378 
2379         io_avail = &pci_bus_res[bus].io_avail;
2380         io_used = &pci_bus_res[bus].io_used;
2381         mem_avail = &pci_bus_res[bus].mem_avail;
2382         mem_used = &pci_bus_res[bus].mem_used;
2383         pmem_avail = &pci_bus_res[bus].pmem_avail;
2384         pmem_used = &pci_bus_res[bus].pmem_used;
2385 
2386         devloc = (uint_t)bus << 16 | (uint_t)dev << 11 | (uint_t)func << 8;
2387         regs[0].pci_phys_hi = devloc;
2388         nreg = 1;       /* rest of regs[0] is all zero */
2389         nasgn = 0;
2390 
2391         baseclass = pci_getb(bus, dev, func, PCI_CONF_BASCLASS);
2392         subclass = pci_getb(bus, dev, func, PCI_CONF_SUBCLASS);
2393         progclass = pci_getb(bus, dev, func, PCI_CONF_PROGCLASS);
2394         header = pci_getb(bus, dev, func, PCI_CONF_HEADER) & PCI_HEADER_TYPE_M;
2395 
2396         switch (header) {
2397         case PCI_HEADER_ZERO:
2398                 max_basereg = PCI_BASE_NUM;
2399                 break;
2400         case PCI_HEADER_PPB:
2401                 max_basereg = PCI_BCNF_BASE_NUM;
2402                 break;
2403         case PCI_HEADER_CARDBUS:
2404                 max_basereg = PCI_CBUS_BASE_NUM;
2405                 reprogram = 1;
2406                 break;
2407         default:
2408                 max_basereg = 0;
2409                 break;
2410         }
2411 
2412         /*
2413          * Create the register property by saving the current
2414          * value of the base register. Write 0xffffffff to the
2415          * base register.  Read the value back to determine the
2416          * required size of the address space.  Restore the base
2417          * register contents.
2418          *
2419          * Do not disable I/O and memory access for bridges; this
2420          * has the side-effect of making the bridge transparent to
2421          * secondary-bus activity (see sections 4.1-4.3 of the
2422          * PCI-PCI Bridge Spec V1.2).  For non-bridges, disable
2423          * I/O and memory access to avoid difficulty with USB
2424          * emulation (see OHCI spec1.0a appendix B
2425          * "Host Controller Mapping")
2426          */
2427         end = PCI_CONF_BASE0 + max_basereg * sizeof (uint_t);
2428         for (j = 0, offset = PCI_CONF_BASE0; offset < end;
2429             j++, offset += bar_sz) {
2430                 uint_t  command;
2431 
2432                 /* determine the size of the address space */
2433                 base = pci_getl(bus, dev, func, offset);
2434                 if (baseclass != PCI_CLASS_BRIDGE) {
2435                         command = (uint_t)pci_getw(bus, dev, func,
2436                             PCI_CONF_COMM);
2437                         pci_putw(bus, dev, func, PCI_CONF_COMM,
2438                             command & ~(PCI_COMM_MAE | PCI_COMM_IO));
2439                 }
2440                 pci_putl(bus, dev, func, offset, 0xffffffff);
2441                 value = pci_getl(bus, dev, func, offset);
2442                 pci_putl(bus, dev, func, offset, base);
2443                 if (baseclass != PCI_CLASS_BRIDGE)
2444                         pci_putw(bus, dev, func, PCI_CONF_COMM, command);
2445 
2446                 /* construct phys hi,med.lo, size hi, lo */
2447                 if ((pciide && j < 4) || (base & PCI_BASE_SPACE_IO)) {
2448                         int hard_decode = 0;
2449 
2450                         /* i/o space */
2451                         bar_sz = PCI_BAR_SZ_32;
2452                         value &= PCI_BASE_IO_ADDR_M;
2453                         len = ((value ^ (value-1)) + 1) >> 1;
2454 
2455                         /* XXX Adjust first 4 IDE registers */
2456                         if (pciide) {
2457                                 if (subclass != PCI_MASS_IDE)
2458                                         progclass = (PCI_IDE_IF_NATIVE_PRI |
2459                                             PCI_IDE_IF_NATIVE_SEC);
2460                                 hard_decode = pciIdeAdjustBAR(progclass, j,
2461                                     &base, &len);
2462                         } else if (value == 0) {
2463                                 /* skip base regs with size of 0 */
2464                                 continue;
2465                         }
2466 
2467                         regs[nreg].pci_phys_hi = PCI_ADDR_IO | devloc |
2468                             (hard_decode ? PCI_RELOCAT_B : offset);
2469                         regs[nreg].pci_phys_low = hard_decode ?
2470                             base & PCI_BASE_IO_ADDR_M : 0;
2471                         assigned[nasgn].pci_phys_hi =
2472                             PCI_RELOCAT_B | regs[nreg].pci_phys_hi;
2473                         regs[nreg].pci_size_low =
2474                             assigned[nasgn].pci_size_low = len;
2475                         type = base & (~PCI_BASE_IO_ADDR_M);
2476                         base &= PCI_BASE_IO_ADDR_M;
2477                         /*
2478                          * A device under a subtractive PPB can allocate
2479                          * resources from its parent bus if there is no resource
2480                          * available on its own bus.
2481                          */
2482                         if ((config_op == CONFIG_NEW) && (*io_avail == NULL)) {
2483                                 res_bus = bus;
2484                                 while (pci_bus_res[res_bus].subtractive) {
2485                                         res_bus = pci_bus_res[res_bus].par_bus;
2486                                         if (res_bus == (uchar_t)-1)
2487                                                 break; /* root bus already */
2488                                         if (pci_bus_res[res_bus].io_avail) {
2489                                                 io_avail = &pci_bus_res
2490                                                     [res_bus].io_avail;
2491                                                 break;
2492                                         }
2493                                 }
2494                         }
2495 
2496                         /*
2497                          * first pass - gather what's there
2498                          * update/second pass - adjust/allocate regions
2499                          *      config - allocate regions
2500                          */
2501                         if (config_op == CONFIG_INFO) { /* first pass */
2502                                 /* take out of the resource map of the bus */
2503                                 if (base != 0) {
2504                                         (void) memlist_remove(io_avail, base,
2505                                             len);
2506                                         memlist_insert(io_used, base, len);
2507                                 } else {
2508                                         reprogram = 1;
2509                                 }
2510                                 pci_bus_res[bus].io_size += len;
2511                         } else if ((*io_avail && base == 0) ||
2512                             pci_bus_res[bus].io_reprogram) {
2513                                 base = (uint_t)memlist_find(io_avail, len, len);
2514                                 if (base != 0) {
2515                                         memlist_insert(io_used, base, len);
2516                                         /* XXX need to worry about 64-bit? */
2517                                         pci_putl(bus, dev, func, offset,
2518                                             base | type);
2519                                         base = pci_getl(bus, dev, func, offset);
2520                                         base &= PCI_BASE_IO_ADDR_M;
2521                                 }
2522                                 if (base == 0) {
2523                                         cmn_err(CE_WARN, "failed to program"
2524                                             " IO space [%d/%d/%d] BAR@0x%x"
2525                                             " length 0x%x",
2526                                             bus, dev, func, offset, len);
2527                                 }
2528                         }
2529                         assigned[nasgn].pci_phys_low = base;
2530                         nreg++, nasgn++;
2531 
2532                 } else {
2533                         /* memory space */
2534                         if ((base & PCI_BASE_TYPE_M) == PCI_BASE_TYPE_ALL) {
2535                                 bar_sz = PCI_BAR_SZ_64;
2536                                 base_hi = pci_getl(bus, dev, func, offset + 4);
2537                                 phys_hi = PCI_ADDR_MEM64;
2538                         } else {
2539                                 bar_sz = PCI_BAR_SZ_32;
2540                                 base_hi = 0;
2541                                 phys_hi = PCI_ADDR_MEM32;
2542                         }
2543 
2544                         /* skip base regs with size of 0 */
2545                         value &= PCI_BASE_M_ADDR_M;
2546 
2547                         if (value == 0)
2548                                 continue;
2549 
2550                         len = ((value ^ (value-1)) + 1) >> 1;
2551                         regs[nreg].pci_size_low =
2552                             assigned[nasgn].pci_size_low = len;
2553 
2554                         phys_hi |= (devloc | offset);
2555                         if (base & PCI_BASE_PREF_M)
2556                                 phys_hi |= PCI_PREFETCH_B;
2557 
2558                         /*
2559                          * A device under a subtractive PPB can allocate
2560                          * resources from its parent bus if there is no resource
2561                          * available on its own bus.
2562                          */
2563                         if ((config_op == CONFIG_NEW) && (*mem_avail == NULL)) {
2564                                 res_bus = bus;
2565                                 while (pci_bus_res[res_bus].subtractive) {
2566                                         res_bus = pci_bus_res[res_bus].par_bus;
2567                                         if (res_bus == (uchar_t)-1)
2568                                                 break; /* root bus already */
2569                                         mem_avail =
2570                                             &pci_bus_res[res_bus].mem_avail;
2571                                         pmem_avail =
2572                                             &pci_bus_res [res_bus].pmem_avail;
2573                                         /*
2574                                          * Break out as long as at least
2575                                          * mem_avail is available
2576                                          */
2577                                         if ((*pmem_avail &&
2578                                             (phys_hi & PCI_PREFETCH_B)) ||
2579                                             *mem_avail)
2580                                                 break;
2581                                 }
2582                         }
2583 
2584                         regs[nreg].pci_phys_hi =
2585                             assigned[nasgn].pci_phys_hi = phys_hi;
2586                         assigned[nasgn].pci_phys_hi |= PCI_RELOCAT_B;
2587                         assigned[nasgn].pci_phys_mid = base_hi;
2588                         type = base & ~PCI_BASE_M_ADDR_M;
2589                         base &= PCI_BASE_M_ADDR_M;
2590 
2591                         if (config_op == CONFIG_INFO) {
2592                                 /* take out of the resource map of the bus */
2593                                 if (base != NULL) {
2594                                         /* remove from PMEM and MEM space */
2595                                         (void) memlist_remove(mem_avail,
2596                                             base, len);
2597                                         (void) memlist_remove(pmem_avail,
2598                                             base, len);
2599                                         /* only note as used in correct map */
2600                                         if (phys_hi & PCI_PREFETCH_B)
2601                                                 memlist_insert(pmem_used,
2602                                                     base, len);
2603                                         else
2604                                                 memlist_insert(mem_used,
2605                                                     base, len);
2606                                 } else {
2607                                         reprogram = 1;
2608                                 }
2609                                 pci_bus_res[bus].mem_size += len;
2610                         } else if ((*mem_avail && base == NULL) ||
2611                             pci_bus_res[bus].mem_reprogram) {
2612                                 /*
2613                                  * When desired, attempt a prefetchable
2614                                  * allocation first
2615                                  */
2616                                 if (phys_hi & PCI_PREFETCH_B) {
2617                                         base = (uint_t)memlist_find(pmem_avail,
2618                                             len, len);
2619                                         if (base != NULL) {
2620                                                 memlist_insert(pmem_used,
2621                                                     base, len);
2622                                                 (void) memlist_remove(mem_avail,
2623                                                     base, len);
2624                                         }
2625                                 }
2626                                 /*
2627                                  * If prefetchable allocation was not
2628                                  * desired, or failed, attempt ordinary
2629                                  * memory allocation
2630                                  */
2631                                 if (base == NULL) {
2632                                         base = (uint_t)memlist_find(mem_avail,
2633                                             len, len);
2634                                         if (base != NULL) {
2635                                                 memlist_insert(mem_used,
2636                                                     base, len);
2637                                                 (void) memlist_remove(
2638                                                     pmem_avail, base, len);
2639                                         }
2640                                 }
2641                                 if (base != NULL) {
2642                                         pci_putl(bus, dev, func, offset,
2643                                             base | type);
2644                                         base = pci_getl(bus, dev, func, offset);
2645                                         base &= PCI_BASE_M_ADDR_M;
2646                                 } else
2647                                         cmn_err(CE_WARN, "failed to program "
2648                                             "mem space [%d/%d/%d] BAR@0x%x"
2649                                             " length 0x%x",
2650                                             bus, dev, func, offset, len);
2651                         }
2652                         assigned[nasgn].pci_phys_low = base;
2653                         nreg++, nasgn++;
2654                 }
2655         }
2656         switch (header) {
2657         case PCI_HEADER_ZERO:
2658                 offset = PCI_CONF_ROM;
2659                 break;
2660         case PCI_HEADER_PPB:
2661                 offset = PCI_BCNF_ROM;
2662                 break;
2663         default: /* including PCI_HEADER_CARDBUS */
2664                 goto done;
2665         }
2666 
2667         /*
2668          * Add the expansion rom memory space
2669          * Determine the size of the ROM base reg; don't write reserved bits
2670          * ROM isn't in the PCI memory space.
2671          */
2672         base = pci_getl(bus, dev, func, offset);
2673         pci_putl(bus, dev, func, offset, PCI_BASE_ROM_ADDR_M);
2674         value = pci_getl(bus, dev, func, offset);
2675         pci_putl(bus, dev, func, offset, base);
2676         if (value & PCI_BASE_ROM_ENABLE)
2677                 value &= PCI_BASE_ROM_ADDR_M;
2678         else
2679                 value = 0;
2680 
2681         if (value != 0) {
2682                 regs[nreg].pci_phys_hi = (PCI_ADDR_MEM32 | devloc) + offset;
2683                 assigned[nasgn].pci_phys_hi = (PCI_RELOCAT_B |
2684                     PCI_ADDR_MEM32 | devloc) + offset;
2685                 base &= PCI_BASE_ROM_ADDR_M;
2686                 assigned[nasgn].pci_phys_low = base;
2687                 len = ((value ^ (value-1)) + 1) >> 1;
2688                 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = len;
2689                 nreg++, nasgn++;
2690                 /* take it out of the memory resource */
2691                 if (base != NULL) {
2692                         (void) memlist_remove(mem_avail, base, len);
2693                         memlist_insert(mem_used, base, len);
2694                         pci_bus_res[bus].mem_size += len;
2695                 }
2696         }
2697 
2698         /*
2699          * Account for "legacy" (alias) video adapter resources
2700          */
2701 
2702         /* add the three hard-decode, aliased address spaces for VGA */
2703         if ((baseclass == PCI_CLASS_DISPLAY && subclass == PCI_DISPLAY_VGA) ||
2704             (baseclass == PCI_CLASS_NONE && subclass == PCI_NONE_VGA)) {
2705 
2706                 /* VGA hard decode 0x3b0-0x3bb */
2707                 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi =
2708                     (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc);
2709                 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x3b0;
2710                 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0xc;
2711                 nreg++, nasgn++;
2712                 (void) memlist_remove(io_avail, 0x3b0, 0xc);
2713                 memlist_insert(io_used, 0x3b0, 0xc);
2714                 pci_bus_res[bus].io_size += 0xc;
2715 
2716                 /* VGA hard decode 0x3c0-0x3df */
2717                 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi =
2718                     (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc);
2719                 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x3c0;
2720                 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0x20;
2721                 nreg++, nasgn++;
2722                 (void) memlist_remove(io_avail, 0x3c0, 0x20);
2723                 memlist_insert(io_used, 0x3c0, 0x20);
2724                 pci_bus_res[bus].io_size += 0x20;
2725 
2726                 /* Video memory */
2727                 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi =
2728                     (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_MEM32 | devloc);
2729                 regs[nreg].pci_phys_low =
2730                     assigned[nasgn].pci_phys_low = 0xa0000;
2731                 regs[nreg].pci_size_low =
2732                     assigned[nasgn].pci_size_low = 0x20000;
2733                 nreg++, nasgn++;
2734                 /* remove from MEM and PMEM space */
2735                 (void) memlist_remove(mem_avail, 0xa0000, 0x20000);
2736                 (void) memlist_remove(pmem_avail, 0xa0000, 0x20000);
2737                 memlist_insert(mem_used, 0xa0000, 0x20000);
2738                 pci_bus_res[bus].mem_size += 0x20000;
2739         }
2740 
2741         /* add the hard-decode, aliased address spaces for 8514 */
2742         if ((baseclass == PCI_CLASS_DISPLAY) &&
2743             (subclass == PCI_DISPLAY_VGA) &&
2744             (progclass & PCI_DISPLAY_IF_8514)) {
2745 
2746                 /* hard decode 0x2e8 */
2747                 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi =
2748                     (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc);
2749                 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x2e8;
2750                 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0x1;
2751                 nreg++, nasgn++;
2752                 (void) memlist_remove(io_avail, 0x2e8, 0x1);
2753                 memlist_insert(io_used, 0x2e8, 0x1);
2754                 pci_bus_res[bus].io_size += 0x1;
2755 
2756                 /* hard decode 0x2ea-0x2ef */
2757                 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi =
2758                     (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc);
2759                 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x2ea;
2760                 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0x6;
2761                 nreg++, nasgn++;
2762                 (void) memlist_remove(io_avail, 0x2ea, 0x6);
2763                 memlist_insert(io_used, 0x2ea, 0x6);
2764                 pci_bus_res[bus].io_size += 0x6;
2765         }
2766 
2767 done:
2768         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "reg",
2769             (int *)regs, nreg * sizeof (pci_regspec_t) / sizeof (int));
2770         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
2771             "assigned-addresses",
2772             (int *)assigned, nasgn * sizeof (pci_regspec_t) / sizeof (int));
2773 
2774         return (reprogram);
2775 }
2776 
2777 static void
2778 add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
2779     int pciex, ushort_t is_pci_bridge)
2780 {
2781         char *dev_type;
2782         int i;
2783         uint_t val, io_range[2], mem_range[2], pmem_range[2];
2784         uchar_t secbus = pci_getb(bus, dev, func, PCI_BCNF_SECBUS);
2785         uchar_t subbus = pci_getb(bus, dev, func, PCI_BCNF_SUBBUS);
2786         uchar_t progclass;
2787 
2788         ASSERT(secbus <= subbus);
2789 
2790         /*
2791          * Check if it's a subtractive PPB.
2792          */
2793         progclass = pci_getb(bus, dev, func, PCI_CONF_PROGCLASS);
2794         if (progclass == PCI_BRIDGE_PCI_IF_SUBDECODE)
2795                 pci_bus_res[secbus].subtractive = B_TRUE;
2796 
2797         /*
2798          * Some BIOSes lie about max pci busses, we allow for
2799          * such mistakes here
2800          */
2801         if (subbus > pci_bios_maxbus) {
2802                 pci_bios_maxbus = subbus;
2803                 alloc_res_array();
2804         }
2805 
2806         ASSERT(pci_bus_res[secbus].dip == NULL);
2807         pci_bus_res[secbus].dip = dip;
2808         pci_bus_res[secbus].par_bus = bus;
2809 
2810         dev_type = (pciex && !is_pci_bridge) ? "pciex" : "pci";
2811 
2812         /* setup bus number hierarchy */
2813         pci_bus_res[secbus].sub_bus = subbus;
2814         /*
2815          * Keep track of the largest subordinate bus number (this is essential
2816          * for peer busses because there is no other way of determining its
2817          * subordinate bus number).
2818          */
2819         if (subbus > pci_bus_res[bus].sub_bus)
2820                 pci_bus_res[bus].sub_bus = subbus;
2821         /*
2822          * Loop through subordinate busses, initializing their parent bus
2823          * field to this bridge's parent.  The subordinate busses' parent
2824          * fields may very well be further refined later, as child bridges
2825          * are enumerated.  (The value is to note that the subordinate busses
2826          * are not peer busses by changing their par_bus fields to anything
2827          * other than -1.)
2828          */
2829         for (i = secbus + 1; i <= subbus; i++)
2830                 pci_bus_res[i].par_bus = bus;
2831 
2832         (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
2833             "device_type", dev_type);
2834         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2835             "#address-cells", 3);
2836         (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2837             "#size-cells", 2);
2838 
2839         /*
2840          * Collect bridge window specifications, and use them to populate
2841          * the "avail" resources for the bus.  Not all of those resources will
2842          * end up being available; this is done top-down, and so the initial
2843          * collection of windows populates the 'ranges' property for the
2844          * bus node.  Later, as children are found, resources are removed from
2845          * the 'avail' list, so that it becomes the freelist for
2846          * this point in the tree.  ranges may be set again after bridge
2847          * reprogramming in fix_ppb_res(), in which case it's set from
2848          * used + avail.
2849          *
2850          * According to PPB spec, the base register should be programmed
2851          * with a value bigger than the limit register when there are
2852          * no resources available. This applies to io, memory, and
2853          * prefetchable memory.
2854          */
2855 
2856         /*
2857          * io range
2858          * We determine i/o windows that are left unconfigured by BIOS
2859          * through its i/o enable bit as Microsoft recommends OEMs to do.
2860          * If it is unset, we disable i/o and mark it for reconfiguration in
2861          * later passes by setting the base > limit
2862          */
2863         val = (uint_t)pci_getw(bus, dev, func, PCI_CONF_COMM);
2864         if (val & PCI_COMM_IO) {
2865                 val = (uint_t)pci_getb(bus, dev, func, PCI_BCNF_IO_BASE_LOW);
2866                 io_range[0] = ((val & 0xf0) << 8);
2867                 val = (uint_t)pci_getb(bus, dev, func, PCI_BCNF_IO_LIMIT_LOW);
2868                 io_range[1]  = ((val & 0xf0) << 8) | 0xFFF;
2869         } else {
2870                 io_range[0] = 0x9fff;
2871                 io_range[1] = 0x1000;
2872                 pci_putb(bus, dev, func, PCI_BCNF_IO_BASE_LOW,
2873                     (uint8_t)((io_range[0] >> 8) & 0xf0));
2874                 pci_putb(bus, dev, func, PCI_BCNF_IO_LIMIT_LOW,
2875                     (uint8_t)((io_range[1] >> 8) & 0xf0));
2876                 pci_putw(bus, dev, func, PCI_BCNF_IO_BASE_HI, 0);
2877                 pci_putw(bus, dev, func, PCI_BCNF_IO_LIMIT_HI, 0);
2878         }
2879 
2880         if (io_range[0] != 0 && io_range[0] < io_range[1]) {
2881                 memlist_insert(&pci_bus_res[secbus].io_avail,
2882                     (uint64_t)io_range[0],
2883                     (uint64_t)(io_range[1] - io_range[0] + 1));
2884                 memlist_insert(&pci_bus_res[bus].io_used,
2885                     (uint64_t)io_range[0],
2886                     (uint64_t)(io_range[1] - io_range[0] + 1));
2887                 if (pci_bus_res[bus].io_avail != NULL) {
2888                         (void) memlist_remove(&pci_bus_res[bus].io_avail,
2889                             (uint64_t)io_range[0],
2890                             (uint64_t)(io_range[1] - io_range[0] + 1));
2891                 }
2892                 dcmn_err(CE_NOTE, "bus %d io-range: 0x%x-%x",
2893                     secbus, io_range[0], io_range[1]);
2894                 /* if 32-bit supported, make sure upper bits are not set */
2895                 if ((val & 0xf) == 1 &&
2896                     pci_getw(bus, dev, func, PCI_BCNF_IO_BASE_HI)) {
2897                         cmn_err(CE_NOTE, "unsupported 32-bit IO address on"
2898                             " pci-pci bridge [%d/%d/%d]", bus, dev, func);
2899                 }
2900         }
2901 
2902         /* mem range */
2903         val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_MEM_BASE);
2904         mem_range[0] = ((val & 0xFFF0) << 16);
2905         val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_MEM_LIMIT);
2906         mem_range[1] = ((val & 0xFFF0) << 16) | 0xFFFFF;
2907         if (mem_range[0] != 0 && mem_range[0] < mem_range[1]) {
2908                 memlist_insert(&pci_bus_res[secbus].mem_avail,
2909                     (uint64_t)mem_range[0],
2910                     (uint64_t)(mem_range[1] - mem_range[0] + 1));
2911                 memlist_insert(&pci_bus_res[bus].mem_used,
2912                     (uint64_t)mem_range[0],
2913                     (uint64_t)(mem_range[1] - mem_range[0] + 1));
2914                 /* remove from parent resource list */
2915                 (void) memlist_remove(&pci_bus_res[bus].mem_avail,
2916                     (uint64_t)mem_range[0],
2917                     (uint64_t)(mem_range[1] - mem_range[0] + 1));
2918                 (void) memlist_remove(&pci_bus_res[bus].pmem_avail,
2919                     (uint64_t)mem_range[0],
2920                     (uint64_t)(mem_range[1] - mem_range[0] + 1));
2921                 dcmn_err(CE_NOTE, "bus %d mem-range: 0x%x-%x",
2922                     secbus, mem_range[0], mem_range[1]);
2923         }
2924 
2925         /* prefetchable memory range */
2926         val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_BASE_LOW);
2927         pmem_range[0] = ((val & 0xFFF0) << 16);
2928         val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_LIMIT_LOW);
2929         pmem_range[1] = ((val & 0xFFF0) << 16) | 0xFFFFF;
2930         if (pmem_range[0] != 0 && pmem_range[0] < pmem_range[1]) {
2931                 memlist_insert(&pci_bus_res[secbus].pmem_avail,
2932                     (uint64_t)pmem_range[0],
2933                     (uint64_t)(pmem_range[1] - pmem_range[0] + 1));
2934                 memlist_insert(&pci_bus_res[bus].pmem_used,
2935                     (uint64_t)pmem_range[0],
2936                     (uint64_t)(pmem_range[1] - pmem_range[0] + 1));
2937                 /* remove from parent resource list */
2938                 (void) memlist_remove(&pci_bus_res[bus].pmem_avail,
2939                     (uint64_t)pmem_range[0],
2940                     (uint64_t)(pmem_range[1] - pmem_range[0] + 1));
2941                 (void) memlist_remove(&pci_bus_res[bus].mem_avail,
2942                     (uint64_t)pmem_range[0],
2943                     (uint64_t)(pmem_range[1] - pmem_range[0] + 1));
2944                 dcmn_err(CE_NOTE, "bus %d pmem-range: 0x%x-%x",
2945                     secbus, pmem_range[0], pmem_range[1]);
2946                 /* if 64-bit supported, make sure upper bits are not set */
2947                 if ((val & 0xf) == 1 &&
2948                     pci_getl(bus, dev, func, PCI_BCNF_PF_BASE_HIGH)) {
2949                         cmn_err(CE_NOTE, "unsupported 64-bit prefetch memory on"
2950                             " pci-pci bridge [%d/%d/%d]", bus, dev, func);
2951                 }
2952         }
2953 
2954         /*
2955          * Add VGA legacy resources to the bridge's pci_bus_res if it
2956          * has VGA_ENABLE set.  Note that we put them in 'avail',
2957          * because that's used to populate the ranges prop; they'll be
2958          * removed from there by the VGA device once it's found.  Also,
2959          * remove them from the parent's available list and note them as
2960          * used in the parent.
2961          */
2962 
2963         if (pci_getw(bus, dev, func, PCI_BCNF_BCNTRL) &
2964             PCI_BCNF_BCNTRL_VGA_ENABLE) {
2965 
2966                 memlist_insert(&pci_bus_res[secbus].io_avail, 0x3b0, 0xc);
2967 
2968                 memlist_insert(&pci_bus_res[bus].io_used, 0x3b0, 0xc);
2969                 if (pci_bus_res[bus].io_avail != NULL) {
2970                         (void) memlist_remove(&pci_bus_res[bus].io_avail,
2971                             0x3b0, 0xc);
2972                 }
2973 
2974                 memlist_insert(&pci_bus_res[secbus].io_avail, 0x3c0, 0x20);
2975 
2976                 memlist_insert(&pci_bus_res[bus].io_used, 0x3c0, 0x20);
2977                 if (pci_bus_res[bus].io_avail != NULL) {
2978                         (void) memlist_remove(&pci_bus_res[bus].io_avail,
2979                             0x3c0, 0x20);
2980                 }
2981 
2982                 memlist_insert(&pci_bus_res[secbus].mem_avail, 0xa0000,
2983                     0x20000);
2984 
2985                 memlist_insert(&pci_bus_res[bus].mem_used, 0xa0000, 0x20000);
2986                 if (pci_bus_res[bus].mem_avail != NULL) {
2987                         (void) memlist_remove(&pci_bus_res[bus].mem_avail,
2988                             0xa0000, 0x20000);
2989                 }
2990         }
2991         add_bus_range_prop(secbus);
2992         add_ranges_prop(secbus, 1);
2993 }
2994 
2995 extern const struct pci_class_strings_s class_pci[];
2996 extern int class_pci_items;
2997 
2998 static void
2999 add_model_prop(dev_info_t *dip, uint_t classcode)
3000 {
3001         const char *desc;
3002         int i;
3003         uchar_t baseclass = classcode >> 16;
3004         uchar_t subclass = (classcode >> 8) & 0xff;
3005         uchar_t progclass = classcode & 0xff;
3006 
3007         if ((baseclass == PCI_CLASS_MASS) && (subclass == PCI_MASS_IDE)) {
3008                 desc = "IDE controller";
3009         } else {
3010                 for (desc = 0, i = 0; i < class_pci_items; i++) {
3011                         if ((baseclass == class_pci[i].base_class) &&
3012                             (subclass == class_pci[i].sub_class) &&
3013                             (progclass == class_pci[i].prog_class)) {
3014                                 desc = class_pci[i].actual_desc;
3015                                 break;
3016                         }
3017                 }
3018                 if (i == class_pci_items)
3019                         desc = "Unknown class of pci/pnpbios device";
3020         }
3021 
3022         (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "model",
3023             (char *)desc);
3024 }
3025 
3026 static void
3027 add_bus_range_prop(int bus)
3028 {
3029         int bus_range[2];
3030 
3031         if (pci_bus_res[bus].dip == NULL)
3032                 return;
3033         bus_range[0] = bus;
3034         bus_range[1] = pci_bus_res[bus].sub_bus;
3035         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, pci_bus_res[bus].dip,
3036             "bus-range", (int *)bus_range, 2);
3037 }
3038 
3039 /*
3040  * Add slot-names property for any named pci hot-plug slots
3041  */
3042 static void
3043 add_bus_slot_names_prop(int bus)
3044 {
3045         char slotprop[256];
3046         int len;
3047         extern int pci_irq_nroutes;
3048         char *slotcap_name;
3049 
3050         /*
3051          * If no irq routing table, then go with the slot-names as set up
3052          * in pciex_slot_names_prop() from slot capability register (if any).
3053          */
3054         if (pci_irq_nroutes == 0)
3055                 return;
3056 
3057         /*
3058          * Otherise delete the slot-names we already have and use the irq
3059          * routing table values as returned by pci_slot_names_prop() instead,
3060          * but keep any property of value "pcie0" as that can't be represented
3061          * in the irq routing table.
3062          */
3063         if (pci_bus_res[bus].dip != NULL) {
3064                 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pci_bus_res[bus].dip,
3065                     DDI_PROP_DONTPASS, "slot-names", &slotcap_name) !=
3066                     DDI_SUCCESS || strcmp(slotcap_name, "pcie0") != 0)
3067                         (void) ndi_prop_remove(DDI_DEV_T_NONE,
3068                             pci_bus_res[bus].dip, "slot-names");
3069         }
3070 
3071         len = pci_slot_names_prop(bus, slotprop, sizeof (slotprop));
3072         if (len > 0) {
3073                 /*
3074                  * Only create a peer bus node if this bus may be a peer bus.
3075                  * It may be a peer bus if the dip is NULL and if par_bus is
3076                  * -1 (par_bus is -1 if this bus was not found to be
3077                  * subordinate to any PCI-PCI bridge).
3078                  * If it's not a peer bus, then the ACPI BBN-handling code
3079                  * will remove it later.
3080                  */
3081                 if (pci_bus_res[bus].par_bus == (uchar_t)-1 &&
3082                     pci_bus_res[bus].dip == NULL) {
3083 
3084                         create_root_bus_dip(bus);
3085                 }
3086                 if (pci_bus_res[bus].dip != NULL) {
3087                         ASSERT((len % sizeof (int)) == 0);
3088                         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
3089                             pci_bus_res[bus].dip, "slot-names",
3090                             (int *)slotprop, len / sizeof (int));
3091                 } else {
3092                         cmn_err(CE_NOTE, "!BIOS BUG: Invalid bus number in PCI "
3093                             "IRQ routing table; Not adding slot-names "
3094                             "property for incorrect bus %d", bus);
3095                 }
3096         }
3097 }
3098 
3099 /*
3100  * Handle both PCI root and PCI-PCI bridge range properties;
3101  * non-zero 'ppb' argument select PCI-PCI bridges versus root.
3102  */
3103 static void
3104 memlist_to_ranges(void **rp, struct memlist *entry, int type, int ppb)
3105 {
3106         ppb_ranges_t *ppb_rp = *rp;
3107         pci_ranges_t *pci_rp = *rp;
3108 
3109         while (entry != NULL) {
3110                 if (ppb) {
3111                         ppb_rp->child_high = ppb_rp->parent_high = type;
3112                         ppb_rp->child_mid = ppb_rp->parent_mid =
3113                             (uint32_t)(entry->ml_address >> 32); /* XXX */
3114                         ppb_rp->child_low = ppb_rp->parent_low =
3115                             (uint32_t)entry->ml_address;
3116                         ppb_rp->size_high =
3117                             (uint32_t)(entry->ml_size >> 32); /* XXX */
3118                         ppb_rp->size_low = (uint32_t)entry->ml_size;
3119                         *rp = ++ppb_rp;
3120                 } else {
3121                         pci_rp->child_high = type;
3122                         pci_rp->child_mid = pci_rp->parent_high =
3123                             (uint32_t)(entry->ml_address >> 32); /* XXX */
3124                         pci_rp->child_low = pci_rp->parent_low =
3125                             (uint32_t)entry->ml_address;
3126                         pci_rp->size_high =
3127                             (uint32_t)(entry->ml_size >> 32); /* XXX */
3128                         pci_rp->size_low = (uint32_t)entry->ml_size;
3129                         *rp = ++pci_rp;
3130                 }
3131                 entry = entry->ml_next;
3132         }
3133 }
3134 
3135 static void
3136 add_ranges_prop(int bus, int ppb)
3137 {
3138         int total, alloc_size;
3139         void    *rp, *next_rp;
3140         struct memlist *iolist, *memlist, *pmemlist;
3141 
3142         /* no devinfo node - unused bus, return */
3143         if (pci_bus_res[bus].dip == NULL)
3144                 return;
3145 
3146         iolist = memlist = pmemlist = (struct memlist *)NULL;
3147 
3148         memlist_merge(&pci_bus_res[bus].io_avail, &iolist);
3149         memlist_merge(&pci_bus_res[bus].io_used, &iolist);
3150         memlist_merge(&pci_bus_res[bus].mem_avail, &memlist);
3151         memlist_merge(&pci_bus_res[bus].mem_used, &memlist);
3152         memlist_merge(&pci_bus_res[bus].pmem_avail, &pmemlist);
3153         memlist_merge(&pci_bus_res[bus].pmem_used, &pmemlist);
3154 
3155         total = memlist_count(iolist);
3156         total += memlist_count(memlist);
3157         total += memlist_count(pmemlist);
3158 
3159         /* no property is created if no ranges are present */
3160         if (total == 0)
3161                 return;
3162 
3163         alloc_size = total *
3164             (ppb ? sizeof (ppb_ranges_t) : sizeof (pci_ranges_t));
3165 
3166         next_rp = rp = kmem_alloc(alloc_size, KM_SLEEP);
3167 
3168         memlist_to_ranges(&next_rp, iolist, PCI_ADDR_IO | PCI_REG_REL_M, ppb);
3169         memlist_to_ranges(&next_rp, memlist,
3170             PCI_ADDR_MEM32 | PCI_REG_REL_M, ppb);
3171         memlist_to_ranges(&next_rp, pmemlist,
3172             PCI_ADDR_MEM32 | PCI_REG_REL_M | PCI_REG_PF_M, ppb);
3173 
3174         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, pci_bus_res[bus].dip,
3175             "ranges", (int *)rp, alloc_size / sizeof (int));
3176 
3177         kmem_free(rp, alloc_size);
3178         memlist_free_all(&iolist);
3179         memlist_free_all(&memlist);
3180         memlist_free_all(&pmemlist);
3181 }
3182 
3183 static void
3184 memlist_remove_list(struct memlist **list, struct memlist *remove_list)
3185 {
3186         while (list && *list && remove_list) {
3187                 (void) memlist_remove(list, remove_list->ml_address,
3188                     remove_list->ml_size);
3189                 remove_list = remove_list->ml_next;
3190         }
3191 }
3192 
3193 static int
3194 memlist_to_spec(struct pci_phys_spec *sp, struct memlist *list, int type)
3195 {
3196         int i = 0;
3197 
3198         while (list) {
3199                 /* assume 32-bit addresses */
3200                 sp->pci_phys_hi = type;
3201                 sp->pci_phys_mid = 0;
3202                 sp->pci_phys_low = (uint32_t)list->ml_address;
3203                 sp->pci_size_hi = 0;
3204                 sp->pci_size_low = (uint32_t)list->ml_size;
3205 
3206                 list = list->ml_next;
3207                 sp++, i++;
3208         }
3209         return (i);
3210 }
3211 
3212 static void
3213 add_bus_available_prop(int bus)
3214 {
3215         int i, count;
3216         struct pci_phys_spec *sp;
3217 
3218         /* no devinfo node - unused bus, return */
3219         if (pci_bus_res[bus].dip == NULL)
3220                 return;
3221 
3222         count = memlist_count(pci_bus_res[bus].io_avail) +
3223             memlist_count(pci_bus_res[bus].mem_avail) +
3224             memlist_count(pci_bus_res[bus].pmem_avail);
3225 
3226         if (count == 0)         /* nothing available */
3227                 return;
3228 
3229         sp = kmem_alloc(count * sizeof (*sp), KM_SLEEP);
3230         i = memlist_to_spec(&sp[0], pci_bus_res[bus].io_avail,
3231             PCI_ADDR_IO | PCI_REG_REL_M);
3232         i += memlist_to_spec(&sp[i], pci_bus_res[bus].mem_avail,
3233             PCI_ADDR_MEM32 | PCI_REG_REL_M);
3234         i += memlist_to_spec(&sp[i], pci_bus_res[bus].pmem_avail,
3235             PCI_ADDR_MEM32 | PCI_REG_REL_M | PCI_REG_PF_M);
3236         ASSERT(i == count);
3237 
3238         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, pci_bus_res[bus].dip,
3239             "available", (int *)sp,
3240             i * sizeof (struct pci_phys_spec) / sizeof (int));
3241         kmem_free(sp, count * sizeof (*sp));
3242 }
3243 
3244 static void
3245 alloc_res_array(void)
3246 {
3247         static int array_size = 0;
3248         int old_size;
3249         void *old_res;
3250 
3251         if (array_size > pci_bios_maxbus + 1)
3252                 return; /* array is big enough */
3253 
3254         old_size = array_size;
3255         old_res = pci_bus_res;
3256 
3257         if (array_size == 0)
3258                 array_size = 16;        /* start with a reasonable number */
3259 
3260         while (array_size <= pci_bios_maxbus + 1)
3261                 array_size <<= 1;
3262         pci_bus_res = (struct pci_bus_resource *)kmem_zalloc(
3263             array_size * sizeof (struct pci_bus_resource), KM_SLEEP);
3264 
3265         if (old_res) {  /* copy content and free old array */
3266                 bcopy(old_res, pci_bus_res,
3267                     old_size * sizeof (struct pci_bus_resource));
3268                 kmem_free(old_res, old_size * sizeof (struct pci_bus_resource));
3269         }
3270 }
3271 
3272 static void
3273 create_ioapic_node(int bus, int dev, int fn, ushort_t vendorid,
3274     ushort_t deviceid)
3275 {
3276         static dev_info_t *ioapicsnode = NULL;
3277         static int numioapics = 0;
3278         dev_info_t *ioapic_node;
3279         uint64_t physaddr;
3280         uint32_t lobase, hibase = 0;
3281 
3282         /* BAR 0 contains the IOAPIC's memory-mapped I/O address */
3283         lobase = (*pci_getl_func)(bus, dev, fn, PCI_CONF_BASE0);
3284 
3285         /* We (and the rest of the world) only support memory-mapped IOAPICs */
3286         if ((lobase & PCI_BASE_SPACE_M) != PCI_BASE_SPACE_MEM)
3287                 return;
3288 
3289         if ((lobase & PCI_BASE_TYPE_M) == PCI_BASE_TYPE_ALL)
3290                 hibase = (*pci_getl_func)(bus, dev, fn, PCI_CONF_BASE0 + 4);
3291 
3292         lobase &= PCI_BASE_M_ADDR_M;
3293 
3294         physaddr = (((uint64_t)hibase) << 32) | lobase;
3295 
3296         /*
3297          * Create a nexus node for all IOAPICs under the root node.
3298          */
3299         if (ioapicsnode == NULL) {
3300                 if (ndi_devi_alloc(ddi_root_node(), IOAPICS_NODE_NAME,
3301                     (pnode_t)DEVI_SID_NODEID, &ioapicsnode) != NDI_SUCCESS) {
3302                         return;
3303                 }
3304                 (void) ndi_devi_online(ioapicsnode, 0);
3305         }
3306 
3307         /*
3308          * Create a child node for this IOAPIC
3309          */
3310         ioapic_node = ddi_add_child(ioapicsnode, IOAPICS_CHILD_NAME,
3311             DEVI_SID_NODEID, numioapics++);
3312         if (ioapic_node == NULL) {
3313                 return;
3314         }
3315 
3316         /* Vendor and Device ID */
3317         (void) ndi_prop_update_int(DDI_DEV_T_NONE, ioapic_node,
3318             IOAPICS_PROP_VENID, vendorid);
3319         (void) ndi_prop_update_int(DDI_DEV_T_NONE, ioapic_node,
3320             IOAPICS_PROP_DEVID, deviceid);
3321 
3322         /* device_type */
3323         (void) ndi_prop_update_string(DDI_DEV_T_NONE, ioapic_node,
3324             "device_type", IOAPICS_DEV_TYPE);
3325 
3326         /* reg */
3327         (void) ndi_prop_update_int64(DDI_DEV_T_NONE, ioapic_node,
3328             "reg", physaddr);
3329 }
3330 
3331 /*
3332  * NOTE: For PCIe slots, the name is generated from the slot number
3333  * information obtained from Slot Capabilities register.
3334  * For non-PCIe slots, it is generated based on the slot number
3335  * information in the PCI IRQ table.
3336  */
3337 static void
3338 pciex_slot_names_prop(dev_info_t *dip, ushort_t slot_num)
3339 {
3340         char slotprop[256];
3341         int len;
3342 
3343         bzero(slotprop, sizeof (slotprop));
3344 
3345         /* set mask to 1 as there is only one slot (i.e dev 0) */
3346         *(uint32_t *)slotprop = 1;
3347         len = 4;
3348         (void) snprintf(slotprop + len, sizeof (slotprop) - len, "pcie%d",
3349             slot_num);
3350         len += strlen(slotprop + len) + 1;
3351         len += len % 4;
3352         (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "slot-names",
3353             (int *)slotprop, len / sizeof (int));
3354 }
3355 
3356 /*
3357  * This is currently a hack, a better way is needed to determine if it
3358  * is a PCIE platform.
3359  */
3360 static boolean_t
3361 is_pcie_platform()
3362 {
3363         uint8_t bus;
3364 
3365         for (bus = 0; bus < pci_bios_maxbus; bus++) {
3366                 if (look_for_any_pciex_device(bus))
3367                         return (B_TRUE);
3368         }
3369         return (B_FALSE);
3370 }
3371 
3372 /*
3373  * Enable reporting of AER capability next pointer.
3374  * This needs to be done only for CK8-04 devices
3375  * by setting NV_XVR_VEND_CYA1 (offset 0xf40) bit 13
3376  * NOTE: BIOS is disabling this, it needs to be enabled temporarily
3377  *
3378  * This function is adapted from npe_ck804_fix_aer_ptr(), and is
3379  * called from pci_boot.c.
3380  */
3381 static void
3382 ck804_fix_aer_ptr(dev_info_t *dip, pcie_req_id_t bdf)
3383 {
3384         dev_info_t *rcdip;
3385         ushort_t cya1;
3386 
3387         rcdip = pcie_get_rc_dip(dip);
3388         ASSERT(rcdip != NULL);
3389 
3390         if ((pci_cfgacc_get16(rcdip, bdf, PCI_CONF_VENID) ==
3391             NVIDIA_VENDOR_ID) &&
3392             (pci_cfgacc_get16(rcdip, bdf, PCI_CONF_DEVID) ==
3393             NVIDIA_CK804_DEVICE_ID) &&
3394             (pci_cfgacc_get8(rcdip, bdf, PCI_CONF_REVID) >=
3395             NVIDIA_CK804_AER_VALID_REVID)) {
3396                 cya1 = pci_cfgacc_get16(rcdip, bdf, NVIDIA_CK804_VEND_CYA1_OFF);
3397                 if (!(cya1 & ~NVIDIA_CK804_VEND_CYA1_ERPT_MASK))
3398                         (void) pci_cfgacc_put16(rcdip, bdf,
3399                             NVIDIA_CK804_VEND_CYA1_OFF,
3400                             cya1 | NVIDIA_CK804_VEND_CYA1_ERPT_VAL);
3401         }
3402 }
--- EOF ---