1 /*
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
5 * 1.0 of the CDDL.
6 *
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.
10 */
11
12 /*
13 * Copyright 2024 Oxide Computer company
14 */
15
16 /*
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.
21 *
22 * PCI Compatible Aliases
23 * ----------------------
24 *
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:
31 *
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>
39 *
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
49 * known conflicts.
50 *
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:
57 *
58 * pci<subsystem vendor>,<subsystem id>,s
59 * pci<vendor id>,<device id>,p
60 *
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().
72 *
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
82 * bridges.
83 *
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:
87 *
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
90 * node name below.
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.
96 *
97 * Node Naming
98 * -----------
99 *
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.
106 *
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
111 * "pci" otherwise.
112 *
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
119 * "display".
120 *
121 * Our order for naming device nodes is:
122 *
123 * 1. Check for display.
124 * 2. Check for ISA.
125 * 3. Attempt to use the subsystem.
126 * 4. Fall back to the normal vendor and device.
127 *
128 * Platforms can influence this in the following ways:
129 *
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.
134 *
135 * Unit Address
136 * ------------
137 *
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.
143 */
144
145 #include <sys/ddi.h>
146 #include <sys/sunddi.h>
147 #include <sys/sunndi.h>
148 #include <sys/cmn_err.h>
149 #include <sys/pci.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>
156
157 typedef struct {
158 uint8_t ppc_class;
159 uint8_t ppc_subclass;
160 uint8_t ppc_pi;
161 } pci_prop_class_t;
162
163 static boolean_t
pci_prop_class_match(const pci_prop_data_t * prop,const pci_prop_class_t * class,const size_t nclass,boolean_t check_pi)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)
166 {
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)) {
171 return (B_TRUE);
172 }
173 }
174
175 return (B_FALSE);
176 }
177
178 /*
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
182 * compatible:
183 *
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
187 */
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 }
192 };
193
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 },
197 };
198
199 static const pci_prop_class_t pci_prop_isa_classes[] = {
200 { PCI_CLASS_BRIDGE, PCI_BRIDGE_ISA, 0 }
201 };
202
203 static const pci_prop_class_t pci_prop_pcibridge_classes[] = {
204 { PCI_CLASS_BRIDGE, PCI_BRIDGE_PCI, 0 }
205 };
206
207 boolean_t
pci_prop_class_is_vga(const pci_prop_data_t * prop)208 pci_prop_class_is_vga(const pci_prop_data_t *prop)
209 {
210 return (pci_prop_class_match(prop, pci_prop_vga_classes,
211 ARRAY_SIZE(pci_prop_vga_classes), B_TRUE));
212 }
213
214 boolean_t
pci_prop_class_is_ioapic(const pci_prop_data_t * prop)215 pci_prop_class_is_ioapic(const pci_prop_data_t *prop)
216 {
217 return (pci_prop_class_match(prop, pci_prop_ioapic_classes,
218 ARRAY_SIZE(pci_prop_ioapic_classes), B_TRUE));
219 }
220
221 /*
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.
226 */
227 boolean_t
pci_prop_class_is_isa(const pci_prop_data_t * prop)228 pci_prop_class_is_isa(const pci_prop_data_t *prop)
229 {
230 return (pci_prop_class_match(prop, pci_prop_isa_classes,
231 ARRAY_SIZE(pci_prop_isa_classes), B_FALSE));
232 }
233
234 /*
235 * We don't check the programming class here because callers don't care if this
236 * is subtractive or not.
237 */
238 boolean_t
pci_prop_class_is_pcibridge(const pci_prop_data_t * prop)239 pci_prop_class_is_pcibridge(const pci_prop_data_t *prop)
240 {
241 return (pci_prop_class_match(prop, pci_prop_pcibridge_classes,
242 ARRAY_SIZE(pci_prop_pcibridge_classes), B_FALSE));
243 }
244
245 static const char *
pci_prop_nodename_prefix(const pci_prop_data_t * prop,pci_prd_compat_flags_t flags)246 pci_prop_nodename_prefix(const pci_prop_data_t *prop,
247 pci_prd_compat_flags_t flags)
248 {
249 if ((flags & PCI_PRD_COMPAT_PCI_NODE_NAME) != 0) {
250 return ("pci");
251 }
252
253 if ((prop->ppd_flags & PCI_PROP_F_PCIE) != 0) {
254 return ("pciex");
255 } else {
256 return ("pci");
257 }
258 }
259
260 static boolean_t
pci_prop_use_subsystem(const pci_prop_data_t * prop,pci_prd_compat_flags_t flags)261 pci_prop_use_subsystem(const pci_prop_data_t *prop,
262 pci_prd_compat_flags_t flags)
263 {
264 if ((flags & PCI_PRD_COMPAT_SUBSYS) != 0 &&
265 prop->ppd_header == PCI_HEADER_PPB) {
266 return (B_FALSE);
267 }
268
269 return (prop->ppd_subvid != 0);
270 }
271
272 /*
273 * Name a device node per the theory statement.
274 */
275 pci_prop_failure_t
pci_prop_name_node(dev_info_t * dip,const pci_prop_data_t * prop)276 pci_prop_name_node(dev_info_t *dip, const pci_prop_data_t *prop)
277 {
278 char buf[64];
279 pci_prd_compat_flags_t flags = pci_prd_compat_flags();
280
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");
286 } else {
287 const char *prefix = pci_prop_nodename_prefix(prop, flags);
288
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);
292 } else {
293 (void) snprintf(buf, sizeof (buf), "%s%x,%x", prefix,
294 prop->ppd_vendid, prop->ppd_devid);
295 }
296 }
297
298 if (ndi_devi_set_nodename(dip, buf, 0) != NDI_SUCCESS) {
299 return (PCI_PROP_E_NDI);
300 }
301 return (PCI_PROP_OK);
302 }
303
304 static uint8_t
pci_prop_get8(ddi_acc_handle_t acc,const pci_prop_data_t * prop,uint16_t off)305 pci_prop_get8(ddi_acc_handle_t acc, const pci_prop_data_t *prop, uint16_t off)
306 {
307 if (acc == NULL) {
308 return ((*pci_getb_func)(prop->ppd_bus, prop->ppd_dev,
309 prop->ppd_func, off));
310 } else {
311 return (pci_config_get8(acc, off));
312 }
313 }
314
315 static uint16_t
pci_prop_get16(ddi_acc_handle_t acc,const pci_prop_data_t * prop,uint16_t off)316 pci_prop_get16(ddi_acc_handle_t acc, const pci_prop_data_t *prop, uint16_t off)
317 {
318 if (acc == NULL) {
319 return ((*pci_getw_func)(prop->ppd_bus, prop->ppd_dev,
320 prop->ppd_func, off));
321 } else {
322 return (pci_config_get16(acc, off));
323 }
324 }
325
326 static uint32_t
pci_prop_get32(ddi_acc_handle_t acc,const pci_prop_data_t * prop,uint16_t off)327 pci_prop_get32(ddi_acc_handle_t acc, const pci_prop_data_t *prop, uint16_t off)
328 {
329 if (acc == NULL) {
330 return ((*pci_getl_func)(prop->ppd_bus, prop->ppd_dev,
331 prop->ppd_func, off));
332 } else {
333 return (pci_config_get32(acc, off));
334 }
335 }
336
337 static pci_prop_failure_t
pci_prop_data_fill_pcie(ddi_acc_handle_t acc,pci_prop_data_t * prop,uint8_t cap_base)338 pci_prop_data_fill_pcie(ddi_acc_handle_t acc, pci_prop_data_t *prop,
339 uint8_t cap_base)
340 {
341 uint16_t pciecap;
342 uint32_t slotcap;
343 uint8_t vers;
344
345 pciecap = pci_prop_get16(acc, prop, cap_base + PCIE_PCIECAP);
346 vers = pciecap & PCIE_PCIECAP_VER_MASK;
347 switch (vers) {
348 case PCIE_PCIECAP_VER_1_0:
349 case PCIE_PCIECAP_VER_2_0:
350 break;
351 default:
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);
356 }
357
358 prop->ppd_flags |= PCI_PROP_F_PCIE;
359 prop->ppd_pcie_type = pciecap & PCIE_PCIECAP_DEV_TYPE_MASK;
360
361 if ((pciecap & PCIE_PCIECAP_SLOT_IMPL) == 0) {
362 return (PCI_PROP_OK);
363 }
364
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);
369 }
370
371 /*
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
376 * the rest.
377 *
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.
380 */
381 pci_prop_failure_t
pci_prop_data_fill(ddi_acc_handle_t acc,uint8_t bus,uint8_t dev,uint8_t func,pci_prop_data_t * prop)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)
384 {
385 uint8_t htype, cap_off, max_cap = PCI_CAP_MAX_PTR;
386 uint16_t status;
387
388 bzero(prop, sizeof (pci_prop_data_t));
389 prop->ppd_bus = bus;
390 prop->ppd_dev = dev;
391 prop->ppd_func = func;
392
393 /*
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.
397 */
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);
401 }
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);
407
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;
412 }
413
414
415 /*
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
419 * capabilities.
420 */
421 switch (prop->ppd_header) {
422 case PCI_HEADER_ZERO:
423 prop->ppd_subvid = pci_prop_get16(acc, prop,
424 PCI_CONF_SUBVENID);
425 prop->ppd_subsys = pci_prop_get16(acc, prop,
426 PCI_CONF_SUBSYSID);
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);
429 break;
430 case PCI_HEADER_CARDBUS:
431 prop->ppd_subvid = pci_prop_get16(acc, prop,
432 PCI_CBUS_SUBVENID);
433 prop->ppd_subsys = pci_prop_get16(acc, prop,
434 PCI_CBUS_SUBSYSID);
435 break;
436 case PCI_HEADER_PPB:
437 break;
438 default:
439 return (PCI_PROP_E_UNKNOWN_HEADER);
440 }
441
442 /*
443 * Capture registers which are used to derive various devinfo
444 * properties and are shared between all device types.
445 */
446 prop->ppd_ipin = pci_prop_get8(acc, prop, PCI_CONF_IPIN);
447 prop->ppd_status = pci_prop_get16(acc, prop, PCI_CONF_STAT);
448
449 /*
450 * If there are no capabilities, there is nothing else for us to do.
451 */
452 status = pci_prop_get16(acc, prop, PCI_CONF_STAT);
453 if ((status & PCI_STAT_CAP) == 0)
454 return (PCI_PROP_OK);
455
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;
462
463 /*
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.
467 */
468 if (cap_id == PCI_EINVAL8) {
469 return (PCI_PROP_OK);
470 }
471
472 switch (cap_id) {
473 case PCI_CAP_ID_PCI_E:
474 ret = pci_prop_data_fill_pcie(acc, prop, cap_addr);
475 if (ret != PCI_PROP_OK) {
476 return (ret);
477 }
478 break;
479 case PCI_CAP_ID_P2P_SUBSYS:
480 /*
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.
486 */
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,
503 subsys);
504 break;
505 }
506
507 break;
508 default:
509 break;
510 }
511
512 /*
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.
516 */
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);
520 }
521 }
522
523 return (PCI_PROP_OK);
524 }
525
526 /*
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.
532 *
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
535 * "pcie<slot>".
536 */
537 static void
pci_prop_set_pciex_slot_name(dev_info_t * dip,uint16_t slotno)538 pci_prop_set_pciex_slot_name(dev_info_t *dip, uint16_t slotno)
539 {
540 uint32_t slot[32];
541 size_t len;
542
543 bzero(slot, sizeof (slot));
544 slot[0] = 1;
545
546 /*
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.
550 */
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);
555 len += 1;
556 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "slot-names",
557 (int *)slot, len);
558 }
559
560 pci_prop_failure_t
pci_prop_set_common_props(dev_info_t * dip,const pci_prop_data_t * prop)561 pci_prop_set_common_props(dev_info_t *dip, const pci_prop_data_t *prop)
562 {
563 int class;
564 char unitaddr[16];
565 pci_prd_compat_flags_t flags = pci_prd_compat_flags();
566
567 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "vendor-id",
568 prop->ppd_vendid);
569 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "device-id",
570 prop->ppd_devid);
571 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "revision-id",
572 prop->ppd_rev);
573
574 class = (prop->ppd_class << 16) | (prop->ppd_subclass << 8) |
575 prop->ppd_pi;
576 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "class-code", class);
577
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",
582 prop->ppd_subsys);
583 }
584
585 if (prop->ppd_func > 0) {
586 (void) snprintf(unitaddr, sizeof (unitaddr), "%x,%x",
587 prop->ppd_dev, prop->ppd_func);
588 } else {
589 (void) snprintf(unitaddr, sizeof (unitaddr), "%x",
590 prop->ppd_dev);
591 }
592 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "unit-address",
593 unitaddr);
594
595 /*
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.
599 */
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");
604 }
605
606 if ((prop->ppd_status & PCI_STAT_66MHZ) != 0) {
607 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
608 "66mhz-capable");
609 }
610
611 if ((prop->ppd_status & PCI_STAT_UDF) != 0) {
612 (void) ndi_prop_create_boolean(DDI_DEV_T_NONE, dip,
613 "udf-supported");
614 }
615
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);
619
620 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip,
621 "max-latency", prop->ppd_maxlat);
622 }
623 } else {
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,
630 prop->ppd_slotno);
631 }
632 }
633 }
634 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "devsel-speed",
635 (prop->ppd_status & PCI_STAT_DEVSELT) >> 9);
636
637 /*
638 * The ipin indicates which INTx value a device should have. Zero
639 * indicates no INTx has been assigned.
640 */
641 if (prop->ppd_ipin != 0) {
642 (void) ndi_prop_update_int(DDI_DEV_T_NONE, dip, "interrupts",
643 prop->ppd_ipin);
644 }
645
646 /*
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
652 * future.
653 */
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");
661 }
662
663 /*
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
668 * bridges).
669 *
670 * The other traditional gotcha here is that any device whose class and
671 * subclass indicated it was an IDE controller got that name.
672 */
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");
681 } else {
682 const char *desc = NULL;
683
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;
689 break;
690 }
691 }
692
693 if (desc == NULL) {
694 /*
695 * Yes, we're not dealing with PNP strictly any more,
696 * but this is the string we've traditionally used.
697 */
698 desc = "Unknown class of pci/pnpbios device";
699 }
700
701 (void) ndi_prop_update_string(DDI_DEV_T_NONE, dip, "model",
702 (char *)desc);
703 }
704
705 return (PCI_PROP_OK);
706 }
707
708
709 /*
710 * This enumeration encodes the different possible forms of the alias
711 * properties. In these definitions, the following groups of letters have
712 * different means:
713 *
714 * "VD": Vendor ID,Device ID (1234,5678)
715 * "SVSI": Subsystem Vendor ID, Subsystem ID
716 * "R": Revision
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
721 */
722 typedef enum {
723 PCI_ALIAS_VD_SVSI_R,
724 PCI_ALIAS_VD_SVSI,
725 PCI_ALIAS_SVSI_S,
726 PCI_ALIAS_SVSI,
727 PCI_ALIAS_VD_R,
728 PCI_ALIAS_VD_P,
729 PCI_ALIAS_VD,
730 PCI_ALIAS_CSPI,
731 PCI_ALIAS_CS,
732 PCI_ALIAS_MAX
733 } pci_alias_t;
734
735 /*
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.
738 */
739 #define PCI_MAX_ALIASES (2 * PCI_ALIAS_MAX)
740
741 typedef enum {
742 /*
743 * This flag indicates that a given alias should only be used for PCI
744 * devices.
745 */
746 PCI_ALIAS_F_PCI_ONLY = 1 << 0,
747 /*
748 * This flag indicates that this value should not be used for any device
749 * with a type 1 header, aka PCI-PCI bridges.
750 */
751 PCI_ALIAS_F_SKIP_BRIDGE = 1 << 1,
752 /*
753 * This flag indicates that we should create subsystem compatibility
754 * IDs. We only expect this to be done on x86 (and SPARC historically).
755 */
756 PCI_ALIAS_F_COMPAT = 1 << 2,
757 /*
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
761 * subsystem ID.
762 */
763 PCI_ALIAS_F_CHECK_SUBSYS = 1 << 3
764 } pci_alias_flags_t;
765
766 typedef struct {
767 pci_alias_t pad_type;
768 pci_alias_flags_t pad_flags;
769 } pci_alias_data_t;
770
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 },
779 { PCI_ALIAS_VD, 0 },
780 { PCI_ALIAS_CSPI, 0 },
781 { PCI_ALIAS_CS, 0 },
782 };
783
784 /*
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
788 */
789 typedef enum {
790 PCI_PROP_NSM_VID_CLASS,
791 PCI_PROP_NSM_SUBSYS
792 } pci_prop_no_subsys_match_t;
793
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;
797 uint16_t ppnsm_vid;
798 uint16_t ppnsm_did;
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;
803
804 static const pci_prop_no_subsys_t pci_prop_no_subsys[] = {
805 /*
806 * We've historically blocked nVidia subsystems because of subsystem
807 * reuse.
808 */
809 { .ppnsm_type = PCI_PROP_NSM_VID_CLASS, .ppnsm_vid = 0x10de,
810 .ppnsm_class = pci_prop_class_is_vga },
811 /*
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
816 * channel.
817 */
818 { .ppnsm_type = PCI_PROP_NSM_SUBSYS, .ppnsm_vid = 0x8086,
819 .ppnsm_did = 0x166, .ppnsm_subvid = 0x8086, .ppnsm_subsys = 0x2044 }
820 };
821
822 static boolean_t
pci_prop_skip_subsys(const pci_prop_data_t * prop)823 pci_prop_skip_subsys(const pci_prop_data_t *prop)
824 {
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)) {
831 return (B_TRUE);
832 }
833 break;
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) {
839 return (B_TRUE);
840 }
841 break;
842 }
843 }
844 return (B_FALSE);
845 }
846
847 static void
pci_prop_alias_pass(const pci_prop_data_t * prop,char ** alias,uint_t * nalias,pci_prd_compat_flags_t compat,boolean_t force_pci)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)
850 {
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;
855
856 for (size_t i = 0; i < ARRAY_SIZE(pci_alias_table); i++) {
857 const pci_alias_data_t *a = &pci_alias_table[i];
858
859 if ((a->pad_flags & PCI_ALIAS_F_PCI_ONLY) != 0 && !is_pci) {
860 continue;
861 }
862
863 if ((a->pad_flags & PCI_ALIAS_F_SKIP_BRIDGE) != 0 &&
864 prop->ppd_header == PCI_HEADER_PPB) {
865 continue;
866 }
867
868 if ((a->pad_flags & PCI_ALIAS_F_COMPAT) != 0 &&
869 (compat & PCI_PRD_COMPAT_SUBSYS) == 0) {
870 continue;
871 }
872
873 if ((a->pad_flags & PCI_ALIAS_F_CHECK_SUBSYS) != 0 &&
874 pci_prop_skip_subsys(prop)) {
875 continue;
876 }
877
878 switch (a->pad_type) {
879 case PCI_ALIAS_VD_SVSI_R:
880 if (!subsys_valid)
881 continue;
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,
885 prop->ppd_rev);
886 break;
887 case PCI_ALIAS_VD_SVSI:
888 if (!subsys_valid)
889 continue;
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);
893 break;
894 case PCI_ALIAS_SVSI_S:
895 if (!subsys_valid)
896 continue;
897 alias[*nalias] = kmem_asprintf("%s%x,%x,s", prefix,
898 prop->ppd_subvid, prop->ppd_subsys);
899 break;
900 case PCI_ALIAS_SVSI:
901 if (!subsys_valid)
902 continue;
903 alias[*nalias] = kmem_asprintf("%s%x,%x", prefix,
904 prop->ppd_subvid, prop->ppd_subsys);
905 break;
906 case PCI_ALIAS_VD_R:
907 alias[*nalias] = kmem_asprintf("%s%x,%x.%x", prefix,
908 prop->ppd_vendid, prop->ppd_devid, prop->ppd_rev);
909 break;
910 case PCI_ALIAS_VD_P:
911 alias[*nalias] = kmem_asprintf("%s%x,%x,p", prefix,
912 prop->ppd_vendid, prop->ppd_devid);
913 break;
914 case PCI_ALIAS_VD:
915 alias[*nalias] = kmem_asprintf("%s%x,%x", prefix,
916 prop->ppd_vendid, prop->ppd_devid);
917 break;
918 case PCI_ALIAS_CSPI:
919 alias[*nalias] = kmem_asprintf("%sclass,%02x%02x%02x",
920 prefix, prop->ppd_class, prop->ppd_subclass,
921 prop->ppd_pi);
922 break;
923 case PCI_ALIAS_CS:
924 alias[*nalias] = kmem_asprintf("%sclass,%02x%02x",
925 prefix, prop->ppd_class, prop->ppd_subclass);
926 break;
927 default:
928 panic("encountered unknown alias type: 0x%x",
929 a->pad_type);
930 }
931
932 *nalias = *nalias + 1;
933 ASSERT3U(*nalias, <=, PCI_MAX_ALIASES);
934 }
935 }
936
937 /*
938 * Go through the messy process of creating the compatible property. See the
939 * theory statement for more info.
940 */
941 pci_prop_failure_t
pci_prop_set_compatible(dev_info_t * dip,const pci_prop_data_t * prop)942 pci_prop_set_compatible(dev_info_t *dip, const pci_prop_data_t *prop)
943 {
944 char *alias[PCI_MAX_ALIASES];
945 uint_t nalias = 0;
946 pci_prd_compat_flags_t compat = pci_prd_compat_flags();
947 boolean_t two_sets = (compat & PCI_PRD_COMPAT_PCI_NODE_NAME) != 0;
948
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);
952 }
953
954 (void) ndi_prop_update_string_array(DDI_DEV_T_NONE, dip, "compatible",
955 alias, nalias);
956 for (uint_t i = 0; i < nalias; i++) {
957 strfree(alias[i]);
958 }
959 return (PCI_PROP_OK);
960 }
961