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