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