xref: /illumos-gate/usr/src/uts/common/io/pciex/pci_props.c (revision 8c0e49e07bbdf2f210e329cb5044fa436481e710)
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