8702 PCI addresses with physaddr > 0xffffffff can't be mapped in
[unleashed.git] / usr / src / uts / intel / io / pci / pci_boot.c
blob35d5013072949ae1f529c054905740c02202e569
1 /*
2 * CDDL HEADER START
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.
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.
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]
19 * CDDL HEADER END
22 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2016 Joyent, Inc.
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <sys/sysmacros.h>
29 #include <sys/sunndi.h>
30 #include <sys/pci.h>
31 #include <sys/pci_impl.h>
32 #include <sys/pcie_impl.h>
33 #include <sys/memlist.h>
34 #include <sys/bootconf.h>
35 #include <io/pci/mps_table.h>
36 #include <sys/pci_cfgacc.h>
37 #include <sys/pci_cfgspace.h>
38 #include <sys/pci_cfgspace_impl.h>
39 #include <sys/psw.h>
40 #include "../../../../common/pci/pci_strings.h"
41 #include <sys/apic.h>
42 #include <io/pciex/pcie_nvidia.h>
43 #include <sys/hotplug/pci/pciehpc_acpi.h>
44 #include <sys/acpi/acpi.h>
45 #include <sys/acpica.h>
46 #include <sys/iommulib.h>
47 #include <sys/devcache.h>
48 #include <sys/pci_cfgacc_x86.h>
50 #define pci_getb (*pci_getb_func)
51 #define pci_getw (*pci_getw_func)
52 #define pci_getl (*pci_getl_func)
53 #define pci_putb (*pci_putb_func)
54 #define pci_putw (*pci_putw_func)
55 #define pci_putl (*pci_putl_func)
56 #define dcmn_err if (pci_boot_debug) cmn_err
58 #define CONFIG_INFO 0
59 #define CONFIG_UPDATE 1
60 #define CONFIG_NEW 2
61 #define CONFIG_FIX 3
62 #define COMPAT_BUFSIZE 512
64 #define PPB_IO_ALIGNMENT 0x1000 /* 4K aligned */
65 #define PPB_MEM_ALIGNMENT 0x100000 /* 1M aligned */
66 /* round down to nearest power of two */
67 #define P2LE(align) \
68 { \
69 int i = 0; \
70 while (align >>= 1) \
71 i ++; \
72 align = 1 << i; \
73 } \
75 /* for is_vga and list_is_vga_only */
77 enum io_mem {
78 IO,
79 MEM
82 /* See AMD-8111 Datasheet Rev 3.03, Page 149: */
83 #define LPC_IO_CONTROL_REG_1 0x40
84 #define AMD8111_ENABLENMI (uint8_t)0x80
85 #define DEVID_AMD8111_LPC 0x7468
87 struct pci_fixundo {
88 uint8_t bus;
89 uint8_t dev;
90 uint8_t fn;
91 void (*undofn)(uint8_t, uint8_t, uint8_t);
92 struct pci_fixundo *next;
95 struct pci_devfunc {
96 struct pci_devfunc *next;
97 dev_info_t *dip;
98 uchar_t dev;
99 uchar_t func;
100 boolean_t reprogram; /* this device needs to be reprogrammed */
103 extern int apic_nvidia_io_max;
104 extern int pseudo_isa;
105 extern int pci_bios_maxbus;
106 static uchar_t max_dev_pci = 32; /* PCI standard */
107 int pci_boot_debug = 0;
108 extern struct memlist *find_bus_res(int, int);
109 static struct pci_fixundo *undolist = NULL;
110 static int num_root_bus = 0; /* count of root buses */
111 extern volatile int acpi_resource_discovery;
112 extern uint64_t mcfg_mem_base;
113 extern void pci_cfgacc_add_workaround(uint16_t, uchar_t, uchar_t);
114 extern dev_info_t *pcie_get_rc_dip(dev_info_t *);
117 * Module prototypes
119 static void enumerate_bus_devs(uchar_t bus, int config_op);
120 static void create_root_bus_dip(uchar_t bus);
121 static void process_devfunc(uchar_t, uchar_t, uchar_t, uchar_t,
122 ushort_t, int);
123 static void add_compatible(dev_info_t *, ushort_t, ushort_t,
124 ushort_t, ushort_t, uchar_t, uint_t, int);
125 static int add_reg_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int, int);
126 static void add_ppb_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int,
127 ushort_t);
128 static void add_model_prop(dev_info_t *, uint_t);
129 static void add_bus_range_prop(int);
130 static void add_bus_slot_names_prop(int);
131 static void add_ranges_prop(int, int);
132 static void add_bus_available_prop(int);
133 static int get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id);
134 static void fix_ppb_res(uchar_t, boolean_t);
135 static void alloc_res_array();
136 static void create_ioapic_node(int bus, int dev, int fn, ushort_t vendorid,
137 ushort_t deviceid);
138 static void pciex_slot_names_prop(dev_info_t *, ushort_t);
139 static void populate_bus_res(uchar_t bus);
140 static void memlist_remove_list(struct memlist **list,
141 struct memlist *remove_list);
142 static void ck804_fix_aer_ptr(dev_info_t *, pcie_req_id_t);
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);
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);
153 extern int pci_slot_names_prop(int, char *, int);
155 /* set non-zero to force PCI peer-bus renumbering */
156 int pci_bus_always_renumber = 0;
159 * used to register ISA resource usage which must not be made
160 * "available" from other PCI node' resource maps
162 static struct {
163 struct memlist *io_used;
164 struct memlist *mem_used;
165 } isa_res;
168 * PCI unit-address cache management
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 */
178 typedef struct {
179 list_node_t pua_nodes;
180 int pua_index;
181 int pua_addr;
182 } pua_node_t;
184 nvf_handle_t puafd_handle;
185 int pua_cache_valid = 0;
188 /*ARGSUSED*/
189 static ACPI_STATUS
190 pci_process_acpi_device(ACPI_HANDLE hdl, UINT32 level, void *ctx, void **rv)
192 ACPI_BUFFER rb;
193 ACPI_OBJECT ro;
194 ACPI_DEVICE_INFO *adi;
195 int busnum;
198 * Use AcpiGetObjectInfo() to find the device _HID
199 * If not a PCI root-bus, ignore this device and continue
200 * the walk
202 if (ACPI_FAILURE(AcpiGetObjectInfo(hdl, &adi)))
203 return (AE_OK);
205 if (!(adi->Valid & ACPI_VALID_HID)) {
206 AcpiOsFree(adi);
207 return (AE_OK);
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);
218 AcpiOsFree(adi);
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
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;
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.
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);
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);
252 /* PCI and no _BBN, continue walk */
253 return (AE_OK);
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.
264 static void
265 pci_scan_bbn()
267 void *rv;
269 (void) AcpiGetDevices(NULL, pci_process_acpi_device, NULL, &rv);
272 static void
273 pci_unitaddr_cache_init(void)
276 puafd_handle = nvf_register_file(&pci_unitaddr_cache_ops);
277 ASSERT(puafd_handle);
279 list_create(nvf_list(puafd_handle), sizeof (pua_node_t),
280 offsetof(pua_node_t, pua_nodes));
282 rw_enter(nvf_lock(puafd_handle), RW_WRITER);
283 (void) nvf_read_file(puafd_handle);
284 rw_exit(nvf_lock(puafd_handle));
288 * Format of /etc/devices/pci_unitaddr_persistent:
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.
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.
300 /*ARGSUSED*/
301 static int
302 pci_cache_unpack_nvlist(nvf_handle_t hdl, nvlist_t *nvl, char *name)
304 long index;
305 int32_t value;
306 nvpair_t *np;
307 pua_node_t *node;
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;
315 if (nvpair_value_int32(np, &value) != 0)
316 continue;
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);
324 pua_cache_valid = 1;
325 return (DDI_SUCCESS);
328 static int
329 pci_cache_pack_nvlist(nvf_handle_t hdl, nvlist_t **ret_nvl)
331 int rval;
332 nvlist_t *nvl, *sub_nvl;
333 list_t *listp;
334 pua_node_t *pua;
335 char buf[13];
337 ASSERT(RW_WRITE_HELD(nvf_lock(hdl)));
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);
346 sub_nvl = NULL;
347 rval = nvlist_alloc(&sub_nvl, NV_UNIQUE_NAME, KM_SLEEP);
348 if (rval != DDI_SUCCESS)
349 goto error;
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;
360 rval = nvlist_add_nvlist(nvl, "table", sub_nvl);
361 if (rval != DDI_SUCCESS)
362 goto error;
363 nvlist_free(sub_nvl);
365 *ret_nvl = nvl;
366 return (DDI_SUCCESS);
368 error:
369 nvlist_free(sub_nvl);
370 ASSERT(nvl);
371 nvlist_free(nvl);
372 *ret_nvl = NULL;
373 return (DDI_FAILURE);
376 static void
377 pci_cache_free_list(nvf_handle_t hdl)
379 list_t *listp;
380 pua_node_t *pua;
382 ASSERT(RW_WRITE_HELD(nvf_lock(hdl)));
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));
393 static int
394 pci_unitaddr_cache_valid(void)
397 /* read only, no need for rw lock */
398 return (pua_cache_valid);
402 static int
403 pci_bus_unitaddr(int index)
405 pua_node_t *pua;
406 list_t *listp;
407 int addr;
409 rw_enter(nvf_lock(puafd_handle), RW_READER);
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;
421 rw_exit(nvf_lock(puafd_handle));
422 return (addr);
425 static void
426 pci_unitaddr_cache_create(void)
428 int i, index;
429 pua_node_t *node;
430 list_t *listp;
432 rw_enter(nvf_lock(puafd_handle), RW_WRITER);
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);
447 (void) nvf_mark_dirty(puafd_handle);
448 rw_exit(nvf_lock(puafd_handle));
449 nvf_wake_daemon();
454 * Enumerate all PCI devices
456 void
457 pci_setup_tree(void)
459 uint_t i, root_bus_addr = 0;
461 alloc_res_array();
462 for (i = 0; i <= pci_bios_maxbus; i++) {
463 pci_bus_res[i].par_bus = (uchar_t)-1;
464 pci_bus_res[i].root_addr = (uchar_t)-1;
465 pci_bus_res[i].sub_bus = i;
468 pci_bus_res[0].root_addr = root_bus_addr++;
469 create_root_bus_dip(0);
470 enumerate_bus_devs(0, CONFIG_INFO);
473 * Now enumerate peer busses
475 * We loop till pci_bios_maxbus. On most systems, there is
476 * one more bus at the high end, which implements the ISA
477 * compatibility bus. We don't care about that.
479 * Note: In the old (bootconf) enumeration, the peer bus
480 * address did not use the bus number, and there were
481 * too many peer busses created. The root_bus_addr is
482 * used to maintain the old peer bus address assignment.
483 * However, we stop enumerating phantom peers with no
484 * device below.
486 for (i = 1; i <= pci_bios_maxbus; i++) {
487 if (pci_bus_res[i].dip == NULL) {
488 pci_bus_res[i].root_addr = root_bus_addr++;
490 enumerate_bus_devs(i, CONFIG_INFO);
492 /* add slot-names property for named pci hot-plug slots */
493 add_bus_slot_names_prop(i);
498 * >0 = present, 0 = not present, <0 = error
500 static int
501 pci_bbn_present(int bus)
503 ACPI_HANDLE hdl;
504 int rv;
506 /* no dip means no _BBN */
507 if (pci_bus_res[bus].dip == NULL)
508 return (0);
510 rv = -1; /* default return value in case of error below */
511 if (ACPI_SUCCESS(acpica_get_handle(pci_bus_res[bus].dip, &hdl))) {
512 switch (AcpiEvaluateObject(hdl, "_BBN", NULL, NULL)) {
513 case AE_OK:
514 rv = 1;
515 break;
516 case AE_NOT_FOUND:
517 rv = 0;
518 break;
519 default:
520 break;
524 return (rv);
528 * Return non-zero if any PCI bus in the system has an associated
529 * _BBN object, 0 otherwise.
531 static int
532 pci_roots_have_bbn(void)
534 int i;
537 * Scan the PCI busses and look for at least 1 _BBN
539 for (i = 0; i <= pci_bios_maxbus; i++) {
540 /* skip non-root (peer) PCI busses */
541 if (pci_bus_res[i].par_bus != (uchar_t)-1)
542 continue;
544 if (pci_bbn_present(i) > 0)
545 return (1);
547 return (0);
552 * return non-zero if the machine is one on which we renumber
553 * the internal pci unit-addresses
555 static int
556 pci_bus_renumber()
558 ACPI_TABLE_HEADER *fadt;
560 if (pci_bus_always_renumber)
561 return (1);
563 /* get the FADT */
564 if (AcpiGetTable(ACPI_SIG_FADT, 1, (ACPI_TABLE_HEADER **)&fadt) !=
565 AE_OK)
566 return (0);
568 /* compare OEM Table ID to "SUNm31" */
569 if (strncmp("SUNm31", fadt->OemId, 6))
570 return (0);
571 else
572 return (1);
576 * Initial enumeration of the physical PCI bus hierarchy can
577 * leave 'gaps' in the order of peer PCI bus unit-addresses.
578 * Systems with more than one peer PCI bus *must* have an ACPI
579 * _BBN object associated with each peer bus; use the presence
580 * of this object to remove gaps in the numbering of the peer
581 * PCI bus unit-addresses - only peer busses with an associated
582 * _BBN are counted.
584 static void
585 pci_renumber_root_busses(void)
587 int pci_regs[] = {0, 0, 0};
588 int i, root_addr = 0;
591 * Currently, we only enable the re-numbering on specific
592 * Sun machines; this is a work-around for the more complicated
593 * issue of upgrade changing physical device paths
595 if (!pci_bus_renumber())
596 return;
599 * If we find no _BBN objects at all, we either don't need
600 * to do anything or can't do anything anyway
602 if (!pci_roots_have_bbn())
603 return;
605 for (i = 0; i <= pci_bios_maxbus; i++) {
606 /* skip non-root (peer) PCI busses */
607 if (pci_bus_res[i].par_bus != (uchar_t)-1)
608 continue;
610 if (pci_bbn_present(i) < 1) {
611 pci_bus_res[i].root_addr = (uchar_t)-1;
612 continue;
615 ASSERT(pci_bus_res[i].dip != NULL);
616 if (pci_bus_res[i].root_addr != root_addr) {
617 /* update reg property for node */
618 pci_bus_res[i].root_addr = root_addr;
619 pci_regs[0] = pci_bus_res[i].root_addr;
620 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
621 pci_bus_res[i].dip, "reg", (int *)pci_regs, 3);
623 root_addr++;
627 void
628 pci_register_isa_resources(int type, uint32_t base, uint32_t size)
630 (void) memlist_insert(
631 (type == 1) ? &isa_res.io_used : &isa_res.mem_used,
632 base, size);
636 * Remove the resources which are already used by devices under a subtractive
637 * bridge from the bus's resources lists, because they're not available, and
638 * shouldn't be allocated to other buses. This is necessary because tracking
639 * resources for subtractive bridges is not complete. (Subtractive bridges only
640 * track some of their claimed resources, not "the rest of the address space" as
641 * they should, so that allocation to peer non-subtractive PPBs is easier. We
642 * need a fully-capable global resource allocator).
644 static void
645 remove_subtractive_res()
647 int i, j;
648 struct memlist *list;
650 for (i = 0; i <= pci_bios_maxbus; i++) {
651 if (pci_bus_res[i].subtractive) {
652 /* remove used io ports */
653 list = pci_bus_res[i].io_used;
654 while (list) {
655 for (j = 0; j <= pci_bios_maxbus; j++)
656 (void) memlist_remove(
657 &pci_bus_res[j].io_avail,
658 list->ml_address, list->ml_size);
659 list = list->ml_next;
661 /* remove used mem resource */
662 list = pci_bus_res[i].mem_used;
663 while (list) {
664 for (j = 0; j <= pci_bios_maxbus; j++) {
665 (void) memlist_remove(
666 &pci_bus_res[j].mem_avail,
667 list->ml_address, list->ml_size);
668 (void) memlist_remove(
669 &pci_bus_res[j].pmem_avail,
670 list->ml_address, list->ml_size);
672 list = list->ml_next;
674 /* remove used prefetchable mem resource */
675 list = pci_bus_res[i].pmem_used;
676 while (list) {
677 for (j = 0; j <= pci_bios_maxbus; j++) {
678 (void) memlist_remove(
679 &pci_bus_res[j].pmem_avail,
680 list->ml_address, list->ml_size);
681 (void) memlist_remove(
682 &pci_bus_res[j].mem_avail,
683 list->ml_address, list->ml_size);
685 list = list->ml_next;
692 * Set up (or complete the setup of) the bus_avail resource list
694 static void
695 setup_bus_res(int bus)
697 uchar_t par_bus;
699 if (pci_bus_res[bus].dip == NULL) /* unused bus */
700 return;
703 * Set up bus_avail if not already filled in by populate_bus_res()
705 if (pci_bus_res[bus].bus_avail == NULL) {
706 ASSERT(pci_bus_res[bus].sub_bus >= bus);
707 memlist_insert(&pci_bus_res[bus].bus_avail, bus,
708 pci_bus_res[bus].sub_bus - bus + 1);
711 ASSERT(pci_bus_res[bus].bus_avail != NULL);
714 * Remove resources from parent bus node if this is not a
715 * root bus.
717 par_bus = pci_bus_res[bus].par_bus;
718 if (par_bus != (uchar_t)-1) {
719 ASSERT(pci_bus_res[par_bus].bus_avail != NULL);
720 memlist_remove_list(&pci_bus_res[par_bus].bus_avail,
721 pci_bus_res[bus].bus_avail);
724 /* remove self from bus_avail */;
725 (void) memlist_remove(&pci_bus_res[bus].bus_avail, bus, 1);
728 static uint64_t
729 get_parbus_io_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align)
731 uint64_t addr = 0;
732 uchar_t res_bus;
735 * Skip root(peer) buses in multiple-root-bus systems when
736 * ACPI resource discovery was not successfully done.
738 if ((pci_bus_res[parbus].par_bus == (uchar_t)-1) &&
739 (num_root_bus > 1) && (acpi_resource_discovery <= 0))
740 return (0);
742 res_bus = parbus;
743 while (pci_bus_res[res_bus].subtractive) {
744 if (pci_bus_res[res_bus].io_avail)
745 break;
746 res_bus = pci_bus_res[res_bus].par_bus;
747 if (res_bus == (uchar_t)-1)
748 break; /* root bus already */
751 if (pci_bus_res[res_bus].io_avail) {
752 addr = memlist_find(&pci_bus_res[res_bus].io_avail,
753 size, align);
754 if (addr) {
755 memlist_insert(&pci_bus_res[res_bus].io_used,
756 addr, size);
758 /* free the old resource */
759 memlist_free_all(&pci_bus_res[bus].io_avail);
760 memlist_free_all(&pci_bus_res[bus].io_used);
762 /* add the new resource */
763 memlist_insert(&pci_bus_res[bus].io_avail, addr, size);
767 return (addr);
770 static uint64_t
771 get_parbus_mem_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align)
773 uint64_t addr = 0;
774 uchar_t res_bus;
777 * Skip root(peer) buses in multiple-root-bus systems when
778 * ACPI resource discovery was not successfully done.
780 if ((pci_bus_res[parbus].par_bus == (uchar_t)-1) &&
781 (num_root_bus > 1) && (acpi_resource_discovery <= 0))
782 return (0);
784 res_bus = parbus;
785 while (pci_bus_res[res_bus].subtractive) {
786 if (pci_bus_res[res_bus].mem_avail)
787 break;
788 res_bus = pci_bus_res[res_bus].par_bus;
789 if (res_bus == (uchar_t)-1)
790 break; /* root bus already */
793 if (pci_bus_res[res_bus].mem_avail) {
794 addr = memlist_find(&pci_bus_res[res_bus].mem_avail,
795 size, align);
796 if (addr) {
797 memlist_insert(&pci_bus_res[res_bus].mem_used,
798 addr, size);
799 (void) memlist_remove(&pci_bus_res[res_bus].pmem_avail,
800 addr, size);
802 /* free the old resource */
803 memlist_free_all(&pci_bus_res[bus].mem_avail);
804 memlist_free_all(&pci_bus_res[bus].mem_used);
806 /* add the new resource */
807 memlist_insert(&pci_bus_res[bus].mem_avail, addr, size);
811 return (addr);
815 * given a cap_id, return its cap_id location in config space
817 static int
818 get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id)
820 uint8_t curcap, cap_id_loc;
821 uint16_t status;
822 int location = -1;
825 * Need to check the Status register for ECP support first.
826 * Also please note that for type 1 devices, the
827 * offset could change. Should support type 1 next.
829 status = pci_getw(bus, dev, func, PCI_CONF_STAT);
830 if (!(status & PCI_STAT_CAP)) {
831 return (-1);
833 cap_id_loc = pci_getb(bus, dev, func, PCI_CONF_CAP_PTR);
835 /* Walk the list of capabilities */
836 while (cap_id_loc && cap_id_loc != (uint8_t)-1) {
837 curcap = pci_getb(bus, dev, func, cap_id_loc);
839 if (curcap == cap_id) {
840 location = cap_id_loc;
841 break;
843 cap_id_loc = pci_getb(bus, dev, func, cap_id_loc + 1);
845 return (location);
849 * Does this resource element live in the legacy VGA range?
853 is_vga(struct memlist *elem, enum io_mem io)
856 if (io == IO) {
857 if ((elem->ml_address == 0x3b0 && elem->ml_size == 0xc) ||
858 (elem->ml_address == 0x3c0 && elem->ml_size == 0x20))
859 return (1);
860 } else {
861 if (elem->ml_address == 0xa0000 && elem->ml_size == 0x20000)
862 return (1);
864 return (0);
868 * Does this entire resource list consist only of legacy VGA resources?
872 list_is_vga_only(struct memlist *l, enum io_mem io)
874 do {
875 if (!is_vga(l, io))
876 return (0);
877 } while ((l = l->ml_next) != NULL);
878 return (1);
882 * Assign valid resources to unconfigured pci(e) bridges. We are trying
883 * to reprogram the bridge when its
884 * i) SECBUS == SUBBUS ||
885 * ii) IOBASE > IOLIM ||
886 * iii) MEMBASE > MEMLIM
887 * This must be done after one full pass through the PCI tree to collect
888 * all BIOS-configured resources, so that we know what resources are
889 * free and available to assign to the unconfigured PPBs.
891 static void
892 fix_ppb_res(uchar_t secbus, boolean_t prog_sub)
894 uchar_t bus, dev, func;
895 uchar_t parbus, subbus;
896 uint_t io_base, io_limit, mem_base, mem_limit;
897 uint_t io_size, mem_size, io_align, mem_align;
898 uint64_t addr = 0;
899 int *regp = NULL;
900 uint_t reglen;
901 int rv, cap_ptr, physhi;
902 dev_info_t *dip;
903 uint16_t cmd_reg;
904 struct memlist *list, *scratch_list;
906 /* skip root (peer) PCI busses */
907 if (pci_bus_res[secbus].par_bus == (uchar_t)-1)
908 return;
910 /* skip subtractive PPB when prog_sub is not TRUE */
911 if (pci_bus_res[secbus].subtractive && !prog_sub)
912 return;
914 /* some entries may be empty due to discontiguous bus numbering */
915 dip = pci_bus_res[secbus].dip;
916 if (dip == NULL)
917 return;
919 rv = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
920 "reg", &regp, &reglen);
921 if (rv != DDI_PROP_SUCCESS || reglen == 0)
922 return;
923 physhi = regp[0];
924 ddi_prop_free(regp);
926 func = (uchar_t)PCI_REG_FUNC_G(physhi);
927 dev = (uchar_t)PCI_REG_DEV_G(physhi);
928 bus = (uchar_t)PCI_REG_BUS_G(physhi);
931 * If pcie bridge, check to see if link is enabled
933 cap_ptr = get_pci_cap(bus, dev, func, PCI_CAP_ID_PCI_E);
934 if (cap_ptr != -1) {
935 cmd_reg = pci_getw(bus, dev, func,
936 (uint16_t)cap_ptr + PCIE_LINKCTL);
937 if (cmd_reg & PCIE_LINKCTL_LINK_DISABLE) {
938 dcmn_err(CE_NOTE,
939 "!fix_ppb_res: ppb[%x/%x/%x] link is disabled.\n",
940 bus, dev, func);
941 return;
945 subbus = pci_getb(bus, dev, func, PCI_BCNF_SUBBUS);
946 parbus = pci_bus_res[secbus].par_bus;
947 ASSERT(parbus == bus);
948 cmd_reg = pci_getw(bus, dev, func, PCI_CONF_COMM);
951 * If we have a Cardbus bridge, but no bus space
953 if (pci_bus_res[secbus].num_cbb != 0 &&
954 pci_bus_res[secbus].bus_avail == NULL) {
955 uchar_t range;
957 /* normally there are 2 buses under a cardbus bridge */
958 range = pci_bus_res[secbus].num_cbb * 2;
961 * Try to find and allocate a bus-range starting at subbus+1
962 * from the parent of the PPB.
964 for (; range != 0; range--) {
965 if (memlist_find_with_startaddr(
966 &pci_bus_res[parbus].bus_avail,
967 subbus + 1, range, 1) != NULL)
968 break; /* find bus range resource at parent */
970 if (range != 0) {
971 memlist_insert(&pci_bus_res[secbus].bus_avail,
972 subbus + 1, range);
973 subbus = subbus + range;
974 pci_bus_res[secbus].sub_bus = subbus;
975 pci_putb(bus, dev, func, PCI_BCNF_SUBBUS, subbus);
976 add_bus_range_prop(secbus);
978 cmn_err(CE_NOTE, "!reprogram bus-range on ppb"
979 "[%x/%x/%x]: %x ~ %x\n", bus, dev, func,
980 secbus, subbus);
985 * Calculate required IO size and alignment
986 * If bus io_size is zero, we are going to assign 512 bytes per bus,
987 * otherwise, we'll choose the maximum value of such calculation and
988 * bus io_size. The size needs to be 4K aligned.
990 * We calculate alignment as the largest power of two less than the
991 * the sum of all children's IO size requirements, because this will
992 * align to the size of the largest child request within that size
993 * (which is always a power of two).
995 io_size = (subbus - secbus + 1) * 0x200;
996 if (io_size < pci_bus_res[secbus].io_size)
997 io_size = pci_bus_res[secbus].io_size;
998 io_size = P2ROUNDUP(io_size, PPB_IO_ALIGNMENT);
999 io_align = io_size;
1000 P2LE(io_align);
1003 * Calculate required MEM size and alignment
1004 * If bus mem_size is zero, we are going to assign 1M bytes per bus,
1005 * otherwise, we'll choose the maximum value of such calculation and
1006 * bus mem_size. The size needs to be 1M aligned.
1008 * For the alignment, refer to the I/O comment above.
1010 mem_size = (subbus - secbus + 1) * PPB_MEM_ALIGNMENT;
1011 if (mem_size < pci_bus_res[secbus].mem_size) {
1012 mem_size = pci_bus_res[secbus].mem_size;
1013 mem_size = P2ROUNDUP(mem_size, PPB_MEM_ALIGNMENT);
1015 mem_align = mem_size;
1016 P2LE(mem_align);
1018 /* Subtractive bridge */
1019 if (pci_bus_res[secbus].subtractive && prog_sub) {
1021 * We program an arbitrary amount of I/O and memory resource
1022 * for the subtractive bridge so that child dynamic-resource-
1023 * allocating devices (such as Cardbus bridges) have a chance
1024 * of success. Until we have full-tree resource rebalancing,
1025 * dynamic resource allocation (thru busra) only looks at the
1026 * parent bridge, so all PPBs must have some allocatable
1027 * resource. For non-subtractive bridges, the resources come
1028 * from the base/limit register "windows", but subtractive
1029 * bridges often don't program those (since they don't need to).
1030 * If we put all the remaining resources on the subtractive
1031 * bridge, then peer non-subtractive bridges can't allocate
1032 * more space (even though this is probably most correct).
1033 * If we put the resources only on the parent, then allocations
1034 * from children of subtractive bridges will fail without
1035 * special-case code for bypassing the subtractive bridge.
1036 * This solution is the middle-ground temporary solution until
1037 * we have fully-capable resource allocation.
1041 * Add an arbitrary I/O resource to the subtractive PPB
1043 if (pci_bus_res[secbus].io_avail == NULL) {
1044 addr = get_parbus_io_res(parbus, secbus, io_size,
1045 io_align);
1046 if (addr) {
1047 add_ranges_prop(secbus, 1);
1048 pci_bus_res[secbus].io_reprogram =
1049 pci_bus_res[parbus].io_reprogram;
1051 cmn_err(CE_NOTE, "!add io-range on subtractive"
1052 " ppb[%x/%x/%x]: 0x%x ~ 0x%x\n",
1053 bus, dev, func, (uint32_t)addr,
1054 (uint32_t)addr + io_size - 1);
1058 * Add an arbitrary memory resource to the subtractive PPB
1060 if (pci_bus_res[secbus].mem_avail == NULL) {
1061 addr = get_parbus_mem_res(parbus, secbus, mem_size,
1062 mem_align);
1063 if (addr) {
1064 add_ranges_prop(secbus, 1);
1065 pci_bus_res[secbus].mem_reprogram =
1066 pci_bus_res[parbus].mem_reprogram;
1068 cmn_err(CE_NOTE, "!add mem-range on "
1069 "subtractive ppb[%x/%x/%x]: 0x%x ~ 0x%x\n",
1070 bus, dev, func, (uint32_t)addr,
1071 (uint32_t)addr + mem_size - 1);
1075 goto cmd_enable;
1079 * Check to see if we need to reprogram I/O space, either because the
1080 * parent bus needed reprogramming and so do we, or because I/O space is
1081 * disabled in base/limit or command register.
1083 io_base = pci_getb(bus, dev, func, PCI_BCNF_IO_BASE_LOW);
1084 io_limit = pci_getb(bus, dev, func, PCI_BCNF_IO_LIMIT_LOW);
1085 io_base = (io_base & PCI_BCNF_IO_MASK) << PCI_BCNF_IO_SHIFT;
1086 io_limit = ((io_limit & PCI_BCNF_IO_MASK) << PCI_BCNF_IO_SHIFT) | 0xfff;
1087 if ((io_base & PCI_BCNF_ADDR_MASK) == PCI_BCNF_IO_32BIT) {
1088 uint16_t io_base_hi, io_limit_hi;
1089 io_base_hi = pci_getw(bus, dev, func, PCI_BCNF_IO_BASE_HI);
1090 io_limit_hi = pci_getw(bus, dev, func, PCI_BCNF_IO_LIMIT_HI);
1092 io_base |= (uint_t)io_base_hi << 16;
1093 io_limit |= (uint_t)io_limit_hi << 16;
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);
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);
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);
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;
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);
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);
1169 memlist_free_all(&scratch_list);
1172 * Check memory space as we did I/O space.
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;
1179 scratch_list = memlist_dup(pci_bus_res[secbus].mem_avail);
1180 memlist_merge(&pci_bus_res[secbus].mem_used, &scratch_list);
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);
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);
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;
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));
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.
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);
1265 add_ranges_prop(secbus, 1);
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);
1272 memlist_free_all(&scratch_list);
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);
1282 void
1283 pci_reprogram(void)
1285 int i, pci_reconfig = 1;
1286 char *onoff;
1287 int bus;
1290 * Scan ACPI namespace for _BBN objects, make sure that
1291 * childless root-bridges appear in devinfo tree
1293 pci_scan_bbn();
1294 pci_unitaddr_cache_init();
1297 * Fix-up unit-address assignments if cache is available
1299 if (pci_unitaddr_cache_valid()) {
1300 int pci_regs[] = {0, 0, 0};
1301 int new_addr;
1302 int index = 0;
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;
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);
1319 index++;
1321 } else {
1322 /* perform legacy processing */
1323 pci_renumber_root_busses();
1324 pci_unitaddr_cache_create();
1328 * Do root-bus resource discovery
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;
1336 * 1. find resources associated with this root bus
1338 populate_bus_res(bus);
1342 * 2. Remove used PCI and ISA resources from bus resource map
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);
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);
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
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);
1376 memlist_free_all(&isa_res.io_used);
1377 memlist_free_all(&isa_res.mem_used);
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);
1385 /* setup bus range resource on each bus */
1386 setup_bus_res(i);
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");
1395 ddi_prop_free(onoff);
1398 remove_subtractive_res();
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);
1405 for (i = 0; i <= pci_bios_maxbus; i++) {
1406 /* configure devices not configured by BIOS */
1407 if (pci_reconfig) {
1409 * Reprogram the subtractive PPB. At this time, all its
1410 * siblings should have got their resources already.
1412 if (pci_bus_res[i].subtractive)
1413 fix_ppb_res(i, B_TRUE);
1414 enumerate_bus_devs(i, CONFIG_NEW);
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);
1424 * populate bus resources
1426 static void
1427 populate_bus_res(uchar_t bus)
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);
1437 * attempt to initialize sub_bus from the largest range-end
1438 * in the bus_avail list
1440 if (pci_bus_res[bus].bus_avail != NULL) {
1441 struct memlist *entry;
1442 int current;
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;
1453 if (bus == 0) {
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.
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);
1469 * Create 'ranges' property here before any resources are
1470 * removed from the resource lists
1472 add_ranges_prop(bus, 0);
1477 * Create top-level bus dips, i.e. /pci@0,0, /pci@1,0...
1479 static void
1480 create_root_bus_dip(uchar_t bus)
1482 int pci_regs[] = {0, 0, 0};
1483 dev_info_t *dip;
1485 ASSERT(pci_bus_res[bus].par_bus == (uchar_t)-1);
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);
1499 * If system has PCIe bus, then create different properties
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");
1505 (void) ndi_devi_bind_driver(dip, 0);
1506 pci_bus_res[bus].dip = dip;
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.
1514 void
1515 enumerate_bus_devs(uchar_t bus, int config_op)
1517 uchar_t dev, func, nfunc, header;
1518 ushort_t venid;
1519 struct pci_devfunc *devlist = NULL, *entry;
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);
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);
1540 kmem_free(entry, sizeof (*entry));
1542 pci_bus_res[bus].privdata = NULL;
1543 return;
1546 for (dev = 0; dev < max_dev_pci; dev++) {
1547 nfunc = 1;
1548 for (func = 0; func < nfunc; func++) {
1550 dcmn_err(CE_NOTE, "probing dev 0x%x, func 0x%x",
1551 dev, func);
1553 venid = pci_getw(bus, dev, func, PCI_CONF_VENID);
1555 if ((venid == 0xffff) || (venid == 0)) {
1556 /* no function at this address */
1557 continue;
1560 header = pci_getb(bus, dev, func, PCI_CONF_HEADER);
1561 if (header == 0xff) {
1562 continue; /* illegal value */
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.
1571 if ((func == 0) && (header & PCI_HEADER_MULTI)) {
1572 nfunc = 8;
1575 if (config_op == CONFIG_FIX ||
1576 config_op == CONFIG_INFO) {
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.
1583 process_devfunc(bus, dev, func, header,
1584 venid, config_op);
1590 /* percolate bus used resources up through parents to root */
1591 if (config_op == CONFIG_INFO) {
1592 int par_bus;
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;
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);
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);
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);
1613 bus = par_bus;
1614 par_bus = pci_bus_res[par_bus].par_bus;
1619 static int
1620 check_pciide_prop(uchar_t revid, ushort_t venid, ushort_t devid,
1621 ushort_t subvenid, ushort_t subdevid)
1623 static int prop_exist = -1;
1624 static char *pciide_str;
1625 char compat[32];
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);
1633 if (!prop_exist)
1634 return (0);
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);
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);
1648 (void) snprintf(compat, sizeof (compat), "pci%x,%x",
1649 subvenid, subdevid);
1650 if (strcmp(pciide_str, compat) == 0)
1651 return (1);
1653 (void) snprintf(compat, sizeof (compat), "pci%x,%x.%x",
1654 venid, devid, revid);
1655 if (strcmp(pciide_str, compat) == 0)
1656 return (1);
1658 (void) snprintf(compat, sizeof (compat), "pci%x,%x", venid, devid);
1659 if (strcmp(pciide_str, compat) == 0)
1660 return (1);
1662 return (0);
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)
1669 struct ide_table { /* table for PCI_MASS_OTHER */
1670 ushort_t venid;
1671 ushort_t devid;
1672 } *entry;
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}
1684 if (basecl != PCI_CLASS_MASS)
1685 return (0);
1687 if (subcl == PCI_MASS_IDE) {
1688 return (1);
1691 if (check_pciide_prop(revid, venid, devid, subvenid, subdevid))
1692 return (1);
1694 if (subcl != PCI_MASS_OTHER && subcl != PCI_MASS_SATA) {
1695 return (0);
1698 entry = &ide_other[0];
1699 while (entry->venid) {
1700 if (entry->venid == venid && entry->devid == devid)
1701 return (1);
1702 entry++;
1704 return (0);
1707 static int
1708 is_display(uint_t classcode)
1710 static uint_t disp_classes[] = {
1711 0x000100,
1712 0x030000,
1713 0x030001
1715 int i, nclasses = sizeof (disp_classes) / sizeof (uint_t);
1717 for (i = 0; i < nclasses; i++) {
1718 if (classcode == disp_classes[i])
1719 return (1);
1721 return (0);
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))
1728 struct pci_fixundo *newundo;
1730 newundo = kmem_alloc(sizeof (struct pci_fixundo), KM_SLEEP);
1733 * Adding an item to this list means that we must turn its NMIENABLE
1734 * bit back on at a later time.
1736 newundo->bus = bus;
1737 newundo->dev = dev;
1738 newundo->fn = fn;
1739 newundo->undofn = undofn;
1740 newundo->next = undolist;
1742 /* add to the undo list in LIFO order */
1743 undolist = newundo;
1746 void
1747 add_pci_fixes(void)
1749 int i;
1751 for (i = 0; i <= pci_bios_maxbus; i++) {
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).
1760 enumerate_bus_devs(i, CONFIG_FIX);
1764 void
1765 undo_pci_fixes(void)
1767 struct pci_fixundo *nextundo;
1768 uint8_t bus, dev, fn;
1771 * All fixes in the undo list are performed unconditionally. Future
1772 * fixes may require selective undo.
1774 while (undolist != NULL) {
1776 bus = undolist->bus;
1777 dev = undolist->dev;
1778 fn = undolist->fn;
1780 (*(undolist->undofn))(bus, dev, fn);
1782 nextundo = undolist->next;
1783 kmem_free(undolist, sizeof (struct pci_fixundo));
1784 undolist = nextundo;
1788 static void
1789 undo_amd8111_pci_fix(uint8_t bus, uint8_t dev, uint8_t fn)
1791 uint8_t val8;
1793 val8 = pci_getb(bus, dev, fn, LPC_IO_CONTROL_REG_1);
1795 * The NMIONERR bit is turned back on to allow the SMM BIOS
1796 * to handle more critical PCI errors (e.g. PERR#).
1798 val8 |= AMD8111_ENABLENMI;
1799 pci_putb(bus, dev, fn, LPC_IO_CONTROL_REG_1, val8);
1802 static void
1803 pci_fix_amd8111(uint8_t bus, uint8_t dev, uint8_t fn)
1805 uint8_t val8;
1807 val8 = pci_getb(bus, dev, fn, LPC_IO_CONTROL_REG_1);
1809 if ((val8 & AMD8111_ENABLENMI) == 0)
1810 return;
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.
1817 val8 &= ~AMD8111_ENABLENMI;
1819 pci_putb(bus, dev, fn, LPC_IO_CONTROL_REG_1, val8);
1821 add_undofix_entry(bus, dev, fn, undo_amd8111_pci_fix);
1824 static void
1825 set_devpm_d0(uchar_t bus, uchar_t dev, uchar_t func)
1827 uint16_t status;
1828 uint8_t header;
1829 uint8_t cap_ptr;
1830 uint8_t cap_id;
1831 uint16_t pmcsr;
1833 status = pci_getw(bus, dev, func, PCI_CONF_STAT);
1834 if (!(status & PCI_STAT_CAP))
1835 return; /* No capabilities list */
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);
1843 * Walk the capabilities list searching for a PM entry.
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;
1855 cap_ptr = pci_getb(bus, dev, func, cap_ptr + PCI_CAP_NEXT_PTR);
1860 #define is_isa(bc, sc) \
1861 (((bc) == PCI_CLASS_BRIDGE) && ((sc) == PCI_BRIDGE_ISA))
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)
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;
1882 ushort_t deviceid = pci_getw(bus, dev, func, PCI_CONF_DEVID);
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;
1902 if (config_op == CONFIG_FIX) {
1903 if (vendorid == VENID_AMD && deviceid == DEVID_AMD8111_LPC) {
1904 pci_fix_amd8111(bus, dev, func);
1906 return;
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;
1914 /* figure out if this is pci-ide */
1915 basecl = classcode >> 16;
1916 subcl = (classcode >> 8) & 0xff;
1917 progcl = classcode & 0xff;
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);
1931 /* make sure parent bus dip has been created */
1932 if (pci_bus_res[bus].dip == NULL)
1933 create_root_bus_dip(bus);
1935 ndi_devi_alloc_sleep(pci_bus_res[bus].dip, nodename,
1936 DEVI_SID_NODEID, &dip);
1938 if (check_if_device_is_pciex(dip, bus, dev, func, &slot_valid,
1939 &slot_num, &is_pci_bridge) == B_TRUE)
1940 pciex = 1;
1942 bdf = PCI_GETBDF(bus, dev, func);
1944 * Record BAD AMD bridges which don't support MMIO config access.
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;
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);
1956 pci_cfgacc_add_workaround(bdf, secbus, subbus);
1960 * Only populate bus_t if this device is sitting under a PCIE root
1961 * complex. Some particular machines have both a PCIE root complex and
1962 * a PCI hostbridge, in which case only devices under the PCIE root
1963 * complex will have their bus_t populated.
1965 if (pcie_get_rc_dip(dip) != NULL) {
1966 ck804_fix_aer_ptr(dip, bdf);
1967 (void) pcie_init_bus(dip, bdf, PCIE_BUS_INITIAL);
1970 /* add properties */
1971 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "device-id", deviceid);
1972 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "vendor-id", vendorid);
1973 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "revision-id", revid);
1974 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
1975 "class-code", classcode);
1976 if (func == 0)
1977 (void) snprintf(unitaddr, sizeof (unitaddr), "%x", dev);
1978 else
1979 (void) snprintf(unitaddr, sizeof (unitaddr),
1980 "%x,%x", dev, func);
1981 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
1982 "unit-address", unitaddr);
1984 /* add device_type for display nodes */
1985 if (is_display(classcode)) {
1986 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
1987 "device_type", "display");
1989 /* add special stuff for header type */
1990 if ((header & PCI_HEADER_TYPE_M) == PCI_HEADER_ZERO) {
1991 uchar_t mingrant = pci_getb(bus, dev, func, PCI_CONF_MIN_G);
1992 uchar_t maxlatency = pci_getb(bus, dev, func, PCI_CONF_MAX_L);
1994 if (subvenid != 0) {
1995 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
1996 "subsystem-id", subdevid);
1997 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
1998 "subsystem-vendor-id", subvenid);
2000 if (!pciex)
2001 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2002 "min-grant", mingrant);
2003 if (!pciex)
2004 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2005 "max-latency", maxlatency);
2008 /* interrupt, record if not 0 */
2009 intr = pci_getb(bus, dev, func, PCI_CONF_IPIN);
2010 if (intr != 0)
2011 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2012 "interrupts", intr);
2015 * Add support for 133 mhz pci eventually
2017 status = pci_getw(bus, dev, func, PCI_CONF_STAT);
2019 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2020 "devsel-speed", (status & PCI_STAT_DEVSELT) >> 9);
2021 if (!pciex && (status & PCI_STAT_FBBC))
2022 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
2023 "fast-back-to-back");
2024 if (!pciex && (status & PCI_STAT_66MHZ))
2025 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
2026 "66mhz-capable");
2027 if (status & PCI_STAT_UDF)
2028 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
2029 "udf-supported");
2030 if (pciex && slot_valid) {
2031 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2032 "physical-slot#", slot_num);
2033 if (!is_pci_bridge)
2034 pciex_slot_names_prop(dip, slot_num);
2037 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
2038 "power-consumption", power, 2);
2040 /* Set the device PM state to D0 */
2041 set_devpm_d0(bus, dev, func);
2043 if ((basecl == PCI_CLASS_BRIDGE) && (subcl == PCI_BRIDGE_PCI))
2044 add_ppb_props(dip, bus, dev, func, pciex, is_pci_bridge);
2045 else {
2047 * Record the non-PPB devices on the bus for possible
2048 * reprogramming at 2nd bus enumeration.
2049 * Note: PPB reprogramming is done in fix_ppb_res()
2051 devlist = (struct pci_devfunc *)pci_bus_res[bus].privdata;
2052 entry = kmem_zalloc(sizeof (*entry), KM_SLEEP);
2053 entry->dip = dip;
2054 entry->dev = dev;
2055 entry->func = func;
2056 entry->next = devlist;
2057 pci_bus_res[bus].privdata = entry;
2060 if (IS_CLASS_IOAPIC(basecl, subcl, progcl)) {
2061 create_ioapic_node(bus, dev, func, vendorid, deviceid);
2064 /* check for NVIDIA CK8-04/MCP55 based LPC bridge */
2065 if (NVIDIA_IS_LPC_BRIDGE(vendorid, deviceid) && (dev == 1) &&
2066 (func == 0)) {
2067 add_nvidia_isa_bridge_props(dip, bus, dev, func);
2068 /* each LPC bridge has an integrated IOAPIC */
2069 apic_nvidia_io_max++;
2072 if (pciex && is_pci_bridge)
2073 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "model",
2074 (char *)"PCIe-PCI bridge");
2075 else
2076 add_model_prop(dip, classcode);
2078 add_compatible(dip, subvenid, subdevid, vendorid, deviceid,
2079 revid, classcode, pciex);
2082 * See if this device is a controller that advertises
2083 * itself to be a standard ATA task file controller, or one that
2084 * has been hard coded.
2086 * If it is, check if any other higher precedence driver listed in
2087 * driver_aliases will claim the node by calling
2088 * ddi_compatibile_driver_major. If so, clear pciide and do not
2089 * create a pci-ide node or any other special handling.
2091 * If another driver does not bind, set the node name to pci-ide
2092 * and then let the special pci-ide handling for registers and
2093 * child pci-ide nodes proceed below.
2095 if (is_pciide(basecl, subcl, revid, vendorid, deviceid,
2096 subvenid, subdevid) == 1) {
2097 if (ddi_compatible_driver_major(dip, NULL) == (major_t)-1) {
2098 (void) ndi_devi_set_nodename(dip, "pci-ide", 0);
2099 pciide = 1;
2103 DEVI_SET_PCI(dip);
2104 reprogram = add_reg_props(dip, bus, dev, func, config_op, pciide);
2105 (void) ndi_devi_bind_driver(dip, 0);
2107 /* special handling for pci-ide */
2108 if (pciide) {
2109 dev_info_t *cdip;
2112 * Create properties specified by P1275 Working Group
2113 * Proposal #414 Version 1
2115 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
2116 "device_type", "pci-ide");
2117 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2118 "#address-cells", 1);
2119 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
2120 "#size-cells", 0);
2122 /* allocate two child nodes */
2123 ndi_devi_alloc_sleep(dip, "ide",
2124 (pnode_t)DEVI_SID_NODEID, &cdip);
2125 (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
2126 "reg", 0);
2127 (void) ndi_devi_bind_driver(cdip, 0);
2128 ndi_devi_alloc_sleep(dip, "ide",
2129 (pnode_t)DEVI_SID_NODEID, &cdip);
2130 (void) ndi_prop_update_int(DDI_DEV_T_NONE, cdip,
2131 "reg", 1);
2132 (void) ndi_devi_bind_driver(cdip, 0);
2134 reprogram = 0; /* don't reprogram pci-ide bridge */
2137 if (is_display(classcode)) {
2138 gfxp = kmem_zalloc(sizeof (*gfxp), KM_SLEEP);
2139 gfxp->g_dip = dip;
2140 gfxp->g_prev = NULL;
2141 gfxp->g_next = gfx_devinfo_list;
2142 gfx_devinfo_list = gfxp;
2143 if (gfxp->g_next)
2144 gfxp->g_next->g_prev = gfxp;
2147 /* special handling for isa */
2148 if (!pseudo_isa && is_isa(basecl, subcl)) {
2149 /* add device_type */
2150 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip,
2151 "device_type", "isa");
2154 if (reprogram && (entry != NULL))
2155 entry->reprogram = B_TRUE;
2160 * Some vendors do not use unique subsystem IDs in their products, which
2161 * makes the use of form 2 compatible names (pciSSSS,ssss) inappropriate.
2162 * Allow for these compatible forms to be excluded on a per-device basis.
2164 /*ARGSUSED*/
2165 static boolean_t
2166 subsys_compat_exclude(ushort_t venid, ushort_t devid, ushort_t subvenid,
2167 ushort_t subdevid, uchar_t revid, uint_t classcode)
2169 /* Nvidia display adapters */
2170 if ((venid == 0x10de) && (is_display(classcode)))
2171 return (B_TRUE);
2173 return (B_FALSE);
2177 * Set the compatible property to a value compliant with
2178 * rev 2.1 of the IEEE1275 PCI binding.
2179 * (Also used for PCI-Express devices).
2181 * pciVVVV,DDDD.SSSS.ssss.RR (0)
2182 * pciVVVV,DDDD.SSSS.ssss (1)
2183 * pciSSSS,ssss (2)
2184 * pciVVVV,DDDD.RR (3)
2185 * pciVVVV,DDDD (4)
2186 * pciclass,CCSSPP (5)
2187 * pciclass,CCSS (6)
2189 * The Subsystem (SSSS) forms are not inserted if
2190 * subsystem-vendor-id is 0.
2192 * NOTE: For PCI-Express devices "pci" is replaced with "pciex" in 0-6 above
2193 * property 2 is not created as per "1275 bindings for PCI Express Interconnect"
2195 * Set with setprop and \x00 between each
2196 * to generate the encoded string array form.
2198 void
2199 add_compatible(dev_info_t *dip, ushort_t subvenid, ushort_t subdevid,
2200 ushort_t vendorid, ushort_t deviceid, uchar_t revid, uint_t classcode,
2201 int pciex)
2203 int i = 0;
2204 int size = COMPAT_BUFSIZE;
2205 char *compat[13];
2206 char *buf, *curr;
2208 curr = buf = kmem_alloc(size, KM_SLEEP);
2210 if (pciex) {
2211 if (subvenid) {
2212 compat[i++] = curr; /* form 0 */
2213 (void) snprintf(curr, size, "pciex%x,%x.%x.%x.%x",
2214 vendorid, deviceid, subvenid, subdevid, revid);
2215 size -= strlen(curr) + 1;
2216 curr += strlen(curr) + 1;
2218 compat[i++] = curr; /* form 1 */
2219 (void) snprintf(curr, size, "pciex%x,%x.%x.%x",
2220 vendorid, deviceid, subvenid, subdevid);
2221 size -= strlen(curr) + 1;
2222 curr += strlen(curr) + 1;
2225 compat[i++] = curr; /* form 3 */
2226 (void) snprintf(curr, size, "pciex%x,%x.%x",
2227 vendorid, deviceid, revid);
2228 size -= strlen(curr) + 1;
2229 curr += strlen(curr) + 1;
2231 compat[i++] = curr; /* form 4 */
2232 (void) snprintf(curr, size, "pciex%x,%x", vendorid, deviceid);
2233 size -= strlen(curr) + 1;
2234 curr += strlen(curr) + 1;
2236 compat[i++] = curr; /* form 5 */
2237 (void) snprintf(curr, size, "pciexclass,%06x", classcode);
2238 size -= strlen(curr) + 1;
2239 curr += strlen(curr) + 1;
2241 compat[i++] = curr; /* form 6 */
2242 (void) snprintf(curr, size, "pciexclass,%04x",
2243 (classcode >> 8));
2244 size -= strlen(curr) + 1;
2245 curr += strlen(curr) + 1;
2248 if (subvenid) {
2249 compat[i++] = curr; /* form 0 */
2250 (void) snprintf(curr, size, "pci%x,%x.%x.%x.%x",
2251 vendorid, deviceid, subvenid, subdevid, revid);
2252 size -= strlen(curr) + 1;
2253 curr += strlen(curr) + 1;
2255 compat[i++] = curr; /* form 1 */
2256 (void) snprintf(curr, size, "pci%x,%x.%x.%x",
2257 vendorid, deviceid, subvenid, subdevid);
2258 size -= strlen(curr) + 1;
2259 curr += strlen(curr) + 1;
2261 if (subsys_compat_exclude(vendorid, deviceid, subvenid,
2262 subdevid, revid, classcode) == B_FALSE) {
2263 compat[i++] = curr; /* form 2 */
2264 (void) snprintf(curr, size, "pci%x,%x", subvenid,
2265 subdevid);
2266 size -= strlen(curr) + 1;
2267 curr += strlen(curr) + 1;
2270 compat[i++] = curr; /* form 3 */
2271 (void) snprintf(curr, size, "pci%x,%x.%x", vendorid, deviceid, revid);
2272 size -= strlen(curr) + 1;
2273 curr += strlen(curr) + 1;
2275 compat[i++] = curr; /* form 4 */
2276 (void) snprintf(curr, size, "pci%x,%x", vendorid, deviceid);
2277 size -= strlen(curr) + 1;
2278 curr += strlen(curr) + 1;
2280 compat[i++] = curr; /* form 5 */
2281 (void) snprintf(curr, size, "pciclass,%06x", classcode);
2282 size -= strlen(curr) + 1;
2283 curr += strlen(curr) + 1;
2285 compat[i++] = curr; /* form 6 */
2286 (void) snprintf(curr, size, "pciclass,%04x", (classcode >> 8));
2287 size -= strlen(curr) + 1;
2288 curr += strlen(curr) + 1;
2290 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, dip,
2291 "compatible", compat, i);
2292 kmem_free(buf, COMPAT_BUFSIZE);
2296 * Adjust the reg properties for a dual channel PCI-IDE device.
2298 * NOTE: don't do anything that changes the order of the hard-decodes
2299 * and programmed BARs. The kernel driver depends on these values
2300 * being in this order regardless of whether they're for a 'native'
2301 * mode BAR or not.
2304 * config info for pci-ide devices
2306 static struct {
2307 uchar_t native_mask; /* 0 == 'compatibility' mode, 1 == native */
2308 uchar_t bar_offset; /* offset for alt status register */
2309 ushort_t addr; /* compatibility mode base address */
2310 ushort_t length; /* number of ports for this BAR */
2311 } pciide_bar[] = {
2312 { 0x01, 0, 0x1f0, 8 }, /* primary lower BAR */
2313 { 0x01, 2, 0x3f6, 1 }, /* primary upper BAR */
2314 { 0x04, 0, 0x170, 8 }, /* secondary lower BAR */
2315 { 0x04, 2, 0x376, 1 } /* secondary upper BAR */
2318 static int
2319 pciIdeAdjustBAR(uchar_t progcl, int index, uint_t *basep, uint_t *lenp)
2321 int hard_decode = 0;
2324 * Adjust the base and len for the BARs of the PCI-IDE
2325 * device's primary and secondary controllers. The first
2326 * two BARs are for the primary controller and the next
2327 * two BARs are for the secondary controller. The fifth
2328 * and sixth bars are never adjusted.
2330 if (index >= 0 && index <= 3) {
2331 *lenp = pciide_bar[index].length;
2333 if (progcl & pciide_bar[index].native_mask) {
2334 *basep += pciide_bar[index].bar_offset;
2335 } else {
2336 *basep = pciide_bar[index].addr;
2337 hard_decode = 1;
2342 * if either base or len is zero make certain both are zero
2344 if (*basep == 0 || *lenp == 0) {
2345 *basep = 0;
2346 *lenp = 0;
2347 hard_decode = 0;
2350 return (hard_decode);
2355 * Add the "reg" and "assigned-addresses" property
2357 static int
2358 add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
2359 int config_op, int pciide)
2361 uchar_t baseclass, subclass, progclass, header;
2362 ushort_t bar_sz;
2363 uint_t value = 0, len, devloc;
2364 uint_t base, base_hi, type;
2365 ushort_t offset, end;
2366 int max_basereg, j, reprogram = 0;
2367 uint_t phys_hi;
2368 struct memlist **io_avail, **io_used;
2369 struct memlist **mem_avail, **mem_used;
2370 struct memlist **pmem_avail, **pmem_used;
2371 uchar_t res_bus;
2373 pci_regspec_t regs[16] = {{0}};
2374 pci_regspec_t assigned[15] = {{0}};
2375 int nreg, nasgn;
2377 io_avail = &pci_bus_res[bus].io_avail;
2378 io_used = &pci_bus_res[bus].io_used;
2379 mem_avail = &pci_bus_res[bus].mem_avail;
2380 mem_used = &pci_bus_res[bus].mem_used;
2381 pmem_avail = &pci_bus_res[bus].pmem_avail;
2382 pmem_used = &pci_bus_res[bus].pmem_used;
2384 devloc = (uint_t)bus << 16 | (uint_t)dev << 11 | (uint_t)func << 8;
2385 regs[0].pci_phys_hi = devloc;
2386 nreg = 1; /* rest of regs[0] is all zero */
2387 nasgn = 0;
2389 baseclass = pci_getb(bus, dev, func, PCI_CONF_BASCLASS);
2390 subclass = pci_getb(bus, dev, func, PCI_CONF_SUBCLASS);
2391 progclass = pci_getb(bus, dev, func, PCI_CONF_PROGCLASS);
2392 header = pci_getb(bus, dev, func, PCI_CONF_HEADER) & PCI_HEADER_TYPE_M;
2394 switch (header) {
2395 case PCI_HEADER_ZERO:
2396 max_basereg = PCI_BASE_NUM;
2397 break;
2398 case PCI_HEADER_PPB:
2399 max_basereg = PCI_BCNF_BASE_NUM;
2400 break;
2401 case PCI_HEADER_CARDBUS:
2402 max_basereg = PCI_CBUS_BASE_NUM;
2403 reprogram = 1;
2404 break;
2405 default:
2406 max_basereg = 0;
2407 break;
2411 * Create the register property by saving the current
2412 * value of the base register. Write 0xffffffff to the
2413 * base register. Read the value back to determine the
2414 * required size of the address space. Restore the base
2415 * register contents.
2417 * Do not disable I/O and memory access for bridges; this
2418 * has the side-effect of making the bridge transparent to
2419 * secondary-bus activity (see sections 4.1-4.3 of the
2420 * PCI-PCI Bridge Spec V1.2). For non-bridges, disable
2421 * I/O and memory access to avoid difficulty with USB
2422 * emulation (see OHCI spec1.0a appendix B
2423 * "Host Controller Mapping")
2425 end = PCI_CONF_BASE0 + max_basereg * sizeof (uint_t);
2426 for (j = 0, offset = PCI_CONF_BASE0; offset < end;
2427 j++, offset += bar_sz) {
2428 uint_t command;
2430 /* determine the size of the address space */
2431 base = pci_getl(bus, dev, func, offset);
2432 if (baseclass != PCI_CLASS_BRIDGE) {
2433 command = (uint_t)pci_getw(bus, dev, func,
2434 PCI_CONF_COMM);
2435 pci_putw(bus, dev, func, PCI_CONF_COMM,
2436 command & ~(PCI_COMM_MAE | PCI_COMM_IO));
2438 pci_putl(bus, dev, func, offset, 0xffffffff);
2439 value = pci_getl(bus, dev, func, offset);
2440 pci_putl(bus, dev, func, offset, base);
2441 if (baseclass != PCI_CLASS_BRIDGE)
2442 pci_putw(bus, dev, func, PCI_CONF_COMM, command);
2444 /* construct phys hi,med.lo, size hi, lo */
2445 if ((pciide && j < 4) || (base & PCI_BASE_SPACE_IO)) {
2446 int hard_decode = 0;
2448 /* i/o space */
2449 bar_sz = PCI_BAR_SZ_32;
2450 value &= PCI_BASE_IO_ADDR_M;
2451 len = ((value ^ (value-1)) + 1) >> 1;
2453 /* XXX Adjust first 4 IDE registers */
2454 if (pciide) {
2455 if (subclass != PCI_MASS_IDE)
2456 progclass = (PCI_IDE_IF_NATIVE_PRI |
2457 PCI_IDE_IF_NATIVE_SEC);
2458 hard_decode = pciIdeAdjustBAR(progclass, j,
2459 &base, &len);
2460 } else if (value == 0) {
2461 /* skip base regs with size of 0 */
2462 continue;
2465 regs[nreg].pci_phys_hi = PCI_ADDR_IO | devloc |
2466 (hard_decode ? PCI_RELOCAT_B : offset);
2467 regs[nreg].pci_phys_low = hard_decode ?
2468 base & PCI_BASE_IO_ADDR_M : 0;
2469 assigned[nasgn].pci_phys_hi =
2470 PCI_RELOCAT_B | regs[nreg].pci_phys_hi;
2471 regs[nreg].pci_size_low =
2472 assigned[nasgn].pci_size_low = len;
2473 type = base & (~PCI_BASE_IO_ADDR_M);
2474 base &= PCI_BASE_IO_ADDR_M;
2476 * A device under a subtractive PPB can allocate
2477 * resources from its parent bus if there is no resource
2478 * available on its own bus.
2480 if ((config_op == CONFIG_NEW) && (*io_avail == NULL)) {
2481 res_bus = bus;
2482 while (pci_bus_res[res_bus].subtractive) {
2483 res_bus = pci_bus_res[res_bus].par_bus;
2484 if (res_bus == (uchar_t)-1)
2485 break; /* root bus already */
2486 if (pci_bus_res[res_bus].io_avail) {
2487 io_avail = &pci_bus_res
2488 [res_bus].io_avail;
2489 break;
2495 * first pass - gather what's there
2496 * update/second pass - adjust/allocate regions
2497 * config - allocate regions
2499 if (config_op == CONFIG_INFO) { /* first pass */
2500 /* take out of the resource map of the bus */
2501 if (base != 0) {
2502 (void) memlist_remove(io_avail, base,
2503 len);
2504 memlist_insert(io_used, base, len);
2505 } else {
2506 reprogram = 1;
2508 pci_bus_res[bus].io_size += len;
2509 } else if ((*io_avail && base == 0) ||
2510 pci_bus_res[bus].io_reprogram) {
2511 base = (uint_t)memlist_find(io_avail, len, len);
2512 if (base != 0) {
2513 memlist_insert(io_used, base, len);
2514 /* XXX need to worry about 64-bit? */
2515 pci_putl(bus, dev, func, offset,
2516 base | type);
2517 base = pci_getl(bus, dev, func, offset);
2518 base &= PCI_BASE_IO_ADDR_M;
2520 if (base == 0) {
2521 cmn_err(CE_WARN, "failed to program"
2522 " IO space [%d/%d/%d] BAR@0x%x"
2523 " length 0x%x",
2524 bus, dev, func, offset, len);
2527 assigned[nasgn].pci_phys_low = base;
2528 nreg++, nasgn++;
2530 } else {
2531 /* memory space */
2532 if ((base & PCI_BASE_TYPE_M) == PCI_BASE_TYPE_ALL) {
2533 bar_sz = PCI_BAR_SZ_64;
2534 base_hi = pci_getl(bus, dev, func, offset + 4);
2535 phys_hi = PCI_ADDR_MEM64;
2536 } else {
2537 bar_sz = PCI_BAR_SZ_32;
2538 base_hi = 0;
2539 phys_hi = PCI_ADDR_MEM32;
2542 /* skip base regs with size of 0 */
2543 value &= PCI_BASE_M_ADDR_M;
2545 if (value == 0)
2546 continue;
2548 len = ((value ^ (value-1)) + 1) >> 1;
2549 regs[nreg].pci_size_low =
2550 assigned[nasgn].pci_size_low = len;
2552 phys_hi |= (devloc | offset);
2553 if (base & PCI_BASE_PREF_M)
2554 phys_hi |= PCI_PREFETCH_B;
2557 * A device under a subtractive PPB can allocate
2558 * resources from its parent bus if there is no resource
2559 * available on its own bus.
2561 if ((config_op == CONFIG_NEW) && (*mem_avail == NULL)) {
2562 res_bus = bus;
2563 while (pci_bus_res[res_bus].subtractive) {
2564 res_bus = pci_bus_res[res_bus].par_bus;
2565 if (res_bus == (uchar_t)-1)
2566 break; /* root bus already */
2567 mem_avail =
2568 &pci_bus_res[res_bus].mem_avail;
2569 pmem_avail =
2570 &pci_bus_res [res_bus].pmem_avail;
2572 * Break out as long as at least
2573 * mem_avail is available
2575 if ((*pmem_avail &&
2576 (phys_hi & PCI_PREFETCH_B)) ||
2577 *mem_avail)
2578 break;
2582 regs[nreg].pci_phys_hi =
2583 assigned[nasgn].pci_phys_hi = phys_hi;
2584 assigned[nasgn].pci_phys_hi |= PCI_RELOCAT_B;
2585 assigned[nasgn].pci_phys_mid = base_hi;
2586 type = base & ~PCI_BASE_M_ADDR_M;
2587 base &= PCI_BASE_M_ADDR_M;
2589 if (config_op == CONFIG_INFO) {
2590 /* take out of the resource map of the bus */
2591 if (base != NULL) {
2592 /* remove from PMEM and MEM space */
2593 (void) memlist_remove(mem_avail,
2594 base, len);
2595 (void) memlist_remove(pmem_avail,
2596 base, len);
2597 /* only note as used in correct map */
2598 if (phys_hi & PCI_PREFETCH_B)
2599 memlist_insert(pmem_used,
2600 base, len);
2601 else
2602 memlist_insert(mem_used,
2603 base, len);
2604 } else {
2605 reprogram = 1;
2607 pci_bus_res[bus].mem_size += len;
2608 } else if ((*mem_avail && base == NULL) ||
2609 pci_bus_res[bus].mem_reprogram) {
2611 * When desired, attempt a prefetchable
2612 * allocation first
2614 if (phys_hi & PCI_PREFETCH_B) {
2615 base = (uint_t)memlist_find(pmem_avail,
2616 len, len);
2617 if (base != NULL) {
2618 memlist_insert(pmem_used,
2619 base, len);
2620 (void) memlist_remove(mem_avail,
2621 base, len);
2625 * If prefetchable allocation was not
2626 * desired, or failed, attempt ordinary
2627 * memory allocation
2629 if (base == NULL) {
2630 base = (uint_t)memlist_find(mem_avail,
2631 len, len);
2632 if (base != NULL) {
2633 memlist_insert(mem_used,
2634 base, len);
2635 (void) memlist_remove(
2636 pmem_avail, base, len);
2639 if (base != NULL) {
2640 pci_putl(bus, dev, func, offset,
2641 base | type);
2642 base = pci_getl(bus, dev, func, offset);
2643 base &= PCI_BASE_M_ADDR_M;
2644 } else
2645 cmn_err(CE_WARN, "failed to program "
2646 "mem space [%d/%d/%d] BAR@0x%x"
2647 " length 0x%x",
2648 bus, dev, func, offset, len);
2650 assigned[nasgn].pci_phys_low = base;
2651 nreg++, nasgn++;
2654 switch (header) {
2655 case PCI_HEADER_ZERO:
2656 offset = PCI_CONF_ROM;
2657 break;
2658 case PCI_HEADER_PPB:
2659 offset = PCI_BCNF_ROM;
2660 break;
2661 default: /* including PCI_HEADER_CARDBUS */
2662 goto done;
2666 * Add the expansion rom memory space
2667 * Determine the size of the ROM base reg; don't write reserved bits
2668 * ROM isn't in the PCI memory space.
2670 base = pci_getl(bus, dev, func, offset);
2671 pci_putl(bus, dev, func, offset, PCI_BASE_ROM_ADDR_M);
2672 value = pci_getl(bus, dev, func, offset);
2673 pci_putl(bus, dev, func, offset, base);
2674 if (value & PCI_BASE_ROM_ENABLE)
2675 value &= PCI_BASE_ROM_ADDR_M;
2676 else
2677 value = 0;
2679 if (value != 0) {
2680 regs[nreg].pci_phys_hi = (PCI_ADDR_MEM32 | devloc) + offset;
2681 assigned[nasgn].pci_phys_hi = (PCI_RELOCAT_B |
2682 PCI_ADDR_MEM32 | devloc) + offset;
2683 base &= PCI_BASE_ROM_ADDR_M;
2684 assigned[nasgn].pci_phys_low = base;
2685 len = ((value ^ (value-1)) + 1) >> 1;
2686 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = len;
2687 nreg++, nasgn++;
2688 /* take it out of the memory resource */
2689 if (base != NULL) {
2690 (void) memlist_remove(mem_avail, base, len);
2691 memlist_insert(mem_used, base, len);
2692 pci_bus_res[bus].mem_size += len;
2697 * Account for "legacy" (alias) video adapter resources
2700 /* add the three hard-decode, aliased address spaces for VGA */
2701 if ((baseclass == PCI_CLASS_DISPLAY && subclass == PCI_DISPLAY_VGA) ||
2702 (baseclass == PCI_CLASS_NONE && subclass == PCI_NONE_VGA)) {
2704 /* VGA hard decode 0x3b0-0x3bb */
2705 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi =
2706 (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc);
2707 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x3b0;
2708 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0xc;
2709 nreg++, nasgn++;
2710 (void) memlist_remove(io_avail, 0x3b0, 0xc);
2711 memlist_insert(io_used, 0x3b0, 0xc);
2712 pci_bus_res[bus].io_size += 0xc;
2714 /* VGA hard decode 0x3c0-0x3df */
2715 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi =
2716 (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc);
2717 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x3c0;
2718 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0x20;
2719 nreg++, nasgn++;
2720 (void) memlist_remove(io_avail, 0x3c0, 0x20);
2721 memlist_insert(io_used, 0x3c0, 0x20);
2722 pci_bus_res[bus].io_size += 0x20;
2724 /* Video memory */
2725 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi =
2726 (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_MEM32 | devloc);
2727 regs[nreg].pci_phys_low =
2728 assigned[nasgn].pci_phys_low = 0xa0000;
2729 regs[nreg].pci_size_low =
2730 assigned[nasgn].pci_size_low = 0x20000;
2731 nreg++, nasgn++;
2732 /* remove from MEM and PMEM space */
2733 (void) memlist_remove(mem_avail, 0xa0000, 0x20000);
2734 (void) memlist_remove(pmem_avail, 0xa0000, 0x20000);
2735 memlist_insert(mem_used, 0xa0000, 0x20000);
2736 pci_bus_res[bus].mem_size += 0x20000;
2739 /* add the hard-decode, aliased address spaces for 8514 */
2740 if ((baseclass == PCI_CLASS_DISPLAY) &&
2741 (subclass == PCI_DISPLAY_VGA) &&
2742 (progclass & PCI_DISPLAY_IF_8514)) {
2744 /* hard decode 0x2e8 */
2745 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi =
2746 (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc);
2747 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x2e8;
2748 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0x1;
2749 nreg++, nasgn++;
2750 (void) memlist_remove(io_avail, 0x2e8, 0x1);
2751 memlist_insert(io_used, 0x2e8, 0x1);
2752 pci_bus_res[bus].io_size += 0x1;
2754 /* hard decode 0x2ea-0x2ef */
2755 regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi =
2756 (PCI_RELOCAT_B | PCI_ALIAS_B | PCI_ADDR_IO | devloc);
2757 regs[nreg].pci_phys_low = assigned[nasgn].pci_phys_low = 0x2ea;
2758 regs[nreg].pci_size_low = assigned[nasgn].pci_size_low = 0x6;
2759 nreg++, nasgn++;
2760 (void) memlist_remove(io_avail, 0x2ea, 0x6);
2761 memlist_insert(io_used, 0x2ea, 0x6);
2762 pci_bus_res[bus].io_size += 0x6;
2765 done:
2766 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "reg",
2767 (int *)regs, nreg * sizeof (pci_regspec_t) / sizeof (int));
2768 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
2769 "assigned-addresses",
2770 (int *)assigned, nasgn * sizeof (pci_regspec_t) / sizeof (int));
2772 return (reprogram);
2775 static void
2776 add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
2777 int pciex, ushort_t is_pci_bridge)
2779 char *dev_type;
2780 int i;
2781 uint_t val;
2782 uint64_t 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;
2787 ASSERT(secbus <= subbus);
2790 * Check if it's a subtractive PPB.
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;
2797 * Some BIOSes lie about max pci busses, we allow for
2798 * such mistakes here
2800 if (subbus > pci_bios_maxbus) {
2801 pci_bios_maxbus = subbus;
2802 alloc_res_array();
2805 ASSERT(pci_bus_res[secbus].dip == NULL);
2806 pci_bus_res[secbus].dip = dip;
2807 pci_bus_res[secbus].par_bus = bus;
2809 dev_type = (pciex && !is_pci_bridge) ? "pciex" : "pci";
2811 /* setup bus number hierarchy */
2812 pci_bus_res[secbus].sub_bus = subbus;
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).
2818 if (subbus > pci_bus_res[bus].sub_bus)
2819 pci_bus_res[bus].sub_bus = subbus;
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.)
2828 for (i = secbus + 1; i <= subbus; i++)
2829 pci_bus_res[i].par_bus = bus;
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);
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.
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.
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
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 & PCI_BCNF_IO_MASK) << PCI_BCNF_IO_SHIFT);
2866 val = (uint_t)pci_getb(bus, dev, func, PCI_BCNF_IO_LIMIT_LOW);
2867 io_range[1] = ((val & PCI_BCNF_IO_MASK) << PCI_BCNF_IO_SHIFT) |
2868 0xfff;
2869 if ((io_range[0] & PCI_BCNF_ADDR_MASK) == PCI_BCNF_IO_32BIT) {
2870 uint16_t io_base_hi, io_limit_hi;
2871 io_base_hi = pci_getw(bus, dev, func,
2872 PCI_BCNF_IO_BASE_HI);
2873 io_limit_hi = pci_getw(bus, dev, func,
2874 PCI_BCNF_IO_LIMIT_HI);
2876 io_range[0] |= (uint32_t)io_base_hi << 16;
2877 io_range[1] |= (uint32_t)io_limit_hi << 16;
2879 } else {
2880 io_range[0] = 0x9fff;
2881 io_range[1] = 0x1000;
2882 pci_putb(bus, dev, func, PCI_BCNF_IO_BASE_LOW,
2883 (uint8_t)((io_range[0] >> 8) & 0xf0));
2884 pci_putb(bus, dev, func, PCI_BCNF_IO_LIMIT_LOW,
2885 (uint8_t)((io_range[1] >> 8) & 0xf0));
2886 pci_putw(bus, dev, func, PCI_BCNF_IO_BASE_HI, 0);
2887 pci_putw(bus, dev, func, PCI_BCNF_IO_LIMIT_HI, 0);
2890 if (io_range[0] != 0 && io_range[0] < io_range[1]) {
2891 memlist_insert(&pci_bus_res[secbus].io_avail,
2892 io_range[0], (io_range[1] - io_range[0] + 1));
2893 memlist_insert(&pci_bus_res[bus].io_used,
2894 io_range[0], (io_range[1] - io_range[0] + 1));
2895 if (pci_bus_res[bus].io_avail != NULL) {
2896 (void) memlist_remove(&pci_bus_res[bus].io_avail,
2897 io_range[0], (io_range[1] - io_range[0] + 1));
2899 dcmn_err(CE_NOTE, "bus %d io-range: 0x%" PRIx64 "-%" PRIx64,
2900 secbus, io_range[0], io_range[1]);
2903 /* mem range */
2904 val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_MEM_BASE);
2905 mem_range[0] = ((val & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT);
2906 val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_MEM_LIMIT);
2907 mem_range[1] = ((val & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT) |
2908 0xfffff;
2909 if (mem_range[0] != 0 && mem_range[0] < mem_range[1]) {
2910 memlist_insert(&pci_bus_res[secbus].mem_avail,
2911 (uint64_t)mem_range[0],
2912 (uint64_t)(mem_range[1] - mem_range[0] + 1));
2913 memlist_insert(&pci_bus_res[bus].mem_used,
2914 (uint64_t)mem_range[0],
2915 (uint64_t)(mem_range[1] - mem_range[0] + 1));
2916 /* remove from parent resource list */
2917 (void) memlist_remove(&pci_bus_res[bus].mem_avail,
2918 (uint64_t)mem_range[0],
2919 (uint64_t)(mem_range[1] - mem_range[0] + 1));
2920 (void) memlist_remove(&pci_bus_res[bus].pmem_avail,
2921 (uint64_t)mem_range[0],
2922 (uint64_t)(mem_range[1] - mem_range[0] + 1));
2923 dcmn_err(CE_NOTE, "bus %d mem-range: 0x%" PRIx64 "-%" PRIx64,
2924 secbus, mem_range[0], mem_range[1]);
2927 /* prefetchable memory range */
2928 val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_BASE_LOW);
2929 pmem_range[0] = ((val & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT);
2930 val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_LIMIT_LOW);
2931 pmem_range[1] = ((val & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT) |
2932 0xfffff;
2933 if ((pmem_range[0] & PCI_BCNF_ADDR_MASK) == PCI_BCNF_PF_MEM_64BIT) {
2934 uint32_t pf_addr_hi, pf_limit_hi;
2935 pf_addr_hi = pci_getl(bus, dev, func, PCI_BCNF_PF_BASE_HIGH);
2936 pf_limit_hi = pci_getl(bus, dev, func, PCI_BCNF_PF_LIMIT_HIGH);
2937 pmem_range[0] |= (uint64_t)pf_addr_hi << 32;
2938 pmem_range[1] |= (uint64_t)pf_limit_hi << 32;
2940 if (pmem_range[0] != 0 && pmem_range[0] < pmem_range[1]) {
2941 memlist_insert(&pci_bus_res[secbus].pmem_avail,
2942 (uint64_t)pmem_range[0],
2943 (uint64_t)(pmem_range[1] - pmem_range[0] + 1));
2944 memlist_insert(&pci_bus_res[bus].pmem_used,
2945 (uint64_t)pmem_range[0],
2946 (uint64_t)(pmem_range[1] - pmem_range[0] + 1));
2947 /* remove from parent resource list */
2948 (void) memlist_remove(&pci_bus_res[bus].pmem_avail,
2949 (uint64_t)pmem_range[0],
2950 (uint64_t)(pmem_range[1] - pmem_range[0] + 1));
2951 (void) memlist_remove(&pci_bus_res[bus].mem_avail,
2952 (uint64_t)pmem_range[0],
2953 (uint64_t)(pmem_range[1] - pmem_range[0] + 1));
2954 dcmn_err(CE_NOTE, "bus %d pmem-range: 0x%" PRIx64 "-%" PRIx64,
2955 secbus, pmem_range[0], pmem_range[1]);
2959 * Add VGA legacy resources to the bridge's pci_bus_res if it
2960 * has VGA_ENABLE set. Note that we put them in 'avail',
2961 * because that's used to populate the ranges prop; they'll be
2962 * removed from there by the VGA device once it's found. Also,
2963 * remove them from the parent's available list and note them as
2964 * used in the parent.
2967 if (pci_getw(bus, dev, func, PCI_BCNF_BCNTRL) &
2968 PCI_BCNF_BCNTRL_VGA_ENABLE) {
2970 memlist_insert(&pci_bus_res[secbus].io_avail, 0x3b0, 0xc);
2972 memlist_insert(&pci_bus_res[bus].io_used, 0x3b0, 0xc);
2973 if (pci_bus_res[bus].io_avail != NULL) {
2974 (void) memlist_remove(&pci_bus_res[bus].io_avail,
2975 0x3b0, 0xc);
2978 memlist_insert(&pci_bus_res[secbus].io_avail, 0x3c0, 0x20);
2980 memlist_insert(&pci_bus_res[bus].io_used, 0x3c0, 0x20);
2981 if (pci_bus_res[bus].io_avail != NULL) {
2982 (void) memlist_remove(&pci_bus_res[bus].io_avail,
2983 0x3c0, 0x20);
2986 memlist_insert(&pci_bus_res[secbus].mem_avail, 0xa0000,
2987 0x20000);
2989 memlist_insert(&pci_bus_res[bus].mem_used, 0xa0000, 0x20000);
2990 if (pci_bus_res[bus].mem_avail != NULL) {
2991 (void) memlist_remove(&pci_bus_res[bus].mem_avail,
2992 0xa0000, 0x20000);
2995 add_bus_range_prop(secbus);
2996 add_ranges_prop(secbus, 1);
2999 extern const struct pci_class_strings_s class_pci[];
3000 extern int class_pci_items;
3002 static void
3003 add_model_prop(dev_info_t *dip, uint_t classcode)
3005 const char *desc;
3006 int i;
3007 uchar_t baseclass = classcode >> 16;
3008 uchar_t subclass = (classcode >> 8) & 0xff;
3009 uchar_t progclass = classcode & 0xff;
3011 if ((baseclass == PCI_CLASS_MASS) && (subclass == PCI_MASS_IDE)) {
3012 desc = "IDE controller";
3013 } else {
3014 for (desc = 0, i = 0; i < class_pci_items; i++) {
3015 if ((baseclass == class_pci[i].base_class) &&
3016 (subclass == class_pci[i].sub_class) &&
3017 (progclass == class_pci[i].prog_class)) {
3018 desc = class_pci[i].actual_desc;
3019 break;
3022 if (i == class_pci_items)
3023 desc = "Unknown class of pci/pnpbios device";
3026 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "model",
3027 (char *)desc);
3030 static void
3031 add_bus_range_prop(int bus)
3033 int bus_range[2];
3035 if (pci_bus_res[bus].dip == NULL)
3036 return;
3037 bus_range[0] = bus;
3038 bus_range[1] = pci_bus_res[bus].sub_bus;
3039 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, pci_bus_res[bus].dip,
3040 "bus-range", (int *)bus_range, 2);
3044 * Add slot-names property for any named pci hot-plug slots
3046 static void
3047 add_bus_slot_names_prop(int bus)
3049 char slotprop[256];
3050 int len;
3051 extern int pci_irq_nroutes;
3052 char *slotcap_name;
3055 * If no irq routing table, then go with the slot-names as set up
3056 * in pciex_slot_names_prop() from slot capability register (if any).
3058 if (pci_irq_nroutes == 0)
3059 return;
3062 * Otherise delete the slot-names we already have and use the irq
3063 * routing table values as returned by pci_slot_names_prop() instead,
3064 * but keep any property of value "pcie0" as that can't be represented
3065 * in the irq routing table.
3067 if (pci_bus_res[bus].dip != NULL) {
3068 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pci_bus_res[bus].dip,
3069 DDI_PROP_DONTPASS, "slot-names", &slotcap_name) !=
3070 DDI_SUCCESS || strcmp(slotcap_name, "pcie0") != 0)
3071 (void) ndi_prop_remove(DDI_DEV_T_NONE,
3072 pci_bus_res[bus].dip, "slot-names");
3075 len = pci_slot_names_prop(bus, slotprop, sizeof (slotprop));
3076 if (len > 0) {
3078 * Only create a peer bus node if this bus may be a peer bus.
3079 * It may be a peer bus if the dip is NULL and if par_bus is
3080 * -1 (par_bus is -1 if this bus was not found to be
3081 * subordinate to any PCI-PCI bridge).
3082 * If it's not a peer bus, then the ACPI BBN-handling code
3083 * will remove it later.
3085 if (pci_bus_res[bus].par_bus == (uchar_t)-1 &&
3086 pci_bus_res[bus].dip == NULL) {
3088 create_root_bus_dip(bus);
3090 if (pci_bus_res[bus].dip != NULL) {
3091 ASSERT((len % sizeof (int)) == 0);
3092 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
3093 pci_bus_res[bus].dip, "slot-names",
3094 (int *)slotprop, len / sizeof (int));
3095 } else {
3096 cmn_err(CE_NOTE, "!BIOS BUG: Invalid bus number in PCI "
3097 "IRQ routing table; Not adding slot-names "
3098 "property for incorrect bus %d", bus);
3104 * Handle both PCI root and PCI-PCI bridge range properties;
3105 * non-zero 'ppb' argument select PCI-PCI bridges versus root.
3107 static void
3108 memlist_to_ranges(void **rp, struct memlist *entry, uint_t type, int ppb)
3110 ppb_ranges_t *ppb_rp = *rp;
3111 pci_ranges_t *pci_rp = *rp;
3113 while (entry != NULL) {
3114 uint_t atype = type;
3115 if ((type & PCI_REG_ADDR_M) == PCI_ADDR_MEM32 &&
3116 (entry->ml_address >= UINT32_MAX ||
3117 entry->ml_size >= UINT32_MAX)) {
3118 atype &= ~PCI_ADDR_MEM32;
3119 atype |= PCI_ADDR_MEM64;
3121 if (ppb) {
3122 ppb_rp->child_high = ppb_rp->parent_high = atype;
3123 ppb_rp->child_mid = ppb_rp->parent_mid =
3124 (uint32_t)(entry->ml_address >> 32);
3125 ppb_rp->child_low = ppb_rp->parent_low =
3126 (uint32_t)entry->ml_address;
3127 ppb_rp->size_high =
3128 (uint32_t)(entry->ml_size >> 32);
3129 ppb_rp->size_low = (uint32_t)entry->ml_size;
3130 *rp = ++ppb_rp;
3131 } else {
3132 pci_rp->child_high = atype;
3133 pci_rp->child_mid = pci_rp->parent_high =
3134 (uint32_t)(entry->ml_address >> 32);
3135 pci_rp->child_low = pci_rp->parent_low =
3136 (uint32_t)entry->ml_address;
3137 pci_rp->size_high =
3138 (uint32_t)(entry->ml_size >> 32);
3139 pci_rp->size_low = (uint32_t)entry->ml_size;
3140 *rp = ++pci_rp;
3142 entry = entry->ml_next;
3146 static void
3147 add_ranges_prop(int bus, int ppb)
3149 int total, alloc_size;
3150 void *rp, *next_rp;
3151 struct memlist *iolist, *memlist, *pmemlist;
3153 /* no devinfo node - unused bus, return */
3154 if (pci_bus_res[bus].dip == NULL)
3155 return;
3157 iolist = memlist = pmemlist = (struct memlist *)NULL;
3159 memlist_merge(&pci_bus_res[bus].io_avail, &iolist);
3160 memlist_merge(&pci_bus_res[bus].io_used, &iolist);
3161 memlist_merge(&pci_bus_res[bus].mem_avail, &memlist);
3162 memlist_merge(&pci_bus_res[bus].mem_used, &memlist);
3163 memlist_merge(&pci_bus_res[bus].pmem_avail, &pmemlist);
3164 memlist_merge(&pci_bus_res[bus].pmem_used, &pmemlist);
3166 total = memlist_count(iolist);
3167 total += memlist_count(memlist);
3168 total += memlist_count(pmemlist);
3170 /* no property is created if no ranges are present */
3171 if (total == 0)
3172 return;
3174 alloc_size = total *
3175 (ppb ? sizeof (ppb_ranges_t) : sizeof (pci_ranges_t));
3177 next_rp = rp = kmem_alloc(alloc_size, KM_SLEEP);
3179 memlist_to_ranges(&next_rp, iolist, PCI_ADDR_IO | PCI_REG_REL_M, ppb);
3180 memlist_to_ranges(&next_rp, memlist,
3181 PCI_ADDR_MEM32 | PCI_REG_REL_M, ppb);
3182 memlist_to_ranges(&next_rp, pmemlist,
3183 PCI_ADDR_MEM32 | PCI_REG_REL_M | PCI_REG_PF_M, ppb);
3185 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, pci_bus_res[bus].dip,
3186 "ranges", (int *)rp, alloc_size / sizeof (int));
3188 kmem_free(rp, alloc_size);
3189 memlist_free_all(&iolist);
3190 memlist_free_all(&memlist);
3191 memlist_free_all(&pmemlist);
3194 static void
3195 memlist_remove_list(struct memlist **list, struct memlist *remove_list)
3197 while (list && *list && remove_list) {
3198 (void) memlist_remove(list, remove_list->ml_address,
3199 remove_list->ml_size);
3200 remove_list = remove_list->ml_next;
3204 static int
3205 memlist_to_spec(struct pci_phys_spec *sp, struct memlist *list, int type)
3207 int i = 0;
3209 while (list) {
3210 /* assume 32-bit addresses */
3211 sp->pci_phys_hi = type;
3212 sp->pci_phys_mid = 0;
3213 sp->pci_phys_low = (uint32_t)list->ml_address;
3214 sp->pci_size_hi = 0;
3215 sp->pci_size_low = (uint32_t)list->ml_size;
3217 list = list->ml_next;
3218 sp++, i++;
3220 return (i);
3223 static void
3224 add_bus_available_prop(int bus)
3226 int i, count;
3227 struct pci_phys_spec *sp;
3229 /* no devinfo node - unused bus, return */
3230 if (pci_bus_res[bus].dip == NULL)
3231 return;
3233 count = memlist_count(pci_bus_res[bus].io_avail) +
3234 memlist_count(pci_bus_res[bus].mem_avail) +
3235 memlist_count(pci_bus_res[bus].pmem_avail);
3237 if (count == 0) /* nothing available */
3238 return;
3240 sp = kmem_alloc(count * sizeof (*sp), KM_SLEEP);
3241 i = memlist_to_spec(&sp[0], pci_bus_res[bus].io_avail,
3242 PCI_ADDR_IO | PCI_REG_REL_M);
3243 i += memlist_to_spec(&sp[i], pci_bus_res[bus].mem_avail,
3244 PCI_ADDR_MEM32 | PCI_REG_REL_M);
3245 i += memlist_to_spec(&sp[i], pci_bus_res[bus].pmem_avail,
3246 PCI_ADDR_MEM32 | PCI_REG_REL_M | PCI_REG_PF_M);
3247 ASSERT(i == count);
3249 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, pci_bus_res[bus].dip,
3250 "available", (int *)sp,
3251 i * sizeof (struct pci_phys_spec) / sizeof (int));
3252 kmem_free(sp, count * sizeof (*sp));
3255 static void
3256 alloc_res_array(void)
3258 static int array_size = 0;
3259 int old_size;
3260 void *old_res;
3262 if (array_size > pci_bios_maxbus + 1)
3263 return; /* array is big enough */
3265 old_size = array_size;
3266 old_res = pci_bus_res;
3268 if (array_size == 0)
3269 array_size = 16; /* start with a reasonable number */
3271 while (array_size <= pci_bios_maxbus + 1)
3272 array_size <<= 1;
3273 pci_bus_res = (struct pci_bus_resource *)kmem_zalloc(
3274 array_size * sizeof (struct pci_bus_resource), KM_SLEEP);
3276 if (old_res) { /* copy content and free old array */
3277 bcopy(old_res, pci_bus_res,
3278 old_size * sizeof (struct pci_bus_resource));
3279 kmem_free(old_res, old_size * sizeof (struct pci_bus_resource));
3283 static void
3284 create_ioapic_node(int bus, int dev, int fn, ushort_t vendorid,
3285 ushort_t deviceid)
3287 static dev_info_t *ioapicsnode = NULL;
3288 static int numioapics = 0;
3289 dev_info_t *ioapic_node;
3290 uint64_t physaddr;
3291 uint32_t lobase, hibase = 0;
3293 /* BAR 0 contains the IOAPIC's memory-mapped I/O address */
3294 lobase = (*pci_getl_func)(bus, dev, fn, PCI_CONF_BASE0);
3296 /* We (and the rest of the world) only support memory-mapped IOAPICs */
3297 if ((lobase & PCI_BASE_SPACE_M) != PCI_BASE_SPACE_MEM)
3298 return;
3300 if ((lobase & PCI_BASE_TYPE_M) == PCI_BASE_TYPE_ALL)
3301 hibase = (*pci_getl_func)(bus, dev, fn, PCI_CONF_BASE0 + 4);
3303 lobase &= PCI_BASE_M_ADDR_M;
3305 physaddr = (((uint64_t)hibase) << 32) | lobase;
3308 * Create a nexus node for all IOAPICs under the root node.
3310 if (ioapicsnode == NULL) {
3311 if (ndi_devi_alloc(ddi_root_node(), IOAPICS_NODE_NAME,
3312 (pnode_t)DEVI_SID_NODEID, &ioapicsnode) != NDI_SUCCESS) {
3313 return;
3315 (void) ndi_devi_online(ioapicsnode, 0);
3319 * Create a child node for this IOAPIC
3321 ioapic_node = ddi_add_child(ioapicsnode, IOAPICS_CHILD_NAME,
3322 DEVI_SID_NODEID, numioapics++);
3323 if (ioapic_node == NULL) {
3324 return;
3327 /* Vendor and Device ID */
3328 (void) ndi_prop_update_int(DDI_DEV_T_NONE, ioapic_node,
3329 IOAPICS_PROP_VENID, vendorid);
3330 (void) ndi_prop_update_int(DDI_DEV_T_NONE, ioapic_node,
3331 IOAPICS_PROP_DEVID, deviceid);
3333 /* device_type */
3334 (void) ndi_prop_update_string(DDI_DEV_T_NONE, ioapic_node,
3335 "device_type", IOAPICS_DEV_TYPE);
3337 /* reg */
3338 (void) ndi_prop_update_int64(DDI_DEV_T_NONE, ioapic_node,
3339 "reg", physaddr);
3343 * NOTE: For PCIe slots, the name is generated from the slot number
3344 * information obtained from Slot Capabilities register.
3345 * For non-PCIe slots, it is generated based on the slot number
3346 * information in the PCI IRQ table.
3348 static void
3349 pciex_slot_names_prop(dev_info_t *dip, ushort_t slot_num)
3351 char slotprop[256];
3352 int len;
3354 bzero(slotprop, sizeof (slotprop));
3356 /* set mask to 1 as there is only one slot (i.e dev 0) */
3357 *(uint32_t *)slotprop = 1;
3358 len = 4;
3359 (void) snprintf(slotprop + len, sizeof (slotprop) - len, "pcie%d",
3360 slot_num);
3361 len += strlen(slotprop + len) + 1;
3362 len += len % 4;
3363 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "slot-names",
3364 (int *)slotprop, len / sizeof (int));
3368 * Enable reporting of AER capability next pointer.
3369 * This needs to be done only for CK8-04 devices
3370 * by setting NV_XVR_VEND_CYA1 (offset 0xf40) bit 13
3371 * NOTE: BIOS is disabling this, it needs to be enabled temporarily
3373 * This function is adapted from npe_ck804_fix_aer_ptr(), and is
3374 * called from pci_boot.c.
3376 static void
3377 ck804_fix_aer_ptr(dev_info_t *dip, pcie_req_id_t bdf)
3379 dev_info_t *rcdip;
3380 ushort_t cya1;
3382 rcdip = pcie_get_rc_dip(dip);
3383 ASSERT(rcdip != NULL);
3385 if ((pci_cfgacc_get16(rcdip, bdf, PCI_CONF_VENID) ==
3386 NVIDIA_VENDOR_ID) &&
3387 (pci_cfgacc_get16(rcdip, bdf, PCI_CONF_DEVID) ==
3388 NVIDIA_CK804_DEVICE_ID) &&
3389 (pci_cfgacc_get8(rcdip, bdf, PCI_CONF_REVID) >=
3390 NVIDIA_CK804_AER_VALID_REVID)) {
3391 cya1 = pci_cfgacc_get16(rcdip, bdf, NVIDIA_CK804_VEND_CYA1_OFF);
3392 if (!(cya1 & ~NVIDIA_CK804_VEND_CYA1_ERPT_MASK))
3393 (void) pci_cfgacc_put16(rcdip, bdf,
3394 NVIDIA_CK804_VEND_CYA1_OFF,
3395 cya1 | NVIDIA_CK804_VEND_CYA1_ERPT_VAL);