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