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