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