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