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