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