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 #include <sys/types.h> 29 #include <sys/kmem.h> 30 #include <sys/conf.h> 31 #include <sys/ddi.h> 32 #include <sys/sunddi.h> 33 #include <sys/fm/protocol.h> 34 #include <sys/fm/util.h> 35 #include <sys/modctl.h> 36 #include <sys/disp.h> 37 #include <sys/stat.h> 38 #include <sys/ddi_impldefs.h> 39 #include <sys/vmem.h> 40 #include <sys/iommutsb.h> 41 #include <sys/cpuvar.h> 42 #include <sys/ivintr.h> 43 #include <sys/byteorder.h> 44 #include <sys/hotplug/pci/pciehpc.h> 45 #include <px_obj.h> 46 #include <pcie_pwr.h> 47 #include <px_regs.h> 48 #include <px_csr.h> 49 #include <sys/machsystm.h> 50 #include "px_lib4u.h" 51 #include "px_err.h" 52 53 #pragma weak jbus_stst_order 54 55 extern void jbus_stst_order(); 56 57 ulong_t px_mmu_dvma_end = 0xfffffffful; 58 uint_t px_ranges_phi_mask = 0xfffffffful; 59 60 static int px_goto_l23ready(px_t *px_p); 61 static int px_goto_l0(px_t *px_p); 62 static int px_pre_pwron_check(px_t *px_p); 63 static uint32_t px_identity_chip(px_t *px_p); 64 static boolean_t px_cpr_callb(void *arg, int code); 65 66 /* 67 * px_lib_map_registers 68 * 69 * This function is called from the attach routine to map the registers 70 * accessed by this driver. 71 * 72 * used by: px_attach() 73 * 74 * return value: DDI_FAILURE on failure 75 */ 76 int 77 px_lib_map_regs(pxu_t *pxu_p, dev_info_t *dip) 78 { 79 ddi_device_acc_attr_t attr; 80 px_reg_bank_t reg_bank = PX_REG_CSR; 81 82 DBG(DBG_ATTACH, dip, "px_lib_map_regs: pxu_p:0x%p, dip 0x%p\n", 83 pxu_p, dip); 84 85 attr.devacc_attr_version = DDI_DEVICE_ATTR_V0; 86 attr.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 87 attr.devacc_attr_endian_flags = DDI_NEVERSWAP_ACC; 88 89 /* 90 * PCI CSR Base 91 */ 92 if (ddi_regs_map_setup(dip, reg_bank, &pxu_p->px_address[reg_bank], 93 0, 0, &attr, &pxu_p->px_ac[reg_bank]) != DDI_SUCCESS) { 94 goto fail; 95 } 96 97 reg_bank++; 98 99 /* 100 * XBUS CSR Base 101 */ 102 if (ddi_regs_map_setup(dip, reg_bank, &pxu_p->px_address[reg_bank], 103 0, 0, &attr, &pxu_p->px_ac[reg_bank]) != DDI_SUCCESS) { 104 goto fail; 105 } 106 107 pxu_p->px_address[reg_bank] -= FIRE_CONTROL_STATUS; 108 109 done: 110 for (; reg_bank >= PX_REG_CSR; reg_bank--) { 111 DBG(DBG_ATTACH, dip, "reg_bank 0x%x address 0x%p\n", 112 reg_bank, pxu_p->px_address[reg_bank]); 113 } 114 115 return (DDI_SUCCESS); 116 117 fail: 118 cmn_err(CE_WARN, "%s%d: unable to map reg entry %d\n", 119 ddi_driver_name(dip), ddi_get_instance(dip), reg_bank); 120 121 for (reg_bank--; reg_bank >= PX_REG_CSR; reg_bank--) { 122 pxu_p->px_address[reg_bank] = NULL; 123 ddi_regs_map_free(&pxu_p->px_ac[reg_bank]); 124 } 125 126 return (DDI_FAILURE); 127 } 128 129 /* 130 * px_lib_unmap_regs: 131 * 132 * This routine unmaps the registers mapped by map_px_registers. 133 * 134 * used by: px_detach(), and error conditions in px_attach() 135 * 136 * return value: none 137 */ 138 void 139 px_lib_unmap_regs(pxu_t *pxu_p) 140 { 141 int i; 142 143 for (i = 0; i < PX_REG_MAX; i++) { 144 if (pxu_p->px_ac[i]) 145 ddi_regs_map_free(&pxu_p->px_ac[i]); 146 } 147 } 148 149 int 150 px_lib_dev_init(dev_info_t *dip, devhandle_t *dev_hdl) 151 { 152 px_t *px_p = DIP_TO_STATE(dip); 153 caddr_t xbc_csr_base, csr_base; 154 px_dvma_range_prop_t px_dvma_range; 155 uint32_t chip_id; 156 pxu_t *pxu_p; 157 158 DBG(DBG_ATTACH, dip, "px_lib_dev_init: dip 0x%p\n", dip); 159 160 if ((chip_id = px_identity_chip(px_p)) == PX_CHIP_UNIDENTIFIED) 161 return (DDI_FAILURE); 162 163 switch (chip_id) { 164 case FIRE_VER_10: 165 cmn_err(CE_WARN, "FIRE Hardware Version 1.0 is not supported"); 166 return (DDI_FAILURE); 167 case FIRE_VER_20: 168 DBG(DBG_ATTACH, dip, "FIRE Hardware Version 2.0\n"); 169 break; 170 default: 171 cmn_err(CE_WARN, "%s%d: FIRE Hardware Version Unknown\n", 172 ddi_driver_name(dip), ddi_get_instance(dip)); 173 return (DDI_FAILURE); 174 } 175 176 /* 177 * Allocate platform specific structure and link it to 178 * the px state structure. 179 */ 180 pxu_p = kmem_zalloc(sizeof (pxu_t), KM_SLEEP); 181 pxu_p->chip_id = chip_id; 182 pxu_p->portid = ddi_getprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 183 "portid", -1); 184 185 /* Map in the registers */ 186 if (px_lib_map_regs(pxu_p, dip) == DDI_FAILURE) { 187 kmem_free(pxu_p, sizeof (pxu_t)); 188 189 return (DDI_FAILURE); 190 } 191 192 xbc_csr_base = (caddr_t)pxu_p->px_address[PX_REG_XBC]; 193 csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 194 195 pxu_p->tsb_cookie = iommu_tsb_alloc(pxu_p->portid); 196 pxu_p->tsb_size = iommu_tsb_cookie_to_size(pxu_p->tsb_cookie); 197 pxu_p->tsb_vaddr = iommu_tsb_cookie_to_va(pxu_p->tsb_cookie); 198 199 /* 200 * Create "virtual-dma" property to support child devices 201 * needing to know DVMA range. 202 */ 203 px_dvma_range.dvma_base = (uint32_t)px_mmu_dvma_end + 1 204 - ((pxu_p->tsb_size >> 3) << MMU_PAGE_SHIFT); 205 px_dvma_range.dvma_len = (uint32_t) 206 px_mmu_dvma_end - px_dvma_range.dvma_base + 1; 207 208 (void) ddi_prop_create(DDI_DEV_T_NONE, dip, DDI_PROP_CANSLEEP, 209 "virtual-dma", (caddr_t)&px_dvma_range, 210 sizeof (px_dvma_range_prop_t)); 211 /* 212 * Initilize all fire hardware specific blocks. 213 */ 214 hvio_cb_init(xbc_csr_base, pxu_p); 215 hvio_ib_init(csr_base, pxu_p); 216 hvio_pec_init(csr_base, pxu_p); 217 hvio_mmu_init(csr_base, pxu_p); 218 219 px_p->px_plat_p = (void *)pxu_p; 220 221 /* 222 * Initialize all the interrupt handlers 223 */ 224 px_err_reg_enable(px_p, PX_ERR_JBC); 225 px_err_reg_enable(px_p, PX_ERR_MMU); 226 px_err_reg_enable(px_p, PX_ERR_IMU); 227 px_err_reg_enable(px_p, PX_ERR_TLU_UE); 228 px_err_reg_enable(px_p, PX_ERR_TLU_CE); 229 px_err_reg_enable(px_p, PX_ERR_TLU_OE); 230 px_err_reg_enable(px_p, PX_ERR_ILU); 231 px_err_reg_enable(px_p, PX_ERR_LPU_LINK); 232 px_err_reg_enable(px_p, PX_ERR_LPU_PHY); 233 px_err_reg_enable(px_p, PX_ERR_LPU_RX); 234 px_err_reg_enable(px_p, PX_ERR_LPU_TX); 235 px_err_reg_enable(px_p, PX_ERR_LPU_LTSSM); 236 px_err_reg_enable(px_p, PX_ERR_LPU_GIGABLZ); 237 238 /* Initilize device handle */ 239 *dev_hdl = (devhandle_t)csr_base; 240 241 DBG(DBG_ATTACH, dip, "px_lib_dev_init: dev_hdl 0x%llx\n", *dev_hdl); 242 243 return (DDI_SUCCESS); 244 } 245 246 int 247 px_lib_dev_fini(dev_info_t *dip) 248 { 249 px_t *px_p = DIP_TO_STATE(dip); 250 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 251 252 DBG(DBG_DETACH, dip, "px_lib_dev_fini: dip 0x%p\n", dip); 253 254 /* 255 * Deinitialize all the interrupt handlers 256 */ 257 px_err_reg_disable(px_p, PX_ERR_JBC); 258 px_err_reg_disable(px_p, PX_ERR_MMU); 259 px_err_reg_disable(px_p, PX_ERR_IMU); 260 px_err_reg_disable(px_p, PX_ERR_TLU_UE); 261 px_err_reg_disable(px_p, PX_ERR_TLU_CE); 262 px_err_reg_disable(px_p, PX_ERR_TLU_OE); 263 px_err_reg_disable(px_p, PX_ERR_ILU); 264 px_err_reg_disable(px_p, PX_ERR_LPU_LINK); 265 px_err_reg_disable(px_p, PX_ERR_LPU_PHY); 266 px_err_reg_disable(px_p, PX_ERR_LPU_RX); 267 px_err_reg_disable(px_p, PX_ERR_LPU_TX); 268 px_err_reg_disable(px_p, PX_ERR_LPU_LTSSM); 269 px_err_reg_disable(px_p, PX_ERR_LPU_GIGABLZ); 270 271 iommu_tsb_free(pxu_p->tsb_cookie); 272 273 px_lib_unmap_regs((pxu_t *)px_p->px_plat_p); 274 kmem_free(px_p->px_plat_p, sizeof (pxu_t)); 275 px_p->px_plat_p = NULL; 276 277 return (DDI_SUCCESS); 278 } 279 280 /*ARGSUSED*/ 281 int 282 px_lib_intr_devino_to_sysino(dev_info_t *dip, devino_t devino, 283 sysino_t *sysino) 284 { 285 px_t *px_p = DIP_TO_STATE(dip); 286 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 287 uint64_t ret; 288 289 DBG(DBG_LIB_INT, dip, "px_lib_intr_devino_to_sysino: dip 0x%p " 290 "devino 0x%x\n", dip, devino); 291 292 if ((ret = hvio_intr_devino_to_sysino(DIP_TO_HANDLE(dip), 293 pxu_p, devino, sysino)) != H_EOK) { 294 DBG(DBG_LIB_INT, dip, 295 "hvio_intr_devino_to_sysino failed, ret 0x%lx\n", ret); 296 return (DDI_FAILURE); 297 } 298 299 DBG(DBG_LIB_INT, dip, "px_lib_intr_devino_to_sysino: sysino 0x%llx\n", 300 *sysino); 301 302 return (DDI_SUCCESS); 303 } 304 305 /*ARGSUSED*/ 306 int 307 px_lib_intr_getvalid(dev_info_t *dip, sysino_t sysino, 308 intr_valid_state_t *intr_valid_state) 309 { 310 uint64_t ret; 311 312 DBG(DBG_LIB_INT, dip, "px_lib_intr_getvalid: dip 0x%p sysino 0x%llx\n", 313 dip, sysino); 314 315 if ((ret = hvio_intr_getvalid(DIP_TO_HANDLE(dip), 316 sysino, intr_valid_state)) != H_EOK) { 317 DBG(DBG_LIB_INT, dip, "hvio_intr_getvalid failed, ret 0x%lx\n", 318 ret); 319 return (DDI_FAILURE); 320 } 321 322 DBG(DBG_LIB_INT, dip, "px_lib_intr_getvalid: intr_valid_state 0x%x\n", 323 *intr_valid_state); 324 325 return (DDI_SUCCESS); 326 } 327 328 /*ARGSUSED*/ 329 int 330 px_lib_intr_setvalid(dev_info_t *dip, sysino_t sysino, 331 intr_valid_state_t intr_valid_state) 332 { 333 uint64_t ret; 334 335 DBG(DBG_LIB_INT, dip, "px_lib_intr_setvalid: dip 0x%p sysino 0x%llx " 336 "intr_valid_state 0x%x\n", dip, sysino, intr_valid_state); 337 338 if ((ret = hvio_intr_setvalid(DIP_TO_HANDLE(dip), 339 sysino, intr_valid_state)) != H_EOK) { 340 DBG(DBG_LIB_INT, dip, "hvio_intr_setvalid failed, ret 0x%lx\n", 341 ret); 342 return (DDI_FAILURE); 343 } 344 345 return (DDI_SUCCESS); 346 } 347 348 /*ARGSUSED*/ 349 int 350 px_lib_intr_getstate(dev_info_t *dip, sysino_t sysino, 351 intr_state_t *intr_state) 352 { 353 uint64_t ret; 354 355 DBG(DBG_LIB_INT, dip, "px_lib_intr_getstate: dip 0x%p sysino 0x%llx\n", 356 dip, sysino); 357 358 if ((ret = hvio_intr_getstate(DIP_TO_HANDLE(dip), 359 sysino, intr_state)) != H_EOK) { 360 DBG(DBG_LIB_INT, dip, "hvio_intr_getstate failed, ret 0x%lx\n", 361 ret); 362 return (DDI_FAILURE); 363 } 364 365 DBG(DBG_LIB_INT, dip, "px_lib_intr_getstate: intr_state 0x%x\n", 366 *intr_state); 367 368 return (DDI_SUCCESS); 369 } 370 371 /*ARGSUSED*/ 372 int 373 px_lib_intr_setstate(dev_info_t *dip, sysino_t sysino, 374 intr_state_t intr_state) 375 { 376 uint64_t ret; 377 378 DBG(DBG_LIB_INT, dip, "px_lib_intr_setstate: dip 0x%p sysino 0x%llx " 379 "intr_state 0x%x\n", dip, sysino, intr_state); 380 381 if ((ret = hvio_intr_setstate(DIP_TO_HANDLE(dip), 382 sysino, intr_state)) != H_EOK) { 383 DBG(DBG_LIB_INT, dip, "hvio_intr_setstate failed, ret 0x%lx\n", 384 ret); 385 return (DDI_FAILURE); 386 } 387 388 return (DDI_SUCCESS); 389 } 390 391 /*ARGSUSED*/ 392 int 393 px_lib_intr_gettarget(dev_info_t *dip, sysino_t sysino, cpuid_t *cpuid) 394 { 395 uint64_t ret; 396 397 DBG(DBG_LIB_INT, dip, "px_lib_intr_gettarget: dip 0x%p sysino 0x%llx\n", 398 dip, sysino); 399 400 if ((ret = hvio_intr_gettarget(DIP_TO_HANDLE(dip), 401 sysino, cpuid)) != H_EOK) { 402 DBG(DBG_LIB_INT, dip, "hvio_intr_gettarget failed, ret 0x%lx\n", 403 ret); 404 return (DDI_FAILURE); 405 } 406 407 DBG(DBG_LIB_INT, dip, "px_lib_intr_gettarget: cpuid 0x%x\n", cpuid); 408 409 return (DDI_SUCCESS); 410 } 411 412 /*ARGSUSED*/ 413 int 414 px_lib_intr_settarget(dev_info_t *dip, sysino_t sysino, cpuid_t cpuid) 415 { 416 uint64_t ret; 417 418 DBG(DBG_LIB_INT, dip, "px_lib_intr_settarget: dip 0x%p sysino 0x%llx " 419 "cpuid 0x%x\n", dip, sysino, cpuid); 420 421 if ((ret = hvio_intr_settarget(DIP_TO_HANDLE(dip), 422 sysino, cpuid)) != H_EOK) { 423 DBG(DBG_LIB_INT, dip, "hvio_intr_settarget failed, ret 0x%lx\n", 424 ret); 425 return (DDI_FAILURE); 426 } 427 428 return (DDI_SUCCESS); 429 } 430 431 /*ARGSUSED*/ 432 int 433 px_lib_intr_reset(dev_info_t *dip) 434 { 435 devino_t ino; 436 sysino_t sysino; 437 438 DBG(DBG_LIB_INT, dip, "px_lib_intr_reset: dip 0x%p\n", dip); 439 440 /* Reset all Interrupts */ 441 for (ino = 0; ino < INTERRUPT_MAPPING_ENTRIES; ino++) { 442 if (px_lib_intr_devino_to_sysino(dip, ino, 443 &sysino) != DDI_SUCCESS) 444 return (BF_FATAL); 445 446 if (px_lib_intr_setstate(dip, sysino, 447 INTR_IDLE_STATE) != DDI_SUCCESS) 448 return (BF_FATAL); 449 } 450 451 return (BF_NONE); 452 } 453 454 /*ARGSUSED*/ 455 int 456 px_lib_iommu_map(dev_info_t *dip, tsbid_t tsbid, pages_t pages, 457 io_attributes_t attr, void *addr, size_t pfn_index, int flags) 458 { 459 px_t *px_p = DIP_TO_STATE(dip); 460 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 461 uint64_t ret; 462 463 DBG(DBG_LIB_DMA, dip, "px_lib_iommu_map: dip 0x%p tsbid 0x%llx " 464 "pages 0x%x attr 0x%x addr 0x%p pfn_index 0x%llx flags 0x%x\n", 465 dip, tsbid, pages, attr, addr, pfn_index, flags); 466 467 if ((ret = hvio_iommu_map(px_p->px_dev_hdl, pxu_p, tsbid, pages, 468 attr, addr, pfn_index, flags)) != H_EOK) { 469 DBG(DBG_LIB_DMA, dip, 470 "px_lib_iommu_map failed, ret 0x%lx\n", ret); 471 return (DDI_FAILURE); 472 } 473 474 return (DDI_SUCCESS); 475 } 476 477 /*ARGSUSED*/ 478 int 479 px_lib_iommu_demap(dev_info_t *dip, tsbid_t tsbid, pages_t pages) 480 { 481 px_t *px_p = DIP_TO_STATE(dip); 482 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 483 uint64_t ret; 484 485 DBG(DBG_LIB_DMA, dip, "px_lib_iommu_demap: dip 0x%p tsbid 0x%llx " 486 "pages 0x%x\n", dip, tsbid, pages); 487 488 if ((ret = hvio_iommu_demap(px_p->px_dev_hdl, pxu_p, tsbid, pages)) 489 != H_EOK) { 490 DBG(DBG_LIB_DMA, dip, 491 "px_lib_iommu_demap failed, ret 0x%lx\n", ret); 492 493 return (DDI_FAILURE); 494 } 495 496 return (DDI_SUCCESS); 497 } 498 499 /*ARGSUSED*/ 500 int 501 px_lib_iommu_getmap(dev_info_t *dip, tsbid_t tsbid, io_attributes_t *attr_p, 502 r_addr_t *r_addr_p) 503 { 504 px_t *px_p = DIP_TO_STATE(dip); 505 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 506 uint64_t ret; 507 508 DBG(DBG_LIB_DMA, dip, "px_lib_iommu_getmap: dip 0x%p tsbid 0x%llx\n", 509 dip, tsbid); 510 511 if ((ret = hvio_iommu_getmap(DIP_TO_HANDLE(dip), pxu_p, tsbid, 512 attr_p, r_addr_p)) != H_EOK) { 513 DBG(DBG_LIB_DMA, dip, 514 "hvio_iommu_getmap failed, ret 0x%lx\n", ret); 515 516 return ((ret == H_ENOMAP) ? DDI_DMA_NOMAPPING:DDI_FAILURE); 517 } 518 519 DBG(DBG_LIB_DMA, dip, "px_lib_iommu_getmap: attr 0x%x r_addr 0x%llx\n", 520 *attr_p, *r_addr_p); 521 522 return (DDI_SUCCESS); 523 } 524 525 526 /* 527 * Checks dma attributes against system bypass ranges 528 * The bypass range is determined by the hardware. Return them so the 529 * common code can do generic checking against them. 530 */ 531 /*ARGSUSED*/ 532 int 533 px_lib_dma_bypass_rngchk(ddi_dma_attr_t *attr_p, uint64_t *lo_p, uint64_t *hi_p) 534 { 535 *lo_p = MMU_BYPASS_BASE; 536 *hi_p = MMU_BYPASS_END; 537 538 return (DDI_SUCCESS); 539 } 540 541 542 /*ARGSUSED*/ 543 int 544 px_lib_iommu_getbypass(dev_info_t *dip, r_addr_t ra, io_attributes_t attr, 545 io_addr_t *io_addr_p) 546 { 547 uint64_t ret; 548 549 DBG(DBG_LIB_DMA, dip, "px_lib_iommu_getbypass: dip 0x%p ra 0x%llx " 550 "attr 0x%x\n", dip, ra, attr); 551 552 if ((ret = hvio_iommu_getbypass(DIP_TO_HANDLE(dip), ra, attr, 553 io_addr_p)) != H_EOK) { 554 DBG(DBG_LIB_DMA, dip, 555 "hvio_iommu_getbypass failed, ret 0x%lx\n", ret); 556 return (DDI_FAILURE); 557 } 558 559 DBG(DBG_LIB_DMA, dip, "px_lib_iommu_getbypass: io_addr 0x%llx\n", 560 *io_addr_p); 561 562 return (DDI_SUCCESS); 563 } 564 565 /* 566 * bus dma sync entry point. 567 */ 568 /*ARGSUSED*/ 569 int 570 px_lib_dma_sync(dev_info_t *dip, dev_info_t *rdip, ddi_dma_handle_t handle, 571 off_t off, size_t len, uint_t cache_flags) 572 { 573 ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle; 574 575 DBG(DBG_LIB_DMA, dip, "px_lib_dma_sync: dip 0x%p rdip 0x%p " 576 "handle 0x%llx off 0x%x len 0x%x flags 0x%x\n", 577 dip, rdip, handle, off, len, cache_flags); 578 579 /* 580 * jbus_stst_order is found only in certain cpu modules. 581 * Just return success if not present. 582 */ 583 if (&jbus_stst_order == NULL) 584 return (DDI_SUCCESS); 585 586 if (!(mp->dmai_flags & PX_DMAI_FLAGS_INUSE)) { 587 cmn_err(CE_WARN, "%s%d: Unbound dma handle %p.", 588 ddi_driver_name(rdip), ddi_get_instance(rdip), (void *)mp); 589 590 return (DDI_FAILURE); 591 } 592 593 if (mp->dmai_flags & PX_DMAI_FLAGS_NOSYNC) 594 return (DDI_SUCCESS); 595 596 /* 597 * No flush needed when sending data from memory to device. 598 * Nothing to do to "sync" memory to what device would already see. 599 */ 600 if (!(mp->dmai_rflags & DDI_DMA_READ) || 601 ((cache_flags & PX_DMA_SYNC_DDI_FLAGS) == DDI_DMA_SYNC_FORDEV)) 602 return (DDI_SUCCESS); 603 604 /* 605 * Perform necessary cpu workaround to ensure jbus ordering. 606 * CPU's internal "invalidate FIFOs" are flushed. 607 */ 608 609 #if !defined(lint) 610 kpreempt_disable(); 611 #endif 612 jbus_stst_order(); 613 #if !defined(lint) 614 kpreempt_enable(); 615 #endif 616 return (DDI_SUCCESS); 617 } 618 619 /* 620 * MSIQ Functions: 621 */ 622 /*ARGSUSED*/ 623 int 624 px_lib_msiq_init(dev_info_t *dip) 625 { 626 px_t *px_p = DIP_TO_STATE(dip); 627 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 628 px_msiq_state_t *msiq_state_p = &px_p->px_ib_p->ib_msiq_state; 629 caddr_t msiq_addr; 630 px_dvma_addr_t pg_index; 631 size_t size; 632 int ret; 633 634 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_init: dip 0x%p\n", dip); 635 636 /* 637 * Map the EQ memory into the Fire MMU (has to be 512KB aligned) 638 * and then initialize the base address register. 639 * 640 * Allocate entries from Fire IOMMU so that the resulting address 641 * is properly aligned. Calculate the index of the first allocated 642 * entry. Note: The size of the mapping is assumed to be a multiple 643 * of the page size. 644 */ 645 msiq_addr = (caddr_t)(((uint64_t)msiq_state_p->msiq_buf_p + 646 (MMU_PAGE_SIZE - 1)) >> MMU_PAGE_SHIFT << MMU_PAGE_SHIFT); 647 648 size = msiq_state_p->msiq_cnt * 649 msiq_state_p->msiq_rec_cnt * sizeof (msiq_rec_t); 650 651 pxu_p->msiq_mapped_p = vmem_xalloc(px_p->px_mmu_p->mmu_dvma_map, 652 size, (512 * 1024), 0, 0, NULL, NULL, VM_NOSLEEP | VM_BESTFIT); 653 654 if (pxu_p->msiq_mapped_p == NULL) 655 return (DDI_FAILURE); 656 657 pg_index = MMU_PAGE_INDEX(px_p->px_mmu_p, 658 MMU_BTOP((ulong_t)pxu_p->msiq_mapped_p)); 659 660 if ((ret = px_lib_iommu_map(px_p->px_dip, PCI_TSBID(0, pg_index), 661 MMU_BTOP(size), PCI_MAP_ATTR_WRITE, (void *)msiq_addr, 0, 662 MMU_MAP_BUF)) != DDI_SUCCESS) { 663 DBG(DBG_LIB_MSIQ, dip, 664 "hvio_msiq_init failed, ret 0x%lx\n", ret); 665 666 (void) px_lib_msiq_fini(dip); 667 return (DDI_FAILURE); 668 } 669 670 (void) hvio_msiq_init(DIP_TO_HANDLE(dip), pxu_p); 671 672 return (DDI_SUCCESS); 673 } 674 675 /*ARGSUSED*/ 676 int 677 px_lib_msiq_fini(dev_info_t *dip) 678 { 679 px_t *px_p = DIP_TO_STATE(dip); 680 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 681 px_msiq_state_t *msiq_state_p = &px_p->px_ib_p->ib_msiq_state; 682 px_dvma_addr_t pg_index; 683 size_t size; 684 685 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_fini: dip 0x%p\n", dip); 686 687 /* 688 * Unmap and free the EQ memory that had been mapped 689 * into the Fire IOMMU. 690 */ 691 size = msiq_state_p->msiq_cnt * 692 msiq_state_p->msiq_rec_cnt * sizeof (msiq_rec_t); 693 694 pg_index = MMU_PAGE_INDEX(px_p->px_mmu_p, 695 MMU_BTOP((ulong_t)pxu_p->msiq_mapped_p)); 696 697 (void) px_lib_iommu_demap(px_p->px_dip, 698 PCI_TSBID(0, pg_index), MMU_BTOP(size)); 699 700 /* Free the entries from the Fire MMU */ 701 vmem_xfree(px_p->px_mmu_p->mmu_dvma_map, 702 (void *)pxu_p->msiq_mapped_p, size); 703 704 return (DDI_SUCCESS); 705 } 706 707 /*ARGSUSED*/ 708 int 709 px_lib_msiq_info(dev_info_t *dip, msiqid_t msiq_id, r_addr_t *ra_p, 710 uint_t *msiq_rec_cnt_p) 711 { 712 px_t *px_p = DIP_TO_STATE(dip); 713 px_msiq_state_t *msiq_state_p = &px_p->px_ib_p->ib_msiq_state; 714 uint64_t *msiq_addr; 715 size_t msiq_size; 716 717 DBG(DBG_LIB_MSIQ, dip, "px_msiq_info: dip 0x%p msiq_id 0x%x\n", 718 dip, msiq_id); 719 720 msiq_addr = (uint64_t *)(((uint64_t)msiq_state_p->msiq_buf_p + 721 (MMU_PAGE_SIZE - 1)) >> MMU_PAGE_SHIFT << MMU_PAGE_SHIFT); 722 msiq_size = msiq_state_p->msiq_rec_cnt * sizeof (msiq_rec_t); 723 ra_p = (r_addr_t *)((caddr_t)msiq_addr + (msiq_id * msiq_size)); 724 725 *msiq_rec_cnt_p = msiq_state_p->msiq_rec_cnt; 726 727 DBG(DBG_LIB_MSIQ, dip, "px_msiq_info: ra_p 0x%p msiq_rec_cnt 0x%x\n", 728 ra_p, *msiq_rec_cnt_p); 729 730 return (DDI_SUCCESS); 731 } 732 733 /*ARGSUSED*/ 734 int 735 px_lib_msiq_getvalid(dev_info_t *dip, msiqid_t msiq_id, 736 pci_msiq_valid_state_t *msiq_valid_state) 737 { 738 uint64_t ret; 739 740 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_getvalid: dip 0x%p msiq_id 0x%x\n", 741 dip, msiq_id); 742 743 if ((ret = hvio_msiq_getvalid(DIP_TO_HANDLE(dip), 744 msiq_id, msiq_valid_state)) != H_EOK) { 745 DBG(DBG_LIB_MSIQ, dip, 746 "hvio_msiq_getvalid failed, ret 0x%lx\n", ret); 747 return (DDI_FAILURE); 748 } 749 750 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_getvalid: msiq_valid_state 0x%x\n", 751 *msiq_valid_state); 752 753 return (DDI_SUCCESS); 754 } 755 756 /*ARGSUSED*/ 757 int 758 px_lib_msiq_setvalid(dev_info_t *dip, msiqid_t msiq_id, 759 pci_msiq_valid_state_t msiq_valid_state) 760 { 761 uint64_t ret; 762 763 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_setvalid: dip 0x%p msiq_id 0x%x " 764 "msiq_valid_state 0x%x\n", dip, msiq_id, msiq_valid_state); 765 766 if ((ret = hvio_msiq_setvalid(DIP_TO_HANDLE(dip), 767 msiq_id, msiq_valid_state)) != H_EOK) { 768 DBG(DBG_LIB_MSIQ, dip, 769 "hvio_msiq_setvalid failed, ret 0x%lx\n", ret); 770 return (DDI_FAILURE); 771 } 772 773 return (DDI_SUCCESS); 774 } 775 776 /*ARGSUSED*/ 777 int 778 px_lib_msiq_getstate(dev_info_t *dip, msiqid_t msiq_id, 779 pci_msiq_state_t *msiq_state) 780 { 781 uint64_t ret; 782 783 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_getstate: dip 0x%p msiq_id 0x%x\n", 784 dip, msiq_id); 785 786 if ((ret = hvio_msiq_getstate(DIP_TO_HANDLE(dip), 787 msiq_id, msiq_state)) != H_EOK) { 788 DBG(DBG_LIB_MSIQ, dip, 789 "hvio_msiq_getstate failed, ret 0x%lx\n", ret); 790 return (DDI_FAILURE); 791 } 792 793 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_getstate: msiq_state 0x%x\n", 794 *msiq_state); 795 796 return (DDI_SUCCESS); 797 } 798 799 /*ARGSUSED*/ 800 int 801 px_lib_msiq_setstate(dev_info_t *dip, msiqid_t msiq_id, 802 pci_msiq_state_t msiq_state) 803 { 804 uint64_t ret; 805 806 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_setstate: dip 0x%p msiq_id 0x%x " 807 "msiq_state 0x%x\n", dip, msiq_id, msiq_state); 808 809 if ((ret = hvio_msiq_setstate(DIP_TO_HANDLE(dip), 810 msiq_id, msiq_state)) != H_EOK) { 811 DBG(DBG_LIB_MSIQ, dip, 812 "hvio_msiq_setstate failed, ret 0x%lx\n", ret); 813 return (DDI_FAILURE); 814 } 815 816 return (DDI_SUCCESS); 817 } 818 819 /*ARGSUSED*/ 820 int 821 px_lib_msiq_gethead(dev_info_t *dip, msiqid_t msiq_id, 822 msiqhead_t *msiq_head) 823 { 824 uint64_t ret; 825 826 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_gethead: dip 0x%p msiq_id 0x%x\n", 827 dip, msiq_id); 828 829 if ((ret = hvio_msiq_gethead(DIP_TO_HANDLE(dip), 830 msiq_id, msiq_head)) != H_EOK) { 831 DBG(DBG_LIB_MSIQ, dip, 832 "hvio_msiq_gethead failed, ret 0x%lx\n", ret); 833 return (DDI_FAILURE); 834 } 835 836 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_gethead: msiq_head 0x%x\n", 837 *msiq_head); 838 839 return (DDI_SUCCESS); 840 } 841 842 /*ARGSUSED*/ 843 int 844 px_lib_msiq_sethead(dev_info_t *dip, msiqid_t msiq_id, 845 msiqhead_t msiq_head) 846 { 847 uint64_t ret; 848 849 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_sethead: dip 0x%p msiq_id 0x%x " 850 "msiq_head 0x%x\n", dip, msiq_id, msiq_head); 851 852 if ((ret = hvio_msiq_sethead(DIP_TO_HANDLE(dip), 853 msiq_id, msiq_head)) != H_EOK) { 854 DBG(DBG_LIB_MSIQ, dip, 855 "hvio_msiq_sethead failed, ret 0x%lx\n", ret); 856 return (DDI_FAILURE); 857 } 858 859 return (DDI_SUCCESS); 860 } 861 862 /*ARGSUSED*/ 863 int 864 px_lib_msiq_gettail(dev_info_t *dip, msiqid_t msiq_id, 865 msiqtail_t *msiq_tail) 866 { 867 uint64_t ret; 868 869 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_gettail: dip 0x%p msiq_id 0x%x\n", 870 dip, msiq_id); 871 872 if ((ret = hvio_msiq_gettail(DIP_TO_HANDLE(dip), 873 msiq_id, msiq_tail)) != H_EOK) { 874 DBG(DBG_LIB_MSIQ, dip, 875 "hvio_msiq_gettail failed, ret 0x%lx\n", ret); 876 return (DDI_FAILURE); 877 } 878 879 DBG(DBG_LIB_MSIQ, dip, "px_lib_msiq_gettail: msiq_tail 0x%x\n", 880 *msiq_tail); 881 882 return (DDI_SUCCESS); 883 } 884 885 /*ARGSUSED*/ 886 void 887 px_lib_get_msiq_rec(dev_info_t *dip, px_msiq_t *msiq_p, msiq_rec_t *msiq_rec_p) 888 { 889 eq_rec_t *eq_rec_p = (eq_rec_t *)msiq_p->msiq_curr; 890 891 DBG(DBG_LIB_MSIQ, dip, "px_lib_get_msiq_rec: dip 0x%p eq_rec_p 0x%p\n", 892 dip, eq_rec_p); 893 894 if (!eq_rec_p->eq_rec_fmt_type) { 895 /* Set msiq_rec_type to zero */ 896 msiq_rec_p->msiq_rec_type = 0; 897 898 return; 899 } 900 901 DBG(DBG_LIB_MSIQ, dip, "px_lib_get_msiq_rec: EQ RECORD, " 902 "eq_rec_rid 0x%llx eq_rec_fmt_type 0x%llx " 903 "eq_rec_len 0x%llx eq_rec_addr0 0x%llx " 904 "eq_rec_addr1 0x%llx eq_rec_data0 0x%llx " 905 "eq_rec_data1 0x%llx\n", eq_rec_p->eq_rec_rid, 906 eq_rec_p->eq_rec_fmt_type, eq_rec_p->eq_rec_len, 907 eq_rec_p->eq_rec_addr0, eq_rec_p->eq_rec_addr1, 908 eq_rec_p->eq_rec_data0, eq_rec_p->eq_rec_data1); 909 910 /* 911 * Only upper 4 bits of eq_rec_fmt_type is used 912 * to identify the EQ record type. 913 */ 914 switch (eq_rec_p->eq_rec_fmt_type >> 3) { 915 case EQ_REC_MSI32: 916 msiq_rec_p->msiq_rec_type = MSI32_REC; 917 918 msiq_rec_p->msiq_rec_data.msi.msi_data = 919 eq_rec_p->eq_rec_data0; 920 break; 921 case EQ_REC_MSI64: 922 msiq_rec_p->msiq_rec_type = MSI64_REC; 923 924 msiq_rec_p->msiq_rec_data.msi.msi_data = 925 eq_rec_p->eq_rec_data0; 926 break; 927 case EQ_REC_MSG: 928 msiq_rec_p->msiq_rec_type = MSG_REC; 929 930 msiq_rec_p->msiq_rec_data.msg.msg_route = 931 eq_rec_p->eq_rec_fmt_type & 7; 932 msiq_rec_p->msiq_rec_data.msg.msg_targ = eq_rec_p->eq_rec_rid; 933 msiq_rec_p->msiq_rec_data.msg.msg_code = eq_rec_p->eq_rec_data0; 934 break; 935 default: 936 cmn_err(CE_WARN, "%s%d: px_lib_get_msiq_rec: " 937 "0x%x is an unknown EQ record type", 938 ddi_driver_name(dip), ddi_get_instance(dip), 939 (int)eq_rec_p->eq_rec_fmt_type); 940 break; 941 } 942 943 msiq_rec_p->msiq_rec_rid = eq_rec_p->eq_rec_rid; 944 msiq_rec_p->msiq_rec_msi_addr = ((eq_rec_p->eq_rec_addr1 << 16) | 945 (eq_rec_p->eq_rec_addr0 << 2)); 946 947 /* Zero out eq_rec_fmt_type field */ 948 eq_rec_p->eq_rec_fmt_type = 0; 949 } 950 951 /* 952 * MSI Functions: 953 */ 954 /*ARGSUSED*/ 955 int 956 px_lib_msi_init(dev_info_t *dip) 957 { 958 px_t *px_p = DIP_TO_STATE(dip); 959 px_msi_state_t *msi_state_p = &px_p->px_ib_p->ib_msi_state; 960 uint64_t ret; 961 962 DBG(DBG_LIB_MSI, dip, "px_lib_msi_init: dip 0x%p\n", dip); 963 964 if ((ret = hvio_msi_init(DIP_TO_HANDLE(dip), 965 msi_state_p->msi_addr32, msi_state_p->msi_addr64)) != H_EOK) { 966 DBG(DBG_LIB_MSIQ, dip, "px_lib_msi_init failed, ret 0x%lx\n", 967 ret); 968 return (DDI_FAILURE); 969 } 970 971 return (DDI_SUCCESS); 972 } 973 974 /*ARGSUSED*/ 975 int 976 px_lib_msi_getmsiq(dev_info_t *dip, msinum_t msi_num, 977 msiqid_t *msiq_id) 978 { 979 uint64_t ret; 980 981 DBG(DBG_LIB_MSI, dip, "px_lib_msi_getmsiq: dip 0x%p msi_num 0x%x\n", 982 dip, msi_num); 983 984 if ((ret = hvio_msi_getmsiq(DIP_TO_HANDLE(dip), 985 msi_num, msiq_id)) != H_EOK) { 986 DBG(DBG_LIB_MSI, dip, 987 "hvio_msi_getmsiq failed, ret 0x%lx\n", ret); 988 return (DDI_FAILURE); 989 } 990 991 DBG(DBG_LIB_MSI, dip, "px_lib_msi_getmsiq: msiq_id 0x%x\n", 992 *msiq_id); 993 994 return (DDI_SUCCESS); 995 } 996 997 /*ARGSUSED*/ 998 int 999 px_lib_msi_setmsiq(dev_info_t *dip, msinum_t msi_num, 1000 msiqid_t msiq_id, msi_type_t msitype) 1001 { 1002 uint64_t ret; 1003 1004 DBG(DBG_LIB_MSI, dip, "px_lib_msi_setmsiq: dip 0x%p msi_num 0x%x " 1005 "msq_id 0x%x\n", dip, msi_num, msiq_id); 1006 1007 if ((ret = hvio_msi_setmsiq(DIP_TO_HANDLE(dip), 1008 msi_num, msiq_id)) != H_EOK) { 1009 DBG(DBG_LIB_MSI, dip, 1010 "hvio_msi_setmsiq failed, ret 0x%lx\n", ret); 1011 return (DDI_FAILURE); 1012 } 1013 1014 return (DDI_SUCCESS); 1015 } 1016 1017 /*ARGSUSED*/ 1018 int 1019 px_lib_msi_getvalid(dev_info_t *dip, msinum_t msi_num, 1020 pci_msi_valid_state_t *msi_valid_state) 1021 { 1022 uint64_t ret; 1023 1024 DBG(DBG_LIB_MSI, dip, "px_lib_msi_getvalid: dip 0x%p msi_num 0x%x\n", 1025 dip, msi_num); 1026 1027 if ((ret = hvio_msi_getvalid(DIP_TO_HANDLE(dip), 1028 msi_num, msi_valid_state)) != H_EOK) { 1029 DBG(DBG_LIB_MSI, dip, 1030 "hvio_msi_getvalid failed, ret 0x%lx\n", ret); 1031 return (DDI_FAILURE); 1032 } 1033 1034 DBG(DBG_LIB_MSI, dip, "px_lib_msi_getvalid: msiq_id 0x%x\n", 1035 *msi_valid_state); 1036 1037 return (DDI_SUCCESS); 1038 } 1039 1040 /*ARGSUSED*/ 1041 int 1042 px_lib_msi_setvalid(dev_info_t *dip, msinum_t msi_num, 1043 pci_msi_valid_state_t msi_valid_state) 1044 { 1045 uint64_t ret; 1046 1047 DBG(DBG_LIB_MSI, dip, "px_lib_msi_setvalid: dip 0x%p msi_num 0x%x " 1048 "msi_valid_state 0x%x\n", dip, msi_num, msi_valid_state); 1049 1050 if ((ret = hvio_msi_setvalid(DIP_TO_HANDLE(dip), 1051 msi_num, msi_valid_state)) != H_EOK) { 1052 DBG(DBG_LIB_MSI, dip, 1053 "hvio_msi_setvalid failed, ret 0x%lx\n", ret); 1054 return (DDI_FAILURE); 1055 } 1056 1057 return (DDI_SUCCESS); 1058 } 1059 1060 /*ARGSUSED*/ 1061 int 1062 px_lib_msi_getstate(dev_info_t *dip, msinum_t msi_num, 1063 pci_msi_state_t *msi_state) 1064 { 1065 uint64_t ret; 1066 1067 DBG(DBG_LIB_MSI, dip, "px_lib_msi_getstate: dip 0x%p msi_num 0x%x\n", 1068 dip, msi_num); 1069 1070 if ((ret = hvio_msi_getstate(DIP_TO_HANDLE(dip), 1071 msi_num, msi_state)) != H_EOK) { 1072 DBG(DBG_LIB_MSI, dip, 1073 "hvio_msi_getstate failed, ret 0x%lx\n", ret); 1074 return (DDI_FAILURE); 1075 } 1076 1077 DBG(DBG_LIB_MSI, dip, "px_lib_msi_getstate: msi_state 0x%x\n", 1078 *msi_state); 1079 1080 return (DDI_SUCCESS); 1081 } 1082 1083 /*ARGSUSED*/ 1084 int 1085 px_lib_msi_setstate(dev_info_t *dip, msinum_t msi_num, 1086 pci_msi_state_t msi_state) 1087 { 1088 uint64_t ret; 1089 1090 DBG(DBG_LIB_MSI, dip, "px_lib_msi_setstate: dip 0x%p msi_num 0x%x " 1091 "msi_state 0x%x\n", dip, msi_num, msi_state); 1092 1093 if ((ret = hvio_msi_setstate(DIP_TO_HANDLE(dip), 1094 msi_num, msi_state)) != H_EOK) { 1095 DBG(DBG_LIB_MSI, dip, 1096 "hvio_msi_setstate failed, ret 0x%lx\n", ret); 1097 return (DDI_FAILURE); 1098 } 1099 1100 return (DDI_SUCCESS); 1101 } 1102 1103 /* 1104 * MSG Functions: 1105 */ 1106 /*ARGSUSED*/ 1107 int 1108 px_lib_msg_getmsiq(dev_info_t *dip, pcie_msg_type_t msg_type, 1109 msiqid_t *msiq_id) 1110 { 1111 uint64_t ret; 1112 1113 DBG(DBG_LIB_MSG, dip, "px_lib_msg_getmsiq: dip 0x%p msg_type 0x%x\n", 1114 dip, msg_type); 1115 1116 if ((ret = hvio_msg_getmsiq(DIP_TO_HANDLE(dip), 1117 msg_type, msiq_id)) != H_EOK) { 1118 DBG(DBG_LIB_MSG, dip, 1119 "hvio_msg_getmsiq failed, ret 0x%lx\n", ret); 1120 return (DDI_FAILURE); 1121 } 1122 1123 DBG(DBG_LIB_MSI, dip, "px_lib_msg_getmsiq: msiq_id 0x%x\n", 1124 *msiq_id); 1125 1126 return (DDI_SUCCESS); 1127 } 1128 1129 /*ARGSUSED*/ 1130 int 1131 px_lib_msg_setmsiq(dev_info_t *dip, pcie_msg_type_t msg_type, 1132 msiqid_t msiq_id) 1133 { 1134 uint64_t ret; 1135 1136 DBG(DBG_LIB_MSG, dip, "px_lib_msi_setstate: dip 0x%p msg_type 0x%x " 1137 "msiq_id 0x%x\n", dip, msg_type, msiq_id); 1138 1139 if ((ret = hvio_msg_setmsiq(DIP_TO_HANDLE(dip), 1140 msg_type, msiq_id)) != H_EOK) { 1141 DBG(DBG_LIB_MSG, dip, 1142 "hvio_msg_setmsiq failed, ret 0x%lx\n", ret); 1143 return (DDI_FAILURE); 1144 } 1145 1146 return (DDI_SUCCESS); 1147 } 1148 1149 /*ARGSUSED*/ 1150 int 1151 px_lib_msg_getvalid(dev_info_t *dip, pcie_msg_type_t msg_type, 1152 pcie_msg_valid_state_t *msg_valid_state) 1153 { 1154 uint64_t ret; 1155 1156 DBG(DBG_LIB_MSG, dip, "px_lib_msg_getvalid: dip 0x%p msg_type 0x%x\n", 1157 dip, msg_type); 1158 1159 if ((ret = hvio_msg_getvalid(DIP_TO_HANDLE(dip), msg_type, 1160 msg_valid_state)) != H_EOK) { 1161 DBG(DBG_LIB_MSG, dip, 1162 "hvio_msg_getvalid failed, ret 0x%lx\n", ret); 1163 return (DDI_FAILURE); 1164 } 1165 1166 DBG(DBG_LIB_MSI, dip, "px_lib_msg_getvalid: msg_valid_state 0x%x\n", 1167 *msg_valid_state); 1168 1169 return (DDI_SUCCESS); 1170 } 1171 1172 /*ARGSUSED*/ 1173 int 1174 px_lib_msg_setvalid(dev_info_t *dip, pcie_msg_type_t msg_type, 1175 pcie_msg_valid_state_t msg_valid_state) 1176 { 1177 uint64_t ret; 1178 1179 DBG(DBG_LIB_MSG, dip, "px_lib_msg_setvalid: dip 0x%p msg_type 0x%x " 1180 "msg_valid_state 0x%x\n", dip, msg_type, msg_valid_state); 1181 1182 if ((ret = hvio_msg_setvalid(DIP_TO_HANDLE(dip), msg_type, 1183 msg_valid_state)) != H_EOK) { 1184 DBG(DBG_LIB_MSG, dip, 1185 "hvio_msg_setvalid failed, ret 0x%lx\n", ret); 1186 return (DDI_FAILURE); 1187 } 1188 1189 return (DDI_SUCCESS); 1190 } 1191 1192 /* 1193 * Suspend/Resume Functions: 1194 * Currently unsupported by hypervisor 1195 */ 1196 int 1197 px_lib_suspend(dev_info_t *dip) 1198 { 1199 px_t *px_p = DIP_TO_STATE(dip); 1200 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 1201 devhandle_t dev_hdl, xbus_dev_hdl; 1202 uint64_t ret; 1203 1204 DBG(DBG_DETACH, dip, "px_lib_suspend: dip 0x%p\n", dip); 1205 1206 dev_hdl = (devhandle_t)pxu_p->px_address[PX_REG_CSR]; 1207 xbus_dev_hdl = (devhandle_t)pxu_p->px_address[PX_REG_XBC]; 1208 1209 if ((ret = hvio_suspend(dev_hdl, pxu_p)) == H_EOK) { 1210 px_p->px_cb_p->xbc_attachcnt--; 1211 if (px_p->px_cb_p->xbc_attachcnt == 0) 1212 if ((ret = hvio_cb_suspend(xbus_dev_hdl, pxu_p)) 1213 != H_EOK) 1214 px_p->px_cb_p->xbc_attachcnt++; 1215 } 1216 1217 return ((ret != H_EOK) ? DDI_FAILURE: DDI_SUCCESS); 1218 } 1219 1220 void 1221 px_lib_resume(dev_info_t *dip) 1222 { 1223 px_t *px_p = DIP_TO_STATE(dip); 1224 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 1225 devhandle_t dev_hdl, xbus_dev_hdl; 1226 devino_t pec_ino = px_p->px_inos[PX_INTR_PEC]; 1227 devino_t xbc_ino = px_p->px_inos[PX_INTR_XBC]; 1228 1229 DBG(DBG_ATTACH, dip, "px_lib_resume: dip 0x%p\n", dip); 1230 1231 dev_hdl = (devhandle_t)pxu_p->px_address[PX_REG_CSR]; 1232 xbus_dev_hdl = (devhandle_t)pxu_p->px_address[PX_REG_XBC]; 1233 1234 px_p->px_cb_p->xbc_attachcnt++; 1235 if (px_p->px_cb_p->xbc_attachcnt == 1) 1236 hvio_cb_resume(dev_hdl, xbus_dev_hdl, xbc_ino, pxu_p); 1237 hvio_resume(dev_hdl, pec_ino, pxu_p); 1238 } 1239 1240 /* 1241 * Misc Functions: 1242 * Currently unsupported by hypervisor 1243 */ 1244 uint64_t 1245 px_lib_get_cb(dev_info_t *dip) 1246 { 1247 px_t *px_p = DIP_TO_STATE(dip); 1248 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 1249 1250 return (CSR_XR((caddr_t)pxu_p->px_address[PX_REG_XBC], JBUS_SCRATCH_1)); 1251 } 1252 1253 void 1254 px_lib_set_cb(dev_info_t *dip, uint64_t val) 1255 { 1256 px_t *px_p = DIP_TO_STATE(dip); 1257 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 1258 1259 CSR_XS((caddr_t)pxu_p->px_address[PX_REG_XBC], JBUS_SCRATCH_1, val); 1260 } 1261 1262 /*ARGSUSED*/ 1263 int 1264 px_lib_map_vconfig(dev_info_t *dip, 1265 ddi_map_req_t *mp, pci_config_offset_t off, 1266 pci_regspec_t *rp, caddr_t *addrp) 1267 { 1268 /* 1269 * No special config space access services in this layer. 1270 */ 1271 return (DDI_FAILURE); 1272 } 1273 1274 void 1275 px_lib_map_attr_check(ddi_map_req_t *mp) 1276 { 1277 ddi_acc_hdl_t *hp = mp->map_handlep; 1278 1279 /* fire does not accept byte masks from PIO store merge */ 1280 if (hp->ah_acc.devacc_attr_dataorder == DDI_STORECACHING_OK_ACC) 1281 hp->ah_acc.devacc_attr_dataorder = DDI_STRICTORDER_ACC; 1282 } 1283 1284 void 1285 px_lib_clr_errs(px_t *px_p) 1286 { 1287 px_pec_t *pec_p = px_p->px_pec_p; 1288 dev_info_t *rpdip = px_p->px_dip; 1289 px_cb_t *cb_p = px_p->px_cb_p; 1290 int err = PX_OK, ret; 1291 int acctype = pec_p->pec_safeacc_type; 1292 ddi_fm_error_t derr; 1293 1294 /* Create the derr */ 1295 bzero(&derr, sizeof (ddi_fm_error_t)); 1296 derr.fme_version = DDI_FME_VERSION; 1297 derr.fme_ena = fm_ena_generate(0, FM_ENA_FMT1); 1298 derr.fme_flag = acctype; 1299 1300 if (acctype == DDI_FM_ERR_EXPECTED) { 1301 derr.fme_status = DDI_FM_NONFATAL; 1302 ndi_fm_acc_err_set(pec_p->pec_acc_hdl, &derr); 1303 } 1304 1305 mutex_enter(&cb_p->xbc_fm_mutex); 1306 1307 /* send ereport/handle/clear fire registers */ 1308 err = px_err_handle(px_p, &derr, PX_LIB_CALL, B_TRUE); 1309 1310 /* Check all child devices for errors */ 1311 ret = ndi_fm_handler_dispatch(rpdip, NULL, &derr); 1312 1313 mutex_exit(&cb_p->xbc_fm_mutex); 1314 1315 /* 1316 * PX_FATAL_HW indicates a condition recovered from Fatal-Reset, 1317 * therefore it does not cause panic. 1318 */ 1319 if ((err & (PX_FATAL_GOS | PX_FATAL_SW)) || (ret == DDI_FM_FATAL)) 1320 PX_FM_PANIC("Fatal System Port Error has occurred\n"); 1321 } 1322 1323 #ifdef DEBUG 1324 int px_peekfault_cnt = 0; 1325 int px_pokefault_cnt = 0; 1326 #endif /* DEBUG */ 1327 1328 /*ARGSUSED*/ 1329 static int 1330 px_lib_do_poke(dev_info_t *dip, dev_info_t *rdip, 1331 peekpoke_ctlops_t *in_args) 1332 { 1333 px_t *px_p = DIP_TO_STATE(dip); 1334 px_pec_t *pec_p = px_p->px_pec_p; 1335 int err = DDI_SUCCESS; 1336 on_trap_data_t otd; 1337 1338 mutex_enter(&pec_p->pec_pokefault_mutex); 1339 pec_p->pec_ontrap_data = &otd; 1340 pec_p->pec_safeacc_type = DDI_FM_ERR_POKE; 1341 1342 /* Set up protected environment. */ 1343 if (!on_trap(&otd, OT_DATA_ACCESS)) { 1344 uintptr_t tramp = otd.ot_trampoline; 1345 1346 otd.ot_trampoline = (uintptr_t)&poke_fault; 1347 err = do_poke(in_args->size, (void *)in_args->dev_addr, 1348 (void *)in_args->host_addr); 1349 otd.ot_trampoline = tramp; 1350 } else 1351 err = DDI_FAILURE; 1352 1353 px_lib_clr_errs(px_p); 1354 1355 if (otd.ot_trap & OT_DATA_ACCESS) 1356 err = DDI_FAILURE; 1357 1358 /* Take down protected environment. */ 1359 no_trap(); 1360 1361 pec_p->pec_ontrap_data = NULL; 1362 pec_p->pec_safeacc_type = DDI_FM_ERR_UNEXPECTED; 1363 mutex_exit(&pec_p->pec_pokefault_mutex); 1364 1365 #ifdef DEBUG 1366 if (err == DDI_FAILURE) 1367 px_pokefault_cnt++; 1368 #endif 1369 return (err); 1370 } 1371 1372 /*ARGSUSED*/ 1373 static int 1374 px_lib_do_caut_put(dev_info_t *dip, dev_info_t *rdip, 1375 peekpoke_ctlops_t *cautacc_ctlops_arg) 1376 { 1377 size_t size = cautacc_ctlops_arg->size; 1378 uintptr_t dev_addr = cautacc_ctlops_arg->dev_addr; 1379 uintptr_t host_addr = cautacc_ctlops_arg->host_addr; 1380 ddi_acc_impl_t *hp = (ddi_acc_impl_t *)cautacc_ctlops_arg->handle; 1381 size_t repcount = cautacc_ctlops_arg->repcount; 1382 uint_t flags = cautacc_ctlops_arg->flags; 1383 1384 px_t *px_p = DIP_TO_STATE(dip); 1385 px_pec_t *pec_p = px_p->px_pec_p; 1386 int err = DDI_SUCCESS; 1387 1388 /* 1389 * Note that i_ndi_busop_access_enter ends up grabbing the pokefault 1390 * mutex. 1391 */ 1392 i_ndi_busop_access_enter(hp->ahi_common.ah_dip, (ddi_acc_handle_t)hp); 1393 1394 pec_p->pec_ontrap_data = (on_trap_data_t *)hp->ahi_err->err_ontrap; 1395 pec_p->pec_safeacc_type = DDI_FM_ERR_EXPECTED; 1396 hp->ahi_err->err_expected = DDI_FM_ERR_EXPECTED; 1397 1398 if (!i_ddi_ontrap((ddi_acc_handle_t)hp)) { 1399 for (; repcount; repcount--) { 1400 switch (size) { 1401 1402 case sizeof (uint8_t): 1403 i_ddi_put8(hp, (uint8_t *)dev_addr, 1404 *(uint8_t *)host_addr); 1405 break; 1406 1407 case sizeof (uint16_t): 1408 i_ddi_put16(hp, (uint16_t *)dev_addr, 1409 *(uint16_t *)host_addr); 1410 break; 1411 1412 case sizeof (uint32_t): 1413 i_ddi_put32(hp, (uint32_t *)dev_addr, 1414 *(uint32_t *)host_addr); 1415 break; 1416 1417 case sizeof (uint64_t): 1418 i_ddi_put64(hp, (uint64_t *)dev_addr, 1419 *(uint64_t *)host_addr); 1420 break; 1421 } 1422 1423 host_addr += size; 1424 1425 if (flags == DDI_DEV_AUTOINCR) 1426 dev_addr += size; 1427 1428 px_lib_clr_errs(px_p); 1429 1430 if (pec_p->pec_ontrap_data->ot_trap & OT_DATA_ACCESS) { 1431 err = DDI_FAILURE; 1432 #ifdef DEBUG 1433 px_pokefault_cnt++; 1434 #endif 1435 break; 1436 } 1437 } 1438 } 1439 1440 i_ddi_notrap((ddi_acc_handle_t)hp); 1441 pec_p->pec_ontrap_data = NULL; 1442 pec_p->pec_safeacc_type = DDI_FM_ERR_UNEXPECTED; 1443 i_ndi_busop_access_exit(hp->ahi_common.ah_dip, (ddi_acc_handle_t)hp); 1444 hp->ahi_err->err_expected = DDI_FM_ERR_UNEXPECTED; 1445 1446 return (err); 1447 } 1448 1449 1450 int 1451 px_lib_ctlops_poke(dev_info_t *dip, dev_info_t *rdip, 1452 peekpoke_ctlops_t *in_args) 1453 { 1454 return (in_args->handle ? px_lib_do_caut_put(dip, rdip, in_args) : 1455 px_lib_do_poke(dip, rdip, in_args)); 1456 } 1457 1458 1459 /*ARGSUSED*/ 1460 static int 1461 px_lib_do_peek(dev_info_t *dip, peekpoke_ctlops_t *in_args) 1462 { 1463 px_t *px_p = DIP_TO_STATE(dip); 1464 px_pec_t *pec_p = px_p->px_pec_p; 1465 int err = DDI_SUCCESS; 1466 on_trap_data_t otd; 1467 1468 mutex_enter(&pec_p->pec_pokefault_mutex); 1469 pec_p->pec_safeacc_type = DDI_FM_ERR_PEEK; 1470 1471 if (!on_trap(&otd, OT_DATA_ACCESS)) { 1472 uintptr_t tramp = otd.ot_trampoline; 1473 1474 otd.ot_trampoline = (uintptr_t)&peek_fault; 1475 err = do_peek(in_args->size, (void *)in_args->dev_addr, 1476 (void *)in_args->host_addr); 1477 otd.ot_trampoline = tramp; 1478 } else 1479 err = DDI_FAILURE; 1480 1481 no_trap(); 1482 pec_p->pec_safeacc_type = DDI_FM_ERR_UNEXPECTED; 1483 mutex_exit(&pec_p->pec_pokefault_mutex); 1484 1485 #ifdef DEBUG 1486 if (err == DDI_FAILURE) 1487 px_peekfault_cnt++; 1488 #endif 1489 return (err); 1490 } 1491 1492 1493 static int 1494 px_lib_do_caut_get(dev_info_t *dip, peekpoke_ctlops_t *cautacc_ctlops_arg) 1495 { 1496 size_t size = cautacc_ctlops_arg->size; 1497 uintptr_t dev_addr = cautacc_ctlops_arg->dev_addr; 1498 uintptr_t host_addr = cautacc_ctlops_arg->host_addr; 1499 ddi_acc_impl_t *hp = (ddi_acc_impl_t *)cautacc_ctlops_arg->handle; 1500 size_t repcount = cautacc_ctlops_arg->repcount; 1501 uint_t flags = cautacc_ctlops_arg->flags; 1502 1503 px_t *px_p = DIP_TO_STATE(dip); 1504 px_pec_t *pec_p = px_p->px_pec_p; 1505 int err = DDI_SUCCESS; 1506 1507 /* 1508 * Note that i_ndi_busop_access_enter ends up grabbing the pokefault 1509 * mutex. 1510 */ 1511 i_ndi_busop_access_enter(hp->ahi_common.ah_dip, (ddi_acc_handle_t)hp); 1512 1513 pec_p->pec_ontrap_data = (on_trap_data_t *)hp->ahi_err->err_ontrap; 1514 pec_p->pec_safeacc_type = DDI_FM_ERR_EXPECTED; 1515 hp->ahi_err->err_expected = DDI_FM_ERR_EXPECTED; 1516 1517 if (repcount == 1) { 1518 if (!i_ddi_ontrap((ddi_acc_handle_t)hp)) { 1519 i_ddi_caut_get(size, (void *)dev_addr, 1520 (void *)host_addr); 1521 } else { 1522 int i; 1523 uint8_t *ff_addr = (uint8_t *)host_addr; 1524 for (i = 0; i < size; i++) 1525 *ff_addr++ = 0xff; 1526 1527 err = DDI_FAILURE; 1528 #ifdef DEBUG 1529 px_peekfault_cnt++; 1530 #endif 1531 } 1532 } else { 1533 if (!i_ddi_ontrap((ddi_acc_handle_t)hp)) { 1534 for (; repcount; repcount--) { 1535 i_ddi_caut_get(size, (void *)dev_addr, 1536 (void *)host_addr); 1537 1538 host_addr += size; 1539 1540 if (flags == DDI_DEV_AUTOINCR) 1541 dev_addr += size; 1542 } 1543 } else { 1544 err = DDI_FAILURE; 1545 #ifdef DEBUG 1546 px_peekfault_cnt++; 1547 #endif 1548 } 1549 } 1550 1551 i_ddi_notrap((ddi_acc_handle_t)hp); 1552 pec_p->pec_ontrap_data = NULL; 1553 pec_p->pec_safeacc_type = DDI_FM_ERR_UNEXPECTED; 1554 i_ndi_busop_access_exit(hp->ahi_common.ah_dip, (ddi_acc_handle_t)hp); 1555 hp->ahi_err->err_expected = DDI_FM_ERR_UNEXPECTED; 1556 1557 return (err); 1558 } 1559 1560 /*ARGSUSED*/ 1561 int 1562 px_lib_ctlops_peek(dev_info_t *dip, dev_info_t *rdip, 1563 peekpoke_ctlops_t *in_args, void *result) 1564 { 1565 result = (void *)in_args->host_addr; 1566 return (in_args->handle ? px_lib_do_caut_get(dip, in_args) : 1567 px_lib_do_peek(dip, in_args)); 1568 } 1569 1570 /* 1571 * implements PPM interface 1572 */ 1573 int 1574 px_lib_pmctl(int cmd, px_t *px_p) 1575 { 1576 ASSERT((cmd & ~PPMREQ_MASK) == PPMREQ); 1577 switch (cmd) { 1578 case PPMREQ_PRE_PWR_OFF: 1579 /* 1580 * Currently there is no device power management for 1581 * the root complex (fire). When there is we need to make 1582 * sure that it is at full power before trying to send the 1583 * PME_Turn_Off message. 1584 */ 1585 DBG(DBG_PWR, px_p->px_dip, 1586 "ioctl: request to send PME_Turn_Off\n"); 1587 return (px_goto_l23ready(px_p)); 1588 1589 case PPMREQ_PRE_PWR_ON: 1590 DBG(DBG_PWR, px_p->px_dip, "ioctl: PRE_PWR_ON request\n"); 1591 return (px_pre_pwron_check(px_p)); 1592 1593 case PPMREQ_POST_PWR_ON: 1594 DBG(DBG_PWR, px_p->px_dip, "ioctl: POST_PWR_ON request\n"); 1595 return (px_goto_l0(px_p)); 1596 1597 default: 1598 return (DDI_FAILURE); 1599 } 1600 } 1601 1602 /* 1603 * sends PME_Turn_Off message to put the link in L2/L3 ready state. 1604 * called by px_ioctl. 1605 * returns DDI_SUCCESS or DDI_FAILURE 1606 * 1. Wait for link to be in L1 state (link status reg) 1607 * 2. write to PME_Turn_off reg to boradcast 1608 * 3. set timeout 1609 * 4. If timeout, return failure. 1610 * 5. If PM_TO_Ack, wait till link is in L2/L3 ready 1611 */ 1612 static int 1613 px_goto_l23ready(px_t *px_p) 1614 { 1615 pcie_pwr_t *pwr_p; 1616 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 1617 caddr_t csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 1618 int ret = DDI_SUCCESS; 1619 clock_t end, timeleft; 1620 int mutex_held = 1; 1621 1622 /* If no PM info, return failure */ 1623 if (!PCIE_PMINFO(px_p->px_dip) || 1624 !(pwr_p = PCIE_NEXUS_PMINFO(px_p->px_dip))) 1625 return (DDI_FAILURE); 1626 1627 mutex_enter(&pwr_p->pwr_lock); 1628 mutex_enter(&px_p->px_l23ready_lock); 1629 /* Clear the PME_To_ACK receieved flag */ 1630 px_p->px_pm_flags &= ~PX_PMETOACK_RECVD; 1631 /* 1632 * When P25 is the downstream device, after receiving 1633 * PME_To_ACK, fire will go to Detect state, which causes 1634 * the link down event. Inform FMA that this is expected. 1635 * In case of all other cards complaint with the pci express 1636 * spec, this will happen when the power is re-applied. FMA 1637 * code will clear this flag after one instance of LDN. Since 1638 * there will not be a LDN event for the spec compliant cards, 1639 * we need to clear the flag after receiving PME_To_ACK. 1640 */ 1641 px_p->px_pm_flags |= PX_LDN_EXPECTED; 1642 if (px_send_pme_turnoff(csr_base) != DDI_SUCCESS) { 1643 ret = DDI_FAILURE; 1644 goto l23ready_done; 1645 } 1646 px_p->px_pm_flags |= PX_PME_TURNOFF_PENDING; 1647 1648 end = ddi_get_lbolt() + drv_usectohz(px_pme_to_ack_timeout); 1649 while (!(px_p->px_pm_flags & PX_PMETOACK_RECVD)) { 1650 timeleft = cv_timedwait(&px_p->px_l23ready_cv, 1651 &px_p->px_l23ready_lock, end); 1652 /* 1653 * if cv_timedwait returns -1, it is either 1654 * 1) timed out or 1655 * 2) there was a pre-mature wakeup but by the time 1656 * cv_timedwait is called again end < lbolt i.e. 1657 * end is in the past. 1658 * 3) By the time we make first cv_timedwait call, 1659 * end < lbolt is true. 1660 */ 1661 if (timeleft == -1) 1662 break; 1663 } 1664 if (!(px_p->px_pm_flags & PX_PMETOACK_RECVD)) { 1665 /* 1666 * Either timedout or interrupt didn't get a 1667 * chance to grab the mutex and set the flag. 1668 * release the mutex and delay for sometime. 1669 * This will 1) give a chance for interrupt to 1670 * set the flag 2) creates a delay between two 1671 * consequetive requests. 1672 */ 1673 mutex_exit(&px_p->px_l23ready_lock); 1674 delay(drv_usectohz(50 * PX_MSEC_TO_USEC)); 1675 mutex_held = 0; 1676 if (!(px_p->px_pm_flags & PX_PMETOACK_RECVD)) { 1677 ret = DDI_FAILURE; 1678 DBG(DBG_PWR, px_p->px_dip, " Timed out while waiting" 1679 " for PME_TO_ACK\n"); 1680 } 1681 } 1682 px_p->px_pm_flags &= 1683 ~(PX_PME_TURNOFF_PENDING | PX_PMETOACK_RECVD | PX_LDN_EXPECTED); 1684 1685 l23ready_done: 1686 if (mutex_held) 1687 mutex_exit(&px_p->px_l23ready_lock); 1688 /* 1689 * Wait till link is in L1 idle, if sending PME_Turn_Off 1690 * was succesful. 1691 */ 1692 if (ret == DDI_SUCCESS) { 1693 if (px_link_wait4l1idle(csr_base) != DDI_SUCCESS) { 1694 DBG(DBG_PWR, px_p->px_dip, " Link is not at L1" 1695 " even though we received PME_To_ACK.\n"); 1696 /* 1697 * Workaround for hardware bug with P25. 1698 * Due to a hardware bug with P25, link state 1699 * will be Detect state rather than L1 after 1700 * link is transitioned to L23Ready state. Since 1701 * we don't know whether link is L23ready state 1702 * without Fire's state being L1_idle, we delay 1703 * here just to make sure that we wait till link 1704 * is transitioned to L23Ready state. 1705 */ 1706 delay(drv_usectohz(100 * PX_MSEC_TO_USEC)); 1707 } 1708 pwr_p->pwr_link_lvl = PM_LEVEL_L3; 1709 1710 } 1711 mutex_exit(&pwr_p->pwr_lock); 1712 return (ret); 1713 } 1714 1715 /* 1716 * Message interrupt handler intended to be shared for both 1717 * PME and PME_TO_ACK msg handling, currently only handles 1718 * PME_To_ACK message. 1719 */ 1720 uint_t 1721 px_pmeq_intr(caddr_t arg) 1722 { 1723 px_t *px_p = (px_t *)arg; 1724 1725 DBG(DBG_PWR, px_p->px_dip, " PME_To_ACK received \n"); 1726 mutex_enter(&px_p->px_l23ready_lock); 1727 cv_broadcast(&px_p->px_l23ready_cv); 1728 if (px_p->px_pm_flags & PX_PME_TURNOFF_PENDING) { 1729 px_p->px_pm_flags |= PX_PMETOACK_RECVD; 1730 } else { 1731 /* 1732 * This maybe the second ack received. If so then, 1733 * we should be receiving it during wait4L1 stage. 1734 */ 1735 px_p->px_pmetoack_ignored++; 1736 } 1737 mutex_exit(&px_p->px_l23ready_lock); 1738 return (DDI_INTR_CLAIMED); 1739 } 1740 1741 static int 1742 px_pre_pwron_check(px_t *px_p) 1743 { 1744 pcie_pwr_t *pwr_p; 1745 1746 /* If no PM info, return failure */ 1747 if (!PCIE_PMINFO(px_p->px_dip) || 1748 !(pwr_p = PCIE_NEXUS_PMINFO(px_p->px_dip))) 1749 return (DDI_FAILURE); 1750 1751 /* 1752 * For the spec compliant downstream cards link down 1753 * is expected when the device is powered on. 1754 */ 1755 px_p->px_pm_flags |= PX_LDN_EXPECTED; 1756 return (pwr_p->pwr_link_lvl == PM_LEVEL_L3 ? DDI_SUCCESS : DDI_FAILURE); 1757 } 1758 1759 static int 1760 px_goto_l0(px_t *px_p) 1761 { 1762 pcie_pwr_t *pwr_p; 1763 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 1764 caddr_t csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 1765 int ret = DDI_SUCCESS; 1766 uint64_t time_spent = 0; 1767 1768 /* If no PM info, return failure */ 1769 if (!PCIE_PMINFO(px_p->px_dip) || 1770 !(pwr_p = PCIE_NEXUS_PMINFO(px_p->px_dip))) 1771 return (DDI_FAILURE); 1772 1773 mutex_enter(&pwr_p->pwr_lock); 1774 /* 1775 * The following link retrain activity will cause LDN and LUP event. 1776 * Receiving LDN prior to receiving LUP is expected, not an error in 1777 * this case. Receiving LUP indicates link is fully up to support 1778 * powering up down stream device, and of course any further LDN and 1779 * LUP outside this context will be error. 1780 */ 1781 px_p->px_lup_pending = 1; 1782 if (px_link_retrain(csr_base) != DDI_SUCCESS) { 1783 ret = DDI_FAILURE; 1784 goto l0_done; 1785 } 1786 1787 /* LUP event takes the order of 15ms amount of time to occur */ 1788 for (; px_p->px_lup_pending && (time_spent < px_lup_poll_to); 1789 time_spent += px_lup_poll_interval) 1790 drv_usecwait(px_lup_poll_interval); 1791 if (px_p->px_lup_pending) 1792 ret = DDI_FAILURE; 1793 l0_done: 1794 px_enable_detect_quiet(csr_base); 1795 if (ret == DDI_SUCCESS) 1796 pwr_p->pwr_link_lvl = PM_LEVEL_L0; 1797 mutex_exit(&pwr_p->pwr_lock); 1798 return (ret); 1799 } 1800 1801 /* 1802 * Extract the drivers binding name to identify which chip we're binding to. 1803 * Whenever a new bus bridge is created, the driver alias entry should be 1804 * added here to identify the device if needed. If a device isn't added, 1805 * the identity defaults to PX_CHIP_UNIDENTIFIED. 1806 */ 1807 static uint32_t 1808 px_identity_chip(px_t *px_p) 1809 { 1810 dev_info_t *dip = px_p->px_dip; 1811 char *name = ddi_binding_name(dip); 1812 uint32_t revision = 0; 1813 1814 revision = ddi_prop_get_int(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 1815 "module-revision#", 0); 1816 1817 /* Check for Fire driver binding name */ 1818 if ((strcmp(name, "pci108e,80f0") == 0) || 1819 (strcmp(name, "pciex108e,80f0") == 0)) { 1820 DBG(DBG_ATTACH, dip, "px_identity_chip: %s%d: " 1821 "name %s module-revision %d\n", ddi_driver_name(dip), 1822 ddi_get_instance(dip), name, revision); 1823 1824 return (PX_CHIP_ID(PX_CHIP_FIRE, revision, 0x00)); 1825 } 1826 1827 DBG(DBG_ATTACH, dip, "%s%d: Unknown PCI Express Host bridge %s %x\n", 1828 ddi_driver_name(dip), ddi_get_instance(dip), name, revision); 1829 1830 return (PX_CHIP_UNIDENTIFIED); 1831 } 1832 1833 int 1834 px_err_add_intr(px_fault_t *px_fault_p) 1835 { 1836 dev_info_t *dip = px_fault_p->px_fh_dip; 1837 px_t *px_p = DIP_TO_STATE(dip); 1838 1839 VERIFY(add_ivintr(px_fault_p->px_fh_sysino, PX_ERR_PIL, 1840 px_fault_p->px_err_func, (caddr_t)px_fault_p, NULL) == 0); 1841 1842 px_ib_intr_enable(px_p, intr_dist_cpuid(), px_fault_p->px_intr_ino); 1843 1844 return (DDI_SUCCESS); 1845 } 1846 1847 void 1848 px_err_rem_intr(px_fault_t *px_fault_p) 1849 { 1850 dev_info_t *dip = px_fault_p->px_fh_dip; 1851 px_t *px_p = DIP_TO_STATE(dip); 1852 1853 px_ib_intr_disable(px_p->px_ib_p, px_fault_p->px_intr_ino, 1854 IB_INTR_WAIT); 1855 1856 rem_ivintr(px_fault_p->px_fh_sysino, NULL); 1857 } 1858 1859 #ifdef FMA 1860 void 1861 px_fill_rc_status(px_fault_t *px_fault_p, pciex_rc_error_regs_t *rc_status) 1862 { 1863 /* populate the rc_status by reading the registers - TBD */ 1864 } 1865 #endif /* FMA */ 1866 1867 /* 1868 * Unprotected raw reads/writes of fabric device's config space. 1869 * Only used for temporary PCI-E Fabric Error Handling. 1870 */ 1871 uint32_t 1872 px_fab_get(px_t *px_p, pcie_req_id_t bdf, uint16_t offset) { 1873 px_ranges_t *rp = px_p->px_ranges_p; 1874 uint64_t range_prop, base_addr; 1875 int bank = PCI_REG_ADDR_G(PCI_ADDR_CONFIG); 1876 uint32_t val; 1877 1878 /* Get Fire's Physical Base Address */ 1879 range_prop = (((uint64_t)(rp[bank].parent_high & 0x7ff)) << 32) | 1880 rp[bank].parent_low; 1881 1882 /* Get config space first. */ 1883 base_addr = range_prop + PX_BDF_TO_CFGADDR(bdf, offset); 1884 1885 val = ldphysio(base_addr); 1886 1887 return (LE_32(val)); 1888 } 1889 1890 void 1891 px_fab_set(px_t *px_p, pcie_req_id_t bdf, uint16_t offset, 1892 uint32_t val) { 1893 px_ranges_t *rp = px_p->px_ranges_p; 1894 uint64_t range_prop, base_addr; 1895 int bank = PCI_REG_ADDR_G(PCI_ADDR_CONFIG); 1896 1897 /* Get Fire's Physical Base Address */ 1898 range_prop = (((uint64_t)(rp[bank].parent_high & 0x7ff)) << 32) | 1899 rp[bank].parent_low; 1900 1901 /* Get config space first. */ 1902 base_addr = range_prop + PX_BDF_TO_CFGADDR(bdf, offset); 1903 1904 stphysio(base_addr, LE_32(val)); 1905 } 1906 1907 /* 1908 * cpr callback 1909 * 1910 * disable fabric error msg interrupt prior to suspending 1911 * all device drivers; re-enable fabric error msg interrupt 1912 * after all devices are resumed. 1913 */ 1914 static boolean_t 1915 px_cpr_callb(void *arg, int code) 1916 { 1917 px_t *px_p = (px_t *)arg; 1918 px_ib_t *ib_p = px_p->px_ib_p; 1919 px_pec_t *pec_p = px_p->px_pec_p; 1920 pxu_t *pxu_p = (pxu_t *)px_p->px_plat_p; 1921 caddr_t csr_base; 1922 devino_t ce_ino, nf_ino, f_ino; 1923 px_ib_ino_info_t *ce_ino_p, *nf_ino_p, *f_ino_p; 1924 uint64_t imu_log_enable, imu_intr_enable; 1925 uint64_t imu_log_mask, imu_intr_mask; 1926 1927 ce_ino = px_msiqid_to_devino(px_p, pec_p->pec_corr_msg_msiq_id); 1928 nf_ino = px_msiqid_to_devino(px_p, pec_p->pec_non_fatal_msg_msiq_id); 1929 f_ino = px_msiqid_to_devino(px_p, pec_p->pec_fatal_msg_msiq_id); 1930 csr_base = (caddr_t)pxu_p->px_address[PX_REG_CSR]; 1931 1932 imu_log_enable = CSR_XR(csr_base, IMU_ERROR_LOG_ENABLE); 1933 imu_intr_enable = CSR_XR(csr_base, IMU_INTERRUPT_ENABLE); 1934 1935 imu_log_mask = BITMASK(IMU_ERROR_LOG_ENABLE_FATAL_MES_NOT_EN_LOG_EN) | 1936 BITMASK(IMU_ERROR_LOG_ENABLE_NONFATAL_MES_NOT_EN_LOG_EN) | 1937 BITMASK(IMU_ERROR_LOG_ENABLE_COR_MES_NOT_EN_LOG_EN); 1938 1939 imu_intr_mask = 1940 BITMASK(IMU_INTERRUPT_ENABLE_FATAL_MES_NOT_EN_S_INT_EN) | 1941 BITMASK(IMU_INTERRUPT_ENABLE_NONFATAL_MES_NOT_EN_S_INT_EN) | 1942 BITMASK(IMU_INTERRUPT_ENABLE_COR_MES_NOT_EN_S_INT_EN) | 1943 BITMASK(IMU_INTERRUPT_ENABLE_FATAL_MES_NOT_EN_P_INT_EN) | 1944 BITMASK(IMU_INTERRUPT_ENABLE_NONFATAL_MES_NOT_EN_P_INT_EN) | 1945 BITMASK(IMU_INTERRUPT_ENABLE_COR_MES_NOT_EN_P_INT_EN); 1946 1947 switch (code) { 1948 case CB_CODE_CPR_CHKPT: 1949 /* disable imu rbne on corr/nonfatal/fatal errors */ 1950 CSR_XS(csr_base, IMU_ERROR_LOG_ENABLE, 1951 imu_log_enable & (~imu_log_mask)); 1952 1953 CSR_XS(csr_base, IMU_INTERRUPT_ENABLE, 1954 imu_intr_enable & (~imu_intr_mask)); 1955 1956 /* disable CORR intr mapping */ 1957 px_ib_intr_disable(ib_p, ce_ino, IB_INTR_NOWAIT); 1958 1959 /* disable NON FATAL intr mapping */ 1960 px_ib_intr_disable(ib_p, nf_ino, IB_INTR_NOWAIT); 1961 1962 /* disable FATAL intr mapping */ 1963 px_ib_intr_disable(ib_p, f_ino, IB_INTR_NOWAIT); 1964 1965 break; 1966 1967 case CB_CODE_CPR_RESUME: 1968 mutex_enter(&ib_p->ib_ino_lst_mutex); 1969 1970 ce_ino_p = px_ib_locate_ino(ib_p, ce_ino); 1971 nf_ino_p = px_ib_locate_ino(ib_p, nf_ino); 1972 f_ino_p = px_ib_locate_ino(ib_p, f_ino); 1973 1974 /* enable CORR intr mapping */ 1975 if (ce_ino_p) 1976 px_ib_intr_enable(px_p, ce_ino_p->ino_cpuid, ce_ino); 1977 else 1978 cmn_err(CE_WARN, "px_cpr_callb: RESUME unable to " 1979 "reenable PCIe Correctable msg intr.\n"); 1980 1981 /* enable NON FATAL intr mapping */ 1982 if (nf_ino_p) 1983 px_ib_intr_enable(px_p, nf_ino_p->ino_cpuid, nf_ino); 1984 else 1985 cmn_err(CE_WARN, "px_cpr_callb: RESUME unable to " 1986 "reenable PCIe Non Fatal msg intr.\n"); 1987 1988 /* enable FATAL intr mapping */ 1989 if (f_ino_p) 1990 px_ib_intr_enable(px_p, f_ino_p->ino_cpuid, f_ino); 1991 else 1992 cmn_err(CE_WARN, "px_cpr_callb: RESUME unable to " 1993 "reenable PCIe Fatal msg intr.\n"); 1994 1995 mutex_exit(&ib_p->ib_ino_lst_mutex); 1996 1997 /* enable corr/nonfatal/fatal not enable error */ 1998 CSR_XS(csr_base, IMU_ERROR_LOG_ENABLE, (imu_log_enable | 1999 (imu_log_mask & px_imu_log_mask))); 2000 CSR_XS(csr_base, IMU_INTERRUPT_ENABLE, (imu_intr_enable | 2001 (imu_intr_mask & px_imu_intr_mask))); 2002 2003 break; 2004 } 2005 2006 return (B_TRUE); 2007 } 2008 2009 /* 2010 * add cpr callback 2011 */ 2012 void 2013 px_cpr_add_callb(px_t *px_p) 2014 { 2015 px_p->px_cprcb_id = callb_add(px_cpr_callb, (void *)px_p, 2016 CB_CL_CPR_POST_USER, "px_cpr"); 2017 } 2018 2019 /* 2020 * remove cpr callback 2021 */ 2022 void 2023 px_cpr_rem_callb(px_t *px_p) 2024 { 2025 (void) callb_delete(px_p->px_cprcb_id); 2026 } 2027 2028 /*ARGSUSED*/ 2029 int 2030 px_lib_hotplug_init(dev_info_t *dip, void *arg) 2031 { 2032 return (DDI_ENOTSUP); 2033 } 2034 2035 /*ARGSUSED*/ 2036 void 2037 px_lib_hotplug_uninit(dev_info_t *dip) 2038 { 2039 } 2040