1 /* 2 * (C) Copyright IBM Corporation 2006 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22 * DEALINGS IN THE SOFTWARE. 23 */ 24 /* 25 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 26 * 27 * Permission is hereby granted, free of charge, to any person obtaining a 28 * copy of this software and associated documentation files (the 29 * "Software"), to deal in the Software without restriction, including 30 * without limitation the rights to use, copy, modify, merge, publish, 31 * distribute, and/or sell copies of the Software, and to permit persons 32 * to whom the Software is furnished to do so, provided that the above 33 * copyright notice(s) and this permission notice appear in all copies of 34 * the Software and that both the above copyright notice(s) and this 35 * permission notice appear in supporting documentation. 36 * 37 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 38 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 39 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 40 * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 41 * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 42 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING 43 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 44 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 45 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 46 * 47 * Except as contained in this notice, the name of a copyright holder 48 * shall not be used in advertising or otherwise to promote the sale, use 49 * or other dealings in this Software without prior written authorization 50 * of the copyright holder. 51 */ 52 /* 53 * Solaris devfs interfaces 54 */ 55 56 #include <stdlib.h> 57 #include <strings.h> 58 #include <stdio.h> 59 #include <unistd.h> 60 #include <sys/types.h> 61 #include <sys/stat.h> 62 #include <fcntl.h> 63 #include <sys/mman.h> 64 #include <dirent.h> 65 #include <errno.h> 66 #include <sys/pci.h> 67 #include <assert.h> 68 #include <libdevinfo.h> 69 #include "pci_tools.h" 70 71 #include "pciaccess.h" 72 #include "pciaccess_private.h" 73 74 #define MAX_DEVICES 256 75 #define CELL_NUMS_1275 (sizeof(pci_regspec_t)/sizeof(uint_t)) 76 typedef union { 77 uint8_t bytes[16 * sizeof (uint32_t)]; 78 uint32_t dwords[16]; 79 } pci_conf_hdr_t; 80 81 typedef struct i_devnode { 82 uint8_t bus; 83 uint8_t dev; 84 uint8_t func; 85 di_node_t node; 86 } i_devnode_t; 87 88 typedef struct nexus { 89 int fd; 90 int domain; 91 struct nexus *next; 92 } nexus_t; 93 94 static nexus_t *nexus_list = NULL; 95 static int num_domains = 0; 96 static int xsvc_fd = -1; 97 /* 98 * Read config space in native processor endianness. Endian-neutral 99 * processing can then take place. On big endian machines, MSB and LSB 100 * of little endian data end up switched if read as little endian. 101 * They are in correct order if read as big endian. 102 */ 103 #if defined(__sparc) 104 #define NATIVE_ENDIAN PCITOOL_ACC_ATTR_ENDN_BIG 105 #elif defined(__x86) 106 #define NATIVE_ENDIAN PCITOOL_ACC_ATTR_ENDN_LTL 107 #else 108 #error "ISA is neither __sparc nor __x86" 109 #endif 110 111 /* 112 * Identify problematic southbridges. These have device id 0x5249 and 113 * vendor id 0x10b9. Check for revision ID 0 and class code 060400 as well. 114 * Values are little endian, so they are reversed for SPARC. 115 * 116 * Check for these southbridges on all architectures, as the issue is a 117 * southbridge issue, independent of processor. 118 * 119 * If one of these is found during probing, skip probing other devs/funcs on 120 * the rest of the bus, since the southbridge and all devs underneath will 121 * otherwise disappear. 122 */ 123 #if (NATIVE_ENDIAN == PCITOOL_ACC_ATTR_ENDN_BIG) 124 #define U45_SB_DEVID_VID 0xb9104952 125 #define U45_SB_CLASS_RID 0x00000406 126 #else 127 #define U45_SB_DEVID_VID 0x524910b9 128 #define U45_SB_CLASS_RID 0x06040000 129 #endif 130 131 #define DEBUGON 0 132 133 134 static int pci_device_solx_devfs_map_range(struct pci_device *dev, 135 struct pci_device_mapping *map); 136 137 static int pci_device_solx_devfs_read_rom( struct pci_device * dev, 138 void * buffer ); 139 140 static int pci_device_solx_devfs_probe( struct pci_device * dev ); 141 142 static int pci_device_solx_devfs_read( struct pci_device * dev, void * data, 143 pciaddr_t offset, pciaddr_t size, pciaddr_t * bytes_read ); 144 145 static int pci_device_solx_devfs_write( struct pci_device * dev, 146 const void * data, pciaddr_t offset, pciaddr_t size, 147 pciaddr_t * bytes_written ); 148 149 static int 150 probe_dev(nexus_t *nexus, pcitool_reg_t *prg_p, struct pci_system *pci_sys); 151 152 static int 153 do_probe(nexus_t *nexus, struct pci_system *pci_sys); 154 155 static int 156 probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg); 157 158 static void 159 pci_system_solx_devfs_destroy( void ); 160 161 static int 162 get_config_header(int fd, uint8_t bus_no, uint8_t dev_no, uint8_t func_no, 163 pci_conf_hdr_t *config_hdr_p); 164 165 int 166 pci_system_solx_devfs_create( void ); 167 168 169 170 171 static const struct pci_system_methods solx_devfs_methods = { 172 .destroy = pci_system_solx_devfs_destroy, 173 .destroy_device = NULL, 174 .read_rom = pci_device_solx_devfs_read_rom, 175 .probe = pci_device_solx_devfs_probe, 176 .map_range = pci_device_solx_devfs_map_range, 177 .unmap_range = pci_device_generic_unmap_range, 178 179 .read = pci_device_solx_devfs_read, 180 .write = pci_device_solx_devfs_write, 181 182 .fill_capabilities = pci_fill_capabilities_generic 183 }; 184 185 static nexus_t * 186 find_nexus_for_domain( int domain ) 187 { 188 nexus_t *nexus; 189 190 for (nexus = nexus_list ; nexus != NULL ; nexus = nexus->next) { 191 if (nexus->domain == domain) { 192 return nexus; 193 } 194 } 195 return NULL; 196 } 197 198 static uint32_t 199 get_config_hdr_value(pci_conf_hdr_t *config_hdr_p, uint16_t offset, 200 uint8_t size) 201 { 202 uint32_t value = 0; 203 204 while (size-- > 0) { 205 value = (value << 8) + config_hdr_p->bytes[offset + size]; 206 } 207 208 return value; 209 } 210 211 #define GET_CONFIG_VAL_8(offset) \ 212 (config_hdr.bytes[offset]) 213 #define GET_CONFIG_VAL_16(offset) \ 214 (uint16_t)get_config_hdr_value(&config_hdr, offset, 2) 215 #define GET_CONFIG_VAL_32(offset) \ 216 (uint32_t)get_config_hdr_value(&config_hdr, offset, 4) 217 218 /* 219 * Release all the resources 220 * Solaris version 221 */ 222 static void 223 pci_system_solx_devfs_destroy( void ) 224 { 225 /* 226 * the memory allocated in create routines 227 * will be freed in pci_system_init 228 * It is more reasonable to free them here 229 */ 230 nexus_t *nexus, *next; 231 for (nexus = nexus_list ; nexus != NULL ; nexus = next) { 232 next = nexus->next; 233 close(nexus->fd); 234 free(nexus); 235 } 236 nexus_list = NULL; 237 238 if (xsvc_fd >= 0) { 239 close(xsvc_fd); 240 xsvc_fd = -1; 241 } 242 243 } 244 245 /* 246 * Attempt to access PCI subsystem using Solaris's devfs interface. 247 * Solaris version 248 */ 249 int 250 pci_system_solx_devfs_create( void ) 251 { 252 int err = 0; 253 di_node_t di_node; 254 255 256 if (nexus_list != NULL) { 257 return 0; 258 } 259 260 /* 261 * Only allow MAX_DEVICES exists 262 * I will fix it later to get 263 * the total devices first 264 */ 265 if ((pci_sys = calloc(1, sizeof (struct pci_system))) != NULL) { 266 pci_sys->methods = &solx_devfs_methods; 267 if ((pci_sys->devices = 268 calloc(MAX_DEVICES, sizeof (struct pci_device_private))) 269 != NULL) { 270 if ((di_node = di_init("/", DINFOCPYALL)) 271 == DI_NODE_NIL) { 272 err = errno; 273 (void) fprintf(stderr, 274 "di_init() failed: %s\n", 275 strerror(errno)); 276 } else { 277 (void) di_walk_minor(di_node, DDI_NT_REGACC, 278 0, pci_sys, 279 probe_nexus_node); 280 di_fini(di_node); 281 } 282 } 283 else { 284 err = errno; 285 } 286 } else { 287 err = errno; 288 } 289 290 if (err != 0) { 291 if (pci_sys != NULL) { 292 free(pci_sys->devices); 293 free(pci_sys); 294 pci_sys = NULL; 295 } 296 } 297 298 return (err); 299 } 300 301 /* 302 * Retrieve first 16 dwords of device's config header, except for the first 303 * dword. First 16 dwords are defined by the PCI specification. 304 */ 305 static int 306 get_config_header(int fd, uint8_t bus_no, uint8_t dev_no, uint8_t func_no, 307 pci_conf_hdr_t *config_hdr_p) 308 { 309 pcitool_reg_t cfg_prg; 310 int i; 311 int rval = 0; 312 313 /* Prepare a local pcitool_reg_t so as to not disturb the caller's. */ 314 cfg_prg.offset = 0; 315 cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_4 + NATIVE_ENDIAN; 316 cfg_prg.bus_no = bus_no; 317 cfg_prg.dev_no = dev_no; 318 cfg_prg.func_no = func_no; 319 cfg_prg.barnum = 0; 320 cfg_prg.user_version = PCITOOL_USER_VERSION; 321 322 /* Get dwords 1-15 of config space. They must be read as uint32_t. */ 323 for (i = 1; i < (sizeof (pci_conf_hdr_t) / sizeof (uint32_t)); i++) { 324 cfg_prg.offset += sizeof (uint32_t); 325 if ((rval = 326 ioctl(fd, PCITOOL_DEVICE_GET_REG, &cfg_prg)) != 0) { 327 break; 328 } 329 config_hdr_p->dwords[i] = (uint32_t)cfg_prg.data; 330 } 331 332 return (rval); 333 } 334 335 336 /* 337 * Probe device's functions. Modifies many fields in the prg_p. 338 */ 339 static int 340 probe_dev(nexus_t *nexus, pcitool_reg_t *prg_p, struct pci_system *pci_sys) 341 { 342 pci_conf_hdr_t config_hdr; 343 boolean_t multi_function_device; 344 int8_t func; 345 int8_t first_func = 0; 346 int8_t last_func = PCI_REG_FUNC_M >> PCI_REG_FUNC_SHIFT; 347 int rval = 0; 348 struct pci_device *pci_base; 349 350 /* 351 * Loop through at least func=first_func. Continue looping through 352 * functions if there are no errors and the device is a multi-function 353 * device. 354 * 355 * (Note, if first_func == 0, header will show whether multifunction 356 * device and set multi_function_device. If first_func != 0, then we 357 * will force the loop as the user wants a specific function to be 358 * checked. 359 */ 360 for (func = first_func, multi_function_device = B_FALSE; 361 ((func <= last_func) && 362 ((func == first_func) || (multi_function_device))); 363 func++) { 364 prg_p->func_no = func; 365 366 /* 367 * Four things can happen here: 368 * 369 * 1) ioctl comes back as EFAULT and prg_p->status is 370 * PCITOOL_INVALID_ADDRESS. There is no device at this 371 * location. 372 * 373 * 2) ioctl comes back successful and the data comes back as 374 * zero. Config space is mapped but no device responded. 375 * 376 * 3) ioctl comes back successful and the data comes back as 377 * non-zero. We've found a device. 378 * 379 * 4) Some other error occurs in an ioctl. 380 */ 381 382 prg_p->status = PCITOOL_SUCCESS; 383 prg_p->offset = 0; 384 prg_p->data = 0; 385 prg_p->user_version = PCITOOL_USER_VERSION; 386 if (((rval = ioctl(nexus->fd, PCITOOL_DEVICE_GET_REG, prg_p)) != 0) || 387 (prg_p->data == 0xffffffff)) { 388 389 /* 390 * Accept errno == EINVAL along with status of 391 * PCITOOL_OUT_OF_RANGE because some systems 392 * don't implement the full range of config space. 393 * Leave the loop quietly in this case. 394 */ 395 if ((errno == EINVAL) || 396 (prg_p->status == PCITOOL_OUT_OF_RANGE)) { 397 break; 398 } 399 400 /* 401 * Exit silently with ENXIO as this means that there are 402 * no devices under the pci root nexus. 403 */ 404 else if ((errno == ENXIO) && 405 (prg_p->status == PCITOOL_IO_ERROR)) { 406 break; 407 } 408 409 /* 410 * Expect errno == EFAULT along with status of 411 * PCITOOL_INVALID_ADDRESS because there won't be 412 * devices at each stop. Quit on any other error. 413 */ 414 else if (((errno != EFAULT) || 415 (prg_p->status != PCITOOL_INVALID_ADDRESS)) && 416 (prg_p->data != 0xffffffff)) { 417 418 break; 419 420 /* 421 * If no function at this location, 422 * just advance to the next function. 423 */ 424 } else { 425 rval = 0; 426 } 427 428 /* 429 * Data came back as 0. 430 * Treat as unresponsive device and check next device. 431 */ 432 } else if (prg_p->data == 0) { 433 rval = 0; 434 break; /* Func loop. */ 435 436 /* Found something. */ 437 } else { 438 config_hdr.dwords[0] = (uint32_t)prg_p->data; 439 440 /* Get the rest of the PCI header. */ 441 if ((rval = get_config_header(nexus->fd, prg_p->bus_no, 442 prg_p->dev_no, prg_p->func_no, &config_hdr)) != 443 0) { 444 break; 445 } 446 447 /* 448 * Special case for the type of Southbridge found on 449 * Ultra-45 and other sun4u fire workstations. 450 */ 451 if ((config_hdr.dwords[0] == U45_SB_DEVID_VID) && 452 (config_hdr.dwords[2] == U45_SB_CLASS_RID)) { 453 rval = ECANCELED; 454 break; 455 } 456 457 /* 458 * Found one device with bus number, device number and 459 * function number. 460 */ 461 462 pci_base = 463 &pci_sys->devices[pci_sys->num_devices].base; 464 465 /* 466 * Domain is peer bus?? 467 */ 468 pci_base->domain = nexus->domain; 469 pci_base->bus = prg_p->bus_no; 470 pci_base->dev = prg_p->dev_no; 471 pci_base->func = func; 472 /* 473 * for the format of device_class, see struct pci_device; 474 */ 475 pci_base->device_class = 476 (GET_CONFIG_VAL_8(PCI_CONF_BASCLASS) << 16) | 477 (GET_CONFIG_VAL_8(PCI_CONF_SUBCLASS) << 8) | 478 GET_CONFIG_VAL_8(PCI_CONF_PROGCLASS); 479 pci_base->revision = 480 GET_CONFIG_VAL_8(PCI_CONF_REVID); 481 pci_base->vendor_id = 482 GET_CONFIG_VAL_16(PCI_CONF_VENID); 483 pci_base->device_id = 484 GET_CONFIG_VAL_16(PCI_CONF_DEVID); 485 pci_base->subvendor_id = 486 GET_CONFIG_VAL_16(PCI_CONF_SUBVENID); 487 pci_base->subdevice_id = 488 GET_CONFIG_VAL_16(PCI_CONF_SUBSYSID); 489 490 pci_sys->devices[pci_sys->num_devices].header_type = 491 GET_CONFIG_VAL_8(PCI_CONF_HEADER); 492 #if DEBUGON 493 fprintf(stderr, "busno = %x, devno = %x, funcno = %x\n", 494 prg_p->bus_no, prg_p->dev_no, func); 495 #endif 496 497 pci_sys->num_devices++; 498 499 /* 500 * Accommodate devices which state their 501 * multi-functionality only in their function 0 config 502 * space. Note multi-functionality throughout probing 503 * of all of this device's functions. 504 */ 505 if (config_hdr.bytes[PCI_CONF_HEADER] & 506 PCI_HEADER_MULTI) { 507 multi_function_device = B_TRUE; 508 } 509 } 510 } 511 512 return (rval); 513 } 514 515 /* 516 * This function is called from di_walk_minor() when any PROBE is processed 517 */ 518 static int 519 probe_nexus_node(di_node_t di_node, di_minor_t minor, void *arg) 520 { 521 struct pci_system *pci_sys = (struct pci_system *) arg; 522 char *nexus_name; 523 nexus_t *nexus; 524 int fd; 525 char nexus_path[MAXPATHLEN]; 526 527 nexus = calloc(1, sizeof(nexus_t)); 528 if (nexus == NULL) { 529 (void) fprintf(stderr, 530 "Error allocating memory for nexus: %s\n", 531 strerror(errno)); 532 return DI_WALK_TERMINATE; 533 } 534 535 nexus_name = di_devfs_minor_path(minor); 536 if (nexus_name == NULL) { 537 (void) fprintf(stderr, "Error getting nexus path: %s\n", 538 strerror(errno)); 539 free(nexus); 540 return (DI_WALK_CONTINUE); 541 } 542 543 snprintf(nexus_path, sizeof(nexus_path), "/devices%s", nexus_name); 544 545 if ((fd = open(nexus_path, O_RDWR)) >= 0) { 546 nexus->fd = fd; 547 nexus->domain = num_domains++; 548 if ((do_probe(nexus, pci_sys) != 0) && (errno != ENXIO)) { 549 (void) fprintf(stderr, "Error probing node %s: %s\n", 550 nexus_path, strerror(errno)); 551 (void) close(fd); 552 free(nexus); 553 } else { 554 nexus->next = nexus_list; 555 nexus_list = nexus; 556 } 557 } else { 558 (void) fprintf(stderr, "Error opening %s: %s\n", 559 nexus_path, strerror(errno)); 560 free(nexus); 561 } 562 di_devfs_path_free(nexus_name); 563 564 return DI_WALK_CONTINUE; 565 } 566 567 568 /* 569 * Solaris version 570 * Probe a given nexus config space for devices. 571 * 572 * fd is the file descriptor of the nexus. 573 * input_args contains commandline options as specified by the user. 574 */ 575 static int 576 do_probe(nexus_t *nexus, struct pci_system *pci_sys) 577 { 578 pcitool_reg_t prg; 579 uint32_t bus; 580 uint8_t dev; 581 uint32_t last_bus = PCI_REG_BUS_M >> PCI_REG_BUS_SHIFT; 582 uint8_t last_dev = PCI_REG_DEV_M >> PCI_REG_DEV_SHIFT; 583 uint8_t first_bus = 0; 584 uint8_t first_dev = 0; 585 int rval = 0; 586 587 prg.barnum = 0; /* Config space. */ 588 589 /* Must read in 4-byte quantities. */ 590 prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_4 + NATIVE_ENDIAN; 591 592 prg.data = 0; 593 594 /* 595 * Loop through all valid bus / dev / func combinations to check for 596 * all devices, with the following exceptions: 597 * 598 * When nothing is found at function 0 of a bus / dev combination, skip 599 * the other functions of that bus / dev combination. 600 * 601 * When a found device's function 0 is probed and it is determined that 602 * it is not a multifunction device, skip probing of that device's 603 * other functions. 604 */ 605 for (bus = first_bus; ((bus <= last_bus) && (rval == 0)); bus++) { 606 prg.bus_no = (uint8_t)bus; 607 for (dev = first_dev; 608 ((dev <= last_dev) && (rval == 0)); dev++) { 609 prg.dev_no = dev; 610 rval = probe_dev(nexus, &prg, pci_sys); 611 } 612 613 /* 614 * Ultra-45 southbridge workaround: 615 * ECANCELED tells to skip to the next bus. 616 */ 617 if (rval == ECANCELED) { 618 rval = 0; 619 } 620 } 621 if (pci_sys->num_devices > MAX_DEVICES) { 622 (void) fprintf(stderr, "pci devices reach maximum number\n"); 623 } 624 625 return (rval); 626 } 627 628 static int 629 find_target_node(di_node_t node, void *arg) 630 { 631 int *regbuf = NULL; 632 int len = 0; 633 uint32_t busno, funcno, devno; 634 i_devnode_t *devnode; 635 void *prop = DI_PROP_NIL; 636 int i; 637 638 devnode = (i_devnode_t *)arg; 639 640 /* 641 * Test the property functions, only for testing 642 */ 643 /* 644 (void) fprintf(stderr, "start of node 0x%x\n", node->nodeid); 645 while ((prop = di_prop_hw_next(node, prop)) != DI_PROP_NIL) { 646 (void) fprintf(stderr, "name=%s: ", di_prop_name(prop)); 647 len = 0; 648 if (!strcmp(di_prop_name(prop), "reg")) { 649 len = di_prop_ints(prop, ®buf); 650 } 651 for (i = 0; i < len; i++) { 652 fprintf(stderr, "0x%0x.", regbuf[i]); 653 } 654 fprintf(stderr, "\n"); 655 } 656 (void) fprintf(stderr, "end of node 0x%x\n", node->nodeid); 657 */ 658 659 len = di_prop_lookup_ints(DDI_DEV_T_ANY, node, "reg", 660 ®buf); 661 662 if (len <= 0) { 663 #if DEBUGON 664 fprintf(stderr, "error = %x\n", errno); 665 fprintf(stderr, "can not find assigned-address\n"); 666 #endif 667 return (DI_WALK_CONTINUE); 668 } 669 busno = PCI_REG_BUS_G(regbuf[0]); 670 devno = PCI_REG_DEV_G(regbuf[0]); 671 funcno = PCI_REG_FUNC_G(regbuf[0]); 672 673 if ((busno == devnode->bus) && 674 (devno == devnode->dev) && 675 (funcno == devnode->func)) { 676 devnode->node = node; 677 678 return (DI_WALK_TERMINATE); 679 } 680 681 return (DI_WALK_CONTINUE); 682 } 683 684 /* 685 * Solaris version 686 */ 687 static int 688 pci_device_solx_devfs_probe( struct pci_device * dev ) 689 { 690 uint8_t config[256]; 691 int err; 692 di_node_t rnode; 693 i_devnode_t args; 694 int *regbuf; 695 pci_regspec_t *reg; 696 int i; 697 pciaddr_t bytes; 698 int len = 0; 699 700 err = pci_device_solx_devfs_read( dev, config, 0, 256, & bytes ); 701 args.node = DI_NODE_NIL; 702 if ( bytes >= 64 ) { 703 struct pci_device_private *priv = 704 (struct pci_device_private *) dev; 705 706 dev->vendor_id = 707 (uint16_t)config[0] + ((uint16_t)config[1] << 8); 708 dev->device_id = 709 (uint16_t)config[2] + ((uint16_t)config[3] << 8); 710 dev->device_class = (uint32_t)config[9] + 711 ((uint32_t)config[10] << 8) + 712 ((uint16_t)config[11] << 16); 713 /* 714 * device class code is already there. 715 * see probe_dev function. 716 */ 717 dev->revision = config[8]; 718 dev->subvendor_id = 719 (uint16_t)config[44] + ((uint16_t)config[45] << 8); 720 dev->subdevice_id = 721 (uint16_t)config[46] + ((uint16_t)config[47] << 8); 722 dev->irq = config[60]; 723 724 priv->header_type = config[14]; 725 /* 726 * starting to find if it is MEM/MEM64/IO 727 * using libdevinfo 728 */ 729 if ((rnode = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) { 730 (void) fprintf(stderr, "di_init failed: %s\n", 731 strerror(errno)); 732 err = errno; 733 } else { 734 args.bus = dev->bus; 735 args.dev = dev->dev; 736 args.func = dev->func; 737 (void) di_walk_node(rnode, DI_WALK_CLDFIRST, 738 (void *)&args, find_target_node); 739 di_fini(rnode); 740 } 741 } 742 if (args.node != DI_NODE_NIL) { 743 /* 744 * It will success for sure, because it was 745 * successfully called in find_target_node 746 */ 747 len = di_prop_lookup_ints(DDI_DEV_T_ANY, args.node, 748 "assigned-addresses", 749 ®buf); 750 751 } 752 753 if (len <= 0) 754 return (err); 755 756 757 /* 758 * how to find the size of rom??? 759 * if the device has expansion rom, 760 * it must be listed in the last 761 * cells because solaris find probe 762 * the base address from offset 0x10 763 * to 0x30h. So only check the last 764 * item. 765 */ 766 reg = (pci_regspec_t *)®buf[len - CELL_NUMS_1275]; 767 if (PCI_REG_REG_G(reg->pci_phys_hi) == 768 PCI_CONF_ROM) { 769 /* 770 * rom can only be 32 bits 771 */ 772 dev->rom_size = reg->pci_size_low; 773 len = len - CELL_NUMS_1275; 774 } 775 else { 776 /* 777 * size default to 64K and base address 778 * default to 0xC0000 779 */ 780 dev->rom_size = 0x10000; 781 } 782 783 /* 784 * solaris has its own BAR index. To be sure that 785 * Xorg has the same BAR number as solaris. ???? 786 */ 787 for (i = 0; i < len; i = i + CELL_NUMS_1275) { 788 int ent = i/CELL_NUMS_1275; 789 790 reg = (pci_regspec_t *)®buf[i]; 791 792 /* 793 * non relocatable resource is excluded 794 * such like 0xa0000, 0x3b0. If it is met, 795 * the loop is broken; 796 */ 797 if (!PCI_REG_REG_G(reg->pci_phys_hi)) 798 break; 799 800 801 if (reg->pci_phys_hi & PCI_PREFETCH_B) { 802 dev->regions[ent].is_prefetchable = 1; 803 } 804 805 switch (reg->pci_phys_hi & PCI_REG_ADDR_M) { 806 case PCI_ADDR_IO: 807 dev->regions[ent].is_IO = 1; 808 break; 809 case PCI_ADDR_MEM32: 810 break; 811 case PCI_ADDR_MEM64: 812 dev->regions[ent].is_64 = 1; 813 break; 814 } 815 /* 816 * We split the shift count 32 into two 16 to 817 * avoid the complaining of the compiler 818 */ 819 dev->regions[ent].base_addr = reg->pci_phys_low + 820 ((reg->pci_phys_mid << 16) << 16); 821 dev->regions[ent].size = reg->pci_size_low + 822 ((reg->pci_size_hi << 16) << 16); 823 } 824 825 826 return (err); 827 } 828 829 /* 830 * Solaris version: read the ROM data 831 */ 832 static int 833 pci_device_solx_devfs_read_rom( struct pci_device * dev, void * buffer ) 834 { 835 void *prom = MAP_FAILED; 836 837 if (xsvc_fd < 0) { 838 if ((xsvc_fd = open("/dev/xsvc", O_RDWR)) < 0) { 839 (void) fprintf(stderr, "can not open xsvc driver\n"); 840 841 return (-1); 842 } 843 } 844 845 prom = mmap(NULL, dev->rom_size, 846 PROT_READ, MAP_SHARED, 847 xsvc_fd, 0xC0000); 848 849 if (prom == MAP_FAILED) { 850 (void) fprintf(stderr, "map rom base =0xC0000 failed"); 851 return (-1); 852 } 853 (void) bcopy(prom, buffer, dev->rom_size); 854 855 856 /* 857 * Still used xsvc to do the user space mapping 858 */ 859 return (0); 860 861 } 862 863 /* 864 * solaris version: Read the configurations space of the devices 865 */ 866 static int 867 pci_device_solx_devfs_read( struct pci_device * dev, void * data, 868 pciaddr_t offset, pciaddr_t size, 869 pciaddr_t * bytes_read ) 870 { 871 pcitool_reg_t cfg_prg; 872 int err = 0; 873 int i = 0; 874 nexus_t *nexus = find_nexus_for_domain(dev->domain); 875 876 *bytes_read = 0; 877 878 if ( nexus == NULL ) { 879 return ENODEV; 880 } 881 882 cfg_prg.offset = offset; 883 cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_1 + NATIVE_ENDIAN; 884 cfg_prg.bus_no = dev->bus; 885 cfg_prg.dev_no = dev->dev; 886 cfg_prg.func_no = dev->func; 887 cfg_prg.barnum = 0; 888 cfg_prg.user_version = PCITOOL_USER_VERSION; 889 890 for (i = 0; i < size; i = i + PCITOOL_ACC_ATTR_SIZE(PCITOOL_ACC_ATTR_SIZE_1)) { 891 892 cfg_prg.offset = offset + i; 893 if ((err = ioctl(nexus->fd, PCITOOL_DEVICE_GET_REG, 894 &cfg_prg)) != 0) { 895 fprintf(stderr, "read bdf<%x,%x,%x,%llx> config space failure\n", 896 cfg_prg.bus_no, 897 cfg_prg.dev_no, 898 cfg_prg.func_no, 899 cfg_prg.offset); 900 fprintf(stderr, "Failure cause = %x\n", err); 901 break; 902 } 903 904 ((uint8_t *)data)[i] = (uint8_t)cfg_prg.data; 905 /* 906 * DWORDS Offset or bytes Offset ?? 907 */ 908 } 909 *bytes_read = i; 910 911 return (err); 912 } 913 914 /* 915 * Solaris version 916 */ 917 static int 918 pci_device_solx_devfs_write( struct pci_device * dev, const void * data, 919 pciaddr_t offset, pciaddr_t size, 920 pciaddr_t * bytes_written ) 921 { 922 pcitool_reg_t cfg_prg; 923 int err = 0; 924 int cmd; 925 nexus_t *nexus = find_nexus_for_domain(dev->domain); 926 927 if ( bytes_written != NULL ) { 928 *bytes_written = 0; 929 } 930 931 if ( nexus == NULL ) { 932 return ENODEV; 933 } 934 935 cfg_prg.offset = offset; 936 switch (size) { 937 case 1: 938 cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_1 + NATIVE_ENDIAN; 939 break; 940 case 2: 941 cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_2 + NATIVE_ENDIAN; 942 break; 943 case 4: 944 cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_4 + NATIVE_ENDIAN; 945 break; 946 case 8: 947 cfg_prg.acc_attr = PCITOOL_ACC_ATTR_SIZE_8 + NATIVE_ENDIAN; 948 break; 949 default: 950 assert(0); 951 952 } 953 cfg_prg.bus_no = dev->bus; 954 cfg_prg.dev_no = dev->dev; 955 cfg_prg.func_no = dev->func; 956 cfg_prg.barnum = 0; 957 cfg_prg.user_version = PCITOOL_USER_VERSION; 958 cfg_prg.data = *((uint64_t *)data); 959 /* 960 * Check if this device is bridge device. 961 * If it is, it is also a nexus node??? 962 * It seems that there is no explicit 963 * PCI nexus device for X86, so not applicable 964 * from pcitool_bus_reg_ops in pci_tools.c 965 */ 966 cmd = PCITOOL_DEVICE_SET_REG; 967 968 if ((err = ioctl(nexus->fd, cmd, &cfg_prg)) != 0) { 969 return (err); 970 } 971 *bytes_written = size; 972 973 return (err); 974 } 975 976 977 /** 978 * Map a memory region for a device using /dev/xsvc. 979 * 980 * \param dev Device whose memory region is to be mapped. 981 * \param map Parameters of the mapping that is to be created. 982 * 983 * \return 984 * Zero on success or an \c errno value on failure. 985 */ 986 static int 987 pci_device_solx_devfs_map_range(struct pci_device *dev, 988 struct pci_device_mapping *map) 989 { 990 const int prot = ((map->flags & PCI_DEV_MAP_FLAG_WRITABLE) != 0) 991 ? (PROT_READ | PROT_WRITE) : PROT_READ; 992 int err = 0; 993 994 995 if (xsvc_fd < 0) { 996 if ((xsvc_fd = open("/dev/xsvc", O_RDWR)) < 0) { 997 (void) fprintf(stderr, "can not open xsvc driver\n"); 998 return errno; 999 } 1000 } 1001 1002 map->memory = mmap(NULL, map->size, prot, MAP_SHARED, xsvc_fd, 1003 map->base); 1004 if (map->memory == MAP_FAILED) { 1005 err = errno; 1006 1007 (void) fprintf(stderr, "map rom region =%llx failed", 1008 map->base); 1009 } 1010 1011 return err; 1012 } 1013