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