2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
13 * Copyright 2024 Oxide Computer company
17 * This file consolidates the basic devinfo properties that exist in the system
18 * for PCI and PCI Express devices and attempts to ensure that there is only one
19 * place to set these items. There are a bunch of different historical
20 * considerations that are taken into account here.
22 * PCI Compatible Aliases
23 * ----------------------
25 * The set of aliases that we put on devices is used in the 'compatible'
26 * property to attach device drivers to nodes. These are ordered from more
27 * specific aliases to less specific aliases. The original set of aliases that
28 * was used was defined by Open Firmware for PCI and discussed in the PCI and
29 * later the PCI Express bindings as part of IEEE 1275. Originally those
30 * bindings consisted of aliases which we could describe as:
32 * pci<vendor id>,<device id>.<subsystem vendor>.<subsytem id>.<revision>
33 * pci<vendor id>,<device id>.<subsystem vendor>.<subsytem id>
34 * pci<subsystem vendor>,<subsytem id>
35 * pci<vendor id>,<device id>.<revision>
36 * pci<vendor id>,<device id>
37 * pciclass,<class code><subclass><programming interface>
38 * pciclass,<class code><subclass>
40 * When it came time to move to PCI Express, Sun had published a draft document
41 * for how to adopt IEEE 1275 bindings to PCI Express. Most notably it dropped
42 * the pci<subsystem vendor>.<subsytem id> entry and instead prefixed everything
43 * with 'pciex' instead of 'pci'. The reason that this was dropped was because
44 * of the fact that while the early days assumed that subsystem IDs were in a
45 * shared namespace with device IDs, they ended up overlapping and therefore
46 * have not proven to be unique. Because that ID syntax overlapped with
47 * pci<vendor id>,<device id> this has led to problems where IDs are reused and
48 * incorrect bindings occur. We already maintain a deny list where there are
51 * To deal with the ambiguity here while trying to avoid the challenges of the
52 * figuring out what IDs were meant to be subsystem IDs and which were primary
53 * IDs (a non-obvious task given that some device drivers are almost exclusively
54 * identified by standalone subsystem IDs -- see smrt(4D) and cpqary3(4D)), we
55 * added two additional aliases for PCI (but not PCI Express) that allow drivers
56 * to express what we call disambiguated IDs. These take the form:
58 * pci<subsystem vendor>,<subsystem id>,s
59 * pci<vendor id>,<device id>,p
61 * Were that this was our only challenge. The next bit that we have to deal with
62 * is another artifact of history. While Sun proposed the different PCIe
63 * bindings in a draft, the original intent was just that the aliases would all
64 * take the form of 'pciex' as above and that was it. However, the x86
65 * implementation didn't actually roll with the plan. Instead, it placed the set
66 * of PCI Express aliases and then followed it with the traditional PCI aliases.
67 * As such, they have double the aliases. We still maintain this on x86, but do
68 * not extend the double aliases to other platforms. Because these are specific
69 * to the platform and not the instruction set architecture, whether this is
70 * required or not is indicated by the PCI PRD compat flags interface
71 * pci_prd_compat_flags().
73 * The last current wrinkle here is that of bridge IDs. Originally PCI bridges
74 * didn't have any form of subsystem ID defined. In the PCI-PCI bridge
75 * specification version 1.2, published in 2003, they eventually added an
76 * optional capability to define a bridge's subsystem. This meant that for most
77 * of PCI's existence this did not exist. In particular, until 2023 we did not
78 * try to search for the capability and add it to a device's compatible
79 * properties. Because of this lapse and having to deal with the above ID
80 * disambiguation, we only add the disambiguated ,s subsystem ID for PCI. Both
81 * PCI Express and PCI still have the fully qualified subsystem IDs added for
84 * Our final set of aliases that we assign to all nodes is in the table below
85 * called 'pci_alias_table'. This table has flags which control the behavior of
86 * the ID generation. To summarize what a platform can control is:
88 * o Whether or not both PCIe and PCI aliases are generated. This is
89 * controlled via PCI_PRD_COMPAT_PCI_NODE_NAME which also influences the
91 * o For PCI, whether or not we should generate the ambiguous subsystem ID
92 * alias. This is controlled by PCI_PRD_COMPAT_SUBSYS. We will always
93 * generate the disambiguated IDs for PCI to stick with IEEE 1275
94 * expectations across the system. PCI Express will not generate either of
95 * the standalone subsystem ID forms.
100 * When we name devinfo names we generally do so in the form <type><subsystem
101 * vendor id>,<subsystem id>. If there is no subsystem ID then we use
102 * <type><vendor id>,<device id>. Type 1 headers do not have a subsystem ID.
103 * They are instead found in an optional capability. Type 0 headers do have a
104 * subsystem ID. If the subsystem vendor ID is zero, that indicates that the
105 * subsystem ID is not present and we fall back to the vendor and device ID.
107 * x86 is again a land of exceptions. Because we never had subsystem IDs present
108 * for bridges, they always use the vendor and device variant for compatibility
109 * purposes. Similarly, x86 always sets the type to "pci" for compatibility.
110 * Other platforms will set the type to "pciex" if it is a PCI Express device or
113 * Traditionally, node naming was originally driven by the PROM on SPARC which
114 * used IEEE 1275 Open Firmware device class names instead of just the device
115 * IDs that we have settled on. On our platforms there are two exceptions to
116 * this. If we find an ISA compatible system and the PCI PRD indicates that the
117 * platform supports ISA, then we will override that. In addition, a subset of
118 * the display class codes have historically been used to name a device node
121 * Our order for naming device nodes is:
123 * 1. Check for display.
125 * 3. Attempt to use the subsystem.
126 * 4. Fall back to the normal vendor and device.
128 * Platforms can influence this in the following ways:
130 * o ISA is only considered if PCI_PRD_COMPAT_ISA is set.
131 * o Bridges will not use the subsystem IDs if PCI_PRD_COMPAT_SUBSYS is set.
132 * o The node name will always start with "pci" if
133 * PCI_PRD_COMPAT_PCI_NODE_NAME is set.
138 * The unit address for a PCI device has historically been its device number.
139 * For multi-function devices, everything past function zero is the device
140 * number followed by the function number. ARI devices technically don't have a
141 * device number. If we encounter such a device, we just set the device portion
142 * of the unit address to 0.
146 #include <sys/sunddi.h>
147 #include <sys/sunndi.h>
148 #include <sys/cmn_err.h>
150 #include <sys/pcie.h>
151 #include <sys/pci_cfgspace.h>
152 #include <sys/pci_props.h>
153 #include <sys/sysmacros.h>
154 #include <sys/plat/pci_prd.h>
155 #include <pci_strings.h>
159 uint8_t ppc_subclass
;
164 pci_prop_class_match(const pci_prop_data_t
*prop
, const pci_prop_class_t
*class,
165 const size_t nclass
, boolean_t check_pi
)
167 for (size_t i
= 0; i
< nclass
; i
++) {
168 if (prop
->ppd_class
== class[i
].ppc_class
&&
169 prop
->ppd_subclass
== class[i
].ppc_subclass
&&
170 (!check_pi
|| prop
->ppd_pi
== class[i
].ppc_pi
)) {
179 * This is used to determine if a given set of data indicates that we have
180 * encountered a VGA class code which should be given the "display" name. The
181 * following tuples of class, subclass, programming interface are VGA
184 * 0x00, 0x01, 0x00: The pre-class code VGA device
185 * 0x03, 0x00, 0x00: A VGA Compatible controller
186 * 0x03, 0x00, 0x01: A 8514 compatible controller
188 static const pci_prop_class_t pci_prop_vga_classes
[] = {
189 { PCI_CLASS_NONE
, PCI_NONE_VGA
, 0x00 },
190 { PCI_CLASS_DISPLAY
, PCI_DISPLAY_VGA
, PCI_DISPLAY_IF_VGA
},
191 { PCI_CLASS_DISPLAY
, PCI_DISPLAY_VGA
, PCI_DISPLAY_IF_8514
}
194 static const pci_prop_class_t pci_prop_ioapic_classes
[] = {
195 { PCI_CLASS_PERIPH
, PCI_PERIPH_PIC
, PCI_PERIPH_PIC_IF_IO_APIC
},
196 { PCI_CLASS_PERIPH
, PCI_PERIPH_PIC
, PCI_PERIPH_PIC_IF_IOX_APIC
},
199 static const pci_prop_class_t pci_prop_isa_classes
[] = {
200 { PCI_CLASS_BRIDGE
, PCI_BRIDGE_ISA
, 0 }
203 static const pci_prop_class_t pci_prop_pcibridge_classes
[] = {
204 { PCI_CLASS_BRIDGE
, PCI_BRIDGE_PCI
, 0 }
208 pci_prop_class_is_vga(const pci_prop_data_t
*prop
)
210 return (pci_prop_class_match(prop
, pci_prop_vga_classes
,
211 ARRAY_SIZE(pci_prop_vga_classes
), B_TRUE
));
215 pci_prop_class_is_ioapic(const pci_prop_data_t
*prop
)
217 return (pci_prop_class_match(prop
, pci_prop_ioapic_classes
,
218 ARRAY_SIZE(pci_prop_ioapic_classes
), B_TRUE
));
222 * Determine if a class indicates that it is ISA. Technically this should be
223 * checking the programming interface as only PI 0x00 is defined; however, this
224 * is the check that has historically been done and the PCI-SIG is unlikely to
225 * define additional programming interfaces for an ISA bridge.
228 pci_prop_class_is_isa(const pci_prop_data_t
*prop
)
230 return (pci_prop_class_match(prop
, pci_prop_isa_classes
,
231 ARRAY_SIZE(pci_prop_isa_classes
), B_FALSE
));
235 * We don't check the programming class here because callers don't care if this
236 * is subtractive or not.
239 pci_prop_class_is_pcibridge(const pci_prop_data_t
*prop
)
241 return (pci_prop_class_match(prop
, pci_prop_pcibridge_classes
,
242 ARRAY_SIZE(pci_prop_pcibridge_classes
), B_FALSE
));
246 pci_prop_nodename_prefix(const pci_prop_data_t
*prop
,
247 pci_prd_compat_flags_t flags
)
249 if ((flags
& PCI_PRD_COMPAT_PCI_NODE_NAME
) != 0) {
253 if ((prop
->ppd_flags
& PCI_PROP_F_PCIE
) != 0) {
261 pci_prop_use_subsystem(const pci_prop_data_t
*prop
,
262 pci_prd_compat_flags_t flags
)
264 if ((flags
& PCI_PRD_COMPAT_SUBSYS
) != 0 &&
265 prop
->ppd_header
== PCI_HEADER_PPB
) {
269 return (prop
->ppd_subvid
!= 0);
273 * Name a device node per the theory statement.
276 pci_prop_name_node(dev_info_t
*dip
, const pci_prop_data_t
*prop
)
279 pci_prd_compat_flags_t flags
= pci_prd_compat_flags();
281 if (pci_prop_class_is_vga(prop
)) {
282 (void) snprintf(buf
, sizeof (buf
), "display");
283 } else if (pci_prop_class_is_isa(prop
) &&
284 (flags
& PCI_PRD_COMPAT_ISA
) != 0) {
285 (void) snprintf(buf
, sizeof (buf
), "isa");
287 const char *prefix
= pci_prop_nodename_prefix(prop
, flags
);
289 if (pci_prop_use_subsystem(prop
, flags
)) {
290 (void) snprintf(buf
, sizeof (buf
), "%s%x,%x", prefix
,
291 prop
->ppd_subvid
, prop
->ppd_subsys
);
293 (void) snprintf(buf
, sizeof (buf
), "%s%x,%x", prefix
,
294 prop
->ppd_vendid
, prop
->ppd_devid
);
298 if (ndi_devi_set_nodename(dip
, buf
, 0) != NDI_SUCCESS
) {
299 return (PCI_PROP_E_NDI
);
301 return (PCI_PROP_OK
);
305 pci_prop_get8(ddi_acc_handle_t acc
, const pci_prop_data_t
*prop
, uint16_t off
)
308 return ((*pci_getb_func
)(prop
->ppd_bus
, prop
->ppd_dev
,
309 prop
->ppd_func
, off
));
311 return (pci_config_get8(acc
, off
));
316 pci_prop_get16(ddi_acc_handle_t acc
, const pci_prop_data_t
*prop
, uint16_t off
)
319 return ((*pci_getw_func
)(prop
->ppd_bus
, prop
->ppd_dev
,
320 prop
->ppd_func
, off
));
322 return (pci_config_get16(acc
, off
));
327 pci_prop_get32(ddi_acc_handle_t acc
, const pci_prop_data_t
*prop
, uint16_t off
)
330 return ((*pci_getl_func
)(prop
->ppd_bus
, prop
->ppd_dev
,
331 prop
->ppd_func
, off
));
333 return (pci_config_get32(acc
, off
));
337 static pci_prop_failure_t
338 pci_prop_data_fill_pcie(ddi_acc_handle_t acc
, pci_prop_data_t
*prop
,
345 pciecap
= pci_prop_get16(acc
, prop
, cap_base
+ PCIE_PCIECAP
);
346 vers
= pciecap
& PCIE_PCIECAP_VER_MASK
;
348 case PCIE_PCIECAP_VER_1_0
:
349 case PCIE_PCIECAP_VER_2_0
:
352 cmn_err(CE_WARN
, "found device at b/d/f 0x%x/0x%x/0x%x with "
353 "PCIe capability with unsupported capability version: 0x%x",
354 prop
->ppd_bus
, prop
->ppd_dev
, prop
->ppd_func
, vers
);
355 return (PCI_PROP_E_BAD_PCIE_CAP
);
358 prop
->ppd_flags
|= PCI_PROP_F_PCIE
;
359 prop
->ppd_pcie_type
= pciecap
& PCIE_PCIECAP_DEV_TYPE_MASK
;
361 if ((pciecap
& PCIE_PCIECAP_SLOT_IMPL
) == 0) {
362 return (PCI_PROP_OK
);
365 slotcap
= pci_prop_get32(acc
, prop
, cap_base
+ PCIE_SLOTCAP
);
366 prop
->ppd_slotno
= PCIE_SLOTCAP_PHY_SLOT_NUM(slotcap
);
367 prop
->ppd_flags
|= PCI_PROP_F_SLOT_VALID
;
368 return (PCI_PROP_OK
);
372 * Obtain basic information about a device and store it for future processing
373 * and for other code's general usage. This may be called early in boot before
374 * we feel like we should use the normal access routines or later in boot where
375 * the system opts to use normal DDI accesses. We accept either and make do with
378 * We err on the side of trying to be lenient with devices that are potentially
379 * a bit odd. Not all devices in the wild actually follow the spec.
382 pci_prop_data_fill(ddi_acc_handle_t acc
, uint8_t bus
, uint8_t dev
, uint8_t func
,
383 pci_prop_data_t
*prop
)
385 uint8_t htype
, cap_off
, max_cap
= PCI_CAP_MAX_PTR
;
388 bzero(prop
, sizeof (pci_prop_data_t
));
391 prop
->ppd_func
= func
;
394 * To fill this out, begin with getting things that are always going to
395 * be the same between different header types. We check the validity of
396 * the vendor ID as a proxy for hardware being present.
398 prop
->ppd_vendid
= pci_prop_get16(acc
, prop
, PCI_CONF_VENID
);
399 if (prop
->ppd_vendid
== PCI_EINVAL16
) {
400 return (PCI_PROP_E_BAD_READ
);
402 prop
->ppd_devid
= pci_prop_get16(acc
, prop
, PCI_CONF_DEVID
);
403 prop
->ppd_rev
= pci_prop_get8(acc
, prop
, PCI_CONF_REVID
);
404 prop
->ppd_class
= pci_prop_get8(acc
, prop
, PCI_CONF_BASCLASS
);
405 prop
->ppd_subclass
= pci_prop_get8(acc
, prop
, PCI_CONF_SUBCLASS
);
406 prop
->ppd_pi
= pci_prop_get8(acc
, prop
, PCI_CONF_PROGCLASS
);
408 htype
= pci_prop_get8(acc
, prop
, PCI_CONF_HEADER
);
409 prop
->ppd_header
= htype
& PCI_HEADER_TYPE_M
;
410 if ((htype
& PCI_HEADER_MULTI
) != 0) {
411 prop
->ppd_flags
|= PCI_PROP_F_MULT_FUNC
;
416 * Next, we get fields from the header that vary between device types or
417 * are specific to a given device type. Bridges do not have a subsystem
418 * ID at this point, instead we will fetch it out when we walk the basic
421 switch (prop
->ppd_header
) {
422 case PCI_HEADER_ZERO
:
423 prop
->ppd_subvid
= pci_prop_get16(acc
, prop
,
425 prop
->ppd_subsys
= pci_prop_get16(acc
, prop
,
427 prop
->ppd_mingrt
= pci_prop_get8(acc
, prop
, PCI_CONF_MIN_G
);
428 prop
->ppd_maxlat
= pci_prop_get8(acc
, prop
, PCI_CONF_MAX_L
);
430 case PCI_HEADER_CARDBUS
:
431 prop
->ppd_subvid
= pci_prop_get16(acc
, prop
,
433 prop
->ppd_subsys
= pci_prop_get16(acc
, prop
,
439 return (PCI_PROP_E_UNKNOWN_HEADER
);
443 * Capture registers which are used to derive various devinfo
444 * properties and are shared between all device types.
446 prop
->ppd_ipin
= pci_prop_get8(acc
, prop
, PCI_CONF_IPIN
);
447 prop
->ppd_status
= pci_prop_get16(acc
, prop
, PCI_CONF_STAT
);
450 * If there are no capabilities, there is nothing else for us to do.
452 status
= pci_prop_get16(acc
, prop
, PCI_CONF_STAT
);
453 if ((status
& PCI_STAT_CAP
) == 0)
454 return (PCI_PROP_OK
);
456 cap_off
= pci_prop_get8(acc
, prop
, PCI_CONF_CAP_PTR
);
457 for (; max_cap
> 0 && cap_off
>= PCI_CAP_PTR_OFF
; max_cap
--) {
458 uint8_t cap_addr
= cap_off
& PCI_CAP_PTR_MASK
;
459 uint8_t cap_id
= pci_prop_get8(acc
, prop
, cap_addr
);
460 uint16_t subvid
, subsys
;
461 pci_prop_failure_t ret
;
464 * Look for an invalid read as a proxy for this being in illegal
465 * capability and that we're done. We don't treat this as fatal
466 * as some devices will place the caps at weird places.
468 if (cap_id
== PCI_EINVAL8
) {
469 return (PCI_PROP_OK
);
473 case PCI_CAP_ID_PCI_E
:
474 ret
= pci_prop_data_fill_pcie(acc
, prop
, cap_addr
);
475 if (ret
!= PCI_PROP_OK
) {
479 case PCI_CAP_ID_P2P_SUBSYS
:
481 * This is only legal in a type 1 header configuration
482 * space. In practice we've found some root complex
483 * event collectors in the wild that have both. Because
484 * this must come after the type 0 header, if this
485 * differs then we'll say something.
487 subvid
= pci_prop_get16(acc
, prop
, cap_addr
+
488 PCI_SUBSYSCAP_SUBVID
);
489 subsys
= pci_prop_get16(acc
, prop
, cap_addr
+
490 PCI_SUBSYSCAP_SUBSYS
);
491 if (prop
->ppd_header
== PCI_HEADER_PPB
) {
492 prop
->ppd_subvid
= subvid
;
493 prop
->ppd_subsys
= subsys
;
494 } else if (subvid
!= prop
->ppd_subvid
||
495 subsys
!= prop
->ppd_subsys
) {
496 cmn_err(CE_WARN
, "found device at b/d/f "
497 "0x%x/0x%x/0x%x with PCI subsystem "
498 "capability, but wrong header type 0x%x "
499 "and mismatched subsystems: header "
500 "0x%x/0x%x, cap: 0x%x/0x%x, using header "
501 "values", bus
, dev
, func
, prop
->ppd_header
,
502 prop
->ppd_subvid
, prop
->ppd_subsys
, subvid
,
513 * Again, we check for invalid capability offsets to try to flag
514 * the case of an invalid read. If we have a zero representing
515 * the end of the list, then we'll break out up above.
517 cap_off
= pci_prop_get8(acc
, prop
, cap_addr
+ PCI_CAP_NEXT_PTR
);
518 if (cap_off
== PCI_EINVAL8
) {
519 return (PCI_PROP_OK
);
523 return (PCI_PROP_OK
);
527 * The IEEE 1275 slot-names property has a unique construction. It starts off
528 * with a uint32_t which is a bitmask of names for each device. Then there is a
529 * number of strings ordered based on the bitfield. The NDI doesn't have a great
530 * way to represent this combination of types so we are bound by history which
531 * says to use an int array. Yes, this is gross.
533 * For PCIe this is at least somewhat straightforward. We only ever have one
534 * device so our bitfield value is always 0x1. The name we use is also always
538 pci_prop_set_pciex_slot_name(dev_info_t
*dip
, uint16_t slotno
)
543 bzero(slot
, sizeof (slot
));
547 * We need to calculate the number of uint32_t's that we used. We round
548 * up the number of bytes used for the name, convert that to a number of
549 * uint32_t's and then add one for the bitfield.
551 len
= snprintf((char *)&slot
[1], sizeof (slot
) - sizeof (slot
[0]),
552 "pcie%u", slotno
) + 1;
553 len
= P2ROUNDUP(len
, sizeof (uint32_t));
554 len
/= sizeof (uint32_t);
556 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE
, dip
, "slot-names",
561 pci_prop_set_common_props(dev_info_t
*dip
, const pci_prop_data_t
*prop
)
565 pci_prd_compat_flags_t flags
= pci_prd_compat_flags();
567 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
, "vendor-id",
569 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
, "device-id",
571 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
, "revision-id",
574 class = (prop
->ppd_class
<< 16) | (prop
->ppd_subclass
<< 8) |
576 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
, "class-code", class);
578 if (prop
->ppd_subvid
!= 0) {
579 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
,
580 "subsystem-vendor-id", prop
->ppd_subvid
);
581 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
, "subsystem-id",
585 if (prop
->ppd_func
> 0) {
586 (void) snprintf(unitaddr
, sizeof (unitaddr
), "%x,%x",
587 prop
->ppd_dev
, prop
->ppd_func
);
589 (void) snprintf(unitaddr
, sizeof (unitaddr
), "%x",
592 (void) ndi_prop_update_string(DDI_DEV_T_NONE
, dip
, "unit-address",
596 * Set properties specific to the device class (i.e. PCI or PCIe).
597 * While devsel-speed is meaningless for PCIe, this is still set
598 * anyways for it to match tradition.
600 if ((prop
->ppd_flags
& PCI_PROP_F_PCIE
) == 0) {
601 if ((prop
->ppd_status
& PCI_STAT_FBBC
) != 0) {
602 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE
, dip
,
603 "fast-back-to-back");
606 if ((prop
->ppd_status
& PCI_STAT_66MHZ
) != 0) {
607 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE
, dip
,
611 if ((prop
->ppd_status
& PCI_STAT_UDF
) != 0) {
612 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE
, dip
,
616 if (prop
->ppd_header
== PCI_HEADER_ZERO
) {
617 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
,
618 "min-grant", prop
->ppd_mingrt
);
620 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
,
621 "max-latency", prop
->ppd_maxlat
);
624 if ((prop
->ppd_flags
& PCI_PROP_F_SLOT_VALID
) != 0) {
625 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
,
626 "physical-slot#", prop
->ppd_slotno
);
627 if (prop
->ppd_pcie_type
!=
628 PCIE_PCIECAP_DEV_TYPE_PCIE2PCI
) {
629 pci_prop_set_pciex_slot_name(dip
,
634 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
, "devsel-speed",
635 (prop
->ppd_status
& PCI_STAT_DEVSELT
) >> 9);
638 * The ipin indicates which INTx value a device should have. Zero
639 * indicates no INTx has been assigned.
641 if (prop
->ppd_ipin
!= 0) {
642 (void) ndi_prop_update_int(DDI_DEV_T_NONE
, dip
, "interrupts",
647 * VGA class devices have required specific device_type and related
648 * properties to be set. The same is true of ISA. Parent bridges and the
649 * synthetic nexus nodes that represent root complexes ala npe, pci,
650 * pcieb, etc. set the device type to either "pci" or "pciex", but that
651 * is not done universally at this time. We should consider that for the
654 if (pci_prop_class_is_vga(prop
)) {
655 (void) ndi_prop_update_string(DDI_DEV_T_NONE
, dip
,
656 "device_type", "display");
657 } else if (pci_prop_class_is_isa(prop
) &&
658 (flags
& PCI_PRD_COMPAT_ISA
) != 0) {
659 (void) ndi_prop_update_string(DDI_DEV_T_NONE
, dip
,
660 "device_type", "isa");
664 * Go through and add the model property. This utilizes the common PCI
665 * class codes. Traditionally a PCIe->PCI bridge was treated specially
666 * and given a unique label because of the fact it was crossing between
667 * the protocols (though the opposite wasn't true for PCI->PCIe
670 * The other traditional gotcha here is that any device whose class and
671 * subclass indicated it was an IDE controller got that name.
673 if ((prop
->ppd_flags
& PCI_PROP_F_PCIE
) != 0 &&
674 prop
->ppd_pcie_type
== PCIE_PCIECAP_DEV_TYPE_PCIE2PCI
) {
675 (void) ndi_prop_update_string(DDI_DEV_T_NONE
, dip
, "model",
676 (char *)"PCIe-PCI bridge");
677 } else if (prop
->ppd_class
== PCI_CLASS_MASS
&&
678 prop
->ppd_subclass
== PCI_MASS_IDE
) {
679 (void) ndi_prop_update_string(DDI_DEV_T_NONE
, dip
, "model",
680 (char *)"IDE controller");
682 const char *desc
= NULL
;
684 for (int i
= 0; i
< class_pci_items
; i
++) {
685 if (prop
->ppd_class
== class_pci
[i
].base_class
&&
686 prop
->ppd_subclass
== class_pci
[i
].sub_class
&&
687 prop
->ppd_pi
== class_pci
[i
].prog_class
) {
688 desc
= class_pci
[i
].actual_desc
;
695 * Yes, we're not dealing with PNP strictly any more,
696 * but this is the string we've traditionally used.
698 desc
= "Unknown class of pci/pnpbios device";
701 (void) ndi_prop_update_string(DDI_DEV_T_NONE
, dip
, "model",
705 return (PCI_PROP_OK
);
710 * This enumeration encodes the different possible forms of the alias
711 * properties. In these definitions, the following groups of letters have
714 * "VD": Vendor ID,Device ID (1234,5678)
715 * "SVSI": Subsystem Vendor ID, Subsystem ID
717 * "S": The string ,s to represent the disambiguated PCI subsystem alias
718 * "P": The string ,p to represent the disambiguated PCI primary alias
719 * "CSPI": Class, subclass, and Programming Interface
720 * "CS": Class, subclass
736 * The upper bound on aliases is if everything is used once for PCIe and then
737 * again for PCI. This is more than should be used.
739 #define PCI_MAX_ALIASES (2 * PCI_ALIAS_MAX)
743 * This flag indicates that a given alias should only be used for PCI
746 PCI_ALIAS_F_PCI_ONLY
= 1 << 0,
748 * This flag indicates that this value should not be used for any device
749 * with a type 1 header, aka PCI-PCI bridges.
751 PCI_ALIAS_F_SKIP_BRIDGE
= 1 << 1,
753 * This flag indicates that we should create subsystem compatibility
754 * IDs. We only expect this to be done on x86 (and SPARC historically).
756 PCI_ALIAS_F_COMPAT
= 1 << 2,
758 * This flag indicates that we need to check whether we've banned the
759 * subsystem ID due to duplication. This is still something we do even
760 * when we don't have PCI_ALIAS_F_COMPAT set for the disambiguated
763 PCI_ALIAS_F_CHECK_SUBSYS
= 1 << 3
767 pci_alias_t pad_type
;
768 pci_alias_flags_t pad_flags
;
771 static const pci_alias_data_t pci_alias_table
[] = {
772 { PCI_ALIAS_VD_SVSI_R
, 0 },
773 { PCI_ALIAS_VD_SVSI
, 0 },
774 { PCI_ALIAS_SVSI_S
, PCI_ALIAS_F_PCI_ONLY
| PCI_ALIAS_F_CHECK_SUBSYS
},
775 { PCI_ALIAS_SVSI
, PCI_ALIAS_F_PCI_ONLY
| PCI_ALIAS_F_SKIP_BRIDGE
|
776 PCI_ALIAS_F_COMPAT
| PCI_ALIAS_F_CHECK_SUBSYS
},
777 { PCI_ALIAS_VD_R
, 0 },
778 { PCI_ALIAS_VD_P
, PCI_ALIAS_F_PCI_ONLY
},
780 { PCI_ALIAS_CSPI
, 0 },
785 * Our big theory statement talks about cases where we already know that PCI IDs
786 * have had overlap with subsystems and them not being appropriate. The
787 * following table describes how to match
790 PCI_PROP_NSM_VID_CLASS
,
792 } pci_prop_no_subsys_match_t
;
794 typedef boolean_t (*pci_prop_no_subsys_class_f
)(const pci_prop_data_t
*);
795 typedef struct pci_prop_no_subsys
{
796 pci_prop_no_subsys_match_t ppnsm_type
;
799 uint16_t ppnsm_subvid
;
800 uint16_t ppnsm_subsys
;
801 pci_prop_no_subsys_class_f ppnsm_class
;
802 } pci_prop_no_subsys_t
;
804 static const pci_prop_no_subsys_t pci_prop_no_subsys
[] = {
806 * We've historically blocked nVidia subsystems because of subsystem
809 { .ppnsm_type
= PCI_PROP_NSM_VID_CLASS
, .ppnsm_vid
= 0x10de,
810 .ppnsm_class
= pci_prop_class_is_vga
},
812 * 8086,166 is the Ivy Bridge built-in graphics controller on some
813 * models. Unfortunately 8086,2044 is the Skylake Server processor
814 * memory channel device. The Ivy Bridge device uses the Skylake
815 * ID as its sub-device ID. The GPU is not a memory controller DIMM
818 { .ppnsm_type
= PCI_PROP_NSM_SUBSYS
, .ppnsm_vid
= 0x8086,
819 .ppnsm_did
= 0x166, .ppnsm_subvid
= 0x8086, .ppnsm_subsys
= 0x2044 }
823 pci_prop_skip_subsys(const pci_prop_data_t
*prop
)
825 for (size_t i
= 0; i
< ARRAY_SIZE(pci_prop_no_subsys
); i
++) {
826 const pci_prop_no_subsys_t
*p
= &pci_prop_no_subsys
[i
];
827 switch (p
->ppnsm_type
) {
828 case PCI_PROP_NSM_VID_CLASS
:
829 if (prop
->ppd_vendid
== p
->ppnsm_vid
&&
830 p
->ppnsm_class(prop
)) {
834 case PCI_PROP_NSM_SUBSYS
:
835 if (prop
->ppd_vendid
== p
->ppnsm_vid
&&
836 prop
->ppd_devid
== p
->ppnsm_did
&&
837 prop
->ppd_subvid
== p
->ppnsm_subvid
&&
838 prop
->ppd_subsys
== p
->ppnsm_subsys
) {
848 pci_prop_alias_pass(const pci_prop_data_t
*prop
, char **alias
, uint_t
*nalias
,
849 pci_prd_compat_flags_t compat
, boolean_t force_pci
)
851 boolean_t is_pci
= force_pci
||
852 (prop
->ppd_flags
& PCI_PROP_F_PCIE
) == 0;
853 const char *prefix
= is_pci
? "pci" : "pciex";
854 boolean_t subsys_valid
= prop
->ppd_subvid
!= 0;
856 for (size_t i
= 0; i
< ARRAY_SIZE(pci_alias_table
); i
++) {
857 const pci_alias_data_t
*a
= &pci_alias_table
[i
];
859 if ((a
->pad_flags
& PCI_ALIAS_F_PCI_ONLY
) != 0 && !is_pci
) {
863 if ((a
->pad_flags
& PCI_ALIAS_F_SKIP_BRIDGE
) != 0 &&
864 prop
->ppd_header
== PCI_HEADER_PPB
) {
868 if ((a
->pad_flags
& PCI_ALIAS_F_COMPAT
) != 0 &&
869 (compat
& PCI_PRD_COMPAT_SUBSYS
) == 0) {
873 if ((a
->pad_flags
& PCI_ALIAS_F_CHECK_SUBSYS
) != 0 &&
874 pci_prop_skip_subsys(prop
)) {
878 switch (a
->pad_type
) {
879 case PCI_ALIAS_VD_SVSI_R
:
882 alias
[*nalias
] = kmem_asprintf("%s%x,%x.%x.%x.%x",
883 prefix
, prop
->ppd_vendid
, prop
->ppd_devid
,
884 prop
->ppd_subvid
, prop
->ppd_subsys
,
887 case PCI_ALIAS_VD_SVSI
:
890 alias
[*nalias
] = kmem_asprintf("%s%x,%x.%x.%x", prefix
,
891 prop
->ppd_vendid
, prop
->ppd_devid
,
892 prop
->ppd_subvid
, prop
->ppd_subsys
);
894 case PCI_ALIAS_SVSI_S
:
897 alias
[*nalias
] = kmem_asprintf("%s%x,%x,s", prefix
,
898 prop
->ppd_subvid
, prop
->ppd_subsys
);
903 alias
[*nalias
] = kmem_asprintf("%s%x,%x", prefix
,
904 prop
->ppd_subvid
, prop
->ppd_subsys
);
907 alias
[*nalias
] = kmem_asprintf("%s%x,%x.%x", prefix
,
908 prop
->ppd_vendid
, prop
->ppd_devid
, prop
->ppd_rev
);
911 alias
[*nalias
] = kmem_asprintf("%s%x,%x,p", prefix
,
912 prop
->ppd_vendid
, prop
->ppd_devid
);
915 alias
[*nalias
] = kmem_asprintf("%s%x,%x", prefix
,
916 prop
->ppd_vendid
, prop
->ppd_devid
);
919 alias
[*nalias
] = kmem_asprintf("%sclass,%02x%02x%02x",
920 prefix
, prop
->ppd_class
, prop
->ppd_subclass
,
924 alias
[*nalias
] = kmem_asprintf("%sclass,%02x%02x",
925 prefix
, prop
->ppd_class
, prop
->ppd_subclass
);
928 panic("encountered unknown alias type: 0x%x",
932 *nalias
= *nalias
+ 1;
933 ASSERT3U(*nalias
, <=, PCI_MAX_ALIASES
);
938 * Go through the messy process of creating the compatible property. See the
939 * theory statement for more info.
942 pci_prop_set_compatible(dev_info_t
*dip
, const pci_prop_data_t
*prop
)
944 char *alias
[PCI_MAX_ALIASES
];
946 pci_prd_compat_flags_t compat
= pci_prd_compat_flags();
947 boolean_t two_sets
= (compat
& PCI_PRD_COMPAT_PCI_NODE_NAME
) != 0;
949 pci_prop_alias_pass(prop
, alias
, &nalias
, compat
, B_FALSE
);
950 if (two_sets
&& (prop
->ppd_flags
& PCI_PROP_F_PCIE
) != 0) {
951 pci_prop_alias_pass(prop
, alias
, &nalias
, compat
, B_TRUE
);
954 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE
, dip
, "compatible",
956 for (uint_t i
= 0; i
< nalias
; i
++) {
959 return (PCI_PROP_OK
);