1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23 */
24
25 /*
26 * PCI configurator (pcicfg)
27 */
28
29 #include <sys/sysmacros.h>
30 #include <sys/conf.h>
31 #include <sys/kmem.h>
32 #include <sys/debug.h>
33 #include <sys/modctl.h>
34 #include <sys/autoconf.h>
35 #include <sys/hwconf.h>
36 #include <sys/pcie.h>
37 #include <sys/pcie_impl.h>
38 #include <sys/pci_cap.h>
39 #include <sys/ddi.h>
40 #include <sys/sunndi.h>
41 #include <sys/hotplug/pci/pcicfg.h>
42 #include <sys/ndi_impldefs.h>
43 #include <sys/pci_cfgacc.h>
44 #include <sys/pcie_impl.h>
45
46 /*
47 * ************************************************************************
48 * *** Implementation specific local data structures/definitions. ***
49 * ************************************************************************
50 */
51
52 static int pcicfg_start_devno = 0; /* for Debug only */
53
54 #define PCICFG_MAX_ARI_FUNCTION 256
55
56 #define PCICFG_NODEVICE 42
57 #define PCICFG_NOMEMORY 43
58 #define PCICFG_NOMULTI 44
59 #define PCICFG_NORESRC 45
60
61 #define PCICFG_HIADDR(n) ((uint32_t)(((uint64_t)(n) & \
62 0xFFFFFFFF00000000ULL)>> 32))
63 #define PCICFG_LOADDR(n) ((uint32_t)((uint64_t)(n) & 0x00000000FFFFFFFF))
64 #define PCICFG_LADDR(lo, hi) (((uint64_t)(hi) << 32) | (uint32_t)(lo))
65
66 #define PCICFG_HIWORD(n) ((uint16_t)(((uint32_t)(n) & 0xFFFF0000)>> 16))
67 #define PCICFG_LOWORD(n) ((uint16_t)((uint32_t)(n) & 0x0000FFFF))
68 #define PCICFG_HIBYTE(n) ((uint8_t)(((uint16_t)(n) & 0xFF00)>> 8))
69 #define PCICFG_LOBYTE(n) ((uint8_t)((uint16_t)(n) & 0x00FF))
70
71 #define PCICFG_ROUND_UP(addr, gran) ((uintptr_t)((gran+addr-1)&(~(gran-1))))
72 #define PCICFG_ROUND_DOWN(addr, gran) ((uintptr_t)((addr) & ~(gran-1)))
73
74 #define PCICFG_MEMGRAN 0x100000
75 #define PCICFG_IOGRAN 0x1000
76 #define PCICFG_4GIG_LIMIT 0xFFFFFFFFUL
77
78 #define PCICFG_MEM_MULT 4
79 #define PCICFG_IO_MULT 4
80 #define PCICFG_RANGE_LEN 3 /* Number of range entries */
81
82 static int pcicfg_slot_busnums = 8;
83 static int pcicfg_slot_memsize = 32 * PCICFG_MEMGRAN; /* 32MB per slot */
84 static int pcicfg_slot_pf_memsize = 32 * PCICFG_MEMGRAN; /* 32MB per slot */
85 static int pcicfg_slot_iosize = 64 * PCICFG_IOGRAN; /* 64K per slot */
86 static int pcicfg_sec_reset_delay = 3000000;
87 static int pcicfg_do_legacy_props = 1; /* create legacy compatible prop */
88
89 typedef struct hole hole_t;
90
91 struct hole {
92 uint64_t start;
93 uint64_t len;
94 hole_t *next;
95 };
96
97 typedef struct pcicfg_phdl pcicfg_phdl_t;
98
99 struct pcicfg_phdl {
100
101 dev_info_t *dip; /* Associated with the bridge */
102 dev_info_t *top_dip; /* top node of the attach point */
103 pcicfg_phdl_t *next;
104
105 /* non-prefetchable memory space */
106 uint64_t memory_base; /* Memory base for this attach point */
107 uint64_t memory_last;
108 uint64_t memory_len;
109
110 /* prefetchable memory space */
111 uint64_t pf_memory_base; /* PF Memory base for this Connection */
112 uint64_t pf_memory_last;
113 uint64_t pf_memory_len;
114
115 /* io space */
116 uint32_t io_base; /* I/O base for this attach point */
117 uint32_t io_last;
118 uint32_t io_len;
119
120 int error;
121 uint_t highest_bus; /* Highest bus seen on the probe */
122
123 hole_t mem_hole; /* Memory hole linked list. */
124 hole_t pf_mem_hole; /* PF Memory hole linked list. */
125 hole_t io_hole; /* IO hole linked list */
126
127 ndi_ra_request_t mem_req; /* allocator request for memory */
128 ndi_ra_request_t pf_mem_req; /* allocator request for PF memory */
129 ndi_ra_request_t io_req; /* allocator request for I/O */
130 };
131
132 struct pcicfg_standard_prop_entry {
133 uchar_t *name;
134 uint_t config_offset;
135 uint_t size;
136 };
137
138
139 struct pcicfg_name_entry {
140 uint32_t class_code;
141 char *name;
142 };
143
144 struct pcicfg_find_ctrl {
145 uint_t device;
146 uint_t function;
147 dev_info_t *dip;
148 };
149
150 /*
151 * List of Indirect Config Map Devices. At least the intent of the
152 * design is to look for a device in this list during the configure
153 * operation, and if the device is listed here, then it is a nontransparent
154 * bridge, hence load the driver and avail the config map services from
155 * the driver. Class and Subclass should be as defined in the PCI specs
156 * ie. class is 0x6, and subclass is 0x9.
157 */
158 static struct {
159 uint8_t mem_range_bar_offset;
160 uint8_t io_range_bar_offset;
161 uint8_t prefetch_mem_range_bar_offset;
162 } pcicfg_indirect_map_devs[] = {
163 PCI_CONF_BASE3, PCI_CONF_BASE2, PCI_CONF_BASE3,
164 0, 0, 0,
165 };
166
167 #define PCICFG_MAKE_REG_HIGH(busnum, devnum, funcnum, register)\
168 (\
169 ((ulong_t)(busnum & 0xff) << 16) |\
170 ((ulong_t)(devnum & 0x1f) << 11) |\
171 ((ulong_t)(funcnum & 0x7) << 8) |\
172 ((ulong_t)(register & 0x3f)))
173
174 /*
175 * debug macros:
176 */
177 #if defined(DEBUG)
178 extern void prom_printf(const char *, ...);
179
180 /*
181 * Following values are defined for this debug flag.
182 *
183 * 1 = dump configuration header only.
184 * 2 = dump generic debug data only (no config header dumped)
185 * 3 = dump everything (both 1 and 2)
186 */
187 int pcicfg_debug = 0;
188
189 static void debug(char *, uintptr_t, uintptr_t,
190 uintptr_t, uintptr_t, uintptr_t);
191
192 #define DEBUG0(fmt)\
193 debug(fmt, 0, 0, 0, 0, 0);
194 #define DEBUG1(fmt, a1)\
195 debug(fmt, (uintptr_t)(a1), 0, 0, 0, 0);
196 #define DEBUG2(fmt, a1, a2)\
197 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
198 #define DEBUG3(fmt, a1, a2, a3)\
199 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2),\
200 (uintptr_t)(a3), 0, 0);
201 #define DEBUG4(fmt, a1, a2, a3, a4)\
202 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2),\
203 (uintptr_t)(a3), (uintptr_t)(a4), 0);
204 #define DEBUG5(fmt, a1, a2, a3, a4, a5)\
205 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2),\
206 (uintptr_t)(a3), (uintptr_t)(a4), (uintptr_t)(a5));
207 #else
208 #define DEBUG0(fmt)
209 #define DEBUG1(fmt, a1)
210 #define DEBUG2(fmt, a1, a2)
211 #define DEBUG3(fmt, a1, a2, a3)
212 #define DEBUG4(fmt, a1, a2, a3, a4)
213 #define DEBUG5(fmt, a1, a2, a3, a4, a5)
214 #endif
215
216 /*
217 * forward declarations for routines defined in this module (called here)
218 */
219
220 static int pcicfg_add_config_reg(dev_info_t *,
221 uint_t, uint_t, uint_t);
222 static int pcicfg_probe_children(dev_info_t *, uint_t, uint_t, uint_t,
223 uint_t *, pcicfg_flags_t, boolean_t);
224 static int pcicfg_match_dev(dev_info_t *, void *);
225 static dev_info_t *pcicfg_devi_find(dev_info_t *, uint_t, uint_t);
226 static pcicfg_phdl_t *pcicfg_find_phdl(dev_info_t *);
227 static pcicfg_phdl_t *pcicfg_create_phdl(dev_info_t *);
228 static int pcicfg_destroy_phdl(dev_info_t *);
229 static int pcicfg_sum_resources(dev_info_t *, void *);
230 static int pcicfg_device_assign(dev_info_t *);
231 static int pcicfg_bridge_assign(dev_info_t *, void *);
232 static int pcicfg_device_assign_readonly(dev_info_t *);
233 static int pcicfg_free_resources(dev_info_t *, pcicfg_flags_t);
234 static void pcicfg_setup_bridge(pcicfg_phdl_t *, ddi_acc_handle_t);
235 static void pcicfg_update_bridge(pcicfg_phdl_t *, ddi_acc_handle_t);
236 static int pcicfg_update_assigned_prop(dev_info_t *, pci_regspec_t *);
237 static void pcicfg_device_on(ddi_acc_handle_t);
238 static void pcicfg_device_off(ddi_acc_handle_t);
239 static int pcicfg_set_busnode_props(dev_info_t *, uint8_t);
240 static int pcicfg_free_bridge_resources(dev_info_t *);
241 static int pcicfg_free_device_resources(dev_info_t *);
242 static int pcicfg_teardown_device(dev_info_t *, pcicfg_flags_t, boolean_t);
243 static void pcicfg_reparent_node(dev_info_t *, dev_info_t *);
244 static int pcicfg_config_setup(dev_info_t *, ddi_acc_handle_t *);
245 static void pcicfg_config_teardown(ddi_acc_handle_t *);
246 static void pcicfg_get_mem(pcicfg_phdl_t *, uint32_t, uint64_t *);
247 static void pcicfg_get_pf_mem(pcicfg_phdl_t *, uint32_t, uint64_t *);
248 static void pcicfg_get_io(pcicfg_phdl_t *, uint32_t, uint32_t *);
249 static int pcicfg_update_ranges_prop(dev_info_t *, ppb_ranges_t *);
250 static int pcicfg_configure_ntbridge(dev_info_t *, uint_t, uint_t);
251 static uint_t pcicfg_ntbridge_child(dev_info_t *);
252 static uint_t pcicfg_get_ntbridge_child_range(dev_info_t *, uint64_t *,
253 uint64_t *, uint_t);
254 static int pcicfg_is_ntbridge(dev_info_t *);
255 static int pcicfg_ntbridge_allocate_resources(dev_info_t *);
256 static int pcicfg_ntbridge_configure_done(dev_info_t *);
257 static int pcicfg_ntbridge_program_child(dev_info_t *);
258 static uint_t pcicfg_ntbridge_unconfigure(dev_info_t *);
259 static int pcicfg_ntbridge_unconfigure_child(dev_info_t *, uint_t);
260 static void pcicfg_free_hole(hole_t *);
261 static uint64_t pcicfg_alloc_hole(hole_t *, uint64_t *, uint32_t);
262 static int pcicfg_device_type(dev_info_t *, ddi_acc_handle_t *);
263 static void pcicfg_update_phdl(dev_info_t *, uint8_t, uint8_t);
264 static int pcicfg_get_cap(ddi_acc_handle_t, uint8_t);
265 static uint8_t pcicfg_get_nslots(dev_info_t *, ddi_acc_handle_t);
266 static int pcicfg_pcie_dev(dev_info_t *, ddi_acc_handle_t);
267 static int pcicfg_pcie_device_type(dev_info_t *, ddi_acc_handle_t);
268 static int pcicfg_pcie_port_type(dev_info_t *, ddi_acc_handle_t);
269 static int pcicfg_probe_bridge(dev_info_t *, ddi_acc_handle_t, uint_t,
270 uint_t *, boolean_t);
271 static int pcicfg_find_resource_end(dev_info_t *, void *);
272 static boolean_t is_pcie_fabric(dev_info_t *);
273
274 static int pcicfg_populate_reg_props(dev_info_t *, ddi_acc_handle_t);
275 static int pcicfg_populate_props_from_bar(dev_info_t *, ddi_acc_handle_t);
276 static int pcicfg_update_assigned_prop_value(dev_info_t *, uint32_t,
277 uint32_t, uint32_t, uint_t);
278 static int pcicfg_ari_configure(dev_info_t *);
279
280 #ifdef DEBUG
281 static void pcicfg_dump_common_config(ddi_acc_handle_t config_handle);
282 static void pcicfg_dump_device_config(ddi_acc_handle_t);
283 static void pcicfg_dump_bridge_config(ddi_acc_handle_t config_handle);
284 static uint64_t pcicfg_unused_space(hole_t *, uint32_t *);
285
286 #define PCICFG_DUMP_COMMON_CONFIG(hdl) (void)pcicfg_dump_common_config(hdl)
287 #define PCICFG_DUMP_DEVICE_CONFIG(hdl) (void)pcicfg_dump_device_config(hdl)
288 #define PCICFG_DUMP_BRIDGE_CONFIG(hdl) (void)pcicfg_dump_bridge_config(hdl)
289 #else
290 #define PCICFG_DUMP_COMMON_CONFIG(handle)
291 #define PCICFG_DUMP_DEVICE_CONFIG(handle)
292 #define PCICFG_DUMP_BRIDGE_CONFIG(handle)
293 #endif
294
295 static kmutex_t pcicfg_list_mutex; /* Protects the probe handle list */
296 static pcicfg_phdl_t *pcicfg_phdl_list = NULL;
297
298 #ifndef _DONT_USE_1275_GENERIC_NAMES
299 /*
300 * Class code table
301 */
302 static struct pcicfg_name_entry pcicfg_class_lookup [] = {
303
304 { 0x001, "display" },
305 { 0x100, "scsi" },
306 { 0x101, "ide" },
307 { 0x102, "fdc" },
308 { 0x103, "ipi" },
309 { 0x104, "raid" },
310 { 0x105, "ata" },
311 { 0x106, "sata" },
312 { 0x200, "ethernet" },
313 { 0x201, "token-ring" },
314 { 0x202, "fddi" },
315 { 0x203, "atm" },
316 { 0x204, "isdn" },
317 { 0x206, "mcd" },
318 { 0x300, "display" },
319 { 0x400, "video" },
320 { 0x401, "sound" },
321 { 0x500, "memory" },
322 { 0x501, "flash" },
323 { 0x600, "host" },
324 { 0x601, "isa" },
325 { 0x602, "eisa" },
326 { 0x603, "mca" },
327 { 0x604, "pci" },
328 { 0x605, "pcmcia" },
329 { 0x606, "nubus" },
330 { 0x607, "cardbus" },
331 { 0x609, "pci" },
332 { 0x60a, "ib-pci" },
333 { 0x700, "serial" },
334 { 0x701, "parallel" },
335 { 0x800, "interrupt-controller" },
336 { 0x801, "dma-controller" },
337 { 0x802, "timer" },
338 { 0x803, "rtc" },
339 { 0x900, "keyboard" },
340 { 0x901, "pen" },
341 { 0x902, "mouse" },
342 { 0xa00, "dock" },
343 { 0xb00, "cpu" },
344 { 0xb01, "cpu" },
345 { 0xb02, "cpu" },
346 { 0xb10, "cpu" },
347 { 0xb20, "cpu" },
348 { 0xb30, "cpu" },
349 { 0xb40, "coproc" },
350 { 0xc00, "firewire" },
351 { 0xc01, "access-bus" },
352 { 0xc02, "ssa" },
353 { 0xc03, "usb" },
354 { 0xc04, "fibre-channel" },
355 { 0xc05, "smbus" },
356 { 0xc06, "ib" },
357 { 0xd00, "irda" },
358 { 0xd01, "ir" },
359 { 0xd10, "rf" },
360 { 0xd11, "btooth" },
361 { 0xd12, "brdband" },
362 { 0xd20, "802.11a" },
363 { 0xd21, "802.11b" },
364 { 0xe00, "i2o" },
365 { 0xf01, "tv" },
366 { 0xf02, "audio" },
367 { 0xf03, "voice" },
368 { 0xf04, "data" },
369 { 0, 0 }
370 };
371 #endif /* _DONT_USE_1275_GENERIC_NAMES */
372
373 /*
374 * Module control operations
375 */
376
377 extern struct mod_ops mod_miscops;
378
379 static struct modlmisc modlmisc = {
380 &mod_miscops, /* Type of module */
381 "PCI configurator"
382 };
383
384 static struct modlinkage modlinkage = {
385 MODREV_1, (void *)&modlmisc, NULL
386 };
387
388
389 #ifdef DEBUG
390
391 static void
pcicfg_dump_common_config(ddi_acc_handle_t config_handle)392 pcicfg_dump_common_config(ddi_acc_handle_t config_handle)
393 {
394 if ((pcicfg_debug & 1) == 0)
395 return;
396 prom_printf(" Vendor ID = [0x%x]\n",
397 pci_config_get16(config_handle, PCI_CONF_VENID));
398 prom_printf(" Device ID = [0x%x]\n",
399 pci_config_get16(config_handle, PCI_CONF_DEVID));
400 prom_printf(" Command REG = [0x%x]\n",
401 pci_config_get16(config_handle, PCI_CONF_COMM));
402 prom_printf(" Status REG = [0x%x]\n",
403 pci_config_get16(config_handle, PCI_CONF_STAT));
404 prom_printf(" Revision ID = [0x%x]\n",
405 pci_config_get8(config_handle, PCI_CONF_REVID));
406 prom_printf(" Prog Class = [0x%x]\n",
407 pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
408 prom_printf(" Dev Class = [0x%x]\n",
409 pci_config_get8(config_handle, PCI_CONF_SUBCLASS));
410 prom_printf(" Base Class = [0x%x]\n",
411 pci_config_get8(config_handle, PCI_CONF_BASCLASS));
412 prom_printf(" Device ID = [0x%x]\n",
413 pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ));
414 prom_printf(" Header Type = [0x%x]\n",
415 pci_config_get8(config_handle, PCI_CONF_HEADER));
416 prom_printf(" BIST = [0x%x]\n",
417 pci_config_get8(config_handle, PCI_CONF_BIST));
418 prom_printf(" BASE 0 = [0x%x]\n",
419 pci_config_get32(config_handle, PCI_CONF_BASE0));
420 prom_printf(" BASE 1 = [0x%x]\n",
421 pci_config_get32(config_handle, PCI_CONF_BASE1));
422
423 }
424
425 static void
pcicfg_dump_device_config(ddi_acc_handle_t config_handle)426 pcicfg_dump_device_config(ddi_acc_handle_t config_handle)
427 {
428 if ((pcicfg_debug & 1) == 0)
429 return;
430 pcicfg_dump_common_config(config_handle);
431
432 prom_printf(" BASE 2 = [0x%x]\n",
433 pci_config_get32(config_handle, PCI_CONF_BASE2));
434 prom_printf(" BASE 3 = [0x%x]\n",
435 pci_config_get32(config_handle, PCI_CONF_BASE3));
436 prom_printf(" BASE 4 = [0x%x]\n",
437 pci_config_get32(config_handle, PCI_CONF_BASE4));
438 prom_printf(" BASE 5 = [0x%x]\n",
439 pci_config_get32(config_handle, PCI_CONF_BASE5));
440 prom_printf(" Cardbus CIS = [0x%x]\n",
441 pci_config_get32(config_handle, PCI_CONF_CIS));
442 prom_printf(" Sub VID = [0x%x]\n",
443 pci_config_get16(config_handle, PCI_CONF_SUBVENID));
444 prom_printf(" Sub SID = [0x%x]\n",
445 pci_config_get16(config_handle, PCI_CONF_SUBSYSID));
446 prom_printf(" ROM = [0x%x]\n",
447 pci_config_get32(config_handle, PCI_CONF_ROM));
448 prom_printf(" I Line = [0x%x]\n",
449 pci_config_get8(config_handle, PCI_CONF_ILINE));
450 prom_printf(" I Pin = [0x%x]\n",
451 pci_config_get8(config_handle, PCI_CONF_IPIN));
452 prom_printf(" Max Grant = [0x%x]\n",
453 pci_config_get8(config_handle, PCI_CONF_MIN_G));
454 prom_printf(" Max Latent = [0x%x]\n",
455 pci_config_get8(config_handle, PCI_CONF_MAX_L));
456 }
457
458 static void
pcicfg_dump_bridge_config(ddi_acc_handle_t config_handle)459 pcicfg_dump_bridge_config(ddi_acc_handle_t config_handle)
460 {
461 if ((pcicfg_debug & 1) == 0)
462 return;
463 pcicfg_dump_common_config(config_handle);
464
465 prom_printf("........................................\n");
466
467 prom_printf(" Pri Bus = [0x%x]\n",
468 pci_config_get8(config_handle, PCI_BCNF_PRIBUS));
469 prom_printf(" Sec Bus = [0x%x]\n",
470 pci_config_get8(config_handle, PCI_BCNF_SECBUS));
471 prom_printf(" Sub Bus = [0x%x]\n",
472 pci_config_get8(config_handle, PCI_BCNF_SUBBUS));
473 prom_printf(" Latency = [0x%x]\n",
474 pci_config_get8(config_handle, PCI_BCNF_LATENCY_TIMER));
475 prom_printf(" I/O Base LO = [0x%x]\n",
476 pci_config_get8(config_handle, PCI_BCNF_IO_BASE_LOW));
477 prom_printf(" I/O Lim LO = [0x%x]\n",
478 pci_config_get8(config_handle, PCI_BCNF_IO_LIMIT_LOW));
479 prom_printf(" Sec. Status = [0x%x]\n",
480 pci_config_get16(config_handle, PCI_BCNF_SEC_STATUS));
481 prom_printf(" Mem Base = [0x%x]\n",
482 pci_config_get16(config_handle, PCI_BCNF_MEM_BASE));
483 prom_printf(" Mem Limit = [0x%x]\n",
484 pci_config_get16(config_handle, PCI_BCNF_MEM_LIMIT));
485 prom_printf(" PF Mem Base = [0x%x]\n",
486 pci_config_get16(config_handle, PCI_BCNF_PF_BASE_LOW));
487 prom_printf(" PF Mem Lim = [0x%x]\n",
488 pci_config_get16(config_handle, PCI_BCNF_PF_LIMIT_LOW));
489 prom_printf(" PF Base HI = [0x%x]\n",
490 pci_config_get32(config_handle, PCI_BCNF_PF_BASE_HIGH));
491 prom_printf(" PF Lim HI = [0x%x]\n",
492 pci_config_get32(config_handle, PCI_BCNF_PF_LIMIT_HIGH));
493 prom_printf(" I/O Base HI = [0x%x]\n",
494 pci_config_get16(config_handle, PCI_BCNF_IO_BASE_HI));
495 prom_printf(" I/O Lim HI = [0x%x]\n",
496 pci_config_get16(config_handle, PCI_BCNF_IO_LIMIT_HI));
497 prom_printf(" ROM addr = [0x%x]\n",
498 pci_config_get32(config_handle, PCI_BCNF_ROM));
499 prom_printf(" Intr Line = [0x%x]\n",
500 pci_config_get8(config_handle, PCI_BCNF_ILINE));
501 prom_printf(" Intr Pin = [0x%x]\n",
502 pci_config_get8(config_handle, PCI_BCNF_IPIN));
503 prom_printf(" Bridge Ctrl = [0x%x]\n",
504 pci_config_get16(config_handle, PCI_BCNF_BCNTRL));
505 }
506 #endif
507
508 int
_init()509 _init()
510 {
511 DEBUG0(" PCI configurator installed\n");
512 mutex_init(&pcicfg_list_mutex, NULL, MUTEX_DRIVER, NULL);
513 return (mod_install(&modlinkage));
514 }
515
516 int
_fini(void)517 _fini(void)
518 {
519 int error;
520
521 error = mod_remove(&modlinkage);
522 if (error != 0) {
523 return (error);
524 }
525 mutex_destroy(&pcicfg_list_mutex);
526 return (0);
527 }
528
529 int
_info(struct modinfo * modinfop)530 _info(struct modinfo *modinfop)
531 {
532 return (mod_info(&modlinkage, modinfop));
533 }
534
535 /*
536 * In the following functions ndi_devi_enter() without holding the
537 * parent dip is sufficient. This is because pci dr is driven through
538 * opens on the nexus which is in the device tree path above the node
539 * being operated on, and implicitly held due to the open.
540 */
541
542 /*
543 * This entry point is called to configure a device (and
544 * all its children) on the given bus. It is called when
545 * a new device is added to the PCI domain. This routine
546 * will create the device tree and program the devices
547 * registers.
548 */
549 int
pcicfg_configure(dev_info_t * devi,uint_t device,uint_t function,pcicfg_flags_t flags)550 pcicfg_configure(dev_info_t *devi, uint_t device, uint_t function,
551 pcicfg_flags_t flags)
552 {
553 uint_t bus;
554 int len;
555 int func;
556 dev_info_t *attach_point;
557 pci_bus_range_t pci_bus_range;
558 int rv;
559 int circ;
560 uint_t highest_bus;
561 int ari_mode = B_FALSE;
562 int max_function = PCI_MAX_FUNCTIONS;
563 int trans_device;
564 dev_info_t *new_device;
565 boolean_t is_pcie;
566
567 if (flags == PCICFG_FLAG_ENABLE_ARI)
568 return (pcicfg_ari_configure(devi));
569
570 /*
571 * Start probing at the device specified in "device" on the
572 * "bus" specified.
573 */
574 len = sizeof (pci_bus_range_t);
575 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, devi, 0, "bus-range",
576 (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
577 DEBUG0("no bus-range property\n");
578 return (PCICFG_FAILURE);
579 }
580
581 bus = pci_bus_range.lo; /* primary bus number of this bus node */
582
583 attach_point = devi;
584
585 is_pcie = is_pcie_fabric(devi);
586
587 ndi_devi_enter(devi, &circ);
588 for (func = 0; func < max_function; ) {
589
590 if ((function != PCICFG_ALL_FUNC) && (function != func))
591 goto next;
592
593 if (ari_mode)
594 trans_device = func >> 3;
595 else
596 trans_device = device;
597
598 switch (rv = pcicfg_probe_children(attach_point,
599 bus, trans_device, func & 7, &highest_bus,
600 flags, is_pcie)) {
601 case PCICFG_NORESRC:
602 case PCICFG_FAILURE:
603 DEBUG2("configure failed: bus [0x%x] device "
604 "[0x%x]\n", bus, trans_device);
605 goto cleanup;
606 case PCICFG_NODEVICE:
607 DEBUG3("no device : bus "
608 "[0x%x] slot [0x%x] func [0x%x]\n",
609 bus, trans_device, func &7);
610
611 /*
612 * When walking the list of ARI functions
613 * we don't expect to see a non-present
614 * function, so we will stop walking
615 * the function list.
616 */
617 if (ari_mode == B_TRUE)
618 break;
619
620 if (func)
621 goto next;
622 break;
623 default:
624 DEBUG3("configure: bus => [%d] "
625 "slot => [%d] func => [%d]\n",
626 bus, trans_device, func & 7);
627 break;
628 }
629
630 if (rv != PCICFG_SUCCESS)
631 break;
632
633 if ((new_device = pcicfg_devi_find(attach_point,
634 trans_device, func & 7)) == NULL) {
635 DEBUG0("Did'nt find device node just created\n");
636 goto cleanup;
637 }
638
639 /*
640 * Up until now, we have detected a non transparent bridge
641 * (ntbridge) as a part of the generic probe code and
642 * configured only one configuration
643 * header which is the side facing the host bus.
644 * Now, configure the other side and create children.
645 *
646 * In order to make the process simpler, lets load the device
647 * driver for the non transparent bridge as this is a
648 * Solaris bundled driver, and use its configuration map
649 * services rather than programming it here.
650 * If the driver is not bundled into Solaris, it must be
651 * first loaded and configured before performing any
652 * hotplug operations.
653 *
654 * This not only makes the code here simpler but also more
655 * generic.
656 *
657 * So here we go.
658 */
659
660 /*
661 * check if this is a bridge in nontransparent mode
662 */
663 if (pcicfg_is_ntbridge(new_device) != DDI_FAILURE) {
664 DEBUG0("pcicfg: Found nontransparent bridge.\n");
665
666 rv = pcicfg_configure_ntbridge(new_device, bus,
667 trans_device);
668 if (rv != PCICFG_SUCCESS)
669 goto cleanup;
670 }
671
672 next:
673 /*
674 * Determine if ARI Forwarding should be enabled.
675 */
676 if (func == 0) {
677 if ((pcie_ari_supported(devi)
678 == PCIE_ARI_FORW_SUPPORTED) &&
679 (pcie_ari_device(new_device) == PCIE_ARI_DEVICE)) {
680 if (pcie_ari_enable(devi) == DDI_SUCCESS) {
681 (void) ddi_prop_create(DDI_DEV_T_NONE,
682 devi, DDI_PROP_CANSLEEP,
683 "ari-enabled", NULL, 0);
684
685 ari_mode = B_TRUE;
686 max_function = PCICFG_MAX_ARI_FUNCTION;
687 }
688 }
689 }
690 if (ari_mode == B_TRUE) {
691 int next_function;
692
693 DEBUG0("Next Function - ARI Device\n");
694 if (pcie_ari_get_next_function(new_device,
695 &next_function) != DDI_SUCCESS)
696 goto cleanup;
697
698 /*
699 * Check if there are more fucntions to probe.
700 */
701 if (next_function == 0) {
702 DEBUG0("Next Function - "
703 "No more ARI Functions\n");
704 break;
705 }
706 func = next_function;
707 } else {
708 func++;
709 }
710 DEBUG1("Next Function - %x\n", func);
711 }
712
713 ndi_devi_exit(devi, circ);
714
715 if (func == 0)
716 return (PCICFG_FAILURE); /* probe failed */
717 else
718 return (PCICFG_SUCCESS);
719
720 cleanup:
721 /*
722 * Clean up a partially created "probe state" tree.
723 * There are no resources allocated to the in the
724 * probe state.
725 */
726
727 for (func = 0; func < PCI_MAX_FUNCTIONS; func++) {
728 if ((function != PCICFG_ALL_FUNC) && (function != func))
729 continue;
730
731 if ((new_device = pcicfg_devi_find(devi, device, func))
732 == NULL) {
733 continue;
734 }
735
736 DEBUG2("Cleaning up device [0x%x] function [0x%x]\n",
737 device, func);
738 /*
739 * If this was a bridge device it will have a
740 * probe handle - if not, no harm in calling this.
741 */
742 (void) pcicfg_destroy_phdl(new_device);
743 if (is_pcie) {
744 /*
745 * free pcie_bus_t for the sub-tree
746 */
747 if (ddi_get_child(new_device) != NULL)
748 pcie_fab_fini_bus(new_device, PCIE_BUS_ALL);
749
750 pcie_fini_bus(new_device, PCIE_BUS_ALL);
751 }
752 /*
753 * This will free up the node
754 */
755 (void) ndi_devi_offline(new_device, NDI_DEVI_REMOVE);
756 }
757 ndi_devi_exit(devi, circ);
758
759 /*
760 * Use private return codes to help identify issues without debugging
761 * enabled. Resource limitations and mis-configurations are
762 * probably the most likely caue of configuration failures on x86.
763 * Convert return code back to values expected by the external
764 * consumer before returning so we will warn only once on the first
765 * encountered failure.
766 */
767 if (rv == PCICFG_NORESRC) {
768 char *path = kmem_alloc(MAXPATHLEN, KM_SLEEP);
769
770 (void) ddi_pathname(devi, path);
771 cmn_err(CE_CONT, "?Not enough PCI resources to "
772 "configure: %s\n", path);
773
774 kmem_free(path, MAXPATHLEN);
775 rv = PCICFG_FAILURE;
776 }
777
778 return (rv);
779 }
780
781 /*
782 * configure the child nodes of ntbridge. new_device points to ntbridge itself
783 */
784 /*ARGSUSED*/
785 static int
pcicfg_configure_ntbridge(dev_info_t * new_device,uint_t bus,uint_t device)786 pcicfg_configure_ntbridge(dev_info_t *new_device, uint_t bus, uint_t device)
787 {
788 int bus_range[2], rc = PCICFG_FAILURE, rc1, max_devs = 0;
789 int devno;
790 dev_info_t *new_ntbridgechild;
791 ddi_acc_handle_t config_handle;
792 uint16_t vid;
793 uint64_t next_bus;
794 uint64_t blen;
795 ndi_ra_request_t req;
796 uint8_t pcie_device_type = 0;
797
798 /*
799 * If we need to do indirect config, lets create a property here
800 * to let the child conf map routine know that it has to
801 * go through the DDI calls, and not assume the devices are
802 * mapped directly under the host.
803 */
804 if ((rc = ndi_prop_update_int(DDI_DEV_T_NONE, new_device,
805 PCI_DEV_CONF_MAP_PROP, (int)DDI_SUCCESS)) != DDI_SUCCESS) {
806 DEBUG0("Cannot create indirect conf map property.\n");
807 return ((int)PCICFG_FAILURE);
808 }
809
810 if (pci_config_setup(new_device, &config_handle) != DDI_SUCCESS)
811 return (PCICFG_FAILURE);
812 /* check if we are PCIe device */
813 if (pcicfg_pcie_device_type(new_device, config_handle) == DDI_SUCCESS) {
814 DEBUG0("PCIe device detected\n");
815 pcie_device_type = 1;
816 }
817 pci_config_teardown(&config_handle);
818 /* create Bus node properties for ntbridge. */
819 if (pcicfg_set_busnode_props(new_device, pcie_device_type)
820 != PCICFG_SUCCESS) {
821 DEBUG0("Failed to set busnode props\n");
822 return (rc);
823 }
824
825 /* For now: Lets only support one layer of child */
826 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
827 req.ra_len = 1;
828 if (ndi_ra_alloc(ddi_get_parent(new_device), &req, &next_bus, &blen,
829 NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
830 DEBUG0("ntbridge: Failed to get a bus number\n");
831 return (PCICFG_NORESRC);
832 }
833
834 DEBUG1("ntbridge bus range start ->[%d]\n", next_bus);
835
836 /*
837 * Following will change, as we detect more bridges
838 * on the way.
839 */
840 bus_range[0] = (int)next_bus;
841 bus_range[1] = (int)next_bus;
842
843 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, new_device, "bus-range",
844 bus_range, 2) != DDI_SUCCESS) {
845 DEBUG0("Cannot set ntbridge bus-range property");
846 return (rc);
847 }
848
849 /*
850 * The other interface (away from the host) will be
851 * initialized by the nexus driver when it loads.
852 * We just have to set the registers and the nexus driver
853 * figures out the rest.
854 */
855
856 /*
857 * finally, lets load and attach the driver
858 * before configuring children of ntbridge.
859 */
860 rc = ndi_devi_online(new_device, NDI_ONLINE_ATTACH|NDI_CONFIG);
861 if (rc != NDI_SUCCESS) {
862 cmn_err(CE_WARN,
863 "pcicfg: Fail:cant load nontransparent bridgd driver..\n");
864 rc = PCICFG_FAILURE;
865 return (rc);
866 }
867 DEBUG0("pcicfg: Success loading nontransparent bridge nexus driver..");
868
869 /* Now set aside pci resource allocation requests for our children */
870 if (pcicfg_ntbridge_allocate_resources(new_device) != PCICFG_SUCCESS) {
871 max_devs = 0;
872 rc = PCICFG_FAILURE;
873 } else
874 max_devs = PCI_MAX_DEVICES;
875
876 /* Probe devices on 2nd bus */
877 rc = PCICFG_SUCCESS;
878 for (devno = pcicfg_start_devno; devno < max_devs; devno++) {
879
880 ndi_devi_alloc_sleep(new_device, DEVI_PSEUDO_NEXNAME,
881 (pnode_t)DEVI_SID_NODEID, &new_ntbridgechild);
882
883 if (pcicfg_add_config_reg(new_ntbridgechild, next_bus, devno, 0)
884 != DDI_PROP_SUCCESS) {
885 cmn_err(CE_WARN,
886 "Failed to add conf reg for ntbridge child.\n");
887 (void) ndi_devi_free(new_ntbridgechild);
888 rc = PCICFG_FAILURE;
889 break;
890 }
891
892 if (pci_config_setup(new_ntbridgechild, &config_handle)
893 != DDI_SUCCESS) {
894 cmn_err(CE_WARN,
895 "Cannot map ntbridge child %x\n", devno);
896 (void) ndi_devi_free(new_ntbridgechild);
897 rc = PCICFG_FAILURE;
898 break;
899 }
900
901 /*
902 * See if there is any PCI HW at this location
903 * by reading the Vendor ID. If it returns with 0xffff
904 * then there is no hardware at this location.
905 */
906 vid = pci_config_get16(config_handle, PCI_CONF_VENID);
907
908 pci_config_teardown(&config_handle);
909 (void) ndi_devi_free(new_ntbridgechild);
910 if (vid == 0xffff)
911 continue;
912
913 /* Lets fake attachments points for each child, */
914 rc = pcicfg_configure(new_device, devno, PCICFG_ALL_FUNC, 0);
915 if (rc != PCICFG_SUCCESS) {
916 int old_dev = pcicfg_start_devno;
917
918 cmn_err(CE_WARN,
919 "Error configuring ntbridge child dev=%d\n", devno);
920
921 while (old_dev != devno) {
922 if (pcicfg_ntbridge_unconfigure_child(
923 new_device, old_dev) == PCICFG_FAILURE)
924 cmn_err(CE_WARN, "Unconfig Error "
925 "ntbridge child dev=%d\n", old_dev);
926 old_dev++;
927 }
928 break;
929 }
930 } /* devno loop */
931 DEBUG1("ntbridge: finish probing 2nd bus, rc=%d\n", rc);
932
933 if (rc == PCICFG_SUCCESS)
934 rc = pcicfg_ntbridge_configure_done(new_device);
935 else {
936 pcicfg_phdl_t *entry = pcicfg_find_phdl(new_device);
937 uint_t *bus;
938 int k;
939
940 if (ddi_getlongprop(DDI_DEV_T_ANY, new_device,
941 DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus, &k)
942 != DDI_PROP_SUCCESS) {
943 DEBUG0("Failed to read bus-range property\n");
944 rc = PCICFG_FAILURE;
945 return (rc);
946 }
947
948 DEBUG2("Need to free bus [%d] range [%d]\n",
949 bus[0], bus[1] - bus[0] + 1);
950
951 if (ndi_ra_free(ddi_get_parent(new_device), (uint64_t)bus[0],
952 (uint64_t)(bus[1] - bus[0] + 1), NDI_RA_TYPE_PCI_BUSNUM,
953 NDI_RA_PASS) != NDI_SUCCESS) {
954 DEBUG0("Failed to free a bus number\n");
955 rc = PCICFG_FAILURE;
956 kmem_free(bus, k);
957 return (rc);
958 }
959
960 /*
961 * Since no memory allocations are done for non transparent
962 * bridges (but instead we just set the handle with the
963 * already allocated memory, we just need to reset the
964 * following values before calling the destroy_phdl()
965 * function next, otherwise the it will try to free
966 * memory allocated as in case of a transparent bridge.
967 */
968 entry->memory_len = 0;
969 entry->pf_memory_len = 0;
970 entry->io_len = 0;
971 kmem_free(bus, k);
972 /* the following will free hole data. */
973 (void) pcicfg_destroy_phdl(new_device);
974 }
975
976 /*
977 * Unload driver just in case child configure failed!
978 */
979 rc1 = ndi_devi_offline(new_device, 0);
980 DEBUG1("pcicfg: now unloading the ntbridge driver. rc1=%d\n", rc1);
981 if (rc1 != NDI_SUCCESS) {
982 cmn_err(CE_WARN,
983 "pcicfg: cant unload ntbridge driver..children.\n");
984 rc = PCICFG_FAILURE;
985 }
986
987 return (rc);
988 }
989
990 static int
pcicfg_ntbridge_allocate_resources(dev_info_t * dip)991 pcicfg_ntbridge_allocate_resources(dev_info_t *dip)
992 {
993 pcicfg_phdl_t *phdl;
994 ndi_ra_request_t *mem_request;
995 ndi_ra_request_t *pf_mem_request;
996 ndi_ra_request_t *io_request;
997 uint64_t boundbase, boundlen;
998
999 phdl = pcicfg_find_phdl(dip);
1000 ASSERT(phdl);
1001
1002 mem_request = &phdl->mem_req;
1003 pf_mem_request = &phdl->pf_mem_req;
1004 io_request = &phdl->io_req;
1005
1006 phdl->error = PCICFG_SUCCESS;
1007
1008 /* Set Memory space handle for ntbridge */
1009 if (pcicfg_get_ntbridge_child_range(dip, &boundbase, &boundlen,
1010 PCI_BASE_SPACE_MEM) != DDI_SUCCESS) {
1011 cmn_err(CE_WARN,
1012 "ntbridge: Mem resource information failure\n");
1013 phdl->memory_len = 0;
1014 return (PCICFG_FAILURE);
1015 }
1016 mem_request->ra_boundbase = boundbase;
1017 mem_request->ra_boundlen = boundbase + boundlen;
1018 mem_request->ra_len = boundlen;
1019 mem_request->ra_align_mask =
1020 PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
1021 mem_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1022
1023 /*
1024 * mem_request->ra_len =
1025 * PCICFG_ROUND_UP(mem_request->ra_len, PCICFG_MEMGRAN);
1026 */
1027
1028 phdl->memory_base = phdl->memory_last = boundbase;
1029 phdl->memory_len = boundlen;
1030 phdl->mem_hole.start = phdl->memory_base;
1031 phdl->mem_hole.len = mem_request->ra_len;
1032 phdl->mem_hole.next = (hole_t *)NULL;
1033
1034 DEBUG2("Connector requested [0x%llx], needs [0x%llx] bytes of memory\n",
1035 boundlen, mem_request->ra_len);
1036
1037 /* Set IO space handle for ntbridge */
1038 if (pcicfg_get_ntbridge_child_range(dip, &boundbase, &boundlen,
1039 PCI_BASE_SPACE_IO) != DDI_SUCCESS) {
1040 cmn_err(CE_WARN, "ntbridge: IO resource information failure\n");
1041 phdl->io_len = 0;
1042 return (PCICFG_FAILURE);
1043 }
1044 io_request->ra_len = boundlen;
1045 io_request->ra_align_mask =
1046 PCICFG_IOGRAN - 1; /* 4K alignment on I/O space */
1047 io_request->ra_boundbase = boundbase;
1048 io_request->ra_boundlen = boundbase + boundlen;
1049 io_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1050
1051 /*
1052 * io_request->ra_len =
1053 * PCICFG_ROUND_UP(io_request->ra_len, PCICFG_IOGRAN);
1054 */
1055
1056 phdl->io_base = phdl->io_last = (uint32_t)boundbase;
1057 phdl->io_len = (uint32_t)boundlen;
1058 phdl->io_hole.start = phdl->io_base;
1059 phdl->io_hole.len = io_request->ra_len;
1060 phdl->io_hole.next = (hole_t *)NULL;
1061
1062 DEBUG2("Connector requested [0x%llx], needs [0x%llx] bytes of IO\n",
1063 boundlen, io_request->ra_len);
1064
1065 /* Set Prefetchable Memory space handle for ntbridge */
1066 if (pcicfg_get_ntbridge_child_range(dip, &boundbase, &boundlen,
1067 PCI_BASE_SPACE_MEM | PCI_BASE_PREF_M) != DDI_SUCCESS) {
1068 cmn_err(CE_WARN,
1069 "ntbridge: PF Mem resource information failure\n");
1070 phdl->pf_memory_len = 0;
1071 return (PCICFG_FAILURE);
1072 }
1073 pf_mem_request->ra_boundbase = boundbase;
1074 pf_mem_request->ra_boundlen = boundbase + boundlen;
1075 pf_mem_request->ra_len = boundlen;
1076 pf_mem_request->ra_align_mask =
1077 PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
1078 pf_mem_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1079
1080 /*
1081 * pf_mem_request->ra_len =
1082 * PCICFG_ROUND_UP(pf_mem_request->ra_len, PCICFG_MEMGRAN);
1083 */
1084
1085 phdl->pf_memory_base = phdl->pf_memory_last = boundbase;
1086 phdl->pf_memory_len = boundlen;
1087 phdl->pf_mem_hole.start = phdl->pf_memory_base;
1088 phdl->pf_mem_hole.len = pf_mem_request->ra_len;
1089 phdl->pf_mem_hole.next = (hole_t *)NULL;
1090
1091 DEBUG2("Connector requested [0x%llx], needs [0x%llx] bytes of PF "
1092 "memory\n", boundlen, pf_mem_request->ra_len);
1093
1094 DEBUG2("MEMORY BASE = [0x%lx] length [0x%lx]\n",
1095 phdl->memory_base, phdl->memory_len);
1096 DEBUG2("IO BASE = [0x%x] length [0x%x]\n",
1097 phdl->io_base, phdl->io_len);
1098 DEBUG2("PF MEMORY BASE = [0x%lx] length [0x%lx]\n",
1099 phdl->pf_memory_base, phdl->pf_memory_len);
1100
1101 return (PCICFG_SUCCESS);
1102 }
1103
1104 static int
pcicfg_ntbridge_configure_done(dev_info_t * dip)1105 pcicfg_ntbridge_configure_done(dev_info_t *dip)
1106 {
1107 ppb_ranges_t range[PCICFG_RANGE_LEN];
1108 pcicfg_phdl_t *entry;
1109 uint_t len;
1110 pci_bus_range_t bus_range;
1111 int new_bus_range[2];
1112
1113 DEBUG1("Configuring children for %p\n", dip);
1114
1115 entry = pcicfg_find_phdl(dip);
1116 ASSERT(entry);
1117
1118 bzero((caddr_t)range, sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
1119 range[1].child_high = range[1].parent_high |=
1120 (PCI_REG_REL_M | PCI_ADDR_MEM32);
1121 range[1].child_low = range[1].parent_low = (uint32_t)entry->memory_base;
1122
1123 range[0].child_high = range[0].parent_high |=
1124 (PCI_REG_REL_M | PCI_ADDR_IO);
1125 range[0].child_low = range[0].parent_low = (uint32_t)entry->io_base;
1126
1127 range[2].child_high = range[2].parent_high |=
1128 (PCI_REG_REL_M | PCI_ADDR_MEM32 | PCI_REG_PF_M);
1129 range[2].child_low = range[2].parent_low =
1130 (uint32_t)entry->pf_memory_base;
1131
1132 len = sizeof (pci_bus_range_t);
1133 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1134 "bus-range", (caddr_t)&bus_range, (int *)&len) != DDI_SUCCESS) {
1135 DEBUG0("no bus-range property\n");
1136 return (PCICFG_FAILURE);
1137 }
1138
1139 new_bus_range[0] = bus_range.lo; /* primary bus number */
1140 if (entry->highest_bus) { /* secondary bus number */
1141 if (entry->highest_bus < bus_range.lo) {
1142 cmn_err(CE_WARN,
1143 "ntbridge bus range invalid !(%d,%d)\n",
1144 bus_range.lo, entry->highest_bus);
1145 new_bus_range[1] = bus_range.lo + entry->highest_bus;
1146 }
1147 else
1148 new_bus_range[1] = entry->highest_bus;
1149 }
1150 else
1151 new_bus_range[1] = bus_range.hi;
1152
1153 DEBUG2("ntbridge: bus range lo=%x, hi=%x\n", new_bus_range[0],
1154 new_bus_range[1]);
1155
1156 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "bus-range",
1157 new_bus_range, 2) != DDI_SUCCESS) {
1158 DEBUG0("Failed to set bus-range property");
1159 entry->error = PCICFG_FAILURE;
1160 return (PCICFG_FAILURE);
1161 }
1162
1163 #ifdef DEBUG
1164 {
1165 uint64_t unused;
1166 unused = pcicfg_unused_space(&entry->io_hole, &len);
1167 DEBUG2("ntbridge: Unused IO space %llx bytes over %d holes\n",
1168 unused, len);
1169 }
1170 #endif
1171
1172 range[0].size_low = entry->io_len;
1173 if (pcicfg_update_ranges_prop(dip, &range[0])) {
1174 DEBUG0("Failed to update ranges (i/o)\n");
1175 entry->error = PCICFG_FAILURE;
1176 return (PCICFG_FAILURE);
1177 }
1178
1179 #ifdef DEBUG
1180 {
1181 uint64_t unused;
1182 unused = pcicfg_unused_space(&entry->mem_hole, &len);
1183 DEBUG2("ntbridge: Unused Mem space %llx bytes over %d holes\n",
1184 unused, len);
1185 }
1186 #endif
1187
1188 range[1].size_low = entry->memory_len;
1189 if (pcicfg_update_ranges_prop(dip, &range[1])) {
1190 DEBUG0("Failed to update ranges (memory)\n");
1191 entry->error = PCICFG_FAILURE;
1192 return (PCICFG_FAILURE);
1193 }
1194
1195 #ifdef DEBUG
1196 {
1197 uint64_t unused;
1198 unused = pcicfg_unused_space(&entry->pf_mem_hole, &len);
1199 DEBUG2("ntbridge: Unused PF Mem space %llx bytes over"
1200 " %d holes\n", unused, len);
1201 }
1202 #endif
1203
1204 range[2].size_low = entry->pf_memory_len;
1205 if (pcicfg_update_ranges_prop(dip, &range[2])) {
1206 DEBUG0("Failed to update ranges (PF memory)\n");
1207 entry->error = PCICFG_FAILURE;
1208 return (PCICFG_FAILURE);
1209 }
1210
1211 return (PCICFG_SUCCESS);
1212 }
1213
1214 static int
pcicfg_ntbridge_program_child(dev_info_t * dip)1215 pcicfg_ntbridge_program_child(dev_info_t *dip)
1216 {
1217 pcicfg_phdl_t *entry;
1218 int rc = PCICFG_SUCCESS;
1219 dev_info_t *anode = dip;
1220
1221 /* Find the Hotplug Connection (CN) node */
1222 while ((anode != NULL) &&
1223 (strcmp(ddi_binding_name(anode), "hp_attachment") != 0)) {
1224 anode = ddi_get_parent(anode);
1225 }
1226
1227 if (anode == NULL) {
1228 DEBUG0("ntbridge child tree not in PROBE state\n");
1229 return (PCICFG_FAILURE);
1230 }
1231 entry = pcicfg_find_phdl(ddi_get_parent(anode));
1232 ASSERT(entry);
1233
1234 if (pcicfg_bridge_assign(dip, entry) == DDI_WALK_TERMINATE) {
1235 cmn_err(CE_WARN,
1236 "ntbridge: Error assigning range for child %s\n",
1237 ddi_get_name(dip));
1238 rc = PCICFG_FAILURE;
1239 }
1240 return (rc);
1241 }
1242
1243 static int
pcicfg_ntbridge_unconfigure_child(dev_info_t * new_device,uint_t devno)1244 pcicfg_ntbridge_unconfigure_child(dev_info_t *new_device, uint_t devno)
1245 {
1246
1247 dev_info_t *new_ntbridgechild;
1248 int len, bus;
1249 uint16_t vid;
1250 ddi_acc_handle_t config_handle;
1251 pci_bus_range_t pci_bus_range;
1252
1253 len = sizeof (pci_bus_range_t);
1254 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, new_device, DDI_PROP_DONTPASS,
1255 "bus-range", (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
1256 DEBUG0("no bus-range property\n");
1257 return (PCICFG_FAILURE);
1258 }
1259
1260 bus = pci_bus_range.lo; /* primary bus number of this bus node */
1261
1262 ndi_devi_alloc_sleep(new_device, DEVI_PSEUDO_NEXNAME,
1263 (pnode_t)DEVI_SID_NODEID, &new_ntbridgechild);
1264
1265 if (pcicfg_add_config_reg(new_ntbridgechild, bus, devno, 0)
1266 != DDI_PROP_SUCCESS) {
1267 cmn_err(CE_WARN, "Unconfigure: Failed to add conf reg prop for "
1268 "ntbridge child.\n");
1269 (void) ndi_devi_free(new_ntbridgechild);
1270 return (PCICFG_FAILURE);
1271 }
1272
1273 if (pci_config_setup(new_ntbridgechild, &config_handle)
1274 != DDI_SUCCESS) {
1275 cmn_err(CE_WARN, "pcicfg: Cannot map ntbridge child %x\n",
1276 devno);
1277 (void) ndi_devi_free(new_ntbridgechild);
1278 return (PCICFG_FAILURE);
1279 }
1280
1281 /*
1282 * See if there is any PCI HW at this location
1283 * by reading the Vendor ID. If it returns with 0xffff
1284 * then there is no hardware at this location.
1285 */
1286 vid = pci_config_get16(config_handle, PCI_CONF_VENID);
1287
1288 pci_config_teardown(&config_handle);
1289 (void) ndi_devi_free(new_ntbridgechild);
1290 if (vid == 0xffff)
1291 return (PCICFG_NODEVICE);
1292
1293 return (pcicfg_unconfigure(new_device, devno, PCICFG_ALL_FUNC, 0));
1294 }
1295
1296 static uint_t
pcicfg_ntbridge_unconfigure(dev_info_t * dip)1297 pcicfg_ntbridge_unconfigure(dev_info_t *dip)
1298 {
1299 pcicfg_phdl_t *entry = pcicfg_find_phdl(dip);
1300 uint_t *bus;
1301 int k, rc = DDI_FAILURE;
1302
1303 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "bus-range",
1304 (caddr_t)&bus, &k) != DDI_PROP_SUCCESS) {
1305 DEBUG0("ntbridge: Failed to read bus-range property\n");
1306 return (rc);
1307 }
1308
1309 DEBUG2("ntbridge: Need to free bus [%d] range [%d]\n",
1310 bus[0], bus[1] - bus[0] + 1);
1311
1312 if (ndi_ra_free(ddi_get_parent(dip), (uint64_t)bus[0],
1313 (uint64_t)(bus[1] - bus[0] + 1),
1314 NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
1315 DEBUG0("ntbridge: Failed to free a bus number\n");
1316 kmem_free(bus, k);
1317 return (rc);
1318 }
1319
1320 /*
1321 * Since our resources will be freed at the parent level,
1322 * just reset these values.
1323 */
1324 entry->memory_len = 0;
1325 entry->io_len = 0;
1326 entry->pf_memory_len = 0;
1327
1328 kmem_free(bus, k);
1329
1330 /* the following will also free hole data. */
1331 return (pcicfg_destroy_phdl(dip));
1332
1333 }
1334
1335 static int
pcicfg_is_ntbridge(dev_info_t * dip)1336 pcicfg_is_ntbridge(dev_info_t *dip)
1337 {
1338 ddi_acc_handle_t config_handle;
1339 uint8_t class, subclass;
1340 int rc = DDI_SUCCESS;
1341
1342 if (pci_config_setup(dip, &config_handle) != DDI_SUCCESS) {
1343 cmn_err(CE_WARN,
1344 "pcicfg: cannot map config space, to get map type\n");
1345 return (DDI_FAILURE);
1346 }
1347 class = pci_config_get8(config_handle, PCI_CONF_BASCLASS);
1348 subclass = pci_config_get8(config_handle, PCI_CONF_SUBCLASS);
1349
1350 /* check for class=6, subclass=9, for non transparent bridges. */
1351 if ((class != PCI_CLASS_BRIDGE) || (subclass != PCI_BRIDGE_STBRIDGE))
1352 rc = DDI_FAILURE;
1353
1354 DEBUG3("pcicfg: checking device %x,%x for indirect map. rc=%d\n",
1355 pci_config_get16(config_handle, PCI_CONF_VENID),
1356 pci_config_get16(config_handle, PCI_CONF_DEVID),
1357 rc);
1358 pci_config_teardown(&config_handle);
1359 return (rc);
1360 }
1361
1362 static uint_t
pcicfg_ntbridge_child(dev_info_t * dip)1363 pcicfg_ntbridge_child(dev_info_t *dip)
1364 {
1365 int len, val, rc = DDI_FAILURE;
1366 dev_info_t *anode = dip;
1367
1368 /*
1369 * Find the Hotplug Connection (CN) node
1370 */
1371 while ((anode != NULL) && (strcmp(ddi_binding_name(anode),
1372 "hp_attachment") != 0)) {
1373 anode = ddi_get_parent(anode);
1374 }
1375
1376 if (anode == NULL) {
1377 DEBUG0("ntbridge child tree not in PROBE state\n");
1378 return (rc);
1379 }
1380 len = sizeof (int);
1381 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, ddi_get_parent(anode),
1382 DDI_PROP_DONTPASS, PCI_DEV_CONF_MAP_PROP, (caddr_t)&val, &len)
1383 != DDI_SUCCESS) {
1384
1385 DEBUG1("ntbridge child: no \"%s\" property\n",
1386 PCI_DEV_CONF_MAP_PROP);
1387 return (rc);
1388 }
1389 DEBUG0("ntbridge child: success\n");
1390 return (DDI_SUCCESS);
1391 }
1392
1393 static uint_t
pcicfg_get_ntbridge_child_range(dev_info_t * dip,uint64_t * boundbase,uint64_t * boundlen,uint_t space_type)1394 pcicfg_get_ntbridge_child_range(dev_info_t *dip, uint64_t *boundbase,
1395 uint64_t *boundlen, uint_t space_type)
1396 {
1397 int length, found = DDI_FAILURE, acount, i, ibridge;
1398 pci_regspec_t *assigned;
1399
1400 if ((ibridge = pcicfg_is_ntbridge(dip)) == DDI_FAILURE)
1401 return (found);
1402
1403 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1404 "assigned-addresses", (caddr_t)&assigned, &length)
1405 != DDI_PROP_SUCCESS) {
1406 DEBUG1("Failed to get assigned-addresses property %llx\n", dip);
1407 return (found);
1408 }
1409 DEBUG1("pcicfg: ntbridge child range: dip = %s\n",
1410 ddi_driver_name(dip));
1411
1412 acount = length / sizeof (pci_regspec_t);
1413
1414 for (i = 0; i < acount; i++) {
1415 if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) ==
1416 pcicfg_indirect_map_devs[ibridge].mem_range_bar_offset) &&
1417 (space_type == PCI_BASE_SPACE_MEM)) {
1418 found = DDI_SUCCESS;
1419 break;
1420 } else if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) ==
1421 pcicfg_indirect_map_devs[ibridge].io_range_bar_offset) &&
1422 (space_type == PCI_BASE_SPACE_IO)) {
1423 found = DDI_SUCCESS;
1424 break;
1425 } else if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) ==
1426 pcicfg_indirect_map_devs[ibridge].
1427 prefetch_mem_range_bar_offset) &&
1428 (space_type == (PCI_BASE_SPACE_MEM |
1429 PCI_BASE_PREF_M))) {
1430 found = DDI_SUCCESS;
1431 break;
1432 }
1433 }
1434 DEBUG3("pcicfg: ntbridge child range: space=%x, base=%lx, len=%lx\n",
1435 space_type, assigned[i].pci_phys_low, assigned[i].pci_size_low);
1436
1437 if (found == DDI_SUCCESS) {
1438 *boundbase = assigned[i].pci_phys_low;
1439 *boundlen = assigned[i].pci_size_low;
1440 }
1441
1442 kmem_free(assigned, length);
1443 return (found);
1444 }
1445
1446 /*
1447 * This will turn resources allocated by pcicfg_configure()
1448 * and remove the device tree from the Hotplug Connection (CN)
1449 * and below. The routine assumes the devices have their
1450 * drivers detached.
1451 */
1452 int
pcicfg_unconfigure(dev_info_t * devi,uint_t device,uint_t function,pcicfg_flags_t flags)1453 pcicfg_unconfigure(dev_info_t *devi, uint_t device, uint_t function,
1454 pcicfg_flags_t flags)
1455 {
1456 dev_info_t *child_dip;
1457 int func;
1458 int i;
1459 int max_function, trans_device;
1460 int circ;
1461 boolean_t is_pcie;
1462
1463 if (pcie_ari_is_enabled(devi) == PCIE_ARI_FORW_ENABLED)
1464 max_function = PCICFG_MAX_ARI_FUNCTION;
1465 else
1466 max_function = PCI_MAX_FUNCTIONS;
1467
1468 /*
1469 * Cycle through devices to make sure none are busy.
1470 * If a single device is busy fail the whole unconfigure.
1471 */
1472 is_pcie = is_pcie_fabric(devi);
1473
1474 ndi_devi_enter(devi, &circ);
1475 for (func = 0; func < max_function; func++) {
1476 if ((function != PCICFG_ALL_FUNC) && (function != func))
1477 continue;
1478
1479 if (max_function == PCICFG_MAX_ARI_FUNCTION)
1480 trans_device = func >> 3; /* ARI Device */
1481 else
1482 trans_device = device;
1483
1484 if ((child_dip = pcicfg_devi_find(devi, trans_device,
1485 func & 7)) == NULL)
1486 continue;
1487
1488 if (ndi_devi_offline(child_dip, NDI_UNCONFIG) == NDI_SUCCESS)
1489 continue;
1490
1491 /*
1492 * Device function is busy. Before returning we have to
1493 * put all functions back online which were taken
1494 * offline during the process.
1495 */
1496 DEBUG2("Device [0x%x] function [0x%x] is busy\n",
1497 trans_device, func & 7);
1498 /*
1499 * If we are only asked to offline one specific function,
1500 * and that fails, we just simply return.
1501 */
1502 if (function != PCICFG_ALL_FUNC)
1503 return (PCICFG_FAILURE);
1504
1505 for (i = 0; i < func; i++) {
1506 if (max_function == PCICFG_MAX_ARI_FUNCTION)
1507 trans_device = i >> 3;
1508
1509 if ((child_dip = pcicfg_devi_find(devi, trans_device,
1510 i & 7)) == NULL) {
1511 DEBUG0("No more devices to put back "
1512 "on line!!\n");
1513 /*
1514 * Made it through all functions
1515 */
1516 continue;
1517 }
1518 if (ndi_devi_online(child_dip, NDI_CONFIG)
1519 != NDI_SUCCESS) {
1520 DEBUG0("Failed to put back devices state\n");
1521 goto fail;
1522 }
1523 }
1524 goto fail;
1525 }
1526
1527 /*
1528 * Now, tear down all devinfo nodes for this Connector.
1529 */
1530 for (func = 0; func < max_function; func++) {
1531 if ((function != PCICFG_ALL_FUNC) && (function != func))
1532 continue;
1533
1534 if (max_function == PCICFG_MAX_ARI_FUNCTION)
1535 trans_device = func >> 3; /* ARI Device */
1536 else
1537 trans_device = device;
1538
1539 if ((child_dip = pcicfg_devi_find(devi, trans_device, func & 7))
1540 == NULL) {
1541 DEBUG2("No device at %x,%x\n", trans_device, func & 7);
1542 continue;
1543 }
1544
1545 DEBUG2("Tearing down device [0x%x] function [0x%x]\n",
1546 trans_device, func & 7);
1547
1548 if (pcicfg_is_ntbridge(child_dip) != DDI_FAILURE)
1549 if (pcicfg_ntbridge_unconfigure(child_dip) !=
1550 PCICFG_SUCCESS) {
1551 cmn_err(CE_WARN,
1552 "ntbridge: unconfigure failed\n");
1553 goto fail;
1554 }
1555
1556 if (pcicfg_teardown_device(child_dip, flags, is_pcie)
1557 != PCICFG_SUCCESS) {
1558 DEBUG2("Failed to tear down device [0x%x]"
1559 "function [0x%x]\n", trans_device, func & 7);
1560 goto fail;
1561 }
1562 }
1563
1564 if (pcie_ari_is_enabled(devi) == PCIE_ARI_FORW_ENABLED) {
1565 (void) ddi_prop_remove(DDI_DEV_T_NONE, devi, "ari-enabled");
1566 (void) pcie_ari_disable(devi);
1567 }
1568
1569 ndi_devi_exit(devi, circ);
1570 return (PCICFG_SUCCESS);
1571
1572 fail:
1573 ndi_devi_exit(devi, circ);
1574 return (PCICFG_FAILURE);
1575 }
1576
1577 static int
pcicfg_teardown_device(dev_info_t * dip,pcicfg_flags_t flags,boolean_t is_pcie)1578 pcicfg_teardown_device(dev_info_t *dip, pcicfg_flags_t flags, boolean_t is_pcie)
1579 {
1580 ddi_acc_handle_t handle;
1581
1582 /*
1583 * Free up resources associated with 'dip'
1584 */
1585 if (pcicfg_free_resources(dip, flags) != PCICFG_SUCCESS) {
1586 DEBUG0("Failed to free resources\n");
1587 return (PCICFG_FAILURE);
1588 }
1589
1590 /*
1591 * disable the device
1592 */
1593 if (pcicfg_config_setup(dip, &handle) != PCICFG_SUCCESS)
1594 return (PCICFG_FAILURE);
1595 pcicfg_device_off(handle);
1596 pcicfg_config_teardown(&handle);
1597
1598 if (is_pcie) {
1599 /*
1600 * free pcie_bus_t for the sub-tree
1601 */
1602 if (ddi_get_child(dip) != NULL)
1603 pcie_fab_fini_bus(dip, PCIE_BUS_ALL);
1604
1605 pcie_fini_bus(dip, PCIE_BUS_ALL);
1606 }
1607
1608 /*
1609 * The framework provides this routine which can
1610 * tear down a sub-tree.
1611 */
1612 if (ndi_devi_offline(dip, NDI_DEVI_REMOVE) != NDI_SUCCESS) {
1613 DEBUG0("Failed to offline and remove node\n");
1614 return (PCICFG_FAILURE);
1615 }
1616
1617 return (PCICFG_SUCCESS);
1618 }
1619
1620 /*
1621 * BEGIN GENERIC SUPPORT ROUTINES
1622 */
1623 static pcicfg_phdl_t *
pcicfg_find_phdl(dev_info_t * dip)1624 pcicfg_find_phdl(dev_info_t *dip)
1625 {
1626 pcicfg_phdl_t *entry;
1627 mutex_enter(&pcicfg_list_mutex);
1628 for (entry = pcicfg_phdl_list; entry != NULL; entry = entry->next) {
1629 if (entry->dip == dip) {
1630 mutex_exit(&pcicfg_list_mutex);
1631 return (entry);
1632 }
1633 }
1634 mutex_exit(&pcicfg_list_mutex);
1635
1636 /*
1637 * Did'nt find entry - create one
1638 */
1639 return (pcicfg_create_phdl(dip));
1640 }
1641
1642 static pcicfg_phdl_t *
pcicfg_create_phdl(dev_info_t * dip)1643 pcicfg_create_phdl(dev_info_t *dip)
1644 {
1645 pcicfg_phdl_t *new;
1646
1647 new = (pcicfg_phdl_t *)kmem_zalloc(sizeof (pcicfg_phdl_t), KM_SLEEP);
1648
1649 new->dip = dip;
1650 mutex_enter(&pcicfg_list_mutex);
1651 new->next = pcicfg_phdl_list;
1652 pcicfg_phdl_list = new;
1653 mutex_exit(&pcicfg_list_mutex);
1654
1655 return (new);
1656 }
1657
1658 static int
pcicfg_destroy_phdl(dev_info_t * dip)1659 pcicfg_destroy_phdl(dev_info_t *dip)
1660 {
1661 pcicfg_phdl_t *entry;
1662 pcicfg_phdl_t *follow = NULL;
1663
1664 mutex_enter(&pcicfg_list_mutex);
1665 for (entry = pcicfg_phdl_list; entry != NULL; follow = entry,
1666 entry = entry->next) {
1667 if (entry->dip == dip) {
1668 if (entry == pcicfg_phdl_list) {
1669 pcicfg_phdl_list = entry->next;
1670 } else {
1671 follow->next = entry->next;
1672 }
1673 /*
1674 * If this entry has any allocated memory
1675 * or IO space associated with it, that
1676 * must be freed up.
1677 */
1678 if (entry->memory_len > 0) {
1679 (void) ndi_ra_free(ddi_get_parent(dip),
1680 entry->memory_base, entry->memory_len,
1681 NDI_RA_TYPE_MEM, NDI_RA_PASS);
1682 }
1683 pcicfg_free_hole(&entry->mem_hole);
1684
1685 if (entry->io_len > 0) {
1686 (void) ndi_ra_free(ddi_get_parent(dip),
1687 entry->io_base, entry->io_len,
1688 NDI_RA_TYPE_IO, NDI_RA_PASS);
1689 }
1690 pcicfg_free_hole(&entry->io_hole);
1691
1692 if (entry->pf_memory_len > 0) {
1693 (void) ndi_ra_free(ddi_get_parent(dip),
1694 entry->pf_memory_base, entry->pf_memory_len,
1695 NDI_RA_TYPE_PCI_PREFETCH_MEM, NDI_RA_PASS);
1696 }
1697 pcicfg_free_hole(&entry->pf_mem_hole);
1698
1699 /*
1700 * Destroy this entry
1701 */
1702 kmem_free((caddr_t)entry, sizeof (pcicfg_phdl_t));
1703 mutex_exit(&pcicfg_list_mutex);
1704 return (PCICFG_SUCCESS);
1705 }
1706 }
1707 mutex_exit(&pcicfg_list_mutex);
1708 /*
1709 * Did'nt find the entry
1710 */
1711 return (PCICFG_FAILURE);
1712 }
1713
1714 static int
pcicfg_bridge_assign(dev_info_t * dip,void * hdl)1715 pcicfg_bridge_assign(dev_info_t *dip, void *hdl)
1716 {
1717 ddi_acc_handle_t handle;
1718 pci_regspec_t *reg;
1719 int length;
1720 int rcount;
1721 int i;
1722 int offset;
1723 uint64_t mem_answer;
1724 uint32_t io_answer;
1725 int count;
1726 uint8_t header_type;
1727 ppb_ranges_t range[PCICFG_RANGE_LEN];
1728 int bus_range[2];
1729 uint64_t mem_residual;
1730 uint64_t pf_mem_residual;
1731 uint64_t io_residual;
1732
1733 pcicfg_phdl_t *entry = (pcicfg_phdl_t *)hdl;
1734
1735 DEBUG1("bridge assign: assigning addresses to %s\n", ddi_get_name(dip));
1736
1737 entry->error = PCICFG_SUCCESS;
1738
1739 if (entry == NULL) {
1740 DEBUG0("Failed to get entry\n");
1741 entry->error = PCICFG_FAILURE;
1742 return (DDI_WALK_TERMINATE);
1743 }
1744
1745 if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
1746 DEBUG0("Failed to map config space!\n");
1747 entry->error = PCICFG_FAILURE;
1748 return (DDI_WALK_TERMINATE);
1749 }
1750
1751 header_type = pci_config_get8(handle, PCI_CONF_HEADER);
1752
1753 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
1754
1755 bzero((caddr_t)range, sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
1756
1757 (void) pcicfg_setup_bridge(entry, handle);
1758
1759 range[0].child_high = range[0].parent_high |=
1760 (PCI_REG_REL_M | PCI_ADDR_IO);
1761 range[0].child_low = range[0].parent_low = entry->io_last;
1762 range[1].child_high = range[1].parent_high |=
1763 (PCI_REG_REL_M | PCI_ADDR_MEM32);
1764 range[1].child_low = range[1].parent_low =
1765 entry->memory_last;
1766 range[2].child_high = range[2].parent_high |=
1767 (PCI_REG_REL_M | PCI_ADDR_MEM32 | PCI_REG_PF_M);
1768 range[2].child_low = range[2].parent_low =
1769 entry->pf_memory_last;
1770
1771 ndi_devi_enter(dip, &count);
1772 ddi_walk_devs(ddi_get_child(dip),
1773 pcicfg_bridge_assign, (void *)entry);
1774 ndi_devi_exit(dip, count);
1775
1776 (void) pcicfg_update_bridge(entry, handle);
1777
1778 bus_range[0] = pci_config_get8(handle, PCI_BCNF_SECBUS);
1779 bus_range[1] = pci_config_get8(handle, PCI_BCNF_SUBBUS);
1780
1781 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
1782 "bus-range", bus_range, 2) != DDI_SUCCESS) {
1783 DEBUG0("Failed to set bus-range property");
1784 entry->error = PCICFG_FAILURE;
1785 (void) pcicfg_config_teardown(&handle);
1786 return (DDI_WALK_TERMINATE);
1787 }
1788
1789 /*
1790 * Put back memory and I/O space not allocated
1791 * under the bridge.
1792 */
1793 mem_residual = entry->memory_len -
1794 (entry->memory_last - entry->memory_base);
1795 if (mem_residual > 0) {
1796 (void) ndi_ra_free(ddi_get_parent(dip),
1797 entry->memory_last, mem_residual,
1798 NDI_RA_TYPE_MEM, NDI_RA_PASS);
1799 }
1800
1801 io_residual = entry->io_len - (entry->io_last - entry->io_base);
1802 if (io_residual > 0) {
1803 (void) ndi_ra_free(ddi_get_parent(dip), entry->io_last,
1804 io_residual, NDI_RA_TYPE_IO, NDI_RA_PASS);
1805 }
1806
1807 pf_mem_residual = entry->pf_memory_len -
1808 (entry->pf_memory_last - entry->pf_memory_base);
1809 if (pf_mem_residual > 0) {
1810 (void) ndi_ra_free(ddi_get_parent(dip),
1811 entry->pf_memory_last, pf_mem_residual,
1812 NDI_RA_TYPE_PCI_PREFETCH_MEM, NDI_RA_PASS);
1813 }
1814
1815 if (entry->io_len > 0) {
1816 range[0].size_low = entry->io_last - entry->io_base;
1817 if (pcicfg_update_ranges_prop(dip, &range[0])) {
1818 DEBUG0("Failed to update ranges (i/o)\n");
1819 entry->error = PCICFG_FAILURE;
1820 (void) pcicfg_config_teardown(&handle);
1821 return (DDI_WALK_TERMINATE);
1822 }
1823 }
1824 if (entry->memory_len > 0) {
1825 range[1].size_low =
1826 entry->memory_last - entry->memory_base;
1827 if (pcicfg_update_ranges_prop(dip, &range[1])) {
1828 DEBUG0("Failed to update ranges (memory)\n");
1829 entry->error = PCICFG_FAILURE;
1830 (void) pcicfg_config_teardown(&handle);
1831 return (DDI_WALK_TERMINATE);
1832 }
1833 }
1834 if (entry->pf_memory_len > 0) {
1835 range[2].size_low =
1836 entry->pf_memory_last - entry->pf_memory_base;
1837 if (pcicfg_update_ranges_prop(dip, &range[2])) {
1838 DEBUG0("Failed to update ranges (PF memory)\n");
1839 entry->error = PCICFG_FAILURE;
1840 (void) pcicfg_config_teardown(&handle);
1841 return (DDI_WALK_TERMINATE);
1842 }
1843 }
1844
1845 (void) pcicfg_device_on(handle);
1846
1847 PCICFG_DUMP_BRIDGE_CONFIG(handle);
1848
1849 (void) pcicfg_config_teardown(&handle);
1850
1851 return (DDI_WALK_PRUNECHILD);
1852 }
1853
1854 /*
1855 * If there is an interrupt pin set program
1856 * interrupt line with default values.
1857 */
1858 if (pci_config_get8(handle, PCI_CONF_IPIN)) {
1859 pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
1860 }
1861
1862 /*
1863 * A single device (under a bridge).
1864 * For each "reg" property with a length, allocate memory
1865 * and program the base registers.
1866 */
1867 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg",
1868 (caddr_t)®, &length) != DDI_PROP_SUCCESS) {
1869 DEBUG0("Failed to read reg property\n");
1870 entry->error = PCICFG_FAILURE;
1871 (void) pcicfg_config_teardown(&handle);
1872 return (DDI_WALK_TERMINATE);
1873 }
1874
1875 rcount = length / sizeof (pci_regspec_t);
1876 offset = PCI_CONF_BASE0;
1877 for (i = 0; i < rcount; i++) {
1878 if ((reg[i].pci_size_low != 0) || (reg[i].pci_size_hi != 0)) {
1879
1880 offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
1881
1882 switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
1883 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
1884
1885 if (reg[i].pci_phys_hi & PCI_REG_PF_M) {
1886 /* allocate prefetchable memory */
1887 pcicfg_get_pf_mem(entry,
1888 reg[i].pci_size_low, &mem_answer);
1889 } else { /* get non prefetchable memory */
1890 pcicfg_get_mem(entry,
1891 reg[i].pci_size_low, &mem_answer);
1892 }
1893 pci_config_put64(handle, offset, mem_answer);
1894 DEBUG2("REGISTER off %x (64)LO ----> [0x%x]\n",
1895 offset, pci_config_get32(handle, offset));
1896 DEBUG2("REGISTER off %x (64)HI ----> [0x%x]\n",
1897 offset + 4,
1898 pci_config_get32(handle, offset + 4));
1899
1900 reg[i].pci_phys_hi |= PCI_REG_REL_M;
1901 reg[i].pci_phys_low = PCICFG_LOADDR(mem_answer);
1902 reg[i].pci_phys_mid = PCICFG_HIADDR(mem_answer);
1903 break;
1904
1905 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
1906 if (reg[i].pci_phys_hi & PCI_REG_PF_M) {
1907 /* allocate prefetchable memory */
1908 pcicfg_get_pf_mem(entry,
1909 reg[i].pci_size_low, &mem_answer);
1910 } else {
1911 /* get non prefetchable memory */
1912 pcicfg_get_mem(entry,
1913 reg[i].pci_size_low, &mem_answer);
1914 }
1915
1916 pci_config_put32(handle, offset,
1917 (uint32_t)mem_answer);
1918
1919 DEBUG2("REGISTER off %x(32)LO ----> [0x%x]\n",
1920 offset, pci_config_get32(handle, offset));
1921
1922 reg[i].pci_phys_hi |= PCI_REG_REL_M;
1923 reg[i].pci_phys_low = (uint32_t)mem_answer;
1924
1925 break;
1926 case PCI_REG_ADDR_G(PCI_ADDR_IO):
1927 /* allocate I/O space from the allocator */
1928
1929 (void) pcicfg_get_io(entry, reg[i].pci_size_low,
1930 &io_answer);
1931 pci_config_put32(handle, offset, io_answer);
1932
1933 DEBUG2("REGISTER off %x (I/O)LO ----> [0x%x]\n",
1934 offset, pci_config_get32(handle, offset));
1935
1936 reg[i].pci_phys_hi |= PCI_REG_REL_M;
1937 reg[i].pci_phys_low = io_answer;
1938
1939 break;
1940 default:
1941 DEBUG0("Unknown register type\n");
1942 kmem_free(reg, length);
1943 (void) pcicfg_config_teardown(&handle);
1944 entry->error = PCICFG_FAILURE;
1945 return (DDI_WALK_TERMINATE);
1946 } /* switch */
1947
1948 /*
1949 * Now that memory locations are assigned,
1950 * update the assigned address property.
1951 */
1952 if (pcicfg_update_assigned_prop(dip, ®[i])
1953 != PCICFG_SUCCESS) {
1954 kmem_free(reg, length);
1955 (void) pcicfg_config_teardown(&handle);
1956 entry->error = PCICFG_FAILURE;
1957 return (DDI_WALK_TERMINATE);
1958 }
1959 }
1960 }
1961 (void) pcicfg_device_on(handle);
1962
1963 PCICFG_DUMP_DEVICE_CONFIG(handle);
1964
1965 (void) pcicfg_config_teardown(&handle);
1966 kmem_free((caddr_t)reg, length);
1967 return (DDI_WALK_CONTINUE);
1968 }
1969
1970 static int
pcicfg_device_assign(dev_info_t * dip)1971 pcicfg_device_assign(dev_info_t *dip)
1972 {
1973 ddi_acc_handle_t handle;
1974 pci_regspec_t *reg;
1975 int length;
1976 int rcount;
1977 int i;
1978 int offset;
1979 ndi_ra_request_t request;
1980 uint64_t answer;
1981 uint64_t alen;
1982
1983 DEBUG1("%llx now under configuration\n", dip);
1984
1985 /* request.ra_len = PCICFG_ROUND_UP(request.ra_len, PCICFG_IOGRAN); */
1986 if (pcicfg_ntbridge_child(dip) == DDI_SUCCESS) {
1987
1988 return (pcicfg_ntbridge_program_child(dip));
1989 }
1990 /*
1991 * XXX Failure here should be noted
1992 */
1993 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg",
1994 (caddr_t)®, &length) != DDI_PROP_SUCCESS) {
1995 DEBUG0("Failed to read reg property\n");
1996 return (PCICFG_FAILURE);
1997 }
1998
1999 if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2000 DEBUG0("Failed to map config space!\n");
2001 kmem_free(reg, length);
2002 return (PCICFG_FAILURE);
2003 }
2004
2005 /*
2006 * A single device
2007 *
2008 * For each "reg" property with a length, allocate memory
2009 * and program the base registers.
2010 */
2011
2012 /*
2013 * If there is an interrupt pin set program
2014 * interrupt line with default values.
2015 */
2016 if (pci_config_get8(handle, PCI_CONF_IPIN)) {
2017 pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
2018 }
2019
2020 bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
2021
2022 /*
2023 * Note: Both non-prefetchable and prefetchable memory space
2024 * allocations are made within 32bit space. Currently, BIOSs
2025 * allocate device memory for PCI devices within the 32bit space
2026 * so this will not be a problem.
2027 */
2028 request.ra_flags |= NDI_RA_ALIGN_SIZE | NDI_RA_ALLOC_BOUNDED;
2029 request.ra_boundbase = 0;
2030 request.ra_boundlen = PCICFG_4GIG_LIMIT;
2031
2032 rcount = length / sizeof (pci_regspec_t);
2033 offset = PCI_CONF_BASE0;
2034 for (i = 0; i < rcount; i++) {
2035 char *mem_type;
2036
2037 if ((reg[i].pci_size_low != 0)|| (reg[i].pci_size_hi != 0)) {
2038
2039 offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
2040 request.ra_len = reg[i].pci_size_low;
2041
2042 switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
2043 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2044 if (reg[i].pci_phys_hi & PCI_REG_PF_M) {
2045 mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2046 } else {
2047 mem_type = NDI_RA_TYPE_MEM;
2048 }
2049 /* allocate memory space from the allocator */
2050 if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2051 &answer, &alen, mem_type, NDI_RA_PASS)
2052 != NDI_SUCCESS) {
2053 DEBUG0("Failed to allocate 64b mem\n");
2054 kmem_free(reg, length);
2055 (void) pcicfg_config_teardown(&handle);
2056 return (PCICFG_NORESRC);
2057 }
2058 DEBUG3("64 addr = [0x%x.0x%x] len [0x%x]\n",
2059 PCICFG_HIADDR(answer),
2060 PCICFG_LOADDR(answer), alen);
2061 /* program the low word */
2062 pci_config_put32(handle, offset,
2063 PCICFG_LOADDR(answer));
2064 /* program the high word */
2065 pci_config_put32(handle, offset + 4,
2066 PCICFG_HIADDR(answer));
2067
2068 reg[i].pci_phys_hi |= PCI_REG_REL_M;
2069 reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2070 reg[i].pci_phys_mid = PCICFG_HIADDR(answer);
2071 /*
2072 * currently support 32b address space
2073 * assignments only.
2074 */
2075 reg[i].pci_phys_hi ^=
2076 PCI_ADDR_MEM64 ^ PCI_ADDR_MEM32;
2077
2078 offset += 8;
2079 break;
2080
2081 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2082 if (reg[i].pci_phys_hi & PCI_REG_PF_M)
2083 mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2084 else
2085 mem_type = NDI_RA_TYPE_MEM;
2086 /* allocate memory space from the allocator */
2087 if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2088 &answer, &alen, mem_type, NDI_RA_PASS)
2089 != NDI_SUCCESS) {
2090 DEBUG0("Failed to allocate 32b mem\n");
2091 kmem_free(reg, length);
2092 (void) pcicfg_config_teardown(&handle);
2093 return (PCICFG_NORESRC);
2094 }
2095 DEBUG3("32 addr = [0x%x.0x%x] len [0x%x]\n",
2096 PCICFG_HIADDR(answer),
2097 PCICFG_LOADDR(answer),
2098 alen);
2099 /* program the low word */
2100 pci_config_put32(handle, offset,
2101 PCICFG_LOADDR(answer));
2102
2103 reg[i].pci_phys_hi |= PCI_REG_REL_M;
2104 reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2105 reg[i].pci_phys_mid = 0;
2106
2107 offset += 4;
2108 break;
2109 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2110 /*
2111 * Try to allocate I/O space. If it fails,
2112 * continue here instead of returning failure
2113 * so that the hotplug for drivers that don't
2114 * use I/O space can succeed, For drivers
2115 * that need to use I/O space, the hotplug
2116 * will still fail later during driver attach.
2117 */
2118 if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2119 &answer, &alen, NDI_RA_TYPE_IO, NDI_RA_PASS)
2120 != NDI_SUCCESS) {
2121 DEBUG0("Failed to allocate I/O\n");
2122 continue;
2123 }
2124 DEBUG3("I/O addr = [0x%x.0x%x] len [0x%x]\n",
2125 PCICFG_HIADDR(answer),
2126 PCICFG_LOADDR(answer), alen);
2127 pci_config_put32(handle, offset,
2128 PCICFG_LOADDR(answer));
2129
2130 reg[i].pci_phys_hi |= PCI_REG_REL_M;
2131 reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2132
2133 offset += 4;
2134 break;
2135 default:
2136 DEBUG0("Unknown register type\n");
2137 kmem_free(reg, length);
2138 (void) pcicfg_config_teardown(&handle);
2139 return (PCICFG_FAILURE);
2140 } /* switch */
2141
2142 /*
2143 * Now that memory locations are assigned,
2144 * update the assigned address property.
2145 */
2146
2147 if (pcicfg_update_assigned_prop(dip, ®[i])
2148 != PCICFG_SUCCESS) {
2149 kmem_free(reg, length);
2150 (void) pcicfg_config_teardown(&handle);
2151 return (PCICFG_FAILURE);
2152 }
2153 }
2154 }
2155
2156 (void) pcicfg_device_on(handle);
2157 kmem_free(reg, length);
2158
2159 PCICFG_DUMP_DEVICE_CONFIG(handle);
2160
2161 (void) pcicfg_config_teardown(&handle);
2162 return (PCICFG_SUCCESS);
2163 }
2164
2165 static int
pcicfg_device_assign_readonly(dev_info_t * dip)2166 pcicfg_device_assign_readonly(dev_info_t *dip)
2167 {
2168 ddi_acc_handle_t handle;
2169 pci_regspec_t *assigned;
2170 int length;
2171 int acount;
2172 int i;
2173 ndi_ra_request_t request;
2174 uint64_t answer;
2175 uint64_t alen;
2176
2177 DEBUG1("%llx now under configuration\n", dip);
2178
2179 /*
2180 * we don't support ntbridges for readonly probe.
2181 */
2182 if (pcicfg_ntbridge_child(dip) == DDI_SUCCESS) {
2183 return (PCICFG_FAILURE);
2184 }
2185
2186 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2187 DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
2188 &length) != DDI_PROP_SUCCESS) {
2189 DEBUG0("Failed to read assigned-addresses property\n");
2190 return (PCICFG_FAILURE);
2191 }
2192
2193 if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2194 DEBUG0("Failed to map config space!\n");
2195 kmem_free(assigned, length);
2196 return (PCICFG_FAILURE);
2197 }
2198
2199 /*
2200 * If there is an interrupt pin set program
2201 * interrupt line with default values.
2202 */
2203 if (pci_config_get8(handle, PCI_CONF_IPIN)) {
2204 pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
2205 }
2206 /*
2207 * Note: Both non-prefetchable and prefetchable memory space
2208 * allocations are made within 32bit space. Currently, BIOSs
2209 * allocate device memory for PCI devices within the 32bit space
2210 * so this will not be a problem.
2211 */
2212 bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
2213
2214 request.ra_flags = NDI_RA_ALLOC_SPECIFIED; /* specified addr */
2215 request.ra_boundbase = 0;
2216 request.ra_boundlen = PCICFG_4GIG_LIMIT;
2217
2218 acount = length / sizeof (pci_regspec_t);
2219 for (i = 0; i < acount; i++) {
2220 char *mem_type;
2221
2222 if ((assigned[i].pci_size_low != 0)||
2223 (assigned[i].pci_size_hi != 0)) {
2224
2225 request.ra_len = assigned[i].pci_size_low;
2226
2227 switch (PCI_REG_ADDR_G(assigned[i].pci_phys_hi)) {
2228 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2229 request.ra_addr = (uint64_t)PCICFG_LADDR(
2230 assigned[i].pci_phys_low,
2231 assigned[i].pci_phys_mid);
2232
2233 if (assigned[i].pci_phys_hi & PCI_REG_PF_M) {
2234 mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2235 } else {
2236 mem_type = NDI_RA_TYPE_MEM;
2237 }
2238 /* allocate memory space from the allocator */
2239 if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2240 &answer, &alen, mem_type, NDI_RA_PASS)
2241 != NDI_SUCCESS) {
2242 DEBUG0("Failed to allocate 64b mem\n");
2243 kmem_free(assigned, length);
2244 return (PCICFG_NORESRC);
2245 }
2246
2247 break;
2248 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2249 request.ra_addr = (uint64_t)
2250 assigned[i].pci_phys_low;
2251
2252 if (assigned[i].pci_phys_hi & PCI_REG_PF_M)
2253 mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2254 else
2255 mem_type = NDI_RA_TYPE_MEM;
2256 /* allocate memory space from the allocator */
2257 if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2258 &answer, &alen, mem_type, NDI_RA_PASS)
2259 != NDI_SUCCESS) {
2260 DEBUG0("Failed to allocate 32b mem\n");
2261 kmem_free(assigned, length);
2262 return (PCICFG_NORESRC);
2263 }
2264
2265 break;
2266 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2267 request.ra_addr = (uint64_t)
2268 assigned[i].pci_phys_low;
2269
2270 /* allocate I/O space from the allocator */
2271 if (ndi_ra_alloc(ddi_get_parent(dip), &request,
2272 &answer, &alen, NDI_RA_TYPE_IO, NDI_RA_PASS)
2273 != NDI_SUCCESS) {
2274 DEBUG0("Failed to allocate I/O\n");
2275 kmem_free(assigned, length);
2276 return (PCICFG_NORESRC);
2277 }
2278
2279 break;
2280 default:
2281 DEBUG0("Unknown register type\n");
2282 kmem_free(assigned, length);
2283 return (PCICFG_FAILURE);
2284 } /* switch */
2285 }
2286 }
2287
2288 (void) pcicfg_device_on(handle);
2289 kmem_free(assigned, length);
2290
2291 PCICFG_DUMP_DEVICE_CONFIG(handle);
2292
2293 (void) pcicfg_config_teardown(&handle);
2294 return (PCICFG_SUCCESS);
2295 }
2296
2297 #ifdef DEBUG
2298 /*
2299 * This function is useful in debug mode, where we can measure how
2300 * much memory was wasted/unallocated in bridge device's domain.
2301 */
2302 static uint64_t
pcicfg_unused_space(hole_t * hole,uint32_t * hole_count)2303 pcicfg_unused_space(hole_t *hole, uint32_t *hole_count)
2304 {
2305 uint64_t len = 0;
2306 uint32_t count = 0;
2307
2308 do {
2309 len += hole->len;
2310 hole = hole->next;
2311 count++;
2312 } while (hole);
2313 *hole_count = count;
2314 return (len);
2315 }
2316 #endif
2317
2318 /*
2319 * This function frees data structures that hold the hole information
2320 * which are allocated in pcicfg_alloc_hole(). This is not freeing
2321 * any memory allocated through NDI calls.
2322 */
2323 static void
pcicfg_free_hole(hole_t * addr_hole)2324 pcicfg_free_hole(hole_t *addr_hole)
2325 {
2326 hole_t *nhole, *hole = addr_hole->next;
2327
2328 while (hole) {
2329 nhole = hole->next;
2330 kmem_free(hole, sizeof (hole_t));
2331 hole = nhole;
2332 }
2333 }
2334
2335 static uint64_t
pcicfg_alloc_hole(hole_t * addr_hole,uint64_t * alast,uint32_t length)2336 pcicfg_alloc_hole(hole_t *addr_hole, uint64_t *alast, uint32_t length)
2337 {
2338 uint64_t actual_hole_start, ostart, olen;
2339 hole_t *hole = addr_hole, *thole, *nhole;
2340
2341 do {
2342 actual_hole_start = PCICFG_ROUND_UP(hole->start, length);
2343 if (((actual_hole_start - hole->start) + length) <= hole->len) {
2344 DEBUG3("hole found. start %llx, len %llx, req=0x%x\n",
2345 hole->start, hole->len, length);
2346 ostart = hole->start;
2347 olen = hole->len;
2348 /* current hole parameters adjust */
2349 if ((actual_hole_start - hole->start) == 0) {
2350 hole->start += length;
2351 hole->len -= length;
2352 if (hole->start > *alast)
2353 *alast = hole->start;
2354 } else {
2355 hole->len = actual_hole_start - hole->start;
2356 nhole = (hole_t *)kmem_zalloc(sizeof (hole_t),
2357 KM_SLEEP);
2358 nhole->start = actual_hole_start + length;
2359 nhole->len = (ostart + olen) - nhole->start;
2360 nhole->next = NULL;
2361 thole = hole->next;
2362 hole->next = nhole;
2363 nhole->next = thole;
2364 if (nhole->start > *alast)
2365 *alast = nhole->start;
2366 DEBUG2("put new hole to %llx, %llx\n",
2367 nhole->start, nhole->len);
2368 }
2369 DEBUG2("adjust current hole to %llx, %llx\n",
2370 hole->start, hole->len);
2371 break;
2372 }
2373 actual_hole_start = 0;
2374 hole = hole->next;
2375 } while (hole);
2376
2377 DEBUG1("return hole at %llx\n", actual_hole_start);
2378 return (actual_hole_start);
2379 }
2380
2381 static void
pcicfg_get_mem(pcicfg_phdl_t * entry,uint32_t length,uint64_t * ans)2382 pcicfg_get_mem(pcicfg_phdl_t *entry, uint32_t length, uint64_t *ans)
2383 {
2384 uint64_t new_mem;
2385
2386 /* See if there is a hole, that can hold this request. */
2387 new_mem = pcicfg_alloc_hole(&entry->mem_hole, &entry->memory_last,
2388 length);
2389 if (new_mem) { /* if non-zero, found a hole. */
2390 if (ans != NULL)
2391 *ans = new_mem;
2392 } else
2393 cmn_err(CE_WARN, "No %u bytes memory window for %s\n",
2394 length, ddi_get_name(entry->dip));
2395 }
2396
2397 static void
pcicfg_get_io(pcicfg_phdl_t * entry,uint32_t length,uint32_t * ans)2398 pcicfg_get_io(pcicfg_phdl_t *entry,
2399 uint32_t length, uint32_t *ans)
2400 {
2401 uint32_t new_io;
2402 uint64_t io_last;
2403
2404 /*
2405 * See if there is a hole, that can hold this request.
2406 * Pass 64 bit parameters and then truncate to 32 bit.
2407 */
2408 io_last = entry->io_last;
2409 new_io = (uint32_t)pcicfg_alloc_hole(&entry->io_hole, &io_last, length);
2410 if (new_io) { /* if non-zero, found a hole. */
2411 entry->io_last = (uint32_t)io_last;
2412 if (ans != NULL)
2413 *ans = new_io;
2414 } else
2415 cmn_err(CE_WARN, "No %u bytes IO space window for %s\n",
2416 length, ddi_get_name(entry->dip));
2417 }
2418
2419 static void
pcicfg_get_pf_mem(pcicfg_phdl_t * entry,uint32_t length,uint64_t * ans)2420 pcicfg_get_pf_mem(pcicfg_phdl_t *entry, uint32_t length, uint64_t *ans)
2421 {
2422 uint64_t new_mem;
2423
2424 /* See if there is a hole, that can hold this request. */
2425 new_mem = pcicfg_alloc_hole(&entry->pf_mem_hole, &entry->pf_memory_last,
2426 length);
2427 if (new_mem) { /* if non-zero, found a hole. */
2428 if (ans != NULL)
2429 *ans = new_mem;
2430 } else
2431 cmn_err(CE_WARN, "No %u bytes PF memory window for %s\n",
2432 length, ddi_get_name(entry->dip));
2433 }
2434
2435 static int
pcicfg_sum_resources(dev_info_t * dip,void * hdl)2436 pcicfg_sum_resources(dev_info_t *dip, void *hdl)
2437 {
2438 pcicfg_phdl_t *entry = (pcicfg_phdl_t *)hdl;
2439 pci_regspec_t *pci_rp;
2440 int length;
2441 int rcount;
2442 int i;
2443 ndi_ra_request_t *pf_mem_request;
2444 ndi_ra_request_t *mem_request;
2445 ndi_ra_request_t *io_request;
2446 uint8_t header_type;
2447 ddi_acc_handle_t handle;
2448
2449 entry->error = PCICFG_SUCCESS;
2450
2451 pf_mem_request = &entry->pf_mem_req;
2452 mem_request = &entry->mem_req;
2453 io_request = &entry->io_req;
2454
2455 if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2456 DEBUG0("Failed to map config space!\n");
2457 entry->error = PCICFG_FAILURE;
2458 return (DDI_WALK_TERMINATE);
2459 }
2460
2461 header_type = pci_config_get8(handle, PCI_CONF_HEADER);
2462
2463 /*
2464 * If its a bridge - just record the highest bus seen
2465 */
2466 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
2467
2468 if (entry->highest_bus < pci_config_get8(handle,
2469 PCI_BCNF_SECBUS)) {
2470 entry->highest_bus =
2471 pci_config_get8(handle, PCI_BCNF_SECBUS);
2472 }
2473 (void) pcicfg_config_teardown(&handle);
2474 entry->error = PCICFG_FAILURE;
2475 return (DDI_WALK_CONTINUE);
2476 } else {
2477 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2478 "reg", (caddr_t)&pci_rp, &length) != DDI_PROP_SUCCESS) {
2479 /*
2480 * If one node in (the subtree of nodes)
2481 * doesn't have a "reg" property fail the
2482 * allocation.
2483 */
2484 entry->memory_len = 0;
2485 entry->io_len = 0;
2486 entry->pf_memory_len = 0;
2487 entry->error = PCICFG_FAILURE;
2488 (void) pcicfg_config_teardown(&handle);
2489 return (DDI_WALK_TERMINATE);
2490 }
2491 /*
2492 * For each "reg" property with a length, add that to the
2493 * total memory (or I/O) to allocate.
2494 */
2495 rcount = length / sizeof (pci_regspec_t);
2496
2497 for (i = 0; i < rcount; i++) {
2498
2499 switch (PCI_REG_ADDR_G(pci_rp[i].pci_phys_hi)) {
2500
2501 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2502 if (pci_rp[i].pci_phys_hi & PCI_REG_PF_M) {
2503 pf_mem_request->ra_len =
2504 pci_rp[i].pci_size_low +
2505 PCICFG_ROUND_UP(
2506 pf_mem_request->ra_len,
2507 pci_rp[i].pci_size_low);
2508 DEBUG1("ADDING 32 --->0x%x\n",
2509 pci_rp[i].pci_size_low);
2510 } else {
2511 mem_request->ra_len =
2512 pci_rp[i].pci_size_low +
2513 PCICFG_ROUND_UP(mem_request->ra_len,
2514 pci_rp[i].pci_size_low);
2515 DEBUG1("ADDING 32 --->0x%x\n",
2516 pci_rp[i].pci_size_low);
2517 }
2518
2519 break;
2520 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2521 if (pci_rp[i].pci_phys_hi & PCI_REG_PF_M) {
2522 pf_mem_request->ra_len =
2523 pci_rp[i].pci_size_low +
2524 PCICFG_ROUND_UP(
2525 pf_mem_request->ra_len,
2526 pci_rp[i].pci_size_low);
2527 DEBUG1("ADDING 64 --->0x%x\n",
2528 pci_rp[i].pci_size_low);
2529 } else {
2530 mem_request->ra_len =
2531 pci_rp[i].pci_size_low +
2532 PCICFG_ROUND_UP(mem_request->ra_len,
2533 pci_rp[i].pci_size_low);
2534 DEBUG1("ADDING 64 --->0x%x\n",
2535 pci_rp[i].pci_size_low);
2536 }
2537
2538 break;
2539 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2540 io_request->ra_len =
2541 pci_rp[i].pci_size_low +
2542 PCICFG_ROUND_UP(io_request->ra_len,
2543 pci_rp[i].pci_size_low);
2544 DEBUG1("ADDING I/O --->0x%x\n",
2545 pci_rp[i].pci_size_low);
2546 break;
2547 default:
2548 /* Config space register - not included */
2549 break;
2550 }
2551 }
2552
2553 /*
2554 * free the memory allocated by ddi_getlongprop
2555 */
2556 kmem_free(pci_rp, length);
2557
2558 /*
2559 * continue the walk to the next sibling to sum memory
2560 */
2561
2562 (void) pcicfg_config_teardown(&handle);
2563
2564 return (DDI_WALK_CONTINUE);
2565 }
2566 }
2567
2568 static int
pcicfg_free_bridge_resources(dev_info_t * dip)2569 pcicfg_free_bridge_resources(dev_info_t *dip)
2570 {
2571 ppb_ranges_t *ranges;
2572 uint_t *bus;
2573 int k;
2574 int length = 0;
2575 int i;
2576
2577
2578 if ((i = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2579 "ranges", (caddr_t)&ranges, &length)) != DDI_PROP_SUCCESS) {
2580 DEBUG0("Failed to read ranges property\n");
2581 if (ddi_get_child(dip)) {
2582 cmn_err(CE_WARN, "No ranges property found for %s",
2583 ddi_get_name(dip));
2584 /*
2585 * strictly speaking, we can check for children with
2586 * assigned-addresses but for now it is better to
2587 * be conservative and assume that if there are child
2588 * nodes, then they do consume PCI memory or IO
2589 * resources, Hence return failure.
2590 */
2591 return (PCICFG_FAILURE);
2592 }
2593 length = 0;
2594 }
2595
2596 for (i = 0; i < length / sizeof (ppb_ranges_t); i++) {
2597 char *mem_type;
2598
2599 if (ranges[i].size_low != 0 || ranges[i].size_high != 0) {
2600 switch (ranges[i].parent_high & PCI_REG_ADDR_M) {
2601 case PCI_ADDR_IO:
2602 DEBUG2("Free I/O base/length = "
2603 "[0x%x]/[0x%x]\n", ranges[i].child_low,
2604 ranges[i].size_low);
2605 if (ndi_ra_free(ddi_get_parent(dip),
2606 (uint64_t)ranges[i].child_low,
2607 (uint64_t)ranges[i].size_low,
2608 NDI_RA_TYPE_IO, NDI_RA_PASS)
2609 != NDI_SUCCESS) {
2610 DEBUG0("Trouble freeing "
2611 "PCI i/o space\n");
2612 kmem_free(ranges, length);
2613 return (PCICFG_FAILURE);
2614 }
2615 break;
2616 case PCI_ADDR_MEM32:
2617 case PCI_ADDR_MEM64:
2618 if (ranges[i].parent_high & PCI_REG_PF_M) {
2619 DEBUG3("Free PF Memory base/length = "
2620 "[0x%x.0x%x]/[0x%x]\n",
2621 ranges[i].child_mid,
2622 ranges[i].child_low,
2623 ranges[i].size_low);
2624 mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2625 } else {
2626 DEBUG3("Free Memory base/length"
2627 " = [0x%x.0x%x]/[0x%x]\n",
2628 ranges[i].child_mid,
2629 ranges[i].child_low,
2630 ranges[i].size_low)
2631 mem_type = NDI_RA_TYPE_MEM;
2632 }
2633 if (ndi_ra_free(ddi_get_parent(dip),
2634 PCICFG_LADDR(ranges[i].child_low,
2635 ranges[i].child_mid),
2636 (uint64_t)ranges[i].size_low,
2637 mem_type, NDI_RA_PASS) != NDI_SUCCESS) {
2638 DEBUG0("Trouble freeing "
2639 "PCI memory space\n");
2640 kmem_free(ranges, length);
2641 return (PCICFG_FAILURE);
2642 }
2643 break;
2644 default:
2645 DEBUG0("Unknown memory space\n");
2646 break;
2647 }
2648 }
2649 }
2650
2651 if (length)
2652 kmem_free(ranges, length);
2653
2654 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2655 "bus-range", (caddr_t)&bus, &k) != DDI_PROP_SUCCESS) {
2656 DEBUG0("Failed to read bus-range property\n");
2657 return (PCICFG_FAILURE);
2658 }
2659
2660 DEBUG2("Need to free bus [%d] range [%d]\n",
2661 bus[0], bus[1] - bus[0] + 1);
2662
2663 if (ndi_ra_free(ddi_get_parent(dip), (uint64_t)bus[0],
2664 (uint64_t)(bus[1] - bus[0] + 1), NDI_RA_TYPE_PCI_BUSNUM,
2665 NDI_RA_PASS) != NDI_SUCCESS) {
2666 DEBUG0("Failed to free a bus number\n");
2667 kmem_free(bus, k);
2668 return (PCICFG_FAILURE);
2669 }
2670
2671 kmem_free(bus, k);
2672 return (PCICFG_SUCCESS);
2673 }
2674
2675 static int
pcicfg_free_device_resources(dev_info_t * dip)2676 pcicfg_free_device_resources(dev_info_t *dip)
2677 {
2678 pci_regspec_t *assigned;
2679
2680 int length;
2681 int acount;
2682 int i;
2683
2684 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2685 "assigned-addresses", (caddr_t)&assigned, &length)
2686 != DDI_PROP_SUCCESS) {
2687 DEBUG0("Failed to read assigned-addresses property\n");
2688 return (PCICFG_FAILURE);
2689 }
2690
2691 /*
2692 * For each "assigned-addresses" property entry with a length,
2693 * call the memory allocation routines to return the
2694 * resource.
2695 */
2696 acount = length / sizeof (pci_regspec_t);
2697 for (i = 0; i < acount; i++) {
2698 char *mem_type;
2699
2700 /*
2701 * Free the resource if the size of it is not zero.
2702 */
2703 if ((assigned[i].pci_size_low != 0)||
2704 (assigned[i].pci_size_hi != 0)) {
2705 switch (PCI_REG_ADDR_G(assigned[i].pci_phys_hi)) {
2706 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2707 /*
2708 * Check the assigned address for zero.
2709 * (Workaround for Devconf (x86) bug to
2710 * skip bogus entry for ROM base address
2711 * register. If the assigned address is
2712 * zero then ignore the entry
2713 * (see bugid 4281306)).
2714 */
2715 if (assigned[i].pci_phys_low == 0)
2716 break; /* ignore the entry */
2717
2718 if (assigned[i].pci_phys_hi & PCI_REG_PF_M)
2719 mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2720 else
2721 mem_type = NDI_RA_TYPE_MEM;
2722
2723 if (ndi_ra_free(ddi_get_parent(dip),
2724 (uint64_t)assigned[i].pci_phys_low,
2725 (uint64_t)assigned[i].pci_size_low,
2726 mem_type, NDI_RA_PASS) != NDI_SUCCESS) {
2727 DEBUG0("Trouble freeing "
2728 "PCI memory space\n");
2729 kmem_free(assigned, length);
2730 return (PCICFG_FAILURE);
2731 }
2732
2733 DEBUG4("Returned 0x%x of 32 bit %s space"
2734 " @ 0x%x from register 0x%x\n",
2735 assigned[i].pci_size_low, mem_type,
2736 assigned[i].pci_phys_low,
2737 PCI_REG_REG_G(assigned[i].pci_phys_hi));
2738
2739 break;
2740 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2741 if (assigned[i].pci_phys_hi & PCI_REG_PF_M)
2742 mem_type = NDI_RA_TYPE_PCI_PREFETCH_MEM;
2743 else
2744 mem_type = NDI_RA_TYPE_MEM;
2745
2746 if (ndi_ra_free(ddi_get_parent(dip),
2747 PCICFG_LADDR(assigned[i].pci_phys_low,
2748 assigned[i].pci_phys_mid),
2749 (uint64_t)assigned[i].pci_size_low,
2750 mem_type, NDI_RA_PASS) != NDI_SUCCESS) {
2751 DEBUG0("Trouble freeing "
2752 "PCI memory space\n");
2753 kmem_free(assigned, length);
2754 return (PCICFG_FAILURE);
2755 }
2756
2757 DEBUG5("Returned 0x%x of 64 bit %s space"
2758 " @ 0x%x.0x%x from register 0x%x\n",
2759 assigned[i].pci_size_low,
2760 mem_type, assigned[i].pci_phys_mid,
2761 assigned[i].pci_phys_low,
2762 PCI_REG_REG_G(assigned[i].pci_phys_hi));
2763
2764 break;
2765 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2766 if (ndi_ra_free(ddi_get_parent(dip),
2767 (uint64_t)assigned[i].pci_phys_low,
2768 (uint64_t)assigned[i].pci_size_low,
2769 NDI_RA_TYPE_IO, NDI_RA_PASS) !=
2770 NDI_SUCCESS) {
2771 DEBUG0("Trouble freeing "
2772 "PCI IO space\n");
2773 kmem_free(assigned, length);
2774 return (PCICFG_FAILURE);
2775 }
2776 DEBUG3("Returned 0x%x of IO space @ 0x%x from "
2777 "register 0x%x\n", assigned[i].pci_size_low,
2778 assigned[i].pci_phys_low,
2779 PCI_REG_REG_G(assigned[i].pci_phys_hi));
2780 break;
2781 default:
2782 DEBUG0("Unknown register type\n");
2783 kmem_free(assigned, length);
2784 return (PCICFG_FAILURE);
2785 } /* switch */
2786 }
2787 }
2788 kmem_free(assigned, length);
2789 return (PCICFG_SUCCESS);
2790 }
2791
2792 static int
pcicfg_free_resources(dev_info_t * dip,pcicfg_flags_t flags)2793 pcicfg_free_resources(dev_info_t *dip, pcicfg_flags_t flags)
2794 {
2795 ddi_acc_handle_t handle;
2796 uint8_t header_type;
2797
2798 if (pci_config_setup(dip, &handle) != DDI_SUCCESS) {
2799 DEBUG0("Failed to map config space!\n");
2800 return (PCICFG_FAILURE);
2801 }
2802
2803 header_type = pci_config_get8(handle, PCI_CONF_HEADER);
2804
2805 (void) pci_config_teardown(&handle);
2806
2807 /*
2808 * A different algorithm is used for bridges and leaf devices.
2809 */
2810 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
2811 /*
2812 * We only support readonly probing for leaf devices.
2813 */
2814 if (flags & PCICFG_FLAG_READ_ONLY)
2815 return (PCICFG_FAILURE);
2816
2817 if (pcicfg_free_bridge_resources(dip) != PCICFG_SUCCESS) {
2818 DEBUG0("Failed freeing up bridge resources\n");
2819 return (PCICFG_FAILURE);
2820 }
2821 } else {
2822 if (pcicfg_free_device_resources(dip) != PCICFG_SUCCESS) {
2823 DEBUG0("Failed freeing up device resources\n");
2824 return (PCICFG_FAILURE);
2825 }
2826 }
2827
2828 return (PCICFG_SUCCESS);
2829 }
2830
2831 #ifndef _DONT_USE_1275_GENERIC_NAMES
2832 static char *
pcicfg_get_class_name(uint32_t classcode)2833 pcicfg_get_class_name(uint32_t classcode)
2834 {
2835 struct pcicfg_name_entry *ptr;
2836
2837 for (ptr = &pcicfg_class_lookup[0]; ptr->name != NULL; ptr++) {
2838 if (ptr->class_code == classcode) {
2839 return (ptr->name);
2840 }
2841 }
2842 return (NULL);
2843 }
2844 #endif /* _DONT_USE_1275_GENERIC_NAMES */
2845
2846 static dev_info_t *
pcicfg_devi_find(dev_info_t * dip,uint_t device,uint_t function)2847 pcicfg_devi_find(dev_info_t *dip, uint_t device, uint_t function)
2848 {
2849 struct pcicfg_find_ctrl ctrl;
2850 int count;
2851
2852 ctrl.device = device;
2853 ctrl.function = function;
2854 ctrl.dip = NULL;
2855
2856 ndi_devi_enter(dip, &count);
2857 ddi_walk_devs(ddi_get_child(dip), pcicfg_match_dev, (void *)&ctrl);
2858 ndi_devi_exit(dip, count);
2859
2860 return (ctrl.dip);
2861 }
2862
2863 static int
pcicfg_match_dev(dev_info_t * dip,void * hdl)2864 pcicfg_match_dev(dev_info_t *dip, void *hdl)
2865 {
2866 struct pcicfg_find_ctrl *ctrl = (struct pcicfg_find_ctrl *)hdl;
2867 pci_regspec_t *pci_rp;
2868 int length;
2869 int pci_dev;
2870 int pci_func;
2871
2872 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2873 "reg", (int **)&pci_rp, (uint_t *)&length) != DDI_PROP_SUCCESS) {
2874 ctrl->dip = NULL;
2875 return (DDI_WALK_TERMINATE);
2876 }
2877
2878 /* get the PCI device address info */
2879 pci_dev = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
2880 pci_func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
2881
2882 /*
2883 * free the memory allocated by ddi_prop_lookup_int_array
2884 */
2885 ddi_prop_free(pci_rp);
2886
2887
2888 if ((pci_dev == ctrl->device) && (pci_func == ctrl->function)) {
2889 /* found the match for the specified device address */
2890 ctrl->dip = dip;
2891 return (DDI_WALK_TERMINATE);
2892 }
2893
2894 /*
2895 * continue the walk to the next sibling to look for a match.
2896 */
2897 return (DDI_WALK_PRUNECHILD);
2898 }
2899
2900 static int
pcicfg_update_assigned_prop(dev_info_t * dip,pci_regspec_t * newone)2901 pcicfg_update_assigned_prop(dev_info_t *dip, pci_regspec_t *newone)
2902 {
2903 int alen;
2904 pci_regspec_t *assigned;
2905 caddr_t newreg;
2906 uint_t status;
2907
2908 status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2909 "assigned-addresses", (caddr_t)&assigned, &alen);
2910 switch (status) {
2911 case DDI_PROP_SUCCESS:
2912 break;
2913 case DDI_PROP_NO_MEMORY:
2914 DEBUG0("no memory for assigned-addresses property\n");
2915 return (PCICFG_FAILURE);
2916 default:
2917 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
2918 "assigned-addresses", (int *)newone,
2919 sizeof (*newone)/sizeof (int));
2920 return (PCICFG_SUCCESS);
2921 }
2922
2923 /*
2924 * Allocate memory for the existing
2925 * assigned-addresses(s) plus one and then
2926 * build it.
2927 */
2928
2929 newreg = kmem_zalloc(alen+sizeof (*newone), KM_SLEEP);
2930
2931 bcopy(assigned, newreg, alen);
2932 bcopy(newone, newreg + alen, sizeof (*newone));
2933
2934 /*
2935 * Write out the new "assigned-addresses" spec
2936 */
2937 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
2938 "assigned-addresses", (int *)newreg,
2939 (alen + sizeof (*newone))/sizeof (int));
2940
2941 kmem_free((caddr_t)newreg, alen+sizeof (*newone));
2942 kmem_free(assigned, alen);
2943
2944 return (PCICFG_SUCCESS);
2945 }
2946
2947 static int
pcicfg_update_ranges_prop(dev_info_t * dip,ppb_ranges_t * addition)2948 pcicfg_update_ranges_prop(dev_info_t *dip, ppb_ranges_t *addition)
2949 {
2950 int rlen;
2951 ppb_ranges_t *ranges;
2952 caddr_t newreg;
2953 uint_t status;
2954
2955 status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
2956 "ranges", (caddr_t)&ranges, &rlen);
2957
2958
2959 switch (status) {
2960 case DDI_PROP_SUCCESS:
2961 break;
2962 case DDI_PROP_NO_MEMORY:
2963 DEBUG0("ranges present, but unable to get memory\n");
2964 return (PCICFG_FAILURE);
2965 default:
2966 DEBUG0("no ranges property - creating one\n");
2967 if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
2968 dip, "ranges", (int *)addition,
2969 sizeof (ppb_ranges_t)/sizeof (int))
2970 != DDI_SUCCESS) {
2971 DEBUG0("Did'nt create ranges property\n");
2972 return (PCICFG_FAILURE);
2973 }
2974 return (PCICFG_SUCCESS);
2975 }
2976
2977 /*
2978 * Allocate memory for the existing ranges plus one and then
2979 * build it.
2980 */
2981 newreg = kmem_zalloc(rlen+sizeof (ppb_ranges_t), KM_SLEEP);
2982
2983 bcopy(ranges, newreg, rlen);
2984 bcopy(addition, newreg + rlen, sizeof (ppb_ranges_t));
2985
2986 /*
2987 * Write out the new "ranges" property
2988 */
2989 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "ranges",
2990 (int *)newreg, (rlen + sizeof (ppb_ranges_t))/sizeof (int));
2991
2992 DEBUG1("Updating ranges property for %d entries",
2993 rlen / sizeof (ppb_ranges_t) + 1);
2994
2995 kmem_free((caddr_t)newreg, rlen+sizeof (ppb_ranges_t));
2996
2997 kmem_free((caddr_t)ranges, rlen);
2998
2999 return (PCICFG_SUCCESS);
3000 }
3001
3002 static int
pcicfg_update_reg_prop(dev_info_t * dip,uint32_t regvalue,uint_t reg_offset)3003 pcicfg_update_reg_prop(dev_info_t *dip, uint32_t regvalue, uint_t reg_offset)
3004 {
3005 int rlen;
3006 pci_regspec_t *reg;
3007 caddr_t newreg;
3008 uint32_t hiword;
3009 pci_regspec_t addition;
3010 uint32_t size;
3011 uint_t status;
3012
3013 status = ddi_getlongprop(DDI_DEV_T_ANY,
3014 dip, DDI_PROP_DONTPASS, "reg", (caddr_t)®, &rlen);
3015
3016 switch (status) {
3017 case DDI_PROP_SUCCESS:
3018 break;
3019 case DDI_PROP_NO_MEMORY:
3020 DEBUG0("reg present, but unable to get memory\n");
3021 return (PCICFG_FAILURE);
3022 default:
3023 DEBUG0("no reg property\n");
3024 return (PCICFG_FAILURE);
3025 }
3026
3027 /*
3028 * Allocate memory for the existing reg(s) plus one and then
3029 * build it.
3030 */
3031 newreg = kmem_zalloc(rlen+sizeof (pci_regspec_t), KM_SLEEP);
3032
3033 /*
3034 * Build the regspec, then add it to the existing one(s)
3035 */
3036
3037 hiword = PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3038 PCI_REG_DEV_G(reg->pci_phys_hi),
3039 PCI_REG_FUNC_G(reg->pci_phys_hi), reg_offset);
3040
3041 if (reg_offset == PCI_CONF_ROM) {
3042 size = (~(PCI_BASE_ROM_ADDR_M & regvalue))+1;
3043 hiword |= PCI_ADDR_MEM32;
3044 } else {
3045 size = (~(PCI_BASE_M_ADDR_M & regvalue))+1;
3046
3047 if ((PCI_BASE_SPACE_M & regvalue) == PCI_BASE_SPACE_MEM) {
3048 if ((PCI_BASE_TYPE_M & regvalue) == PCI_BASE_TYPE_MEM) {
3049 hiword |= PCI_ADDR_MEM32;
3050 } else if ((PCI_BASE_TYPE_M & regvalue)
3051 == PCI_BASE_TYPE_ALL) {
3052 hiword |= PCI_ADDR_MEM64;
3053 }
3054 if (regvalue & PCI_BASE_PREF_M)
3055 hiword |= PCI_REG_PF_M;
3056 } else {
3057 hiword |= PCI_ADDR_IO;
3058 }
3059 }
3060
3061 addition.pci_phys_hi = hiword;
3062 addition.pci_phys_mid = 0;
3063 addition.pci_phys_low = 0;
3064 addition.pci_size_hi = 0;
3065 addition.pci_size_low = size;
3066
3067 bcopy(reg, newreg, rlen);
3068 bcopy(&addition, newreg + rlen, sizeof (pci_regspec_t));
3069
3070 DEBUG3("updating BAR@off %x with %x,%x\n", reg_offset, hiword, size);
3071 /*
3072 * Write out the new "reg" property
3073 */
3074 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "reg",
3075 (int *)newreg, (rlen + sizeof (pci_regspec_t))/sizeof (int));
3076
3077 kmem_free((caddr_t)newreg, rlen+sizeof (pci_regspec_t));
3078 kmem_free((caddr_t)reg, rlen);
3079
3080 return (PCICFG_SUCCESS);
3081 }
3082
3083 static int
pcicfg_update_assigned_prop_value(dev_info_t * dip,uint32_t size,uint32_t base,uint32_t base_hi,uint_t reg_offset)3084 pcicfg_update_assigned_prop_value(dev_info_t *dip, uint32_t size,
3085 uint32_t base, uint32_t base_hi, uint_t reg_offset)
3086 {
3087 int rlen;
3088 pci_regspec_t *reg;
3089 uint32_t hiword;
3090 pci_regspec_t addition;
3091 uint_t status;
3092
3093 status = ddi_getlongprop(DDI_DEV_T_ANY,
3094 dip, DDI_PROP_DONTPASS, "reg", (caddr_t)®, &rlen);
3095
3096 switch (status) {
3097 case DDI_PROP_SUCCESS:
3098 break;
3099 case DDI_PROP_NO_MEMORY:
3100 DEBUG0("reg present, but unable to get memory\n");
3101 return (PCICFG_FAILURE);
3102 default:
3103 /*
3104 * Since the config space "reg" entry should have been
3105 * created, we expect a "reg" property already
3106 * present here.
3107 */
3108 DEBUG0("no reg property\n");
3109 return (PCICFG_FAILURE);
3110 }
3111
3112 /*
3113 * Build the regspec, then add it to the existing one(s)
3114 */
3115
3116 hiword = PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3117 PCI_REG_DEV_G(reg->pci_phys_hi),
3118 PCI_REG_FUNC_G(reg->pci_phys_hi), reg_offset);
3119
3120 hiword |= PCI_REG_REL_M;
3121
3122 if (reg_offset == PCI_CONF_ROM) {
3123 hiword |= PCI_ADDR_MEM32;
3124
3125 base = PCI_BASE_ROM_ADDR_M & base;
3126 } else {
3127 if ((PCI_BASE_SPACE_M & base) == PCI_BASE_SPACE_MEM) {
3128 if ((PCI_BASE_TYPE_M & base) == PCI_BASE_TYPE_MEM) {
3129 hiword |= PCI_ADDR_MEM32;
3130 } else if ((PCI_BASE_TYPE_M & base)
3131 == PCI_BASE_TYPE_ALL) {
3132 hiword |= PCI_ADDR_MEM64;
3133 }
3134 if (base & PCI_BASE_PREF_M)
3135 hiword |= PCI_REG_PF_M;
3136
3137 base = PCI_BASE_M_ADDR_M & base;
3138 } else {
3139 hiword |= PCI_ADDR_IO;
3140
3141 base = PCI_BASE_IO_ADDR_M & base;
3142 base_hi = 0;
3143 }
3144 }
3145
3146 addition.pci_phys_hi = hiword;
3147 addition.pci_phys_mid = base_hi;
3148 addition.pci_phys_low = base;
3149 addition.pci_size_hi = 0;
3150 addition.pci_size_low = size;
3151
3152 DEBUG3("updating BAR@off %x with %x,%x\n", reg_offset, hiword, size);
3153
3154 kmem_free((caddr_t)reg, rlen);
3155
3156 return (pcicfg_update_assigned_prop(dip, &addition));
3157 }
3158
3159 static void
pcicfg_device_on(ddi_acc_handle_t config_handle)3160 pcicfg_device_on(ddi_acc_handle_t config_handle)
3161 {
3162 /*
3163 * Enable memory, IO, and bus mastership
3164 * XXX should we enable parity, SERR#,
3165 * fast back-to-back, and addr. stepping?
3166 */
3167 pci_config_put16(config_handle, PCI_CONF_COMM,
3168 pci_config_get16(config_handle, PCI_CONF_COMM) | 0x7);
3169 }
3170
3171 static void
pcicfg_device_off(ddi_acc_handle_t config_handle)3172 pcicfg_device_off(ddi_acc_handle_t config_handle)
3173 {
3174 /*
3175 * Disable I/O and memory traffic through the bridge
3176 */
3177 pci_config_put16(config_handle, PCI_CONF_COMM, 0x0);
3178 }
3179
3180 /*
3181 * Setup the basic 1275 properties based on information found in the config
3182 * header of the PCI device
3183 */
3184 static int
pcicfg_set_standard_props(dev_info_t * dip,ddi_acc_handle_t config_handle,uint8_t pcie_dev)3185 pcicfg_set_standard_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
3186 uint8_t pcie_dev)
3187 {
3188 int ret;
3189 uint16_t cap_id_loc, val;
3190 uint32_t wordval;
3191 uint8_t byteval;
3192
3193 /* These two exists only for non-bridges */
3194 if (((pci_config_get8(config_handle, PCI_CONF_HEADER) &
3195 PCI_HEADER_TYPE_M) == PCI_HEADER_ZERO) && !pcie_dev) {
3196 byteval = pci_config_get8(config_handle, PCI_CONF_MIN_G);
3197 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3198 "min-grant", byteval)) != DDI_SUCCESS) {
3199 return (ret);
3200 }
3201
3202 byteval = pci_config_get8(config_handle, PCI_CONF_MAX_L);
3203 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3204 "max-latency", byteval)) != DDI_SUCCESS) {
3205 return (ret);
3206 }
3207 }
3208
3209 /*
3210 * These should always exist and have the value of the
3211 * corresponding register value
3212 */
3213 val = pci_config_get16(config_handle, PCI_CONF_VENID);
3214
3215 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, "vendor-id", val))
3216 != DDI_SUCCESS) {
3217 return (ret);
3218 }
3219 val = pci_config_get16(config_handle, PCI_CONF_DEVID);
3220 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, "device-id", val))
3221 != DDI_SUCCESS) {
3222 return (ret);
3223 }
3224 byteval = pci_config_get8(config_handle, PCI_CONF_REVID);
3225 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3226 "revision-id", byteval)) != DDI_SUCCESS) {
3227 return (ret);
3228 }
3229
3230 wordval = (pci_config_get16(config_handle, PCI_CONF_SUBCLASS)<< 8) |
3231 (pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
3232
3233 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3234 "class-code", wordval)) != DDI_SUCCESS) {
3235 return (ret);
3236 }
3237 val = (pci_config_get16(config_handle, PCI_CONF_STAT) &
3238 PCI_STAT_DEVSELT);
3239 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3240 "devsel-speed", val)) != DDI_SUCCESS) {
3241 return (ret);
3242 }
3243
3244 /*
3245 * The next three are bits set in the status register. The property is
3246 * present (but with no value other than its own existence) if the bit
3247 * is set, non-existent otherwise
3248 */
3249 if ((!pcie_dev) &&
3250 (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_FBBC)) {
3251 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3252 "fast-back-to-back", 0)) != DDI_SUCCESS) {
3253 return (ret);
3254 }
3255 }
3256 if ((!pcie_dev) &&
3257 (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_66MHZ)) {
3258 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3259 "66mhz-capable", 0)) != DDI_SUCCESS) {
3260 return (ret);
3261 }
3262 }
3263 if (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_UDF) {
3264 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3265 "udf-supported", 0)) != DDI_SUCCESS) {
3266 return (ret);
3267 }
3268 }
3269
3270 /*
3271 * These next three are optional and are not present
3272 * if the corresponding register is zero. If the value
3273 * is non-zero then the property exists with the value
3274 * of the register.
3275 */
3276 if ((val = pci_config_get16(config_handle, PCI_CONF_SUBVENID)) != 0) {
3277 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3278 "subsystem-vendor-id", val)) != DDI_SUCCESS) {
3279 return (ret);
3280 }
3281 }
3282 if ((val = pci_config_get16(config_handle, PCI_CONF_SUBSYSID)) != 0) {
3283 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3284 "subsystem-id", val)) != DDI_SUCCESS) {
3285 return (ret);
3286 }
3287 }
3288 if ((val = pci_config_get16(config_handle, PCI_CONF_CACHE_LINESZ))
3289 != 0) {
3290 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3291 "cache-line-size", val)) != DDI_SUCCESS) {
3292 return (ret);
3293 }
3294 }
3295
3296 /*
3297 * If the Interrupt Pin register is non-zero then the
3298 * interrupts property exists
3299 */
3300 if ((byteval = pci_config_get8(config_handle, PCI_CONF_IPIN)) != 0) {
3301 /*
3302 * If interrupt pin is non-zero,
3303 * record the interrupt line used
3304 */
3305 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3306 "interrupts", byteval)) != DDI_SUCCESS) {
3307 return (ret);
3308 }
3309 }
3310 (void) PCI_CAP_LOCATE(config_handle, PCI_CAP_ID_PCI_E, &cap_id_loc);
3311 if (pcie_dev && cap_id_loc != PCI_CAP_NEXT_PTR_NULL) {
3312 val = pci_config_get16(config_handle, cap_id_loc + PCIE_PCIECAP)
3313 & PCIE_PCIECAP_SLOT_IMPL;
3314 /* if slot implemented, get physical slot number */
3315 if (val) {
3316 wordval = pci_config_get32(config_handle, cap_id_loc +
3317 PCIE_SLOTCAP);
3318 /* create the property only if slotnum set correctly? */
3319 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3320 "physical-slot#", PCIE_SLOTCAP_PHY_SLOT_NUM(
3321 wordval))) != DDI_SUCCESS) {
3322 return (ret);
3323 }
3324 }
3325 }
3326
3327 return (PCICFG_SUCCESS);
3328 }
3329
3330 static int
pcicfg_set_busnode_props(dev_info_t * dip,uint8_t pcie_device_type)3331 pcicfg_set_busnode_props(dev_info_t *dip, uint8_t pcie_device_type)
3332 {
3333 int ret;
3334 char device_type[8];
3335
3336 if (pcie_device_type)
3337 (void) strcpy(device_type, "pciex");
3338 else
3339 (void) strcpy(device_type, "pci");
3340
3341 if ((ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip,
3342 "device_type", device_type)) != DDI_SUCCESS) {
3343 return (ret);
3344 }
3345 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3346 "#address-cells", 3)) != DDI_SUCCESS) {
3347 return (ret);
3348 }
3349 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip, "#size-cells", 2))
3350 != DDI_SUCCESS) {
3351 return (ret);
3352 }
3353 return (PCICFG_SUCCESS);
3354 }
3355
3356 static int
pcicfg_set_childnode_props(dev_info_t * dip,ddi_acc_handle_t config_handle,uint8_t pcie_dev)3357 pcicfg_set_childnode_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
3358 uint8_t pcie_dev)
3359 {
3360
3361 int ret;
3362 char *name;
3363 char buffer[64], pprefix[8], nprefix[8];
3364 uint16_t classcode;
3365 uint8_t revid, pif, pclass, psubclass;
3366 char *compat[24];
3367 int i;
3368 int n;
3369 uint16_t sub_vid, sub_sid, vid, did;
3370 /* set the property prefix based on the device type */
3371 if (pcie_dev) {
3372 (void) sprintf(pprefix, "pciex");
3373 } else
3374 (void) sprintf(pprefix, "pci");
3375
3376 /* set the prefix right for name property */
3377 /* x86 platforms need to go with pci for upgrade purposes */
3378 (void) sprintf(nprefix, "pci");
3379
3380 /*
3381 * NOTE: These are for both a child and PCI-PCI bridge node
3382 */
3383 sub_vid = pci_config_get16(config_handle, PCI_CONF_SUBVENID);
3384 sub_sid = pci_config_get16(config_handle, PCI_CONF_SUBSYSID);
3385 vid = pci_config_get16(config_handle, PCI_CONF_VENID);
3386 did = pci_config_get16(config_handle, PCI_CONF_DEVID);
3387 revid = pci_config_get8(config_handle, PCI_CONF_REVID);
3388 pif = pci_config_get8(config_handle, PCI_CONF_PROGCLASS);
3389 classcode = pci_config_get16(config_handle, PCI_CONF_SUBCLASS);
3390 pclass = pci_config_get8(config_handle, PCI_CONF_BASCLASS);
3391 psubclass = pci_config_get8(config_handle, PCI_CONF_SUBCLASS);
3392
3393 if (!sub_vid)
3394 (void) sprintf(buffer, "%s%x,%x", nprefix, vid, did);
3395 else
3396 (void) sprintf(buffer, "%s%x,%x", nprefix, sub_vid, sub_sid);
3397
3398 /*
3399 * In some environments, trying to use "generic" 1275 names is
3400 * not the convention. In those cases use the name as created
3401 * above. In all the rest of the cases, check to see if there
3402 * is a generic name first.
3403 */
3404 #ifdef _DONT_USE_1275_GENERIC_NAMES
3405 name = buffer;
3406 #else
3407 if ((name = pcicfg_get_class_name(classcode)) == NULL) {
3408 /*
3409 * Set name to the above fabricated name
3410 */
3411 name = buffer;
3412 }
3413 #endif
3414
3415 /*
3416 * The node name field needs to be filled in with the name
3417 */
3418 if (ndi_devi_set_nodename(dip, name, 0) != NDI_SUCCESS) {
3419 DEBUG0("Failed to set nodename for node\n");
3420 return (PCICFG_FAILURE);
3421 }
3422
3423 /*
3424 * Create the compatible property as an array of pointers
3425 * to strings. Start with the buffer created above.
3426 */
3427 n = 0;
3428
3429 /*
3430 * Setup 'compatible' as per the PCI2.1 bindings document.
3431 * pci[ex]VVVV,DDDD.SSSS.ssss.RR
3432 * pci[ex]VVVV,DDDD.SSSS.ssss
3433 * pciSSSS.ssss -> not created for PCIe as per PCIe bindings
3434 * pci[ex]VVVV,DDDD.RR
3435 * pci[ex]VVVV,DDDD
3436 * pci[ex]class,CCSSPP
3437 * pci[ex]class,CCSS
3438 * Add legacy entries for compatibility with legacy devices and OS
3439 * for x86.
3440 * pciVVVV,DDDD.SSSS.ssss.RR
3441 * pciVVVV,DDDD.SSSS.ssss
3442 * pciSSSS.ssss
3443 * pciVVVV,DDDD.RR
3444 * pciVVVV,DDDD
3445 * pciclass,CCSSPP
3446 * pciclass,CCSS
3447 */
3448
3449 do {
3450 if (sub_vid) {
3451 /* pci[ex]VVVV,DDDD.SSSS.ssss.RR */
3452 (void) sprintf(buffer, "%s%x,%x.%x.%x.%x", pprefix, vid,
3453 did, sub_vid, sub_sid, revid);
3454 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3455 (void) strcpy(compat[n++], buffer);
3456
3457 /* pci[ex]VVVV,DDDD.SSSS.ssss */
3458 (void) sprintf(buffer, "%s%x,%x.%x.%x", pprefix, vid,
3459 did, sub_vid, sub_sid);
3460 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3461 (void) strcpy(compat[n++], buffer);
3462
3463 /* pciSSSS.ssss -> not created for PCIe as per PCIe */
3464 /* binding to IEEE 1275 spec. */
3465 if (!pcie_dev && pcicfg_do_legacy_props) {
3466 (void) sprintf(buffer, "pci%x,%x", sub_vid,
3467 sub_sid);
3468 compat[n] = kmem_alloc(strlen(buffer) + 1,
3469 KM_SLEEP);
3470 (void) strcpy(compat[n++], buffer);
3471 }
3472 }
3473
3474 /* pci[ex]VVVV,DDDD.RR */
3475 (void) sprintf(buffer, "%s%x,%x.%x", pprefix, vid, did, revid);
3476 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3477 (void) strcpy(compat[n++], buffer);
3478
3479 /* pci[ex]VVVV,DDDD */
3480 (void) sprintf(buffer, "%s%x,%x", pprefix, vid, did);
3481 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3482 (void) strcpy(compat[n++], buffer);
3483
3484 /* pci[ex]class,CCSSPP */
3485 (void) sprintf(buffer, "%sclass,%02x%02x%02x", pprefix, pclass,
3486 psubclass, pif);
3487 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3488 (void) strcpy(compat[n++], buffer);
3489
3490 /* pci[ex]class,CCSS */
3491 (void) sprintf(buffer, "%sclass,%04x", pprefix, classcode);
3492 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3493 (void) strcpy(compat[n++], buffer);
3494
3495 if (!pcie_dev)
3496 break;
3497
3498 /* also add compatible names using "pci" prefix */
3499 (void) sprintf(pprefix, "pci");
3500 pcie_dev = 0;
3501
3502 } while (pcicfg_do_legacy_props);
3503
3504 ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, dip, "compatible",
3505 (char **)compat, n);
3506
3507 for (i = 0; i < n; i++) {
3508 kmem_free(compat[i], strlen(compat[i]) + 1);
3509 }
3510
3511 return (ret);
3512 }
3513
3514 /*
3515 * Program the bus numbers into the bridge
3516 */
3517 static void
pcicfg_set_bus_numbers(ddi_acc_handle_t config_handle,uint_t primary,uint_t secondary,uint_t subordinate)3518 pcicfg_set_bus_numbers(ddi_acc_handle_t config_handle,
3519 uint_t primary, uint_t secondary, uint_t subordinate)
3520 {
3521 DEBUG3("Setting bridge bus-range %d,%d,%d\n", primary, secondary,
3522 subordinate);
3523 /*
3524 * Primary bus#
3525 */
3526 pci_config_put8(config_handle, PCI_BCNF_PRIBUS, primary);
3527
3528 /*
3529 * Secondary bus#
3530 */
3531 pci_config_put8(config_handle, PCI_BCNF_SECBUS, secondary);
3532
3533 /*
3534 * Set the subordinate bus number to ff in order to pass through any
3535 * type 1 cycle with a bus number higher than the secondary bus#
3536 */
3537 pci_config_put8(config_handle, PCI_BCNF_SUBBUS, subordinate);
3538 }
3539
3540 /*
3541 * Put bridge registers into initial state
3542 */
3543 static void
pcicfg_setup_bridge(pcicfg_phdl_t * entry,ddi_acc_handle_t handle)3544 pcicfg_setup_bridge(pcicfg_phdl_t *entry,
3545 ddi_acc_handle_t handle)
3546 {
3547 /*
3548 * The highest bus seen during probing is the max-subordinate bus
3549 */
3550 pci_config_put8(handle, PCI_BCNF_SUBBUS, entry->highest_bus);
3551
3552 /*
3553 * Reset the secondary bus
3554 */
3555 pci_config_put16(handle, PCI_BCNF_BCNTRL,
3556 pci_config_get16(handle, PCI_BCNF_BCNTRL) | 0x40);
3557 drv_usecwait(1000);
3558 pci_config_put16(handle, PCI_BCNF_BCNTRL,
3559 pci_config_get16(handle, PCI_BCNF_BCNTRL) & ~0x40);
3560 drv_usecwait(1000);
3561
3562 /*
3563 * Program the memory base register with the
3564 * start of the memory range
3565 */
3566 pci_config_put16(handle, PCI_BCNF_MEM_BASE,
3567 PCICFG_HIWORD(PCICFG_LOADDR(entry->memory_last)));
3568
3569 /*
3570 * Program the I/O base register with the start of the I/O range
3571 */
3572 pci_config_put8(handle, PCI_BCNF_IO_BASE_LOW,
3573 PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(entry->io_last))));
3574 pci_config_put16(handle, PCI_BCNF_IO_BASE_HI,
3575 PCICFG_HIWORD(PCICFG_LOADDR(entry->io_last)));
3576
3577 /*
3578 * Program the PF memory base register with the start of
3579 * PF memory range
3580 */
3581 pci_config_put16(handle, PCI_BCNF_PF_BASE_LOW,
3582 PCICFG_HIWORD(PCICFG_LOADDR(entry->pf_memory_last)));
3583 pci_config_put32(handle, PCI_BCNF_PF_BASE_HIGH,
3584 PCICFG_HIADDR(entry->pf_memory_last));
3585
3586 /*
3587 * Clear status bits
3588 */
3589 pci_config_put16(handle, PCI_BCNF_SEC_STATUS, 0xffff);
3590
3591 /*
3592 * Needs to be set to this value
3593 */
3594 pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
3595
3596 /*
3597 * XXX - may be delay should be used since noone configures
3598 * devices in the interrupt context
3599 */
3600 drv_usecwait(pcicfg_sec_reset_delay); /* 1 sec wait */
3601 }
3602
3603 static void
pcicfg_update_bridge(pcicfg_phdl_t * entry,ddi_acc_handle_t handle)3604 pcicfg_update_bridge(pcicfg_phdl_t *entry,
3605 ddi_acc_handle_t handle)
3606 {
3607 uint_t length;
3608
3609 /*
3610 * Program the memory limit register with the end of the memory range
3611 */
3612
3613 DEBUG1("DOWN ROUNDED ===>[0x%x]\n",
3614 PCICFG_ROUND_DOWN(entry->memory_last, PCICFG_MEMGRAN));
3615
3616 pci_config_put16(handle, PCI_BCNF_MEM_LIMIT,
3617 PCICFG_HIWORD(PCICFG_LOADDR(
3618 PCICFG_ROUND_DOWN(entry->memory_last, PCICFG_MEMGRAN))));
3619 /*
3620 * Since this is a bridge, the rest of this range will
3621 * be responded to by the bridge. We have to round up
3622 * so no other device claims it.
3623 */
3624 if ((length = (PCICFG_ROUND_UP(entry->memory_last, PCICFG_MEMGRAN)
3625 - entry->memory_last)) > 0) {
3626 (void) pcicfg_get_mem(entry, length, NULL);
3627 DEBUG1("Added [0x%x]at the top of the bridge (mem)\n", length);
3628 }
3629
3630 /*
3631 * Program the PF memory limit register with the end of the memory range
3632 */
3633
3634 DEBUG1("DOWN ROUNDED ===>[0x%x]\n",
3635 PCICFG_ROUND_DOWN(entry->pf_memory_last, PCICFG_MEMGRAN));
3636
3637 pci_config_put16(handle, PCI_BCNF_PF_LIMIT_LOW,
3638 PCICFG_HIWORD(PCICFG_LOADDR(PCICFG_ROUND_DOWN(
3639 entry->pf_memory_last, PCICFG_MEMGRAN))));
3640 pci_config_put32(handle, PCI_BCNF_PF_LIMIT_HIGH, PCICFG_HIADDR(
3641 PCICFG_ROUND_DOWN(entry->pf_memory_last, PCICFG_MEMGRAN)));
3642 if ((length = (PCICFG_ROUND_UP(entry->pf_memory_last, PCICFG_MEMGRAN)
3643 - entry->pf_memory_last)) > 0) {
3644 (void) pcicfg_get_pf_mem(entry, length, NULL);
3645 DEBUG1("Added [0x%x]at the top of the bridge (PF mem)\n",
3646 length);
3647 }
3648
3649 /*
3650 * Program the I/O limit register with the end of the I/O range
3651 */
3652 pci_config_put8(handle, PCI_BCNF_IO_LIMIT_LOW,
3653 PCICFG_HIBYTE(PCICFG_LOWORD(
3654 PCICFG_LOADDR(PCICFG_ROUND_DOWN(entry->io_last, PCICFG_IOGRAN)))));
3655
3656 pci_config_put16(handle, PCI_BCNF_IO_LIMIT_HI, PCICFG_HIWORD(
3657 PCICFG_LOADDR(PCICFG_ROUND_DOWN(entry->io_last, PCICFG_IOGRAN))));
3658
3659 /*
3660 * Same as above for I/O space. Since this is a
3661 * bridge, the rest of this range will be responded
3662 * to by the bridge. We have to round up so no
3663 * other device claims it.
3664 */
3665 if ((length = (PCICFG_ROUND_UP(entry->io_last, PCICFG_IOGRAN)
3666 - entry->io_last)) > 0) {
3667 (void) pcicfg_get_io(entry, length, NULL);
3668 DEBUG1("Added [0x%x]at the top of the bridge (I/O)\n", length);
3669 }
3670 }
3671
3672 static int
pcicfg_probe_children(dev_info_t * parent,uint_t bus,uint_t device,uint_t func,uint_t * highest_bus,pcicfg_flags_t flags,boolean_t is_pcie)3673 pcicfg_probe_children(dev_info_t *parent, uint_t bus, uint_t device,
3674 uint_t func, uint_t *highest_bus, pcicfg_flags_t flags, boolean_t is_pcie)
3675 {
3676 dev_info_t *new_child;
3677 ddi_acc_handle_t config_handle;
3678 uint8_t header_type, pcie_dev = 0;
3679 int ret = PCICFG_FAILURE;
3680
3681 /*
3682 * This node will be put immediately below
3683 * "parent". Allocate a blank device node. It will either
3684 * be filled in or freed up based on further probing.
3685 */
3686
3687 ndi_devi_alloc_sleep(parent, DEVI_PSEUDO_NEXNAME,
3688 (pnode_t)DEVI_SID_NODEID, &new_child);
3689
3690 if (pcicfg_add_config_reg(new_child, bus, device, func)
3691 != DDI_SUCCESS) {
3692 DEBUG0("pcicfg_probe_children():Failed to add candidate REG\n");
3693 goto failedconfig;
3694 }
3695
3696 if ((ret = pcicfg_config_setup(new_child, &config_handle))
3697 != PCICFG_SUCCESS) {
3698 if (ret == PCICFG_NODEVICE) {
3699 (void) ndi_devi_free(new_child);
3700 return (ret);
3701 }
3702 DEBUG0("pcicfg_probe_children():"
3703 "Failed to setup config space\n");
3704 goto failedconfig;
3705 }
3706
3707 if (is_pcie)
3708 (void) pcie_init_bus(new_child, PCI_GETBDF(bus, device, func),
3709 PCIE_BUS_INITIAL);
3710
3711 /*
3712 * As soon as we have access to config space,
3713 * turn off device. It will get turned on
3714 * later (after memory is assigned).
3715 */
3716 (void) pcicfg_device_off(config_handle);
3717
3718 /* check if we are PCIe device */
3719 if (pcicfg_pcie_dev(new_child, config_handle) == DDI_SUCCESS) {
3720 DEBUG0("PCIe device detected\n");
3721 pcie_dev = 1;
3722 }
3723
3724 /*
3725 * Set 1275 properties common to all devices
3726 */
3727 if (pcicfg_set_standard_props(new_child, config_handle, pcie_dev)
3728 != PCICFG_SUCCESS) {
3729 DEBUG0("Failed to set standard properties\n");
3730 goto failedchild;
3731 }
3732
3733 /*
3734 * Child node properties NOTE: Both for PCI-PCI bridge and child node
3735 */
3736 if (pcicfg_set_childnode_props(new_child, config_handle, pcie_dev)
3737 != PCICFG_SUCCESS) {
3738 goto failedchild;
3739 }
3740
3741 header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
3742
3743 /*
3744 * If this is not a multi-function card only probe function zero.
3745 */
3746 if ((!(header_type & PCI_HEADER_MULTI)) && (func != 0)) {
3747
3748 ret = PCICFG_NODEVICE;
3749 goto failedchild;
3750 }
3751
3752 /*
3753 * Attach the child to its parent
3754 */
3755 (void) i_ndi_config_node(new_child, DS_LINKED, 0);
3756
3757 DEVI_SET_PCI(new_child);
3758
3759 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
3760
3761 DEBUG3("--Bridge found bus [0x%x] device[0x%x] func [0x%x]\n",
3762 bus, device, func);
3763
3764 /* Only support read-only probe for leaf device */
3765 if (flags & PCICFG_FLAG_READ_ONLY)
3766 goto failedchild;
3767
3768 ret = pcicfg_probe_bridge(new_child, config_handle, bus,
3769 highest_bus, is_pcie);
3770 if (ret != PCICFG_SUCCESS) {
3771 (void) pcicfg_free_bridge_resources(new_child);
3772 goto failedchild;
3773 }
3774
3775 } else {
3776
3777 DEBUG3("--Leaf device found bus [0x%x] device"
3778 "[0x%x] func [0x%x]\n", bus, device, func);
3779
3780 if (flags & PCICFG_FLAG_READ_ONLY) {
3781 /*
3782 * with read-only probe, don't do any resource
3783 * allocation, just read the BARs and update props.
3784 */
3785 ret = pcicfg_populate_props_from_bar(new_child,
3786 config_handle);
3787 if (ret != PCICFG_SUCCESS)
3788 goto failedchild;
3789
3790 /*
3791 * now allocate the resources, just remove the
3792 * resources from the parent busra pool.
3793 */
3794 ret = pcicfg_device_assign_readonly(new_child);
3795 if (ret != PCICFG_SUCCESS) {
3796 (void) pcicfg_free_device_resources(new_child);
3797 goto failedchild;
3798 }
3799
3800 } else {
3801 /*
3802 * update "reg" property by sizing the BARs.
3803 */
3804 ret = pcicfg_populate_reg_props(new_child,
3805 config_handle);
3806 if (ret != PCICFG_SUCCESS)
3807 goto failedchild;
3808
3809 /* now allocate & program the resources */
3810 ret = pcicfg_device_assign(new_child);
3811 if (ret != PCICFG_SUCCESS) {
3812 (void) pcicfg_free_device_resources(new_child);
3813 goto failedchild;
3814 }
3815 }
3816
3817 (void) ndi_devi_bind_driver(new_child, 0);
3818 }
3819
3820 (void) pcicfg_config_teardown(&config_handle);
3821
3822 /*
3823 * Properties have been setted up, so initialize the remaining
3824 * bus_t fields
3825 */
3826 if (is_pcie)
3827 (void) pcie_init_bus(new_child, 0, PCIE_BUS_FINAL);
3828
3829 return (PCICFG_SUCCESS);
3830
3831 failedchild:
3832 /*
3833 * XXX check if it should be taken offline (if online)
3834 */
3835 (void) pcicfg_config_teardown(&config_handle);
3836
3837 if (is_pcie)
3838 pcie_fini_bus(new_child, PCIE_BUS_FINAL);
3839
3840 failedconfig:
3841
3842 (void) ndi_devi_free(new_child);
3843 return (ret);
3844 }
3845
3846 /*
3847 * Sizing the BARs and update "reg" property
3848 */
3849 static int
pcicfg_populate_reg_props(dev_info_t * new_child,ddi_acc_handle_t config_handle)3850 pcicfg_populate_reg_props(dev_info_t *new_child,
3851 ddi_acc_handle_t config_handle)
3852 {
3853 int i;
3854 uint32_t request;
3855
3856 i = PCI_CONF_BASE0;
3857
3858 while (i <= PCI_CONF_BASE5) {
3859
3860 pci_config_put32(config_handle, i, 0xffffffff);
3861
3862 request = pci_config_get32(config_handle, i);
3863 /*
3864 * If its a zero length, don't do
3865 * any programming.
3866 */
3867 if (request != 0) {
3868 /*
3869 * Add to the "reg" property
3870 */
3871 if (pcicfg_update_reg_prop(new_child,
3872 request, i) != PCICFG_SUCCESS) {
3873 goto failedchild;
3874 }
3875 } else {
3876 DEBUG1("BASE register [0x%x] asks for "
3877 "[0x0]=[0x0](32)\n", i);
3878 i += 4;
3879 continue;
3880 }
3881
3882 /*
3883 * Increment by eight if it is 64 bit address space
3884 */
3885 if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
3886 DEBUG3("BASE register [0x%x] asks for "
3887 "[0x%x]=[0x%x] (64)\n",
3888 i, request, (~(PCI_BASE_M_ADDR_M & request))+1);
3889 i += 8;
3890 } else {
3891 DEBUG3("BASE register [0x%x] asks for "
3892 "[0x%x]=[0x%x](32)\n",
3893 i, request, (~(PCI_BASE_M_ADDR_M & request))+1);
3894 i += 4;
3895 }
3896 }
3897
3898 /*
3899 * Get the ROM size and create register for it
3900 */
3901 pci_config_put32(config_handle, PCI_CONF_ROM, 0xfffffffe);
3902
3903 request = pci_config_get32(config_handle, PCI_CONF_ROM);
3904 /*
3905 * If its a zero length, don't do
3906 * any programming.
3907 */
3908
3909 if (request != 0) {
3910 DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]\n",
3911 PCI_CONF_ROM, request,
3912 (~(PCI_BASE_ROM_ADDR_M & request)) + 1);
3913 /*
3914 * Add to the "reg" property
3915 */
3916 if (pcicfg_update_reg_prop(new_child, request, PCI_CONF_ROM)
3917 != PCICFG_SUCCESS) {
3918 goto failedchild;
3919 }
3920 }
3921
3922 return (PCICFG_SUCCESS);
3923
3924 failedchild:
3925 return (PCICFG_FAILURE);
3926 }
3927
3928 /*
3929 * Read the BARs and update properties. Used in virtual hotplug.
3930 */
3931 static int
pcicfg_populate_props_from_bar(dev_info_t * new_child,ddi_acc_handle_t config_handle)3932 pcicfg_populate_props_from_bar(dev_info_t *new_child,
3933 ddi_acc_handle_t config_handle)
3934 {
3935 uint32_t request, base, base_hi, size;
3936 int i;
3937
3938 i = PCI_CONF_BASE0;
3939
3940 while (i <= PCI_CONF_BASE5) {
3941 /*
3942 * determine the size of the address space
3943 */
3944 base = pci_config_get32(config_handle, i);
3945 pci_config_put32(config_handle, i, 0xffffffff);
3946 request = pci_config_get32(config_handle, i);
3947 pci_config_put32(config_handle, i, base);
3948
3949 /*
3950 * If its a zero length, don't do any programming.
3951 */
3952 if (request != 0) {
3953 /*
3954 * Add to the "reg" property
3955 */
3956 if (pcicfg_update_reg_prop(new_child,
3957 request, i) != PCICFG_SUCCESS) {
3958 goto failedchild;
3959 }
3960
3961 if ((PCI_BASE_SPACE_IO & request) == 0 &&
3962 (PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
3963 base_hi = pci_config_get32(config_handle, i+4);
3964 } else {
3965 base_hi = 0;
3966 }
3967 /*
3968 * Add to "assigned-addresses" property
3969 */
3970 size = (~(PCI_BASE_M_ADDR_M & request))+1;
3971 if (pcicfg_update_assigned_prop_value(new_child,
3972 size, base, base_hi, i) != PCICFG_SUCCESS) {
3973 goto failedchild;
3974 }
3975 } else {
3976 DEBUG1("BASE register [0x%x] asks for [0x0]=[0x0]"
3977 "(32)\n", i);
3978 i += 4;
3979 continue;
3980 }
3981
3982 /*
3983 * Increment by eight if it is 64 bit address space
3984 */
3985 if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
3986 DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]"
3987 "(64)\n", i, request,
3988 (~(PCI_BASE_M_ADDR_M & request)) + 1);
3989 i += 8;
3990 } else {
3991 DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]"
3992 "(32)\n", i, request,
3993 (~(PCI_BASE_M_ADDR_M & request)) + 1);
3994 i += 4;
3995 }
3996 }
3997
3998 /*
3999 * Get the ROM size and create register for it
4000 */
4001 base = pci_config_get32(config_handle, PCI_CONF_ROM);
4002 pci_config_put32(config_handle, PCI_CONF_ROM, 0xfffffffe);
4003 request = pci_config_get32(config_handle, PCI_CONF_ROM);
4004 pci_config_put32(config_handle, PCI_CONF_ROM, base);
4005
4006 /*
4007 * If its a zero length, don't do
4008 * any programming.
4009 */
4010 if (request != 0) {
4011 DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]\n",
4012 PCI_CONF_ROM, request,
4013 (~(PCI_BASE_ROM_ADDR_M & request)) + 1);
4014 /*
4015 * Add to the "reg" property
4016 */
4017 if (pcicfg_update_reg_prop(new_child, request, PCI_CONF_ROM)
4018 != PCICFG_SUCCESS) {
4019 goto failedchild;
4020 }
4021 /*
4022 * Add to "assigned-addresses" property
4023 */
4024 size = (~(PCI_BASE_ROM_ADDR_M & request))+1;
4025 if (pcicfg_update_assigned_prop_value(new_child, size,
4026 base, 0, PCI_CONF_ROM) != PCICFG_SUCCESS) {
4027 goto failedchild;
4028 }
4029 }
4030
4031 return (PCICFG_SUCCESS);
4032
4033 failedchild:
4034 return (PCICFG_FAILURE);
4035 }
4036
4037 static int
pcicfg_probe_bridge(dev_info_t * new_child,ddi_acc_handle_t h,uint_t bus,uint_t * highest_bus,boolean_t is_pcie)4038 pcicfg_probe_bridge(dev_info_t *new_child, ddi_acc_handle_t h, uint_t bus,
4039 uint_t *highest_bus, boolean_t is_pcie)
4040 {
4041 uint64_t next_bus;
4042 uint_t new_bus, num_slots;
4043 ndi_ra_request_t req;
4044 int rval, i, j;
4045 uint64_t mem_answer, io_answer, mem_base, io_base, mem_alen, io_alen;
4046 uint64_t pf_mem_answer, pf_mem_base, pf_mem_alen;
4047 uint64_t mem_size, io_size, pf_mem_size;
4048 uint64_t mem_end, pf_mem_end, io_end;
4049 uint64_t round_answer, round_len;
4050 ppb_ranges_t range[PCICFG_RANGE_LEN];
4051 int bus_range[2];
4052 pcicfg_phdl_t phdl;
4053 int count;
4054 uint64_t pcibus_base, pcibus_alen;
4055 uint64_t max_bus;
4056 uint8_t pcie_device_type = 0;
4057 uint_t pf_mem_supported = 0;
4058 dev_info_t *new_device;
4059 int trans_device;
4060 int ari_mode = B_FALSE;
4061 int max_function = PCI_MAX_FUNCTIONS;
4062
4063 io_answer = io_base = io_alen = io_size = 0;
4064 pf_mem_answer = pf_mem_base = pf_mem_size = pf_mem_alen = 0;
4065
4066 /*
4067 * Set "device_type" to "pci", the actual type will be set later
4068 * by pcicfg_set_busnode_props() below. This is needed as the
4069 * pcicfg_ra_free() below would update "available" property based
4070 * on "device_type".
4071 *
4072 * This code can be removed later after PCI configurator is changed
4073 * to use PCIRM, which automatically update properties upon allocation
4074 * and free, at that time we'll be able to remove the code inside
4075 * ndi_ra_alloc/free() which currently updates "available" property
4076 * for pci/pcie devices in pcie fabric.
4077 */
4078 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
4079 "device_type", "pci") != DDI_SUCCESS) {
4080 DEBUG0("Failed to set \"device_type\" props\n");
4081 return (PCICFG_FAILURE);
4082 }
4083
4084 /*
4085 * setup resource maps for the bridge node
4086 */
4087 if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_PCI_BUSNUM)
4088 == NDI_FAILURE) {
4089 DEBUG0("Can not setup resource map - NDI_RA_TYPE_PCI_BUSNUM\n");
4090 rval = PCICFG_FAILURE;
4091 goto cleanup;
4092 }
4093 if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
4094 DEBUG0("Can not setup resource map - NDI_RA_TYPE_MEM\n");
4095 rval = PCICFG_FAILURE;
4096 goto cleanup;
4097 }
4098 if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_IO) == NDI_FAILURE) {
4099 DEBUG0("Can not setup resource map - NDI_RA_TYPE_IO\n");
4100 rval = PCICFG_FAILURE;
4101 goto cleanup;
4102 }
4103 if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_PCI_PREFETCH_MEM) ==
4104 NDI_FAILURE) {
4105 DEBUG0("Can not setup resource map -"
4106 " NDI_RA_TYPE_PCI_PREFETCH_MEM\n");
4107 rval = PCICFG_FAILURE;
4108 goto cleanup;
4109 }
4110
4111 /*
4112 * Allocate bus range pool for the bridge.
4113 */
4114 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4115 req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
4116 req.ra_boundbase = 0;
4117 req.ra_boundlen = req.ra_len = (PCI_MAX_BUS_NUM -1);
4118 req.ra_align_mask = 0; /* no alignment needed */
4119
4120 rval = ndi_ra_alloc(ddi_get_parent(new_child), &req,
4121 &pcibus_base, &pcibus_alen, NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
4122
4123 if (rval != NDI_SUCCESS) {
4124 if (rval == NDI_RA_PARTIAL_REQ) {
4125 /*EMPTY*/
4126 DEBUG0("NDI_RA_PARTIAL_REQ returned for bus range\n");
4127 } else {
4128 DEBUG0(
4129 "Failed to allocate bus range for bridge\n");
4130 rval = PCICFG_NORESRC;
4131 goto cleanup;
4132 }
4133 }
4134
4135 DEBUG2("Bus Range Allocated [base=%d] [len=%d]\n",
4136 pcibus_base, pcibus_alen);
4137
4138 /*
4139 * Put available bus range into the pool.
4140 * Take the first one for this bridge to use and don't give
4141 * to child.
4142 */
4143 (void) ndi_ra_free(new_child, pcibus_base+1, pcibus_alen-1,
4144 NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
4145
4146 next_bus = pcibus_base;
4147 max_bus = pcibus_base + pcibus_alen - 1;
4148
4149 new_bus = next_bus;
4150
4151 DEBUG1("NEW bus found ->[%d]\n", new_bus);
4152
4153 /* Keep track of highest bus for subordinate bus programming */
4154 *highest_bus = new_bus;
4155
4156 /*
4157 * Allocate (non-prefetchable) Memory Space for Bridge
4158 */
4159 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4160 req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
4161 req.ra_boundbase = 0;
4162 /*
4163 * limit the boundlen,len to a 32b quantity. It should be Ok to
4164 * lose alignment-based-size of resource due to this.
4165 */
4166 req.ra_boundlen = PCICFG_4GIG_LIMIT;
4167 req.ra_len = PCICFG_4GIG_LIMIT; /* Get as big as possible */
4168 req.ra_align_mask =
4169 PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
4170
4171 rval = ndi_ra_alloc(ddi_get_parent(new_child), &req,
4172 &mem_answer, &mem_alen, NDI_RA_TYPE_MEM, NDI_RA_PASS);
4173
4174 if (rval != NDI_SUCCESS) {
4175 if (rval == NDI_RA_PARTIAL_REQ) {
4176 /*EMPTY*/
4177 DEBUG0("NDI_RA_PARTIAL_REQ returned\n");
4178 } else {
4179 DEBUG0(
4180 "Failed to allocate memory for bridge\n");
4181 rval = PCICFG_NORESRC;
4182 goto cleanup;
4183 }
4184 }
4185
4186 DEBUG3("Bridge Memory Allocated [0x%x.%x] len [0x%x]\n",
4187 PCICFG_HIADDR(mem_answer),
4188 PCICFG_LOADDR(mem_answer),
4189 mem_alen);
4190
4191 /*
4192 * Put available memory into the pool.
4193 */
4194 (void) ndi_ra_free(new_child, mem_answer, mem_alen, NDI_RA_TYPE_MEM,
4195 NDI_RA_PASS);
4196
4197 mem_base = mem_answer;
4198
4199 /*
4200 * Allocate I/O Space for Bridge
4201 */
4202 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4203 req.ra_align_mask = PCICFG_IOGRAN - 1; /* 4k alignment */
4204 req.ra_boundbase = 0;
4205 req.ra_boundlen = PCICFG_4GIG_LIMIT;
4206 req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
4207 req.ra_len = PCICFG_4GIG_LIMIT; /* Get as big as possible */
4208
4209 rval = ndi_ra_alloc(ddi_get_parent(new_child), &req, &io_answer,
4210 &io_alen, NDI_RA_TYPE_IO, NDI_RA_PASS);
4211
4212 if (rval != NDI_SUCCESS) {
4213 if (rval == NDI_RA_PARTIAL_REQ) {
4214 /*EMPTY*/
4215 DEBUG0("NDI_RA_PARTIAL_REQ returned\n");
4216 } else {
4217 DEBUG0("Failed to allocate io space for bridge\n");
4218 /* i/o space is an optional requirement so continue */
4219 }
4220 }
4221
4222 DEBUG3("Bridge IO Space Allocated [0x%x.%x] len [0x%x]\n",
4223 PCICFG_HIADDR(io_answer), PCICFG_LOADDR(io_answer), io_alen);
4224
4225 /*
4226 * Put available I/O into the pool.
4227 */
4228 (void) ndi_ra_free(new_child, io_answer, io_alen, NDI_RA_TYPE_IO,
4229 NDI_RA_PASS);
4230
4231 io_base = io_answer;
4232
4233 /*
4234 * Check if the bridge supports Prefetchable memory range.
4235 * If it does, then we setup PF memory range for the bridge.
4236 * Otherwise, we skip the step of setting up PF memory
4237 * range for it. This could cause config operation to
4238 * fail if any devices under the bridge need PF memory.
4239 */
4240 /* write a non zero value to the PF BASE register */
4241 pci_config_put16(h, PCI_BCNF_PF_BASE_LOW, 0xfff0);
4242 /* if the read returns zero then PF range is not supported */
4243 if (pci_config_get16(h, PCI_BCNF_PF_BASE_LOW) == 0) {
4244 /* bridge doesn't support PF memory range */
4245 goto pf_setup_end;
4246 } else {
4247 pf_mem_supported = 1;
4248 /* reset the PF BASE register */
4249 pci_config_put16(h, PCI_BCNF_PF_BASE_LOW, 0);
4250 }
4251
4252 /*
4253 * Bridge supports PF mem range; Allocate PF Memory Space for it.
4254 *
4255 * Note: Both non-prefetchable and prefetchable memory space
4256 * allocations are made within 32bit space. Currently, BIOSs
4257 * allocate device memory for PCI devices within the 32bit space
4258 * so this will not be a problem.
4259 */
4260 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4261 req.ra_flags = NDI_RA_ALLOC_PARTIAL_OK | NDI_RA_ALLOC_BOUNDED;
4262 req.ra_boundbase = 0;
4263 req.ra_len = PCICFG_4GIG_LIMIT; /* Get as big as possible */
4264 req.ra_align_mask =
4265 PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
4266
4267 rval = ndi_ra_alloc(ddi_get_parent(new_child), &req,
4268 &pf_mem_answer, &pf_mem_alen, NDI_RA_TYPE_PCI_PREFETCH_MEM,
4269 NDI_RA_PASS);
4270
4271 if (rval != NDI_SUCCESS) {
4272 if (rval == NDI_RA_PARTIAL_REQ) {
4273 /*EMPTY*/
4274 DEBUG0("NDI_RA_PARTIAL_REQ returned\n");
4275 } else {
4276 DEBUG0(
4277 "Failed to allocate PF memory for bridge\n");
4278 /* PF mem is an optional requirement so continue */
4279 }
4280 }
4281
4282 DEBUG3("Bridge PF Memory Allocated [0x%x.%x] len [0x%x]\n",
4283 PCICFG_HIADDR(pf_mem_answer),
4284 PCICFG_LOADDR(pf_mem_answer),
4285 pf_mem_alen);
4286
4287 /*
4288 * Put available PF memory into the pool.
4289 */
4290 (void) ndi_ra_free(new_child, pf_mem_answer, pf_mem_alen,
4291 NDI_RA_TYPE_PCI_PREFETCH_MEM, NDI_RA_PASS);
4292
4293 pf_mem_base = pf_mem_answer;
4294
4295 /*
4296 * Program the PF memory base register with the
4297 * start of the memory range
4298 */
4299 pci_config_put16(h, PCI_BCNF_PF_BASE_LOW,
4300 PCICFG_HIWORD(PCICFG_LOADDR(pf_mem_answer)));
4301 pci_config_put32(h, PCI_BCNF_PF_BASE_HIGH,
4302 PCICFG_HIADDR(pf_mem_answer));
4303
4304 /*
4305 * Program the PF memory limit register with the
4306 * end of the memory range.
4307 */
4308 pci_config_put16(h, PCI_BCNF_PF_LIMIT_LOW,
4309 PCICFG_HIWORD(PCICFG_LOADDR(
4310 PCICFG_ROUND_DOWN((pf_mem_answer + pf_mem_alen),
4311 PCICFG_MEMGRAN) - 1)));
4312 pci_config_put32(h, PCI_BCNF_PF_LIMIT_HIGH,
4313 PCICFG_HIADDR(PCICFG_ROUND_DOWN((pf_mem_answer + pf_mem_alen),
4314 PCICFG_MEMGRAN) - 1));
4315
4316 /*
4317 * Allocate the chunk of PF memory (if any) not programmed into the
4318 * bridge because of the round down.
4319 */
4320 if (PCICFG_ROUND_DOWN((pf_mem_answer + pf_mem_alen), PCICFG_MEMGRAN)
4321 != (pf_mem_answer + pf_mem_alen)) {
4322 DEBUG0("Need to allocate Memory round off chunk\n");
4323 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4324 req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
4325 req.ra_addr = PCICFG_ROUND_DOWN((pf_mem_answer + pf_mem_alen),
4326 PCICFG_MEMGRAN);
4327 req.ra_len = (pf_mem_answer + pf_mem_alen) -
4328 (PCICFG_ROUND_DOWN((pf_mem_answer + pf_mem_alen),
4329 PCICFG_MEMGRAN));
4330
4331 (void) ndi_ra_alloc(new_child, &req,
4332 &round_answer, &round_len, NDI_RA_TYPE_PCI_PREFETCH_MEM,
4333 NDI_RA_PASS);
4334 }
4335
4336 pf_setup_end:
4337
4338 /*
4339 * Program the memory base register with the
4340 * start of the memory range
4341 */
4342 pci_config_put16(h, PCI_BCNF_MEM_BASE,
4343 PCICFG_HIWORD(PCICFG_LOADDR(mem_answer)));
4344
4345 /*
4346 * Program the memory limit register with the
4347 * end of the memory range.
4348 */
4349
4350 pci_config_put16(h, PCI_BCNF_MEM_LIMIT,
4351 PCICFG_HIWORD(PCICFG_LOADDR(
4352 PCICFG_ROUND_DOWN((mem_answer + mem_alen), PCICFG_MEMGRAN) - 1)));
4353
4354 /*
4355 * Allocate the chunk of memory (if any) not programmed into the
4356 * bridge because of the round down.
4357 */
4358 if (PCICFG_ROUND_DOWN((mem_answer + mem_alen), PCICFG_MEMGRAN)
4359 != (mem_answer + mem_alen)) {
4360 DEBUG0("Need to allocate Memory round off chunk\n");
4361 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4362 req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
4363 req.ra_addr = PCICFG_ROUND_DOWN((mem_answer + mem_alen),
4364 PCICFG_MEMGRAN);
4365 req.ra_len = (mem_answer + mem_alen) -
4366 (PCICFG_ROUND_DOWN((mem_answer + mem_alen),
4367 PCICFG_MEMGRAN));
4368
4369 (void) ndi_ra_alloc(new_child, &req,
4370 &round_answer, &round_len, NDI_RA_TYPE_MEM, NDI_RA_PASS);
4371 }
4372
4373 /*
4374 * Program the I/O Space Base
4375 */
4376 pci_config_put8(h, PCI_BCNF_IO_BASE_LOW,
4377 PCICFG_HIBYTE(PCICFG_LOWORD(
4378 PCICFG_LOADDR(io_answer))));
4379
4380 pci_config_put16(h, PCI_BCNF_IO_BASE_HI,
4381 PCICFG_HIWORD(PCICFG_LOADDR(io_answer)));
4382
4383 /*
4384 * Program the I/O Space Limit
4385 */
4386 pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW,
4387 PCICFG_HIBYTE(PCICFG_LOWORD(
4388 PCICFG_LOADDR(PCICFG_ROUND_DOWN(io_answer + io_alen,
4389 PCICFG_IOGRAN)))) - 1);
4390
4391 pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI,
4392 PCICFG_HIWORD(PCICFG_LOADDR(
4393 PCICFG_ROUND_DOWN(io_answer + io_alen, PCICFG_IOGRAN)))
4394 - 1);
4395
4396 /*
4397 * Allocate the chunk of I/O (if any) not programmed into the
4398 * bridge because of the round down.
4399 */
4400 if (PCICFG_ROUND_DOWN((io_answer + io_alen), PCICFG_IOGRAN)
4401 != (io_answer + io_alen)) {
4402 DEBUG0("Need to allocate I/O round off chunk\n");
4403 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4404 req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
4405 req.ra_addr = PCICFG_ROUND_DOWN((io_answer + io_alen),
4406 PCICFG_IOGRAN);
4407 req.ra_len = (io_answer + io_alen) -
4408 (PCICFG_ROUND_DOWN((io_answer + io_alen),
4409 PCICFG_IOGRAN));
4410
4411 (void) ndi_ra_alloc(new_child, &req,
4412 &round_answer, &round_len, NDI_RA_TYPE_IO, NDI_RA_PASS);
4413 }
4414
4415 (void) pcicfg_set_bus_numbers(h, bus, new_bus, max_bus);
4416
4417 /*
4418 * Setup "ranges" and "bus-range" properties before onlining
4419 * the bridge.
4420 */
4421 bzero((caddr_t)range, sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
4422
4423 range[0].child_high = range[0].parent_high |= (PCI_REG_REL_M |
4424 PCI_ADDR_IO);
4425 range[0].child_low = range[0].parent_low = io_base;
4426 range[1].child_high = range[1].parent_high |=
4427 (PCI_REG_REL_M | PCI_ADDR_MEM32);
4428 range[1].child_low = range[1].parent_low = mem_base;
4429 range[2].child_high = range[2].parent_high |=
4430 (PCI_REG_REL_M | PCI_ADDR_MEM64 | PCI_REG_PF_M);
4431 range[2].child_low = range[2].parent_low = pf_mem_base;
4432
4433 range[0].size_low = io_alen;
4434 (void) pcicfg_update_ranges_prop(new_child, &range[0]);
4435 range[1].size_low = mem_alen;
4436 (void) pcicfg_update_ranges_prop(new_child, &range[1]);
4437 range[2].size_low = pf_mem_alen;
4438 (void) pcicfg_update_ranges_prop(new_child, &range[2]);
4439
4440 bus_range[0] = new_bus;
4441 bus_range[1] = max_bus;
4442 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, new_child,
4443 "bus-range", bus_range, 2);
4444
4445 /*
4446 * Reset the secondary bus
4447 */
4448 pci_config_put16(h, PCI_BCNF_BCNTRL,
4449 pci_config_get16(h, PCI_BCNF_BCNTRL) | 0x40);
4450
4451 drv_usecwait(100);
4452
4453 pci_config_put16(h, PCI_BCNF_BCNTRL,
4454 pci_config_get16(h, PCI_BCNF_BCNTRL) & ~0x40);
4455
4456 /*
4457 * Clear status bits
4458 */
4459 pci_config_put16(h, PCI_BCNF_SEC_STATUS, 0xffff);
4460
4461 /*
4462 * Needs to be set to this value
4463 */
4464 pci_config_put8(h, PCI_CONF_ILINE, 0xf);
4465
4466 /* check our device_type as defined by Open Firmware */
4467 if (pcicfg_pcie_device_type(new_child, h) == DDI_SUCCESS)
4468 pcie_device_type = 1;
4469
4470 /*
4471 * Set bus properties
4472 */
4473 if (pcicfg_set_busnode_props(new_child, pcie_device_type)
4474 != PCICFG_SUCCESS) {
4475 DEBUG0("Failed to set busnode props\n");
4476 rval = PCICFG_FAILURE;
4477 goto cleanup;
4478 }
4479
4480 (void) pcicfg_device_on(h);
4481
4482 if (is_pcie)
4483 (void) pcie_init_bus(new_child, 0, PCIE_BUS_FINAL);
4484 if (ndi_devi_online(new_child, NDI_NO_EVENT|NDI_CONFIG)
4485 != NDI_SUCCESS) {
4486 DEBUG0("Unable to online bridge\n");
4487 rval = PCICFG_FAILURE;
4488 goto cleanup;
4489 }
4490
4491 DEBUG0("Bridge is ONLINE\n");
4492
4493 /*
4494 * After a Reset, we need to wait 2^25 clock cycles before the
4495 * first Configuration access. The worst case is 33MHz, which
4496 * is a 1 second wait.
4497 */
4498 drv_usecwait(pcicfg_sec_reset_delay);
4499
4500 /*
4501 * Probe all children devices
4502 */
4503 DEBUG0("Bridge Programming Complete - probe children\n");
4504 ndi_devi_enter(new_child, &count);
4505 for (i = 0; ((i < PCI_MAX_DEVICES) && (ari_mode == B_FALSE));
4506 i++) {
4507 for (j = 0; j < max_function; ) {
4508 if (ari_mode)
4509 trans_device = j >> 3;
4510 else
4511 trans_device = i;
4512
4513 if ((rval = pcicfg_probe_children(new_child,
4514 new_bus, trans_device, j & 7, highest_bus,
4515 0, is_pcie)) != PCICFG_SUCCESS) {
4516 if (rval == PCICFG_NODEVICE) {
4517 DEBUG3("No Device at bus [0x%x]"
4518 "device [0x%x] "
4519 "func [0x%x]\n", new_bus,
4520 trans_device, j & 7);
4521
4522 if (j)
4523 goto next;
4524 } else
4525 /*EMPTY*/
4526 DEBUG3("Failed to configure bus "
4527 "[0x%x] device [0x%x] "
4528 "func [0x%x]\n", new_bus,
4529 trans_device, j & 7);
4530 break;
4531 }
4532 next:
4533 new_device = pcicfg_devi_find(new_child, trans_device,
4534 (j & 7));
4535
4536 /*
4537 * Determine if ARI Forwarding should be enabled.
4538 */
4539 if (j == 0) {
4540 if (new_device == NULL)
4541 break;
4542
4543 if ((pcie_ari_supported(new_child) ==
4544 PCIE_ARI_FORW_SUPPORTED) &&
4545 (pcie_ari_device(new_device) ==
4546 PCIE_ARI_DEVICE)) {
4547 if (pcie_ari_enable(new_child) ==
4548 DDI_SUCCESS) {
4549 (void) ddi_prop_create(
4550 DDI_DEV_T_NONE,
4551 new_child,
4552 DDI_PROP_CANSLEEP,
4553 "ari-enabled", NULL, 0);
4554 ari_mode = B_TRUE;
4555 max_function =
4556 PCICFG_MAX_ARI_FUNCTION;
4557 }
4558 }
4559 }
4560 if (ari_mode == B_TRUE) {
4561 int next_function;
4562
4563 if (new_device == NULL)
4564 break;
4565
4566 if (pcie_ari_get_next_function(new_device,
4567 &next_function) != DDI_SUCCESS)
4568 break;
4569
4570 j = next_function;
4571
4572 if (next_function == 0)
4573 break;
4574 } else
4575 j++;
4576
4577 }
4578 /* if any function fails to be configured, no need to proceed */
4579 if (rval != PCICFG_NODEVICE)
4580 break;
4581 }
4582 ndi_devi_exit(new_child, count);
4583
4584 /*
4585 * Offline the bridge to allow reprogramming of resources.
4586 *
4587 * This should always succeed since nobody else has started to
4588 * use it yet, failing to detach the driver would indicate a bug.
4589 * Also in that case it's better just panic than allowing the
4590 * configurator to proceed with BAR reprogramming without bridge
4591 * driver detached.
4592 */
4593 VERIFY(ndi_devi_offline(new_child, NDI_NO_EVENT|NDI_UNCONFIG)
4594 == NDI_SUCCESS);
4595 if (is_pcie)
4596 pcie_fini_bus(new_child, PCIE_BUS_INITIAL);
4597
4598 phdl.dip = new_child;
4599 phdl.memory_base = mem_answer;
4600 phdl.io_base = io_answer;
4601 phdl.pf_memory_base = pf_mem_answer;
4602 phdl.error = PCICFG_SUCCESS; /* in case of empty child tree */
4603
4604 ndi_devi_enter(ddi_get_parent(new_child), &count);
4605 ddi_walk_devs(new_child, pcicfg_find_resource_end, (void *)&phdl);
4606 ndi_devi_exit(ddi_get_parent(new_child), count);
4607
4608 num_slots = pcicfg_get_nslots(new_child, h);
4609 mem_end = PCICFG_ROUND_UP(phdl.memory_base, PCICFG_MEMGRAN);
4610 io_end = PCICFG_ROUND_UP(phdl.io_base, PCICFG_IOGRAN);
4611 pf_mem_end = PCICFG_ROUND_UP(phdl.pf_memory_base, PCICFG_MEMGRAN);
4612
4613 DEBUG4("Start of Unallocated Bridge(%d slots) Resources Mem=0x%lx "
4614 "I/O=0x%lx PF_mem=%x%lx\n", num_slots, mem_end, io_end, pf_mem_end);
4615
4616 /*
4617 * Before probing the children we've allocated maximum MEM/IO
4618 * resources from parent, and updated "available" property
4619 * accordingly. Later we'll be giving up unused resources to
4620 * the parent, thus we need to destroy "available" property
4621 * here otherwise it will be out-of-sync with the actual free
4622 * resources this bridge has. This property will be rebuilt below
4623 * with the actual free resources reserved for hotplug slots
4624 * (if any).
4625 */
4626 (void) ndi_prop_remove(DDI_DEV_T_NONE, new_child, "available");
4627 /*
4628 * if the bridge a slots, then preallocate. If not, assume static
4629 * configuration. Also check for preallocation limits and spit
4630 * warning messages appropriately (perhaps some can be in debug mode).
4631 */
4632 if (num_slots) {
4633 uint64_t mem_reqd = mem_answer +
4634 (num_slots * pcicfg_slot_memsize);
4635 uint64_t io_reqd = io_answer +
4636 (num_slots * pcicfg_slot_iosize);
4637 uint64_t pf_mem_reqd = pf_mem_answer +
4638 (num_slots * pcicfg_slot_pf_memsize);
4639 uint8_t highest_bus_reqd = new_bus +
4640 (num_slots * pcicfg_slot_busnums);
4641 #ifdef DEBUG
4642 if (mem_end > mem_reqd)
4643 DEBUG3("Memory space consumed by bridge more "
4644 "than planned for %d slot(s)(%" PRIx64 ",%"
4645 PRIx64 ")", num_slots, mem_answer, mem_end);
4646 if (io_end > io_reqd)
4647 DEBUG3("IO space consumed by bridge more than"
4648 " planned for %d slot(s)(%" PRIx64 ",%" PRIx64 ")",
4649 num_slots, io_answer, io_end);
4650 if (pf_mem_end > pf_mem_reqd)
4651 DEBUG3("PF Memory space consumed by bridge"
4652 " more than planned for %d slot(s)(%" PRIx64 ",%"
4653 PRIx64 ")", num_slots, pf_mem_answer, pf_mem_end);
4654 if (*highest_bus > highest_bus_reqd)
4655 DEBUG3("Buses consumed by bridge more "
4656 "than planned for %d slot(s)(%x, %x)",
4657 num_slots, new_bus, *highest_bus);
4658
4659 if (mem_reqd > (mem_answer + mem_alen))
4660 DEBUG3("Memory space required by bridge more "
4661 "than available for %d slot(s)(%" PRIx64 ",%"
4662 PRIx64 ")", num_slots, mem_answer, mem_end);
4663 if (io_reqd > (io_answer + io_alen))
4664 DEBUG3("IO space required by bridge more than"
4665 "available for %d slot(s)(%" PRIx64 ",%" PRIx64 ")",
4666 num_slots, io_answer, io_end);
4667 if (pf_mem_reqd > (pf_mem_answer + pf_mem_alen))
4668 DEBUG3("PF Memory space required by bridge"
4669 " more than available for %d slot(s)(%" PRIx64 ",%"
4670 PRIx64 ")", num_slots, pf_mem_answer, pf_mem_end);
4671 if (highest_bus_reqd > max_bus)
4672 DEBUG3("Bus numbers required by bridge more "
4673 "than available for %d slot(s)(%x, %x)",
4674 num_slots, new_bus, *highest_bus);
4675 #endif
4676 mem_end = MAX((MIN(mem_reqd, (mem_answer + mem_alen))),
4677 mem_end);
4678 io_end = MAX((MIN(io_reqd, (io_answer + io_alen))), io_end);
4679 pf_mem_end = MAX((MIN(pf_mem_reqd, (pf_mem_answer +
4680 pf_mem_alen))), pf_mem_end);
4681 *highest_bus = MAX((MIN(highest_bus_reqd, max_bus)),
4682 *highest_bus);
4683 DEBUG4("mem_end %lx, io_end %lx, pf_mem_end %lx"
4684 " highest_bus %x\n", mem_end, io_end, pf_mem_end,
4685 *highest_bus);
4686 }
4687
4688 /*
4689 * Give back unused memory space to parent.
4690 */
4691 (void) ndi_ra_free(ddi_get_parent(new_child), mem_end,
4692 (mem_answer + mem_alen) - mem_end, NDI_RA_TYPE_MEM, NDI_RA_PASS);
4693
4694 if (mem_end == mem_answer) {
4695 DEBUG0("No memory resources used\n");
4696 /*
4697 * To prevent the bridge from forwarding any Memory
4698 * transactions, the Memory Limit will be programmed
4699 * with a smaller value than the Memory Base.
4700 */
4701 pci_config_put16(h, PCI_BCNF_MEM_BASE, 0xffff);
4702 pci_config_put16(h, PCI_BCNF_MEM_LIMIT, 0);
4703
4704 mem_size = 0;
4705 } else {
4706 /*
4707 * Reprogram the end of the memory.
4708 */
4709 pci_config_put16(h, PCI_BCNF_MEM_LIMIT,
4710 PCICFG_HIWORD(mem_end) - 1);
4711 mem_size = mem_end - mem_base;
4712 }
4713
4714 /*
4715 * Give back unused io space to parent.
4716 */
4717 (void) ndi_ra_free(ddi_get_parent(new_child),
4718 io_end, (io_answer + io_alen) - io_end,
4719 NDI_RA_TYPE_IO, NDI_RA_PASS);
4720
4721 if (io_end == io_answer) {
4722 DEBUG0("No IO Space resources used\n");
4723
4724 /*
4725 * To prevent the bridge from forwarding any I/O
4726 * transactions, the I/O Limit will be programmed
4727 * with a smaller value than the I/O Base.
4728 */
4729 pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW, 0);
4730 pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI, 0);
4731 pci_config_put8(h, PCI_BCNF_IO_BASE_LOW, 0xff);
4732 pci_config_put16(h, PCI_BCNF_IO_BASE_HI, 0);
4733
4734 io_size = 0;
4735 } else {
4736 /*
4737 * Reprogram the end of the io space.
4738 */
4739 pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW,
4740 PCICFG_HIBYTE(PCICFG_LOWORD(
4741 PCICFG_LOADDR(io_end) - 1)));
4742
4743 pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI,
4744 PCICFG_HIWORD(PCICFG_LOADDR(io_end - 1)));
4745
4746 io_size = io_end - io_base;
4747 }
4748
4749 /*
4750 * Give back unused PF memory space to parent.
4751 */
4752 if (pf_mem_supported) {
4753 (void) ndi_ra_free(ddi_get_parent(new_child),
4754 pf_mem_end, (pf_mem_answer + pf_mem_alen) - pf_mem_end,
4755 NDI_RA_TYPE_PCI_PREFETCH_MEM, NDI_RA_PASS);
4756
4757 if (pf_mem_end == pf_mem_answer) {
4758 DEBUG0("No PF memory resources used\n");
4759 /*
4760 * To prevent the bridge from forwarding any PF Memory
4761 * transactions, the PF Memory Limit will be programmed
4762 * with a smaller value than the Memory Base.
4763 */
4764 pci_config_put16(h, PCI_BCNF_PF_BASE_LOW, 0xfff0);
4765 pci_config_put32(h, PCI_BCNF_PF_BASE_HIGH, 0xffffffff);
4766 pci_config_put16(h, PCI_BCNF_PF_LIMIT_LOW, 0);
4767 pci_config_put32(h, PCI_BCNF_PF_LIMIT_HIGH, 0);
4768
4769 pf_mem_size = 0;
4770 } else {
4771 /*
4772 * Reprogram the end of the PF memory range.
4773 */
4774 pci_config_put16(h, PCI_BCNF_PF_LIMIT_LOW,
4775 PCICFG_HIWORD(PCICFG_LOADDR(pf_mem_end - 1)));
4776 pci_config_put32(h, PCI_BCNF_PF_LIMIT_HIGH,
4777 PCICFG_HIADDR(pf_mem_end - 1));
4778 pf_mem_size = pf_mem_end - pf_mem_base;
4779 }
4780 }
4781
4782 if ((max_bus - *highest_bus) > 0) {
4783 /*
4784 * Give back unused bus numbers
4785 */
4786 (void) ndi_ra_free(ddi_get_parent(new_child),
4787 *highest_bus+1, max_bus - *highest_bus,
4788 NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
4789 }
4790
4791 /*
4792 * Set bus numbers to ranges encountered during scan
4793 */
4794 (void) pcicfg_set_bus_numbers(h, bus, new_bus, *highest_bus);
4795
4796 /*
4797 * Remove the ranges property if it exists since we will create
4798 * a new one.
4799 */
4800 (void) ndi_prop_remove(DDI_DEV_T_NONE, new_child, "ranges");
4801
4802 DEBUG2("Creating Ranges property - Mem Address %lx Mem Size %x\n",
4803 mem_base, mem_size);
4804 DEBUG2(" - I/O Address %lx I/O Size %x\n",
4805 io_base, io_size);
4806 DEBUG2(" - PF Mem address %lx PF Mem Size %x\n",
4807 pf_mem_base, pf_mem_size);
4808
4809 bzero((caddr_t)range, sizeof (ppb_ranges_t) * PCICFG_RANGE_LEN);
4810
4811 range[0].child_high = range[0].parent_high |= (PCI_REG_REL_M |
4812 PCI_ADDR_IO);
4813 range[0].child_low = range[0].parent_low = io_base;
4814 range[1].child_high = range[1].parent_high |=
4815 (PCI_REG_REL_M | PCI_ADDR_MEM32);
4816 range[1].child_low = range[1].parent_low = mem_base;
4817 range[2].child_high = range[2].parent_high |=
4818 (PCI_REG_REL_M | PCI_ADDR_MEM64 | PCI_REG_PF_M);
4819 range[2].child_low = range[2].parent_low = pf_mem_base;
4820
4821 if (io_size > 0) {
4822 range[0].size_low = io_size;
4823 (void) pcicfg_update_ranges_prop(new_child, &range[0]);
4824 }
4825 if (mem_size > 0) {
4826 range[1].size_low = mem_size;
4827 (void) pcicfg_update_ranges_prop(new_child, &range[1]);
4828 }
4829 if (pf_mem_size > 0) {
4830 range[2].size_low = pf_mem_size;
4831 (void) pcicfg_update_ranges_prop(new_child, &range[2]);
4832 }
4833
4834 bus_range[0] = pci_config_get8(h, PCI_BCNF_SECBUS);
4835 bus_range[1] = pci_config_get8(h, PCI_BCNF_SUBBUS);
4836 DEBUG1("End of bridge probe: bus_range[0] = %d\n", bus_range[0]);
4837 DEBUG1("End of bridge probe: bus_range[1] = %d\n", bus_range[1]);
4838
4839 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, new_child,
4840 "bus-range", bus_range, 2);
4841
4842 rval = PCICFG_SUCCESS;
4843
4844 PCICFG_DUMP_BRIDGE_CONFIG(h);
4845
4846 cleanup:
4847 /* free up resources (for error return case only) */
4848 if (rval != PCICFG_SUCCESS) {
4849 if (mem_alen)
4850 (void) ndi_ra_free(ddi_get_parent(new_child), mem_base,
4851 mem_alen, NDI_RA_TYPE_MEM, NDI_RA_PASS);
4852 if (io_alen)
4853 (void) ndi_ra_free(ddi_get_parent(new_child), io_base,
4854 io_alen, NDI_RA_TYPE_IO, NDI_RA_PASS);
4855 if (pf_mem_alen)
4856 (void) ndi_ra_free(ddi_get_parent(new_child),
4857 pf_mem_base, pf_mem_alen,
4858 NDI_RA_TYPE_PCI_PREFETCH_MEM, NDI_RA_PASS);
4859 if (pcibus_alen)
4860 (void) ndi_ra_free(ddi_get_parent(new_child),
4861 pcibus_base, pcibus_alen, NDI_RA_TYPE_PCI_BUSNUM,
4862 NDI_RA_PASS);
4863 }
4864
4865 /* free up any resource maps setup for the bridge node */
4866 (void) ndi_ra_map_destroy(new_child, NDI_RA_TYPE_PCI_BUSNUM);
4867 (void) ndi_ra_map_destroy(new_child, NDI_RA_TYPE_IO);
4868 (void) ndi_ra_map_destroy(new_child, NDI_RA_TYPE_MEM);
4869 (void) ndi_ra_map_destroy(new_child, NDI_RA_TYPE_PCI_PREFETCH_MEM);
4870
4871 return (rval);
4872 }
4873
4874 static int
pcicfg_find_resource_end(dev_info_t * dip,void * hdl)4875 pcicfg_find_resource_end(dev_info_t *dip, void *hdl)
4876 {
4877 pcicfg_phdl_t *entry = (pcicfg_phdl_t *)hdl;
4878 pci_regspec_t *pci_ap;
4879 int length;
4880 int rcount;
4881 int i;
4882
4883 entry->error = PCICFG_SUCCESS;
4884
4885 if (dip == entry->dip) {
4886 DEBUG0("Don't include parent bridge node\n");
4887 return (DDI_WALK_CONTINUE);
4888 } else {
4889 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
4890 DDI_PROP_DONTPASS, "assigned-addresses",
4891 (caddr_t)&pci_ap, &length) != DDI_PROP_SUCCESS) {
4892 DEBUG0("Node doesn't have assigned-addresses\n");
4893 return (DDI_WALK_CONTINUE);
4894 }
4895
4896 rcount = length / sizeof (pci_regspec_t);
4897
4898 for (i = 0; i < rcount; i++) {
4899
4900 switch (PCI_REG_ADDR_G(pci_ap[i].pci_phys_hi)) {
4901
4902 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
4903 if (pci_ap[i].pci_phys_hi & PCI_REG_PF_M) {
4904 if ((pci_ap[i].pci_phys_low +
4905 pci_ap[i].pci_size_low) >
4906 entry->pf_memory_base) {
4907 entry->pf_memory_base =
4908 pci_ap[i].pci_phys_low +
4909 pci_ap[i].pci_size_low;
4910 }
4911 } else {
4912 if ((pci_ap[i].pci_phys_low +
4913 pci_ap[i].pci_size_low) >
4914 entry->memory_base) {
4915 entry->memory_base =
4916 pci_ap[i].pci_phys_low +
4917 pci_ap[i].pci_size_low;
4918 }
4919 }
4920 break;
4921 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
4922 if (pci_ap[i].pci_phys_hi & PCI_REG_PF_M) {
4923 if ((PCICFG_LADDR(
4924 pci_ap[i].pci_phys_low,
4925 pci_ap[i].pci_phys_mid) +
4926 pci_ap[i].pci_size_low) >
4927 entry->pf_memory_base) {
4928 entry->pf_memory_base =
4929 PCICFG_LADDR(
4930 pci_ap[i].pci_phys_low,
4931 pci_ap[i].pci_phys_mid) +
4932 pci_ap[i].pci_size_low;
4933 }
4934 } else {
4935 if ((PCICFG_LADDR(
4936 pci_ap[i].pci_phys_low,
4937 pci_ap[i].pci_phys_mid) +
4938 pci_ap[i].pci_size_low) >
4939 entry->memory_base) {
4940 entry->memory_base =
4941 PCICFG_LADDR(
4942 pci_ap[i].pci_phys_low,
4943 pci_ap[i].pci_phys_mid) +
4944 pci_ap[i].pci_size_low;
4945 }
4946 }
4947 break;
4948 case PCI_REG_ADDR_G(PCI_ADDR_IO):
4949 if ((pci_ap[i].pci_phys_low +
4950 pci_ap[i].pci_size_low) >
4951 entry->io_base) {
4952 entry->io_base =
4953 pci_ap[i].pci_phys_low +
4954 pci_ap[i].pci_size_low;
4955 }
4956 break;
4957 }
4958 }
4959
4960 /*
4961 * free the memory allocated by ddi_getlongprop
4962 */
4963 kmem_free(pci_ap, length);
4964
4965 /*
4966 * continue the walk to the next sibling to sum memory
4967 */
4968 return (DDI_WALK_CONTINUE);
4969 }
4970 }
4971
4972 /*
4973 * Make "parent" be the parent of the "child" dip
4974 */
4975 static void
pcicfg_reparent_node(dev_info_t * child,dev_info_t * parent)4976 pcicfg_reparent_node(dev_info_t *child, dev_info_t *parent)
4977 {
4978 int circ;
4979 dev_info_t *opdip;
4980
4981 ASSERT(i_ddi_node_state(child) <= DS_LINKED);
4982 /*
4983 * Unlink node from tree before reparenting
4984 */
4985 opdip = ddi_get_parent(child);
4986 ndi_devi_enter(opdip, &circ);
4987 (void) i_ndi_unconfig_node(child, DS_PROTO, 0);
4988 ndi_devi_exit(opdip, circ);
4989
4990 DEVI(child)->devi_parent = DEVI(parent);
4991 DEVI(child)->devi_bus_ctl = DEVI(parent);
4992 (void) ndi_devi_bind_driver(child, 0);
4993 }
4994
4995 /*
4996 * Return PCICFG_SUCCESS if device exists at the specified address.
4997 * Return PCICFG_NODEVICE is no device exists at the specified address.
4998 */
4999 int
pcicfg_config_setup(dev_info_t * dip,ddi_acc_handle_t * handle)5000 pcicfg_config_setup(dev_info_t *dip, ddi_acc_handle_t *handle)
5001 {
5002 caddr_t cfgaddr;
5003 ddi_device_acc_attr_t attr;
5004 dev_info_t *anode;
5005 int status;
5006 int rlen;
5007 pci_regspec_t *reg;
5008 int ret = DDI_SUCCESS;
5009 int16_t tmp;
5010
5011 /*
5012 * Get the pci register spec from the node
5013 */
5014 status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg",
5015 (caddr_t)®, &rlen);
5016
5017 switch (status) {
5018 case DDI_PROP_SUCCESS:
5019 break;
5020 case DDI_PROP_NO_MEMORY:
5021 DEBUG0("reg present, but unable to get memory\n");
5022 return (PCICFG_FAILURE);
5023 default:
5024 DEBUG0("no reg property\n");
5025 return (PCICFG_FAILURE);
5026 }
5027
5028 anode = dip;
5029 DEBUG2("conf_map: dip=%p, anode=%p\n", dip, anode);
5030
5031 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
5032 attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
5033 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
5034
5035 if (ddi_regs_map_setup(anode, 0, &cfgaddr, 0, 0, &attr, handle)
5036 != DDI_SUCCESS) {
5037 DEBUG0("Failed to setup registers\n");
5038 kmem_free((caddr_t)reg, rlen);
5039 return (PCICFG_FAILURE);
5040 }
5041
5042 /*
5043 * need to use DDI interfaces as the conf space is
5044 * cannot be directly accessed by the host.
5045 */
5046 tmp = (int16_t)ddi_get16(*handle, (uint16_t *)cfgaddr);
5047 if ((tmp == (int16_t)0xffff) || (tmp == -1)) {
5048 DEBUG1("NO DEVICEFOUND, read %x\n", tmp);
5049 ret = PCICFG_NODEVICE;
5050 } else {
5051 if (tmp == 0) {
5052 DEBUG0("Device Not Ready yet ?");
5053 ret = PCICFG_NODEVICE;
5054 } else {
5055 DEBUG1("DEVICEFOUND, read %x\n", tmp);
5056 ret = PCICFG_SUCCESS;
5057 }
5058 }
5059
5060 if (ret == PCICFG_NODEVICE)
5061 ddi_regs_map_free(handle);
5062 kmem_free((caddr_t)reg, rlen);
5063
5064 return (ret);
5065
5066 }
5067
5068 static void
pcicfg_config_teardown(ddi_acc_handle_t * handle)5069 pcicfg_config_teardown(ddi_acc_handle_t *handle)
5070 {
5071 (void) ddi_regs_map_free(handle);
5072 }
5073
5074 static int
pcicfg_add_config_reg(dev_info_t * dip,uint_t bus,uint_t device,uint_t func)5075 pcicfg_add_config_reg(dev_info_t *dip,
5076 uint_t bus, uint_t device, uint_t func)
5077 {
5078 int reg[10] = { PCI_ADDR_CONFIG, 0, 0, 0, 0};
5079
5080 reg[0] = PCICFG_MAKE_REG_HIGH(bus, device, func, 0);
5081
5082 return (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "reg", reg, 5));
5083 }
5084
5085 static int
pcicfg_ari_configure(dev_info_t * dip)5086 pcicfg_ari_configure(dev_info_t *dip)
5087 {
5088 if (pcie_ari_supported(dip) == PCIE_ARI_FORW_NOT_SUPPORTED)
5089 return (DDI_FAILURE);
5090
5091 /*
5092 * Until we have resource balancing, dynamically configure
5093 * ARI functions without firmware assistamce.
5094 */
5095 return (DDI_FAILURE);
5096 }
5097
5098
5099 #ifdef DEBUG
5100 static void
debug(char * fmt,uintptr_t a1,uintptr_t a2,uintptr_t a3,uintptr_t a4,uintptr_t a5)5101 debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3,
5102 uintptr_t a4, uintptr_t a5)
5103 {
5104 if (pcicfg_debug > 1) {
5105 prom_printf("pcicfg: ");
5106 prom_printf(fmt, a1, a2, a3, a4, a5);
5107 }
5108 }
5109 #endif
5110
5111 /*ARGSUSED*/
5112 static uint8_t
pcicfg_get_nslots(dev_info_t * dip,ddi_acc_handle_t handle)5113 pcicfg_get_nslots(dev_info_t *dip, ddi_acc_handle_t handle)
5114 {
5115 uint16_t cap_id_loc, slot_id_loc;
5116 uint8_t num_slots = 0;
5117
5118 /* just depend on the pcie_cap for now. */
5119 (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_id_loc);
5120 (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_SLOT_ID, &slot_id_loc);
5121 if (cap_id_loc != PCI_CAP_NEXT_PTR_NULL) {
5122 if (pci_config_get8(handle, cap_id_loc + PCI_CAP_ID_REGS_OFF) &
5123 PCIE_PCIECAP_SLOT_IMPL)
5124 num_slots = 1;
5125 } else /* not a PCIe switch/bridge. Must be a PCI-PCI[-X] bridge */
5126 if (slot_id_loc != PCI_CAP_NEXT_PTR_NULL) {
5127 uint8_t esr_reg = pci_config_get8(handle, slot_id_loc + 2);
5128 num_slots = PCI_CAPSLOT_NSLOTS(esr_reg);
5129 }
5130 /* XXX - need to cover PCI-PCIe bridge with n slots */
5131 return (num_slots);
5132 }
5133
5134 /*ARGSUSED*/
5135 static int
pcicfg_pcie_dev(dev_info_t * dip,ddi_acc_handle_t handle)5136 pcicfg_pcie_dev(dev_info_t *dip, ddi_acc_handle_t handle)
5137 {
5138 /* get parent device's device_type property */
5139 char *device_type;
5140 int val;
5141 dev_info_t *pdip = ddi_get_parent(dip);
5142
5143 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS,
5144 "device_type", &device_type) != DDI_PROP_SUCCESS) {
5145 DEBUG2("device_type property missing for %s#%d",
5146 ddi_get_name(pdip), ddi_get_instance(pdip));
5147 return (DDI_FAILURE);
5148 }
5149 DEBUG1("device_type=<%s>\n", device_type);
5150
5151 val = DDI_FAILURE;
5152 if (strcmp(device_type, "pciex") == 0)
5153 val = DDI_SUCCESS;
5154 ddi_prop_free(device_type);
5155 return (val);
5156 }
5157
5158 static int
pcicfg_pcie_device_type(dev_info_t * dip,ddi_acc_handle_t handle)5159 pcicfg_pcie_device_type(dev_info_t *dip, ddi_acc_handle_t handle)
5160 {
5161 int port_type = pcicfg_pcie_port_type(dip, handle);
5162
5163 DEBUG1("device port_type = %x\n", port_type);
5164 /* No PCIe CAP regs, we are not PCIe device_type */
5165 if (port_type < 0)
5166 return (DDI_FAILURE);
5167
5168 /* check for all PCIe device_types */
5169 if ((port_type == PCIE_PCIECAP_DEV_TYPE_UP) ||
5170 (port_type == PCIE_PCIECAP_DEV_TYPE_DOWN) ||
5171 (port_type == PCIE_PCIECAP_DEV_TYPE_ROOT) ||
5172 (port_type == PCIE_PCIECAP_DEV_TYPE_PCI2PCIE))
5173 return (DDI_SUCCESS);
5174
5175 return (DDI_FAILURE);
5176
5177 }
5178
5179 /*ARGSUSED*/
5180 static int
pcicfg_pcie_port_type(dev_info_t * dip,ddi_acc_handle_t handle)5181 pcicfg_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle)
5182 {
5183 int port_type = -1;
5184 uint16_t cap_loc;
5185
5186 /* Note: need to look at the port type information here */
5187 (void) PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_loc);
5188 if (cap_loc != PCI_CAP_NEXT_PTR_NULL)
5189 port_type = pci_config_get16(handle,
5190 cap_loc + PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
5191
5192 return (port_type);
5193 }
5194
5195 /*
5196 * Return true if the devinfo node is in a PCI Express hierarchy.
5197 */
5198 static boolean_t
is_pcie_fabric(dev_info_t * dip)5199 is_pcie_fabric(dev_info_t *dip)
5200 {
5201 dev_info_t *root = ddi_root_node();
5202 dev_info_t *pdip;
5203 boolean_t found = B_FALSE;
5204 char *bus;
5205
5206 /*
5207 * Does this device reside in a pcie fabric ?
5208 */
5209 for (pdip = dip; pdip && (pdip != root) && !found;
5210 pdip = ddi_get_parent(pdip)) {
5211 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
5212 DDI_PROP_DONTPASS, "device_type", &bus) !=
5213 DDI_PROP_SUCCESS)
5214 break;
5215
5216 if (strcmp(bus, "pciex") == 0)
5217 found = B_TRUE;
5218
5219 ddi_prop_free(bus);
5220 }
5221
5222 return (found);
5223 }
5224