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 2006 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 /* 29 * OPL CMU-CH PCI nexus driver. 30 * 31 */ 32 33 #include <sys/types.h> 34 #include <sys/sysmacros.h> 35 #include <sys/systm.h> 36 #include <sys/intreg.h> 37 #include <sys/intr.h> 38 #include <sys/machsystm.h> 39 #include <sys/conf.h> 40 #include <sys/stat.h> 41 #include <sys/kmem.h> 42 #include <sys/async.h> 43 #include <sys/ivintr.h> 44 #include <sys/sunddi.h> 45 #include <sys/sunndi.h> 46 #include <sys/ndifm.h> 47 #include <sys/ontrap.h> 48 #include <sys/ddi_impldefs.h> 49 #include <sys/ddi_subrdefs.h> 50 #include <sys/epm.h> 51 #include <sys/spl.h> 52 #include <sys/fm/util.h> 53 #include <sys/fm/util.h> 54 #include <sys/fm/protocol.h> 55 #include <sys/fm/io/pci.h> 56 #include <sys/fm/io/sun4upci.h> 57 #include <sys/pcicmu/pcicmu.h> 58 59 #include <sys/cmn_err.h> 60 #include <sys/time.h> 61 #include <sys/pci.h> 62 #include <sys/modctl.h> 63 #include <sys/open.h> 64 #include <sys/errno.h> 65 #include <sys/file.h> 66 67 68 uint32_t pcmu_spurintr_duration = 60000000; /* One minute */ 69 70 /* 71 * The variable controls the default setting of the command register 72 * for pci devices. See pcmu_init_child() for details. 73 * 74 * This flags also controls the setting of bits in the bridge control 75 * register pci to pci bridges. See pcmu_init_child() for details. 76 */ 77 ushort_t pcmu_command_default = PCI_COMM_SERR_ENABLE | 78 PCI_COMM_WAIT_CYC_ENAB | 79 PCI_COMM_PARITY_DETECT | 80 PCI_COMM_ME | 81 PCI_COMM_MAE | 82 PCI_COMM_IO; 83 /* 84 * The following driver parameters are defined as variables to allow 85 * patching for debugging and tuning. Flags that can be set on a per 86 * PBM basis are bit fields where the PBM device instance number maps 87 * to the bit position. 88 */ 89 #ifdef DEBUG 90 uint64_t pcmu_debug_flags = 0; 91 #endif 92 uint_t ecc_error_intr_enable = 1; 93 94 uint_t pcmu_ecc_afsr_retries = 100; /* XXX - what's a good value? */ 95 96 uint_t pcmu_intr_retry_intv = 5; /* for interrupt retry reg */ 97 uint_t pcmu_panic_on_fatal_errors = 1; /* should be 1 at beta */ 98 99 hrtime_t pcmu_intrpend_timeout = 5ll * NANOSEC; /* 5 seconds in nanoseconds */ 100 101 uint64_t pcmu_errtrig_pa = 0x0; 102 103 104 /* 105 * The following value is the number of consecutive unclaimed interrupts that 106 * will be tolerated for a particular ino_p before the interrupt is deemed to 107 * be jabbering and is blocked. 108 */ 109 uint_t pcmu_unclaimed_intr_max = 20; 110 111 /* 112 * function prototypes for dev ops routines: 113 */ 114 static int pcmu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd); 115 static int pcmu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd); 116 static int pcmu_info(dev_info_t *dip, ddi_info_cmd_t infocmd, 117 void *arg, void **result); 118 static int pcmu_open(dev_t *devp, int flags, int otyp, cred_t *credp); 119 static int pcmu_close(dev_t dev, int flags, int otyp, cred_t *credp); 120 static int pcmu_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 121 cred_t *credp, int *rvalp); 122 static int pcmu_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, 123 int flags, char *name, caddr_t valuep, int *lengthp); 124 static int pcmu_ctlops_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args); 125 static int pcmu_ctlops_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args, 126 void *result); 127 128 static int map_pcmu_registers(pcmu_t *, dev_info_t *); 129 static void unmap_pcmu_registers(pcmu_t *); 130 static void pcmu_pbm_clear_error(pcmu_pbm_t *); 131 132 static int pcmu_ctlops(dev_info_t *, dev_info_t *, ddi_ctl_enum_t, 133 void *, void *); 134 static int pcmu_map(dev_info_t *, dev_info_t *, ddi_map_req_t *, 135 off_t, off_t, caddr_t *); 136 static int pcmu_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t, 137 ddi_intr_handle_impl_t *, void *); 138 139 static uint32_t pcmu_identity_init(pcmu_t *pcmu_p); 140 static int pcmu_intr_setup(pcmu_t *pcmu_p); 141 static void pcmu_pbm_errstate_get(pcmu_t *pcmu_p, 142 pcmu_pbm_errstate_t *pbm_err_p); 143 static int pcmu_obj_setup(pcmu_t *pcmu_p); 144 static void pcmu_obj_destroy(pcmu_t *pcmu_p); 145 static void pcmu_obj_resume(pcmu_t *pcmu_p); 146 static void pcmu_obj_suspend(pcmu_t *pcmu_p); 147 148 static void u2u_ittrans_init(pcmu_t *, u2u_ittrans_data_t **); 149 static void u2u_ittrans_resume(u2u_ittrans_data_t **); 150 static void u2u_ittrans_uninit(u2u_ittrans_data_t *); 151 152 static pcmu_ksinfo_t *pcmu_name_kstat; 153 154 /* 155 * bus ops and dev ops structures: 156 */ 157 static struct bus_ops pcmu_bus_ops = { 158 BUSO_REV, 159 pcmu_map, 160 0, 161 0, 162 0, 163 i_ddi_map_fault, 164 0, 165 0, 166 0, 167 0, 168 0, 169 0, 170 0, 171 0, 172 pcmu_ctlops, 173 ddi_bus_prop_op, 174 ndi_busop_get_eventcookie, /* (*bus_get_eventcookie)(); */ 175 ndi_busop_add_eventcall, /* (*bus_add_eventcall)(); */ 176 ndi_busop_remove_eventcall, /* (*bus_remove_eventcall)(); */ 177 ndi_post_event, /* (*bus_post_event)(); */ 178 NULL, /* (*bus_intr_ctl)(); */ 179 NULL, /* (*bus_config)(); */ 180 NULL, /* (*bus_unconfig)(); */ 181 NULL, /* (*bus_fm_init)(); */ 182 NULL, /* (*bus_fm_fini)(); */ 183 NULL, /* (*bus_fm_access_enter)(); */ 184 NULL, /* (*bus_fm_access_fini)(); */ 185 NULL, /* (*bus_power)(); */ 186 pcmu_intr_ops /* (*bus_intr_op)(); */ 187 }; 188 189 struct cb_ops pcmu_cb_ops = { 190 pcmu_open, /* open */ 191 pcmu_close, /* close */ 192 nodev, /* strategy */ 193 nodev, /* print */ 194 nodev, /* dump */ 195 nodev, /* read */ 196 nodev, /* write */ 197 pcmu_ioctl, /* ioctl */ 198 nodev, /* devmap */ 199 nodev, /* mmap */ 200 nodev, /* segmap */ 201 nochpoll, /* poll */ 202 pcmu_prop_op, /* cb_prop_op */ 203 NULL, /* streamtab */ 204 D_NEW | D_MP | D_HOTPLUG, /* Driver compatibility flag */ 205 CB_REV, /* rev */ 206 nodev, /* int (*cb_aread)() */ 207 nodev /* int (*cb_awrite)() */ 208 }; 209 210 static struct dev_ops pcmu_ops = { 211 DEVO_REV, 212 0, 213 pcmu_info, 214 nulldev, 215 0, 216 pcmu_attach, 217 pcmu_detach, 218 nodev, 219 &pcmu_cb_ops, 220 &pcmu_bus_ops, 221 0 222 }; 223 224 /* 225 * module definitions: 226 */ 227 extern struct mod_ops mod_driverops; 228 229 static struct modldrv modldrv = { 230 &mod_driverops, /* Type of module - driver */ 231 "OPL CMU-CH PCI Nexus driver %I%", /* Name of module. */ 232 &pcmu_ops, /* driver ops */ 233 }; 234 235 static struct modlinkage modlinkage = { 236 MODREV_1, (void *)&modldrv, NULL 237 }; 238 239 /* 240 * driver global data: 241 */ 242 void *per_pcmu_state; /* per-pbm soft state pointer */ 243 kmutex_t pcmu_global_mutex; /* attach/detach common struct lock */ 244 errorq_t *pcmu_ecc_queue = NULL; /* per-system ecc handling queue */ 245 246 extern void pcmu_child_cfg_save(dev_info_t *dip); 247 extern void pcmu_child_cfg_restore(dev_info_t *dip); 248 249 int 250 _init(void) 251 { 252 int e; 253 254 /* 255 * Initialize per-pci bus soft state pointer. 256 */ 257 e = ddi_soft_state_init(&per_pcmu_state, sizeof (pcmu_t), 1); 258 if (e != 0) 259 return (e); 260 261 /* 262 * Initialize global mutexes. 263 */ 264 mutex_init(&pcmu_global_mutex, NULL, MUTEX_DRIVER, NULL); 265 266 /* 267 * Create the performance kstats. 268 */ 269 pcmu_kstat_init(); 270 271 /* 272 * Install the module. 273 */ 274 e = mod_install(&modlinkage); 275 if (e != 0) { 276 ddi_soft_state_fini(&per_pcmu_state); 277 mutex_destroy(&pcmu_global_mutex); 278 } 279 return (e); 280 } 281 282 int 283 _fini(void) 284 { 285 int e; 286 287 /* 288 * Remove the module. 289 */ 290 e = mod_remove(&modlinkage); 291 if (e != 0) { 292 return (e); 293 } 294 295 /* 296 * Destroy pcmu_ecc_queue, and set it to NULL. 297 */ 298 if (pcmu_ecc_queue) { 299 errorq_destroy(pcmu_ecc_queue); 300 pcmu_ecc_queue = NULL; 301 } 302 303 /* 304 * Destroy the performance kstats. 305 */ 306 pcmu_kstat_fini(); 307 308 /* 309 * Free the per-pci and per-CMU-CH soft state info and destroy 310 * mutex for per-CMU-CH soft state. 311 */ 312 ddi_soft_state_fini(&per_pcmu_state); 313 mutex_destroy(&pcmu_global_mutex); 314 return (e); 315 } 316 317 int 318 _info(struct modinfo *modinfop) 319 { 320 return (mod_info(&modlinkage, modinfop)); 321 } 322 323 /*ARGSUSED*/ 324 static int 325 pcmu_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 326 { 327 int instance = getminor((dev_t)arg) >> 8; 328 pcmu_t *pcmu_p = get_pcmu_soft_state(instance); 329 330 switch (infocmd) { 331 case DDI_INFO_DEVT2INSTANCE: 332 *result = (void *)(uintptr_t)instance; 333 return (DDI_SUCCESS); 334 335 case DDI_INFO_DEVT2DEVINFO: 336 if (pcmu_p == NULL) 337 return (DDI_FAILURE); 338 *result = (void *)pcmu_p->pcmu_dip; 339 return (DDI_SUCCESS); 340 341 default: 342 return (DDI_FAILURE); 343 } 344 } 345 346 347 /* device driver entry points */ 348 /* 349 * attach entry point: 350 */ 351 static int 352 pcmu_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) 353 { 354 pcmu_t *pcmu_p; 355 int instance = ddi_get_instance(dip); 356 357 switch (cmd) { 358 case DDI_ATTACH: 359 PCMU_DBG0(PCMU_DBG_ATTACH, dip, "DDI_ATTACH\n"); 360 361 /* 362 * Allocate and get the per-pci soft state structure. 363 */ 364 if (alloc_pcmu_soft_state(instance) != DDI_SUCCESS) { 365 cmn_err(CE_WARN, "%s%d: can't allocate pci state", 366 ddi_driver_name(dip), instance); 367 goto err_bad_pcmu_softstate; 368 } 369 pcmu_p = get_pcmu_soft_state(instance); 370 pcmu_p->pcmu_dip = dip; 371 mutex_init(&pcmu_p->pcmu_mutex, NULL, MUTEX_DRIVER, NULL); 372 pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_CLOSED; 373 pcmu_p->pcmu_open_count = 0; 374 375 /* 376 * Get key properties of the pci bridge node. 377 */ 378 if (get_pcmu_properties(pcmu_p, dip) == DDI_FAILURE) { 379 goto err_bad_pcmu_prop; 380 } 381 382 /* 383 * Map in the registers. 384 */ 385 if (map_pcmu_registers(pcmu_p, dip) == DDI_FAILURE) { 386 goto err_bad_reg_prop; 387 } 388 if (pcmu_obj_setup(pcmu_p) != DDI_SUCCESS) { 389 goto err_bad_objs; 390 } 391 392 if (ddi_create_minor_node(dip, "devctl", S_IFCHR, 393 (uint_t)instance<<8 | 0xff, 394 DDI_NT_NEXUS, 0) != DDI_SUCCESS) { 395 goto err_bad_devctl_node; 396 } 397 398 /* 399 * Due to unresolved hardware issues, disable PCIPM until 400 * the problem is fully understood. 401 * 402 * pcmu_pwr_setup(pcmu_p, dip); 403 */ 404 405 ddi_report_dev(dip); 406 407 pcmu_p->pcmu_state = PCMU_ATTACHED; 408 PCMU_DBG0(PCMU_DBG_ATTACH, dip, "attach success\n"); 409 break; 410 411 err_bad_objs: 412 ddi_remove_minor_node(dip, "devctl"); 413 err_bad_devctl_node: 414 unmap_pcmu_registers(pcmu_p); 415 err_bad_reg_prop: 416 free_pcmu_properties(pcmu_p); 417 err_bad_pcmu_prop: 418 mutex_destroy(&pcmu_p->pcmu_mutex); 419 free_pcmu_soft_state(instance); 420 err_bad_pcmu_softstate: 421 return (DDI_FAILURE); 422 423 case DDI_RESUME: 424 PCMU_DBG0(PCMU_DBG_ATTACH, dip, "DDI_RESUME\n"); 425 426 /* 427 * Make sure the CMU-CH control registers 428 * are configured properly. 429 */ 430 pcmu_p = get_pcmu_soft_state(instance); 431 mutex_enter(&pcmu_p->pcmu_mutex); 432 433 /* 434 * Make sure this instance has been suspended. 435 */ 436 if (pcmu_p->pcmu_state != PCMU_SUSPENDED) { 437 PCMU_DBG0(PCMU_DBG_ATTACH, dip, 438 "instance NOT suspended\n"); 439 mutex_exit(&pcmu_p->pcmu_mutex); 440 return (DDI_FAILURE); 441 } 442 pcmu_obj_resume(pcmu_p); 443 pcmu_p->pcmu_state = PCMU_ATTACHED; 444 445 pcmu_child_cfg_restore(dip); 446 447 mutex_exit(&pcmu_p->pcmu_mutex); 448 break; 449 450 default: 451 PCMU_DBG0(PCMU_DBG_ATTACH, dip, "unsupported attach op\n"); 452 return (DDI_FAILURE); 453 } 454 455 return (DDI_SUCCESS); 456 } 457 458 /* 459 * detach entry point: 460 */ 461 static int 462 pcmu_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) 463 { 464 int instance = ddi_get_instance(dip); 465 pcmu_t *pcmu_p = get_pcmu_soft_state(instance); 466 int len; 467 468 /* 469 * Make sure we are currently attached 470 */ 471 if (pcmu_p->pcmu_state != PCMU_ATTACHED) { 472 PCMU_DBG0(PCMU_DBG_ATTACH, dip, 473 "failed - instance not attached\n"); 474 return (DDI_FAILURE); 475 } 476 477 mutex_enter(&pcmu_p->pcmu_mutex); 478 479 switch (cmd) { 480 case DDI_DETACH: 481 PCMU_DBG0(PCMU_DBG_DETACH, dip, "DDI_DETACH\n"); 482 pcmu_obj_destroy(pcmu_p); 483 484 /* 485 * Free the pci soft state structure and the rest of the 486 * resources it's using. 487 */ 488 free_pcmu_properties(pcmu_p); 489 unmap_pcmu_registers(pcmu_p); 490 mutex_exit(&pcmu_p->pcmu_mutex); 491 mutex_destroy(&pcmu_p->pcmu_mutex); 492 free_pcmu_soft_state(instance); 493 494 /* Free the interrupt-priorities prop if we created it. */ 495 if (ddi_getproplen(DDI_DEV_T_ANY, dip, 496 DDI_PROP_NOTPROM | DDI_PROP_DONTPASS, 497 "interrupt-priorities", &len) == DDI_PROP_SUCCESS) { 498 (void) ddi_prop_remove(DDI_DEV_T_NONE, dip, 499 "interrupt-priorities"); 500 } 501 return (DDI_SUCCESS); 502 503 case DDI_SUSPEND: 504 pcmu_child_cfg_save(dip); 505 pcmu_obj_suspend(pcmu_p); 506 pcmu_p->pcmu_state = PCMU_SUSPENDED; 507 508 mutex_exit(&pcmu_p->pcmu_mutex); 509 return (DDI_SUCCESS); 510 511 default: 512 PCMU_DBG0(PCMU_DBG_DETACH, dip, "unsupported detach op\n"); 513 mutex_exit(&pcmu_p->pcmu_mutex); 514 return (DDI_FAILURE); 515 } 516 } 517 518 519 /*LINTLIBRARY*/ 520 521 /* ARGSUSED3 */ 522 static int 523 pcmu_open(dev_t *devp, int flags, int otyp, cred_t *credp) 524 { 525 pcmu_t *pcmu_p; 526 527 if (otyp != OTYP_CHR) { 528 return (EINVAL); 529 } 530 531 /* 532 * Get the soft state structure for the device. 533 */ 534 pcmu_p = DEV_TO_SOFTSTATE(*devp); 535 if (pcmu_p == NULL) { 536 return (ENXIO); 537 } 538 539 /* 540 * Handle the open by tracking the device state. 541 */ 542 PCMU_DBG2(PCMU_DBG_OPEN, pcmu_p->pcmu_dip, 543 "devp=%x: flags=%x\n", devp, flags); 544 mutex_enter(&pcmu_p->pcmu_mutex); 545 if (flags & FEXCL) { 546 if (pcmu_p->pcmu_soft_state != PCMU_SOFT_STATE_CLOSED) { 547 mutex_exit(&pcmu_p->pcmu_mutex); 548 PCMU_DBG0(PCMU_DBG_OPEN, pcmu_p->pcmu_dip, "busy\n"); 549 return (EBUSY); 550 } 551 pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_OPEN_EXCL; 552 } else { 553 if (pcmu_p->pcmu_soft_state == PCMU_SOFT_STATE_OPEN_EXCL) { 554 mutex_exit(&pcmu_p->pcmu_mutex); 555 PCMU_DBG0(PCMU_DBG_OPEN, pcmu_p->pcmu_dip, "busy\n"); 556 return (EBUSY); 557 } 558 pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_OPEN; 559 } 560 pcmu_p->pcmu_open_count++; 561 mutex_exit(&pcmu_p->pcmu_mutex); 562 return (0); 563 } 564 565 566 /* ARGSUSED */ 567 static int 568 pcmu_close(dev_t dev, int flags, int otyp, cred_t *credp) 569 { 570 pcmu_t *pcmu_p; 571 572 if (otyp != OTYP_CHR) { 573 return (EINVAL); 574 } 575 576 pcmu_p = DEV_TO_SOFTSTATE(dev); 577 if (pcmu_p == NULL) { 578 return (ENXIO); 579 } 580 581 PCMU_DBG2(PCMU_DBG_CLOSE, pcmu_p->pcmu_dip, 582 "dev=%x: flags=%x\n", dev, flags); 583 mutex_enter(&pcmu_p->pcmu_mutex); 584 pcmu_p->pcmu_soft_state = PCMU_SOFT_STATE_CLOSED; 585 pcmu_p->pcmu_open_count = 0; 586 mutex_exit(&pcmu_p->pcmu_mutex); 587 return (0); 588 } 589 590 /* ARGSUSED */ 591 static int 592 pcmu_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, 593 cred_t *credp, int *rvalp) 594 { 595 pcmu_t *pcmu_p; 596 dev_info_t *dip; 597 struct devctl_iocdata *dcp; 598 uint_t bus_state; 599 int rv = 0; 600 601 pcmu_p = DEV_TO_SOFTSTATE(dev); 602 if (pcmu_p == NULL) { 603 return (ENXIO); 604 } 605 606 dip = pcmu_p->pcmu_dip; 607 PCMU_DBG2(PCMU_DBG_IOCTL, dip, "dev=%x: cmd=%x\n", dev, cmd); 608 609 /* 610 * We can use the generic implementation for these ioctls 611 */ 612 switch (cmd) { 613 case DEVCTL_DEVICE_GETSTATE: 614 case DEVCTL_DEVICE_ONLINE: 615 case DEVCTL_DEVICE_OFFLINE: 616 case DEVCTL_BUS_GETSTATE: 617 return (ndi_devctl_ioctl(dip, cmd, arg, mode, 0)); 618 } 619 620 /* 621 * read devctl ioctl data 622 */ 623 if (ndi_dc_allochdl((void *)arg, &dcp) != NDI_SUCCESS) 624 return (EFAULT); 625 626 switch (cmd) { 627 628 case DEVCTL_DEVICE_RESET: 629 PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_DEVICE_RESET\n"); 630 rv = ENOTSUP; 631 break; 632 633 634 case DEVCTL_BUS_QUIESCE: 635 PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_QUIESCE\n"); 636 if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS) { 637 if (bus_state == BUS_QUIESCED) { 638 break; 639 } 640 } 641 (void) ndi_set_bus_state(dip, BUS_QUIESCED); 642 break; 643 644 case DEVCTL_BUS_UNQUIESCE: 645 PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_UNQUIESCE\n"); 646 if (ndi_get_bus_state(dip, &bus_state) == NDI_SUCCESS) { 647 if (bus_state == BUS_ACTIVE) { 648 break; 649 } 650 } 651 (void) ndi_set_bus_state(dip, BUS_ACTIVE); 652 break; 653 654 case DEVCTL_BUS_RESET: 655 PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_RESET\n"); 656 rv = ENOTSUP; 657 break; 658 659 case DEVCTL_BUS_RESETALL: 660 PCMU_DBG0(PCMU_DBG_IOCTL, dip, "DEVCTL_BUS_RESETALL\n"); 661 rv = ENOTSUP; 662 break; 663 664 default: 665 rv = ENOTTY; 666 } 667 668 ndi_dc_freehdl(dcp); 669 return (rv); 670 } 671 672 static int pcmu_prop_op(dev_t dev, dev_info_t *dip, ddi_prop_op_t prop_op, 673 int flags, char *name, caddr_t valuep, int *lengthp) 674 { 675 return (ddi_prop_op(dev, dip, prop_op, flags, name, valuep, lengthp)); 676 } 677 /* bus driver entry points */ 678 679 /* 680 * bus map entry point: 681 * 682 * if map request is for an rnumber 683 * get the corresponding regspec from device node 684 * build a new regspec in our parent's format 685 * build a new map_req with the new regspec 686 * call up the tree to complete the mapping 687 */ 688 static int 689 pcmu_map(dev_info_t *dip, dev_info_t *rdip, ddi_map_req_t *mp, 690 off_t off, off_t len, caddr_t *addrp) 691 { 692 pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip)); 693 struct regspec p_regspec; 694 ddi_map_req_t p_mapreq; 695 int reglen, rval, r_no; 696 pci_regspec_t reloc_reg, *rp = &reloc_reg; 697 698 PCMU_DBG2(PCMU_DBG_MAP, dip, "rdip=%s%d:", 699 ddi_driver_name(rdip), ddi_get_instance(rdip)); 700 701 if (mp->map_flags & DDI_MF_USER_MAPPING) { 702 return (DDI_ME_UNIMPLEMENTED); 703 } 704 705 switch (mp->map_type) { 706 case DDI_MT_REGSPEC: 707 reloc_reg = *(pci_regspec_t *)mp->map_obj.rp; /* dup whole */ 708 break; 709 710 case DDI_MT_RNUMBER: 711 r_no = mp->map_obj.rnumber; 712 PCMU_DBG1(PCMU_DBG_MAP | PCMU_DBG_CONT, dip, " r#=%x", r_no); 713 714 if (ddi_getlongprop(DDI_DEV_T_NONE, rdip, DDI_PROP_DONTPASS, 715 "reg", (caddr_t)&rp, ®len) != DDI_SUCCESS) { 716 return (DDI_ME_RNUMBER_RANGE); 717 } 718 719 if (r_no < 0 || r_no >= reglen / sizeof (pci_regspec_t)) { 720 kmem_free(rp, reglen); 721 return (DDI_ME_RNUMBER_RANGE); 722 } 723 rp += r_no; 724 break; 725 726 default: 727 return (DDI_ME_INVAL); 728 } 729 PCMU_DBG0(PCMU_DBG_MAP | PCMU_DBG_CONT, dip, "\n"); 730 731 /* use "assigned-addresses" to relocate regspec within pci space */ 732 if (rval = pcmu_reloc_reg(dip, rdip, pcmu_p, rp)) { 733 goto done; 734 } 735 736 /* adjust regspec according to mapping request */ 737 if (len) { 738 rp->pci_size_low = (uint_t)len; 739 } 740 rp->pci_phys_low += off; 741 742 /* use "ranges" to translate relocated pci regspec into parent space */ 743 if (rval = pcmu_xlate_reg(pcmu_p, rp, &p_regspec)) { 744 goto done; 745 } 746 747 p_mapreq = *mp; /* dup the whole structure */ 748 p_mapreq.map_type = DDI_MT_REGSPEC; 749 p_mapreq.map_obj.rp = &p_regspec; 750 rval = ddi_map(dip, &p_mapreq, 0, 0, addrp); 751 752 done: 753 if (mp->map_type == DDI_MT_RNUMBER) { 754 kmem_free(rp - r_no, reglen); 755 } 756 return (rval); 757 } 758 759 #ifdef DEBUG 760 int pcmu_peekfault_cnt = 0; 761 int pcmu_pokefault_cnt = 0; 762 #endif /* DEBUG */ 763 764 static int 765 pcmu_do_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args) 766 { 767 pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p; 768 int err = DDI_SUCCESS; 769 on_trap_data_t otd; 770 771 mutex_enter(&pcbm_p->pcbm_pokeflt_mutex); 772 pcbm_p->pcbm_ontrap_data = &otd; 773 774 /* Set up protected environment. */ 775 if (!on_trap(&otd, OT_DATA_ACCESS)) { 776 uintptr_t tramp = otd.ot_trampoline; 777 778 otd.ot_trampoline = (uintptr_t)&poke_fault; 779 err = do_poke(in_args->size, (void *)in_args->dev_addr, 780 (void *)in_args->host_addr); 781 otd.ot_trampoline = tramp; 782 } else { 783 err = DDI_FAILURE; 784 } 785 786 /* 787 * Read the async fault register for the PBM to see it sees 788 * a master-abort. 789 */ 790 pcmu_pbm_clear_error(pcbm_p); 791 792 if (otd.ot_trap & OT_DATA_ACCESS) { 793 err = DDI_FAILURE; 794 } 795 796 /* Take down protected environment. */ 797 no_trap(); 798 799 pcbm_p->pcbm_ontrap_data = NULL; 800 mutex_exit(&pcbm_p->pcbm_pokeflt_mutex); 801 802 #ifdef DEBUG 803 if (err == DDI_FAILURE) 804 pcmu_pokefault_cnt++; 805 #endif 806 return (err); 807 } 808 809 810 static int 811 pcmu_ctlops_poke(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args) 812 { 813 return (pcmu_do_poke(pcmu_p, in_args)); 814 } 815 816 /* ARGSUSED */ 817 static int 818 pcmu_do_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args) 819 { 820 int err = DDI_SUCCESS; 821 on_trap_data_t otd; 822 823 if (!on_trap(&otd, OT_DATA_ACCESS)) { 824 uintptr_t tramp = otd.ot_trampoline; 825 826 otd.ot_trampoline = (uintptr_t)&peek_fault; 827 err = do_peek(in_args->size, (void *)in_args->dev_addr, 828 (void *)in_args->host_addr); 829 otd.ot_trampoline = tramp; 830 } else 831 err = DDI_FAILURE; 832 833 no_trap(); 834 835 #ifdef DEBUG 836 if (err == DDI_FAILURE) 837 pcmu_peekfault_cnt++; 838 #endif 839 return (err); 840 } 841 842 843 static int 844 pcmu_ctlops_peek(pcmu_t *pcmu_p, peekpoke_ctlops_t *in_args, void *result) 845 { 846 result = (void *)in_args->host_addr; 847 return (pcmu_do_peek(pcmu_p, in_args)); 848 } 849 850 /* 851 * control ops entry point: 852 * 853 * Requests handled completely: 854 * DDI_CTLOPS_INITCHILD see pcmu_init_child() for details 855 * DDI_CTLOPS_UNINITCHILD 856 * DDI_CTLOPS_REPORTDEV see report_dev() for details 857 * DDI_CTLOPS_XLATE_INTRS nothing to do 858 * DDI_CTLOPS_IOMIN cache line size if streaming otherwise 1 859 * DDI_CTLOPS_REGSIZE 860 * DDI_CTLOPS_NREGS 861 * DDI_CTLOPS_NINTRS 862 * DDI_CTLOPS_DVMAPAGESIZE 863 * DDI_CTLOPS_POKE 864 * DDI_CTLOPS_PEEK 865 * DDI_CTLOPS_QUIESCE 866 * DDI_CTLOPS_UNQUIESCE 867 * 868 * All others passed to parent. 869 */ 870 static int 871 pcmu_ctlops(dev_info_t *dip, dev_info_t *rdip, 872 ddi_ctl_enum_t op, void *arg, void *result) 873 { 874 pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip)); 875 876 switch (op) { 877 case DDI_CTLOPS_INITCHILD: 878 return (pcmu_init_child(pcmu_p, (dev_info_t *)arg)); 879 880 case DDI_CTLOPS_UNINITCHILD: 881 return (pcmu_uninit_child(pcmu_p, (dev_info_t *)arg)); 882 883 case DDI_CTLOPS_REPORTDEV: 884 return (pcmu_report_dev(rdip)); 885 886 case DDI_CTLOPS_IOMIN: 887 /* 888 * If we are using the streaming cache, align at 889 * least on a cache line boundary. Otherwise use 890 * whatever alignment is passed in. 891 */ 892 return (DDI_SUCCESS); 893 894 case DDI_CTLOPS_REGSIZE: 895 *((off_t *)result) = pcmu_get_reg_set_size(rdip, *((int *)arg)); 896 return (DDI_SUCCESS); 897 898 case DDI_CTLOPS_NREGS: 899 *((uint_t *)result) = pcmu_get_nreg_set(rdip); 900 return (DDI_SUCCESS); 901 902 case DDI_CTLOPS_DVMAPAGESIZE: 903 *((ulong_t *)result) = 0; 904 return (DDI_SUCCESS); 905 906 case DDI_CTLOPS_POKE: 907 return (pcmu_ctlops_poke(pcmu_p, (peekpoke_ctlops_t *)arg)); 908 909 case DDI_CTLOPS_PEEK: 910 return (pcmu_ctlops_peek(pcmu_p, (peekpoke_ctlops_t *)arg, 911 result)); 912 913 case DDI_CTLOPS_AFFINITY: 914 break; 915 916 case DDI_CTLOPS_QUIESCE: 917 return (DDI_FAILURE); 918 919 case DDI_CTLOPS_UNQUIESCE: 920 return (DDI_FAILURE); 921 922 default: 923 break; 924 } 925 926 /* 927 * Now pass the request up to our parent. 928 */ 929 PCMU_DBG2(PCMU_DBG_CTLOPS, dip, 930 "passing request to parent: rdip=%s%d\n", 931 ddi_driver_name(rdip), ddi_get_instance(rdip)); 932 return (ddi_ctlops(dip, rdip, op, arg, result)); 933 } 934 935 936 /* ARGSUSED */ 937 static int 938 pcmu_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t intr_op, 939 ddi_intr_handle_impl_t *hdlp, void *result) 940 { 941 pcmu_t *pcmu_p = get_pcmu_soft_state(ddi_get_instance(dip)); 942 int ret = DDI_SUCCESS; 943 944 switch (intr_op) { 945 case DDI_INTROP_GETCAP: 946 /* GetCap will always fail for all non PCI devices */ 947 (void) pci_intx_get_cap(rdip, (int *)result); 948 break; 949 case DDI_INTROP_SETCAP: 950 ret = DDI_ENOTSUP; 951 break; 952 case DDI_INTROP_ALLOC: 953 *(int *)result = hdlp->ih_scratch1; 954 break; 955 case DDI_INTROP_FREE: 956 break; 957 case DDI_INTROP_GETPRI: 958 *(int *)result = hdlp->ih_pri ? hdlp->ih_pri : 0; 959 break; 960 case DDI_INTROP_SETPRI: 961 break; 962 case DDI_INTROP_ADDISR: 963 ret = pcmu_add_intr(dip, rdip, hdlp); 964 break; 965 case DDI_INTROP_REMISR: 966 ret = pcmu_remove_intr(dip, rdip, hdlp); 967 break; 968 case DDI_INTROP_ENABLE: 969 ret = pcmu_ib_update_intr_state(pcmu_p, rdip, hdlp, 970 PCMU_INTR_STATE_ENABLE); 971 break; 972 case DDI_INTROP_DISABLE: 973 ret = pcmu_ib_update_intr_state(pcmu_p, rdip, hdlp, 974 PCMU_INTR_STATE_DISABLE); 975 break; 976 case DDI_INTROP_SETMASK: 977 ret = pci_intx_set_mask(rdip); 978 break; 979 case DDI_INTROP_CLRMASK: 980 ret = pci_intx_clr_mask(rdip); 981 break; 982 case DDI_INTROP_GETPENDING: 983 ret = pci_intx_get_pending(rdip, (int *)result); 984 break; 985 case DDI_INTROP_NINTRS: 986 case DDI_INTROP_NAVAIL: 987 *(int *)result = i_ddi_get_nintrs(rdip); 988 break; 989 case DDI_INTROP_SUPPORTED_TYPES: 990 /* PCI nexus driver supports only fixed interrupts */ 991 *(int *)result = i_ddi_get_nintrs(rdip) ? 992 DDI_INTR_TYPE_FIXED : 0; 993 break; 994 default: 995 ret = DDI_ENOTSUP; 996 break; 997 } 998 999 return (ret); 1000 } 1001 1002 /* 1003 * CMU-CH specifics implementation: 1004 * interrupt mapping register 1005 * PBM configuration 1006 * ECC and PBM error handling 1007 */ 1008 1009 /* called by pcmu_attach() DDI_ATTACH to initialize pci objects */ 1010 static int 1011 pcmu_obj_setup(pcmu_t *pcmu_p) 1012 { 1013 int ret; 1014 1015 mutex_enter(&pcmu_global_mutex); 1016 pcmu_p->pcmu_rev = ddi_prop_get_int(DDI_DEV_T_ANY, pcmu_p->pcmu_dip, 1017 DDI_PROP_DONTPASS, "module-revision#", 0); 1018 1019 pcmu_ib_create(pcmu_p); 1020 pcmu_cb_create(pcmu_p); 1021 pcmu_ecc_create(pcmu_p); 1022 pcmu_pbm_create(pcmu_p); 1023 pcmu_err_create(pcmu_p); 1024 if ((ret = pcmu_intr_setup(pcmu_p)) != DDI_SUCCESS) 1025 goto done; 1026 1027 pcmu_kstat_create(pcmu_p); 1028 done: 1029 mutex_exit(&pcmu_global_mutex); 1030 if (ret != DDI_SUCCESS) { 1031 cmn_err(CE_NOTE, "Interrupt register failure, returning 0x%x\n", 1032 ret); 1033 } 1034 return (ret); 1035 } 1036 1037 /* called by pcmu_detach() DDI_DETACH to destroy pci objects */ 1038 static void 1039 pcmu_obj_destroy(pcmu_t *pcmu_p) 1040 { 1041 mutex_enter(&pcmu_global_mutex); 1042 1043 pcmu_kstat_destroy(pcmu_p); 1044 pcmu_pbm_destroy(pcmu_p); 1045 pcmu_err_destroy(pcmu_p); 1046 pcmu_ecc_destroy(pcmu_p); 1047 pcmu_cb_destroy(pcmu_p); 1048 pcmu_ib_destroy(pcmu_p); 1049 pcmu_intr_teardown(pcmu_p); 1050 1051 mutex_exit(&pcmu_global_mutex); 1052 } 1053 1054 /* called by pcmu_attach() DDI_RESUME to (re)initialize pci objects */ 1055 static void 1056 pcmu_obj_resume(pcmu_t *pcmu_p) 1057 { 1058 mutex_enter(&pcmu_global_mutex); 1059 1060 pcmu_ib_configure(pcmu_p->pcmu_ib_p); 1061 pcmu_ecc_configure(pcmu_p); 1062 pcmu_ib_resume(pcmu_p->pcmu_ib_p); 1063 u2u_ittrans_resume((u2u_ittrans_data_t **) 1064 &(pcmu_p->pcmu_cb_p->pcb_ittrans_cookie)); 1065 1066 pcmu_pbm_configure(pcmu_p->pcmu_pcbm_p); 1067 1068 pcmu_cb_resume(pcmu_p->pcmu_cb_p); 1069 1070 pcmu_pbm_resume(pcmu_p->pcmu_pcbm_p); 1071 1072 mutex_exit(&pcmu_global_mutex); 1073 } 1074 1075 /* called by pcmu_detach() DDI_SUSPEND to suspend pci objects */ 1076 static void 1077 pcmu_obj_suspend(pcmu_t *pcmu_p) 1078 { 1079 mutex_enter(&pcmu_global_mutex); 1080 1081 pcmu_pbm_suspend(pcmu_p->pcmu_pcbm_p); 1082 pcmu_ib_suspend(pcmu_p->pcmu_ib_p); 1083 pcmu_cb_suspend(pcmu_p->pcmu_cb_p); 1084 1085 mutex_exit(&pcmu_global_mutex); 1086 } 1087 1088 static int 1089 pcmu_intr_setup(pcmu_t *pcmu_p) 1090 { 1091 dev_info_t *dip = pcmu_p->pcmu_dip; 1092 pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p; 1093 pcmu_cb_t *pcb_p = pcmu_p->pcmu_cb_p; 1094 int i, no_of_intrs; 1095 1096 /* 1097 * Get the interrupts property. 1098 */ 1099 if (ddi_getlongprop(DDI_DEV_T_NONE, dip, DDI_PROP_DONTPASS, 1100 "interrupts", (caddr_t)&pcmu_p->pcmu_inos, 1101 &pcmu_p->pcmu_inos_len) != DDI_SUCCESS) { 1102 cmn_err(CE_PANIC, "%s%d: no interrupts property\n", 1103 ddi_driver_name(dip), ddi_get_instance(dip)); 1104 } 1105 1106 /* 1107 * figure out number of interrupts in the "interrupts" property 1108 * and convert them all into ino. 1109 */ 1110 i = ddi_getprop(DDI_DEV_T_ANY, dip, 0, "#interrupt-cells", 1); 1111 i = CELLS_1275_TO_BYTES(i); 1112 no_of_intrs = pcmu_p->pcmu_inos_len / i; 1113 for (i = 0; i < no_of_intrs; i++) { 1114 pcmu_p->pcmu_inos[i] = 1115 PCMU_IB_MONDO_TO_INO(pcmu_p->pcmu_inos[i]); 1116 } 1117 1118 pcb_p->pcb_no_of_inos = no_of_intrs; 1119 if (i = pcmu_ecc_register_intr(pcmu_p)) { 1120 goto teardown; 1121 } 1122 1123 intr_dist_add(pcmu_cb_intr_dist, pcb_p); 1124 pcmu_ecc_enable_intr(pcmu_p); 1125 1126 if (i = pcmu_pbm_register_intr(pcbm_p)) { 1127 intr_dist_rem(pcmu_cb_intr_dist, pcb_p); 1128 goto teardown; 1129 } 1130 intr_dist_add(pcmu_pbm_intr_dist, pcbm_p); 1131 pcmu_ib_intr_enable(pcmu_p, pcmu_p->pcmu_inos[CBNINTR_PBM]); 1132 1133 intr_dist_add_weighted(pcmu_ib_intr_dist_all, pcmu_p->pcmu_ib_p); 1134 return (DDI_SUCCESS); 1135 teardown: 1136 pcmu_intr_teardown(pcmu_p); 1137 return (i); 1138 } 1139 1140 /* 1141 * pcmu_fix_ranges - fixes the config space entry of the "ranges" 1142 * property on CMU-CH platforms 1143 */ 1144 void 1145 pcmu_fix_ranges(pcmu_ranges_t *rng_p, int rng_entries) 1146 { 1147 int i; 1148 for (i = 0; i < rng_entries; i++, rng_p++) { 1149 if ((rng_p->child_high & PCI_REG_ADDR_M) == PCI_ADDR_CONFIG) 1150 rng_p->parent_low |= rng_p->child_high; 1151 } 1152 } 1153 1154 /* 1155 * map_pcmu_registers 1156 * 1157 * This function is called from the attach routine to map the registers 1158 * accessed by this driver. 1159 * 1160 * used by: pcmu_attach() 1161 * 1162 * return value: DDI_FAILURE on failure 1163 */ 1164 static int 1165 map_pcmu_registers(pcmu_t *pcmu_p, dev_info_t *dip) 1166 { 1167 ddi_device_acc_attr_t attr; 1168 1169 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1170 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1171 1172 attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 1173 if (ddi_regs_map_setup(dip, 0, &pcmu_p->pcmu_address[0], 0, 0, 1174 &attr, &pcmu_p->pcmu_ac[0]) != DDI_SUCCESS) { 1175 cmn_err(CE_WARN, "%s%d: unable to map reg entry 0\n", 1176 ddi_driver_name(dip), ddi_get_instance(dip)); 1177 return (DDI_FAILURE); 1178 } 1179 1180 /* 1181 * We still use pcmu_address[2] 1182 */ 1183 if (ddi_regs_map_setup(dip, 2, &pcmu_p->pcmu_address[2], 0, 0, 1184 &attr, &pcmu_p->pcmu_ac[2]) != DDI_SUCCESS) { 1185 cmn_err(CE_WARN, "%s%d: unable to map reg entry 2\n", 1186 ddi_driver_name(dip), ddi_get_instance(dip)); 1187 ddi_regs_map_free(&pcmu_p->pcmu_ac[0]); 1188 return (DDI_FAILURE); 1189 } 1190 1191 /* 1192 * The second register set contains the bridge's configuration 1193 * header. This header is at the very beginning of the bridge's 1194 * configuration space. This space has litte-endian byte order. 1195 */ 1196 attr.devacc_attr_endian_flags = DDI_STRUCTURE_LE_ACC; 1197 if (ddi_regs_map_setup(dip, 1, &pcmu_p->pcmu_address[1], 0, 1198 PCI_CONF_HDR_SIZE, &attr, &pcmu_p->pcmu_ac[1]) != DDI_SUCCESS) { 1199 1200 cmn_err(CE_WARN, "%s%d: unable to map reg entry 1\n", 1201 ddi_driver_name(dip), ddi_get_instance(dip)); 1202 ddi_regs_map_free(&pcmu_p->pcmu_ac[0]); 1203 return (DDI_FAILURE); 1204 } 1205 PCMU_DBG2(PCMU_DBG_ATTACH, dip, "address (%p,%p)\n", 1206 pcmu_p->pcmu_address[0], pcmu_p->pcmu_address[1]); 1207 return (DDI_SUCCESS); 1208 } 1209 1210 /* 1211 * unmap_pcmu_registers: 1212 * 1213 * This routine unmap the registers mapped by map_pcmu_registers. 1214 * 1215 * used by: pcmu_detach() 1216 * 1217 * return value: none 1218 */ 1219 static void 1220 unmap_pcmu_registers(pcmu_t *pcmu_p) 1221 { 1222 ddi_regs_map_free(&pcmu_p->pcmu_ac[0]); 1223 ddi_regs_map_free(&pcmu_p->pcmu_ac[1]); 1224 ddi_regs_map_free(&pcmu_p->pcmu_ac[2]); 1225 } 1226 1227 /* 1228 * These convenience wrappers relies on map_pcmu_registers() to setup 1229 * pcmu_address[0-2] correctly at first. 1230 */ 1231 static uintptr_t 1232 get_reg_base(pcmu_t *pcmu_p) 1233 { 1234 return ((uintptr_t)pcmu_p->pcmu_address[2]); 1235 } 1236 1237 /* The CMU-CH config reg base is always the 2nd reg entry */ 1238 static uintptr_t 1239 get_config_reg_base(pcmu_t *pcmu_p) 1240 { 1241 return ((uintptr_t)(pcmu_p->pcmu_address[1])); 1242 } 1243 1244 uint64_t 1245 ib_get_map_reg(pcmu_ib_mondo_t mondo, uint32_t cpu_id) 1246 { 1247 return ((mondo) | (cpu_id << PCMU_INTR_MAP_REG_TID_SHIFT) | 1248 PCMU_INTR_MAP_REG_VALID); 1249 1250 } 1251 1252 uint32_t 1253 ib_map_reg_get_cpu(volatile uint64_t reg) 1254 { 1255 return ((reg & PCMU_INTR_MAP_REG_TID) >> 1256 PCMU_INTR_MAP_REG_TID_SHIFT); 1257 } 1258 1259 uint64_t * 1260 ib_intr_map_reg_addr(pcmu_ib_t *pib_p, pcmu_ib_ino_t ino) 1261 { 1262 uint64_t *addr; 1263 1264 ASSERT(ino & 0x20); 1265 addr = (uint64_t *)(pib_p->pib_obio_intr_map_regs + 1266 (((uint_t)ino & 0x1f) << 3)); 1267 return (addr); 1268 } 1269 1270 uint64_t * 1271 ib_clear_intr_reg_addr(pcmu_ib_t *pib_p, pcmu_ib_ino_t ino) 1272 { 1273 uint64_t *addr; 1274 1275 ASSERT(ino & 0x20); 1276 addr = (uint64_t *)(pib_p->pib_obio_clear_intr_regs + 1277 (((uint_t)ino & 0x1f) << 3)); 1278 return (addr); 1279 } 1280 1281 uintptr_t 1282 pcmu_ib_setup(pcmu_ib_t *pib_p) 1283 { 1284 pcmu_t *pcmu_p = pib_p->pib_pcmu_p; 1285 uintptr_t a = get_reg_base(pcmu_p); 1286 1287 pib_p->pib_ign = PCMU_ID_TO_IGN(pcmu_p->pcmu_id); 1288 pib_p->pib_max_ino = PCMU_MAX_INO; 1289 pib_p->pib_obio_intr_map_regs = a + PCMU_IB_OBIO_INTR_MAP_REG_OFFSET; 1290 pib_p->pib_obio_clear_intr_regs = 1291 a + PCMU_IB_OBIO_CLEAR_INTR_REG_OFFSET; 1292 return (a); 1293 } 1294 1295 /* 1296 * Return the cpuid to to be used for an ino. 1297 * 1298 * On multi-function pci devices, functions have separate devinfo nodes and 1299 * interrupts. 1300 * 1301 * This function determines if there is already an established slot-oriented 1302 * interrupt-to-cpu binding established, if there is then it returns that 1303 * cpu. Otherwise a new cpu is selected by intr_dist_cpuid(). 1304 * 1305 * The devinfo node we are trying to associate a cpu with is 1306 * ino_p->pino_ih_head->ih_dip. 1307 */ 1308 uint32_t 1309 pcmu_intr_dist_cpuid(pcmu_ib_t *pib_p, pcmu_ib_ino_info_t *ino_p) 1310 { 1311 dev_info_t *rdip = ino_p->pino_ih_head->ih_dip; 1312 dev_info_t *prdip = ddi_get_parent(rdip); 1313 pcmu_ib_ino_info_t *sino_p; 1314 dev_info_t *sdip; 1315 dev_info_t *psdip; 1316 char *buf1 = NULL, *buf2 = NULL; 1317 char *s1, *s2, *s3; 1318 int l2; 1319 int cpu_id; 1320 1321 /* must be CMU-CH driver parent (not ebus) */ 1322 if (strcmp(ddi_driver_name(prdip), "pcicmu") != 0) 1323 goto newcpu; 1324 1325 /* 1326 * From PCI 1275 binding: 2.2.1.3 Unit Address representation: 1327 * Since the "unit-number" is the address that appears in on Open 1328 * Firmware 'device path', it follows that only the DD and DD,FF 1329 * forms of the text representation can appear in a 'device path'. 1330 * 1331 * The rdip unit address is of the form "DD[,FF]". Define two 1332 * unit address strings that represent same-slot use: "DD" and "DD,". 1333 * The first compare uses strcmp, the second uses strncmp. 1334 */ 1335 s1 = ddi_get_name_addr(rdip); 1336 if (s1 == NULL) { 1337 goto newcpu; 1338 } 1339 1340 buf1 = kmem_alloc(MAXNAMELEN, KM_SLEEP); /* strcmp */ 1341 buf2 = kmem_alloc(MAXNAMELEN, KM_SLEEP); /* strncmp */ 1342 s1 = strcpy(buf1, s1); 1343 s2 = strcpy(buf2, s1); 1344 1345 s1 = strrchr(s1, ','); 1346 if (s1) { 1347 *s1 = '\0'; /* have "DD,FF" */ 1348 s1 = buf1; /* search via strcmp "DD" */ 1349 1350 s2 = strrchr(s2, ','); 1351 *(s2 + 1) = '\0'; 1352 s2 = buf2; 1353 l2 = strlen(s2); /* search via strncmp "DD," */ 1354 } else { 1355 (void) strcat(s2, ","); /* have "DD" */ 1356 l2 = strlen(s2); /* search via strncmp "DD," */ 1357 } 1358 1359 /* 1360 * Search the established ino list for devinfo nodes bound 1361 * to an ino that matches one of the slot use strings. 1362 */ 1363 ASSERT(MUTEX_HELD(&pib_p->pib_ino_lst_mutex)); 1364 for (sino_p = pib_p->pib_ino_lst; sino_p; sino_p = sino_p->pino_next) { 1365 /* skip self and non-established */ 1366 if ((sino_p == ino_p) || (sino_p->pino_established == 0)) 1367 continue; 1368 1369 /* skip non-siblings */ 1370 sdip = sino_p->pino_ih_head->ih_dip; 1371 psdip = ddi_get_parent(sdip); 1372 if (psdip != prdip) 1373 continue; 1374 1375 /* must be CMU-CH driver parent (not ebus) */ 1376 if (strcmp(ddi_driver_name(psdip), "pcicmu") != 0) 1377 continue; 1378 1379 s3 = ddi_get_name_addr(sdip); 1380 if ((s1 && (strcmp(s1, s3) == 0)) || 1381 (strncmp(s2, s3, l2) == 0)) { 1382 extern int intr_dist_debug; 1383 1384 if (intr_dist_debug) { 1385 cmn_err(CE_CONT, "intr_dist: " 1386 "pcicmu`pcmu_intr_dist_cpuid " 1387 "%s#%d %s: cpu %d established " 1388 "by %s#%d %s\n", ddi_driver_name(rdip), 1389 ddi_get_instance(rdip), 1390 ddi_deviname(rdip, buf1), 1391 sino_p->pino_cpuid, 1392 ddi_driver_name(sdip), 1393 ddi_get_instance(sdip), 1394 ddi_deviname(sdip, buf2)); 1395 } 1396 break; 1397 } 1398 } 1399 1400 /* If a slot use match is found then use established cpu */ 1401 if (sino_p) { 1402 cpu_id = sino_p->pino_cpuid; /* target established cpu */ 1403 goto out; 1404 } 1405 1406 newcpu: cpu_id = intr_dist_cpuid(); /* target new cpu */ 1407 1408 out: if (buf1) 1409 kmem_free(buf1, MAXNAMELEN); 1410 if (buf2) 1411 kmem_free(buf2, MAXNAMELEN); 1412 return (cpu_id); 1413 } 1414 1415 void 1416 pcmu_cb_teardown(pcmu_t *pcmu_p) 1417 { 1418 pcmu_cb_t *pcb_p = pcmu_p->pcmu_cb_p; 1419 1420 u2u_ittrans_uninit((u2u_ittrans_data_t *)pcb_p->pcb_ittrans_cookie); 1421 } 1422 1423 int 1424 pcmu_ecc_add_intr(pcmu_t *pcmu_p, int inum, pcmu_ecc_intr_info_t *eii_p) 1425 { 1426 uint32_t mondo; 1427 1428 mondo = ((pcmu_p->pcmu_cb_p->pcb_ign << PCMU_INO_BITS) | 1429 pcmu_p->pcmu_inos[inum]); 1430 1431 VERIFY(add_ivintr(mondo, pcmu_pil[inum], pcmu_ecc_intr, 1432 (caddr_t)eii_p, NULL) == 0); 1433 return (PCMU_ATTACH_RETCODE(PCMU_ECC_OBJ, 1434 PCMU_OBJ_INTR_ADD, DDI_SUCCESS)); 1435 } 1436 1437 /* ARGSUSED */ 1438 void 1439 pcmu_ecc_rem_intr(pcmu_t *pcmu_p, int inum, pcmu_ecc_intr_info_t *eii_p) 1440 { 1441 uint32_t mondo; 1442 1443 mondo = ((pcmu_p->pcmu_cb_p->pcb_ign << PCMU_INO_BITS) | 1444 pcmu_p->pcmu_inos[inum]); 1445 rem_ivintr(mondo, NULL); 1446 } 1447 1448 void 1449 pcmu_pbm_configure(pcmu_pbm_t *pcbm_p) 1450 { 1451 pcmu_t *pcmu_p = pcbm_p->pcbm_pcmu_p; 1452 dev_info_t *dip = pcmu_p->pcmu_dip; 1453 1454 #define pbm_err ((PCMU_PCI_AFSR_E_MASK << PCMU_PCI_AFSR_PE_SHIFT) | \ 1455 (PCMU_PCI_AFSR_E_MASK << PCMU_PCI_AFSR_SE_SHIFT)) 1456 #define csr_err (PCI_STAT_PERROR | PCI_STAT_S_PERROR | \ 1457 PCI_STAT_R_MAST_AB | PCI_STAT_R_TARG_AB | \ 1458 PCI_STAT_S_TARG_AB | PCI_STAT_S_PERROR) 1459 1460 /* 1461 * Clear any PBM errors. 1462 */ 1463 *pcbm_p->pcbm_async_flt_status_reg = pbm_err; 1464 1465 /* 1466 * Clear error bits in configuration status register. 1467 */ 1468 PCMU_DBG1(PCMU_DBG_ATTACH, dip, 1469 "pcmu_pbm_configure: conf status reg=%x\n", csr_err); 1470 1471 pcbm_p->pcbm_config_header->ch_status_reg = csr_err; 1472 1473 PCMU_DBG1(PCMU_DBG_ATTACH, dip, 1474 "pcmu_pbm_configure: conf status reg==%x\n", 1475 pcbm_p->pcbm_config_header->ch_status_reg); 1476 1477 (void) ndi_prop_update_int(DDI_DEV_T_ANY, dip, "latency-timer", 1478 (int)pcbm_p->pcbm_config_header->ch_latency_timer_reg); 1479 #undef pbm_err 1480 #undef csr_err 1481 } 1482 1483 uint_t 1484 pcmu_pbm_disable_errors(pcmu_pbm_t *pcbm_p) 1485 { 1486 pcmu_t *pcmu_p = pcbm_p->pcbm_pcmu_p; 1487 pcmu_ib_t *pib_p = pcmu_p->pcmu_ib_p; 1488 1489 /* 1490 * Disable error and streaming byte hole interrupts via the 1491 * PBM control register. 1492 */ 1493 *pcbm_p->pcbm_ctrl_reg &= ~PCMU_PCI_CTRL_ERR_INT_EN; 1494 1495 /* 1496 * Disable error interrupts via the interrupt mapping register. 1497 */ 1498 pcmu_ib_intr_disable(pib_p, 1499 pcmu_p->pcmu_inos[CBNINTR_PBM], PCMU_IB_INTR_NOWAIT); 1500 return (BF_NONE); 1501 } 1502 1503 void 1504 pcmu_cb_setup(pcmu_t *pcmu_p) 1505 { 1506 uint64_t csr, csr_pa, pa; 1507 pcmu_cb_t *pcb_p = pcmu_p->pcmu_cb_p; 1508 1509 pcb_p->pcb_ign = PCMU_ID_TO_IGN(pcmu_p->pcmu_id); 1510 pa = (uint64_t)hat_getpfnum(kas.a_hat, pcmu_p->pcmu_address[0]); 1511 pcb_p->pcb_base_pa = pa = pa >> (32 - MMU_PAGESHIFT) << 32; 1512 pcb_p->pcb_map_pa = pa + PCMU_IB_OBIO_INTR_MAP_REG_OFFSET; 1513 pcb_p->pcb_clr_pa = pa + PCMU_IB_OBIO_CLEAR_INTR_REG_OFFSET; 1514 pcb_p->pcb_obsta_pa = pa + PCMU_IB_OBIO_INTR_STATE_DIAG_REG; 1515 1516 csr_pa = pa + PCMU_CB_CONTROL_STATUS_REG_OFFSET; 1517 csr = lddphysio(csr_pa); 1518 1519 /* 1520 * Clear any pending address parity errors. 1521 */ 1522 if (csr & PCMU_CB_CONTROL_STATUS_APERR) { 1523 csr |= PCMU_CB_CONTROL_STATUS_APERR; 1524 cmn_err(CE_WARN, "clearing UPA address parity error\n"); 1525 } 1526 csr |= PCMU_CB_CONTROL_STATUS_APCKEN; 1527 csr &= ~PCMU_CB_CONTROL_STATUS_IAP; 1528 stdphysio(csr_pa, csr); 1529 1530 u2u_ittrans_init(pcmu_p, 1531 (u2u_ittrans_data_t **)&pcb_p->pcb_ittrans_cookie); 1532 } 1533 1534 void 1535 pcmu_ecc_setup(pcmu_ecc_t *pecc_p) 1536 { 1537 pecc_p->pecc_ue.pecc_errpndg_mask = 0; 1538 pecc_p->pecc_ue.pecc_offset_mask = PCMU_ECC_UE_AFSR_DW_OFFSET; 1539 pecc_p->pecc_ue.pecc_offset_shift = PCMU_ECC_UE_AFSR_DW_OFFSET_SHIFT; 1540 pecc_p->pecc_ue.pecc_size_log2 = 3; 1541 } 1542 1543 static uintptr_t 1544 get_pbm_reg_base(pcmu_t *pcmu_p) 1545 { 1546 return ((uintptr_t)(pcmu_p->pcmu_address[0])); 1547 } 1548 1549 void 1550 pcmu_pbm_setup(pcmu_pbm_t *pcbm_p) 1551 { 1552 pcmu_t *pcmu_p = pcbm_p->pcbm_pcmu_p; 1553 1554 /* 1555 * Get the base virtual address for the PBM control block. 1556 */ 1557 uintptr_t a = get_pbm_reg_base(pcmu_p); 1558 1559 /* 1560 * Get the virtual address of the PCI configuration header. 1561 * This should be mapped little-endian. 1562 */ 1563 pcbm_p->pcbm_config_header = 1564 (config_header_t *)get_config_reg_base(pcmu_p); 1565 1566 /* 1567 * Get the virtual addresses for control, error and diag 1568 * registers. 1569 */ 1570 pcbm_p->pcbm_ctrl_reg = (uint64_t *)(a + PCMU_PCI_CTRL_REG_OFFSET); 1571 pcbm_p->pcbm_diag_reg = (uint64_t *)(a + PCMU_PCI_DIAG_REG_OFFSET); 1572 pcbm_p->pcbm_async_flt_status_reg = 1573 (uint64_t *)(a + PCMU_PCI_ASYNC_FLT_STATUS_REG_OFFSET); 1574 pcbm_p->pcbm_async_flt_addr_reg = 1575 (uint64_t *)(a + PCMU_PCI_ASYNC_FLT_ADDR_REG_OFFSET); 1576 } 1577 1578 /*ARGSUSED*/ 1579 void 1580 pcmu_pbm_teardown(pcmu_pbm_t *pcbm_p) 1581 { 1582 } 1583 1584 int 1585 pcmu_get_numproxy(dev_info_t *dip) 1586 { 1587 return (ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1588 "#upa-interrupt-proxies", 1)); 1589 } 1590 1591 int 1592 pcmu_get_portid(dev_info_t *dip) 1593 { 1594 return (ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1595 "portid", -1)); 1596 } 1597 1598 /* 1599 * CMU-CH Performance Events. 1600 */ 1601 static pcmu_kev_mask_t 1602 pcicmu_pcmu_events[] = { 1603 {"pio_cycles_b", 0xf}, {"interrupts", 0x11}, 1604 {"upa_inter_nack", 0x12}, {"pio_reads", 0x13}, 1605 {"pio_writes", 0x14}, 1606 {"clear_pic", 0x1f} 1607 }; 1608 1609 /* 1610 * Create the picN kstat's. 1611 */ 1612 void 1613 pcmu_kstat_init() 1614 { 1615 pcmu_name_kstat = (pcmu_ksinfo_t *)kmem_alloc(sizeof (pcmu_ksinfo_t), 1616 KM_NOSLEEP); 1617 1618 if (pcmu_name_kstat == NULL) { 1619 cmn_err(CE_WARN, "pcicmu : no space for kstat\n"); 1620 } else { 1621 pcmu_name_kstat->pic_no_evs = 1622 sizeof (pcicmu_pcmu_events) / sizeof (pcmu_kev_mask_t); 1623 pcmu_name_kstat->pic_shift[0] = PCMU_SHIFT_PIC0; 1624 pcmu_name_kstat->pic_shift[1] = PCMU_SHIFT_PIC1; 1625 pcmu_create_name_kstat("pcmup", 1626 pcmu_name_kstat, pcicmu_pcmu_events); 1627 } 1628 } 1629 1630 /* 1631 * Called from _fini() 1632 */ 1633 void 1634 pcmu_kstat_fini() 1635 { 1636 if (pcmu_name_kstat != NULL) { 1637 pcmu_delete_name_kstat(pcmu_name_kstat); 1638 kmem_free(pcmu_name_kstat, sizeof (pcmu_ksinfo_t)); 1639 pcmu_name_kstat = NULL; 1640 } 1641 } 1642 1643 /* 1644 * Create the performance 'counters' kstat. 1645 */ 1646 void 1647 pcmu_add_upstream_kstat(pcmu_t *pcmu_p) 1648 { 1649 pcmu_cntr_pa_t *cntr_pa_p = &pcmu_p->pcmu_uks_pa; 1650 uint64_t regbase = va_to_pa((void *)get_reg_base(pcmu_p)); 1651 1652 cntr_pa_p->pcr_pa = regbase + PCMU_PERF_PCR_OFFSET; 1653 cntr_pa_p->pic_pa = regbase + PCMU_PERF_PIC_OFFSET; 1654 pcmu_p->pcmu_uksp = pcmu_create_cntr_kstat(pcmu_p, "pcmup", 1655 NUM_OF_PICS, pcmu_cntr_kstat_pa_update, cntr_pa_p); 1656 } 1657 1658 /* 1659 * u2u_ittrans_init() is caled from in pci.c's pcmu_cb_setup() per CMU. 1660 * Second argument "ittrans_cookie" is address of pcb_ittrans_cookie in 1661 * pcb_p member. allocated interrupt block is returned in it. 1662 */ 1663 static void 1664 u2u_ittrans_init(pcmu_t *pcmu_p, u2u_ittrans_data_t **ittrans_cookie) 1665 { 1666 1667 u2u_ittrans_data_t *u2u_trans_p; 1668 ddi_device_acc_attr_t attr; 1669 int ret; 1670 int board; 1671 1672 /* 1673 * Allocate the data structure to support U2U's 1674 * interrupt target translations. 1675 */ 1676 u2u_trans_p = (u2u_ittrans_data_t *) 1677 kmem_zalloc(sizeof (u2u_ittrans_data_t), KM_SLEEP); 1678 1679 /* 1680 * Get other properties, "board#" 1681 */ 1682 board = ddi_getprop(DDI_DEV_T_ANY, pcmu_p->pcmu_dip, 1683 DDI_PROP_DONTPASS, "board#", -1); 1684 1685 u2u_trans_p->u2u_board = board; 1686 1687 if (board == -1) { 1688 /* this cannot happen on production systems */ 1689 cmn_err(CE_PANIC, "u2u:Invalid property;board = %d", board); 1690 } 1691 1692 /* 1693 * Initialize interrupt target translations mutex. 1694 */ 1695 mutex_init(&(u2u_trans_p->u2u_ittrans_lock), "u2u_ittrans_lock", 1696 MUTEX_DEFAULT, NULL); 1697 1698 /* 1699 * Get U2U's registers space by ddi_regs_map_setup(9F) 1700 */ 1701 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 1702 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1703 attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 1704 1705 ret = ddi_regs_map_setup(pcmu_p->pcmu_dip, 1706 REGS_INDEX_OF_U2U, (caddr_t *)(&(u2u_trans_p->u2u_regs_base)), 1707 0, 0, &attr, &(u2u_trans_p->u2u_acc)); 1708 1709 /* 1710 * check result of ddi_regs_map_setup(). 1711 */ 1712 if (ret != DDI_SUCCESS) { 1713 cmn_err(CE_PANIC, "u2u%d: registers map setup failed", board); 1714 } 1715 1716 /* 1717 * Read Port-id(1 byte) in u2u 1718 */ 1719 u2u_trans_p->u2u_port_id = *(volatile int32_t *) 1720 (u2u_trans_p->u2u_regs_base + U2U_PID_REGISTER_OFFSET); 1721 1722 if (pcmu_p->pcmu_id != u2u_trans_p->u2u_port_id) { 1723 cmn_err(CE_PANIC, "u2u%d: Invalid Port-ID", board); 1724 } 1725 1726 *ittrans_cookie = u2u_trans_p; 1727 } 1728 1729 /* 1730 * u2u_ittras_resume() is called from pcmu_obj_resume() at DDI_RESUME entry. 1731 */ 1732 static void 1733 u2u_ittrans_resume(u2u_ittrans_data_t **ittrans_cookie) 1734 { 1735 1736 u2u_ittrans_data_t *u2u_trans_p; 1737 u2u_ittrans_id_t *ittrans_id_p; 1738 uintptr_t data_reg_addr; 1739 int ix; 1740 1741 u2u_trans_p = *ittrans_cookie; 1742 1743 /* 1744 * Set U2U Data Register 1745 */ 1746 for (ix = 0; ix < U2U_DATA_NUM; ix++) { 1747 ittrans_id_p = &(u2u_trans_p->u2u_ittrans_id[ix]); 1748 data_reg_addr = u2u_trans_p->u2u_regs_base + 1749 U2U_DATA_REGISTER_OFFSET + (ix * sizeof (uint64_t)); 1750 if (ittrans_id_p->u2u_ino_map_reg == NULL) { 1751 /* This index was not set */ 1752 continue; 1753 } 1754 *(volatile uint32_t *) (data_reg_addr) = 1755 (uint32_t)ittrans_id_p->u2u_tgt_cpu_id; 1756 1757 } 1758 } 1759 1760 /* 1761 * u2u_ittras_uninit() is called from ib_destroy() at detach, 1762 * or occuring error in attach. 1763 */ 1764 static void 1765 u2u_ittrans_uninit(u2u_ittrans_data_t *ittrans_cookie) 1766 { 1767 1768 if (ittrans_cookie == NULL) { 1769 return; /* not support */ 1770 } 1771 1772 if (ittrans_cookie == (u2u_ittrans_data_t *)(-1)) { 1773 return; /* illeagal case */ 1774 } 1775 1776 ddi_regs_map_free(&(ittrans_cookie->u2u_acc)); 1777 mutex_destroy(&(ittrans_cookie->u2u_ittrans_lock)); 1778 kmem_free((void *)ittrans_cookie, sizeof (u2u_ittrans_data_t)); 1779 } 1780 1781 /* 1782 * This routine,u2u_translate_tgtid(, , cpu_id, pino_map_reg), 1783 * searches index having same value of pino_map_reg, or empty. 1784 * Then, stores cpu_id in a U2U Data Register as this index, 1785 * and return this index. 1786 */ 1787 int 1788 u2u_translate_tgtid(pcmu_t *pcmu_p, uint_t cpu_id, 1789 volatile uint64_t *pino_map_reg) 1790 { 1791 1792 int index = -1; 1793 int ix; 1794 int err_level; /* severity level for cmn_err */ 1795 u2u_ittrans_id_t *ittrans_id_p; 1796 uintptr_t data_reg_addr; 1797 u2u_ittrans_data_t *ittrans_cookie; 1798 1799 ittrans_cookie = 1800 (u2u_ittrans_data_t *)(pcmu_p->pcmu_cb_p->pcb_ittrans_cookie); 1801 1802 if (ittrans_cookie == NULL) { 1803 return (cpu_id); 1804 } 1805 1806 if (ittrans_cookie == (u2u_ittrans_data_t *)(-1)) { 1807 return (-1); /* illeagal case */ 1808 } 1809 1810 mutex_enter(&(ittrans_cookie->u2u_ittrans_lock)); 1811 1812 /* 1813 * Decide index No. of U2U Data registers in either 1814 * already used by same pino_map_reg, or empty. 1815 */ 1816 for (ix = 0; ix < U2U_DATA_NUM; ix++) { 1817 ittrans_id_p = &(ittrans_cookie->u2u_ittrans_id[ix]); 1818 if (ittrans_id_p->u2u_ino_map_reg == pino_map_reg) { 1819 /* already used this pino_map_reg */ 1820 index = ix; 1821 break; 1822 } 1823 if (index == -1 && 1824 ittrans_id_p->u2u_ino_map_reg == NULL) { 1825 index = ix; 1826 } 1827 } 1828 1829 if (index == -1) { 1830 if (panicstr) { 1831 err_level = CE_WARN; 1832 } else { 1833 err_level = CE_PANIC; 1834 } 1835 cmn_err(err_level, "u2u%d:No more U2U-Data regs!!", 1836 ittrans_cookie->u2u_board); 1837 return (cpu_id); 1838 } 1839 1840 /* 1841 * For U2U 1842 * set cpu_id into u2u_data_reg by index. 1843 * ((uint64_t)(u2u_regs_base 1844 * + U2U_DATA_REGISTER_OFFSET))[index] = cpu_id; 1845 */ 1846 1847 data_reg_addr = ittrans_cookie->u2u_regs_base 1848 + U2U_DATA_REGISTER_OFFSET 1849 + (index * sizeof (uint64_t)); 1850 1851 /* 1852 * Set cpu_id into U2U Data register[index] 1853 */ 1854 *(volatile uint32_t *) (data_reg_addr) = (uint32_t)cpu_id; 1855 1856 /* 1857 * Setup for software, excepting at panicing. 1858 * and rebooting, etc...? 1859 */ 1860 if (!panicstr) { 1861 ittrans_id_p = &(ittrans_cookie->u2u_ittrans_id[index]); 1862 ittrans_id_p->u2u_tgt_cpu_id = cpu_id; 1863 ittrans_id_p->u2u_ino_map_reg = pino_map_reg; 1864 } 1865 1866 mutex_exit(&(ittrans_cookie->u2u_ittrans_lock)); 1867 1868 return (index); 1869 } 1870 1871 /* 1872 * u2u_ittrans_cleanup() is called from common_pcmu_ib_intr_disable() 1873 * after called intr_rem_cpu(mondo). 1874 */ 1875 void 1876 u2u_ittrans_cleanup(u2u_ittrans_data_t *ittrans_cookie, 1877 volatile uint64_t *pino_map_reg) 1878 { 1879 1880 int ix; 1881 u2u_ittrans_id_t *ittrans_id_p; 1882 1883 if (ittrans_cookie == NULL) { 1884 return; 1885 } 1886 1887 if (ittrans_cookie == (u2u_ittrans_data_t *)(-1)) { 1888 return; /* illeagal case */ 1889 } 1890 1891 mutex_enter(&(ittrans_cookie->u2u_ittrans_lock)); 1892 1893 for (ix = 0; ix < U2U_DATA_NUM; ix++) { 1894 ittrans_id_p = &(ittrans_cookie->u2u_ittrans_id[ix]); 1895 if (ittrans_id_p->u2u_ino_map_reg == pino_map_reg) { 1896 ittrans_id_p->u2u_ino_map_reg = NULL; 1897 break; 1898 } 1899 } 1900 1901 mutex_exit(&(ittrans_cookie->u2u_ittrans_lock)); 1902 } 1903 1904 /* 1905 * pcmu_ecc_classify, called by ecc_handler to classify ecc errors 1906 * and determine if we should panic or not. 1907 */ 1908 void 1909 pcmu_ecc_classify(uint64_t err, pcmu_ecc_errstate_t *ecc_err_p) 1910 { 1911 struct async_flt *ecc = &ecc_err_p->ecc_aflt; 1912 /* LINTED */ 1913 pcmu_t *pcmu_p = ecc_err_p->ecc_ii_p.pecc_p->pecc_pcmu_p; 1914 1915 ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex)); 1916 1917 ecc_err_p->ecc_bridge_type = PCI_OPLCMU; /* RAGS */ 1918 /* 1919 * Get the parent bus id that caused the error. 1920 */ 1921 ecc_err_p->ecc_dev_id = (ecc_err_p->ecc_afsr & PCMU_ECC_UE_AFSR_ID) 1922 >> PCMU_ECC_UE_AFSR_ID_SHIFT; 1923 /* 1924 * Determine the doubleword offset of the error. 1925 */ 1926 ecc_err_p->ecc_dw_offset = (ecc_err_p->ecc_afsr & 1927 PCMU_ECC_UE_AFSR_DW_OFFSET) >> PCMU_ECC_UE_AFSR_DW_OFFSET_SHIFT; 1928 /* 1929 * Determine the primary error type. 1930 */ 1931 switch (err) { 1932 case PCMU_ECC_UE_AFSR_E_PIO: 1933 if (ecc_err_p->pecc_pri) { 1934 ecc->flt_erpt_class = PCI_ECC_PIO_UE; 1935 } else { 1936 ecc->flt_erpt_class = PCI_ECC_SEC_PIO_UE; 1937 } 1938 /* For CMU-CH, a UE is always fatal. */ 1939 ecc->flt_panic = 1; 1940 break; 1941 1942 default: 1943 return; 1944 } 1945 } 1946 1947 /* 1948 * pcmu_pbm_classify, called by pcmu_pbm_afsr_report to classify piow afsr. 1949 */ 1950 int 1951 pcmu_pbm_classify(pcmu_pbm_errstate_t *pbm_err_p) 1952 { 1953 uint32_t e; 1954 int nerr = 0; 1955 char **tmp_class; 1956 1957 if (pbm_err_p->pcbm_pri) { 1958 tmp_class = &pbm_err_p->pcbm_pci.pcmu_err_class; 1959 e = PBM_AFSR_TO_PRIERR(pbm_err_p->pbm_afsr); 1960 pbm_err_p->pbm_log = FM_LOG_PCI; 1961 } else { 1962 tmp_class = &pbm_err_p->pbm_err_class; 1963 e = PBM_AFSR_TO_SECERR(pbm_err_p->pbm_afsr); 1964 pbm_err_p->pbm_log = FM_LOG_PBM; 1965 } 1966 1967 if (e & PCMU_PCI_AFSR_E_MA) { 1968 *tmp_class = pbm_err_p->pcbm_pri ? PCI_MA : PCI_SEC_MA; 1969 nerr++; 1970 } 1971 return (nerr); 1972 } 1973 1974 /* 1975 * Function used to clear PBM/PCI/IOMMU error state after error handling 1976 * is complete. Only clearing error bits which have been logged. Called by 1977 * pcmu_pbm_err_handler and pcmu_bus_exit. 1978 */ 1979 static void 1980 pcmu_clear_error(pcmu_t *pcmu_p, pcmu_pbm_errstate_t *pbm_err_p) 1981 { 1982 pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p; 1983 1984 ASSERT(MUTEX_HELD(&pcbm_p->pcbm_pcmu_p->pcmu_err_mutex)); 1985 1986 *pcbm_p->pcbm_ctrl_reg = pbm_err_p->pbm_ctl_stat; 1987 *pcbm_p->pcbm_async_flt_status_reg = pbm_err_p->pbm_afsr; 1988 pcbm_p->pcbm_config_header->ch_status_reg = 1989 pbm_err_p->pcbm_pci.pcmu_cfg_stat; 1990 } 1991 1992 /*ARGSUSED*/ 1993 int 1994 pcmu_pbm_err_handler(dev_info_t *dip, ddi_fm_error_t *derr, 1995 const void *impl_data, int caller) 1996 { 1997 int fatal = 0; 1998 int nonfatal = 0; 1999 int unknown = 0; 2000 uint32_t prierr, secerr; 2001 pcmu_pbm_errstate_t pbm_err; 2002 pcmu_t *pcmu_p = (pcmu_t *)impl_data; 2003 int ret = 0; 2004 2005 ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex)); 2006 pcmu_pbm_errstate_get(pcmu_p, &pbm_err); 2007 2008 derr->fme_ena = derr->fme_ena ? derr->fme_ena : 2009 fm_ena_generate(0, FM_ENA_FMT1); 2010 2011 prierr = PBM_AFSR_TO_PRIERR(pbm_err.pbm_afsr); 2012 secerr = PBM_AFSR_TO_SECERR(pbm_err.pbm_afsr); 2013 2014 if (derr->fme_flag == DDI_FM_ERR_PEEK) { 2015 /* 2016 * For ddi_peek treat all events as nonfatal. We only 2017 * really call this function so that pcmu_clear_error() 2018 * and ndi_fm_handler_dispatch() will get called. 2019 */ 2020 nonfatal++; 2021 goto done; 2022 } else if (derr->fme_flag == DDI_FM_ERR_POKE) { 2023 /* 2024 * For ddi_poke we can treat as nonfatal if the 2025 * following conditions are met : 2026 * 1. Make sure only primary error is MA/TA 2027 * 2. Make sure no secondary error 2028 * 3. check pci config header stat reg to see MA/TA is 2029 * logged. We cannot verify only MA/TA is recorded 2030 * since it gets much more complicated when a 2031 * PCI-to-PCI bridge is present. 2032 */ 2033 if ((prierr == PCMU_PCI_AFSR_E_MA) && !secerr && 2034 (pbm_err.pcbm_pci.pcmu_cfg_stat & PCI_STAT_R_MAST_AB)) { 2035 nonfatal++; 2036 goto done; 2037 } 2038 } 2039 2040 if (prierr || secerr) { 2041 ret = pcmu_pbm_afsr_report(dip, derr->fme_ena, &pbm_err); 2042 if (ret == DDI_FM_FATAL) { 2043 fatal++; 2044 } else { 2045 nonfatal++; 2046 } 2047 } 2048 2049 ret = pcmu_cfg_report(dip, derr, &pbm_err.pcbm_pci, caller, prierr); 2050 if (ret == DDI_FM_FATAL) { 2051 fatal++; 2052 } else if (ret == DDI_FM_NONFATAL) { 2053 nonfatal++; 2054 } 2055 2056 done: 2057 if (ret == DDI_FM_FATAL) { 2058 fatal++; 2059 } else if (ret == DDI_FM_NONFATAL) { 2060 nonfatal++; 2061 } else if (ret == DDI_FM_UNKNOWN) { 2062 unknown++; 2063 } 2064 2065 /* Cleanup and reset error bits */ 2066 pcmu_clear_error(pcmu_p, &pbm_err); 2067 2068 return (fatal ? DDI_FM_FATAL : (nonfatal ? DDI_FM_NONFATAL : 2069 (unknown ? DDI_FM_UNKNOWN : DDI_FM_OK))); 2070 } 2071 2072 int 2073 pcmu_check_error(pcmu_t *pcmu_p) 2074 { 2075 pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p; 2076 uint16_t pcmu_cfg_stat; 2077 uint64_t pbm_afsr; 2078 2079 ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex)); 2080 2081 pcmu_cfg_stat = pcbm_p->pcbm_config_header->ch_status_reg; 2082 pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg; 2083 2084 if ((pcmu_cfg_stat & (PCI_STAT_S_PERROR | PCI_STAT_S_TARG_AB | 2085 PCI_STAT_R_TARG_AB | PCI_STAT_R_MAST_AB | 2086 PCI_STAT_S_SYSERR | PCI_STAT_PERROR)) || 2087 (PBM_AFSR_TO_PRIERR(pbm_afsr))) { 2088 return (1); 2089 } 2090 return (0); 2091 2092 } 2093 2094 /* 2095 * Function used to gather PBM/PCI error state for the 2096 * pcmu_pbm_err_handler. This function must be called while pcmu_err_mutex 2097 * is held. 2098 */ 2099 static void 2100 pcmu_pbm_errstate_get(pcmu_t *pcmu_p, pcmu_pbm_errstate_t *pbm_err_p) 2101 { 2102 pcmu_pbm_t *pcbm_p = pcmu_p->pcmu_pcbm_p; 2103 2104 ASSERT(MUTEX_HELD(&pcmu_p->pcmu_err_mutex)); 2105 bzero(pbm_err_p, sizeof (pcmu_pbm_errstate_t)); 2106 2107 /* 2108 * Capture all pbm error state for later logging 2109 */ 2110 pbm_err_p->pbm_bridge_type = PCI_OPLCMU; /* RAGS */ 2111 pbm_err_p->pcbm_pci.pcmu_cfg_stat = 2112 pcbm_p->pcbm_config_header->ch_status_reg; 2113 pbm_err_p->pbm_ctl_stat = *pcbm_p->pcbm_ctrl_reg; 2114 pbm_err_p->pcbm_pci.pcmu_cfg_comm = 2115 pcbm_p->pcbm_config_header->ch_command_reg; 2116 pbm_err_p->pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg; 2117 pbm_err_p->pbm_afar = *pcbm_p->pcbm_async_flt_addr_reg; 2118 pbm_err_p->pcbm_pci.pcmu_pa = *pcbm_p->pcbm_async_flt_addr_reg; 2119 } 2120 2121 static void 2122 pcmu_pbm_clear_error(pcmu_pbm_t *pcbm_p) 2123 { 2124 uint64_t pbm_afsr; 2125 2126 /* 2127 * for poke() support - called from POKE_FLUSH. Spin waiting 2128 * for MA, TA or SERR to be cleared by a pcmu_pbm_error_intr(). 2129 * We have to wait for SERR too in case the device is beyond 2130 * a pci-pci bridge. 2131 */ 2132 pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg; 2133 while (((pbm_afsr >> PCMU_PCI_AFSR_PE_SHIFT) & 2134 (PCMU_PCI_AFSR_E_MA | PCMU_PCI_AFSR_E_TA))) { 2135 pbm_afsr = *pcbm_p->pcbm_async_flt_status_reg; 2136 } 2137 } 2138 2139 void 2140 pcmu_err_create(pcmu_t *pcmu_p) 2141 { 2142 /* 2143 * PCI detected ECC errorq, to schedule async handling 2144 * of ECC errors and logging. 2145 * The errorq is created here but destroyed when _fini is called 2146 * for the pci module. 2147 */ 2148 if (pcmu_ecc_queue == NULL) { 2149 pcmu_ecc_queue = errorq_create("pcmu_ecc_queue", 2150 (errorq_func_t)pcmu_ecc_err_drain, 2151 (void *)NULL, 2152 ECC_MAX_ERRS, sizeof (pcmu_ecc_errstate_t), 2153 PIL_2, ERRORQ_VITAL); 2154 if (pcmu_ecc_queue == NULL) 2155 panic("failed to create required system error queue"); 2156 } 2157 2158 /* 2159 * Initialize error handling mutex. 2160 */ 2161 mutex_init(&pcmu_p->pcmu_err_mutex, NULL, MUTEX_DRIVER, 2162 (void *)pcmu_p->pcmu_fm_ibc); 2163 } 2164 2165 void 2166 pcmu_err_destroy(pcmu_t *pcmu_p) 2167 { 2168 mutex_destroy(&pcmu_p->pcmu_err_mutex); 2169 } 2170 2171 /* 2172 * Function used to post PCI block module specific ereports. 2173 */ 2174 void 2175 pcmu_pbm_ereport_post(dev_info_t *dip, uint64_t ena, 2176 pcmu_pbm_errstate_t *pbm_err) 2177 { 2178 char *aux_msg; 2179 uint32_t prierr, secerr; 2180 pcmu_t *pcmu_p; 2181 int instance = ddi_get_instance(dip); 2182 2183 ena = ena ? ena : fm_ena_generate(0, FM_ENA_FMT1); 2184 2185 pcmu_p = get_pcmu_soft_state(instance); 2186 prierr = PBM_AFSR_TO_PRIERR(pbm_err->pbm_afsr); 2187 secerr = PBM_AFSR_TO_SECERR(pbm_err->pbm_afsr); 2188 if (prierr) 2189 aux_msg = "PCI primary error: Master Abort"; 2190 else if (secerr) 2191 aux_msg = "PCI secondary error: Master Abort"; 2192 else 2193 aux_msg = ""; 2194 cmn_err(CE_WARN, "%s %s: %s %s=0x%lx, %s=0x%lx, %s=0x%lx %s=0x%x", 2195 (pcmu_p->pcmu_pcbm_p)->pcbm_nameinst_str, 2196 (pcmu_p->pcmu_pcbm_p)->pcbm_nameaddr_str, 2197 aux_msg, 2198 PCI_PBM_AFAR, pbm_err->pbm_afar, 2199 PCI_PBM_AFSR, pbm_err->pbm_afsr, 2200 PCI_PBM_CSR, pbm_err->pbm_ctl_stat, 2201 "portid", pcmu_p->pcmu_id); 2202 } 2203