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) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2019 Joyent, Inc.
24 * Copyright 2023 Oxide Computer Company
25 */
26
27 /*
28 * PCI configurator (pcicfg)
29 */
30
31 #include <sys/isa_defs.h>
32
33 #include <sys/conf.h>
34 #include <sys/kmem.h>
35 #include <sys/debug.h>
36 #include <sys/modctl.h>
37 #include <sys/autoconf.h>
38 #include <sys/hwconf.h>
39 #include <sys/ddi_impldefs.h>
40 #include <sys/fcode.h>
41 #include <sys/pci.h>
42 #include <sys/pcie.h>
43 #include <sys/pcie_impl.h>
44 #include <sys/ddi.h>
45 #include <sys/sunddi.h>
46 #include <sys/sunndi.h>
47 #include <sys/pci_cap.h>
48 #include <sys/hotplug/pci/pcicfg.h>
49 #include <sys/ndi_impldefs.h>
50 #include <sys/pci_cfgacc.h>
51
52 #define PCICFG_DEVICE_TYPE_PCI 1
53 #define PCICFG_DEVICE_TYPE_PCIE 2
54
55 #define EFCODE21554 /* changes for supporting 21554 */
56
57 static int pcicfg_alloc_resource(dev_info_t *, pci_regspec_t);
58 static int pcicfg_free_resource(dev_info_t *, pci_regspec_t, pcicfg_flags_t);
59 static int pcicfg_remove_assigned_prop(dev_info_t *, pci_regspec_t *);
60
61 #ifdef PCICFG_INTERPRET_FCODE
62 static int pcicfg_fcode_assign_bars(ddi_acc_handle_t, dev_info_t *,
63 uint_t, uint_t, uint_t, int32_t, pci_regspec_t *);
64 #endif /* PCICFG_INTERPRET_FCODE */
65
66 /*
67 * ************************************************************************
68 * *** Implementation specific local data structures/definitions. ***
69 * ************************************************************************
70 */
71
72 static int pcicfg_start_devno = 0; /* for Debug only */
73
74 #define PCICFG_MAX_DEVICE 32
75 #define PCICFG_MAX_FUNCTION 8
76 #define PCICFG_MAX_ARI_FUNCTION 256
77 #define PCICFG_MAX_REGISTER 64
78 #define PCICFG_MAX_BUS_DEPTH 255
79
80 #define PCICFG_NODEVICE 42
81 #define PCICFG_NOMEMORY 43
82 #define PCICFG_NOMULTI 44
83
84 #define PCICFG_HIADDR(n) ((uint32_t)(((uint64_t)(n) & 0xFFFFFFFF00000000)>> 32))
85 #define PCICFG_LOADDR(n) ((uint32_t)((uint64_t)(n) & 0x00000000FFFFFFFF))
86 #define PCICFG_LADDR(lo, hi) (((uint64_t)(hi) << 32) | (uint32_t)(lo))
87
88 #define PCICFG_HIWORD(n) ((uint16_t)(((uint32_t)(n) & 0xFFFF0000)>> 16))
89 #define PCICFG_LOWORD(n) ((uint16_t)((uint32_t)(n) & 0x0000FFFF))
90 #define PCICFG_HIBYTE(n) ((uint8_t)(((uint16_t)(n) & 0xFF00)>> 8))
91 #define PCICFG_LOBYTE(n) ((uint8_t)((uint16_t)(n) & 0x00FF))
92
93 #define PCICFG_ROUND_UP(addr, gran) ((uintptr_t)((gran+addr-1)&(~(gran-1))))
94 #define PCICFG_ROUND_DOWN(addr, gran) ((uintptr_t)((addr) & ~(gran-1)))
95
96 #define PCICFG_MEMGRAN 0x100000
97 #define PCICFG_IOGRAN 0x1000
98 #define PCICFG_4GIG_LIMIT 0xFFFFFFFFUL
99
100 #define PCICFG_MEM_MULT 4
101 #define PCICFG_IO_MULT 4
102 #define PCICFG_RANGE_LEN 2 /* Number of range entries */
103
104 static int pcicfg_slot_busnums = 8;
105 static int pcicfg_slot_memsize = 32 * PCICFG_MEMGRAN; /* 32MB per slot */
106 static int pcicfg_slot_iosize = 16 * PCICFG_IOGRAN; /* 64K per slot */
107 static int pcicfg_chassis_per_tree = 1;
108 static int pcicfg_sec_reset_delay = 1000000;
109
110 /*
111 * The following typedef is used to represent a
112 * 1275 "bus-range" property of a PCI Bus node.
113 * DAF - should be in generic include file...
114 */
115
116 typedef struct pcicfg_bus_range {
117 uint32_t lo;
118 uint32_t hi;
119 } pcicfg_bus_range_t;
120
121 typedef struct pcicfg_range {
122
123 uint32_t child_hi;
124 uint32_t child_mid;
125 uint32_t child_lo;
126 uint32_t parent_hi;
127 uint32_t parent_mid;
128 uint32_t parent_lo;
129 uint32_t size_hi;
130 uint32_t size_lo;
131
132 } pcicfg_range_t;
133
134 typedef struct hole hole_t;
135
136 struct hole {
137 uint64_t start;
138 uint64_t len;
139 hole_t *next;
140 };
141
142 typedef struct pcicfg_phdl pcicfg_phdl_t;
143
144 struct pcicfg_phdl {
145
146 dev_info_t *dip; /* Associated with the attach point */
147 pcicfg_phdl_t *next;
148
149 uint64_t memory_base; /* Memory base for this attach point */
150 uint64_t memory_last;
151 uint64_t memory_len;
152 uint32_t io_base; /* I/O base for this attach point */
153 uint32_t io_last;
154 uint32_t io_len;
155
156 int error;
157 uint_t highest_bus; /* Highest bus seen on the probe */
158
159 hole_t mem_hole; /* Memory hole linked list. */
160 hole_t io_hole; /* IO hole linked list */
161
162 ndi_ra_request_t mem_req; /* allocator request for memory */
163 ndi_ra_request_t io_req; /* allocator request for I/O */
164 };
165
166 struct pcicfg_standard_prop_entry {
167 uchar_t *name;
168 uint_t config_offset;
169 uint_t size;
170 };
171
172
173 struct pcicfg_name_entry {
174 uint32_t class_code;
175 char *name;
176 };
177
178 struct pcicfg_find_ctrl {
179 uint_t device;
180 uint_t function;
181 dev_info_t *dip;
182 };
183
184 typedef struct pcicfg_err_regs {
185 uint16_t cmd;
186 uint16_t bcntl;
187 uint16_t pcie_dev;
188 uint16_t devctl;
189 uint16_t pcie_cap_off;
190 } pcicfg_err_regs_t;
191
192 /*
193 * List of Indirect Config Map Devices. At least the intent of the
194 * design is to look for a device in this list during the configure
195 * operation, and if the device is listed here, then it is a nontransparent
196 * bridge, hence load the driver and avail the config map services from
197 * the driver. Class and Subclass should be as defined in the PCI specs
198 * ie. class is 0x6, and subclass is 0x9.
199 */
200 static struct {
201 uint8_t mem_range_bar_offset;
202 uint8_t io_range_bar_offset;
203 uint8_t prefetch_mem_range_bar_offset;
204 } pcicfg_indirect_map_devs[] = {
205 PCI_CONF_BASE3, PCI_CONF_BASE2, PCI_CONF_BASE3,
206 0, 0, 0,
207 };
208
209 #define PCICFG_MAKE_REG_HIGH(busnum, devnum, funcnum, register)\
210 (\
211 ((ulong_t)(busnum & 0xff) << 16) |\
212 ((ulong_t)(devnum & 0x1f) << 11) |\
213 ((ulong_t)(funcnum & 0x7) << 8) |\
214 ((ulong_t)(register & 0x3f)))
215
216 /*
217 * debug macros:
218 */
219 #if defined(DEBUG)
220 extern void prom_printf(const char *, ...);
221
222 /*
223 * Following values are defined for this debug flag.
224 *
225 * 1 = dump configuration header only.
226 * 2 = dump generic debug data only (no config header dumped)
227 * 3 = dump everything (both 1 and 2)
228 */
229 int pcicfg_debug = 0;
230 int pcicfg_dump_fcode = 0;
231
232 static void debug(char *, uintptr_t, uintptr_t,
233 uintptr_t, uintptr_t, uintptr_t);
234
235 #define DEBUG0(fmt)\
236 debug(fmt, 0, 0, 0, 0, 0);
237 #define DEBUG1(fmt, a1)\
238 debug(fmt, (uintptr_t)(a1), 0, 0, 0, 0);
239 #define DEBUG2(fmt, a1, a2)\
240 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2), 0, 0, 0);
241 #define DEBUG3(fmt, a1, a2, a3)\
242 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2),\
243 (uintptr_t)(a3), 0, 0);
244 #define DEBUG4(fmt, a1, a2, a3, a4)\
245 debug(fmt, (uintptr_t)(a1), (uintptr_t)(a2),\
246 (uintptr_t)(a3), (uintptr_t)(a4), 0);
247 #else
248 #define DEBUG0(fmt)
249 #define DEBUG1(fmt, a1)
250 #define DEBUG2(fmt, a1, a2)
251 #define DEBUG3(fmt, a1, a2, a3)
252 #define DEBUG4(fmt, a1, a2, a3, a4)
253 #endif
254
255 #ifdef PCICFG_INTERPRET_FCODE
256 int pcicfg_dont_interpret = 0;
257 #else
258 int pcicfg_dont_interpret = 1;
259 #endif
260
261 /*
262 * forward declarations for routines defined in this module (called here)
263 */
264
265 static int pcicfg_add_config_reg(dev_info_t *,
266 uint_t, uint_t, uint_t);
267 static int pcicfg_probe_children(dev_info_t *, uint_t, uint_t, uint_t,
268 uint_t *, pcicfg_flags_t, boolean_t);
269
270 #ifdef PCICFG_INTERPRET_FCODE
271 static int pcicfg_load_fcode(dev_info_t *, uint_t, uint_t, uint_t,
272 uint16_t, uint16_t, uchar_t **, int *, int, int);
273 #endif
274
275 static int pcicfg_fcode_probe(dev_info_t *, uint_t, uint_t, uint_t,
276 uint_t *, pcicfg_flags_t, boolean_t);
277 static int pcicfg_probe_bridge(dev_info_t *, ddi_acc_handle_t, uint_t,
278 uint_t *, boolean_t);
279 static int pcicfg_free_all_resources(dev_info_t *);
280 static int pcicfg_alloc_new_resources(dev_info_t *);
281 static int pcicfg_match_dev(dev_info_t *, void *);
282 static dev_info_t *pcicfg_devi_find(dev_info_t *, uint_t, uint_t);
283 static pcicfg_phdl_t *pcicfg_find_phdl(dev_info_t *);
284 static pcicfg_phdl_t *pcicfg_create_phdl(dev_info_t *);
285 static int pcicfg_destroy_phdl(dev_info_t *);
286 static int pcicfg_sum_resources(dev_info_t *, void *);
287 static int pcicfg_find_resource_end(dev_info_t *, void *);
288 static int pcicfg_allocate_chunk(dev_info_t *);
289 static int pcicfg_program_ap(dev_info_t *);
290 static int pcicfg_device_assign(dev_info_t *);
291 static int pcicfg_bridge_assign(dev_info_t *, void *);
292 static int pcicfg_device_assign_readonly(dev_info_t *);
293 static int pcicfg_free_resources(dev_info_t *, pcicfg_flags_t);
294 static void pcicfg_setup_bridge(pcicfg_phdl_t *, ddi_acc_handle_t,
295 dev_info_t *);
296 static void pcicfg_update_bridge(pcicfg_phdl_t *, ddi_acc_handle_t);
297 static void pcicfg_enable_bridge_probe_err(dev_info_t *dip,
298 ddi_acc_handle_t h, pcicfg_err_regs_t *regs);
299 static void pcicfg_disable_bridge_probe_err(dev_info_t *dip,
300 ddi_acc_handle_t h, pcicfg_err_regs_t *regs);
301 static int pcicfg_update_assigned_prop(dev_info_t *, pci_regspec_t *);
302 static void pcicfg_device_on(ddi_acc_handle_t);
303 static void pcicfg_device_off(ddi_acc_handle_t);
304 static int pcicfg_set_busnode_props(dev_info_t *, uint8_t, int, int);
305 static int pcicfg_free_bridge_resources(dev_info_t *);
306 static int pcicfg_free_device_resources(dev_info_t *, pcicfg_flags_t);
307 static int pcicfg_teardown_device(dev_info_t *, pcicfg_flags_t, boolean_t);
308 static int pcicfg_config_setup(dev_info_t *, ddi_acc_handle_t *);
309 static void pcicfg_config_teardown(ddi_acc_handle_t *);
310 static void pcicfg_get_mem(pcicfg_phdl_t *, uint32_t, uint64_t *);
311 static void pcicfg_get_io(pcicfg_phdl_t *, uint32_t, uint32_t *);
312 static int pcicfg_update_ranges_prop(dev_info_t *, pcicfg_range_t *);
313 static int pcicfg_map_phys(dev_info_t *, pci_regspec_t *, caddr_t *,
314 ddi_device_acc_attr_t *, ddi_acc_handle_t *);
315 static void pcicfg_unmap_phys(ddi_acc_handle_t *, pci_regspec_t *);
316 static int pcicfg_dump_assigned(dev_info_t *);
317 static uint_t pcicfg_configure_ntbridge(dev_info_t *, uint_t, uint_t);
318 static int pcicfg_indirect_map(dev_info_t *dip);
319 static uint_t pcicfg_get_ntbridge_child_range(dev_info_t *, uint64_t *,
320 uint64_t *, uint_t);
321 static int pcicfg_is_ntbridge(dev_info_t *);
322 static int pcicfg_ntbridge_allocate_resources(dev_info_t *);
323 static int pcicfg_ntbridge_configure_done(dev_info_t *);
324 static int pcicfg_ntbridge_unconfigure(dev_info_t *);
325 static int pcicfg_ntbridge_unconfigure_child(dev_info_t *, uint_t);
326 static void pcicfg_free_hole(hole_t *);
327 static uint64_t pcicfg_alloc_hole(hole_t *, uint64_t *, uint32_t);
328 static int pcicfg_update_available_prop(dev_info_t *, pci_regspec_t *);
329 static int pcicfg_ari_configure(dev_info_t *);
330 static int pcicfg_populate_reg_props(dev_info_t *, ddi_acc_handle_t);
331 static int pcicfg_populate_props_from_bar(dev_info_t *, ddi_acc_handle_t);
332 static int pcicfg_update_assigned_prop_value(dev_info_t *, uint32_t,
333 uint32_t, uint32_t, uint_t);
334 static boolean_t is_pcie_fabric(dev_info_t *dip);
335
336 #ifdef DEBUG
337 static void pcicfg_dump_common_config(ddi_acc_handle_t config_handle);
338 static void pcicfg_dump_device_config(ddi_acc_handle_t);
339
340 static void pcicfg_dump_bridge_config(ddi_acc_handle_t config_handle);
341 static uint64_t pcicfg_unused_space(hole_t *, uint32_t *);
342
343 #define PCICFG_DUMP_COMMON_CONFIG(hdl) (void)pcicfg_dump_common_config(hdl)
344 #define PCICFG_DUMP_DEVICE_CONFIG(hdl) (void)pcicfg_dump_device_config(hdl)
345 #define PCICFG_DUMP_BRIDGE_CONFIG(hdl) (void)pcicfg_dump_bridge_config(hdl)
346 #else
347 #define PCICFG_DUMP_COMMON_CONFIG(handle)
348 #define PCICFG_DUMP_DEVICE_CONFIG(handle)
349 #define PCICFG_DUMP_BRIDGE_CONFIG(handle)
350 #endif
351
352 static kmutex_t pcicfg_list_mutex; /* Protects the probe handle list */
353 static pcicfg_phdl_t *pcicfg_phdl_list = NULL;
354
355 #ifndef _DONT_USE_1275_GENERIC_NAMES
356 /*
357 * Class code table
358 */
359 static struct pcicfg_name_entry pcicfg_class_lookup [] = {
360
361 { 0x001, "display" },
362 { 0x100, "scsi" },
363 { 0x101, "ide" },
364 { 0x102, "fdc" },
365 { 0x103, "ipi" },
366 { 0x104, "raid" },
367 { 0x200, "ethernet" },
368 { 0x201, "token-ring" },
369 { 0x202, "fddi" },
370 { 0x203, "atm" },
371 { 0x300, "display" },
372 { 0x400, "video" },
373 { 0x401, "sound" },
374 { 0x500, "memory" },
375 { 0x501, "flash" },
376 { 0x600, "host" },
377 { 0x601, "isa" },
378 { 0x602, "eisa" },
379 { 0x603, "mca" },
380 { 0x604, "pci" },
381 { 0x605, "pcmcia" },
382 { 0x606, "nubus" },
383 { 0x607, "cardbus" },
384 { 0x609, "pci" },
385 { 0x700, "serial" },
386 { 0x701, "parallel" },
387 { 0x800, "interrupt-controller" },
388 { 0x801, "dma-controller" },
389 { 0x802, "timer" },
390 { 0x803, "rtc" },
391 { 0x900, "keyboard" },
392 { 0x901, "pen" },
393 { 0x902, "mouse" },
394 { 0xa00, "dock" },
395 { 0xb00, "cpu" },
396 { 0xc00, "firewire" },
397 { 0xc01, "access-bus" },
398 { 0xc02, "ssa" },
399 { 0xc03, "usb" },
400 { 0xc04, "fibre-channel" },
401 { 0, 0 }
402 };
403 #endif /* _DONT_USE_1275_GENERIC_NAMES */
404
405 /*
406 * Module control operations
407 */
408
409 extern struct mod_ops mod_miscops;
410
411 static struct modlmisc modlmisc = {
412 &mod_miscops, /* Type of module */
413 "PCIe/PCI Config (EFCode Enabled)"
414 };
415
416 static struct modlinkage modlinkage = {
417 MODREV_1, (void *)&modlmisc, NULL
418 };
419
420 #ifdef DEBUG
421
422 static void
pcicfg_dump_common_config(ddi_acc_handle_t config_handle)423 pcicfg_dump_common_config(ddi_acc_handle_t config_handle)
424 {
425 if ((pcicfg_debug & 1) == 0)
426 return;
427 cmn_err(CE_CONT, " Vendor ID = [0x%x]\n",
428 pci_config_get16(config_handle, PCI_CONF_VENID));
429 cmn_err(CE_CONT, " Device ID = [0x%x]\n",
430 pci_config_get16(config_handle, PCI_CONF_DEVID));
431 cmn_err(CE_CONT, " Command REG = [0x%x]\n",
432 pci_config_get16(config_handle, PCI_CONF_COMM));
433 cmn_err(CE_CONT, " Status REG = [0x%x]\n",
434 pci_config_get16(config_handle, PCI_CONF_STAT));
435 cmn_err(CE_CONT, " Revision ID = [0x%x]\n",
436 pci_config_get8(config_handle, PCI_CONF_REVID));
437 cmn_err(CE_CONT, " Prog Class = [0x%x]\n",
438 pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
439 cmn_err(CE_CONT, " Dev Class = [0x%x]\n",
440 pci_config_get8(config_handle, PCI_CONF_SUBCLASS));
441 cmn_err(CE_CONT, " Base Class = [0x%x]\n",
442 pci_config_get8(config_handle, PCI_CONF_BASCLASS));
443 cmn_err(CE_CONT, " Device ID = [0x%x]\n",
444 pci_config_get8(config_handle, PCI_CONF_CACHE_LINESZ));
445 cmn_err(CE_CONT, " Header Type = [0x%x]\n",
446 pci_config_get8(config_handle, PCI_CONF_HEADER));
447 cmn_err(CE_CONT, " BIST = [0x%x]\n",
448 pci_config_get8(config_handle, PCI_CONF_BIST));
449 cmn_err(CE_CONT, " BASE 0 = [0x%x]\n",
450 pci_config_get32(config_handle, PCI_CONF_BASE0));
451 cmn_err(CE_CONT, " BASE 1 = [0x%x]\n",
452 pci_config_get32(config_handle, PCI_CONF_BASE1));
453
454 }
455
456 static void
pcicfg_dump_device_config(ddi_acc_handle_t config_handle)457 pcicfg_dump_device_config(ddi_acc_handle_t config_handle)
458 {
459 if ((pcicfg_debug & 1) == 0)
460 return;
461 pcicfg_dump_common_config(config_handle);
462
463 cmn_err(CE_CONT, " BASE 2 = [0x%x]\n",
464 pci_config_get32(config_handle, PCI_CONF_BASE2));
465 cmn_err(CE_CONT, " BASE 3 = [0x%x]\n",
466 pci_config_get32(config_handle, PCI_CONF_BASE3));
467 cmn_err(CE_CONT, " BASE 4 = [0x%x]\n",
468 pci_config_get32(config_handle, PCI_CONF_BASE4));
469 cmn_err(CE_CONT, " BASE 5 = [0x%x]\n",
470 pci_config_get32(config_handle, PCI_CONF_BASE5));
471 cmn_err(CE_CONT, " Cardbus CIS = [0x%x]\n",
472 pci_config_get32(config_handle, PCI_CONF_CIS));
473 cmn_err(CE_CONT, " Sub VID = [0x%x]\n",
474 pci_config_get16(config_handle, PCI_CONF_SUBVENID));
475 cmn_err(CE_CONT, " Sub SID = [0x%x]\n",
476 pci_config_get16(config_handle, PCI_CONF_SUBSYSID));
477 cmn_err(CE_CONT, " ROM = [0x%x]\n",
478 pci_config_get32(config_handle, PCI_CONF_ROM));
479 cmn_err(CE_CONT, " I Line = [0x%x]\n",
480 pci_config_get8(config_handle, PCI_CONF_ILINE));
481 cmn_err(CE_CONT, " I Pin = [0x%x]\n",
482 pci_config_get8(config_handle, PCI_CONF_IPIN));
483 cmn_err(CE_CONT, " Max Grant = [0x%x]\n",
484 pci_config_get8(config_handle, PCI_CONF_MIN_G));
485 cmn_err(CE_CONT, " Max Latent = [0x%x]\n",
486 pci_config_get8(config_handle, PCI_CONF_MAX_L));
487 }
488
489 static void
pcicfg_dump_bridge_config(ddi_acc_handle_t config_handle)490 pcicfg_dump_bridge_config(ddi_acc_handle_t config_handle)
491 {
492 if ((pcicfg_debug & 1) == 0)
493 return;
494
495 pcicfg_dump_common_config(config_handle);
496
497 cmn_err(CE_CONT, "........................................\n");
498
499 cmn_err(CE_CONT, " Pri Bus = [0x%x]\n",
500 pci_config_get8(config_handle, PCI_BCNF_PRIBUS));
501 cmn_err(CE_CONT, " Sec Bus = [0x%x]\n",
502 pci_config_get8(config_handle, PCI_BCNF_SECBUS));
503 cmn_err(CE_CONT, " Sub Bus = [0x%x]\n",
504 pci_config_get8(config_handle, PCI_BCNF_SUBBUS));
505 cmn_err(CE_CONT, " Latency = [0x%x]\n",
506 pci_config_get8(config_handle, PCI_BCNF_LATENCY_TIMER));
507 cmn_err(CE_CONT, " I/O Base LO = [0x%x]\n",
508 pci_config_get8(config_handle, PCI_BCNF_IO_BASE_LOW));
509 cmn_err(CE_CONT, " I/O Lim LO = [0x%x]\n",
510 pci_config_get8(config_handle, PCI_BCNF_IO_LIMIT_LOW));
511 cmn_err(CE_CONT, " Sec. Status = [0x%x]\n",
512 pci_config_get16(config_handle, PCI_BCNF_SEC_STATUS));
513 cmn_err(CE_CONT, " Mem Base = [0x%x]\n",
514 pci_config_get16(config_handle, PCI_BCNF_MEM_BASE));
515 cmn_err(CE_CONT, " Mem Limit = [0x%x]\n",
516 pci_config_get16(config_handle, PCI_BCNF_MEM_LIMIT));
517 cmn_err(CE_CONT, " PF Mem Base = [0x%x]\n",
518 pci_config_get16(config_handle, PCI_BCNF_PF_BASE_LOW));
519 cmn_err(CE_CONT, " PF Mem Lim = [0x%x]\n",
520 pci_config_get16(config_handle, PCI_BCNF_PF_LIMIT_LOW));
521 cmn_err(CE_CONT, " PF Base HI = [0x%x]\n",
522 pci_config_get32(config_handle, PCI_BCNF_PF_BASE_HIGH));
523 cmn_err(CE_CONT, " PF Lim HI = [0x%x]\n",
524 pci_config_get32(config_handle, PCI_BCNF_PF_LIMIT_HIGH));
525 cmn_err(CE_CONT, " I/O Base HI = [0x%x]\n",
526 pci_config_get16(config_handle, PCI_BCNF_IO_BASE_HI));
527 cmn_err(CE_CONT, " I/O Lim HI = [0x%x]\n",
528 pci_config_get16(config_handle, PCI_BCNF_IO_LIMIT_HI));
529 cmn_err(CE_CONT, " ROM addr = [0x%x]\n",
530 pci_config_get32(config_handle, PCI_BCNF_ROM));
531 cmn_err(CE_CONT, " Intr Line = [0x%x]\n",
532 pci_config_get8(config_handle, PCI_BCNF_ILINE));
533 cmn_err(CE_CONT, " Intr Pin = [0x%x]\n",
534 pci_config_get8(config_handle, PCI_BCNF_IPIN));
535 cmn_err(CE_CONT, " Bridge Ctrl = [0x%x]\n",
536 pci_config_get16(config_handle, PCI_BCNF_BCNTRL));
537 }
538
539 #endif
540
541
542 int
_init()543 _init()
544 {
545 DEBUG0("PCI configurator installed - Fcode Interpretation/21554\n");
546
547 mutex_init(&pcicfg_list_mutex, NULL, MUTEX_DRIVER, NULL);
548 return (mod_install(&modlinkage));
549 }
550
551 int
_fini(void)552 _fini(void)
553 {
554 int error;
555
556 error = mod_remove(&modlinkage);
557 if (error != 0) {
558 return (error);
559 }
560 mutex_destroy(&pcicfg_list_mutex);
561 return (0);
562 }
563
564 int
_info(struct modinfo * modinfop)565 _info(struct modinfo *modinfop)
566 {
567 return (mod_info(&modlinkage, modinfop));
568 }
569
570 /*ARGSUSED*/
571 static uint8_t
pcicfg_get_nslots(dev_info_t * dip,ddi_acc_handle_t handle)572 pcicfg_get_nslots(dev_info_t *dip, ddi_acc_handle_t handle)
573 {
574 uint8_t num_slots = 0;
575 uint16_t cap_ptr;
576
577 if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_HOTPLUG,
578 &cap_ptr)) == DDI_SUCCESS) {
579 uint32_t config;
580
581 PCI_CAP_PUT8(handle, 0, cap_ptr, PCI_HP_DWORD_SELECT_OFF,
582 PCI_HP_SLOT_CONFIGURATION_REG);
583 config = PCI_CAP_GET32(handle, 0, cap_ptr,
584 PCI_HP_DWORD_DATA_OFF);
585 num_slots = config & 0x1F;
586 } else if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_SLOT_ID, &cap_ptr))
587 == DDI_SUCCESS) {
588 uint8_t esr_reg = PCI_CAP_GET8(handle, 0,
589 cap_ptr, PCI_CAP_ID_REGS_OFF);
590
591 num_slots = PCI_CAPSLOT_NSLOTS(esr_reg);
592 } else if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_ptr))
593 == DDI_SUCCESS) {
594 int port_type = PCI_CAP_GET16(handle, 0, cap_ptr,
595 PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
596
597 if ((port_type == PCIE_PCIECAP_DEV_TYPE_DOWN) &&
598 (PCI_CAP_GET16(handle, 0, cap_ptr, PCIE_PCIECAP)
599 & PCIE_PCIECAP_SLOT_IMPL))
600 num_slots = 1;
601 }
602
603 DEBUG3("%s#%d has %d slots",
604 ddi_get_name(dip), ddi_get_instance(dip), num_slots);
605
606 return (num_slots);
607 }
608
609 /*ARGSUSED*/
610 static uint8_t
pcicfg_is_chassis(dev_info_t * dip,ddi_acc_handle_t handle)611 pcicfg_is_chassis(dev_info_t *dip, ddi_acc_handle_t handle)
612 {
613 uint16_t cap_ptr;
614
615 if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_SLOT_ID, &cap_ptr)) !=
616 DDI_FAILURE) {
617
618 uint8_t esr_reg = PCI_CAP_GET8(handle, 0, cap_ptr, 2);
619 if (PCI_CAPSLOT_FIC(esr_reg))
620 return (B_TRUE);
621 }
622 return (B_FALSE);
623 }
624
625 /*ARGSUSED*/
626 static int
pcicfg_pcie_dev(dev_info_t * dip,int bus_type,pcicfg_err_regs_t * regs)627 pcicfg_pcie_dev(dev_info_t *dip, int bus_type, pcicfg_err_regs_t *regs)
628 {
629 /* get parent device's device_type property */
630 char *device_type;
631 int rc = DDI_FAILURE;
632 dev_info_t *pdip = ddi_get_parent(dip);
633
634 regs->pcie_dev = 0;
635 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
636 DDI_PROP_DONTPASS, "device_type", &device_type)
637 != DDI_PROP_SUCCESS) {
638 DEBUG2("device_type property missing for %s#%d",
639 ddi_get_name(pdip), ddi_get_instance(pdip));
640 return (DDI_FAILURE);
641 }
642 switch (bus_type) {
643 case PCICFG_DEVICE_TYPE_PCIE:
644 if (strcmp(device_type, "pciex") == 0) {
645 rc = DDI_SUCCESS;
646 regs->pcie_dev = 1;
647 }
648 break;
649 case PCICFG_DEVICE_TYPE_PCI:
650 if (strcmp(device_type, "pci") == 0)
651 rc = DDI_SUCCESS;
652 break;
653 default:
654 break;
655 }
656 ddi_prop_free(device_type);
657 return (rc);
658 }
659
660 /*ARGSUSED*/
661 static int
pcicfg_pcie_port_type(dev_info_t * dip,ddi_acc_handle_t handle)662 pcicfg_pcie_port_type(dev_info_t *dip, ddi_acc_handle_t handle)
663 {
664 int port_type = -1;
665 uint16_t cap_ptr;
666
667 if ((PCI_CAP_LOCATE(handle, PCI_CAP_ID_PCI_E, &cap_ptr)) !=
668 DDI_FAILURE)
669 port_type = PCI_CAP_GET16(handle, 0,
670 cap_ptr, PCIE_PCIECAP) & PCIE_PCIECAP_DEV_TYPE_MASK;
671
672 return (port_type);
673 }
674
675 static int
pcicfg_pcie_device_type(dev_info_t * dip,ddi_acc_handle_t handle)676 pcicfg_pcie_device_type(dev_info_t *dip, ddi_acc_handle_t handle)
677 {
678 int port_type = pcicfg_pcie_port_type(dip, handle);
679
680 DEBUG1("device port_type = %x\n", port_type);
681 /* No PCIe CAP regs, we are not PCIe device_type */
682 if (port_type < 0)
683 return (DDI_FAILURE);
684
685 /* check for all PCIe device_types */
686 if ((port_type == PCIE_PCIECAP_DEV_TYPE_UP) ||
687 (port_type == PCIE_PCIECAP_DEV_TYPE_DOWN) ||
688 (port_type == PCIE_PCIECAP_DEV_TYPE_ROOT) ||
689 (port_type == PCIE_PCIECAP_DEV_TYPE_PCI2PCIE))
690 return (DDI_SUCCESS);
691
692 return (DDI_FAILURE);
693
694 }
695
696 /*
697 * In the following functions ndi_devi_enter() without holding the
698 * parent dip is sufficient. This is because pci dr is driven through
699 * opens on the nexus which is in the device tree path above the node
700 * being operated on, and implicitly held due to the open.
701 */
702
703 /*
704 * This entry point is called to configure a device (and
705 * all its children) on the given bus. It is called when
706 * a new device is added to the PCI domain. This routine
707 * will create the device tree and program the devices
708 * registers.
709 */
710
711 int
pcicfg_configure(dev_info_t * devi,uint_t device,uint_t function,pcicfg_flags_t flags)712 pcicfg_configure(dev_info_t *devi, uint_t device, uint_t function,
713 pcicfg_flags_t flags)
714 {
715 uint_t bus;
716 int len;
717 int func;
718 int trans_device;
719 dev_info_t *new_device;
720 pcicfg_bus_range_t pci_bus_range;
721 int rv;
722 uint_t highest_bus = 0;
723 int ari_mode = B_FALSE;
724 int max_function = PCICFG_MAX_FUNCTION;
725 boolean_t is_pcie;
726
727 if (flags == PCICFG_FLAG_ENABLE_ARI)
728 return (pcicfg_ari_configure(devi));
729
730 /*
731 * Start probing at the device specified in "device" on the
732 * "bus" specified.
733 */
734 len = sizeof (pcicfg_bus_range_t);
735 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, devi, DDI_PROP_DONTPASS,
736 "bus-range", (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
737 DEBUG0("no bus-range property\n");
738 return (PCICFG_FAILURE);
739 }
740
741 bus = pci_bus_range.lo; /* primary bus number of this bus node */
742
743 is_pcie = is_pcie_fabric(devi);
744
745 ndi_devi_enter(devi);
746 for (func = 0; func < max_function; ) {
747 if ((function != PCICFG_ALL_FUNC) && (function != func))
748 goto next;
749
750 if (ari_mode)
751 trans_device = func >> 3;
752 else
753 trans_device = device;
754
755 DEBUG3("Configuring [0x%x][0x%x][0x%x]\n",
756 bus, trans_device, func & 7);
757
758 /*
759 * Try executing fcode if available.
760 */
761 switch (rv = pcicfg_fcode_probe(devi, bus, trans_device,
762 func & 7, &highest_bus, flags, is_pcie)) {
763 case PCICFG_FAILURE:
764 DEBUG2("configure failed: "
765 "bus [0x%x] device [0x%x]\n",
766 bus, trans_device);
767 break;
768 case PCICFG_NODEVICE:
769 DEBUG3("no device : bus "
770 "[0x%x] slot [0x%x] func [0x%x]\n",
771 bus, trans_device, func & 7);
772
773 /*
774 * When walking the list of ARI functions
775 * we don't expect to see a non-present
776 * function, so we will stop walking
777 * the function list.
778 */
779 if (ari_mode == B_TRUE)
780 break;
781
782 if (func)
783 goto next;
784 break;
785 default:
786 DEBUG3("configure: bus => [%d] "
787 "slot => [%d] func => [%d]\n",
788 bus, trans_device, func & 7);
789 break;
790 }
791
792 if (rv != PCICFG_SUCCESS)
793 break;
794
795 if ((new_device = pcicfg_devi_find(devi,
796 trans_device, (func & 7))) == NULL) {
797 DEBUG0("Did'nt find device node just created\n");
798 goto cleanup;
799 }
800
801 next:
802 /*
803 * Determine if ARI Forwarding should be enabled.
804 */
805 if (func == 0) {
806 if ((pcie_ari_supported(devi)
807 == PCIE_ARI_FORW_SUPPORTED) &&
808 (pcie_ari_device(new_device) == PCIE_ARI_DEVICE)) {
809 if (pcie_ari_enable(devi) == DDI_SUCCESS) {
810 (void) ddi_prop_create(DDI_DEV_T_NONE,
811 devi, DDI_PROP_CANSLEEP,
812 "ari-enabled", NULL, 0);
813
814 ari_mode = B_TRUE;
815 max_function = PCICFG_MAX_ARI_FUNCTION;
816 }
817 }
818 }
819
820 if (ari_mode == B_TRUE) {
821 int next_function;
822
823 DEBUG0("Next Function - ARI Device\n");
824 if (pcie_ari_get_next_function(new_device,
825 &next_function) != DDI_SUCCESS)
826 goto cleanup;
827
828 /*
829 * Check if there are more fucntions to probe.
830 */
831 if (next_function == 0) {
832 DEBUG0("Next Function - "
833 "No more ARI Functions\n");
834 break;
835 }
836 func = next_function;
837 } else {
838 func++;
839 }
840
841 DEBUG1("Next Function - %x\n", func);
842 }
843
844 ndi_devi_exit(devi);
845
846 if (func == 0)
847 return (PCICFG_FAILURE); /* probe failed */
848 else
849 return (PCICFG_SUCCESS);
850
851 cleanup:
852 /*
853 * Clean up a partially created "probe state" tree.
854 * There are no resources allocated to the in the
855 * probe state.
856 */
857 if (pcie_ari_is_enabled(devi) == PCIE_ARI_FORW_ENABLED)
858 max_function = PCICFG_MAX_ARI_FUNCTION;
859 else
860 max_function = PCICFG_MAX_FUNCTION;
861
862 for (func = 0; func < max_function; func++) {
863
864 if (max_function == PCICFG_MAX_ARI_FUNCTION)
865 trans_device = func >> 3; /* ARI Device */
866 else
867 trans_device = device;
868
869 if ((new_device = pcicfg_devi_find(devi,
870 trans_device, (func & 0x7))) == NULL) {
871 DEBUG0("No more devices to clean up\n");
872 continue;
873 }
874
875 DEBUG2("Cleaning up device [0x%x] function [0x%x]\n",
876 trans_device, func & 7);
877 /*
878 * If this was a bridge device it will have a
879 * probe handle - if not, no harm in calling this.
880 */
881 (void) pcicfg_destroy_phdl(new_device);
882
883 if (is_pcie) {
884 /*
885 * Free bus_t structure
886 */
887 if (ddi_get_child(new_device) != NULL)
888 pcie_fab_fini_bus(new_device, PCIE_BUS_ALL);
889
890 pcie_fini_bus(new_device, PCIE_BUS_ALL);
891 }
892 /*
893 * This will free up the node
894 */
895 (void) ndi_devi_offline(new_device, NDI_DEVI_REMOVE);
896 }
897 ndi_devi_exit(devi);
898
899 return (PCICFG_FAILURE);
900 }
901
902 /*
903 * configure the child nodes of ntbridge. new_device points to ntbridge itself
904 */
905 /*ARGSUSED*/
906 static uint_t
pcicfg_configure_ntbridge(dev_info_t * new_device,uint_t bus,uint_t device)907 pcicfg_configure_ntbridge(dev_info_t *new_device, uint_t bus, uint_t device)
908 {
909 int bus_range[2], rc = PCICFG_FAILURE, rc1, max_devs = 0;
910 int devno;
911 dev_info_t *new_ntbridgechild;
912 ddi_acc_handle_t config_handle;
913 uint16_t vid;
914 uint64_t next_bus;
915 uint64_t blen;
916 ndi_ra_request_t req;
917 uint8_t pcie_device_type = 0;
918
919 /*
920 * If we need to do indirect config, lets create a property here
921 * to let the child conf map routine know that it has to
922 * go through the DDI calls, and not assume the devices are
923 * mapped directly under the host.
924 */
925 if ((rc = ndi_prop_update_int(DDI_DEV_T_NONE, new_device,
926 PCI_DEV_CONF_MAP_PROP, (int)DDI_SUCCESS))
927 != DDI_SUCCESS) {
928
929 DEBUG0("Cannot create indirect conf map property.\n");
930 return ((uint_t)PCICFG_FAILURE);
931 }
932 if (pci_config_setup(new_device, &config_handle) != DDI_SUCCESS)
933 return ((uint_t)PCICFG_FAILURE);
934 /* check if we are PCIe device */
935 if (pcicfg_pcie_device_type(new_device, config_handle) == DDI_SUCCESS)
936 pcie_device_type = 1;
937 pci_config_teardown(&config_handle);
938
939 /* create Bus node properties for ntbridge. */
940 if (pcicfg_set_busnode_props(new_device, pcie_device_type, -1, -1) !=
941 PCICFG_SUCCESS) {
942 DEBUG0("Failed to set busnode props\n");
943 return (rc);
944 }
945
946 /* For now: Lets only support one layer of child */
947 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
948 req.ra_len = 1;
949 if (ndi_ra_alloc(ddi_get_parent(new_device), &req,
950 &next_bus, &blen, NDI_RA_TYPE_PCI_BUSNUM,
951 NDI_RA_PASS) != NDI_SUCCESS) {
952 DEBUG0("ntbridge: Failed to get a bus number\n");
953 return (rc);
954 }
955
956 DEBUG1("ntbridge bus range start ->[%d]\n", next_bus);
957
958 /*
959 * Following will change, as we detect more bridges
960 * on the way.
961 */
962 bus_range[0] = (int)next_bus;
963 bus_range[1] = (int)next_bus;
964
965 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, new_device,
966 "bus-range", bus_range, 2) != DDI_SUCCESS) {
967 DEBUG0("Cannot set ntbridge bus-range property");
968 return (rc);
969 }
970
971 /*
972 * The other interface (away from the host) will be
973 * initialized by the nexus driver when it loads.
974 * We just have to set the registers and the nexus driver
975 * figures out the rest.
976 */
977
978 /*
979 * finally, lets load and attach the driver
980 * before configuring children of ntbridge.
981 */
982 rc = ndi_devi_online(new_device, NDI_NO_EVENT|NDI_CONFIG);
983 if (rc != NDI_SUCCESS) {
984 cmn_err(CE_WARN,
985 "pcicfg: Fail: can\'t load non-transparent bridge \
986 driver.\n");
987 rc = PCICFG_FAILURE;
988 return (rc);
989 }
990 DEBUG0("pcicfg: Success loading nontransparent bridge nexus driver..");
991
992 /* Now set aside pci resources for our children. */
993 if (pcicfg_ntbridge_allocate_resources(new_device) !=
994 PCICFG_SUCCESS) {
995 max_devs = 0;
996 rc = PCICFG_FAILURE;
997 } else
998 max_devs = PCICFG_MAX_DEVICE;
999
1000 /* Probe devices on 2nd bus */
1001 for (devno = pcicfg_start_devno; devno < max_devs; devno++) {
1002
1003 if (ndi_devi_alloc(new_device, DEVI_PSEUDO_NEXNAME,
1004 (pnode_t)DEVI_SID_NODEID, &new_ntbridgechild)
1005 != NDI_SUCCESS) {
1006
1007 DEBUG0("pcicfg: Failed to alloc test node\n");
1008 rc = PCICFG_FAILURE;
1009 break;
1010 }
1011
1012 if (pcicfg_add_config_reg(new_ntbridgechild, next_bus, devno, 0)
1013 != DDI_PROP_SUCCESS) {
1014 cmn_err(CE_WARN,
1015 "Failed to add conf reg for ntbridge child.\n");
1016 (void) ndi_devi_free(new_ntbridgechild);
1017 rc = PCICFG_FAILURE;
1018 break;
1019 }
1020
1021 if ((rc = pci_config_setup(new_ntbridgechild,
1022 &config_handle)) != PCICFG_SUCCESS) {
1023 cmn_err(CE_WARN,
1024 "Cannot map ntbridge child %x\n", devno);
1025 (void) ndi_devi_free(new_ntbridgechild);
1026 rc = PCICFG_FAILURE;
1027 break;
1028 }
1029
1030 /*
1031 * See if there is any PCI HW at this location
1032 * by reading the Vendor ID. If it returns with 0xffff
1033 * then there is no hardware at this location.
1034 */
1035 vid = pci_config_get16(config_handle, PCI_CONF_VENID);
1036
1037 pci_config_teardown(&config_handle);
1038 (void) ndi_devi_free(new_ntbridgechild);
1039 if (vid == 0xffff)
1040 continue;
1041
1042 /* Lets fake attachments points for each child, */
1043 if (pcicfg_configure(new_device, devno, PCICFG_ALL_FUNC, 0)
1044 != PCICFG_SUCCESS) {
1045 int old_dev = pcicfg_start_devno;
1046
1047 cmn_err(CE_WARN,
1048 "Error configuring ntbridge child dev=%d\n", devno);
1049
1050 rc = PCICFG_FAILURE;
1051 while (old_dev != devno) {
1052 if (pcicfg_ntbridge_unconfigure_child(
1053 new_device, old_dev) == PCICFG_FAILURE)
1054
1055 cmn_err(CE_WARN,
1056 "Unconfig Error ntbridge child "
1057 "dev=%d\n", old_dev);
1058 old_dev++;
1059 }
1060 break;
1061 }
1062 } /* devno loop */
1063 DEBUG1("ntbridge: finish probing 2nd bus, rc=%d\n", rc);
1064
1065 if (rc != PCICFG_FAILURE)
1066 rc = pcicfg_ntbridge_configure_done(new_device);
1067 else {
1068 pcicfg_phdl_t *entry = pcicfg_find_phdl(new_device);
1069 uint_t *bus;
1070 int k;
1071
1072 if (ddi_getlongprop(DDI_DEV_T_ANY, new_device,
1073 DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus,
1074 &k) != DDI_PROP_SUCCESS) {
1075 DEBUG0("Failed to read bus-range property\n");
1076 rc = PCICFG_FAILURE;
1077 return (rc);
1078 }
1079
1080 DEBUG2("Need to free bus [%d] range [%d]\n",
1081 bus[0], bus[1] - bus[0] + 1);
1082
1083 if (ndi_ra_free(ddi_get_parent(new_device),
1084 (uint64_t)bus[0], (uint64_t)(bus[1] - bus[0] + 1),
1085 NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
1086 DEBUG0("Failed to free a bus number\n");
1087 rc = PCICFG_FAILURE;
1088 /*
1089 * Don't forget to free up memory from ddi_getlongprop
1090 */
1091 kmem_free((caddr_t)bus, k);
1092
1093 return (rc);
1094 }
1095
1096 /*
1097 * Since no memory allocations are done for non transparent
1098 * bridges (but instead we just set the handle with the
1099 * already allocated memory, we just need to reset the
1100 * following values before calling the destroy_phdl()
1101 * function next, otherwise the it will try to free
1102 * memory allocated as in case of a transparent bridge.
1103 */
1104 entry->memory_len = 0;
1105 entry->io_len = 0;
1106 /* the following will free hole data. */
1107 (void) pcicfg_destroy_phdl(new_device);
1108 /*
1109 * Don't forget to free up memory from ddi_getlongprop
1110 */
1111 kmem_free((caddr_t)bus, k);
1112 }
1113
1114 /*
1115 * Unload driver just in case child configure failed!
1116 */
1117 rc1 = ndi_devi_offline(new_device, NDI_NO_EVENT);
1118 DEBUG1("pcicfg: now unloading the ntbridge driver. rc1=%d\n", rc1);
1119 if (rc1 != NDI_SUCCESS) {
1120 cmn_err(CE_WARN,
1121 "pcicfg: can\'t unload ntbridge driver children.\n");
1122 rc = PCICFG_FAILURE;
1123 }
1124
1125 return (rc);
1126 }
1127
1128 static int
pcicfg_ntbridge_allocate_resources(dev_info_t * dip)1129 pcicfg_ntbridge_allocate_resources(dev_info_t *dip)
1130 {
1131 pcicfg_phdl_t *phdl;
1132 ndi_ra_request_t *mem_request;
1133 ndi_ra_request_t *io_request;
1134 uint64_t boundbase, boundlen;
1135
1136 phdl = pcicfg_find_phdl(dip);
1137 ASSERT(phdl);
1138
1139 mem_request = &phdl->mem_req;
1140 io_request = &phdl->io_req;
1141
1142 phdl->error = PCICFG_SUCCESS;
1143
1144 /* Set Memory space handle for ntbridge */
1145 if (pcicfg_get_ntbridge_child_range(dip, &boundbase, &boundlen,
1146 PCI_BASE_SPACE_MEM) != DDI_SUCCESS) {
1147 cmn_err(CE_WARN,
1148 "ntbridge: Mem resource information failure\n");
1149 phdl->memory_len = 0;
1150 return (PCICFG_FAILURE);
1151 }
1152 mem_request->ra_boundbase = boundbase;
1153 mem_request->ra_boundlen = boundbase + boundlen;
1154 mem_request->ra_len = boundlen;
1155 mem_request->ra_align_mask =
1156 PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
1157 mem_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1158
1159 /*
1160 * mem_request->ra_len =
1161 * PCICFG_ROUND_UP(mem_request->ra_len, PCICFG_MEMGRAN);
1162 */
1163
1164 phdl->memory_base = phdl->memory_last = boundbase;
1165 phdl->memory_len = boundlen;
1166 phdl->mem_hole.start = phdl->memory_base;
1167 phdl->mem_hole.len = mem_request->ra_len;
1168 phdl->mem_hole.next = (hole_t *)NULL;
1169
1170 DEBUG2("Connector requested [0x%llx], needs [0x%llx] bytes of memory\n",
1171 boundlen, mem_request->ra_len);
1172
1173 /* set up a memory resource map for NT bridge */
1174 if (ndi_ra_map_setup(dip, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
1175 DEBUG0("Can not setup ntbridge memory resource map\n");
1176 return (PCICFG_FAILURE);
1177 }
1178 /* initialize the memory map */
1179 if (ndi_ra_free(dip, boundbase, boundlen, NDI_RA_TYPE_MEM,
1180 NDI_RA_PASS) != NDI_SUCCESS) {
1181 DEBUG0("Can not initalize ntbridge memory resource map\n");
1182 return (PCICFG_FAILURE);
1183 }
1184 /* Set IO space handle for ntbridge */
1185 if (pcicfg_get_ntbridge_child_range(dip, &boundbase, &boundlen,
1186 PCI_BASE_SPACE_IO) != DDI_SUCCESS) {
1187 cmn_err(CE_WARN, "ntbridge: IO resource information failure\n");
1188 phdl->io_len = 0;
1189 return (PCICFG_FAILURE);
1190 }
1191 io_request->ra_len = boundlen;
1192 io_request->ra_align_mask =
1193 PCICFG_IOGRAN - 1; /* 4K alignment on I/O space */
1194 io_request->ra_boundbase = boundbase;
1195 io_request->ra_boundlen = boundbase + boundlen;
1196 io_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
1197
1198 /*
1199 * io_request->ra_len =
1200 * PCICFG_ROUND_UP(io_request->ra_len, PCICFG_IOGRAN);
1201 */
1202
1203 phdl->io_base = phdl->io_last = (uint32_t)boundbase;
1204 phdl->io_len = (uint32_t)boundlen;
1205 phdl->io_hole.start = phdl->io_base;
1206 phdl->io_hole.len = io_request->ra_len;
1207 phdl->io_hole.next = (hole_t *)NULL;
1208
1209 DEBUG2("Connector requested [0x%llx], needs [0x%llx] bytes of IO\n",
1210 boundlen, io_request->ra_len);
1211
1212 DEBUG2("MEMORY BASE = [0x%x] length [0x%x]\n",
1213 phdl->memory_base, phdl->memory_len);
1214 DEBUG2("IO BASE = [0x%x] length [0x%x]\n",
1215 phdl->io_base, phdl->io_len);
1216
1217 /* set up a IO resource map for NT bridge */
1218 if (ndi_ra_map_setup(dip, NDI_RA_TYPE_IO) == NDI_FAILURE) {
1219 DEBUG0("Can not setup ntbridge memory resource map\n");
1220 return (PCICFG_FAILURE);
1221 }
1222 /* initialize the IO map */
1223 if (ndi_ra_free(dip, boundbase, boundlen, NDI_RA_TYPE_IO,
1224 NDI_RA_PASS) != NDI_SUCCESS) {
1225 DEBUG0("Can not initalize ntbridge memory resource map\n");
1226 return (PCICFG_FAILURE);
1227 }
1228
1229 return (PCICFG_SUCCESS);
1230 }
1231
1232 static int
pcicfg_ntbridge_configure_done(dev_info_t * dip)1233 pcicfg_ntbridge_configure_done(dev_info_t *dip)
1234 {
1235 pcicfg_range_t range[PCICFG_RANGE_LEN];
1236 pcicfg_phdl_t *entry;
1237 uint_t len;
1238 pcicfg_bus_range_t bus_range;
1239 int new_bus_range[2];
1240
1241 DEBUG1("Configuring children for %llx\n", dip);
1242
1243 entry = pcicfg_find_phdl(dip);
1244 ASSERT(entry);
1245
1246 bzero((caddr_t)range,
1247 sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
1248 range[1].child_hi = range[1].parent_hi |=
1249 (PCI_REG_REL_M | PCI_ADDR_MEM32);
1250 range[1].child_lo = range[1].parent_lo = (uint32_t)entry->memory_base;
1251
1252 range[0].child_hi = range[0].parent_hi |=
1253 (PCI_REG_REL_M | PCI_ADDR_IO);
1254 range[0].child_lo = range[0].parent_lo = (uint32_t)entry->io_base;
1255
1256 len = sizeof (pcicfg_bus_range_t);
1257 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
1258 "bus-range", (caddr_t)&bus_range, (int *)&len) != DDI_SUCCESS) {
1259 DEBUG0("no bus-range property\n");
1260 return (PCICFG_FAILURE);
1261 }
1262
1263 new_bus_range[0] = bus_range.lo; /* primary bus number */
1264 if (entry->highest_bus) { /* secondary bus number */
1265 if (entry->highest_bus < bus_range.lo) {
1266 cmn_err(CE_WARN,
1267 "ntbridge bus range invalid !(%d,%d)\n",
1268 bus_range.lo, entry->highest_bus);
1269 new_bus_range[1] = bus_range.lo + entry->highest_bus;
1270 }
1271 else
1272 new_bus_range[1] = entry->highest_bus;
1273 }
1274 else
1275 new_bus_range[1] = bus_range.hi;
1276
1277 DEBUG2("ntbridge: bus range lo=%x, hi=%x\n",
1278 new_bus_range[0], new_bus_range[1]);
1279
1280 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
1281 "bus-range", new_bus_range, 2) != DDI_SUCCESS) {
1282 DEBUG0("Failed to set bus-range property");
1283 entry->error = PCICFG_FAILURE;
1284 return (PCICFG_FAILURE);
1285 }
1286
1287 #ifdef DEBUG
1288 {
1289 uint64_t unused;
1290 unused = pcicfg_unused_space(&entry->io_hole, &len);
1291 DEBUG2("ntbridge: Unused IO space %llx bytes over %d holes\n",
1292 unused, len);
1293 }
1294 #endif
1295
1296 range[0].size_lo = entry->io_len;
1297 if (pcicfg_update_ranges_prop(dip, &range[0])) {
1298 DEBUG0("Failed to update ranges (i/o)\n");
1299 entry->error = PCICFG_FAILURE;
1300 return (PCICFG_FAILURE);
1301 }
1302
1303 #ifdef DEBUG
1304 {
1305 uint64_t unused;
1306 unused = pcicfg_unused_space(&entry->mem_hole, &len);
1307 DEBUG2("ntbridge: Unused Mem space %llx bytes over %d holes\n",
1308 unused, len);
1309 }
1310 #endif
1311
1312 range[1].size_lo = entry->memory_len;
1313 if (pcicfg_update_ranges_prop(dip, &range[1])) {
1314 DEBUG0("Failed to update ranges (memory)\n");
1315 entry->error = PCICFG_FAILURE;
1316 return (PCICFG_FAILURE);
1317 }
1318
1319 return (PCICFG_SUCCESS);
1320 }
1321
1322 static int
pcicfg_ntbridge_unconfigure_child(dev_info_t * new_device,uint_t devno)1323 pcicfg_ntbridge_unconfigure_child(dev_info_t *new_device, uint_t devno)
1324 {
1325
1326 dev_info_t *new_ntbridgechild;
1327 int len, bus;
1328 uint16_t vid;
1329 ddi_acc_handle_t config_handle;
1330 pcicfg_bus_range_t pci_bus_range;
1331
1332 len = sizeof (pcicfg_bus_range_t);
1333 if (ddi_getlongprop_buf(DDI_DEV_T_ANY, new_device, DDI_PROP_DONTPASS,
1334 "bus-range", (caddr_t)&pci_bus_range, &len) != DDI_SUCCESS) {
1335 DEBUG0("no bus-range property\n");
1336 return (PCICFG_FAILURE);
1337 }
1338
1339 bus = pci_bus_range.lo; /* primary bus number of this bus node */
1340
1341 if (ndi_devi_alloc(new_device, DEVI_PSEUDO_NEXNAME,
1342 (pnode_t)DEVI_SID_NODEID, &new_ntbridgechild) != NDI_SUCCESS) {
1343
1344 DEBUG0("pcicfg: Failed to alloc test node\n");
1345 return (PCICFG_FAILURE);
1346 }
1347
1348 if (pcicfg_add_config_reg(new_ntbridgechild, bus, devno, 0)
1349 != DDI_PROP_SUCCESS) {
1350 cmn_err(CE_WARN,
1351 "Unconfigure: Failed to add conf reg prop for ntbridge "
1352 "child.\n");
1353 (void) ndi_devi_free(new_ntbridgechild);
1354 return (PCICFG_FAILURE);
1355 }
1356
1357 if (pcicfg_config_setup(new_ntbridgechild, &config_handle)
1358 != DDI_SUCCESS) {
1359 cmn_err(CE_WARN,
1360 "pcicfg: Cannot map ntbridge child %x\n", devno);
1361 (void) ndi_devi_free(new_ntbridgechild);
1362 return (PCICFG_FAILURE);
1363 }
1364
1365 /*
1366 * See if there is any PCI HW at this location
1367 * by reading the Vendor ID. If it returns with 0xffff
1368 * then there is no hardware at this location.
1369 */
1370 vid = pci_config_get16(config_handle, PCI_CONF_VENID);
1371
1372 pci_config_teardown(&config_handle);
1373 (void) ndi_devi_free(new_ntbridgechild);
1374 if (vid == 0xffff)
1375 return (PCICFG_NODEVICE);
1376
1377 return (pcicfg_unconfigure(new_device, devno, PCICFG_ALL_FUNC, 0));
1378 }
1379
1380 static int
pcicfg_ntbridge_unconfigure(dev_info_t * dip)1381 pcicfg_ntbridge_unconfigure(dev_info_t *dip)
1382 {
1383 pcicfg_phdl_t *entry = pcicfg_find_phdl(dip);
1384 uint_t *bus;
1385 int k, rc = PCICFG_FAILURE;
1386
1387 if (entry->memory_len)
1388 if (ndi_ra_map_destroy(dip, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
1389 DEBUG1("cannot destroy ntbridge memory map size=%x\n",
1390 entry->memory_len);
1391 return (PCICFG_FAILURE);
1392 }
1393 if (entry->io_len)
1394 if (ndi_ra_map_destroy(dip, NDI_RA_TYPE_IO) == NDI_FAILURE) {
1395 DEBUG1("cannot destroy ntbridge io map size=%x\n",
1396 entry->io_len);
1397 return (PCICFG_FAILURE);
1398 }
1399 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1400 DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus,
1401 &k) != DDI_PROP_SUCCESS) {
1402 DEBUG0("ntbridge: Failed to read bus-range property\n");
1403 return (rc);
1404 }
1405
1406 DEBUG2("ntbridge: Need to free bus [%d] range [%d]\n",
1407 bus[0], bus[1] - bus[0] + 1);
1408
1409 if (ndi_ra_free(ddi_get_parent(dip),
1410 (uint64_t)bus[0], (uint64_t)(bus[1] - bus[0] + 1),
1411 NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
1412 DEBUG0("ntbridge: Failed to free a bus number\n");
1413 /*
1414 * Don't forget to free up memory from ddi_getlongprop
1415 */
1416 kmem_free((caddr_t)bus, k);
1417
1418 return (rc);
1419 }
1420
1421 /*
1422 * Don't forget to free up memory from ddi_getlongprop
1423 */
1424 kmem_free((caddr_t)bus, k);
1425
1426 /*
1427 * Since our resources will be freed at the parent level,
1428 * just reset these values.
1429 */
1430 entry->memory_len = 0;
1431 entry->io_len = 0;
1432 /* the following will also free hole data. */
1433 return (pcicfg_destroy_phdl(dip));
1434
1435 }
1436
1437 static int
pcicfg_is_ntbridge(dev_info_t * dip)1438 pcicfg_is_ntbridge(dev_info_t *dip)
1439 {
1440 ddi_acc_handle_t config_handle;
1441 uint8_t class, subclass;
1442 int rc = DDI_SUCCESS;
1443
1444 if (pcicfg_config_setup(dip, &config_handle) != DDI_SUCCESS) {
1445 cmn_err(CE_WARN,
1446 "pcicfg: cannot map config space, to get map type\n");
1447 return (DDI_FAILURE);
1448 }
1449 class = pci_config_get8(config_handle, PCI_CONF_BASCLASS);
1450 subclass = pci_config_get8(config_handle, PCI_CONF_SUBCLASS);
1451
1452 /* check for class=6, subclass=9, for non transparent bridges. */
1453 if ((class != PCI_CLASS_BRIDGE) || (subclass != PCI_BRIDGE_STBRIDGE))
1454 rc = DDI_FAILURE;
1455
1456 DEBUG3("pcicfg: checking device %x,%x for indirect map. rc=%d\n",
1457 pci_config_get16(config_handle, PCI_CONF_VENID),
1458 pci_config_get16(config_handle, PCI_CONF_DEVID),
1459 rc);
1460 pci_config_teardown(&config_handle);
1461 return (rc);
1462 }
1463
1464 /*
1465 * this function is called only for SPARC platforms, where we may have
1466 * a mix n' match of direct vs indirectly mapped configuration space.
1467 * On x86, this function does not get called. We always return TRUE
1468 * via a macro for x86.
1469 */
1470 /*ARGSUSED*/
1471 static int
pcicfg_indirect_map(dev_info_t * dip)1472 pcicfg_indirect_map(dev_info_t *dip)
1473 {
1474 #if defined(__sparc)
1475 int rc = DDI_FAILURE;
1476
1477 if (ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip), 0,
1478 PCI_DEV_CONF_MAP_PROP, DDI_FAILURE) != DDI_FAILURE)
1479 rc = DDI_SUCCESS;
1480 else
1481 if (ddi_prop_get_int(DDI_DEV_T_ANY, ddi_get_parent(dip),
1482 0, PCI_BUS_CONF_MAP_PROP,
1483 DDI_FAILURE) != DDI_FAILURE)
1484 rc = DDI_SUCCESS;
1485 DEBUG1("pci conf map = %d", rc);
1486 return (rc);
1487 #else
1488 return (DDI_SUCCESS);
1489 #endif
1490 }
1491
1492 static uint_t
pcicfg_get_ntbridge_child_range(dev_info_t * dip,uint64_t * boundbase,uint64_t * boundlen,uint_t space_type)1493 pcicfg_get_ntbridge_child_range(dev_info_t *dip, uint64_t *boundbase,
1494 uint64_t *boundlen, uint_t space_type)
1495 {
1496 int length, found = DDI_FAILURE, acount, i, ibridge;
1497 pci_regspec_t *assigned;
1498
1499 if ((ibridge = pcicfg_is_ntbridge(dip)) == DDI_FAILURE)
1500 return (found);
1501
1502 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1503 DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
1504 &length) != DDI_PROP_SUCCESS) {
1505 DEBUG1("Failed to get assigned-addresses property %llx\n", dip);
1506 return (found);
1507 }
1508 DEBUG1("pcicfg: ntbridge child range: dip = %s\n",
1509 ddi_driver_name(dip));
1510
1511 acount = length / sizeof (pci_regspec_t);
1512
1513 for (i = 0; i < acount; i++) {
1514 if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) ==
1515 pcicfg_indirect_map_devs[ibridge].mem_range_bar_offset) &&
1516 (space_type == PCI_BASE_SPACE_MEM)) {
1517 found = DDI_SUCCESS;
1518 break;
1519 } else {
1520 if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) ==
1521 pcicfg_indirect_map_devs[ibridge].\
1522 io_range_bar_offset) &&
1523 (space_type == PCI_BASE_SPACE_IO)) {
1524 found = DDI_SUCCESS;
1525 break;
1526 }
1527 }
1528 }
1529 DEBUG3("pcicfg: ntbridge child range: space=%x, base=%lx, len=%lx\n",
1530 space_type, assigned[i].pci_phys_low, assigned[i].pci_size_low);
1531
1532 if (found == DDI_SUCCESS) {
1533 *boundbase = assigned[i].pci_phys_low;
1534 *boundlen = assigned[i].pci_size_low;
1535 }
1536
1537 kmem_free(assigned, length);
1538 return (found);
1539 }
1540
1541 /*
1542 * This will turn resources allocated by pcicfg_configure()
1543 * and remove the device tree from the Hotplug Connection (CN)
1544 * and below. The routine assumes the devices have their
1545 * drivers detached.
1546 */
1547 int
pcicfg_unconfigure(dev_info_t * devi,uint_t device,uint_t function,pcicfg_flags_t flags)1548 pcicfg_unconfigure(dev_info_t *devi, uint_t device, uint_t function,
1549 pcicfg_flags_t flags)
1550 {
1551 dev_info_t *child_dip;
1552 int func;
1553 int i;
1554 int max_function;
1555 int trans_device;
1556 boolean_t is_pcie;
1557
1558 if (pcie_ari_is_enabled(devi) == PCIE_ARI_FORW_ENABLED)
1559 max_function = PCICFG_MAX_ARI_FUNCTION;
1560 else
1561 max_function = PCICFG_MAX_FUNCTION;
1562
1563 /*
1564 * Cycle through devices to make sure none are busy.
1565 * If a single device is busy fail the whole unconfigure.
1566 */
1567 is_pcie = is_pcie_fabric(devi);
1568
1569 ndi_devi_enter(devi);
1570 for (func = 0; func < max_function; func++) {
1571
1572 if (max_function == PCICFG_MAX_ARI_FUNCTION)
1573 trans_device = func >> 3; /* ARI Device */
1574 else
1575 trans_device = device;
1576
1577 if ((child_dip = pcicfg_devi_find(devi, trans_device,
1578 (func & 0x7))) == NULL)
1579 continue;
1580
1581 if (ndi_devi_offline(child_dip, NDI_UNCONFIG) == NDI_SUCCESS)
1582 continue;
1583 /*
1584 * Device function is busy. Before returning we have to
1585 * put all functions back online which were taken
1586 * offline during the process.
1587 */
1588 DEBUG2("Device [0x%x] function [%x] is busy\n", device, func);
1589 /*
1590 * If we are only asked to offline one specific function,
1591 * and that fails, we just simply return.
1592 */
1593 if (function != PCICFG_ALL_FUNC)
1594 return (PCICFG_FAILURE);
1595
1596 for (i = 0; i < func; i++) {
1597
1598 if (max_function == PCICFG_MAX_ARI_FUNCTION)
1599 trans_device = i >> 3;
1600
1601 if ((child_dip =
1602 pcicfg_devi_find(devi, trans_device, (i & 7)))
1603 == NULL) {
1604 DEBUG0(
1605 "No more devices to put back on line!!\n");
1606 /*
1607 * Made it through all functions
1608 */
1609 continue;
1610 }
1611 if (ndi_devi_online(child_dip, NDI_CONFIG)
1612 != NDI_SUCCESS) {
1613 DEBUG0("Failed to put back devices state\n");
1614 goto fail;
1615 }
1616 }
1617 goto fail;
1618 }
1619
1620 /*
1621 * Now, tear down all devinfo nodes for this Connector.
1622 */
1623 for (func = 0; func < max_function; func++) {
1624
1625 if (max_function == PCICFG_MAX_ARI_FUNCTION)
1626 trans_device = func >> 3; /* ARI Device */
1627 else
1628 trans_device = device;
1629
1630 if ((child_dip = pcicfg_devi_find(devi,
1631 trans_device, (func & 7))) == NULL) {
1632 DEBUG0("No more devices to tear down!\n");
1633 continue;
1634 }
1635
1636 DEBUG2("Tearing down device [0x%x] function [0x%x]\n",
1637 trans_device, (func & 7));
1638
1639 if (pcicfg_is_ntbridge(child_dip) != DDI_FAILURE)
1640 if (pcicfg_ntbridge_unconfigure(child_dip) !=
1641 PCICFG_SUCCESS) {
1642 cmn_err(CE_WARN,
1643 "ntbridge: unconfigure failed\n");
1644 goto fail;
1645 }
1646
1647 if (pcicfg_teardown_device(child_dip, flags, is_pcie)
1648 != PCICFG_SUCCESS) {
1649 DEBUG2("Failed to tear down device [0x%x]"
1650 "function [0x%x]\n",
1651 trans_device, func & 7);
1652 goto fail;
1653 }
1654 }
1655
1656 if (pcie_ari_is_enabled(devi) == PCIE_ARI_FORW_ENABLED) {
1657 (void) ddi_prop_remove(DDI_DEV_T_NONE, devi, "ari-enabled");
1658 (void) pcie_ari_disable(devi);
1659 }
1660
1661 ndi_devi_exit(devi);
1662 return (PCICFG_SUCCESS);
1663
1664 fail:
1665 ndi_devi_exit(devi);
1666 return (PCICFG_FAILURE);
1667 }
1668
1669 static int
pcicfg_teardown_device(dev_info_t * dip,pcicfg_flags_t flags,boolean_t is_pcie)1670 pcicfg_teardown_device(dev_info_t *dip, pcicfg_flags_t flags, boolean_t is_pcie)
1671 {
1672 ddi_acc_handle_t config_handle;
1673
1674 /*
1675 * Free up resources associated with 'dip'
1676 */
1677 if (pcicfg_free_resources(dip, flags) != PCICFG_SUCCESS) {
1678 DEBUG0("Failed to free resources\n");
1679 return (PCICFG_FAILURE);
1680 }
1681
1682 /*
1683 * This will disable the device
1684 */
1685 if (pci_config_setup(dip, &config_handle) != PCICFG_SUCCESS) {
1686 return (PCICFG_FAILURE);
1687 }
1688
1689 pcicfg_device_off(config_handle);
1690 pci_config_teardown(&config_handle);
1691
1692 /*
1693 * free pcie_bus_t for the sub-tree
1694 */
1695 if (is_pcie) {
1696 if (ddi_get_child(dip) != NULL)
1697 pcie_fab_fini_bus(dip, PCIE_BUS_ALL);
1698
1699 pcie_fini_bus(dip, PCIE_BUS_ALL);
1700 }
1701
1702 /*
1703 * The framework provides this routine which can
1704 * tear down a sub-tree.
1705 */
1706 if (ndi_devi_offline(dip, NDI_DEVI_REMOVE) != NDI_SUCCESS) {
1707 DEBUG0("Failed to offline and remove node\n");
1708 return (PCICFG_FAILURE);
1709 }
1710
1711 return (PCICFG_SUCCESS);
1712 }
1713
1714 /*
1715 * BEGIN GENERIC SUPPORT ROUTINES
1716 */
1717 static pcicfg_phdl_t *
pcicfg_find_phdl(dev_info_t * dip)1718 pcicfg_find_phdl(dev_info_t *dip)
1719 {
1720 pcicfg_phdl_t *entry;
1721 mutex_enter(&pcicfg_list_mutex);
1722 for (entry = pcicfg_phdl_list; entry != NULL; entry = entry->next) {
1723 if (entry->dip == dip) {
1724 mutex_exit(&pcicfg_list_mutex);
1725 return (entry);
1726 }
1727 }
1728 mutex_exit(&pcicfg_list_mutex);
1729
1730 /*
1731 * Did'nt find entry - create one
1732 */
1733 return (pcicfg_create_phdl(dip));
1734 }
1735
1736 static pcicfg_phdl_t *
pcicfg_create_phdl(dev_info_t * dip)1737 pcicfg_create_phdl(dev_info_t *dip)
1738 {
1739 pcicfg_phdl_t *new;
1740
1741 new = (pcicfg_phdl_t *)kmem_zalloc(sizeof (pcicfg_phdl_t),
1742 KM_SLEEP);
1743
1744 new->dip = dip;
1745 mutex_enter(&pcicfg_list_mutex);
1746 new->next = pcicfg_phdl_list;
1747 pcicfg_phdl_list = new;
1748 mutex_exit(&pcicfg_list_mutex);
1749
1750 return (new);
1751 }
1752
1753 static int
pcicfg_destroy_phdl(dev_info_t * dip)1754 pcicfg_destroy_phdl(dev_info_t *dip)
1755 {
1756 pcicfg_phdl_t *entry;
1757 pcicfg_phdl_t *follow = NULL;
1758
1759 mutex_enter(&pcicfg_list_mutex);
1760 for (entry = pcicfg_phdl_list; entry != NULL; follow = entry,
1761 entry = entry->next) {
1762 if (entry->dip == dip) {
1763 if (entry == pcicfg_phdl_list) {
1764 pcicfg_phdl_list = entry->next;
1765 } else {
1766 follow->next = entry->next;
1767 }
1768 /*
1769 * If this entry has any allocated memory
1770 * or IO space associated with it, that
1771 * must be freed up.
1772 */
1773 if (entry->memory_len > 0) {
1774 (void) ndi_ra_free(ddi_get_parent(dip),
1775 entry->memory_base,
1776 entry->memory_len,
1777 NDI_RA_TYPE_MEM, NDI_RA_PASS);
1778 }
1779 pcicfg_free_hole(&entry->mem_hole);
1780
1781 if (entry->io_len > 0) {
1782 (void) ndi_ra_free(ddi_get_parent(dip),
1783 entry->io_base,
1784 entry->io_len,
1785 NDI_RA_TYPE_IO, NDI_RA_PASS);
1786 }
1787 pcicfg_free_hole(&entry->io_hole);
1788
1789 /*
1790 * Destroy this entry
1791 */
1792 kmem_free((caddr_t)entry, sizeof (pcicfg_phdl_t));
1793 mutex_exit(&pcicfg_list_mutex);
1794 return (PCICFG_SUCCESS);
1795 }
1796 }
1797 mutex_exit(&pcicfg_list_mutex);
1798 /*
1799 * Did'nt find the entry
1800 */
1801 return (PCICFG_FAILURE);
1802 }
1803
1804 static int
pcicfg_program_ap(dev_info_t * dip)1805 pcicfg_program_ap(dev_info_t *dip)
1806 {
1807 pcicfg_phdl_t *phdl;
1808 uint8_t header_type;
1809 ddi_acc_handle_t handle;
1810 pcicfg_phdl_t *entry;
1811
1812 if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
1813 DEBUG0("Failed to map config space!\n");
1814 return (PCICFG_FAILURE);
1815
1816 }
1817
1818 header_type = pci_config_get8(handle, PCI_CONF_HEADER);
1819
1820 (void) pcicfg_config_teardown(&handle);
1821
1822 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
1823
1824 if (pcicfg_allocate_chunk(dip) != PCICFG_SUCCESS) {
1825 DEBUG0("Not enough memory to hotplug\n");
1826 (void) pcicfg_destroy_phdl(dip);
1827 return (PCICFG_FAILURE);
1828 }
1829
1830 phdl = pcicfg_find_phdl(dip);
1831 ASSERT(phdl);
1832
1833 (void) pcicfg_bridge_assign(dip, (void *)phdl);
1834
1835 if (phdl->error != PCICFG_SUCCESS) {
1836 DEBUG0("Problem assigning bridge\n");
1837 (void) pcicfg_destroy_phdl(dip);
1838 return (phdl->error);
1839 }
1840
1841 /*
1842 * Successfully allocated and assigned
1843 * memory. Set the memory and IO length
1844 * to zero so when the handle is freed up
1845 * it will not de-allocate assigned resources.
1846 */
1847 entry = (pcicfg_phdl_t *)phdl;
1848
1849 entry->memory_len = entry->io_len = 0;
1850
1851 /*
1852 * Free up the "entry" structure.
1853 */
1854 (void) pcicfg_destroy_phdl(dip);
1855 } else {
1856 if (pcicfg_device_assign(dip) != PCICFG_SUCCESS) {
1857 return (PCICFG_FAILURE);
1858 }
1859 }
1860 return (PCICFG_SUCCESS);
1861 }
1862
1863 static int
pcicfg_bridge_assign(dev_info_t * dip,void * hdl)1864 pcicfg_bridge_assign(dev_info_t *dip, void *hdl)
1865 {
1866 ddi_acc_handle_t handle;
1867 pci_regspec_t *reg;
1868 int length;
1869 int rcount;
1870 int i;
1871 int offset;
1872 uint64_t mem_answer;
1873 uint32_t io_answer;
1874 uint8_t header_type;
1875 pcicfg_range_t range[PCICFG_RANGE_LEN];
1876 int bus_range[2];
1877
1878 pcicfg_phdl_t *entry = (pcicfg_phdl_t *)hdl;
1879
1880 DEBUG1("bridge assign: assigning addresses to %s\n", ddi_get_name(dip));
1881
1882 if (entry == NULL) {
1883 DEBUG0("Failed to get entry\n");
1884 return (DDI_WALK_TERMINATE);
1885 }
1886
1887 entry->error = PCICFG_SUCCESS;
1888
1889 if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
1890 DEBUG0("Failed to map config space!\n");
1891 entry->error = PCICFG_FAILURE;
1892 return (DDI_WALK_TERMINATE);
1893 }
1894
1895 header_type = pci_config_get8(handle, PCI_CONF_HEADER);
1896
1897 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
1898
1899 bzero((caddr_t)range,
1900 sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
1901
1902 (void) pcicfg_setup_bridge(entry, handle, dip);
1903
1904 range[0].child_hi = range[0].parent_hi |=
1905 (PCI_REG_REL_M | PCI_ADDR_IO);
1906 range[0].child_lo = range[0].parent_lo =
1907 entry->io_last;
1908 range[1].child_hi = range[1].parent_hi |=
1909 (PCI_REG_REL_M | PCI_ADDR_MEM32);
1910 range[1].child_lo = range[1].parent_lo =
1911 entry->memory_last;
1912
1913 ndi_devi_enter(dip);
1914 ddi_walk_devs(ddi_get_child(dip),
1915 pcicfg_bridge_assign, (void *)entry);
1916 ndi_devi_exit(dip);
1917
1918 (void) pcicfg_update_bridge(entry, handle);
1919
1920 bus_range[0] = pci_config_get8(handle, PCI_BCNF_SECBUS);
1921 bus_range[1] = pci_config_get8(handle, PCI_BCNF_SUBBUS);
1922
1923 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
1924 "bus-range", bus_range, 2) != DDI_SUCCESS) {
1925 DEBUG0("Failed to set bus-range property");
1926 entry->error = PCICFG_FAILURE;
1927 return (DDI_WALK_TERMINATE);
1928 }
1929
1930 if (entry->io_len > 0) {
1931 range[0].size_lo = entry->io_last - entry->io_base;
1932 if (pcicfg_update_ranges_prop(dip, &range[0])) {
1933 DEBUG0("Failed to update ranges (i/o)\n");
1934 entry->error = PCICFG_FAILURE;
1935 return (DDI_WALK_TERMINATE);
1936 }
1937 }
1938 if (entry->memory_len > 0) {
1939 range[1].size_lo =
1940 entry->memory_last - entry->memory_base;
1941 if (pcicfg_update_ranges_prop(dip, &range[1])) {
1942 DEBUG0("Failed to update ranges (memory)\n");
1943 entry->error = PCICFG_FAILURE;
1944 return (DDI_WALK_TERMINATE);
1945 }
1946 }
1947
1948 (void) pcicfg_device_on(handle);
1949
1950 PCICFG_DUMP_BRIDGE_CONFIG(handle);
1951
1952 return (DDI_WALK_PRUNECHILD);
1953 }
1954
1955 /*
1956 * If there is an interrupt pin set program
1957 * interrupt line with default values.
1958 */
1959 if (pci_config_get8(handle, PCI_CONF_IPIN)) {
1960 pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
1961 }
1962
1963 /*
1964 * A single device (under a bridge).
1965 * For each "reg" property with a length, allocate memory
1966 * and program the base registers.
1967 */
1968 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
1969 DDI_PROP_DONTPASS, "reg", (caddr_t)®,
1970 &length) != DDI_PROP_SUCCESS) {
1971 DEBUG0("Failed to read reg property\n");
1972 entry->error = PCICFG_FAILURE;
1973 return (DDI_WALK_TERMINATE);
1974 }
1975
1976 rcount = length / sizeof (pci_regspec_t);
1977 offset = PCI_CONF_BASE0;
1978 for (i = 0; i < rcount; i++) {
1979 if ((reg[i].pci_size_low != 0)||
1980 (reg[i].pci_size_hi != 0)) {
1981
1982 offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
1983
1984 switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
1985 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
1986
1987 (void) pcicfg_get_mem(entry,
1988 reg[i].pci_size_low, &mem_answer);
1989 pci_config_put64(handle, offset, mem_answer);
1990 DEBUG2("REGISTER off %x (64)LO ----> [0x%x]\n",
1991 offset,
1992 pci_config_get32(handle, offset));
1993 DEBUG2("REGISTER off %x (64)HI ----> [0x%x]\n",
1994 offset + 4,
1995 pci_config_get32(handle, offset + 4));
1996
1997 reg[i].pci_phys_low = PCICFG_HIADDR(mem_answer);
1998 reg[i].pci_phys_mid =
1999 PCICFG_LOADDR(mem_answer);
2000
2001 break;
2002
2003 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2004 /* allocate memory space from the allocator */
2005
2006 (void) pcicfg_get_mem(entry,
2007 reg[i].pci_size_low, &mem_answer);
2008 pci_config_put32(handle,
2009 offset, (uint32_t)mem_answer);
2010
2011 DEBUG2("REGISTER off %x(32)LO ----> [0x%x]\n",
2012 offset,
2013 pci_config_get32(handle, offset));
2014
2015 reg[i].pci_phys_low = (uint32_t)mem_answer;
2016
2017 break;
2018 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2019 /* allocate I/O space from the allocator */
2020
2021 (void) pcicfg_get_io(entry,
2022 reg[i].pci_size_low, &io_answer);
2023 pci_config_put32(handle, offset, io_answer);
2024
2025 DEBUG2("REGISTER off %x (I/O)LO ----> [0x%x]\n",
2026 offset,
2027 pci_config_get32(handle, offset));
2028
2029 reg[i].pci_phys_low = io_answer;
2030
2031 break;
2032 default:
2033 DEBUG0("Unknown register type\n");
2034 kmem_free(reg, length);
2035 (void) pcicfg_config_teardown(&handle);
2036 entry->error = PCICFG_FAILURE;
2037 return (DDI_WALK_TERMINATE);
2038 } /* switch */
2039
2040 /*
2041 * Now that memory locations are assigned,
2042 * update the assigned address property.
2043 */
2044 if (pcicfg_update_assigned_prop(dip,
2045 ®[i]) != PCICFG_SUCCESS) {
2046 kmem_free(reg, length);
2047 (void) pcicfg_config_teardown(&handle);
2048 entry->error = PCICFG_FAILURE;
2049 return (DDI_WALK_TERMINATE);
2050 }
2051 }
2052 }
2053 (void) pcicfg_device_on(handle);
2054
2055 PCICFG_DUMP_DEVICE_CONFIG(handle);
2056
2057 (void) pcicfg_config_teardown(&handle);
2058 /*
2059 * Don't forget to free up memory from ddi_getlongprop
2060 */
2061 kmem_free((caddr_t)reg, length);
2062
2063 return (DDI_WALK_CONTINUE);
2064 }
2065
2066 static int
pcicfg_device_assign(dev_info_t * dip)2067 pcicfg_device_assign(dev_info_t *dip)
2068 {
2069 ddi_acc_handle_t handle;
2070 pci_regspec_t *reg;
2071 int length;
2072 int rcount;
2073 int i;
2074 int offset;
2075 ndi_ra_request_t request;
2076 uint64_t answer;
2077 uint64_t alen;
2078
2079 DEBUG1("%llx now under configuration\n", dip);
2080
2081 /*
2082 * XXX Failure here should be noted
2083 */
2084 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2085 DDI_PROP_DONTPASS, "reg", (caddr_t)®,
2086 &length) != DDI_PROP_SUCCESS) {
2087 DEBUG0("Failed to read reg property\n");
2088 return (PCICFG_FAILURE);
2089 }
2090
2091 if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2092 DEBUG0("Failed to map config space!\n");
2093 /*
2094 * Don't forget to free up memory from ddi_getlongprop
2095 */
2096 kmem_free((caddr_t)reg, length);
2097
2098 return (PCICFG_FAILURE);
2099 }
2100
2101 /*
2102 * A single device
2103 *
2104 * For each "reg" property with a length, allocate memory
2105 * and program the base registers.
2106 */
2107
2108 /*
2109 * If there is an interrupt pin set program
2110 * interrupt line with default values.
2111 */
2112 if (pci_config_get8(handle, PCI_CONF_IPIN)) {
2113 pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
2114 }
2115
2116 bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
2117
2118 request.ra_flags = NDI_RA_ALIGN_SIZE;
2119 request.ra_boundbase = 0;
2120 request.ra_boundlen = PCICFG_4GIG_LIMIT;
2121
2122 rcount = length / sizeof (pci_regspec_t);
2123 for (i = 0; i < rcount; i++) {
2124 if ((reg[i].pci_size_low != 0)||
2125 (reg[i].pci_size_hi != 0)) {
2126
2127 offset = PCI_REG_REG_G(reg[i].pci_phys_hi);
2128 request.ra_len = reg[i].pci_size_low;
2129
2130 switch (PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
2131 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2132 request.ra_flags &= ~NDI_RA_ALLOC_BOUNDED;
2133 /* allocate memory space from the allocator */
2134 if (ndi_ra_alloc(ddi_get_parent(dip),
2135 &request, &answer, &alen,
2136 NDI_RA_TYPE_MEM, NDI_RA_PASS)
2137 != NDI_SUCCESS) {
2138 DEBUG0("Failed to allocate 64b mem\n");
2139 kmem_free(reg, length);
2140 (void) pcicfg_config_teardown(&handle);
2141 return (PCICFG_FAILURE);
2142 }
2143 DEBUG3("64 addr = [0x%x.%x] len [0x%x]\n",
2144 PCICFG_HIADDR(answer),
2145 PCICFG_LOADDR(answer),
2146 alen);
2147 /* program the low word */
2148 pci_config_put32(handle,
2149 offset, PCICFG_LOADDR(answer));
2150
2151 /* program the high word */
2152 pci_config_put32(handle, offset + 4,
2153 PCICFG_HIADDR(answer));
2154
2155 reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2156 reg[i].pci_phys_mid = PCICFG_HIADDR(answer);
2157
2158 /* adjust to 32b address space when possible */
2159 if ((answer + alen) <= PCICFG_4GIG_LIMIT)
2160 reg[i].pci_phys_hi ^=
2161 PCI_ADDR_MEM64 ^ PCI_ADDR_MEM32;
2162 break;
2163
2164 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2165 request.ra_flags |= NDI_RA_ALLOC_BOUNDED;
2166 /* allocate memory space from the allocator */
2167 if (ndi_ra_alloc(ddi_get_parent(dip),
2168 &request, &answer, &alen,
2169 NDI_RA_TYPE_MEM, NDI_RA_PASS)
2170 != NDI_SUCCESS) {
2171 DEBUG0("Failed to allocate 32b mem\n");
2172 kmem_free(reg, length);
2173 (void) pcicfg_config_teardown(&handle);
2174 return (PCICFG_FAILURE);
2175 }
2176 DEBUG3("32 addr = [0x%x.%x] len [0x%x]\n",
2177 PCICFG_HIADDR(answer),
2178 PCICFG_LOADDR(answer),
2179 alen);
2180 /* program the low word */
2181 pci_config_put32(handle,
2182 offset, PCICFG_LOADDR(answer));
2183
2184 reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2185 break;
2186
2187 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2188 /* allocate I/O space from the allocator */
2189 request.ra_flags |= NDI_RA_ALLOC_BOUNDED;
2190 if (ndi_ra_alloc(ddi_get_parent(dip),
2191 &request, &answer, &alen,
2192 NDI_RA_TYPE_IO, NDI_RA_PASS)
2193 != NDI_SUCCESS) {
2194 DEBUG0("Failed to allocate I/O\n");
2195 kmem_free(reg, length);
2196 (void) pcicfg_config_teardown(&handle);
2197 return (PCICFG_FAILURE);
2198 }
2199 DEBUG3("I/O addr = [0x%x.%x] len [0x%x]\n",
2200 PCICFG_HIADDR(answer),
2201 PCICFG_LOADDR(answer),
2202 alen);
2203 pci_config_put32(handle,
2204 offset, PCICFG_LOADDR(answer));
2205
2206 reg[i].pci_phys_low = PCICFG_LOADDR(answer);
2207 break;
2208
2209 default:
2210 DEBUG0("Unknown register type\n");
2211 kmem_free(reg, length);
2212 (void) pcicfg_config_teardown(&handle);
2213 return (PCICFG_FAILURE);
2214 } /* switch */
2215
2216 /*
2217 * Now that memory locations are assigned,
2218 * update the assigned address property.
2219 */
2220
2221 if (pcicfg_update_assigned_prop(dip,
2222 ®[i]) != PCICFG_SUCCESS) {
2223 kmem_free(reg, length);
2224 (void) pcicfg_config_teardown(&handle);
2225 return (PCICFG_FAILURE);
2226 }
2227 }
2228 }
2229
2230 (void) pcicfg_device_on(handle);
2231 kmem_free(reg, length);
2232
2233 PCICFG_DUMP_DEVICE_CONFIG(handle);
2234
2235 (void) pcicfg_config_teardown(&handle);
2236 return (PCICFG_SUCCESS);
2237 }
2238
2239 static int
pcicfg_device_assign_readonly(dev_info_t * dip)2240 pcicfg_device_assign_readonly(dev_info_t *dip)
2241 {
2242 ddi_acc_handle_t handle;
2243 pci_regspec_t *assigned;
2244 int length;
2245 int acount;
2246 int i;
2247 ndi_ra_request_t request;
2248 uint64_t answer;
2249 uint64_t alen;
2250
2251
2252 DEBUG1("%llx now under configuration\n", dip);
2253
2254 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2255 DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
2256 &length) != DDI_PROP_SUCCESS) {
2257 DEBUG0("Failed to read assigned-addresses property\n");
2258 return (PCICFG_FAILURE);
2259 }
2260
2261 if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2262 DEBUG0("Failed to map config space!\n");
2263 /*
2264 * Don't forget to free up memory from ddi_getlongprop
2265 */
2266 kmem_free((caddr_t)assigned, length);
2267
2268 return (PCICFG_FAILURE);
2269 }
2270
2271 /*
2272 * For each "assigned-addresses" property entry with a length,
2273 * call the memory allocation routines to return the
2274 * resource.
2275 */
2276 /*
2277 * If there is an interrupt pin set program
2278 * interrupt line with default values.
2279 */
2280 if (pci_config_get8(handle, PCI_CONF_IPIN)) {
2281 pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
2282 }
2283
2284 bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
2285
2286 request.ra_flags = NDI_RA_ALLOC_SPECIFIED; /* specified addr */
2287 request.ra_boundbase = 0;
2288 request.ra_boundlen = PCICFG_4GIG_LIMIT;
2289
2290 acount = length / sizeof (pci_regspec_t);
2291 for (i = 0; i < acount; i++) {
2292 if ((assigned[i].pci_size_low != 0)||
2293 (assigned[i].pci_size_hi != 0)) {
2294
2295 request.ra_len = assigned[i].pci_size_low;
2296
2297 switch (PCI_REG_ADDR_G(assigned[i].pci_phys_hi)) {
2298 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2299 request.ra_addr = (uint64_t)PCICFG_LADDR(
2300 assigned[i].pci_phys_low,
2301 assigned[i].pci_phys_mid);
2302
2303 /* allocate memory space from the allocator */
2304 if (ndi_ra_alloc(ddi_get_parent(dip),
2305 &request, &answer, &alen,
2306 NDI_RA_TYPE_MEM, NDI_RA_PASS)
2307 != NDI_SUCCESS) {
2308 DEBUG0("Failed to allocate 64b mem\n");
2309 kmem_free(assigned, length);
2310 return (PCICFG_FAILURE);
2311 }
2312
2313 break;
2314 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2315 request.ra_addr = (uint64_t)
2316 assigned[i].pci_phys_low;
2317
2318 /* allocate memory space from the allocator */
2319 if (ndi_ra_alloc(ddi_get_parent(dip),
2320 &request, &answer, &alen,
2321 NDI_RA_TYPE_MEM, NDI_RA_PASS)
2322 != NDI_SUCCESS) {
2323 DEBUG0("Failed to allocate 32b mem\n");
2324 kmem_free(assigned, length);
2325 return (PCICFG_FAILURE);
2326 }
2327
2328 break;
2329 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2330 request.ra_addr = (uint64_t)
2331 assigned[i].pci_phys_low;
2332
2333 /* allocate I/O space from the allocator */
2334 if (ndi_ra_alloc(ddi_get_parent(dip),
2335 &request, &answer, &alen,
2336 NDI_RA_TYPE_IO, NDI_RA_PASS)
2337 != NDI_SUCCESS) {
2338 DEBUG0("Failed to allocate I/O\n");
2339 kmem_free(assigned, length);
2340 return (PCICFG_FAILURE);
2341 }
2342
2343 break;
2344 default:
2345 DEBUG0("Unknown register type\n");
2346 kmem_free(assigned, length);
2347 return (PCICFG_FAILURE);
2348 } /* switch */
2349 }
2350 }
2351
2352 (void) pcicfg_device_on(handle);
2353 kmem_free(assigned, length);
2354
2355 PCICFG_DUMP_DEVICE_CONFIG(handle);
2356
2357 (void) pcicfg_config_teardown(&handle);
2358 return (PCICFG_SUCCESS);
2359 }
2360
2361 /*
2362 * The "dip" passed to this routine is assumed to be
2363 * the device at the Hotplug Connection (CN). Currently it is
2364 * assumed to be a bridge.
2365 */
2366 static int
pcicfg_allocate_chunk(dev_info_t * dip)2367 pcicfg_allocate_chunk(dev_info_t *dip)
2368 {
2369 pcicfg_phdl_t *phdl;
2370 ndi_ra_request_t *mem_request;
2371 ndi_ra_request_t *io_request;
2372 uint64_t mem_answer;
2373 uint64_t io_answer;
2374 uint64_t alen;
2375
2376 /*
2377 * This should not find an existing entry - so
2378 * it will create a new one.
2379 */
2380 phdl = pcicfg_find_phdl(dip);
2381 ASSERT(phdl);
2382
2383 mem_request = &phdl->mem_req;
2384 io_request = &phdl->io_req;
2385
2386 /*
2387 * From this point in the tree - walk the devices,
2388 * The function passed in will read and "sum" up
2389 * the memory and I/O requirements and put them in
2390 * structure "phdl".
2391 */
2392 ndi_devi_enter(ddi_get_parent(dip));
2393 ddi_walk_devs(dip, pcicfg_sum_resources, (void *)phdl);
2394 ndi_devi_exit(ddi_get_parent(dip));
2395
2396 if (phdl->error != PCICFG_SUCCESS) {
2397 DEBUG0("Failure summing resources\n");
2398 return (phdl->error);
2399 }
2400
2401 /*
2402 * Call into the memory allocator with the request.
2403 * Record the addresses returned in the phdl
2404 */
2405 DEBUG1("Connector requires [0x%x] bytes of memory space\n",
2406 mem_request->ra_len);
2407 DEBUG1("Connector requires [0x%x] bytes of I/O space\n",
2408 io_request->ra_len);
2409
2410 mem_request->ra_align_mask =
2411 PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
2412 io_request->ra_align_mask =
2413 PCICFG_IOGRAN - 1; /* 4K alignment on I/O space */
2414 io_request->ra_boundbase = 0;
2415 io_request->ra_boundlen = PCICFG_4GIG_LIMIT;
2416 io_request->ra_flags |= NDI_RA_ALLOC_BOUNDED;
2417
2418 mem_request->ra_len =
2419 PCICFG_ROUND_UP(mem_request->ra_len, PCICFG_MEMGRAN);
2420
2421 io_request->ra_len =
2422 PCICFG_ROUND_UP(io_request->ra_len, PCICFG_IOGRAN);
2423
2424 if (ndi_ra_alloc(ddi_get_parent(dip),
2425 mem_request, &mem_answer, &alen,
2426 NDI_RA_TYPE_MEM, NDI_RA_PASS) != NDI_SUCCESS) {
2427 DEBUG0("Failed to allocate memory\n");
2428 return (PCICFG_FAILURE);
2429 }
2430
2431 phdl->memory_base = phdl->memory_last = mem_answer;
2432 phdl->memory_len = alen;
2433
2434 phdl->mem_hole.start = phdl->memory_base;
2435 phdl->mem_hole.len = phdl->memory_len;
2436 phdl->mem_hole.next = (hole_t *)NULL;
2437
2438 if (ndi_ra_alloc(ddi_get_parent(dip), io_request, &io_answer,
2439 &alen, NDI_RA_TYPE_IO, NDI_RA_PASS) != NDI_SUCCESS) {
2440
2441 DEBUG0("Failed to allocate I/O space\n");
2442 (void) ndi_ra_free(ddi_get_parent(dip), mem_answer,
2443 alen, NDI_RA_TYPE_MEM, NDI_RA_PASS);
2444 phdl->memory_len = phdl->io_len = 0;
2445 return (PCICFG_FAILURE);
2446 }
2447
2448 phdl->io_base = phdl->io_last = (uint32_t)io_answer;
2449 phdl->io_len = (uint32_t)alen;
2450
2451 phdl->io_hole.start = phdl->io_base;
2452 phdl->io_hole.len = phdl->io_len;
2453 phdl->io_hole.next = (hole_t *)NULL;
2454
2455 DEBUG2("MEMORY BASE = [0x%x] length [0x%x]\n",
2456 phdl->memory_base, phdl->memory_len);
2457 DEBUG2("IO BASE = [0x%x] length [0x%x]\n",
2458 phdl->io_base, phdl->io_len);
2459
2460 return (PCICFG_SUCCESS);
2461 }
2462
2463 #ifdef DEBUG
2464 /*
2465 * This function is useful in debug mode, where we can measure how
2466 * much memory was wasted/unallocated in bridge device's domain.
2467 */
2468 static uint64_t
pcicfg_unused_space(hole_t * hole,uint32_t * hole_count)2469 pcicfg_unused_space(hole_t *hole, uint32_t *hole_count)
2470 {
2471 uint64_t len = 0;
2472 uint32_t count = 0;
2473
2474 do {
2475 len += hole->len;
2476 hole = hole->next;
2477 count++;
2478 } while (hole);
2479 *hole_count = count;
2480 return (len);
2481 }
2482 #endif
2483
2484 /*
2485 * This function frees data structures that hold the hole information
2486 * which are allocated in pcicfg_alloc_hole(). This is not freeing
2487 * any memory allocated through NDI calls.
2488 */
2489 static void
pcicfg_free_hole(hole_t * addr_hole)2490 pcicfg_free_hole(hole_t *addr_hole)
2491 {
2492 hole_t *nhole, *hole = addr_hole->next;
2493
2494 while (hole) {
2495 nhole = hole->next;
2496 kmem_free(hole, sizeof (hole_t));
2497 hole = nhole;
2498 }
2499 }
2500
2501 static uint64_t
pcicfg_alloc_hole(hole_t * addr_hole,uint64_t * alast,uint32_t length)2502 pcicfg_alloc_hole(hole_t *addr_hole, uint64_t *alast, uint32_t length)
2503 {
2504 uint64_t actual_hole_start, ostart, olen;
2505 hole_t *hole = addr_hole, *thole, *nhole;
2506
2507 do {
2508 actual_hole_start = PCICFG_ROUND_UP(hole->start, length);
2509 if (((actual_hole_start - hole->start) + length) <= hole->len) {
2510 DEBUG3("hole found. start %llx, len %llx, req=%x\n",
2511 hole->start, hole->len, length);
2512 ostart = hole->start;
2513 olen = hole->len;
2514 /* current hole parameters adjust */
2515 if ((actual_hole_start - hole->start) == 0) {
2516 hole->start += length;
2517 hole->len -= length;
2518 if (hole->start > *alast)
2519 *alast = hole->start;
2520 } else {
2521 hole->len = actual_hole_start - hole->start;
2522 nhole = (hole_t *)kmem_zalloc(sizeof (hole_t),
2523 KM_SLEEP);
2524 nhole->start = actual_hole_start + length;
2525 nhole->len = (ostart + olen) - nhole->start;
2526 nhole->next = NULL;
2527 thole = hole->next;
2528 hole->next = nhole;
2529 nhole->next = thole;
2530 if (nhole->start > *alast)
2531 *alast = nhole->start;
2532 DEBUG2("put new hole to %llx, %llx\n",
2533 nhole->start, nhole->len);
2534 }
2535 DEBUG2("adjust current hole to %llx, %llx\n",
2536 hole->start, hole->len);
2537 break;
2538 }
2539 actual_hole_start = 0;
2540 hole = hole->next;
2541 } while (hole);
2542
2543 DEBUG1("return hole at %llx\n", actual_hole_start);
2544 return (actual_hole_start);
2545 }
2546
2547 static void
pcicfg_get_mem(pcicfg_phdl_t * entry,uint32_t length,uint64_t * ans)2548 pcicfg_get_mem(pcicfg_phdl_t *entry, uint32_t length, uint64_t *ans)
2549 {
2550 uint64_t new_mem;
2551
2552 /* See if there is a hole, that can hold this request. */
2553 new_mem = pcicfg_alloc_hole(&entry->mem_hole, &entry->memory_last,
2554 length);
2555 if (new_mem) { /* if non-zero, found a hole. */
2556 if (ans != NULL)
2557 *ans = new_mem;
2558 } else
2559 cmn_err(CE_WARN, "No %u bytes memory window for %s\n",
2560 length, ddi_get_name(entry->dip));
2561 }
2562
2563 static void
pcicfg_get_io(pcicfg_phdl_t * entry,uint32_t length,uint32_t * ans)2564 pcicfg_get_io(pcicfg_phdl_t *entry, uint32_t length, uint32_t *ans)
2565 {
2566 uint32_t new_io;
2567 uint64_t io_last;
2568
2569 /*
2570 * See if there is a hole, that can hold this request.
2571 * Pass 64 bit parameters and then truncate to 32 bit.
2572 */
2573 io_last = entry->io_last;
2574 new_io = (uint32_t)pcicfg_alloc_hole(&entry->io_hole, &io_last, length);
2575 if (new_io) { /* if non-zero, found a hole. */
2576 entry->io_last = (uint32_t)io_last;
2577 if (ans != NULL)
2578 *ans = new_io;
2579 } else
2580 cmn_err(CE_WARN, "No %u bytes IO space window for %s\n",
2581 length, ddi_get_name(entry->dip));
2582 }
2583
2584 static int
pcicfg_sum_resources(dev_info_t * dip,void * hdl)2585 pcicfg_sum_resources(dev_info_t *dip, void *hdl)
2586 {
2587 pcicfg_phdl_t *entry = (pcicfg_phdl_t *)hdl;
2588 pci_regspec_t *pci_rp;
2589 int length;
2590 int rcount;
2591 int i;
2592 ndi_ra_request_t *mem_request;
2593 ndi_ra_request_t *io_request;
2594 uint8_t header_type;
2595 ddi_acc_handle_t handle;
2596
2597 entry->error = PCICFG_SUCCESS;
2598
2599 mem_request = &entry->mem_req;
2600 io_request = &entry->io_req;
2601
2602 if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2603 DEBUG0("Failed to map config space!\n");
2604 entry->error = PCICFG_FAILURE;
2605 return (DDI_WALK_TERMINATE);
2606 }
2607
2608 header_type = pci_config_get8(handle, PCI_CONF_HEADER);
2609
2610 /*
2611 * If its a bridge - just record the highest bus seen
2612 */
2613 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
2614
2615 if (entry->highest_bus < pci_config_get8(handle,
2616 PCI_BCNF_SECBUS)) {
2617 entry->highest_bus =
2618 pci_config_get8(handle, PCI_BCNF_SECBUS);
2619 }
2620
2621 (void) pcicfg_config_teardown(&handle);
2622 entry->error = PCICFG_FAILURE;
2623 return (DDI_WALK_CONTINUE);
2624 } else {
2625 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2626 DDI_PROP_DONTPASS, "reg", (caddr_t)&pci_rp,
2627 &length) != DDI_PROP_SUCCESS) {
2628 /*
2629 * If one node in (the subtree of nodes)
2630 * does'nt have a "reg" property fail the
2631 * allocation.
2632 */
2633 entry->memory_len = 0;
2634 entry->io_len = 0;
2635 entry->error = PCICFG_FAILURE;
2636 return (DDI_WALK_TERMINATE);
2637 }
2638 /*
2639 * For each "reg" property with a length, add that to the
2640 * total memory (or I/O) to allocate.
2641 */
2642 rcount = length / sizeof (pci_regspec_t);
2643
2644 for (i = 0; i < rcount; i++) {
2645
2646 switch (PCI_REG_ADDR_G(pci_rp[i].pci_phys_hi)) {
2647
2648 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2649 mem_request->ra_len =
2650 pci_rp[i].pci_size_low +
2651 PCICFG_ROUND_UP(mem_request->ra_len,
2652 pci_rp[i].pci_size_low);
2653 DEBUG1("ADDING 32 --->0x%x\n",
2654 pci_rp[i].pci_size_low);
2655
2656 break;
2657 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2658 mem_request->ra_len =
2659 pci_rp[i].pci_size_low +
2660 PCICFG_ROUND_UP(mem_request->ra_len,
2661 pci_rp[i].pci_size_low);
2662 DEBUG1("ADDING 64 --->0x%x\n",
2663 pci_rp[i].pci_size_low);
2664
2665 break;
2666 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2667 io_request->ra_len =
2668 pci_rp[i].pci_size_low +
2669 PCICFG_ROUND_UP(io_request->ra_len,
2670 pci_rp[i].pci_size_low);
2671 DEBUG1("ADDING I/O --->0x%x\n",
2672 pci_rp[i].pci_size_low);
2673 break;
2674 default:
2675 /* Config space register - not included */
2676 break;
2677 }
2678 }
2679
2680 /*
2681 * free the memory allocated by ddi_getlongprop
2682 */
2683 kmem_free(pci_rp, length);
2684
2685 /*
2686 * continue the walk to the next sibling to sum memory
2687 */
2688
2689 (void) pcicfg_config_teardown(&handle);
2690
2691 return (DDI_WALK_CONTINUE);
2692 }
2693 }
2694
2695 static int
pcicfg_find_resource_end(dev_info_t * dip,void * hdl)2696 pcicfg_find_resource_end(dev_info_t *dip, void *hdl)
2697 {
2698 pcicfg_phdl_t *entry_p = (pcicfg_phdl_t *)hdl;
2699 pci_regspec_t *pci_ap;
2700 pcicfg_range_t *ranges;
2701 int length;
2702 int rcount;
2703 int i;
2704
2705 entry_p->error = PCICFG_SUCCESS;
2706
2707 if (dip == entry_p->dip) {
2708 DEBUG0("Don't include parent bridge node\n");
2709 return (DDI_WALK_CONTINUE);
2710 }
2711
2712 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2713 DDI_PROP_DONTPASS, "ranges",
2714 (caddr_t)&ranges, &length) != DDI_PROP_SUCCESS) {
2715 DEBUG0("Node doesn't have ranges\n");
2716 goto ap;
2717 }
2718
2719 rcount = length / sizeof (pcicfg_range_t);
2720
2721 for (i = 0; i < rcount; i++) {
2722 uint64_t base;
2723 uint64_t mid = ranges[i].child_mid;
2724 uint64_t lo = ranges[i].child_lo;
2725 uint64_t size = ranges[i].size_lo;
2726
2727 switch (PCI_REG_ADDR_G(ranges[i].child_hi)) {
2728
2729 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2730 base = entry_p->memory_base;
2731 entry_p->memory_base = MAX(base, lo + size);
2732 break;
2733 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2734 base = entry_p->memory_base;
2735 entry_p->memory_base = MAX(base,
2736 PCICFG_LADDR(lo, mid) + size);
2737 break;
2738 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2739 base = entry_p->io_base;
2740 entry_p->io_base = MAX(base, lo + size);
2741 break;
2742 }
2743 }
2744
2745 kmem_free(ranges, length);
2746 return (DDI_WALK_CONTINUE);
2747
2748 ap: if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2749 DDI_PROP_DONTPASS, "assigned-addresses",
2750 (caddr_t)&pci_ap, &length) != DDI_PROP_SUCCESS) {
2751 DEBUG0("Node doesn't have assigned-addresses\n");
2752 return (DDI_WALK_CONTINUE);
2753 }
2754
2755 rcount = length / sizeof (pci_regspec_t);
2756
2757 for (i = 0; i < rcount; i++) {
2758
2759 switch (PCI_REG_ADDR_G(pci_ap[i].pci_phys_hi)) {
2760
2761 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
2762 if ((pci_ap[i].pci_phys_low +
2763 pci_ap[i].pci_size_low) >
2764 entry_p->memory_base) {
2765 entry_p->memory_base =
2766 pci_ap[i].pci_phys_low +
2767 pci_ap[i].pci_size_low;
2768 }
2769 break;
2770 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
2771 if ((PCICFG_LADDR(pci_ap[i].pci_phys_low,
2772 pci_ap[i].pci_phys_mid) +
2773 pci_ap[i].pci_size_low) >
2774 entry_p->memory_base) {
2775 entry_p->memory_base = PCICFG_LADDR(
2776 pci_ap[i].pci_phys_low,
2777 pci_ap[i].pci_phys_mid) +
2778 pci_ap[i].pci_size_low;
2779 }
2780 break;
2781 case PCI_REG_ADDR_G(PCI_ADDR_IO):
2782 if ((pci_ap[i].pci_phys_low +
2783 pci_ap[i].pci_size_low) >
2784 entry_p->io_base) {
2785 entry_p->io_base =
2786 pci_ap[i].pci_phys_low +
2787 pci_ap[i].pci_size_low;
2788 }
2789 break;
2790 }
2791 }
2792
2793 /*
2794 * free the memory allocated by ddi_getlongprop
2795 */
2796 kmem_free(pci_ap, length);
2797
2798 /*
2799 * continue the walk to the next sibling to sum memory
2800 */
2801 return (DDI_WALK_CONTINUE);
2802 }
2803
2804 static int
pcicfg_free_bridge_resources(dev_info_t * dip)2805 pcicfg_free_bridge_resources(dev_info_t *dip)
2806 {
2807 pcicfg_range_t *ranges;
2808 uint_t *bus;
2809 int k;
2810 int length;
2811 int i;
2812
2813
2814 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2815 DDI_PROP_DONTPASS, "ranges", (caddr_t)&ranges,
2816 &length) != DDI_PROP_SUCCESS) {
2817 DEBUG0("Failed to read ranges property\n");
2818 if (ddi_get_child(dip)) {
2819 cmn_err(CE_WARN, "No ranges property found for %s",
2820 ddi_get_name(dip));
2821 /*
2822 * strictly speaking, we can check for children with
2823 * assigned-addresses but for now it is better to
2824 * be conservative and assume that if there are child
2825 * nodes, then they do consume PCI memory or IO
2826 * resources, Hence return failure.
2827 */
2828 return (PCICFG_FAILURE);
2829 }
2830 length = 0;
2831
2832 }
2833
2834 for (i = 0; i < length / sizeof (pcicfg_range_t); i++) {
2835 if (ranges[i].size_lo != 0 ||
2836 ranges[i].size_hi != 0) {
2837 switch (ranges[i].parent_hi & PCI_REG_ADDR_M) {
2838 case PCI_ADDR_IO:
2839 DEBUG2("Free I/O "
2840 "base/length = [0x%x]/[0x%x]\n",
2841 ranges[i].child_lo,
2842 ranges[i].size_lo);
2843 if (ndi_ra_free(ddi_get_parent(dip),
2844 (uint64_t)ranges[i].child_lo,
2845 (uint64_t)ranges[i].size_lo,
2846 NDI_RA_TYPE_IO, NDI_RA_PASS)
2847 != NDI_SUCCESS) {
2848 DEBUG0("Trouble freeing "
2849 "PCI i/o space\n");
2850 kmem_free(ranges, length);
2851 return (PCICFG_FAILURE);
2852 }
2853 break;
2854 case PCI_ADDR_MEM32:
2855 case PCI_ADDR_MEM64:
2856 DEBUG3("Free Memory base/length = "
2857 "[0x%x.%x]/[0x%x]\n",
2858 ranges[i].child_mid,
2859 ranges[i].child_lo,
2860 ranges[i].size_lo)
2861 if (ndi_ra_free(ddi_get_parent(dip),
2862 PCICFG_LADDR(ranges[i].child_lo,
2863 ranges[i].child_mid),
2864 (uint64_t)ranges[i].size_lo,
2865 NDI_RA_TYPE_MEM, NDI_RA_PASS)
2866 != NDI_SUCCESS) {
2867 DEBUG0("Trouble freeing "
2868 "PCI memory space\n");
2869 kmem_free(ranges, length);
2870 return (PCICFG_FAILURE);
2871 }
2872 break;
2873 default:
2874 DEBUG0("Unknown memory space\n");
2875 break;
2876 }
2877 }
2878 }
2879
2880 if (length)
2881 kmem_free(ranges, length);
2882
2883 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2884 DDI_PROP_DONTPASS, "bus-range", (caddr_t)&bus,
2885 &k) != DDI_PROP_SUCCESS) {
2886 DEBUG0("Failed to read bus-range property\n");
2887 return (PCICFG_FAILURE);
2888 }
2889
2890 DEBUG2("Need to free bus [%d] range [%d]\n",
2891 bus[0], bus[1] - bus[0] + 1);
2892
2893 if (ndi_ra_free(ddi_get_parent(dip),
2894 (uint64_t)bus[0], (uint64_t)(bus[1] - bus[0] + 1),
2895 NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS) != NDI_SUCCESS) {
2896 /*EMPTY*/
2897 DEBUG0("Failed to free a bus number\n");
2898 }
2899 /*
2900 * Don't forget to free up memory from ddi_getlongprop
2901 */
2902 kmem_free((caddr_t)bus, k);
2903
2904 return (PCICFG_SUCCESS);
2905 }
2906
2907 static int
pcicfg_free_device_resources(dev_info_t * dip,pcicfg_flags_t flags)2908 pcicfg_free_device_resources(dev_info_t *dip, pcicfg_flags_t flags)
2909 {
2910 pci_regspec_t *assigned;
2911
2912 int length;
2913 int acount;
2914 int i;
2915
2916 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
2917 DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
2918 &length) != DDI_PROP_SUCCESS) {
2919 DEBUG0("Failed to read assigned-addresses property\n");
2920 return (PCICFG_FAILURE);
2921 }
2922
2923 /*
2924 * For each "assigned-addresses" property entry with a length,
2925 * call the memory allocation routines to return the
2926 * resource.
2927 */
2928 acount = length / sizeof (pci_regspec_t);
2929 for (i = 0; i < acount; i++) {
2930 /*
2931 * Workaround for Devconf (x86) bug to skip extra entries
2932 * beyond the PCI_CONF_BASE5 offset. But we want to free up
2933 * any memory for expansion roms if allocated.
2934 */
2935 if ((PCI_REG_REG_G(assigned[i].pci_phys_hi) > PCI_CONF_BASE5) &&
2936 (PCI_REG_REG_G(assigned[i].pci_phys_hi) != PCI_CONF_ROM))
2937 break;
2938
2939 if (pcicfg_free_resource(dip, assigned[i], flags)) {
2940 DEBUG1("pcicfg_free_device_resources - Trouble freeing "
2941 "%x\n", assigned[i].pci_phys_hi);
2942 /*
2943 * Don't forget to free up memory from ddi_getlongprop
2944 */
2945 kmem_free((caddr_t)assigned, length);
2946
2947 return (PCICFG_FAILURE);
2948 }
2949 }
2950 kmem_free(assigned, length);
2951 return (PCICFG_SUCCESS);
2952 }
2953
2954 static int
pcicfg_free_resources(dev_info_t * dip,pcicfg_flags_t flags)2955 pcicfg_free_resources(dev_info_t *dip, pcicfg_flags_t flags)
2956 {
2957 ddi_acc_handle_t handle;
2958 uint8_t header_type;
2959
2960 if (pcicfg_config_setup(dip, &handle) != DDI_SUCCESS) {
2961 DEBUG0("Failed to map config space!\n");
2962 return (PCICFG_FAILURE);
2963 }
2964
2965 header_type = pci_config_get8(handle, PCI_CONF_HEADER);
2966
2967 (void) pci_config_teardown(&handle);
2968
2969 /*
2970 * A different algorithm is used for bridges and leaf devices.
2971 */
2972 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
2973 /*
2974 * We only support readonly probing for leaf devices.
2975 */
2976 if (flags & PCICFG_FLAG_READ_ONLY)
2977 return (PCICFG_FAILURE);
2978
2979 if (pcicfg_free_bridge_resources(dip) != PCICFG_SUCCESS) {
2980 DEBUG0("Failed freeing up bridge resources\n");
2981 return (PCICFG_FAILURE);
2982 }
2983 } else {
2984 if (pcicfg_free_device_resources(dip, flags)
2985 != PCICFG_SUCCESS) {
2986 DEBUG0("Failed freeing up device resources\n");
2987 return (PCICFG_FAILURE);
2988 }
2989 }
2990 return (PCICFG_SUCCESS);
2991 }
2992
2993 #ifndef _DONT_USE_1275_GENERIC_NAMES
2994 static char *
pcicfg_get_class_name(uint32_t classcode)2995 pcicfg_get_class_name(uint32_t classcode)
2996 {
2997 struct pcicfg_name_entry *ptr;
2998
2999 for (ptr = &pcicfg_class_lookup[0]; ptr->name != NULL; ptr++) {
3000 if (ptr->class_code == classcode) {
3001 return (ptr->name);
3002 }
3003 }
3004 return (NULL);
3005 }
3006 #endif /* _DONT_USE_1275_GENERIC_NAMES */
3007
3008 static dev_info_t *
pcicfg_devi_find(dev_info_t * dip,uint_t device,uint_t function)3009 pcicfg_devi_find(dev_info_t *dip, uint_t device, uint_t function)
3010 {
3011 struct pcicfg_find_ctrl ctrl;
3012
3013 ctrl.device = device;
3014 ctrl.function = function;
3015 ctrl.dip = NULL;
3016
3017 ndi_devi_enter(dip);
3018 ddi_walk_devs(ddi_get_child(dip), pcicfg_match_dev, (void *)&ctrl);
3019 ndi_devi_exit(dip);
3020
3021 return (ctrl.dip);
3022 }
3023
3024 static int
pcicfg_match_dev(dev_info_t * dip,void * hdl)3025 pcicfg_match_dev(dev_info_t *dip, void *hdl)
3026 {
3027 struct pcicfg_find_ctrl *ctrl = (struct pcicfg_find_ctrl *)hdl;
3028 pci_regspec_t *pci_rp;
3029 int length;
3030 int pci_dev;
3031 int pci_func;
3032
3033 if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip,
3034 DDI_PROP_DONTPASS, "reg", (int **)&pci_rp,
3035 (uint_t *)&length) != DDI_PROP_SUCCESS) {
3036 ctrl->dip = NULL;
3037 return (DDI_WALK_TERMINATE);
3038 }
3039
3040 /* get the PCI device address info */
3041 pci_dev = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
3042 pci_func = PCI_REG_FUNC_G(pci_rp->pci_phys_hi);
3043
3044 /*
3045 * free the memory allocated by ddi_prop_lookup_int_array
3046 */
3047 ddi_prop_free(pci_rp);
3048
3049
3050 if ((pci_dev == ctrl->device) && (pci_func == ctrl->function)) {
3051 /* found the match for the specified device address */
3052 ctrl->dip = dip;
3053 return (DDI_WALK_TERMINATE);
3054 }
3055
3056 /*
3057 * continue the walk to the next sibling to look for a match.
3058 */
3059 return (DDI_WALK_PRUNECHILD);
3060 }
3061
3062 static int
pcicfg_update_assigned_prop(dev_info_t * dip,pci_regspec_t * newone)3063 pcicfg_update_assigned_prop(dev_info_t *dip, pci_regspec_t *newone)
3064 {
3065 int alen;
3066 pci_regspec_t *assigned;
3067 caddr_t newreg;
3068 uint_t status;
3069
3070 DEBUG0("pcicfg_update_assigned_prop()\n");
3071 status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3072 "assigned-addresses", (caddr_t)&assigned, &alen);
3073 switch (status) {
3074 case DDI_PROP_SUCCESS:
3075 break;
3076 case DDI_PROP_NO_MEMORY:
3077 DEBUG0("no memory for assigned-addresses property\n");
3078 return (PCICFG_FAILURE);
3079 default:
3080 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3081 "assigned-addresses", (int *)newone,
3082 sizeof (*newone)/sizeof (int));
3083
3084 (void) pcicfg_dump_assigned(dip);
3085
3086 return (PCICFG_SUCCESS);
3087 }
3088
3089 /*
3090 * Allocate memory for the existing
3091 * assigned-addresses(s) plus one and then
3092 * build it.
3093 */
3094
3095 newreg = kmem_zalloc(alen+sizeof (*newone), KM_SLEEP);
3096
3097 bcopy(assigned, newreg, alen);
3098 bcopy(newone, newreg + alen, sizeof (*newone));
3099
3100 /*
3101 * Write out the new "assigned-addresses" spec
3102 */
3103 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3104 "assigned-addresses", (int *)newreg,
3105 (alen + sizeof (*newone))/sizeof (int));
3106
3107 kmem_free((caddr_t)newreg, alen+sizeof (*newone));
3108
3109 /*
3110 * Don't forget to free up memory from ddi_getlongprop
3111 */
3112 kmem_free((caddr_t)assigned, alen);
3113
3114 (void) pcicfg_dump_assigned(dip);
3115
3116 return (PCICFG_SUCCESS);
3117 }
3118 static int
pcicfg_update_ranges_prop(dev_info_t * dip,pcicfg_range_t * addition)3119 pcicfg_update_ranges_prop(dev_info_t *dip, pcicfg_range_t *addition)
3120 {
3121 int rlen;
3122 pcicfg_range_t *ranges;
3123 caddr_t newreg;
3124 uint_t status;
3125
3126 status = ddi_getlongprop(DDI_DEV_T_ANY,
3127 dip, DDI_PROP_DONTPASS, "ranges", (caddr_t)&ranges, &rlen);
3128
3129
3130 switch (status) {
3131 case DDI_PROP_SUCCESS:
3132 break;
3133 case DDI_PROP_NO_MEMORY:
3134 DEBUG0("ranges present, but unable to get memory\n");
3135 return (PCICFG_FAILURE);
3136 default:
3137 DEBUG0("no ranges property - creating one\n");
3138 if (ndi_prop_update_int_array(DDI_DEV_T_NONE,
3139 dip, "ranges", (int *)addition,
3140 sizeof (pcicfg_range_t)/sizeof (int))
3141 != DDI_SUCCESS) {
3142 DEBUG0("Did'nt create ranges property\n");
3143 return (PCICFG_FAILURE);
3144 }
3145 return (PCICFG_SUCCESS);
3146 }
3147
3148 /*
3149 * Allocate memory for the existing reg(s) plus one and then
3150 * build it.
3151 */
3152 newreg = kmem_zalloc(rlen + sizeof (pcicfg_range_t), KM_SLEEP);
3153
3154 bcopy(ranges, newreg, rlen);
3155 bcopy(addition, newreg + rlen, sizeof (pcicfg_range_t));
3156
3157 /*
3158 * Write out the new "ranges" property
3159 */
3160 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
3161 dip, "ranges", (int *)newreg,
3162 (rlen + sizeof (pcicfg_range_t))/sizeof (int));
3163
3164 kmem_free((caddr_t)newreg, rlen+sizeof (pcicfg_range_t));
3165
3166 kmem_free((caddr_t)ranges, rlen);
3167
3168 return (PCICFG_SUCCESS);
3169 }
3170
3171 static int
pcicfg_update_reg_prop(dev_info_t * dip,uint32_t regvalue,uint_t reg_offset)3172 pcicfg_update_reg_prop(dev_info_t *dip, uint32_t regvalue, uint_t reg_offset)
3173 {
3174 int rlen;
3175 pci_regspec_t *reg;
3176 caddr_t newreg;
3177 uint32_t hiword;
3178 pci_regspec_t addition;
3179 uint32_t size;
3180 uint_t status;
3181
3182 status = ddi_getlongprop(DDI_DEV_T_ANY,
3183 dip, DDI_PROP_DONTPASS, "reg", (caddr_t)®, &rlen);
3184
3185 switch (status) {
3186 case DDI_PROP_SUCCESS:
3187 break;
3188 case DDI_PROP_NO_MEMORY:
3189 DEBUG0("reg present, but unable to get memory\n");
3190 return (PCICFG_FAILURE);
3191 default:
3192 DEBUG0("no reg property\n");
3193 return (PCICFG_FAILURE);
3194 }
3195
3196 /*
3197 * Allocate memory for the existing reg(s) plus one and then
3198 * build it.
3199 */
3200 newreg = kmem_zalloc(rlen+sizeof (pci_regspec_t), KM_SLEEP);
3201
3202 /*
3203 * Build the regspec, then add it to the existing one(s)
3204 */
3205
3206 hiword = PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3207 PCI_REG_DEV_G(reg->pci_phys_hi),
3208 PCI_REG_FUNC_G(reg->pci_phys_hi), reg_offset);
3209
3210 if (reg_offset == PCI_CONF_ROM) {
3211 size = (~(PCI_BASE_ROM_ADDR_M & regvalue))+1;
3212 hiword |= PCI_ADDR_MEM32;
3213 } else {
3214 size = (~(PCI_BASE_M_ADDR_M & regvalue))+1;
3215
3216 if ((PCI_BASE_SPACE_M & regvalue) == PCI_BASE_SPACE_MEM) {
3217 if ((PCI_BASE_TYPE_M & regvalue) == PCI_BASE_TYPE_MEM) {
3218 hiword |= PCI_ADDR_MEM32;
3219 } else if ((PCI_BASE_TYPE_M & regvalue)
3220 == PCI_BASE_TYPE_ALL) {
3221 hiword |= PCI_ADDR_MEM64;
3222 }
3223 } else {
3224 hiword |= PCI_ADDR_IO;
3225 }
3226 }
3227
3228 addition.pci_phys_hi = hiword;
3229 addition.pci_phys_mid = 0;
3230 addition.pci_phys_low = 0;
3231 addition.pci_size_hi = 0;
3232 addition.pci_size_low = size;
3233
3234 bcopy(reg, newreg, rlen);
3235 bcopy(&addition, newreg + rlen, sizeof (pci_regspec_t));
3236
3237 /*
3238 * Write out the new "reg" property
3239 */
3240 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE,
3241 dip, "reg", (int *)newreg,
3242 (rlen + sizeof (pci_regspec_t))/sizeof (int));
3243
3244 kmem_free((caddr_t)newreg, rlen+sizeof (pci_regspec_t));
3245 kmem_free((caddr_t)reg, rlen);
3246
3247 return (PCICFG_SUCCESS);
3248 }
3249 static int
pcicfg_update_available_prop(dev_info_t * dip,pci_regspec_t * newone)3250 pcicfg_update_available_prop(dev_info_t *dip, pci_regspec_t *newone)
3251 {
3252 int alen;
3253 pci_regspec_t *avail_p;
3254 caddr_t new_avail;
3255 uint_t status;
3256
3257 DEBUG2("pcicfg_update_available_prop() - Address %lx Size %x\n",
3258 newone->pci_phys_low, newone->pci_size_low);
3259 status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3260 "available", (caddr_t)&avail_p, &alen);
3261 switch (status) {
3262 case DDI_PROP_SUCCESS:
3263 break;
3264 case DDI_PROP_NO_MEMORY:
3265 DEBUG0("no memory for available property\n");
3266 return (PCICFG_FAILURE);
3267 default:
3268 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3269 "available", (int *)newone,
3270 sizeof (*newone)/sizeof (int));
3271
3272 return (PCICFG_SUCCESS);
3273 }
3274
3275 /*
3276 * Allocate memory for the existing available plus one and then
3277 * build it.
3278 */
3279 new_avail = kmem_zalloc(alen+sizeof (*newone), KM_SLEEP);
3280
3281 bcopy(avail_p, new_avail, alen);
3282 bcopy(newone, new_avail + alen, sizeof (*newone));
3283
3284 /* Write out the new "available" spec */
3285 (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
3286 "available", (int *)new_avail,
3287 (alen + sizeof (*newone))/sizeof (int));
3288
3289 kmem_free((caddr_t)new_avail, alen+sizeof (*newone));
3290
3291 /* Don't forget to free up memory from ddi_getlongprop */
3292 kmem_free((caddr_t)avail_p, alen);
3293
3294 return (PCICFG_SUCCESS);
3295 }
3296
3297 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)3298 pcicfg_update_assigned_prop_value(dev_info_t *dip, uint32_t size,
3299 uint32_t base, uint32_t base_hi, uint_t reg_offset)
3300 {
3301 int rlen;
3302 pci_regspec_t *reg;
3303 uint32_t hiword;
3304 pci_regspec_t addition;
3305 uint_t status;
3306
3307 status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
3308 "reg", (caddr_t)®, &rlen);
3309
3310 switch (status) {
3311 case DDI_PROP_SUCCESS:
3312 break;
3313 case DDI_PROP_NO_MEMORY:
3314 DEBUG0("reg present, but unable to get memory\n");
3315 return (PCICFG_FAILURE);
3316 default:
3317 /*
3318 * Since the config space "reg" entry should have been
3319 * created, we expect a "reg" property already
3320 * present here.
3321 */
3322 DEBUG0("no reg property\n");
3323 return (PCICFG_FAILURE);
3324 }
3325
3326 /*
3327 * Build the regspec, then add it to the existing one(s)
3328 */
3329
3330 hiword = PCICFG_MAKE_REG_HIGH(PCI_REG_BUS_G(reg->pci_phys_hi),
3331 PCI_REG_DEV_G(reg->pci_phys_hi),
3332 PCI_REG_FUNC_G(reg->pci_phys_hi), reg_offset);
3333
3334 hiword |= PCI_REG_REL_M;
3335
3336 if (reg_offset == PCI_CONF_ROM) {
3337 hiword |= PCI_ADDR_MEM32;
3338
3339 base = PCI_BASE_ROM_ADDR_M & base;
3340 } else {
3341 if ((PCI_BASE_SPACE_M & base) == PCI_BASE_SPACE_MEM) {
3342 if ((PCI_BASE_TYPE_M & base) == PCI_BASE_TYPE_MEM) {
3343 hiword |= PCI_ADDR_MEM32;
3344 } else if ((PCI_BASE_TYPE_M & base)
3345 == PCI_BASE_TYPE_ALL) {
3346 hiword |= PCI_ADDR_MEM64;
3347 }
3348
3349 if (base & PCI_BASE_PREF_M)
3350 hiword |= PCI_REG_PF_M;
3351
3352 base = PCI_BASE_M_ADDR_M & base;
3353 } else {
3354 hiword |= PCI_ADDR_IO;
3355
3356 base = PCI_BASE_IO_ADDR_M & base;
3357 base_hi = 0;
3358 }
3359 }
3360
3361 addition.pci_phys_hi = hiword;
3362 addition.pci_phys_mid = base_hi;
3363 addition.pci_phys_low = base;
3364 addition.pci_size_hi = 0;
3365 addition.pci_size_low = size;
3366
3367 DEBUG3("updating BAR@off %x with %x,%x\n", reg_offset, hiword, size);
3368
3369 kmem_free((caddr_t)reg, rlen);
3370
3371 return (pcicfg_update_assigned_prop(dip, &addition));
3372 }
3373
3374 static void
pcicfg_device_on(ddi_acc_handle_t config_handle)3375 pcicfg_device_on(ddi_acc_handle_t config_handle)
3376 {
3377 /*
3378 * Enable memory, IO, and bus mastership
3379 * XXX should we enable parity, SERR#,
3380 * fast back-to-back, and addr. stepping?
3381 */
3382 pci_config_put16(config_handle, PCI_CONF_COMM,
3383 pci_config_get16(config_handle, PCI_CONF_COMM) | 0x7);
3384 }
3385
3386 static void
pcicfg_device_off(ddi_acc_handle_t config_handle)3387 pcicfg_device_off(ddi_acc_handle_t config_handle)
3388 {
3389 /*
3390 * Disable I/O and memory traffic through the bridge
3391 */
3392 pci_config_put16(config_handle, PCI_CONF_COMM, 0x0);
3393 }
3394
3395 /*
3396 * Setup the basic 1275 properties based on information found in the config
3397 * header of the PCI device
3398 */
3399 static int
pcicfg_set_standard_props(dev_info_t * dip,ddi_acc_handle_t config_handle,uint8_t pcie_dev)3400 pcicfg_set_standard_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
3401 uint8_t pcie_dev)
3402 {
3403 int ret;
3404 uint16_t val, cap_ptr;
3405 uint32_t wordval;
3406 uint8_t byteval;
3407
3408 /* These two exists only for non-bridges */
3409 if (((pci_config_get8(config_handle, PCI_CONF_HEADER)
3410 & PCI_HEADER_TYPE_M) == PCI_HEADER_ZERO) && !pcie_dev) {
3411 byteval = pci_config_get8(config_handle, PCI_CONF_MIN_G);
3412 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3413 "min-grant", byteval)) != DDI_SUCCESS) {
3414 return (ret);
3415 }
3416
3417 byteval = pci_config_get8(config_handle, PCI_CONF_MAX_L);
3418 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3419 "max-latency", byteval)) != DDI_SUCCESS) {
3420 return (ret);
3421 }
3422 }
3423
3424 /*
3425 * These should always exist and have the value of the
3426 * corresponding register value
3427 */
3428 val = pci_config_get16(config_handle, PCI_CONF_VENID);
3429
3430 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3431 "vendor-id", val)) != DDI_SUCCESS) {
3432 return (ret);
3433 }
3434 val = pci_config_get16(config_handle, PCI_CONF_DEVID);
3435 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3436 "device-id", val)) != DDI_SUCCESS) {
3437 return (ret);
3438 }
3439 byteval = pci_config_get8(config_handle, PCI_CONF_REVID);
3440 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3441 "revision-id", byteval)) != DDI_SUCCESS) {
3442 return (ret);
3443 }
3444
3445 wordval = (pci_config_get16(config_handle, PCI_CONF_SUBCLASS)<< 8) |
3446 (pci_config_get8(config_handle, PCI_CONF_PROGCLASS));
3447
3448 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3449 "class-code", wordval)) != DDI_SUCCESS) {
3450 return (ret);
3451 }
3452 /* devsel-speed starts at the 9th bit */
3453 val = (pci_config_get16(config_handle,
3454 PCI_CONF_STAT) & PCI_STAT_DEVSELT) >> 9;
3455 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3456 "devsel-speed", val)) != DDI_SUCCESS) {
3457 return (ret);
3458 }
3459
3460 /*
3461 * The next three are bits set in the status register. The property is
3462 * present (but with no value other than its own existence) if the bit
3463 * is set, non-existent otherwise
3464 */
3465 if ((!pcie_dev) &&
3466 (pci_config_get16(config_handle, PCI_CONF_STAT) &
3467 PCI_STAT_FBBC)) {
3468 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3469 "fast-back-to-back", 0)) != DDI_SUCCESS) {
3470 return (ret);
3471 }
3472 }
3473 if ((!pcie_dev) &&
3474 (pci_config_get16(config_handle, PCI_CONF_STAT) &
3475 PCI_STAT_66MHZ)) {
3476 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3477 "66mhz-capable", 0)) != DDI_SUCCESS) {
3478 return (ret);
3479 }
3480 }
3481 if (pci_config_get16(config_handle, PCI_CONF_STAT) & PCI_STAT_UDF) {
3482 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3483 "udf-supported", 0)) != DDI_SUCCESS) {
3484 return (ret);
3485 }
3486 }
3487
3488 /*
3489 * These next three are optional and are not present
3490 * if the corresponding register is zero. If the value
3491 * is non-zero then the property exists with the value
3492 * of the register.
3493 */
3494 if ((val = pci_config_get16(config_handle,
3495 PCI_CONF_SUBVENID)) != 0) {
3496 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3497 "subsystem-vendor-id", val)) != DDI_SUCCESS) {
3498 return (ret);
3499 }
3500 }
3501 if ((val = pci_config_get16(config_handle,
3502 PCI_CONF_SUBSYSID)) != 0) {
3503 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3504 "subsystem-id", val)) != DDI_SUCCESS) {
3505 return (ret);
3506 }
3507 }
3508 if ((val = pci_config_get16(config_handle,
3509 PCI_CONF_CACHE_LINESZ)) != 0) {
3510 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3511 "cache-line-size", val)) != DDI_SUCCESS) {
3512 return (ret);
3513 }
3514 }
3515
3516 /*
3517 * If the Interrupt Pin register is non-zero then the
3518 * interrupts property exists
3519 */
3520 if ((byteval = pci_config_get8(config_handle, PCI_CONF_IPIN)) != 0) {
3521 /*
3522 * If interrupt pin is non-zero,
3523 * record the interrupt line used
3524 */
3525 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3526 "interrupts", byteval)) != DDI_SUCCESS) {
3527 return (ret);
3528 }
3529 }
3530
3531 ret = PCI_CAP_LOCATE(config_handle, PCI_CAP_ID_PCI_E, &cap_ptr);
3532
3533 if (pcie_dev && (ret == DDI_SUCCESS)) {
3534 val = PCI_CAP_GET16(config_handle, 0, cap_ptr,
3535 PCIE_PCIECAP) & PCIE_PCIECAP_SLOT_IMPL;
3536 /* if slot implemented, get physical slot number */
3537 if (val) {
3538 wordval = (PCI_CAP_GET32(config_handle, 0,
3539 cap_ptr, PCIE_SLOTCAP) >>
3540 PCIE_SLOTCAP_PHY_SLOT_NUM_SHIFT) &
3541 PCIE_SLOTCAP_PHY_SLOT_NUM_MASK;
3542 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE,
3543 dip, "physical-slot#", wordval))
3544 != DDI_SUCCESS) {
3545 return (ret);
3546 }
3547 }
3548 }
3549 return (PCICFG_SUCCESS);
3550 }
3551 static int
pcicfg_set_busnode_props(dev_info_t * dip,uint8_t pcie_device_type,int pbus,int sbus)3552 pcicfg_set_busnode_props(dev_info_t *dip, uint8_t pcie_device_type,
3553 int pbus, int sbus)
3554 {
3555 int ret;
3556 char device_type[8];
3557
3558 if (pcie_device_type)
3559 (void) strcpy(device_type, "pciex");
3560 else
3561 (void) strcpy(device_type, "pci");
3562
3563 if ((ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip,
3564 "device_type", device_type)) != DDI_SUCCESS) {
3565 return (ret);
3566 }
3567 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3568 "#address-cells", 3)) != DDI_SUCCESS) {
3569 return (ret);
3570 }
3571 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3572 "#size-cells", 2)) != DDI_SUCCESS) {
3573 return (ret);
3574 }
3575
3576 /*
3577 * Create primary-bus and secondary-bus properties to be used
3578 * to restore bus numbers in the pcicfg_setup_bridge() routine.
3579 */
3580 if (pbus != -1 && sbus != -1) {
3581 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3582 "primary-bus", pbus)) != DDI_SUCCESS) {
3583 return (ret);
3584 }
3585 if ((ret = ndi_prop_update_int(DDI_DEV_T_NONE, dip,
3586 "secondary-bus", sbus)) != DDI_SUCCESS) {
3587 return (ret);
3588 }
3589 }
3590 return (PCICFG_SUCCESS);
3591 }
3592
3593 static int
pcicfg_set_childnode_props(dev_info_t * dip,ddi_acc_handle_t config_handle,uint8_t pcie_dev)3594 pcicfg_set_childnode_props(dev_info_t *dip, ddi_acc_handle_t config_handle,
3595 uint8_t pcie_dev)
3596 {
3597
3598 int ret;
3599 char *name;
3600 char buffer[64], pprefix[8];
3601 uint16_t classcode;
3602 uint8_t revid, pif, pclass, psubclass;
3603 char *compat[24];
3604 int i;
3605 int n;
3606 uint16_t sub_vid, sub_sid, vid, did;
3607
3608 /* set the property prefix based on the device type */
3609 if (pcie_dev)
3610 (void) sprintf(pprefix, "pciex");
3611 else
3612 (void) sprintf(pprefix, "pci");
3613 sub_vid = pci_config_get16(config_handle, PCI_CONF_SUBVENID);
3614 sub_sid = pci_config_get16(config_handle, PCI_CONF_SUBSYSID);
3615 vid = pci_config_get16(config_handle, PCI_CONF_VENID);
3616 did = pci_config_get16(config_handle, PCI_CONF_DEVID);
3617 revid = pci_config_get8(config_handle, PCI_CONF_REVID);
3618 pif = pci_config_get8(config_handle, PCI_CONF_PROGCLASS);
3619 classcode = pci_config_get16(config_handle, PCI_CONF_SUBCLASS);
3620 pclass = pci_config_get8(config_handle, PCI_CONF_BASCLASS);
3621 psubclass = pci_config_get8(config_handle, PCI_CONF_SUBCLASS);
3622
3623 /*
3624 * NOTE: These are for both a child and PCI-PCI bridge node
3625 */
3626
3627 /*
3628 * "name" property rule
3629 * --------------------
3630 *
3631 *
3632 * | \svid |
3633 * | \ |
3634 * | \ |
3635 * | ssid \ | =0 | != 0 |
3636 * |------------|-----------------------|-----------------------|
3637 * | | | |
3638 * | =0 | vid,did | svid,ssid |
3639 * | | | |
3640 * |------------|-----------------------|-----------------------|
3641 * | | | |
3642 * | !=0 | svid,ssid | svid,ssid |
3643 * | | | |
3644 * |------------|-----------------------|-----------------------|
3645 *
3646 * where:
3647 * vid = vendor id
3648 * did = device id
3649 * svid = subsystem vendor id
3650 * ssid = subsystem id
3651 */
3652
3653 if ((sub_sid != 0) || (sub_vid != 0)) {
3654 (void) sprintf(buffer, "%s%x,%x", pprefix, sub_vid, sub_sid);
3655 } else {
3656 (void) sprintf(buffer, "%s%x,%x", pprefix, vid, did);
3657 }
3658
3659 /*
3660 * In some environments, trying to use "generic" 1275 names is
3661 * not the convention. In those cases use the name as created
3662 * above. In all the rest of the cases, check to see if there
3663 * is a generic name first.
3664 */
3665 #ifdef _DONT_USE_1275_GENERIC_NAMES
3666 name = buffer;
3667 #else
3668 if ((name = pcicfg_get_class_name(classcode)) == NULL) {
3669 /*
3670 * Set name to the above fabricated name
3671 */
3672 name = buffer;
3673 }
3674 #endif
3675
3676 /*
3677 * The node name field needs to be filled in with the name
3678 */
3679 if (ndi_devi_set_nodename(dip, name, 0) != NDI_SUCCESS) {
3680 DEBUG0("Failed to set nodename for node\n");
3681 return (PCICFG_FAILURE);
3682 }
3683
3684 /*
3685 * Create the compatible property as an array of pointers
3686 * to strings. Start with the buffer created above.
3687 */
3688 n = 0;
3689 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3690 (void) strcpy(compat[n++], buffer);
3691
3692 /*
3693 * Setup 'compatible' as per the PCI2.1 bindings document.
3694 * pci[ex]VVVV,DDDD.SSSS.ssss.RR
3695 * pci[ex]VVVV,DDDD.SSSS.ssss
3696 * pciSSSS.ssss -> not created for PCIe as per PCIe bindings
3697 * pci[ex]VVVV,DDDD.RR
3698 * pci[ex]VVVV,DDDD
3699 * pci[ex]class,CCSSPP
3700 * pci[ex]class,CCSS
3701 */
3702
3703 /* pci[ex]VVVV,DDDD.SSSS.ssss.RR */
3704 (void) sprintf(buffer, "%s%x,%x.%x.%x.%x", pprefix, vid, did,
3705 sub_vid, sub_sid, revid);
3706 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3707 (void) strcpy(compat[n++], buffer);
3708
3709 /* pci[ex]VVVV,DDDD.SSSS.ssss */
3710 (void) sprintf(buffer, "%s%x,%x.%x.%x", pprefix, vid, did,
3711 sub_vid, sub_sid);
3712 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3713 (void) strcpy(compat[n++], buffer);
3714
3715 /* pciSSSS.ssss -> not created for PCIe as per PCIe bindings */
3716 if (!pcie_dev) {
3717 (void) sprintf(buffer, "pci%x,%x,s", sub_vid, sub_sid);
3718 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3719 (void) strcpy(compat[n++], buffer);
3720
3721 (void) sprintf(buffer, "pci%x,%x", sub_vid, sub_sid);
3722 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3723 (void) strcpy(compat[n++], buffer);
3724 }
3725
3726 /* pci[ex]VVVV,DDDD.RR */
3727 (void) sprintf(buffer, "%s%x,%x.%x", pprefix, vid, did, revid);
3728 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3729 (void) strcpy(compat[n++], buffer);
3730
3731 /* pci[ex]VVVV,DDDD */
3732 (void) sprintf(buffer, "%s%x,%x", pprefix, vid, did);
3733 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3734 (void) strcpy(compat[n++], buffer);
3735
3736 if (!pcie_dev) {
3737 (void) sprintf(buffer, "%s%x,%x,p", pprefix, vid, did);
3738 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3739 (void) strcpy(compat[n++], buffer);
3740 }
3741
3742 /* pci[ex]class,CCSSPP */
3743 (void) sprintf(buffer, "%sclass,%02x%02x%02x", pprefix,
3744 pclass, psubclass, pif);
3745 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3746 (void) strcpy(compat[n++], buffer);
3747
3748 /* pci[ex]class,CCSS */
3749 (void) sprintf(buffer, "%sclass,%04x", pprefix, classcode);
3750 compat[n] = kmem_alloc(strlen(buffer) + 1, KM_SLEEP);
3751 (void) strcpy(compat[n++], buffer);
3752
3753 if ((ret = ndi_prop_update_string_array(DDI_DEV_T_NONE, dip,
3754 "compatible", (char **)compat, n)) != DDI_SUCCESS) {
3755 return (ret);
3756 }
3757
3758 for (i = 0; i < n; i++) {
3759 kmem_free(compat[i], strlen(compat[i]) + 1);
3760 }
3761
3762 DEBUG1("pcicfg_set_childnode_props - creating name=%s\n", name);
3763 if ((ret = ndi_prop_update_string(DDI_DEV_T_NONE, dip,
3764 "name", name)) != DDI_SUCCESS) {
3765
3766 DEBUG0("pcicfg_set_childnode_props - Unable to create name "
3767 "property\n");
3768
3769 return (ret);
3770 }
3771
3772 return (PCICFG_SUCCESS);
3773 }
3774
3775 /*
3776 * Program the bus numbers into the bridge
3777 */
3778
3779 static void
pcicfg_set_bus_numbers(ddi_acc_handle_t config_handle,uint_t primary,uint_t secondary,uint_t subordinate)3780 pcicfg_set_bus_numbers(ddi_acc_handle_t config_handle,
3781 uint_t primary, uint_t secondary, uint_t subordinate)
3782 {
3783 DEBUG3("Setting bridge bus-range %d,%d,%d\n", primary, secondary,
3784 subordinate);
3785 /*
3786 * Primary bus#
3787 */
3788 pci_config_put8(config_handle, PCI_BCNF_PRIBUS, primary);
3789
3790 /*
3791 * Secondary bus#
3792 */
3793 pci_config_put8(config_handle, PCI_BCNF_SECBUS, secondary);
3794
3795 /*
3796 * Subordinate bus#
3797 */
3798 pci_config_put8(config_handle, PCI_BCNF_SUBBUS, subordinate);
3799 }
3800
3801 /*
3802 * Put bridge registers into initial state
3803 */
3804 static void
pcicfg_setup_bridge(pcicfg_phdl_t * entry,ddi_acc_handle_t handle,dev_info_t * dip)3805 pcicfg_setup_bridge(pcicfg_phdl_t *entry,
3806 ddi_acc_handle_t handle, dev_info_t *dip)
3807 {
3808 int pbus, sbus;
3809
3810 /*
3811 * The highest bus seen during probing is the max-subordinate bus
3812 */
3813 pci_config_put8(handle, PCI_BCNF_SUBBUS, entry->highest_bus);
3814
3815
3816 /*
3817 * If there exists more than 1 downstream bridge, it
3818 * will be reset by the below secondary bus reset which
3819 * will clear the bus numbers assumed to be programmed in
3820 * the pcicfg_probe_children() routine. We therefore restore
3821 * them here.
3822 */
3823 if (pci_config_get8(handle, PCI_BCNF_SECBUS) == 0) {
3824 pbus = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
3825 DDI_PROP_DONTPASS, "primary-bus", -1);
3826 sbus = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
3827 DDI_PROP_DONTPASS, "secondary-bus", -1);
3828 if (pbus != -1 && sbus != -1) {
3829 pci_config_put8(handle, PCI_BCNF_PRIBUS, (uint_t)pbus);
3830 pci_config_put8(handle, PCI_BCNF_SECBUS, (uint_t)sbus);
3831 } else {
3832 cmn_err(CE_WARN, "Invalid Bridge number detected: \
3833 %s%d: pbus = 0x%x, sbus = 0x%x",
3834 ddi_get_name(dip), ddi_get_instance(dip), pbus,
3835 sbus);
3836 }
3837 }
3838
3839 /*
3840 * Reset the secondary bus
3841 */
3842 pci_config_put16(handle, PCI_BCNF_BCNTRL,
3843 pci_config_get16(handle, PCI_BCNF_BCNTRL) | 0x40);
3844
3845 drv_usecwait(100);
3846
3847 pci_config_put16(handle, PCI_BCNF_BCNTRL,
3848 pci_config_get16(handle, PCI_BCNF_BCNTRL) & ~0x40);
3849
3850 /*
3851 * Program the memory base register with the
3852 * start of the memory range
3853 */
3854 pci_config_put16(handle, PCI_BCNF_MEM_BASE,
3855 PCICFG_HIWORD(PCICFG_LOADDR(entry->memory_last)));
3856
3857 /*
3858 * Program the I/O base register with the start of the I/O range
3859 */
3860 pci_config_put8(handle, PCI_BCNF_IO_BASE_LOW,
3861 PCICFG_HIBYTE(PCICFG_LOWORD(PCICFG_LOADDR(entry->io_last))));
3862 pci_config_put16(handle, PCI_BCNF_IO_BASE_HI,
3863 PCICFG_HIWORD(PCICFG_LOADDR(entry->io_last)));
3864
3865 /*
3866 * Clear status bits
3867 */
3868 pci_config_put16(handle, PCI_BCNF_SEC_STATUS, 0xffff);
3869
3870 /*
3871 * Turn off prefetchable range
3872 */
3873 pci_config_put32(handle, PCI_BCNF_PF_BASE_LOW, 0x0000ffff);
3874 pci_config_put32(handle, PCI_BCNF_PF_BASE_HIGH, 0xffffffff);
3875 pci_config_put32(handle, PCI_BCNF_PF_LIMIT_HIGH, 0x0);
3876
3877 /*
3878 * Needs to be set to this value
3879 */
3880 pci_config_put8(handle, PCI_CONF_ILINE, 0xf);
3881
3882 /*
3883 * After a Reset, we need to wait 2^25 clock cycles before the
3884 * first Configuration access. The worst case is 33MHz, which
3885 * is a 1 second wait.
3886 */
3887 drv_usecwait(pcicfg_sec_reset_delay);
3888
3889 }
3890
3891 static void
pcicfg_update_bridge(pcicfg_phdl_t * entry,ddi_acc_handle_t handle)3892 pcicfg_update_bridge(pcicfg_phdl_t *entry,
3893 ddi_acc_handle_t handle)
3894 {
3895 uint_t length;
3896
3897 /*
3898 * Program the memory limit register with the end of the memory range
3899 */
3900
3901 DEBUG1("DOWN ROUNDED ===>[0x%x]\n",
3902 PCICFG_ROUND_DOWN(entry->memory_last,
3903 PCICFG_MEMGRAN));
3904
3905 pci_config_put16(handle, PCI_BCNF_MEM_LIMIT,
3906 PCICFG_HIWORD(PCICFG_LOADDR(
3907 PCICFG_ROUND_DOWN(entry->memory_last,
3908 PCICFG_MEMGRAN))));
3909 /*
3910 * Since this is a bridge, the rest of this range will
3911 * be responded to by the bridge. We have to round up
3912 * so no other device claims it.
3913 */
3914 if ((length = (PCICFG_ROUND_UP(entry->memory_last,
3915 PCICFG_MEMGRAN) - entry->memory_last)) > 0) {
3916 (void) pcicfg_get_mem(entry, length, NULL);
3917 DEBUG1("Added [0x%x]at the top of "
3918 "the bridge (mem)\n", length);
3919 }
3920
3921 /*
3922 * Program the I/O limit register with the end of the I/O range
3923 */
3924 pci_config_put8(handle, PCI_BCNF_IO_LIMIT_LOW,
3925 PCICFG_HIBYTE(PCICFG_LOWORD(
3926 PCICFG_LOADDR(PCICFG_ROUND_DOWN(entry->io_last,
3927 PCICFG_IOGRAN)))));
3928
3929 pci_config_put16(handle, PCI_BCNF_IO_LIMIT_HI,
3930 PCICFG_HIWORD(PCICFG_LOADDR(PCICFG_ROUND_DOWN(entry->io_last,
3931 PCICFG_IOGRAN))));
3932
3933 /*
3934 * Same as above for I/O space. Since this is a
3935 * bridge, the rest of this range will be responded
3936 * to by the bridge. We have to round up so no
3937 * other device claims it.
3938 */
3939 if ((length = (PCICFG_ROUND_UP(entry->io_last,
3940 PCICFG_IOGRAN) - entry->io_last)) > 0) {
3941 (void) pcicfg_get_io(entry, length, NULL);
3942 DEBUG1("Added [0x%x]at the top of "
3943 "the bridge (I/O)\n", length);
3944 }
3945 }
3946
3947 /*ARGSUSED*/
3948 static void
pcicfg_disable_bridge_probe_err(dev_info_t * dip,ddi_acc_handle_t h,pcicfg_err_regs_t * regs)3949 pcicfg_disable_bridge_probe_err(dev_info_t *dip, ddi_acc_handle_t h,
3950 pcicfg_err_regs_t *regs)
3951 {
3952 uint16_t val;
3953
3954 /* disable SERR generated in the context of Master Aborts. */
3955 regs->cmd = val = pci_config_get16(h, PCI_CONF_COMM);
3956 val &= ~PCI_COMM_SERR_ENABLE;
3957 pci_config_put16(h, PCI_CONF_COMM, val);
3958 regs->bcntl = val = pci_config_get16(h, PCI_BCNF_BCNTRL);
3959 val &= ~PCI_BCNF_BCNTRL_SERR_ENABLE;
3960 pci_config_put16(h, PCI_BCNF_BCNTRL, val);
3961 /* clear any current pending errors */
3962 pci_config_put16(h, PCI_CONF_STAT, PCI_STAT_S_TARG_AB|
3963 PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB | PCI_STAT_S_SYSERR);
3964 pci_config_put16(h, PCI_BCNF_SEC_STATUS, PCI_STAT_S_TARG_AB|
3965 PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB | PCI_STAT_S_SYSERR);
3966 /* if we are a PCIe device, disable the generation of UR, CE and NFE */
3967 if (regs->pcie_dev) {
3968 uint16_t devctl;
3969 uint16_t cap_ptr;
3970
3971 if ((PCI_CAP_LOCATE(h, PCI_CAP_ID_PCI_E, &cap_ptr)) ==
3972 DDI_FAILURE)
3973 return;
3974
3975 regs->pcie_cap_off = cap_ptr;
3976 regs->devctl = devctl = PCI_CAP_GET16(h, 0, cap_ptr,
3977 PCIE_DEVCTL);
3978 devctl &= ~(PCIE_DEVCTL_UR_REPORTING_EN |
3979 PCIE_DEVCTL_CE_REPORTING_EN |
3980 PCIE_DEVCTL_NFE_REPORTING_EN |
3981 PCIE_DEVCTL_FE_REPORTING_EN);
3982 PCI_CAP_PUT16(h, 0, cap_ptr, PCIE_DEVCTL, devctl);
3983 }
3984 }
3985
3986 /*ARGSUSED*/
3987 static void
pcicfg_enable_bridge_probe_err(dev_info_t * dip,ddi_acc_handle_t h,pcicfg_err_regs_t * regs)3988 pcicfg_enable_bridge_probe_err(dev_info_t *dip, ddi_acc_handle_t h,
3989 pcicfg_err_regs_t *regs)
3990 {
3991 /* clear any pending errors */
3992 pci_config_put16(h, PCI_CONF_STAT, PCI_STAT_S_TARG_AB|
3993 PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB | PCI_STAT_S_SYSERR);
3994 pci_config_put16(h, PCI_BCNF_SEC_STATUS, PCI_STAT_S_TARG_AB|
3995 PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB | PCI_STAT_S_SYSERR);
3996
3997 /* restore original settings */
3998 if (regs->pcie_dev) {
3999 pcie_clear_errors(dip);
4000 pci_config_put16(h, regs->pcie_cap_off + PCIE_DEVCTL,
4001 regs->devctl);
4002 }
4003
4004 pci_config_put16(h, PCI_BCNF_BCNTRL, regs->bcntl);
4005 pci_config_put16(h, PCI_CONF_COMM, regs->cmd);
4006
4007 }
4008
4009 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)4010 pcicfg_probe_children(dev_info_t *parent, uint_t bus, uint_t device,
4011 uint_t func, uint_t *highest_bus, pcicfg_flags_t flags, boolean_t is_pcie)
4012 {
4013 dev_info_t *new_child;
4014 ddi_acc_handle_t config_handle;
4015 uint8_t header_type, pcie_dev = 0;
4016 int ret;
4017 pcicfg_err_regs_t regs;
4018
4019 /*
4020 * This node will be put immediately below
4021 * "parent". Allocate a blank device node. It will either
4022 * be filled in or freed up based on further probing.
4023 */
4024 /*
4025 * Note: in usr/src/uts/common/io/hotplug/pcicfg/pcicfg.c
4026 * ndi_devi_alloc() is called as ndi_devi_alloc_sleep()
4027 */
4028 if (ndi_devi_alloc(parent, DEVI_PSEUDO_NEXNAME,
4029 (pnode_t)DEVI_SID_NODEID, &new_child)
4030 != NDI_SUCCESS) {
4031 DEBUG0("pcicfg_probe_children(): Failed to alloc child node\n");
4032 return (PCICFG_FAILURE);
4033 }
4034
4035 if (pcicfg_add_config_reg(new_child, bus,
4036 device, func) != DDI_SUCCESS) {
4037 DEBUG0("pcicfg_probe_children():"
4038 "Failed to add candidate REG\n");
4039 goto failedconfig;
4040 }
4041
4042 if ((ret = pcicfg_config_setup(new_child, &config_handle))
4043 != PCICFG_SUCCESS) {
4044 if (ret == PCICFG_NODEVICE) {
4045 (void) ndi_devi_free(new_child);
4046 return (ret);
4047 }
4048 DEBUG0("pcicfg_probe_children():"
4049 "Failed to setup config space\n");
4050 goto failedconfig;
4051 }
4052
4053 if (is_pcie)
4054 (void) pcie_init_bus(new_child, PCI_GETBDF(bus, device, func),
4055 PCIE_BUS_INITIAL);
4056
4057 /*
4058 * As soon as we have access to config space,
4059 * turn off device. It will get turned on
4060 * later (after memory is assigned).
4061 */
4062 (void) pcicfg_device_off(config_handle);
4063
4064 /* check if we are PCIe device */
4065 if (pcicfg_pcie_dev(new_child, PCICFG_DEVICE_TYPE_PCIE, ®s)
4066 == DDI_SUCCESS) {
4067 DEBUG0("PCIe device detected\n");
4068 pcie_dev = 1;
4069 }
4070
4071 /*
4072 * Set 1275 properties common to all devices
4073 */
4074 if (pcicfg_set_standard_props(new_child, config_handle,
4075 pcie_dev) != PCICFG_SUCCESS) {
4076 DEBUG0("Failed to set standard properties\n");
4077 goto failedchild;
4078 }
4079
4080 /*
4081 * Child node properties NOTE: Both for PCI-PCI bridge and child node
4082 */
4083 if (pcicfg_set_childnode_props(new_child, config_handle,
4084 pcie_dev) != PCICFG_SUCCESS) {
4085 goto failedchild;
4086 }
4087
4088 header_type = pci_config_get8(config_handle, PCI_CONF_HEADER);
4089
4090 /*
4091 * If this is not a multi-function card only probe function zero.
4092 */
4093 if ((!(header_type & PCI_HEADER_MULTI)) && (func != 0)) {
4094
4095 (void) pcicfg_config_teardown(&config_handle);
4096 (void) ndi_devi_free(new_child);
4097 return (PCICFG_NODEVICE);
4098 }
4099
4100 DEBUG1("---Vendor ID = [0x%x]\n",
4101 pci_config_get16(config_handle, PCI_CONF_VENID));
4102 DEBUG1("---Device ID = [0x%x]\n",
4103 pci_config_get16(config_handle, PCI_CONF_DEVID));
4104
4105 /*
4106 * Attach the child to its parent
4107 */
4108 (void) i_ndi_config_node(new_child, DS_LINKED, 0);
4109
4110 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
4111
4112 DEBUG3("--Bridge found bus [0x%x] device"
4113 "[0x%x] func [0x%x]\n", bus, device, func);
4114
4115 /* Only support read-only probe for leaf device */
4116 if (flags & PCICFG_FLAG_READ_ONLY)
4117 goto failedchild;
4118
4119 if (pcicfg_probe_bridge(new_child, config_handle,
4120 bus, highest_bus, is_pcie) != PCICFG_SUCCESS) {
4121 (void) pcicfg_free_bridge_resources(new_child);
4122 goto failedchild;
4123 }
4124
4125 } else {
4126
4127 DEBUG3("--Leaf device found bus [0x%x] device"
4128 "[0x%x] func [0x%x]\n",
4129 bus, device, func);
4130
4131 if (flags & PCICFG_FLAG_READ_ONLY) {
4132 /*
4133 * with read-only probe, don't do any resource
4134 * allocation, just read the BARs and update props.
4135 */
4136 ret = pcicfg_populate_props_from_bar(new_child,
4137 config_handle);
4138 if (ret != PCICFG_SUCCESS)
4139 goto failedchild;
4140
4141 /*
4142 * for readonly probe "assigned-addresses" property
4143 * has already been setup by reading the BAR, here
4144 * just substract the resource from its parent here.
4145 */
4146 ret = pcicfg_device_assign_readonly(new_child);
4147 if (ret != PCICFG_SUCCESS) {
4148 (void) pcicfg_free_device_resources(new_child,
4149 flags);
4150 goto failedchild;
4151 }
4152 } else {
4153 /*
4154 * update "reg" property by sizing the BARs.
4155 */
4156 ret = pcicfg_populate_reg_props(new_child,
4157 config_handle);
4158 if (ret != PCICFG_SUCCESS)
4159 goto failedchild;
4160
4161 /* now allocate & program the resources */
4162 ret = pcicfg_device_assign(new_child);
4163 if (ret != PCICFG_SUCCESS) {
4164 (void) pcicfg_free_device_resources(new_child,
4165 flags);
4166 goto failedchild;
4167 }
4168 }
4169
4170 (void) ndi_devi_bind_driver(new_child, 0);
4171 }
4172
4173 (void) pcicfg_config_teardown(&config_handle);
4174
4175 /*
4176 * Properties have been setted up, so initilize the rest fields
4177 * in bus_t.
4178 */
4179 if (is_pcie)
4180 (void) pcie_init_bus(new_child, 0, PCIE_BUS_FINAL);
4181
4182 return (PCICFG_SUCCESS);
4183
4184 failedchild:
4185
4186 (void) pcicfg_config_teardown(&config_handle);
4187 if (is_pcie)
4188 pcie_fini_bus(new_child, PCIE_BUS_FINAL);
4189
4190 failedconfig:
4191
4192 (void) ndi_devi_free(new_child);
4193 return (PCICFG_FAILURE);
4194 }
4195
4196 /*
4197 * Sizing the BARs and update "reg" property
4198 */
4199 static int
pcicfg_populate_reg_props(dev_info_t * new_child,ddi_acc_handle_t config_handle)4200 pcicfg_populate_reg_props(dev_info_t *new_child,
4201 ddi_acc_handle_t config_handle)
4202 {
4203 int i;
4204 uint32_t request;
4205
4206 i = PCI_CONF_BASE0;
4207
4208 while (i <= PCI_CONF_BASE5) {
4209
4210 pci_config_put32(config_handle, i, 0xffffffff);
4211
4212 request = pci_config_get32(config_handle, i);
4213 /*
4214 * If its a zero length, don't do
4215 * any programming.
4216 */
4217 if (request != 0) {
4218 /*
4219 * Add to the "reg" property
4220 */
4221 if (pcicfg_update_reg_prop(new_child,
4222 request, i) != PCICFG_SUCCESS) {
4223 goto failedchild;
4224 }
4225 } else {
4226 DEBUG1("BASE register [0x%x] asks for "
4227 "[0x0]=[0x0](32)\n", i);
4228 i += 4;
4229 continue;
4230 }
4231
4232 /*
4233 * Increment by eight if it is 64 bit address space
4234 */
4235 if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
4236 DEBUG3("BASE register [0x%x] asks for "
4237 "[0x%x]=[0x%x] (64)\n",
4238 i, request,
4239 (~(PCI_BASE_M_ADDR_M & request))+1)
4240 i += 8;
4241 } else {
4242 DEBUG3("BASE register [0x%x] asks for "
4243 "[0x%x]=[0x%x](32)\n",
4244 i, request,
4245 (~(PCI_BASE_M_ADDR_M & request))+1)
4246 i += 4;
4247 }
4248 }
4249
4250 /*
4251 * Get the ROM size and create register for it
4252 */
4253 pci_config_put32(config_handle, PCI_CONF_ROM, 0xfffffffe);
4254
4255 request = pci_config_get32(config_handle, PCI_CONF_ROM);
4256 /*
4257 * If its a zero length, don't do
4258 * any programming.
4259 */
4260
4261 if (request != 0) {
4262 DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]\n",
4263 PCI_CONF_ROM, request,
4264 (~(PCI_BASE_ROM_ADDR_M & request))+1);
4265 /*
4266 * Add to the "reg" property
4267 */
4268 if (pcicfg_update_reg_prop(new_child,
4269 request, PCI_CONF_ROM) != PCICFG_SUCCESS) {
4270 goto failedchild;
4271 }
4272 }
4273
4274 return (PCICFG_SUCCESS);
4275
4276 failedchild:
4277 return (PCICFG_FAILURE);
4278 }
4279
4280 static int
pcicfg_fcode_probe(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)4281 pcicfg_fcode_probe(dev_info_t *parent, uint_t bus, uint_t device,
4282 uint_t func, uint_t *highest_bus, pcicfg_flags_t flags, boolean_t is_pcie)
4283 {
4284 dev_info_t *new_child;
4285 int8_t header_type;
4286 int ret;
4287 ddi_acc_handle_t h, ph;
4288 int error = 0;
4289 extern int pcicfg_dont_interpret;
4290 pcicfg_err_regs_t parent_regs, regs;
4291 char *status_prop = NULL;
4292 #ifdef PCICFG_INTERPRET_FCODE
4293 struct pci_ops_bus_args po;
4294 fco_handle_t c;
4295 char unit_address[64];
4296 int fcode_size = 0;
4297 uchar_t *fcode_addr;
4298 uint64_t mem_answer, mem_alen;
4299 pci_regspec_t p;
4300 int32_t request;
4301 ndi_ra_request_t req;
4302 int16_t vendor_id, device_id;
4303 #endif
4304
4305 /*
4306 * check if our parent is of type pciex.
4307 * if so, program config space to disable error msgs during probe.
4308 */
4309 if (pcicfg_pcie_dev(parent, PCICFG_DEVICE_TYPE_PCIE, &parent_regs)
4310 == DDI_SUCCESS) {
4311 DEBUG0("PCI/PCIe parent detected. Disable errors.\n");
4312 /*
4313 * disable parent generating URs or SERR#s during probing
4314 * alone.
4315 */
4316 if (pci_config_setup(parent, &ph) != DDI_SUCCESS)
4317 return (DDI_FAILURE);
4318
4319 if ((flags & PCICFG_FLAG_READ_ONLY) == 0) {
4320 pcicfg_disable_bridge_probe_err(parent,
4321 ph, &parent_regs);
4322 }
4323 }
4324
4325 /*
4326 * This node will be put immediately below
4327 * "parent". Allocate a blank device node. It will either
4328 * be filled in or freed up based on further probing.
4329 */
4330
4331 if (ndi_devi_alloc(parent, DEVI_PSEUDO_NEXNAME,
4332 (pnode_t)DEVI_SID_NODEID, &new_child)
4333 != NDI_SUCCESS) {
4334 DEBUG0("pcicfg_fcode_probe(): Failed to alloc child node\n");
4335 /* return (PCICFG_FAILURE); */
4336 ret = PCICFG_FAILURE;
4337 goto failed2;
4338 }
4339
4340 /*
4341 * Create a dummy reg property. This will be replaced with
4342 * a real reg property when fcode completes or if we need to
4343 * produce one by hand.
4344 */
4345 if (pcicfg_add_config_reg(new_child, bus,
4346 device, func) != DDI_SUCCESS) {
4347 ret = PCICFG_FAILURE;
4348 goto failed3;
4349 }
4350 #ifdef EFCODE21554
4351 if ((ret = pcicfg_config_setup(new_child, &h))
4352 != PCICFG_SUCCESS) {
4353 DEBUG0("pcicfg_fcode_probe():"
4354 "Failed to setup config space\n");
4355 ret = PCICFG_NODEVICE;
4356 goto failed3;
4357 }
4358
4359 #else
4360 p.pci_phys_hi = PCICFG_MAKE_REG_HIGH(bus, device, func, 0);
4361 p.pci_phys_mid = p.pci_phys_low = 0;
4362 p.pci_size_hi = p.pci_size_low = 0;
4363
4364 /*
4365 * Map in configuration space (temporarily)
4366 */
4367 acc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
4368 acc.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
4369 acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
4370
4371 if (pcicfg_map_phys(new_child, &p, &virt, &acc, &h)) {
4372 DEBUG0("pcicfg_fcode_probe():"
4373 "Failed to setup config space\n");
4374 ret = PCICFG_NODEVICE;
4375 goto failed3;
4376 }
4377
4378 /*
4379 * First use ddi_peek16 so that if there is not a device there,
4380 * a bus error will not cause a panic.
4381 */
4382 v = virt + PCI_CONF_VENID;
4383 if (ddi_peek16(new_child, (int16_t *)v, &vendor_id)) {
4384 DEBUG0("Can not read Vendor ID");
4385 pcicfg_unmap_phys(&h, &p);
4386 ret = PCICFG_NODEVICE;
4387 goto failed3;
4388 }
4389 #endif
4390
4391 if (is_pcie)
4392 (void) pcie_init_bus(new_child, PCI_GETBDF(bus, device, func),
4393 PCIE_BUS_INITIAL);
4394
4395 DEBUG0("fcode_probe: conf space mapped.\n");
4396 /*
4397 * As soon as we have access to config space,
4398 * turn off device. It will get turned on
4399 * later (after memory is assigned).
4400 */
4401 (void) pcicfg_device_off(h);
4402
4403 /* check if we are PCIe device */
4404 if (pcicfg_pcie_dev(new_child, PCICFG_DEVICE_TYPE_PCIE, ®s)
4405 == DDI_SUCCESS) {
4406 /*EMPTY*/
4407 DEBUG0("PCI/PCIe device detected\n");
4408 }
4409
4410 /*
4411 * Set 1275 properties common to all devices
4412 */
4413 if (pcicfg_set_standard_props(new_child,
4414 h, regs.pcie_dev) != PCICFG_SUCCESS) {
4415 DEBUG0("Failed to set standard properties\n");
4416 goto failed;
4417 }
4418
4419 /*
4420 * Child node properties NOTE: Both for PCI-PCI bridge and child node
4421 */
4422 if (pcicfg_set_childnode_props(new_child,
4423 h, regs.pcie_dev) != PCICFG_SUCCESS) {
4424 ret = PCICFG_FAILURE;
4425 goto failed;
4426 }
4427
4428 header_type = pci_config_get8(h, PCI_CONF_HEADER);
4429
4430 /*
4431 * If this is not a multi-function card only probe function zero.
4432 */
4433 if (!(header_type & PCI_HEADER_MULTI) && (func > 0)) {
4434
4435 ret = PCICFG_NODEVICE;
4436 goto failed;
4437 }
4438
4439 if ((header_type & PCI_HEADER_TYPE_M) == PCI_HEADER_PPB) {
4440
4441 /*
4442 * XXX - Transparent bridges are handled differently
4443 * than other devices with regards to fcode. Since
4444 * no transparent bridge currently ships with fcode,
4445 * there is no reason to try to extract it from its rom
4446 * or call the fcode interpreter to try to load a drop-in.
4447 * If fcode is developed to handle transparent bridges,
4448 * this code will have to change.
4449 */
4450
4451 DEBUG3("--Bridge found bus [0x%x] device"
4452 "[0x%x] func [0x%x]\n", bus, device, func);
4453
4454 /* Only support read-only probe for leaf device */
4455 if (flags & PCICFG_FLAG_READ_ONLY)
4456 goto failed;
4457
4458 if ((ret = pcicfg_probe_bridge(new_child, h,
4459 bus, highest_bus, is_pcie)) != PCICFG_SUCCESS)
4460 (void) pcicfg_free_bridge_resources(new_child);
4461 goto done;
4462 } else {
4463
4464 DEBUG3("--Leaf device found bus [0x%x] device"
4465 "[0x%x] func [0x%x]\n",
4466 bus, device, func);
4467
4468 /*
4469 * link in tree, but don't bind driver
4470 * We don't have compatible property yet
4471 */
4472 (void) i_ndi_config_node(new_child, DS_LINKED, 0);
4473
4474 /* XXX for now, don't run Fcode in read-only probe. */
4475 if (flags & PCICFG_FLAG_READ_ONLY)
4476 goto no_fcode;
4477
4478 if (pci_config_get8(h, PCI_CONF_IPIN)) {
4479 pci_config_put8(h, PCI_CONF_ILINE, 0xf);
4480 }
4481
4482 #ifdef PCICFG_INTERPRET_FCODE
4483 /*
4484 * Some platforms (x86) don't run fcode, so don't interpret
4485 * fcode that might be in the ROM.
4486 */
4487 if (pcicfg_dont_interpret == 0) {
4488
4489 /* This platform supports fcode */
4490
4491 vendor_id = pci_config_get16(h, PCI_CONF_VENID);
4492 device_id = pci_config_get16(h, PCI_CONF_DEVID);
4493
4494 /*
4495 * Get the ROM size and create register for it
4496 */
4497 pci_config_put32(h, PCI_CONF_ROM, 0xfffffffe);
4498
4499 request = pci_config_get32(h, PCI_CONF_ROM);
4500
4501 /*
4502 * If its a zero length, don't do
4503 * any programming.
4504 */
4505
4506 if (request != 0) {
4507 /*
4508 * Add resource to assigned-addresses.
4509 */
4510 if (pcicfg_fcode_assign_bars(h, new_child,
4511 bus, device, func, request, &p)
4512 != PCICFG_SUCCESS) {
4513 DEBUG0("Failed to assign addresses to "
4514 "implemented BARs");
4515 ret = PCICFG_FAILURE;
4516 goto failed;
4517 }
4518
4519 /* Turn device on */
4520 (void) pcicfg_device_on(h);
4521
4522 /*
4523 * Attempt to load fcode.
4524 */
4525 (void) pcicfg_load_fcode(new_child, bus, device,
4526 func, vendor_id, device_id, &fcode_addr,
4527 &fcode_size, PCICFG_LOADDR(mem_answer),
4528 (~(PCI_BASE_ROM_ADDR_M & request)) + 1);
4529
4530 /* Turn device off */
4531 (void) pcicfg_device_off(h);
4532
4533 /*
4534 * Free the ROM resources.
4535 */
4536 (void) pcicfg_free_resource(new_child, p, 0);
4537
4538 DEBUG2("configure: fcode addr %lx size %x\n",
4539 fcode_addr, fcode_size);
4540
4541 /*
4542 * Create the fcode-rom-offset property. The
4543 * buffer containing the fcode always starts
4544 * with 0xF1, so the fcode offset is zero.
4545 */
4546 if (ndi_prop_update_int(DDI_DEV_T_NONE,
4547 new_child, "fcode-rom-offset", 0)
4548 != DDI_SUCCESS) {
4549 DEBUG0("Failed to create "
4550 "fcode-rom-offset property\n");
4551 ret = PCICFG_FAILURE;
4552 goto failed;
4553 }
4554 } else {
4555 DEBUG0("There is no Expansion ROM\n");
4556 fcode_addr = NULL;
4557 fcode_size = 0;
4558 }
4559
4560 /*
4561 * Fill in the bus specific arguments. For
4562 * PCI, it is the config address.
4563 */
4564 po.config_address =
4565 PCICFG_MAKE_REG_HIGH(bus, device, func, 0);
4566
4567 DEBUG1("config_address=%x\n", po.config_address);
4568
4569 /*
4570 * Build unit address.
4571 */
4572 (void) sprintf(unit_address, "%x,%x", device, func);
4573
4574 DEBUG3("pci_fc_ops_alloc_handle ap=%lx "
4575 "new device=%lx unit address=%s\n",
4576 parent, new_child, unit_address);
4577
4578 c = pci_fc_ops_alloc_handle(parent, new_child,
4579 fcode_addr, fcode_size, unit_address, &po);
4580
4581 DEBUG0("calling fcode_interpreter()\n");
4582
4583 DEBUG3("Before int DIP=%lx binding name %s major %d\n",
4584 new_child, ddi_binding_name(new_child),
4585 ddi_driver_major(new_child));
4586
4587 error = fcode_interpreter(parent, &pci_fc_ops, c);
4588
4589 DEBUG1("returned from fcode_interpreter() - "
4590 "returned %x\n", error);
4591
4592 pci_fc_ops_free_handle(c);
4593
4594 DEBUG1("fcode size = %x\n", fcode_size);
4595 /*
4596 * We don't need the fcode anymore. While allocating
4597 * we had rounded up to a page size.
4598 */
4599 if (fcode_size) {
4600 kmem_free(fcode_addr, ptob(btopr(fcode_size)));
4601 }
4602 } else {
4603 /* This platform does not support fcode */
4604
4605 DEBUG0("NOT calling fcode_interpreter()\n");
4606 }
4607
4608 #endif /* PCICFG_INTERPRET_FCODE */
4609
4610 if ((error == 0) && (pcicfg_dont_interpret == 0)) {
4611 /*
4612 * The interpreter completed successfully.
4613 * We need to redo the resources based on the new reg
4614 * property.
4615 */
4616 DEBUG3("DIP=%lx binding name %s major %d\n", new_child,
4617 ddi_binding_name(new_child),
4618 ddi_driver_major(new_child));
4619
4620 /*
4621 * Readjust resources specified by reg property.
4622 */
4623 if (pcicfg_alloc_new_resources(new_child) ==
4624 PCICFG_FAILURE) {
4625 ret = PCICFG_FAILURE;
4626 goto failed;
4627 }
4628
4629 /*
4630 * At this stage, there should be enough info to pull
4631 * the status property if it exists.
4632 */
4633 if (ddi_prop_lookup_string(DDI_DEV_T_ANY,
4634 new_child, 0, "status", &status_prop) ==
4635 DDI_PROP_SUCCESS) {
4636 if ((strncmp("disabled", status_prop, 8) ==
4637 0) || (strncmp("fail", status_prop, 4) ==
4638 0)) {
4639 ret = PCICFG_FAILURE;
4640 ddi_prop_free(status_prop);
4641 goto failed;
4642 } else {
4643 ddi_prop_free(status_prop);
4644 }
4645 }
4646
4647 ret = PCICFG_SUCCESS;
4648 /* no fcode, bind driver now */
4649 (void) ndi_devi_bind_driver(new_child, 0);
4650
4651 goto done;
4652 } else if ((error != FC_NO_FCODE) &&
4653 (pcicfg_dont_interpret == 0)) {
4654 /*
4655 * The interpreter located fcode, but had an error in
4656 * processing. Cleanup and fail the operation.
4657 */
4658 DEBUG0("Interpreter detected fcode failure\n");
4659 (void) pcicfg_free_resources(new_child, flags);
4660 ret = PCICFG_FAILURE;
4661 goto failed;
4662 } else {
4663 no_fcode:
4664 /*
4665 * Either the interpreter failed with FC_NO_FCODE or we
4666 * chose not to run the interpreter
4667 * (pcicfg_dont_interpret).
4668 *
4669 * If the interpreter failed because there was no
4670 * dropin, then we need to probe the device ourself.
4671 */
4672
4673 /*
4674 * Free any resources that may have been assigned
4675 * during fcode loading/execution since we need
4676 * to start over.
4677 */
4678 (void) pcicfg_free_resources(new_child, flags);
4679
4680 #ifdef EFCODE21554
4681 pcicfg_config_teardown(&h);
4682 #else
4683 pcicfg_unmap_phys(&h, &p);
4684 #endif
4685 /* destroy the bus_t before the dev node is gone */
4686 if (is_pcie)
4687 pcie_fini_bus(new_child, PCIE_BUS_FINAL);
4688
4689 (void) ndi_devi_free(new_child);
4690
4691 DEBUG0("No Drop-in Probe device ourself\n");
4692
4693 ret = pcicfg_probe_children(parent, bus, device, func,
4694 highest_bus, flags, is_pcie);
4695
4696 if (ret != PCICFG_SUCCESS) {
4697 DEBUG0("Could not self probe child\n");
4698 goto failed2;
4699 }
4700
4701 /*
4702 * We successfully self probed the device.
4703 */
4704 if ((new_child = pcicfg_devi_find(
4705 parent, device, func)) == NULL) {
4706 DEBUG0("Did'nt find device node "
4707 "just created\n");
4708 ret = PCICFG_FAILURE;
4709 goto failed2;
4710 }
4711 #ifdef EFCODE21554
4712 /*
4713 * Till now, we have detected a non transparent bridge
4714 * (ntbridge) as a part of the generic probe code and
4715 * configured only one configuration
4716 * header which is the side facing the host bus.
4717 * Now, configure the other side and create children.
4718 *
4719 * To make the process simpler, lets load the device
4720 * driver for the non transparent bridge as this is a
4721 * Solaris bundled driver, and use its configuration map
4722 * services rather than programming it here.
4723 * If the driver is not bundled into Solaris, it must be
4724 * first loaded and configured before performing any
4725 * hotplug operations.
4726 *
4727 * This not only makes the code simpler but also more
4728 * generic.
4729 *
4730 * So here we go.
4731 */
4732 if (pcicfg_is_ntbridge(new_child) != DDI_FAILURE) {
4733
4734 DEBUG0("Found nontransparent bridge.\n");
4735
4736 ret = pcicfg_configure_ntbridge(new_child,
4737 bus, device);
4738 }
4739 if (ret != PCICFG_SUCCESS) {
4740 /*
4741 * Bridge configure failed. Free up the self
4742 * probed entry. The bus resource allocation
4743 * maps need to be cleaned up to prevent
4744 * warnings on retries of the failed configure.
4745 */
4746 (void) pcicfg_ntbridge_unconfigure(new_child);
4747 (void) pcicfg_teardown_device(new_child,
4748 flags, is_pcie);
4749 }
4750 #endif
4751 goto done2;
4752 }
4753 }
4754 done:
4755 failed:
4756 if (is_pcie) {
4757 if (ret == PCICFG_SUCCESS)
4758 (void) pcie_init_bus(new_child, 0, PCIE_BUS_FINAL);
4759 else
4760 pcie_fini_bus(new_child, PCIE_BUS_FINAL);
4761 }
4762
4763 #ifdef EFCODE21554
4764 pcicfg_config_teardown(&h);
4765 #else
4766 pcicfg_unmap_phys(&h, &p);
4767 #endif
4768 failed3:
4769 if (ret != PCICFG_SUCCESS)
4770 (void) ndi_devi_free(new_child);
4771 done2:
4772 failed2:
4773 if (parent_regs.pcie_dev) {
4774 if ((flags & PCICFG_FLAG_READ_ONLY) == 0) {
4775 pcicfg_enable_bridge_probe_err(parent,
4776 ph, &parent_regs);
4777 }
4778 pci_config_teardown(&ph);
4779 }
4780
4781 return (ret);
4782 }
4783
4784 /*
4785 * Read the BARs and update properties. Used in virtual hotplug.
4786 */
4787 static int
pcicfg_populate_props_from_bar(dev_info_t * new_child,ddi_acc_handle_t config_handle)4788 pcicfg_populate_props_from_bar(dev_info_t *new_child,
4789 ddi_acc_handle_t config_handle)
4790 {
4791 uint32_t request, base, base_hi, size;
4792 int i;
4793
4794 i = PCI_CONF_BASE0;
4795
4796 while (i <= PCI_CONF_BASE5) {
4797 /*
4798 * determine the size of the address space
4799 */
4800 base = pci_config_get32(config_handle, i);
4801 pci_config_put32(config_handle, i, 0xffffffff);
4802 request = pci_config_get32(config_handle, i);
4803 pci_config_put32(config_handle, i, base);
4804
4805 /*
4806 * If its a zero length, don't do any programming.
4807 */
4808 if (request != 0) {
4809 /*
4810 * Add to the "reg" property
4811 */
4812 if (pcicfg_update_reg_prop(new_child,
4813 request, i) != PCICFG_SUCCESS) {
4814 goto failedchild;
4815 }
4816
4817 if ((PCI_BASE_SPACE_IO & request) == 0 &&
4818 (PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
4819 base_hi = pci_config_get32(config_handle, i+4);
4820 } else {
4821 base_hi = 0;
4822 }
4823 /*
4824 * Add to "assigned-addresses" property
4825 */
4826 size = (~(PCI_BASE_M_ADDR_M & request))+1;
4827 if (pcicfg_update_assigned_prop_value(new_child,
4828 size, base, base_hi, i) != PCICFG_SUCCESS) {
4829 goto failedchild;
4830 }
4831 } else {
4832 DEBUG1("BASE register [0x%x] asks for "
4833 "[0x0]=[0x0](32)\n", i);
4834 i += 4;
4835 continue;
4836 }
4837
4838 /*
4839 * Increment by eight if it is 64 bit address space
4840 */
4841 if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
4842 DEBUG3("BASE register [0x%x] asks for "
4843 "[0x%x]=[0x%x] (64)\n",
4844 i, request,
4845 (~(PCI_BASE_M_ADDR_M & request))+1)
4846 i += 8;
4847 } else {
4848 DEBUG3("BASE register [0x%x] asks for "
4849 "[0x%x]=[0x%x](32)\n",
4850 i, request,
4851 (~(PCI_BASE_M_ADDR_M & request))+1)
4852 i += 4;
4853 }
4854 }
4855
4856 /*
4857 * Get the ROM size and create register for it
4858 */
4859 base = pci_config_get32(config_handle, PCI_CONF_ROM);
4860 pci_config_put32(config_handle, PCI_CONF_ROM, 0xfffffffe);
4861 request = pci_config_get32(config_handle, PCI_CONF_ROM);
4862 pci_config_put32(config_handle, PCI_CONF_ROM, base);
4863
4864 /*
4865 * If its a zero length, don't do
4866 * any programming.
4867 */
4868 if (request != 0) {
4869 DEBUG3("BASE register [0x%x] asks for [0x%x]=[0x%x]\n",
4870 PCI_CONF_ROM, request,
4871 (~(PCI_BASE_ROM_ADDR_M & request))+1);
4872 /*
4873 * Add to the "reg" property
4874 */
4875 if (pcicfg_update_reg_prop(new_child,
4876 request, PCI_CONF_ROM) != PCICFG_SUCCESS) {
4877 goto failedchild;
4878 }
4879 /*
4880 * Add to "assigned-addresses" property
4881 */
4882 size = (~(PCI_BASE_ROM_ADDR_M & request))+1;
4883 if (pcicfg_update_assigned_prop_value(new_child, size,
4884 base, 0, PCI_CONF_ROM) != PCICFG_SUCCESS) {
4885 goto failedchild;
4886 }
4887 }
4888
4889 return (PCICFG_SUCCESS);
4890
4891 failedchild:
4892 return (PCICFG_FAILURE);
4893 }
4894
4895 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)4896 pcicfg_probe_bridge(dev_info_t *new_child, ddi_acc_handle_t h, uint_t bus,
4897 uint_t *highest_bus, boolean_t is_pcie)
4898 {
4899 uint64_t next_bus;
4900 uint_t new_bus, num_slots;
4901 ndi_ra_request_t req;
4902 int rval, i, j;
4903 uint64_t mem_answer, mem_base, mem_alen, mem_size, mem_end;
4904 uint64_t io_answer, io_base, io_alen, io_size, io_end;
4905 uint64_t round_answer, round_len;
4906 pcicfg_range_t range[PCICFG_RANGE_LEN];
4907 int bus_range[2];
4908 pcicfg_phdl_t phdl;
4909 uint64_t pcibus_base, pcibus_alen;
4910 uint64_t max_bus;
4911 uint8_t pcie_device_type = 0;
4912 dev_info_t *new_device;
4913 int trans_device;
4914 int ari_mode = B_FALSE;
4915 int max_function = PCICFG_MAX_FUNCTION;
4916
4917 /*
4918 * Set "device_type" to "pci", the actual type will be set later
4919 * by pcicfg_set_busnode_props() below. This is needed as the
4920 * pcicfg_ra_free() below would update "available" property based
4921 * on "device_type".
4922 *
4923 * This code can be removed later after PCI configurator is changed
4924 * to use PCIRM, which automatically update properties upon allocation
4925 * and free, at that time we'll be able to remove the code inside
4926 * ndi_ra_alloc/free() which currently updates "available" property
4927 * for pci/pcie devices in pcie fabric.
4928 */
4929 if (ndi_prop_update_string(DDI_DEV_T_NONE, new_child,
4930 "device_type", "pci") != DDI_SUCCESS) {
4931 DEBUG0("Failed to set \"device_type\" props\n");
4932 return (PCICFG_FAILURE);
4933 }
4934
4935 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4936 req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
4937 req.ra_boundbase = 0;
4938 req.ra_boundlen = PCICFG_MAX_BUS_DEPTH;
4939 req.ra_len = PCICFG_MAX_BUS_DEPTH;
4940 req.ra_align_mask = 0; /* no alignment needed */
4941
4942 rval = ndi_ra_alloc(ddi_get_parent(new_child), &req,
4943 &pcibus_base, &pcibus_alen, NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
4944
4945 if (rval != NDI_SUCCESS) {
4946 if (rval == NDI_RA_PARTIAL_REQ) {
4947 /*EMPTY*/
4948 DEBUG0("NDI_RA_PARTIAL_REQ returned for bus range\n");
4949 } else {
4950 DEBUG0(
4951 "Failed to allocate bus range for bridge\n");
4952 return (PCICFG_FAILURE);
4953 }
4954 }
4955
4956 DEBUG2("Bus Range Allocated [base=%d] [len=%d]\n",
4957 pcibus_base, pcibus_alen);
4958
4959 if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_PCI_BUSNUM)
4960 == NDI_FAILURE) {
4961 DEBUG0("Can not setup resource map - NDI_RA_TYPE_PCI_BUSNUM\n");
4962 return (PCICFG_FAILURE);
4963 }
4964
4965 /*
4966 * Put available bus range into the pool.
4967 * Take the first one for this bridge to use and don't give
4968 * to child.
4969 */
4970 (void) ndi_ra_free(new_child, pcibus_base+1, pcibus_alen-1,
4971 NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
4972
4973 next_bus = pcibus_base;
4974 max_bus = pcibus_base + pcibus_alen - 1;
4975
4976 new_bus = next_bus;
4977
4978 DEBUG1("NEW bus found ->[%d]\n", new_bus);
4979
4980 /* Keep track of highest bus for subordinate bus programming */
4981 *highest_bus = new_bus;
4982
4983 /*
4984 * Allocate Memory Space for Bridge
4985 */
4986 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
4987 req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
4988 req.ra_boundbase = 0;
4989 /*
4990 * Note: To support a 32b system, boundlen and len need to be
4991 * 32b quantities
4992 */
4993 req.ra_boundlen = PCICFG_4GIG_LIMIT + 1;
4994 req.ra_len = PCICFG_4GIG_LIMIT + 1; /* Get as big as possible */
4995 req.ra_align_mask =
4996 PCICFG_MEMGRAN - 1; /* 1M alignment on memory space */
4997
4998 rval = ndi_ra_alloc(ddi_get_parent(new_child), &req,
4999 &mem_answer, &mem_alen, NDI_RA_TYPE_MEM, NDI_RA_PASS);
5000
5001 if (rval != NDI_SUCCESS) {
5002 if (rval == NDI_RA_PARTIAL_REQ) {
5003 /*EMPTY*/
5004 DEBUG0("NDI_RA_PARTIAL_REQ returned\n");
5005 } else {
5006 DEBUG0(
5007 "Failed to allocate memory for bridge\n");
5008 return (PCICFG_FAILURE);
5009 }
5010 }
5011
5012 DEBUG3("Bridge Memory Allocated [0x%x.%x] len [0x%x]\n",
5013 PCICFG_HIADDR(mem_answer),
5014 PCICFG_LOADDR(mem_answer),
5015 mem_alen);
5016
5017 if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
5018 DEBUG0("Can not setup resource map - NDI_RA_TYPE_MEM\n");
5019 return (PCICFG_FAILURE);
5020 }
5021
5022 /*
5023 * Put available memory into the pool.
5024 */
5025 (void) ndi_ra_free(new_child, mem_answer, mem_alen, NDI_RA_TYPE_MEM,
5026 NDI_RA_PASS);
5027
5028 mem_base = mem_answer;
5029
5030 /*
5031 * Allocate I/O Space for Bridge
5032 */
5033 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
5034 req.ra_align_mask = PCICFG_IOGRAN - 1; /* 4k alignment */
5035 req.ra_boundbase = 0;
5036 req.ra_boundlen = PCICFG_4GIG_LIMIT;
5037 req.ra_flags = (NDI_RA_ALLOC_BOUNDED | NDI_RA_ALLOC_PARTIAL_OK);
5038 req.ra_len = PCICFG_4GIG_LIMIT; /* Get as big as possible */
5039
5040 rval = ndi_ra_alloc(ddi_get_parent(new_child), &req, &io_answer,
5041 &io_alen, NDI_RA_TYPE_IO, NDI_RA_PASS);
5042
5043 if (rval != NDI_SUCCESS) {
5044 if (rval == NDI_RA_PARTIAL_REQ) {
5045 /*EMPTY*/
5046 DEBUG0("NDI_RA_PARTIAL_REQ returned\n");
5047 } else {
5048 DEBUG0("Failed to allocate io space for bridge\n");
5049 io_base = io_answer = io_alen = 0;
5050 /* return (PCICFG_FAILURE); */
5051 }
5052 }
5053
5054 if (io_alen) {
5055 DEBUG3("Bridge IO Space Allocated [0x%x.%x] len [0x%x]\n",
5056 PCICFG_HIADDR(io_answer), PCICFG_LOADDR(io_answer),
5057 io_alen);
5058
5059 if (ndi_ra_map_setup(new_child, NDI_RA_TYPE_IO) ==
5060 NDI_FAILURE) {
5061 DEBUG0("Can not setup resource map - NDI_RA_TYPE_IO\n");
5062 return (PCICFG_FAILURE);
5063 }
5064
5065 /*
5066 * Put available I/O into the pool.
5067 */
5068 (void) ndi_ra_free(new_child, io_answer, io_alen,
5069 NDI_RA_TYPE_IO, NDI_RA_PASS);
5070 io_base = io_answer;
5071 }
5072
5073 pcicfg_set_bus_numbers(h, bus, new_bus, max_bus);
5074
5075 /*
5076 * Setup "bus-range" property before onlining the bridge.
5077 */
5078 bus_range[0] = new_bus;
5079 bus_range[1] = max_bus;
5080
5081 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, new_child,
5082 "bus-range", bus_range, 2) != DDI_SUCCESS) {
5083 DEBUG0("Failed to set bus-range property");
5084 return (PCICFG_FAILURE);
5085 }
5086
5087 /*
5088 * Reset the secondary bus
5089 */
5090 pci_config_put16(h, PCI_BCNF_BCNTRL,
5091 pci_config_get16(h, PCI_BCNF_BCNTRL) | 0x40);
5092
5093 drv_usecwait(100);
5094
5095 pci_config_put16(h, PCI_BCNF_BCNTRL,
5096 pci_config_get16(h, PCI_BCNF_BCNTRL) & ~0x40);
5097
5098 /*
5099 * Program the memory base register with the
5100 * start of the memory range
5101 */
5102 pci_config_put16(h, PCI_BCNF_MEM_BASE,
5103 PCICFG_HIWORD(PCICFG_LOADDR(mem_answer)));
5104
5105 /*
5106 * Program the memory limit register with the
5107 * end of the memory range.
5108 */
5109
5110 pci_config_put16(h, PCI_BCNF_MEM_LIMIT,
5111 PCICFG_HIWORD(PCICFG_LOADDR(
5112 PCICFG_ROUND_DOWN((mem_answer + mem_alen), PCICFG_MEMGRAN) - 1)));
5113
5114 /*
5115 * Allocate the chunk of memory (if any) not programmed into the
5116 * bridge because of the round down.
5117 */
5118 if (PCICFG_ROUND_DOWN((mem_answer + mem_alen), PCICFG_MEMGRAN)
5119 != (mem_answer + mem_alen)) {
5120 DEBUG0("Need to allocate Memory round off chunk\n");
5121 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
5122 req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
5123 req.ra_addr = PCICFG_ROUND_DOWN((mem_answer + mem_alen),
5124 PCICFG_MEMGRAN);
5125 req.ra_len = (mem_answer + mem_alen) -
5126 (PCICFG_ROUND_DOWN((mem_answer + mem_alen),
5127 PCICFG_MEMGRAN));
5128
5129 (void) ndi_ra_alloc(new_child, &req,
5130 &round_answer, &round_len, NDI_RA_TYPE_MEM, NDI_RA_PASS);
5131 }
5132
5133 /*
5134 * Program the I/O Space Base
5135 */
5136 pci_config_put8(h, PCI_BCNF_IO_BASE_LOW,
5137 PCICFG_HIBYTE(PCICFG_LOWORD(
5138 PCICFG_LOADDR(io_answer))));
5139
5140 pci_config_put16(h, PCI_BCNF_IO_BASE_HI,
5141 PCICFG_HIWORD(PCICFG_LOADDR(io_answer)));
5142
5143 /*
5144 * Program the I/O Space Limit
5145 */
5146 pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW,
5147 PCICFG_HIBYTE(PCICFG_LOWORD(
5148 PCICFG_LOADDR(PCICFG_ROUND_DOWN(io_answer + io_alen,
5149 PCICFG_IOGRAN)))) - 1);
5150
5151 pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI,
5152 PCICFG_HIWORD(PCICFG_LOADDR(
5153 PCICFG_ROUND_DOWN(io_answer + io_alen, PCICFG_IOGRAN)))
5154 - 1);
5155
5156 /*
5157 * Allocate the chunk of I/O (if any) not programmed into the
5158 * bridge because of the round down.
5159 */
5160 if (PCICFG_ROUND_DOWN((io_answer + io_alen), PCICFG_IOGRAN)
5161 != (io_answer + io_alen)) {
5162 DEBUG0("Need to allocate I/O round off chunk\n");
5163 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
5164 req.ra_flags = NDI_RA_ALLOC_SPECIFIED;
5165 req.ra_addr = PCICFG_ROUND_DOWN((io_answer + io_alen),
5166 PCICFG_IOGRAN);
5167 req.ra_len = (io_answer + io_alen) -
5168 (PCICFG_ROUND_DOWN((io_answer + io_alen),
5169 PCICFG_IOGRAN));
5170
5171 (void) ndi_ra_alloc(new_child, &req,
5172 &round_answer, &round_len, NDI_RA_TYPE_IO, NDI_RA_PASS);
5173 }
5174
5175 /*
5176 * Setup "ranges" property before onlining the bridge.
5177 */
5178 bzero((caddr_t)range, sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
5179
5180 range[0].child_hi = range[0].parent_hi |= (PCI_REG_REL_M | PCI_ADDR_IO);
5181 range[0].child_lo = range[0].parent_lo = io_base;
5182 range[1].child_hi = range[1].parent_hi |=
5183 (PCI_REG_REL_M | PCI_ADDR_MEM32);
5184 range[1].child_lo = range[1].parent_lo = mem_base;
5185
5186 range[0].size_lo = io_alen;
5187 if (pcicfg_update_ranges_prop(new_child, &range[0])) {
5188 DEBUG0("Failed to update ranges (io)\n");
5189 return (PCICFG_FAILURE);
5190 }
5191 range[1].size_lo = mem_alen;
5192 if (pcicfg_update_ranges_prop(new_child, &range[1])) {
5193 DEBUG0("Failed to update ranges (memory)\n");
5194 return (PCICFG_FAILURE);
5195 }
5196
5197 /*
5198 * Clear status bits
5199 */
5200 pci_config_put16(h, PCI_BCNF_SEC_STATUS, 0xffff);
5201
5202 /*
5203 * Turn off prefetchable range
5204 */
5205 pci_config_put32(h, PCI_BCNF_PF_BASE_LOW, 0x0000ffff);
5206 pci_config_put32(h, PCI_BCNF_PF_BASE_HIGH, 0xffffffff);
5207 pci_config_put32(h, PCI_BCNF_PF_LIMIT_HIGH, 0x0);
5208
5209 /*
5210 * Needs to be set to this value
5211 */
5212 pci_config_put8(h, PCI_CONF_ILINE, 0xf);
5213
5214 /* check our device_type as defined by Open Firmware */
5215 if (pcicfg_pcie_device_type(new_child, h) == DDI_SUCCESS)
5216 pcie_device_type = 1;
5217
5218 /*
5219 * Set bus properties
5220 */
5221 if (pcicfg_set_busnode_props(new_child, pcie_device_type,
5222 (int)bus, (int)new_bus) != PCICFG_SUCCESS) {
5223 DEBUG0("Failed to set busnode props\n");
5224 return (PCICFG_FAILURE);
5225 }
5226
5227 (void) pcicfg_device_on(h);
5228
5229 if (is_pcie)
5230 (void) pcie_init_bus(new_child, 0, PCIE_BUS_FINAL);
5231 if (ndi_devi_online(new_child, NDI_NO_EVENT|NDI_CONFIG)
5232 != NDI_SUCCESS) {
5233 DEBUG0("Unable to online bridge\n");
5234 return (PCICFG_FAILURE);
5235 }
5236
5237 DEBUG0("Bridge is ONLINE\n");
5238
5239 /*
5240 * After a Reset, we need to wait 2^25 clock cycles before the
5241 * first Configuration access. The worst case is 33MHz, which
5242 * is a 1 second wait.
5243 */
5244 drv_usecwait(pcicfg_sec_reset_delay);
5245
5246 /*
5247 * Probe all children devices
5248 */
5249 DEBUG0("Bridge Programming Complete - probe children\n");
5250 ndi_devi_enter(new_child);
5251 for (i = 0; ((i < PCICFG_MAX_DEVICE) && (ari_mode == B_FALSE));
5252 i++) {
5253 for (j = 0; j < max_function; ) {
5254 if (ari_mode)
5255 trans_device = j >> 3;
5256 else
5257 trans_device = i;
5258
5259 if ((rval = pcicfg_fcode_probe(new_child,
5260 new_bus, trans_device, (j & 7), highest_bus,
5261 0, is_pcie))
5262 != PCICFG_SUCCESS) {
5263 if (rval == PCICFG_NODEVICE) {
5264 DEBUG3("No Device at bus [0x%x]"
5265 "device [0x%x] "
5266 "func [0x%x]\n", new_bus,
5267 trans_device, j & 7);
5268
5269 if (j)
5270 goto next;
5271 } else {
5272 DEBUG3("Failed to configure bus "
5273 "[0x%x] device [0x%x] "
5274 "func [0x%x]\n", new_bus,
5275 trans_device, j & 7);
5276
5277 rval = PCICFG_FAILURE;
5278 }
5279 break;
5280 }
5281 next:
5282 new_device = pcicfg_devi_find(new_child,
5283 trans_device, (j & 7));
5284
5285 /*
5286 * Determine if ARI Forwarding should be enabled.
5287 */
5288 if (j == 0) {
5289 if (new_device == NULL)
5290 break;
5291
5292 if ((pcie_ari_supported(new_child) ==
5293 PCIE_ARI_FORW_ENABLED) &&
5294 (pcie_ari_device(new_device) ==
5295 PCIE_ARI_DEVICE)) {
5296 if (pcie_ari_enable(new_child) ==
5297 DDI_SUCCESS) {
5298 (void) ddi_prop_create(
5299 DDI_DEV_T_NONE,
5300 new_child,
5301 DDI_PROP_CANSLEEP,
5302 "ari-enabled", NULL, 0);
5303 ari_mode = B_TRUE;
5304 max_function =
5305 PCICFG_MAX_ARI_FUNCTION;
5306 }
5307 }
5308 }
5309
5310 if (ari_mode == B_TRUE) {
5311 int next_function;
5312
5313 if (new_device == NULL)
5314 break;
5315
5316 if (pcie_ari_get_next_function(new_device,
5317 &next_function) != DDI_SUCCESS)
5318 break;
5319
5320 j = next_function;
5321
5322 if (next_function == 0)
5323 break;
5324 } else
5325 j++;
5326 }
5327 }
5328
5329 ndi_devi_exit(new_child);
5330
5331 /* if empty topology underneath, it is still a success. */
5332 if (rval != PCICFG_FAILURE)
5333 rval = PCICFG_SUCCESS;
5334
5335 /*
5336 * Offline the bridge to allow reprogramming of resources.
5337 *
5338 * This should always succeed since nobody else has started to
5339 * use it yet, failing to detach the driver would indicate a bug.
5340 * Also in that case it's better just panic than allowing the
5341 * configurator to proceed with BAR reprogramming without bridge
5342 * driver detached.
5343 */
5344 VERIFY(ndi_devi_offline(new_child, NDI_NO_EVENT|NDI_UNCONFIG)
5345 == NDI_SUCCESS);
5346 if (is_pcie)
5347 pcie_fini_bus(new_child, PCIE_BUS_INITIAL);
5348
5349 phdl.dip = new_child;
5350 phdl.memory_base = mem_answer;
5351 phdl.io_base = (uint32_t)io_answer;
5352 phdl.error = PCICFG_SUCCESS; /* in case of empty child tree */
5353
5354 ndi_devi_enter(ddi_get_parent(new_child));
5355 ddi_walk_devs(new_child, pcicfg_find_resource_end, (void *)&phdl);
5356 ndi_devi_exit(ddi_get_parent(new_child));
5357
5358 if (phdl.error != PCICFG_SUCCESS) {
5359 DEBUG0("Failure summing resources\n");
5360 return (PCICFG_FAILURE);
5361 }
5362
5363 num_slots = pcicfg_get_nslots(new_child, h);
5364 mem_end = PCICFG_ROUND_UP(phdl.memory_base, PCICFG_MEMGRAN);
5365 io_end = PCICFG_ROUND_UP(phdl.io_base, PCICFG_IOGRAN);
5366
5367 DEBUG3("Start of Unallocated Bridge(%d slots) Resources "
5368 "Mem=0x%lx I/O=0x%lx\n", num_slots, mem_end, io_end);
5369
5370 /*
5371 * Before probing the children we've allocated maximum MEM/IO
5372 * resources from parent, and updated "available" property
5373 * accordingly. Later we'll be giving up unused resources to
5374 * the parent, thus we need to destroy "available" property
5375 * here otherwise it will be out-of-sync with the actual free
5376 * resources this bridge has. This property will be rebuilt below
5377 * with the actual free resources reserved for hotplug slots
5378 * (if any).
5379 */
5380 (void) ndi_prop_remove(DDI_DEV_T_NONE, new_child, "available");
5381 /*
5382 * if the bridge a slots, then preallocate. If not, assume static
5383 * configuration. Also check for preallocation limits and spit
5384 * warning messages appropriately (perhaps some can be in debug mode).
5385 */
5386 if (num_slots) {
5387 pci_regspec_t reg;
5388 uint64_t mem_assigned = mem_end;
5389 uint64_t io_assigned = io_end;
5390 uint64_t mem_reqd = mem_answer + (num_slots *
5391 pcicfg_slot_memsize);
5392 uint64_t io_reqd = io_answer + (num_slots *
5393 pcicfg_slot_iosize);
5394 uint8_t highest_bus_reqd = new_bus + (num_slots *
5395 pcicfg_slot_busnums);
5396 #ifdef DEBUG
5397 if (mem_end > mem_reqd)
5398 DEBUG3("Memory space consumed by bridge"
5399 " more than planned for %d slot(s)(%lx, %lx)",
5400 num_slots, mem_answer, mem_end);
5401 if (io_end > io_reqd)
5402 DEBUG3("IO space consumed by bridge"
5403 " more than planned for %d slot(s)(%lx, %lx)",
5404 num_slots, io_answer, io_end);
5405 if (*highest_bus > highest_bus_reqd)
5406 DEBUG3("Buses consumed by bridge"
5407 " more than planned for %d slot(s)(%x, %x)",
5408 num_slots, new_bus, *highest_bus);
5409
5410 if (mem_reqd > (mem_answer + mem_alen))
5411 DEBUG3("Memory space required by bridge"
5412 " more than available for %d slot(s)(%lx, %lx)",
5413 num_slots, mem_answer, mem_end);
5414
5415 if (io_reqd > (io_answer + io_alen))
5416 DEBUG3("IO space required by bridge"
5417 " more than available for %d slot(s)(%lx, %lx)",
5418 num_slots, io_answer, io_end);
5419 if (highest_bus_reqd > max_bus)
5420 DEBUG3("Bus numbers required by bridge"
5421 " more than available for %d slot(s)(%x, %x)",
5422 num_slots, new_bus, *highest_bus);
5423 #endif
5424 mem_end = MAX((MIN(mem_reqd, (mem_answer + mem_alen))),
5425 mem_end);
5426 io_end = MAX((MIN(io_reqd, (io_answer + io_alen))), io_end);
5427 *highest_bus = MAX((MIN(highest_bus_reqd, max_bus)),
5428 *highest_bus);
5429 DEBUG3("mem_end %lx, io_end %lx, highest_bus %x\n",
5430 mem_end, io_end, *highest_bus);
5431
5432 mem_size = mem_end - mem_assigned;
5433 io_size = io_end - io_assigned;
5434
5435 reg.pci_phys_mid = reg.pci_size_hi = 0;
5436 if (io_size > 0) {
5437 reg.pci_phys_hi = (PCI_REG_REL_M | PCI_ADDR_IO);
5438 reg.pci_phys_low = io_assigned;
5439 reg.pci_size_low = io_size;
5440 if (pcicfg_update_available_prop(new_child, ®)) {
5441 DEBUG0("Failed to update available prop "
5442 "(io)\n");
5443 return (PCICFG_FAILURE);
5444 }
5445 }
5446 if (mem_size > 0) {
5447 reg.pci_phys_hi = (PCI_REG_REL_M | PCI_ADDR_MEM32);
5448 reg.pci_phys_low = mem_assigned;
5449 reg.pci_size_low = mem_size;
5450 if (pcicfg_update_available_prop(new_child, ®)) {
5451 DEBUG0("Failed to update available prop "
5452 "(memory)\n");
5453 return (PCICFG_FAILURE);
5454 }
5455 }
5456 }
5457
5458 /*
5459 * Give back unused memory space to parent.
5460 */
5461 (void) ndi_ra_free(ddi_get_parent(new_child),
5462 mem_end, (mem_answer + mem_alen) - mem_end, NDI_RA_TYPE_MEM,
5463 NDI_RA_PASS);
5464
5465 if (mem_end == mem_answer) {
5466 DEBUG0("No memory resources used\n");
5467 /*
5468 * To prevent the bridge from forwarding any Memory
5469 * transactions, the Memory Limit will be programmed
5470 * with a smaller value than the Memory Base.
5471 */
5472 pci_config_put16(h, PCI_BCNF_MEM_BASE, 0xffff);
5473 pci_config_put16(h, PCI_BCNF_MEM_LIMIT, 0);
5474
5475 mem_size = 0;
5476 } else {
5477 /*
5478 * Reprogram the end of the memory.
5479 */
5480 pci_config_put16(h, PCI_BCNF_MEM_LIMIT,
5481 PCICFG_HIWORD(mem_end) - 1);
5482 mem_size = mem_end - mem_base;
5483 }
5484
5485 /*
5486 * Give back unused io space to parent.
5487 */
5488 (void) ndi_ra_free(ddi_get_parent(new_child),
5489 io_end, (io_answer + io_alen) - io_end,
5490 NDI_RA_TYPE_IO, NDI_RA_PASS);
5491
5492 if (io_end == io_answer) {
5493 DEBUG0("No IO Space resources used\n");
5494
5495 /*
5496 * To prevent the bridge from forwarding any I/O
5497 * transactions, the I/O Limit will be programmed
5498 * with a smaller value than the I/O Base.
5499 */
5500 pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW, 0);
5501 pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI, 0);
5502 pci_config_put8(h, PCI_BCNF_IO_BASE_LOW, 0xff);
5503 pci_config_put16(h, PCI_BCNF_IO_BASE_HI, 0);
5504
5505 io_size = 0;
5506 } else {
5507 /*
5508 * Reprogram the end of the io space.
5509 */
5510 pci_config_put8(h, PCI_BCNF_IO_LIMIT_LOW,
5511 PCICFG_HIBYTE(PCICFG_LOWORD(
5512 PCICFG_LOADDR(io_end) - 1)));
5513
5514 pci_config_put16(h, PCI_BCNF_IO_LIMIT_HI,
5515 PCICFG_HIWORD(PCICFG_LOADDR(io_end - 1)));
5516
5517 io_size = io_end - io_base;
5518 }
5519
5520 if ((max_bus - *highest_bus) > 0) {
5521 /*
5522 * Give back unused bus numbers
5523 */
5524 (void) ndi_ra_free(ddi_get_parent(new_child),
5525 *highest_bus+1, max_bus - *highest_bus,
5526 NDI_RA_TYPE_PCI_BUSNUM, NDI_RA_PASS);
5527 }
5528
5529 /*
5530 * Set bus numbers to ranges encountered during scan
5531 */
5532 pcicfg_set_bus_numbers(h, bus, new_bus, *highest_bus);
5533
5534 bus_range[0] = pci_config_get8(h, PCI_BCNF_SECBUS);
5535 bus_range[1] = pci_config_get8(h, PCI_BCNF_SUBBUS);
5536 DEBUG1("End of bridge probe: bus_range[0] = %d\n", bus_range[0]);
5537 DEBUG1("End of bridge probe: bus_range[1] = %d\n", bus_range[1]);
5538
5539 if (ndi_prop_update_int_array(DDI_DEV_T_NONE, new_child,
5540 "bus-range", bus_range, 2) != DDI_SUCCESS) {
5541 DEBUG0("Failed to set bus-range property");
5542 return (PCICFG_FAILURE);
5543 }
5544
5545 /*
5546 * Remove the ranges property if it exists since we will create
5547 * a new one.
5548 */
5549 (void) ndi_prop_remove(DDI_DEV_T_NONE, new_child, "ranges");
5550
5551 DEBUG2("Creating Ranges property - Mem Address %lx Mem Size %x\n",
5552 mem_base, mem_size);
5553 DEBUG2(" - I/O Address %lx I/O Size %x\n",
5554 io_base, io_size);
5555
5556 bzero((caddr_t)range, sizeof (pcicfg_range_t) * PCICFG_RANGE_LEN);
5557
5558 range[0].child_hi = range[0].parent_hi |= (PCI_REG_REL_M | PCI_ADDR_IO);
5559 range[0].child_lo = range[0].parent_lo = io_base;
5560 range[1].child_hi = range[1].parent_hi |=
5561 (PCI_REG_REL_M | PCI_ADDR_MEM32);
5562 range[1].child_lo = range[1].parent_lo = mem_base;
5563
5564 if (io_size > 0) {
5565 range[0].size_lo = io_size;
5566 if (pcicfg_update_ranges_prop(new_child, &range[0])) {
5567 DEBUG0("Failed to update ranges (io)\n");
5568 return (PCICFG_FAILURE);
5569 }
5570 }
5571 if (mem_size > 0) {
5572 range[1].size_lo = mem_size;
5573 if (pcicfg_update_ranges_prop(new_child, &range[1])) {
5574 DEBUG0("Failed to update ranges (memory)\n");
5575 return (PCICFG_FAILURE);
5576 }
5577 }
5578
5579 /*
5580 * Remove the resource maps for the bridge since we no longer
5581 * need them. Note that the failure is ignored since the
5582 * ndi_devi_offline above may have already taken care of it via
5583 * driver detach.
5584 * It has been checked that there are no other reasons for
5585 * failure other than map itself being non-existent. So we are Ok.
5586 */
5587 if (ndi_ra_map_destroy(new_child, NDI_RA_TYPE_MEM) == NDI_FAILURE) {
5588 /*EMPTY*/
5589 DEBUG0("Can not destroy resource map - NDI_RA_TYPE_MEM\n");
5590 }
5591
5592 if (ndi_ra_map_destroy(new_child, NDI_RA_TYPE_IO) == NDI_FAILURE) {
5593 /*EMPTY*/
5594 DEBUG0("Can not destroy resource map - NDI_RA_TYPE_IO\n");
5595 }
5596
5597 if (ndi_ra_map_destroy(new_child, NDI_RA_TYPE_PCI_BUSNUM)
5598 == NDI_FAILURE) {
5599 /*EMPTY*/
5600 DEBUG0("Can't destroy resource map - NDI_RA_TYPE_PCI_BUSNUM\n");
5601 }
5602
5603 return (rval);
5604 }
5605
5606 /*
5607 * Return PCICFG_SUCCESS if device exists at the specified address.
5608 * Return PCICFG_NODEVICE is no device exists at the specified address.
5609 *
5610 */
5611 int
pcicfg_config_setup(dev_info_t * dip,ddi_acc_handle_t * handle)5612 pcicfg_config_setup(dev_info_t *dip, ddi_acc_handle_t *handle)
5613 {
5614 caddr_t virt;
5615 ddi_device_acc_attr_t attr;
5616 int status;
5617 int rlen;
5618 pci_regspec_t *reg;
5619 int ret = DDI_SUCCESS;
5620 int16_t tmp;
5621 /*
5622 * flags = PCICFG_CONF_INDIRECT_MAP if configuration space is indirectly
5623 * mapped, otherwise it is 0. "flags" is introduced in support of any
5624 * non transparent bridges, where configuration space is indirectly
5625 * mapped.
5626 * Indirect mapping is always true on sun4v systems.
5627 */
5628 int flags = 0;
5629
5630
5631 /*
5632 * Get the pci register spec from the node
5633 */
5634 status = ddi_getlongprop(DDI_DEV_T_ANY,
5635 dip, DDI_PROP_DONTPASS, "reg", (caddr_t)®, &rlen);
5636
5637 switch (status) {
5638 case DDI_PROP_SUCCESS:
5639 break;
5640 case DDI_PROP_NO_MEMORY:
5641 DEBUG0("reg present, but unable to get memory\n");
5642 return (PCICFG_FAILURE);
5643 default:
5644 DEBUG0("no reg property\n");
5645 return (PCICFG_FAILURE);
5646 }
5647
5648 if (pcicfg_indirect_map(dip) == DDI_SUCCESS)
5649 flags |= PCICFG_CONF_INDIRECT_MAP;
5650
5651 /*
5652 * Map in configuration space (temporarily)
5653 */
5654 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0;
5655 attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
5656 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
5657 attr.devacc_attr_access = DDI_CAUTIOUS_ACC;
5658
5659 #ifdef EFCODE21554
5660 if (ddi_regs_map_setup(dip, 0, &virt,
5661 0, 0, &attr, handle) != DDI_SUCCESS)
5662 #else
5663 if (pcicfg_map_phys(dip, reg, &virt, &attr, handle)
5664 != DDI_SUCCESS)
5665 #endif
5666 {
5667 DEBUG0("pcicfg_config_setup():"
5668 "Failed to setup config space\n");
5669
5670 kmem_free((caddr_t)reg, rlen);
5671 return (PCICFG_FAILURE);
5672 }
5673
5674 if (flags & PCICFG_CONF_INDIRECT_MAP) {
5675 /*
5676 * need to use DDI interfaces as the conf space is
5677 * cannot be directly accessed by the host.
5678 */
5679 tmp = (int16_t)ddi_get16(*handle, (uint16_t *)virt);
5680 } else {
5681 ret = ddi_peek16(dip, (int16_t *)virt, &tmp);
5682 }
5683
5684 if (ret == DDI_SUCCESS) {
5685 if (tmp == -1) {
5686 DEBUG1("NO DEVICEFOUND, read %x\n", tmp);
5687 ret = PCICFG_NODEVICE;
5688 } else {
5689 /* XXX - Need to check why HV is returning 0 */
5690 if (tmp == 0) {
5691 DEBUG0("Device Not Ready yet ?");
5692 ret = PCICFG_NODEVICE;
5693 } else {
5694 DEBUG1("DEVICEFOUND, read %x\n", tmp);
5695 ret = PCICFG_SUCCESS;
5696 }
5697 }
5698 } else {
5699 DEBUG0("ddi_peek failed, must be NODEVICE\n");
5700 ret = PCICFG_NODEVICE;
5701 }
5702
5703 /*
5704 * A bug in XMITS 3.0 causes us to miss the Master Abort Split
5705 * Completion message. The result is the error message being
5706 * sent back as part of the config data. If the first two words
5707 * of the config space happen to be the same as the Master Abort
5708 * message, then report back that there is no device there.
5709 */
5710 if ((ret == PCICFG_SUCCESS) && !(flags & PCICFG_CONF_INDIRECT_MAP)) {
5711 int32_t pcix_scm;
5712
5713 #define PCICFG_PCIX_SCM 0x10000004
5714
5715 pcix_scm = 0;
5716 (void) ddi_peek32(dip, (int32_t *)virt, &pcix_scm);
5717 if (pcix_scm == PCICFG_PCIX_SCM) {
5718 pcix_scm = 0;
5719 (void) ddi_peek32(dip,
5720 (int32_t *)(virt + 4), &pcix_scm);
5721 if (pcix_scm == PCICFG_PCIX_SCM)
5722 ret = PCICFG_NODEVICE;
5723 }
5724 }
5725
5726 if (ret == PCICFG_NODEVICE)
5727 #ifdef EFCODE21554
5728 ddi_regs_map_free(handle);
5729 #else
5730 pcicfg_unmap_phys(handle, reg);
5731 #endif
5732
5733 kmem_free((caddr_t)reg, rlen);
5734
5735 return (ret);
5736
5737 }
5738
5739 static void
pcicfg_config_teardown(ddi_acc_handle_t * handle)5740 pcicfg_config_teardown(ddi_acc_handle_t *handle)
5741 {
5742 (void) ddi_regs_map_free(handle);
5743 }
5744
5745 static int
pcicfg_add_config_reg(dev_info_t * dip,uint_t bus,uint_t device,uint_t func)5746 pcicfg_add_config_reg(dev_info_t *dip,
5747 uint_t bus, uint_t device, uint_t func)
5748 {
5749 int reg[10] = { PCI_ADDR_CONFIG, 0, 0, 0, 0};
5750
5751 reg[0] = PCICFG_MAKE_REG_HIGH(bus, device, func, 0);
5752
5753 return (ndi_prop_update_int_array(DDI_DEV_T_NONE, dip,
5754 "reg", reg, 5));
5755 }
5756
5757 static int
pcicfg_dump_assigned(dev_info_t * dip)5758 pcicfg_dump_assigned(dev_info_t *dip)
5759 {
5760 pci_regspec_t *reg;
5761 int length;
5762 int rcount;
5763 int i;
5764
5765 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
5766 DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)®,
5767 &length) != DDI_PROP_SUCCESS) {
5768 DEBUG0("Failed to read assigned-addresses property\n");
5769 return (PCICFG_FAILURE);
5770 }
5771
5772 rcount = length / sizeof (pci_regspec_t);
5773 for (i = 0; i < rcount; i++) {
5774 DEBUG4("pcicfg_dump_assigned - size=%x low=%x mid=%x high=%x\n",
5775 reg[i].pci_size_low, reg[i].pci_phys_low,
5776 reg[i].pci_phys_mid, reg[i].pci_phys_hi);
5777 }
5778 /*
5779 * Don't forget to free up memory from ddi_getlongprop
5780 */
5781 kmem_free((caddr_t)reg, length);
5782
5783 return (PCICFG_SUCCESS);
5784 }
5785
5786 #ifdef PCICFG_INTERPRET_FCODE
5787 static int
pcicfg_load_fcode(dev_info_t * dip,uint_t bus,uint_t device,uint_t func,uint16_t vendor_id,uint16_t device_id,uchar_t ** fcode_addr,int * fcode_size,int rom_paddr,int rom_size)5788 pcicfg_load_fcode(dev_info_t *dip, uint_t bus, uint_t device, uint_t func,
5789 uint16_t vendor_id, uint16_t device_id, uchar_t **fcode_addr,
5790 int *fcode_size, int rom_paddr, int rom_size)
5791 {
5792 pci_regspec_t p;
5793 int pci_data;
5794 int start_of_fcode;
5795 int image_length;
5796 int code_type;
5797 ddi_acc_handle_t h;
5798 ddi_device_acc_attr_t acc;
5799 uint8_t *addr;
5800 int8_t image_not_found, indicator;
5801 uint16_t vendor_id_img, device_id_img;
5802 int16_t rom_sig;
5803 #ifdef DEBUG
5804 int i;
5805 #endif
5806
5807 DEBUG4("pcicfg_load_fcode() - "
5808 "bus %x device =%x func=%x rom_paddr=%lx\n",
5809 bus, device, func, rom_paddr);
5810 DEBUG2("pcicfg_load_fcode() - vendor_id=%x device_id=%x\n",
5811 vendor_id, device_id);
5812
5813 *fcode_size = 0;
5814 *fcode_addr = NULL;
5815
5816 acc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
5817 acc.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
5818 acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
5819
5820 p.pci_phys_hi = PCI_ADDR_MEM32 | PCICFG_MAKE_REG_HIGH(bus, device,
5821 func, PCI_CONF_ROM);
5822
5823 p.pci_phys_mid = 0;
5824 p.pci_phys_low = 0;
5825
5826 p.pci_size_low = rom_size;
5827 p.pci_size_hi = 0;
5828
5829 if (pcicfg_map_phys(dip, &p, (caddr_t *)&addr, &acc, &h)) {
5830 DEBUG1("Can Not map in ROM %x\n", p.pci_phys_low);
5831 return (PCICFG_FAILURE);
5832 }
5833
5834 /*
5835 * Walk the ROM to find the proper image for this device.
5836 */
5837 image_not_found = 1;
5838 while (image_not_found) {
5839 DEBUG1("Expansion ROM maps to %lx\n", addr);
5840
5841 #ifdef DEBUG
5842 if (pcicfg_dump_fcode) {
5843 for (i = 0; i < 100; i++)
5844 DEBUG2("ROM 0x%x --> 0x%x\n", i,
5845 ddi_get8(h, (uint8_t *)(addr + i)));
5846 }
5847 #endif
5848
5849 /*
5850 * Some device say they have an Expansion ROM, but do not, so
5851 * for non-21554 devices use peek so we don't panic due to
5852 * accessing non existent memory.
5853 */
5854 if (pcicfg_indirect_map(dip) == DDI_SUCCESS) {
5855 rom_sig = ddi_get16(h,
5856 (uint16_t *)(addr + PCI_ROM_SIGNATURE));
5857 } else {
5858 if (ddi_peek16(dip,
5859 (int16_t *)(addr + PCI_ROM_SIGNATURE), &rom_sig)) {
5860 cmn_err(CE_WARN,
5861 "PCI Expansion ROM is not accessible");
5862 pcicfg_unmap_phys(&h, &p);
5863 return (PCICFG_FAILURE);
5864 }
5865 }
5866
5867 /*
5868 * Validate the ROM Signature.
5869 */
5870 if ((uint16_t)rom_sig != 0xaa55) {
5871 DEBUG1("Invalid ROM Signature %x\n", (uint16_t)rom_sig);
5872 pcicfg_unmap_phys(&h, &p);
5873 return (PCICFG_FAILURE);
5874 }
5875
5876 DEBUG0("Valid ROM Signature Found\n");
5877
5878 start_of_fcode = ddi_get16(h, (uint16_t *)(addr + 2));
5879
5880 pci_data = ddi_get16(h,
5881 (uint16_t *)(addr + PCI_ROM_PCI_DATA_STRUCT_PTR));
5882
5883 DEBUG2("Pointer To PCI Data Structure %x %x\n", pci_data,
5884 addr);
5885
5886 /*
5887 * Validate the PCI Data Structure Signature.
5888 * 0x52494350 = "PCIR"
5889 */
5890
5891 if (ddi_get8(h, (uint8_t *)(addr + pci_data)) != 0x50) {
5892 DEBUG0("Invalid PCI Data Structure Signature\n");
5893 pcicfg_unmap_phys(&h, &p);
5894 return (PCICFG_FAILURE);
5895 }
5896
5897 if (ddi_get8(h, (uint8_t *)(addr + pci_data + 1)) != 0x43) {
5898 DEBUG0("Invalid PCI Data Structure Signature\n");
5899 pcicfg_unmap_phys(&h, &p);
5900 return (PCICFG_FAILURE);
5901 }
5902 if (ddi_get8(h, (uint8_t *)(addr + pci_data + 2)) != 0x49) {
5903 DEBUG0("Invalid PCI Data Structure Signature\n");
5904 pcicfg_unmap_phys(&h, &p);
5905 return (PCICFG_FAILURE);
5906 }
5907 if (ddi_get8(h, (uint8_t *)(addr + pci_data + 3)) != 0x52) {
5908 DEBUG0("Invalid PCI Data Structure Signature\n");
5909 pcicfg_unmap_phys(&h, &p);
5910 return (PCICFG_FAILURE);
5911 }
5912
5913 /*
5914 * Is this image for this device?
5915 */
5916 vendor_id_img = ddi_get16(h,
5917 (uint16_t *)(addr + pci_data + PCI_PDS_VENDOR_ID));
5918 device_id_img = ddi_get16(h,
5919 (uint16_t *)(addr + pci_data + PCI_PDS_DEVICE_ID));
5920
5921 DEBUG2("This image is for vendor_id=%x device_id=%x\n",
5922 vendor_id_img, device_id_img);
5923
5924 code_type = ddi_get8(h, addr + pci_data + PCI_PDS_CODE_TYPE);
5925
5926 switch (code_type) {
5927 case PCI_PDS_CODE_TYPE_PCAT:
5928 DEBUG0("ROM is of x86/PC-AT Type\n");
5929 break;
5930 case PCI_PDS_CODE_TYPE_OPEN_FW:
5931 DEBUG0("ROM is of Open Firmware Type\n");
5932 break;
5933 default:
5934 DEBUG1("ROM is of Unknown Type 0x%x\n", code_type);
5935 break;
5936 }
5937
5938 if ((vendor_id_img != vendor_id) ||
5939 (device_id_img != device_id) ||
5940 (code_type != PCI_PDS_CODE_TYPE_OPEN_FW)) {
5941 DEBUG0("Firmware Image is not for this device..."
5942 "goto next image\n");
5943 /*
5944 * Read indicator byte to see if there is another
5945 * image in the ROM
5946 */
5947 indicator = ddi_get8(h,
5948 (uint8_t *)(addr + pci_data + PCI_PDS_INDICATOR));
5949
5950 if (indicator != 1) {
5951 /*
5952 * There is another image in the ROM.
5953 */
5954 image_length = ddi_get16(h, (uint16_t *)(addr +
5955 pci_data + PCI_PDS_IMAGE_LENGTH)) * 512;
5956
5957 addr += image_length;
5958 } else {
5959 /*
5960 * There are no more images.
5961 */
5962 DEBUG0("There are no more images in the ROM\n");
5963 pcicfg_unmap_phys(&h, &p);
5964
5965 return (PCICFG_FAILURE);
5966 }
5967 } else {
5968 DEBUG0("Correct image was found\n");
5969 image_not_found = 0; /* Image was found */
5970 }
5971 }
5972
5973 *fcode_size = (ddi_get8(h, addr + start_of_fcode + 4) << 24) |
5974 (ddi_get8(h, addr + start_of_fcode + 5) << 16) |
5975 (ddi_get8(h, addr + start_of_fcode + 6) << 8) |
5976 (ddi_get8(h, addr + start_of_fcode + 7));
5977
5978 DEBUG1("Fcode Size %x\n", *fcode_size);
5979
5980 /*
5981 * Allocate page aligned buffer space
5982 */
5983 *fcode_addr = kmem_zalloc(ptob(btopr(*fcode_size)), KM_SLEEP);
5984
5985 if (*fcode_addr == NULL) {
5986 DEBUG0("kmem_zalloc returned NULL\n");
5987 pcicfg_unmap_phys(&h, &p);
5988 return (PCICFG_FAILURE);
5989 }
5990
5991 DEBUG1("Fcode Addr %lx\n", *fcode_addr);
5992
5993 ddi_rep_get8(h, *fcode_addr, addr + start_of_fcode, *fcode_size,
5994 DDI_DEV_AUTOINCR);
5995
5996 pcicfg_unmap_phys(&h, &p);
5997
5998 return (PCICFG_SUCCESS);
5999 }
6000
6001 static int
pcicfg_fcode_assign_bars(ddi_acc_handle_t h,dev_info_t * dip,uint_t bus,uint_t device,uint_t func,int32_t fc_request,pci_regspec_t * rom_regspec)6002 pcicfg_fcode_assign_bars(ddi_acc_handle_t h, dev_info_t *dip, uint_t bus,
6003 uint_t device, uint_t func, int32_t fc_request, pci_regspec_t *rom_regspec)
6004 {
6005 /*
6006 * Assign values to all BARs so that it is safe to turn on the
6007 * device for accessing the fcode on the PROM. On successful
6008 * exit from this function, "assigned-addresses" are created
6009 * for all BARs and ROM BAR is enabled. Also, rom_regspec is
6010 * filled with the values that can be used to free up this
6011 * resource later.
6012 */
6013 uint32_t request, hiword, size;
6014 pci_regspec_t phys_spec;
6015 ndi_ra_request_t req;
6016 uint64_t mem_answer, mem_alen;
6017 int i;
6018
6019 DEBUG1("pcicfg_fcode_assign_bars :%s\n", DEVI(dip)->devi_name);
6020
6021 /*
6022 * Process the BARs.
6023 */
6024 for (i = PCI_CONF_BASE0; i <= PCI_CONF_BASE5; ) {
6025 pci_config_put32(h, i, 0xffffffff);
6026 request = pci_config_get32(h, i);
6027 /*
6028 * Check if implemented
6029 */
6030 if (request == 0) {
6031 DEBUG1("pcicfg_fcode_assign_bars :"
6032 "BASE register [0x%x] asks for 0(32)\n", i);
6033 i += 4;
6034 continue;
6035 }
6036 /*
6037 * Build the phys_spec for this BAR
6038 */
6039 hiword = PCICFG_MAKE_REG_HIGH(bus, device, func, i);
6040 size = (~(PCI_BASE_M_ADDR_M & request)) + 1;
6041
6042 DEBUG3("pcicfg_fcode_assign_bars :"
6043 "BASE register [0x%x] asks for [0x%x]=[0x%x]\n",
6044 i, request, size);
6045
6046 if ((PCI_BASE_SPACE_M & request) == PCI_BASE_SPACE_MEM) {
6047 if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_MEM) {
6048 hiword |= PCI_ADDR_MEM32;
6049 } else if ((PCI_BASE_TYPE_M & request)
6050 == PCI_BASE_TYPE_ALL) {
6051 hiword |= PCI_ADDR_MEM64;
6052 }
6053 if (request & PCI_BASE_PREF_M)
6054 hiword |= PCI_REG_PF_M;
6055 } else {
6056 hiword |= PCI_ADDR_IO;
6057 }
6058 phys_spec.pci_phys_hi = hiword;
6059 phys_spec.pci_phys_mid = 0;
6060 phys_spec.pci_phys_low = 0;
6061 phys_spec.pci_size_hi = 0;
6062 phys_spec.pci_size_low = size;
6063
6064 /*
6065 * The following function
6066 * - allocates address space
6067 * - programs the BAR
6068 * - adds an "assigned-addresses" property
6069 */
6070 if (pcicfg_alloc_resource(dip, phys_spec)) {
6071 cmn_err(CE_WARN, "failed to allocate %d bytes"
6072 " for dev %s BASE register [0x%x]\n",
6073 size, DEVI(dip)->devi_name, i);
6074 goto failure;
6075 }
6076 if ((PCI_BASE_TYPE_M & request) == PCI_BASE_TYPE_ALL) {
6077 /*
6078 * 64 bit, should be in memory space.
6079 */
6080 i += 8;
6081 } else {
6082 /*
6083 * 32 bit, either memory or I/O space.
6084 */
6085 i += 4;
6086 }
6087 }
6088
6089 /*
6090 * Handle ROM BAR. We do not use the common
6091 * resource allocator function because we need to
6092 * return reg spec to the caller.
6093 */
6094 size = (~(PCI_BASE_ROM_ADDR_M & fc_request)) + 1;
6095
6096 DEBUG3("BASE register [0x%x] asks for "
6097 "[0x%x]=[0x%x]\n", PCI_CONF_ROM, fc_request, size);
6098
6099 bzero((caddr_t)&req, sizeof (ndi_ra_request_t));
6100
6101 req.ra_boundbase = 0;
6102 req.ra_boundlen = PCICFG_4GIG_LIMIT;
6103 req.ra_len = size;
6104 req.ra_flags = (NDI_RA_ALIGN_SIZE | NDI_RA_ALLOC_BOUNDED);
6105
6106 if (ndi_ra_alloc(ddi_get_parent(dip),
6107 &req, &mem_answer, &mem_alen,
6108 NDI_RA_TYPE_MEM, NDI_RA_PASS)) {
6109 cmn_err(CE_WARN, "failed to allocate %d bytes"
6110 " for dev %s ROM BASE register\n",
6111 size, DEVI(dip)->devi_name);
6112 goto failure;
6113 }
6114
6115 DEBUG3("ROM addr = [0x%x.%x] len [0x%x]\n",
6116 PCICFG_HIADDR(mem_answer),
6117 PCICFG_LOADDR(mem_answer), mem_alen);
6118
6119 /*
6120 * Assign address space and enable ROM.
6121 */
6122 pci_config_put32(h, PCI_CONF_ROM,
6123 PCICFG_LOADDR(mem_answer) | PCI_BASE_ROM_ENABLE);
6124
6125 /*
6126 * Add resource to assigned-addresses.
6127 */
6128 phys_spec.pci_phys_hi = PCICFG_MAKE_REG_HIGH(bus, device, func, \
6129 PCI_CONF_ROM) | PCI_ADDR_MEM32;
6130 if (fc_request & PCI_BASE_PREF_M)
6131 phys_spec.pci_phys_hi |= PCI_REG_PF_M;
6132 phys_spec.pci_phys_mid = 0;
6133 phys_spec.pci_phys_low = PCICFG_LOADDR(mem_answer);
6134 phys_spec.pci_size_hi = 0;
6135 phys_spec.pci_size_low = size;
6136
6137 if (pcicfg_update_assigned_prop(dip, &phys_spec)
6138 != PCICFG_SUCCESS) {
6139 cmn_err(CE_WARN, "failed to update"
6140 " assigned-address property for dev %s\n",
6141 DEVI(dip)->devi_name);
6142 goto failure;
6143 }
6144 /*
6145 * Copy out the reg spec.
6146 */
6147 *rom_regspec = phys_spec;
6148
6149 return (PCICFG_SUCCESS);
6150
6151 failure:
6152 /*
6153 * We came in with no "assigned-addresses".
6154 * Free up the resources we may have allocated.
6155 */
6156 (void) pcicfg_free_device_resources(dip, 0);
6157
6158 return (PCICFG_FAILURE);
6159 }
6160
6161 #endif /* PCICFG_INTERPRET_FCODE */
6162
6163 static int
pcicfg_free_all_resources(dev_info_t * dip)6164 pcicfg_free_all_resources(dev_info_t *dip)
6165 {
6166 pci_regspec_t *assigned;
6167 int assigned_len;
6168 int acount;
6169 int i;
6170
6171 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
6172 DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
6173 &assigned_len) != DDI_PROP_SUCCESS) {
6174 DEBUG0("Failed to read assigned-addresses property\n");
6175 return (PCICFG_FAILURE);
6176 }
6177
6178 acount = assigned_len / sizeof (pci_regspec_t);
6179
6180 for (i = 0; i < acount; i++) {
6181 if (pcicfg_free_resource(dip, assigned[i], 0)) {
6182 /*
6183 * Dont forget to free mem from ddi_getlongprop
6184 */
6185 kmem_free((caddr_t)assigned, assigned_len);
6186 return (PCICFG_FAILURE);
6187 }
6188 }
6189
6190 /*
6191 * Don't forget to free up memory from ddi_getlongprop
6192 */
6193 if (assigned_len)
6194 kmem_free((caddr_t)assigned, assigned_len);
6195
6196 return (PCICFG_SUCCESS);
6197 }
6198 static int
pcicfg_alloc_new_resources(dev_info_t * dip)6199 pcicfg_alloc_new_resources(dev_info_t *dip)
6200 {
6201 pci_regspec_t *assigned, *reg;
6202 int assigned_len, reg_len;
6203 int acount, rcount;
6204 int i, j, alloc_size;
6205 boolean_t alloc;
6206
6207 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
6208 DDI_PROP_DONTPASS, "reg", (caddr_t)®,
6209 ®_len) != DDI_PROP_SUCCESS) {
6210 DEBUG0("Failed to read reg property\n");
6211 return (PCICFG_FAILURE);
6212 }
6213 rcount = reg_len / sizeof (pci_regspec_t);
6214
6215 DEBUG2("pcicfg_alloc_new_resources() reg size=%x entries=%x\n",
6216 reg_len, rcount);
6217
6218 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
6219 DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
6220 &assigned_len) != DDI_PROP_SUCCESS) {
6221 acount = 0;
6222 } else {
6223 acount = assigned_len / sizeof (pci_regspec_t);
6224 }
6225
6226 DEBUG1("assigned-addresses property len=%x\n", acount);
6227
6228 /*
6229 * For each address described by reg, search for it in the
6230 * assigned-addresses property. If it does not exist, allocate
6231 * resources for it. If it does exist, check the size in both.
6232 * The size needs to be bigger of the two.
6233 */
6234 for (i = 1; i < rcount; i++) {
6235 alloc = B_TRUE;
6236 alloc_size = reg[i].pci_size_low;
6237 for (j = 0; j < acount; j++) {
6238 if (assigned[j].pci_phys_hi == reg[i].pci_phys_hi) {
6239 /*
6240 * There is an exact match. Check size.
6241 */
6242 DEBUG1("pcicfg_alloc_new_resources "
6243 "- %x - MATCH\n",
6244 reg[i].pci_phys_hi);
6245
6246 if (reg[i].pci_size_low >
6247 assigned[j].pci_size_low) {
6248 /*
6249 * Fcode wants more.
6250 */
6251 DEBUG3("pcicfg_alloc_new_resources"
6252 " - %x - RESIZE"
6253 " assigned 0x%x reg 0x%x\n",
6254 assigned[j].pci_phys_hi,
6255 assigned[j].pci_size_low,
6256 reg[i].pci_size_low);
6257
6258 /*
6259 * Free the old resource.
6260 */
6261 (void) pcicfg_free_resource(dip,
6262 assigned[j], 0);
6263 } else {
6264 DEBUG3("pcicfg_alloc_new_resources"
6265 " - %x - ENOUGH"
6266 " assigned 0x%x reg 0x%x\n",
6267 assigned[j].pci_phys_hi,
6268 assigned[j].pci_size_low,
6269 reg[i].pci_size_low);
6270
6271 alloc = B_FALSE;
6272 }
6273 break;
6274 }
6275 /*
6276 * Fcode may have set one or more of the
6277 * NPT bits in phys.hi.
6278 */
6279 if (PCI_REG_BDFR_G(assigned[j].pci_phys_hi) ==
6280 PCI_REG_BDFR_G(reg[i].pci_phys_hi)) {
6281
6282 DEBUG2("pcicfg_alloc_new_resources "
6283 "- PARTIAL MATCH assigned 0x%x "
6284 "reg 0x%x\n", assigned[j].pci_phys_hi,
6285 reg[i].pci_phys_hi);
6286 /*
6287 * Changing the SS bits is an error
6288 */
6289 if (PCI_REG_ADDR_G(
6290 assigned[j].pci_phys_hi) !=
6291 PCI_REG_ADDR_G(reg[i].pci_phys_hi)) {
6292
6293 DEBUG2("Fcode changing"
6294 " SS bits of - 0x%x -"
6295 " on %s\n", reg[i].pci_phys_hi,
6296 DEVI(dip)->devi_name);
6297
6298 }
6299
6300
6301 /*
6302 * We are going to allocate new resource.
6303 * Free the old resource. Again, adjust
6304 * the size to be safe.
6305 */
6306 (void) pcicfg_free_resource(dip,
6307 assigned[j], 0);
6308
6309 alloc_size = MAX(reg[i].pci_size_low,
6310 assigned[j].pci_size_low);
6311
6312 break;
6313 }
6314 }
6315 /*
6316 * We are allocating resources for one of three reasons -
6317 * - Fcode wants a larger address space
6318 * - Fcode has set changed/set n, p, t bits.
6319 * - It is a new "reg", it should be only ROM bar, but
6320 * we don't do the checking.
6321 */
6322 if (alloc == B_TRUE) {
6323 DEBUG1("pcicfg_alloc_new_resources : creating 0x%x\n",
6324 reg[i].pci_phys_hi);
6325
6326 reg[i].pci_size_low = alloc_size;
6327 if (pcicfg_alloc_resource(dip, reg[i])) {
6328 /*
6329 * Dont forget to free mem from
6330 * ddi_getlongprop
6331 */
6332 if (acount != 0)
6333 kmem_free((caddr_t)assigned,
6334 assigned_len);
6335 kmem_free((caddr_t)reg, reg_len);
6336 return (PCICFG_FAILURE);
6337 }
6338 }
6339 }
6340
6341 /*
6342 * Don't forget to free up memory from ddi_getlongprop
6343 */
6344 if (acount != 0)
6345 kmem_free((caddr_t)assigned, assigned_len);
6346 kmem_free((caddr_t)reg, reg_len);
6347
6348 return (PCICFG_SUCCESS);
6349 }
6350
6351 static int
pcicfg_alloc_resource(dev_info_t * dip,pci_regspec_t phys_spec)6352 pcicfg_alloc_resource(dev_info_t *dip, pci_regspec_t phys_spec)
6353 {
6354 uint64_t answer;
6355 uint64_t alen;
6356 int offset;
6357 pci_regspec_t config;
6358 caddr_t virt, v;
6359 ddi_device_acc_attr_t acc;
6360 ddi_acc_handle_t h;
6361 ndi_ra_request_t request;
6362 pci_regspec_t *assigned;
6363 int assigned_len, entries, i;
6364
6365 if (ddi_getlongprop(DDI_DEV_T_ANY, dip,
6366 DDI_PROP_DONTPASS, "assigned-addresses", (caddr_t)&assigned,
6367 &assigned_len) == DDI_PROP_SUCCESS) {
6368 DEBUG0("pcicfg_alloc_resource - "
6369 "searching assigned-addresses\n");
6370
6371 entries = assigned_len / (sizeof (pci_regspec_t));
6372
6373 /*
6374 * Walk through the assigned-addresses entries. If there is
6375 * a match, there is no need to allocate the resource.
6376 */
6377 for (i = 0; i < entries; i++) {
6378 if (assigned[i].pci_phys_hi == phys_spec.pci_phys_hi) {
6379 DEBUG1("pcicfg_alloc_resource - MATCH %x\n",
6380 assigned[i].pci_phys_hi);
6381 kmem_free(assigned, assigned_len);
6382 return (0);
6383 }
6384 }
6385 kmem_free(assigned, assigned_len);
6386 }
6387
6388 bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
6389
6390 config.pci_phys_hi = PCI_CONF_ADDR_MASK & phys_spec.pci_phys_hi;
6391 config.pci_phys_hi &= ~PCI_REG_REG_M;
6392 config.pci_phys_mid = config.pci_phys_low = 0;
6393 config.pci_size_hi = config.pci_size_low = 0;
6394
6395 /*
6396 * Map in configuration space (temporarily)
6397 */
6398 acc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
6399 acc.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
6400 acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
6401
6402 if (pcicfg_map_phys(dip, &config, &virt, &acc, &h)) {
6403 DEBUG0("Can not map in config space\n");
6404 return (1);
6405 }
6406
6407 request.ra_flags = NDI_RA_ALIGN_SIZE;
6408 request.ra_boundbase = 0;
6409 request.ra_boundlen = PCICFG_4GIG_LIMIT;
6410 /*
6411 * Use size stored in phys_spec parameter.
6412 */
6413 request.ra_len = phys_spec.pci_size_low;
6414
6415 offset = PCI_REG_REG_G(phys_spec.pci_phys_hi);
6416
6417 v = virt + offset;
6418
6419 if (PCI_REG_REG_G(phys_spec.pci_phys_hi) == PCI_CONF_ROM) {
6420
6421 request.ra_flags |= NDI_RA_ALLOC_BOUNDED;
6422
6423 /* allocate memory space from the allocator */
6424
6425 if (ndi_ra_alloc(ddi_get_parent(dip),
6426 &request, &answer, &alen,
6427 NDI_RA_TYPE_MEM, NDI_RA_PASS)
6428 != NDI_SUCCESS) {
6429 DEBUG0("(ROM)Failed to allocate 32b mem");
6430 pcicfg_unmap_phys(&h, &config);
6431 return (1);
6432 }
6433 DEBUG3("ROM addr = [0x%x.%x] len [0x%x]\n",
6434 PCICFG_HIADDR(answer),
6435 PCICFG_LOADDR(answer),
6436 alen);
6437
6438 /* program the low word */
6439
6440 ddi_put32(h, (uint32_t *)v, (uint32_t)PCICFG_LOADDR(answer));
6441
6442 phys_spec.pci_phys_low = PCICFG_LOADDR(answer);
6443 phys_spec.pci_phys_mid = PCICFG_HIADDR(answer);
6444 } else {
6445
6446 switch (PCI_REG_ADDR_G(phys_spec.pci_phys_hi)) {
6447 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
6448 request.ra_flags &= ~NDI_RA_ALLOC_BOUNDED;
6449 /* allocate memory space from the allocator */
6450 if (ndi_ra_alloc(ddi_get_parent(dip),
6451 &request, &answer, &alen,
6452 NDI_RA_TYPE_MEM, NDI_RA_PASS)
6453 != NDI_SUCCESS) {
6454 DEBUG0("Failed to allocate 64b mem\n");
6455 pcicfg_unmap_phys(&h, &config);
6456 return (1);
6457 }
6458 DEBUG3("64 addr = [0x%x.%x] len [0x%x]\n",
6459 PCICFG_HIADDR(answer),
6460 PCICFG_LOADDR(answer),
6461 alen);
6462
6463 /* program the low word */
6464
6465 ddi_put32(h, (uint32_t *)v,
6466 (uint32_t)PCICFG_LOADDR(answer));
6467
6468 /* program the high word with value zero */
6469 v += 4;
6470 ddi_put32(h, (uint32_t *)v,
6471 (uint32_t)PCICFG_HIADDR(answer));
6472
6473 phys_spec.pci_phys_low = PCICFG_LOADDR(answer);
6474 phys_spec.pci_phys_mid = PCICFG_HIADDR(answer);
6475 /*
6476 * currently support 32b address space
6477 * assignments only.
6478 */
6479 phys_spec.pci_phys_hi ^= PCI_ADDR_MEM64 ^
6480 PCI_ADDR_MEM32;
6481
6482 break;
6483
6484 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
6485 request.ra_flags |= NDI_RA_ALLOC_BOUNDED;
6486 /* allocate memory space from the allocator */
6487 if (ndi_ra_alloc(ddi_get_parent(dip),
6488 &request, &answer, &alen,
6489 NDI_RA_TYPE_MEM, NDI_RA_PASS)
6490 != NDI_SUCCESS) {
6491 DEBUG0("Failed to allocate 32b mem\n");
6492 pcicfg_unmap_phys(&h, &config);
6493 return (1);
6494 }
6495
6496 DEBUG3("32 addr = [0x%x.%x] len [0x%x]\n",
6497 PCICFG_HIADDR(answer),
6498 PCICFG_LOADDR(answer),
6499 alen);
6500
6501 /* program the low word */
6502
6503 ddi_put32(h, (uint32_t *)v,
6504 (uint32_t)PCICFG_LOADDR(answer));
6505
6506 phys_spec.pci_phys_low = PCICFG_LOADDR(answer);
6507
6508 break;
6509 case PCI_REG_ADDR_G(PCI_ADDR_IO):
6510 /* allocate I/O space from the allocator */
6511 request.ra_flags |= NDI_RA_ALLOC_BOUNDED;
6512 if (ndi_ra_alloc(ddi_get_parent(dip),
6513 &request, &answer, &alen,
6514 NDI_RA_TYPE_IO, NDI_RA_PASS)
6515 != NDI_SUCCESS) {
6516 DEBUG0("Failed to allocate I/O\n");
6517 pcicfg_unmap_phys(&h, &config);
6518 return (1);
6519 }
6520 DEBUG3("I/O addr = [0x%x.%x] len [0x%x]\n",
6521 PCICFG_HIADDR(answer),
6522 PCICFG_LOADDR(answer),
6523 alen);
6524
6525 ddi_put32(h, (uint32_t *)v,
6526 (uint32_t)PCICFG_LOADDR(answer));
6527
6528 phys_spec.pci_phys_low = PCICFG_LOADDR(answer);
6529
6530 break;
6531 default:
6532 DEBUG0("Unknown register type\n");
6533 pcicfg_unmap_phys(&h, &config);
6534 return (1);
6535 } /* switch */
6536 }
6537
6538 /*
6539 * Now that memory locations are assigned,
6540 * update the assigned address property.
6541 */
6542
6543 DEBUG1("updating assigned-addresss for %x\n", phys_spec.pci_phys_hi);
6544
6545 if (pcicfg_update_assigned_prop(dip, &phys_spec)) {
6546 pcicfg_unmap_phys(&h, &config);
6547 return (1);
6548 }
6549
6550 pcicfg_unmap_phys(&h, &config);
6551
6552 return (0);
6553 }
6554
6555 static int
pcicfg_free_resource(dev_info_t * dip,pci_regspec_t phys_spec,pcicfg_flags_t flags)6556 pcicfg_free_resource(dev_info_t *dip, pci_regspec_t phys_spec,
6557 pcicfg_flags_t flags)
6558 {
6559 int offset;
6560 pci_regspec_t config;
6561 caddr_t virt, v;
6562 ddi_device_acc_attr_t acc;
6563 ddi_acc_handle_t h;
6564 ndi_ra_request_t request;
6565 int l;
6566
6567 bzero((caddr_t)&request, sizeof (ndi_ra_request_t));
6568
6569 config.pci_phys_hi = PCI_CONF_ADDR_MASK & phys_spec.pci_phys_hi;
6570 config.pci_phys_hi &= ~PCI_REG_REG_M;
6571 config.pci_phys_mid = config.pci_phys_low = 0;
6572 config.pci_size_hi = config.pci_size_low = 0;
6573
6574 /*
6575 * Map in configuration space (temporarily)
6576 */
6577 acc.devacc_attr_version = DDI_DEVICE_ATTR_V0;
6578 acc.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC;
6579 acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC;
6580
6581 if (pcicfg_map_phys(dip, &config, &virt, &acc, &h)) {
6582 DEBUG0("Can not map in config space\n");
6583 return (1);
6584 }
6585
6586 offset = PCI_REG_REG_G(phys_spec.pci_phys_hi);
6587
6588 v = virt + offset;
6589
6590 /*
6591 * Use size stored in phys_spec parameter.
6592 */
6593 l = phys_spec.pci_size_low;
6594
6595 if (PCI_REG_REG_G(phys_spec.pci_phys_hi) == PCI_CONF_ROM) {
6596
6597 /* free memory back to the allocator */
6598 if (ndi_ra_free(ddi_get_parent(dip), phys_spec.pci_phys_low,
6599 l, NDI_RA_TYPE_MEM, NDI_RA_PASS) != NDI_SUCCESS) {
6600 DEBUG0("(ROM)Can not free 32b mem");
6601 pcicfg_unmap_phys(&h, &config);
6602 return (1);
6603 }
6604
6605 /* Unmap the BAR by writing a zero */
6606
6607 if ((flags & PCICFG_FLAG_READ_ONLY) == 0)
6608 ddi_put32(h, (uint32_t *)v, (uint32_t)0);
6609 } else {
6610
6611 switch (PCI_REG_ADDR_G(phys_spec.pci_phys_hi)) {
6612
6613 case PCI_REG_ADDR_G(PCI_ADDR_MEM64):
6614 case PCI_REG_ADDR_G(PCI_ADDR_MEM32):
6615 /* free memory back to the allocator */
6616 if (ndi_ra_free(ddi_get_parent(dip),
6617 PCICFG_LADDR(phys_spec.pci_phys_low,
6618 phys_spec.pci_phys_mid),
6619 l, NDI_RA_TYPE_MEM,
6620 NDI_RA_PASS) != NDI_SUCCESS) {
6621 DEBUG0("Cannot free mem");
6622 pcicfg_unmap_phys(&h, &config);
6623 return (1);
6624 }
6625 break;
6626
6627 case PCI_REG_ADDR_G(PCI_ADDR_IO):
6628 /* free I/O space back to the allocator */
6629 if (ndi_ra_free(ddi_get_parent(dip),
6630 phys_spec.pci_phys_low,
6631 l, NDI_RA_TYPE_IO,
6632 NDI_RA_PASS) != NDI_SUCCESS) {
6633 DEBUG0("Can not free I/O space");
6634 pcicfg_unmap_phys(&h, &config);
6635 return (1);
6636 }
6637 break;
6638
6639 default:
6640 DEBUG0("Unknown register type\n");
6641 pcicfg_unmap_phys(&h, &config);
6642 return (1);
6643 } /* switch */
6644 }
6645
6646 /*
6647 * Now that memory locations are assigned,
6648 * update the assigned address property.
6649 */
6650
6651 DEBUG1("updating assigned-addresss for %x\n", phys_spec.pci_phys_hi);
6652
6653 if (pcicfg_remove_assigned_prop(dip, &phys_spec)) {
6654 pcicfg_unmap_phys(&h, &config);
6655 return (1);
6656 }
6657
6658 pcicfg_unmap_phys(&h, &config);
6659
6660 return (0);
6661 }
6662
6663 static int
pcicfg_remove_assigned_prop(dev_info_t * dip,pci_regspec_t * oldone)6664 pcicfg_remove_assigned_prop(dev_info_t *dip, pci_regspec_t *oldone)
6665 {
6666 int alen, num_entries, i;
6667 pci_regspec_t *assigned, *assigned_copy;
6668 uint_t status;
6669
6670 status = ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS,
6671 "assigned-addresses", (caddr_t)&assigned, &alen);
6672 switch (status) {
6673 case DDI_PROP_SUCCESS:
6674 break;
6675 case DDI_PROP_NO_MEMORY:
6676 DEBUG0("no memory for assigned-addresses property\n");
6677 return (1);
6678 default:
6679 DEBUG0("assigned-addresses property does not exist\n");
6680 return (0);
6681 }
6682
6683 /*
6684 * Make a copy of old assigned-addresses property.
6685 */
6686 assigned_copy = kmem_alloc(alen, KM_SLEEP);
6687 bcopy(assigned, assigned_copy, alen);
6688
6689 status = ndi_prop_remove(DDI_DEV_T_NONE, dip, "assigned-addresses");
6690
6691 if (status != DDI_PROP_SUCCESS) {
6692 /*
6693 * If "assigned-addresses" is retrieved from PROM, the
6694 * ndi_prop_remove() will fail.
6695 */
6696 DEBUG1("pcicfg_remove_assigned_prop: 0x%x not removed\n",
6697 oldone->pci_phys_hi);
6698
6699 /*
6700 * Free up allocated memory
6701 */
6702 kmem_free(assigned_copy, alen);
6703 kmem_free((caddr_t)assigned, alen);
6704
6705 return (0);
6706 }
6707
6708 num_entries = alen / sizeof (pci_regspec_t);
6709
6710 /*
6711 * Rebuild the assigned-addresses property.
6712 */
6713 for (i = 0; i < num_entries; i++) {
6714 if (assigned_copy[i].pci_phys_hi != oldone->pci_phys_hi) {
6715 (void) pcicfg_update_assigned_prop(dip,
6716 &assigned_copy[i]);
6717 }
6718 }
6719
6720 /*
6721 * Free the copy of the original assigned-addresses.
6722 */
6723 kmem_free(assigned_copy, alen);
6724
6725 /*
6726 * Don't forget to free up memory from ddi_getlongprop
6727 */
6728 kmem_free((caddr_t)assigned, alen);
6729
6730 return (0);
6731 }
6732
6733 static int
pcicfg_map_phys(dev_info_t * dip,pci_regspec_t * phys_spec,caddr_t * addrp,ddi_device_acc_attr_t * accattrp,ddi_acc_handle_t * handlep)6734 pcicfg_map_phys(dev_info_t *dip, pci_regspec_t *phys_spec,
6735 caddr_t *addrp, ddi_device_acc_attr_t *accattrp,
6736 ddi_acc_handle_t *handlep)
6737 {
6738 ddi_map_req_t mr;
6739 ddi_acc_hdl_t *hp;
6740 int result;
6741
6742 *handlep = impl_acc_hdl_alloc(KM_SLEEP, NULL);
6743 hp = impl_acc_hdl_get(*handlep);
6744 hp->ah_vers = VERS_ACCHDL;
6745 hp->ah_dip = dip;
6746 hp->ah_rnumber = 0;
6747 hp->ah_offset = 0;
6748 hp->ah_len = 0;
6749 hp->ah_acc = *accattrp;
6750
6751 mr.map_op = DDI_MO_MAP_LOCKED;
6752 mr.map_type = DDI_MT_REGSPEC;
6753 mr.map_obj.rp = (struct regspec *)phys_spec;
6754 mr.map_prot = PROT_READ | PROT_WRITE;
6755 mr.map_flags = DDI_MF_KERNEL_MAPPING;
6756 mr.map_handlep = hp;
6757 mr.map_vers = DDI_MAP_VERSION;
6758
6759 result = ddi_map(dip, &mr, 0, 0, addrp);
6760
6761 if (result != DDI_SUCCESS) {
6762 impl_acc_hdl_free(*handlep);
6763 *handlep = (ddi_acc_handle_t)NULL;
6764 } else {
6765 hp->ah_addr = *addrp;
6766 }
6767
6768 return (result);
6769 }
6770
6771 void
pcicfg_unmap_phys(ddi_acc_handle_t * handlep,pci_regspec_t * ph)6772 pcicfg_unmap_phys(ddi_acc_handle_t *handlep, pci_regspec_t *ph)
6773 {
6774 ddi_map_req_t mr;
6775 ddi_acc_hdl_t *hp;
6776
6777 hp = impl_acc_hdl_get(*handlep);
6778 ASSERT(hp);
6779
6780 mr.map_op = DDI_MO_UNMAP;
6781 mr.map_type = DDI_MT_REGSPEC;
6782 mr.map_obj.rp = (struct regspec *)ph;
6783 mr.map_prot = PROT_READ | PROT_WRITE;
6784 mr.map_flags = DDI_MF_KERNEL_MAPPING;
6785 mr.map_handlep = hp;
6786 mr.map_vers = DDI_MAP_VERSION;
6787
6788 (void) ddi_map(hp->ah_dip, &mr, hp->ah_offset,
6789 hp->ah_len, &hp->ah_addr);
6790
6791 impl_acc_hdl_free(*handlep);
6792 *handlep = (ddi_acc_handle_t)NULL;
6793 }
6794
6795 static int
pcicfg_ari_configure(dev_info_t * dip)6796 pcicfg_ari_configure(dev_info_t *dip)
6797 {
6798 if (pcie_ari_supported(dip) == PCIE_ARI_FORW_NOT_SUPPORTED)
6799 return (DDI_FAILURE);
6800
6801 /*
6802 * Until we have resource balancing, dynamically configure
6803 * ARI functions without firmware assistamce.
6804 */
6805 return (DDI_FAILURE);
6806 }
6807
6808 #ifdef DEBUG
6809 static void
debug(char * fmt,uintptr_t a1,uintptr_t a2,uintptr_t a3,uintptr_t a4,uintptr_t a5)6810 debug(char *fmt, uintptr_t a1, uintptr_t a2, uintptr_t a3,
6811 uintptr_t a4, uintptr_t a5)
6812 {
6813 if (pcicfg_debug == 1) {
6814 prom_printf("pcicfg: ");
6815 prom_printf(fmt, a1, a2, a3, a4, a5);
6816 } else
6817 if (pcicfg_debug)
6818 cmn_err(CE_CONT, fmt, a1, a2, a3, a4, a5);
6819 }
6820 #endif
6821
6822 /*
6823 * Return true if the devinfo node is in a PCI Express hierarchy.
6824 */
6825 static boolean_t
is_pcie_fabric(dev_info_t * dip)6826 is_pcie_fabric(dev_info_t *dip)
6827 {
6828 dev_info_t *root = ddi_root_node();
6829 dev_info_t *pdip;
6830 boolean_t found = B_FALSE;
6831 char *bus;
6832
6833 /*
6834 * Does this device reside in a pcie fabric ?
6835 */
6836 for (pdip = dip; pdip && (pdip != root) && !found;
6837 pdip = ddi_get_parent(pdip)) {
6838 if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pdip,
6839 DDI_PROP_DONTPASS, "device_type", &bus) !=
6840 DDI_PROP_SUCCESS)
6841 break;
6842
6843 if (strcmp(bus, "pciex") == 0)
6844 found = B_TRUE;
6845
6846 ddi_prop_free(bus);
6847 }
6848
6849 return (found);
6850 }
6851