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