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