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