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