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 /* 23 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* 28 * sun4 specific DDI implementation 29 */ 30 #include <sys/cpuvar.h> 31 #include <sys/ddi_subrdefs.h> 32 #include <sys/machsystm.h> 33 #include <sys/sunndi.h> 34 #include <sys/sysmacros.h> 35 #include <sys/ontrap.h> 36 #include <vm/seg_kmem.h> 37 #include <sys/membar.h> 38 #include <sys/dditypes.h> 39 #include <sys/ndifm.h> 40 #include <sys/fm/io/ddi.h> 41 #include <sys/ivintr.h> 42 #include <sys/bootconf.h> 43 #include <sys/conf.h> 44 #include <sys/ethernet.h> 45 #include <sys/idprom.h> 46 #include <sys/promif.h> 47 #include <sys/prom_plat.h> 48 #include <sys/systeminfo.h> 49 #include <sys/fpu/fpusystm.h> 50 #include <sys/vm.h> 51 #include <sys/ddi_isa.h> 52 #include <sys/modctl.h> 53 54 dev_info_t *get_intr_parent(dev_info_t *, dev_info_t *, 55 ddi_intr_handle_impl_t *); 56 #pragma weak get_intr_parent 57 58 int process_intr_ops(dev_info_t *, dev_info_t *, ddi_intr_op_t, 59 ddi_intr_handle_impl_t *, void *); 60 #pragma weak process_intr_ops 61 62 void cells_1275_copy(prop_1275_cell_t *, prop_1275_cell_t *, int32_t); 63 prop_1275_cell_t *cells_1275_cmp(prop_1275_cell_t *, prop_1275_cell_t *, 64 int32_t len); 65 #pragma weak cells_1275_copy 66 67 /* 68 * Wrapper for ddi_prop_lookup_int_array(). 69 * This is handy because it returns the prop length in 70 * bytes which is what most of the callers require. 71 */ 72 73 static int 74 get_prop_int_array(dev_info_t *di, char *pname, int **pval, uint_t *plen) 75 { 76 int ret; 77 78 if ((ret = ddi_prop_lookup_int_array(DDI_DEV_T_ANY, di, 79 DDI_PROP_DONTPASS, pname, pval, plen)) == DDI_PROP_SUCCESS) { 80 *plen = (*plen) * (uint_t)sizeof (int); 81 } 82 return (ret); 83 } 84 85 /* 86 * SECTION: DDI Node Configuration 87 */ 88 89 /* 90 * init_regspec_64: 91 * 92 * If the parent #size-cells is 2, convert the upa-style or 93 * safari-style reg property from 2-size cells to 1 size cell 94 * format, ignoring the size_hi, which must be zero for devices. 95 * (It won't be zero in the memory list properties in the memory 96 * nodes, but that doesn't matter here.) 97 */ 98 struct ddi_parent_private_data * 99 init_regspec_64(dev_info_t *dip) 100 { 101 struct ddi_parent_private_data *pd; 102 dev_info_t *parent; 103 int size_cells; 104 105 /* 106 * If there are no "reg"s in the child node, return. 107 */ 108 pd = ddi_get_parent_data(dip); 109 if ((pd == NULL) || (pd->par_nreg == 0)) { 110 return (pd); 111 } 112 parent = ddi_get_parent(dip); 113 114 size_cells = ddi_prop_get_int(DDI_DEV_T_ANY, parent, 115 DDI_PROP_DONTPASS, "#size-cells", 1); 116 117 if (size_cells != 1) { 118 119 int n, j; 120 struct regspec *irp; 121 struct reg_64 { 122 uint_t addr_hi, addr_lo, size_hi, size_lo; 123 }; 124 struct reg_64 *r64_rp; 125 struct regspec *rp; 126 uint_t len = 0; 127 int *reg_prop; 128 129 ASSERT(size_cells == 2); 130 131 /* 132 * We already looked the property up once before if 133 * pd is non-NULL. 134 */ 135 (void) ddi_prop_lookup_int_array(DDI_DEV_T_ANY, dip, 136 DDI_PROP_DONTPASS, OBP_REG, ®_prop, &len); 137 ASSERT(len != 0); 138 139 n = sizeof (struct reg_64) / sizeof (int); 140 n = len / n; 141 142 /* 143 * We're allocating a buffer the size of the PROM's property, 144 * but we're only using a smaller portion when we assign it 145 * to a regspec. We do this so that in the 146 * impl_ddi_sunbus_removechild function, we will 147 * always free the right amount of memory. 148 */ 149 irp = rp = (struct regspec *)reg_prop; 150 r64_rp = (struct reg_64 *)pd->par_reg; 151 152 for (j = 0; j < n; ++j, ++rp, ++r64_rp) { 153 ASSERT(r64_rp->size_hi == 0); 154 rp->regspec_bustype = r64_rp->addr_hi; 155 rp->regspec_addr = r64_rp->addr_lo; 156 rp->regspec_size = r64_rp->size_lo; 157 } 158 159 ddi_prop_free((void *)pd->par_reg); 160 pd->par_nreg = n; 161 pd->par_reg = irp; 162 } 163 return (pd); 164 } 165 166 /* 167 * Create a ddi_parent_private_data structure from the ddi properties of 168 * the dev_info node. 169 * 170 * The "reg" is required if the driver wishes to create mappings on behalf 171 * of the device. The "reg" property is assumed to be a list of at least 172 * one triplet 173 * 174 * <bustype, address, size>*1 175 * 176 * The "interrupt" property is no longer part of parent private data on 177 * sun4u. The interrupt parent is may not be the device tree parent. 178 * 179 * The "ranges" property describes the mapping of child addresses to parent 180 * addresses. 181 * 182 * N.B. struct rangespec is defined for the following default values: 183 * parent child 184 * #address-cells 2 2 185 * #size-cells 1 1 186 * This function doesn't deal with non-default cells and will not create 187 * ranges in such cases. 188 */ 189 void 190 make_ddi_ppd(dev_info_t *child, struct ddi_parent_private_data **ppd) 191 { 192 struct ddi_parent_private_data *pdptr; 193 int *reg_prop, *rng_prop; 194 uint_t reg_len = 0, rng_len = 0; 195 dev_info_t *parent; 196 int parent_addr_cells, parent_size_cells; 197 int child_addr_cells, child_size_cells; 198 199 *ppd = pdptr = kmem_zalloc(sizeof (*pdptr), KM_SLEEP); 200 201 /* 202 * root node has no parent private data, so *ppd should 203 * be initialized for naming to work properly. 204 */ 205 if ((parent = ddi_get_parent(child)) == NULL) 206 return; 207 208 /* 209 * Set reg field of parent data from "reg" property 210 */ 211 if ((get_prop_int_array(child, OBP_REG, ®_prop, ®_len) 212 == DDI_PROP_SUCCESS) && (reg_len != 0)) { 213 pdptr->par_nreg = (int)(reg_len / sizeof (struct regspec)); 214 pdptr->par_reg = (struct regspec *)reg_prop; 215 } 216 217 /* 218 * "ranges" property ... 219 * 220 * This function does not handle cases where #address-cells != 2 221 * and * min(parent, child) #size-cells != 1 (see bugid 4211124). 222 * 223 * Nexus drivers with such exceptions (e.g. pci ranges) 224 * should either create a separate function for handling 225 * ranges or not use parent private data to store ranges. 226 */ 227 228 /* root node has no ranges */ 229 if ((parent = ddi_get_parent(child)) == NULL) 230 return; 231 232 child_addr_cells = ddi_prop_get_int(DDI_DEV_T_ANY, child, 233 DDI_PROP_DONTPASS, "#address-cells", 2); 234 child_size_cells = ddi_prop_get_int(DDI_DEV_T_ANY, child, 235 DDI_PROP_DONTPASS, "#size-cells", 1); 236 parent_addr_cells = ddi_prop_get_int(DDI_DEV_T_ANY, parent, 237 DDI_PROP_DONTPASS, "#address-cells", 2); 238 parent_size_cells = ddi_prop_get_int(DDI_DEV_T_ANY, parent, 239 DDI_PROP_DONTPASS, "#size-cells", 1); 240 if (child_addr_cells != 2 || parent_addr_cells != 2 || 241 (child_size_cells != 1 && parent_size_cells != 1)) { 242 NDI_CONFIG_DEBUG((CE_NOTE, "!ranges not made in parent data; " 243 "#address-cells or #size-cells have non-default value")); 244 return; 245 } 246 247 if (get_prop_int_array(child, OBP_RANGES, &rng_prop, &rng_len) 248 == DDI_PROP_SUCCESS) { 249 pdptr->par_nrng = rng_len / (int)(sizeof (struct rangespec)); 250 pdptr->par_rng = (struct rangespec *)rng_prop; 251 } 252 } 253 254 /* 255 * Free ddi_parent_private_data structure 256 */ 257 void 258 impl_free_ddi_ppd(dev_info_t *dip) 259 { 260 struct ddi_parent_private_data *pdptr = ddi_get_parent_data(dip); 261 262 if (pdptr == NULL) 263 return; 264 265 if (pdptr->par_nrng != 0) 266 ddi_prop_free((void *)pdptr->par_rng); 267 268 if (pdptr->par_nreg != 0) 269 ddi_prop_free((void *)pdptr->par_reg); 270 271 kmem_free(pdptr, sizeof (*pdptr)); 272 ddi_set_parent_data(dip, NULL); 273 } 274 275 /* 276 * Name a child of sun busses based on the reg spec. 277 * Handles the following properties: 278 * 279 * Property value 280 * Name type 281 * 282 * reg register spec 283 * interrupts new (bus-oriented) interrupt spec 284 * ranges range spec 285 * 286 * This may be called multiple times, independent of 287 * initchild calls. 288 */ 289 static int 290 impl_sunbus_name_child(dev_info_t *child, char *name, int namelen) 291 { 292 struct ddi_parent_private_data *pdptr; 293 struct regspec *rp; 294 295 /* 296 * Fill in parent-private data and this function returns to us 297 * an indication if it used "registers" to fill in the data. 298 */ 299 if (ddi_get_parent_data(child) == NULL) { 300 make_ddi_ppd(child, &pdptr); 301 ddi_set_parent_data(child, pdptr); 302 } 303 304 /* 305 * No reg property, return null string as address 306 * (e.g. root node) 307 */ 308 name[0] = '\0'; 309 if (sparc_pd_getnreg(child) == 0) { 310 return (DDI_SUCCESS); 311 } 312 313 rp = sparc_pd_getreg(child, 0); 314 (void) snprintf(name, namelen, "%x,%x", 315 rp->regspec_bustype, rp->regspec_addr); 316 return (DDI_SUCCESS); 317 } 318 319 320 /* 321 * Called from the bus_ctl op of some drivers. 322 * to implement the DDI_CTLOPS_INITCHILD operation. 323 * 324 * NEW drivers should NOT use this function, but should declare 325 * there own initchild/uninitchild handlers. (This function assumes 326 * the layout of the parent private data and the format of "reg", 327 * "ranges", "interrupts" properties and that #address-cells and 328 * #size-cells of the parent bus are defined to be default values.) 329 */ 330 int 331 impl_ddi_sunbus_initchild(dev_info_t *child) 332 { 333 char name[MAXNAMELEN]; 334 335 (void) impl_sunbus_name_child(child, name, MAXNAMELEN); 336 ddi_set_name_addr(child, name); 337 338 /* 339 * Try to merge .conf node. If successful, return failure to 340 * remove this child. 341 */ 342 if ((ndi_dev_is_persistent_node(child) == 0) && 343 (ndi_merge_node(child, impl_sunbus_name_child) == DDI_SUCCESS)) { 344 impl_ddi_sunbus_removechild(child); 345 return (DDI_FAILURE); 346 } 347 return (DDI_SUCCESS); 348 } 349 350 /* 351 * A better name for this function would be impl_ddi_sunbus_uninitchild() 352 * It does not remove the child, it uninitializes it, reclaiming the 353 * resources taken by impl_ddi_sunbus_initchild. 354 */ 355 void 356 impl_ddi_sunbus_removechild(dev_info_t *dip) 357 { 358 impl_free_ddi_ppd(dip); 359 ddi_set_name_addr(dip, NULL); 360 /* 361 * Strip the node to properly convert it back to prototype form 362 */ 363 impl_rem_dev_props(dip); 364 } 365 366 /* 367 * SECTION: DDI Interrupt 368 */ 369 370 void 371 cells_1275_copy(prop_1275_cell_t *from, prop_1275_cell_t *to, int32_t len) 372 { 373 int i; 374 for (i = 0; i < len; i++) 375 *to = *from; 376 } 377 378 prop_1275_cell_t * 379 cells_1275_cmp(prop_1275_cell_t *cell1, prop_1275_cell_t *cell2, int32_t len) 380 { 381 prop_1275_cell_t *match_cell = 0; 382 int32_t i; 383 384 for (i = 0; i < len; i++) 385 if (cell1[i] != cell2[i]) { 386 match_cell = &cell1[i]; 387 break; 388 } 389 390 return (match_cell); 391 } 392 393 /* 394 * get_intr_parent() is a generic routine that process a 1275 interrupt 395 * map (imap) property. This function returns a dev_info_t structure 396 * which claims ownership of the interrupt domain. 397 * It also returns the new interrupt translation within this new domain. 398 * If an interrupt-parent or interrupt-map property are not found, 399 * then we fallback to using the device tree's parent. 400 * 401 * imap entry format: 402 * <reg>,<interrupt>,<phandle>,<translated interrupt> 403 * reg - The register specification in the interrupts domain 404 * interrupt - The interrupt specification 405 * phandle - PROM handle of the device that owns the xlated interrupt domain 406 * translated interrupt - interrupt specifier in the parents domain 407 * note: <reg>,<interrupt> - The reg and interrupt can be combined to create 408 * a unique entry called a unit interrupt specifier. 409 * 410 * Here's the processing steps: 411 * step1 - If the interrupt-parent property exists, create the ispec and 412 * return the dip of the interrupt parent. 413 * step2 - Extract the interrupt-map property and the interrupt-map-mask 414 * If these don't exist, just return the device tree parent. 415 * step3 - build up the unit interrupt specifier to match against the 416 * interrupt map property 417 * step4 - Scan the interrupt-map property until a match is found 418 * step4a - Extract the interrupt parent 419 * step4b - Compare the unit interrupt specifier 420 */ 421 dev_info_t * 422 get_intr_parent(dev_info_t *pdip, dev_info_t *dip, ddi_intr_handle_impl_t *hdlp) 423 { 424 prop_1275_cell_t *imap, *imap_mask, *scan, *reg_p, *match_req; 425 int32_t imap_sz, imap_cells, imap_scan_cells, imap_mask_sz, 426 addr_cells, intr_cells, reg_len, i, j; 427 int32_t match_found = 0; 428 dev_info_t *intr_parent_dip = NULL; 429 uint32_t *intr = &hdlp->ih_vector; 430 uint32_t nodeid; 431 #ifdef DEBUG 432 static int debug = 0; 433 #endif 434 435 /* 436 * step1 437 * If we have an interrupt-parent property, this property represents 438 * the nodeid of our interrupt parent. 439 */ 440 if ((nodeid = ddi_getprop(DDI_DEV_T_ANY, dip, 0, 441 "interrupt-parent", -1)) != -1) { 442 intr_parent_dip = e_ddi_nodeid_to_dip(nodeid); 443 ASSERT(intr_parent_dip); 444 445 /* 446 * Attach the interrupt parent. 447 * 448 * N.B. e_ddi_nodeid_to_dip() isn't safe under DR. 449 * Also, interrupt parent isn't held. This needs 450 * to be revisited if DR-capable platforms implement 451 * interrupt redirection. 452 */ 453 if (i_ddi_attach_node_hierarchy(intr_parent_dip) 454 != DDI_SUCCESS) { 455 ndi_rele_devi(intr_parent_dip); 456 return (NULL); 457 } 458 459 return (intr_parent_dip); 460 } 461 462 /* 463 * step2 464 * Get interrupt map structure from PROM property 465 */ 466 if (ddi_getlongprop(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS, 467 "interrupt-map", (caddr_t)&imap, &imap_sz) 468 != DDI_PROP_SUCCESS) { 469 /* 470 * If we don't have an imap property, default to using the 471 * device tree. 472 */ 473 474 ndi_hold_devi(pdip); 475 return (pdip); 476 } 477 478 /* Get the interrupt mask property */ 479 if (ddi_getlongprop(DDI_DEV_T_ANY, pdip, DDI_PROP_DONTPASS, 480 "interrupt-map-mask", (caddr_t)&imap_mask, &imap_mask_sz) 481 != DDI_PROP_SUCCESS) { 482 /* 483 * If we don't find this property, we have to fail the request 484 * because the 1275 imap property wasn't defined correctly. 485 */ 486 ASSERT(intr_parent_dip == NULL); 487 goto exit2; 488 } 489 490 /* Get the address cell size */ 491 addr_cells = ddi_getprop(DDI_DEV_T_ANY, pdip, 0, 492 "#address-cells", 2); 493 494 /* Get the interrupts cell size */ 495 intr_cells = ddi_getprop(DDI_DEV_T_ANY, pdip, 0, 496 "#interrupt-cells", 1); 497 498 /* 499 * step3 500 * Now lets build up the unit interrupt specifier e.g. reg,intr 501 * and apply the imap mask. match_req will hold this when we're 502 * through. 503 */ 504 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, "reg", 505 (caddr_t)®_p, ®_len) != DDI_SUCCESS) { 506 ASSERT(intr_parent_dip == NULL); 507 goto exit3; 508 } 509 510 match_req = kmem_alloc(CELLS_1275_TO_BYTES(addr_cells) + 511 CELLS_1275_TO_BYTES(intr_cells), KM_SLEEP); 512 513 for (i = 0; i < addr_cells; i++) 514 match_req[i] = (reg_p[i] & imap_mask[i]); 515 516 for (j = 0; j < intr_cells; i++, j++) 517 match_req[i] = (intr[j] & imap_mask[i]); 518 519 /* Calculate the imap size in cells */ 520 imap_cells = BYTES_TO_1275_CELLS(imap_sz); 521 522 #ifdef DEBUG 523 if (debug) 524 prom_printf("reg cell size 0x%x, intr cell size 0x%x, " 525 "match_request 0x%p, imap 0x%p\n", addr_cells, intr_cells, 526 (void *)match_req, (void *)imap); 527 #endif 528 529 /* 530 * Scan the imap property looking for a match of the interrupt unit 531 * specifier. This loop is rather complex since the data within the 532 * imap property may vary in size. 533 */ 534 for (scan = imap, imap_scan_cells = i = 0; 535 imap_scan_cells < imap_cells; scan += i, imap_scan_cells += i) { 536 int new_intr_cells; 537 538 /* Set the index to the nodeid field */ 539 i = addr_cells + intr_cells; 540 541 /* 542 * step4a 543 * Translate the nodeid field to a dip 544 */ 545 ASSERT(intr_parent_dip == NULL); 546 intr_parent_dip = e_ddi_nodeid_to_dip((uint_t)scan[i++]); 547 548 ASSERT(intr_parent_dip != 0); 549 #ifdef DEBUG 550 if (debug) 551 prom_printf("scan 0x%p\n", (void *)scan); 552 #endif 553 /* 554 * The tmp_dip describes the new domain, get it's interrupt 555 * cell size 556 */ 557 new_intr_cells = ddi_getprop(DDI_DEV_T_ANY, intr_parent_dip, 0, 558 "#interrupts-cells", 1); 559 560 /* 561 * step4b 562 * See if we have a match on the interrupt unit specifier 563 */ 564 if (cells_1275_cmp(match_req, scan, addr_cells + intr_cells) 565 == 0) { 566 uint32_t *intr; 567 568 match_found = 1; 569 570 /* 571 * If we have an imap parent whose not in our device 572 * tree path, we need to hold and install that driver. 573 */ 574 if (i_ddi_attach_node_hierarchy(intr_parent_dip) 575 != DDI_SUCCESS) { 576 ndi_rele_devi(intr_parent_dip); 577 intr_parent_dip = (dev_info_t *)NULL; 578 goto exit4; 579 } 580 581 /* 582 * We need to handcraft an ispec along with a bus 583 * interrupt value, so we can dup it into our 584 * standard ispec structure. 585 */ 586 /* Extract the translated interrupt information */ 587 intr = kmem_alloc( 588 CELLS_1275_TO_BYTES(new_intr_cells), KM_SLEEP); 589 590 for (j = 0; j < new_intr_cells; j++, i++) 591 intr[j] = scan[i]; 592 593 cells_1275_copy(intr, &hdlp->ih_vector, new_intr_cells); 594 595 kmem_free(intr, CELLS_1275_TO_BYTES(new_intr_cells)); 596 597 #ifdef DEBUG 598 if (debug) 599 prom_printf("dip 0x%p\n", 600 (void *)intr_parent_dip); 601 #endif 602 break; 603 } else { 604 #ifdef DEBUG 605 if (debug) 606 prom_printf("dip 0x%p\n", 607 (void *)intr_parent_dip); 608 #endif 609 ndi_rele_devi(intr_parent_dip); 610 intr_parent_dip = NULL; 611 i += new_intr_cells; 612 } 613 } 614 615 /* 616 * If we haven't found our interrupt parent at this point, fallback 617 * to using the device tree. 618 */ 619 if (!match_found) { 620 ndi_hold_devi(pdip); 621 ASSERT(intr_parent_dip == NULL); 622 intr_parent_dip = pdip; 623 } 624 625 ASSERT(intr_parent_dip != NULL); 626 627 exit4: 628 kmem_free(reg_p, reg_len); 629 kmem_free(match_req, CELLS_1275_TO_BYTES(addr_cells) + 630 CELLS_1275_TO_BYTES(intr_cells)); 631 632 exit3: 633 kmem_free(imap_mask, imap_mask_sz); 634 635 exit2: 636 kmem_free(imap, imap_sz); 637 638 return (intr_parent_dip); 639 } 640 641 /* 642 * process_intr_ops: 643 * 644 * Process the interrupt op via the interrupt parent. 645 */ 646 int 647 process_intr_ops(dev_info_t *pdip, dev_info_t *rdip, ddi_intr_op_t op, 648 ddi_intr_handle_impl_t *hdlp, void *result) 649 { 650 int ret = DDI_FAILURE; 651 652 if (NEXUS_HAS_INTR_OP(pdip)) { 653 ret = (*(DEVI(pdip)->devi_ops->devo_bus_ops-> 654 bus_intr_op)) (pdip, rdip, op, hdlp, result); 655 } else { 656 cmn_err(CE_WARN, "Failed to process interrupt " 657 "for %s%d due to down-rev nexus driver %s%d", 658 ddi_get_name(rdip), ddi_get_instance(rdip), 659 ddi_get_name(pdip), ddi_get_instance(pdip)); 660 } 661 662 return (ret); 663 } 664 665 /*ARGSUSED*/ 666 uint_t 667 softlevel1(caddr_t arg) 668 { 669 softint(); 670 return (1); 671 } 672 673 /* 674 * indirection table, to save us some large switch statements 675 * NOTE: This must agree with "INTLEVEL_foo" constants in 676 * <sys/avintr.h> 677 */ 678 struct autovec *const vectorlist[] = { 0 }; 679 680 /* 681 * This value is exported here for the functions in avintr.c 682 */ 683 const uint_t maxautovec = (sizeof (vectorlist) / sizeof (vectorlist[0])); 684 685 /* 686 * Check for machine specific interrupt levels which cannot be reassigned by 687 * settrap(), sun4u version. 688 * 689 * sun4u does not support V8 SPARC "fast trap" handlers. 690 */ 691 /*ARGSUSED*/ 692 int 693 exclude_settrap(int lvl) 694 { 695 return (1); 696 } 697 698 /* 699 * Check for machine specific interrupt levels which cannot have interrupt 700 * handlers added. We allow levels 1 through 15; level 0 is nonsense. 701 */ 702 /*ARGSUSED*/ 703 int 704 exclude_level(int lvl) 705 { 706 return ((lvl < 1) || (lvl > 15)); 707 } 708 709 /* 710 * Wrapper functions used by New DDI interrupt framework. 711 */ 712 713 /* 714 * i_ddi_intr_ops: 715 */ 716 int 717 i_ddi_intr_ops(dev_info_t *dip, dev_info_t *rdip, ddi_intr_op_t op, 718 ddi_intr_handle_impl_t *hdlp, void *result) 719 { 720 dev_info_t *pdip = ddi_get_parent(dip); 721 int ret = DDI_FAILURE; 722 723 /* 724 * The following check is required to address 725 * one of the test case of ADDI test suite. 726 */ 727 if (pdip == NULL) 728 return (DDI_FAILURE); 729 730 if (hdlp->ih_type != DDI_INTR_TYPE_FIXED) 731 return (process_intr_ops(pdip, rdip, op, hdlp, result)); 732 733 if (hdlp->ih_vector == 0) 734 hdlp->ih_vector = i_ddi_get_inum(rdip, hdlp->ih_inum); 735 736 if (hdlp->ih_pri == 0) 737 hdlp->ih_pri = i_ddi_get_intr_pri(rdip, hdlp->ih_inum); 738 739 switch (op) { 740 case DDI_INTROP_ADDISR: 741 case DDI_INTROP_REMISR: 742 case DDI_INTROP_GETTARGET: 743 case DDI_INTROP_SETTARGET: 744 case DDI_INTROP_ENABLE: 745 case DDI_INTROP_DISABLE: 746 case DDI_INTROP_BLOCKENABLE: 747 case DDI_INTROP_BLOCKDISABLE: 748 /* 749 * Try and determine our parent and possibly an interrupt 750 * translation. intr parent dip returned held 751 */ 752 if ((pdip = get_intr_parent(pdip, dip, hdlp)) == NULL) 753 goto done; 754 } 755 756 ret = process_intr_ops(pdip, rdip, op, hdlp, result); 757 758 done: 759 switch (op) { 760 case DDI_INTROP_ADDISR: 761 case DDI_INTROP_REMISR: 762 case DDI_INTROP_ENABLE: 763 case DDI_INTROP_DISABLE: 764 case DDI_INTROP_BLOCKENABLE: 765 case DDI_INTROP_BLOCKDISABLE: 766 /* Release hold acquired in get_intr_parent() */ 767 if (pdip) 768 ndi_rele_devi(pdip); 769 } 770 771 hdlp->ih_vector = 0; 772 773 return (ret); 774 } 775 776 /* 777 * i_ddi_add_ivintr: 778 */ 779 /*ARGSUSED*/ 780 int 781 i_ddi_add_ivintr(ddi_intr_handle_impl_t *hdlp) 782 { 783 /* 784 * If the PIL was set and is valid use it, otherwise 785 * default it to 1 786 */ 787 if ((hdlp->ih_pri < 1) || (hdlp->ih_pri > PIL_MAX)) 788 hdlp->ih_pri = 1; 789 790 VERIFY(add_ivintr(hdlp->ih_vector, hdlp->ih_pri, 791 (intrfunc)hdlp->ih_cb_func, hdlp->ih_cb_arg1, 792 hdlp->ih_cb_arg2, NULL) == 0); 793 794 return (DDI_SUCCESS); 795 } 796 797 /* 798 * i_ddi_rem_ivintr: 799 */ 800 /*ARGSUSED*/ 801 void 802 i_ddi_rem_ivintr(ddi_intr_handle_impl_t *hdlp) 803 { 804 VERIFY(rem_ivintr(hdlp->ih_vector, hdlp->ih_pri) == 0); 805 } 806 807 /* 808 * i_ddi_get_inum - Get the interrupt number property from the 809 * specified device. Note that this function is called only for 810 * the FIXED interrupt type. 811 */ 812 uint32_t 813 i_ddi_get_inum(dev_info_t *dip, uint_t inumber) 814 { 815 int32_t intrlen, intr_cells, max_intrs; 816 prop_1275_cell_t *ip, intr_sz; 817 uint32_t intr = 0; 818 819 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS | 820 DDI_PROP_CANSLEEP, 821 "interrupts", (caddr_t)&ip, &intrlen) == DDI_SUCCESS) { 822 823 intr_cells = ddi_getprop(DDI_DEV_T_ANY, dip, 0, 824 "#interrupt-cells", 1); 825 826 /* adjust for number of bytes */ 827 intr_sz = CELLS_1275_TO_BYTES(intr_cells); 828 829 /* Calculate the number of interrupts */ 830 max_intrs = intrlen / intr_sz; 831 832 if (inumber < max_intrs) { 833 prop_1275_cell_t *intrp = ip; 834 835 /* Index into interrupt property */ 836 intrp += (inumber * intr_cells); 837 838 cells_1275_copy(intrp, &intr, intr_cells); 839 } 840 841 kmem_free(ip, intrlen); 842 } 843 844 return (intr); 845 } 846 847 /* 848 * i_ddi_get_intr_pri - Get the interrupt-priorities property from 849 * the specified device. Note that this function is called only for 850 * the FIXED interrupt type. 851 */ 852 uint32_t 853 i_ddi_get_intr_pri(dev_info_t *dip, uint_t inumber) 854 { 855 uint32_t *intr_prio_p; 856 uint32_t pri = 0; 857 int32_t i; 858 859 /* 860 * Use the "interrupt-priorities" property to determine the 861 * the pil/ipl for the interrupt handler. 862 */ 863 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS, 864 "interrupt-priorities", (caddr_t)&intr_prio_p, 865 &i) == DDI_SUCCESS) { 866 if (inumber < (i / sizeof (int32_t))) 867 pri = intr_prio_p[inumber]; 868 kmem_free(intr_prio_p, i); 869 } 870 871 return (pri); 872 } 873 874 int 875 i_ddi_get_intx_nintrs(dev_info_t *dip) 876 { 877 int32_t intrlen; 878 prop_1275_cell_t intr_sz; 879 prop_1275_cell_t *ip; 880 int32_t ret = 0; 881 882 if (ddi_getlongprop(DDI_DEV_T_ANY, dip, DDI_PROP_DONTPASS | 883 DDI_PROP_CANSLEEP, 884 "interrupts", (caddr_t)&ip, &intrlen) == DDI_SUCCESS) { 885 886 intr_sz = ddi_getprop(DDI_DEV_T_ANY, dip, 0, 887 "#interrupt-cells", 1); 888 /* adjust for number of bytes */ 889 intr_sz = CELLS_1275_TO_BYTES(intr_sz); 890 891 ret = intrlen / intr_sz; 892 893 kmem_free(ip, intrlen); 894 } 895 896 return (ret); 897 } 898 899 /* 900 * i_ddi_add_softint - allocate and add a software interrupt. 901 * 902 * NOTE: All software interrupts that are registered through DDI 903 * should be triggered only on a single target or CPU. 904 */ 905 int 906 i_ddi_add_softint(ddi_softint_hdl_impl_t *hdlp) 907 { 908 if ((hdlp->ih_private = (void *)add_softintr(hdlp->ih_pri, 909 hdlp->ih_cb_func, hdlp->ih_cb_arg1, SOFTINT_ST)) == NULL) 910 return (DDI_FAILURE); 911 912 return (DDI_SUCCESS); 913 } 914 915 /* 916 * i_ddi_remove_softint - remove and free a software interrupt. 917 */ 918 void 919 i_ddi_remove_softint(ddi_softint_hdl_impl_t *hdlp) 920 { 921 ASSERT(hdlp->ih_private != NULL); 922 923 if (rem_softintr((uint64_t)hdlp->ih_private) == 0) 924 hdlp->ih_private = NULL; 925 } 926 927 /* 928 * i_ddi_trigger_softint - trigger a software interrupt. 929 */ 930 int 931 i_ddi_trigger_softint(ddi_softint_hdl_impl_t *hdlp, void *arg2) 932 { 933 int ret; 934 935 ASSERT(hdlp->ih_private != NULL); 936 937 /* Update the second argument for the software interrupt */ 938 if ((ret = update_softint_arg2((uint64_t)hdlp->ih_private, arg2)) == 0) 939 setsoftint((uint64_t)hdlp->ih_private); 940 941 return (ret ? DDI_EPENDING : DDI_SUCCESS); 942 } 943 944 /* 945 * i_ddi_set_softint_pri - change software interrupt priority. 946 */ 947 /* ARGSUSED */ 948 int 949 i_ddi_set_softint_pri(ddi_softint_hdl_impl_t *hdlp, uint_t old_pri) 950 { 951 int ret; 952 953 ASSERT(hdlp->ih_private != NULL); 954 955 /* Update the interrupt priority for the software interrupt */ 956 ret = update_softint_pri((uint64_t)hdlp->ih_private, hdlp->ih_pri); 957 958 return (ret ? DDI_FAILURE : DDI_SUCCESS); 959 } 960 961 /*ARGSUSED*/ 962 void 963 i_ddi_alloc_intr_phdl(ddi_intr_handle_impl_t *hdlp) 964 { 965 } 966 967 /*ARGSUSED*/ 968 void 969 i_ddi_free_intr_phdl(ddi_intr_handle_impl_t *hdlp) 970 { 971 } 972 973 /* 974 * SECTION: DDI Memory/DMA 975 */ 976 977 /* set HAT endianess attributes from ddi_device_acc_attr */ 978 void 979 i_ddi_devacc_to_hatacc(ddi_device_acc_attr_t *devaccp, uint_t *hataccp) 980 { 981 if (devaccp != NULL) { 982 if (devaccp->devacc_attr_endian_flags == DDI_STRUCTURE_LE_ACC) { 983 *hataccp &= ~HAT_ENDIAN_MASK; 984 *hataccp |= HAT_STRUCTURE_LE; 985 } 986 } 987 } 988 989 /* 990 * Check if the specified cache attribute is supported on the platform. 991 * This function must be called before i_ddi_cacheattr_to_hatacc(). 992 */ 993 boolean_t 994 i_ddi_check_cache_attr(uint_t flags) 995 { 996 /* 997 * The cache attributes are mutually exclusive. Any combination of 998 * the attributes leads to a failure. 999 */ 1000 uint_t cache_attr = IOMEM_CACHE_ATTR(flags); 1001 if ((cache_attr != 0) && ((cache_attr & (cache_attr - 1)) != 0)) 1002 return (B_FALSE); 1003 1004 /* 1005 * On the sparc architecture, only IOMEM_DATA_CACHED is meaningful, 1006 * but others lead to a failure. 1007 */ 1008 if (cache_attr & IOMEM_DATA_CACHED) 1009 return (B_TRUE); 1010 else 1011 return (B_FALSE); 1012 } 1013 1014 /* set HAT cache attributes from the cache attributes */ 1015 void 1016 i_ddi_cacheattr_to_hatacc(uint_t flags, uint_t *hataccp) 1017 { 1018 uint_t cache_attr = IOMEM_CACHE_ATTR(flags); 1019 static char *fname = "i_ddi_cacheattr_to_hatacc"; 1020 #if defined(lint) 1021 *hataccp = *hataccp; 1022 #endif 1023 /* 1024 * set HAT attrs according to the cache attrs. 1025 */ 1026 switch (cache_attr) { 1027 /* 1028 * The cache coherency is always maintained on SPARC, and 1029 * nothing is required. 1030 */ 1031 case IOMEM_DATA_CACHED: 1032 break; 1033 /* 1034 * Both IOMEM_DATA_UC_WRITE_COMBINED and IOMEM_DATA_UNCACHED are 1035 * not supported on SPARC -- this case must not occur because the 1036 * cache attribute is scrutinized before this function is called. 1037 */ 1038 case IOMEM_DATA_UNCACHED: 1039 case IOMEM_DATA_UC_WR_COMBINE: 1040 default: 1041 cmn_err(CE_WARN, "%s: cache_attr=0x%x is ignored.", 1042 fname, cache_attr); 1043 } 1044 } 1045 1046 static vmem_t *little_endian_arena; 1047 static vmem_t *big_endian_arena; 1048 1049 static void * 1050 segkmem_alloc_le(vmem_t *vmp, size_t size, int flag) 1051 { 1052 return (segkmem_xalloc(vmp, NULL, size, flag, HAT_STRUCTURE_LE, 1053 segkmem_page_create, NULL)); 1054 } 1055 1056 static void * 1057 segkmem_alloc_be(vmem_t *vmp, size_t size, int flag) 1058 { 1059 return (segkmem_xalloc(vmp, NULL, size, flag, HAT_STRUCTURE_BE, 1060 segkmem_page_create, NULL)); 1061 } 1062 1063 void 1064 ka_init(void) 1065 { 1066 little_endian_arena = vmem_create("little_endian", NULL, 0, 1, 1067 segkmem_alloc_le, segkmem_free, heap_arena, 0, VM_SLEEP); 1068 big_endian_arena = vmem_create("big_endian", NULL, 0, 1, 1069 segkmem_alloc_be, segkmem_free, heap_arena, 0, VM_SLEEP); 1070 } 1071 1072 /* 1073 * Allocate from the system, aligned on a specific boundary. 1074 * The alignment, if non-zero, must be a power of 2. 1075 */ 1076 static void * 1077 kalloca(size_t size, size_t align, int cansleep, uint_t endian_flags) 1078 { 1079 size_t *addr, *raddr, rsize; 1080 size_t hdrsize = 4 * sizeof (size_t); /* must be power of 2 */ 1081 1082 align = MAX(align, hdrsize); 1083 ASSERT((align & (align - 1)) == 0); 1084 1085 /* 1086 * We need to allocate 1087 * rsize = size + hdrsize + align - MIN(hdrsize, buffer_alignment) 1088 * bytes to be sure we have enough freedom to satisfy the request. 1089 * Since the buffer alignment depends on the request size, this is 1090 * not straightforward to use directly. 1091 * 1092 * kmem guarantees that any allocation of a 64-byte multiple will be 1093 * 64-byte aligned. Since rounding up the request could add more 1094 * than we save, we compute the size with and without alignment, and 1095 * use the smaller of the two. 1096 */ 1097 rsize = size + hdrsize + align; 1098 1099 if (endian_flags == DDI_STRUCTURE_LE_ACC) { 1100 raddr = vmem_alloc(little_endian_arena, rsize, 1101 cansleep ? VM_SLEEP : VM_NOSLEEP); 1102 } else { 1103 raddr = vmem_alloc(big_endian_arena, rsize, 1104 cansleep ? VM_SLEEP : VM_NOSLEEP); 1105 } 1106 1107 if (raddr == NULL) 1108 return (NULL); 1109 1110 addr = (size_t *)P2ROUNDUP((uintptr_t)raddr + hdrsize, align); 1111 ASSERT((uintptr_t)addr + size - (uintptr_t)raddr <= rsize); 1112 1113 addr[-3] = (size_t)endian_flags; 1114 addr[-2] = (size_t)raddr; 1115 addr[-1] = rsize; 1116 1117 return (addr); 1118 } 1119 1120 static void 1121 kfreea(void *addr) 1122 { 1123 size_t *saddr = addr; 1124 1125 if (saddr[-3] == DDI_STRUCTURE_LE_ACC) 1126 vmem_free(little_endian_arena, (void *)saddr[-2], saddr[-1]); 1127 else 1128 vmem_free(big_endian_arena, (void *)saddr[-2], saddr[-1]); 1129 } 1130 1131 int 1132 i_ddi_mem_alloc(dev_info_t *dip, ddi_dma_attr_t *attr, 1133 size_t length, int cansleep, int flags, 1134 ddi_device_acc_attr_t *accattrp, 1135 caddr_t *kaddrp, size_t *real_length, ddi_acc_hdl_t *handlep) 1136 { 1137 caddr_t a; 1138 int iomin, align, streaming; 1139 uint_t endian_flags = DDI_NEVERSWAP_ACC; 1140 1141 #if defined(lint) 1142 *handlep = *handlep; 1143 #endif 1144 1145 /* 1146 * Check legality of arguments 1147 */ 1148 if (length == 0 || kaddrp == NULL || attr == NULL) { 1149 return (DDI_FAILURE); 1150 } 1151 1152 if (attr->dma_attr_minxfer == 0 || attr->dma_attr_align == 0 || 1153 (attr->dma_attr_align & (attr->dma_attr_align - 1)) || 1154 (attr->dma_attr_minxfer & (attr->dma_attr_minxfer - 1))) { 1155 return (DDI_FAILURE); 1156 } 1157 1158 /* 1159 * check if a streaming sequential xfer is requested. 1160 */ 1161 streaming = (flags & DDI_DMA_STREAMING) ? 1 : 0; 1162 1163 /* 1164 * Drivers for 64-bit capable SBus devices will encode 1165 * the burtsizes for 64-bit xfers in the upper 16-bits. 1166 * For DMA alignment, we use the most restrictive 1167 * alignment of 32-bit and 64-bit xfers. 1168 */ 1169 iomin = (attr->dma_attr_burstsizes & 0xffff) | 1170 ((attr->dma_attr_burstsizes >> 16) & 0xffff); 1171 /* 1172 * If a driver set burtsizes to 0, we give him byte alignment. 1173 * Otherwise align at the burtsizes boundary. 1174 */ 1175 if (iomin == 0) 1176 iomin = 1; 1177 else 1178 iomin = 1 << (ddi_fls(iomin) - 1); 1179 iomin = maxbit(iomin, attr->dma_attr_minxfer); 1180 iomin = maxbit(iomin, attr->dma_attr_align); 1181 iomin = ddi_iomin(dip, iomin, streaming); 1182 if (iomin == 0) 1183 return (DDI_FAILURE); 1184 1185 ASSERT((iomin & (iomin - 1)) == 0); 1186 ASSERT(iomin >= attr->dma_attr_minxfer); 1187 ASSERT(iomin >= attr->dma_attr_align); 1188 1189 length = P2ROUNDUP(length, iomin); 1190 align = iomin; 1191 1192 if (accattrp != NULL) 1193 endian_flags = accattrp->devacc_attr_endian_flags; 1194 1195 a = kalloca(length, align, cansleep, endian_flags); 1196 if ((*kaddrp = a) == 0) { 1197 return (DDI_FAILURE); 1198 } else { 1199 if (real_length) { 1200 *real_length = length; 1201 } 1202 if (handlep) { 1203 /* 1204 * assign handle information 1205 */ 1206 impl_acc_hdl_init(handlep); 1207 } 1208 return (DDI_SUCCESS); 1209 } 1210 } 1211 1212 /* 1213 * covert old DMA limits structure to DMA attribute structure 1214 * and continue 1215 */ 1216 int 1217 i_ddi_mem_alloc_lim(dev_info_t *dip, ddi_dma_lim_t *limits, 1218 size_t length, int cansleep, int streaming, 1219 ddi_device_acc_attr_t *accattrp, caddr_t *kaddrp, 1220 uint_t *real_length, ddi_acc_hdl_t *ap) 1221 { 1222 ddi_dma_attr_t dma_attr, *attrp; 1223 size_t rlen; 1224 int ret; 1225 1226 ASSERT(limits); 1227 attrp = &dma_attr; 1228 attrp->dma_attr_version = DMA_ATTR_V0; 1229 attrp->dma_attr_addr_lo = (uint64_t)limits->dlim_addr_lo; 1230 attrp->dma_attr_addr_hi = (uint64_t)limits->dlim_addr_hi; 1231 attrp->dma_attr_count_max = (uint64_t)-1; 1232 attrp->dma_attr_align = 1; 1233 attrp->dma_attr_burstsizes = (uint_t)limits->dlim_burstsizes; 1234 attrp->dma_attr_minxfer = (uint32_t)limits->dlim_minxfer; 1235 attrp->dma_attr_maxxfer = (uint64_t)-1; 1236 attrp->dma_attr_seg = (uint64_t)limits->dlim_cntr_max; 1237 attrp->dma_attr_sgllen = 1; 1238 attrp->dma_attr_granular = 1; 1239 attrp->dma_attr_flags = 0; 1240 1241 ret = i_ddi_mem_alloc(dip, attrp, length, cansleep, streaming, 1242 accattrp, kaddrp, &rlen, ap); 1243 if (ret == DDI_SUCCESS) { 1244 if (real_length) 1245 *real_length = (uint_t)rlen; 1246 } 1247 return (ret); 1248 } 1249 1250 /* ARGSUSED */ 1251 void 1252 i_ddi_mem_free(caddr_t kaddr, ddi_acc_hdl_t *ap) 1253 { 1254 kfreea(kaddr); 1255 } 1256 1257 /* 1258 * SECTION: DDI Data Access 1259 */ 1260 1261 static uintptr_t impl_acc_hdl_id = 0; 1262 1263 /* 1264 * access handle allocator 1265 */ 1266 ddi_acc_hdl_t * 1267 impl_acc_hdl_get(ddi_acc_handle_t hdl) 1268 { 1269 /* 1270 * Extract the access handle address from the DDI implemented 1271 * access handle 1272 */ 1273 return (&((ddi_acc_impl_t *)hdl)->ahi_common); 1274 } 1275 1276 ddi_acc_handle_t 1277 impl_acc_hdl_alloc(int (*waitfp)(caddr_t), caddr_t arg) 1278 { 1279 ddi_acc_impl_t *hp; 1280 on_trap_data_t *otp; 1281 int sleepflag; 1282 1283 sleepflag = ((waitfp == (int (*)())KM_SLEEP) ? KM_SLEEP : KM_NOSLEEP); 1284 1285 /* 1286 * Allocate and initialize the data access handle and error status. 1287 */ 1288 if ((hp = kmem_zalloc(sizeof (ddi_acc_impl_t), sleepflag)) == NULL) 1289 goto fail; 1290 if ((hp->ahi_err = (ndi_err_t *)kmem_zalloc( 1291 sizeof (ndi_err_t), sleepflag)) == NULL) { 1292 kmem_free(hp, sizeof (ddi_acc_impl_t)); 1293 goto fail; 1294 } 1295 if ((otp = (on_trap_data_t *)kmem_zalloc( 1296 sizeof (on_trap_data_t), sleepflag)) == NULL) { 1297 kmem_free(hp->ahi_err, sizeof (ndi_err_t)); 1298 kmem_free(hp, sizeof (ddi_acc_impl_t)); 1299 goto fail; 1300 } 1301 hp->ahi_err->err_ontrap = otp; 1302 hp->ahi_common.ah_platform_private = (void *)hp; 1303 1304 return ((ddi_acc_handle_t)hp); 1305 fail: 1306 if ((waitfp != (int (*)())KM_SLEEP) && 1307 (waitfp != (int (*)())KM_NOSLEEP)) 1308 ddi_set_callback(waitfp, arg, &impl_acc_hdl_id); 1309 return (NULL); 1310 } 1311 1312 void 1313 impl_acc_hdl_free(ddi_acc_handle_t handle) 1314 { 1315 ddi_acc_impl_t *hp; 1316 1317 /* 1318 * The supplied (ddi_acc_handle_t) is actually a (ddi_acc_impl_t *), 1319 * because that's what we allocated in impl_acc_hdl_alloc() above. 1320 */ 1321 hp = (ddi_acc_impl_t *)handle; 1322 if (hp) { 1323 kmem_free(hp->ahi_err->err_ontrap, sizeof (on_trap_data_t)); 1324 kmem_free(hp->ahi_err, sizeof (ndi_err_t)); 1325 kmem_free(hp, sizeof (ddi_acc_impl_t)); 1326 if (impl_acc_hdl_id) 1327 ddi_run_callback(&impl_acc_hdl_id); 1328 } 1329 } 1330 1331 #define PCI_GET_MP_PFN(mp, page_no) ((mp)->dmai_ndvmapages == 1 ? \ 1332 (pfn_t)(mp)->dmai_iopte:(((pfn_t *)(mp)->dmai_iopte)[page_no])) 1333 1334 /* 1335 * Function called after a dma fault occurred to find out whether the 1336 * fault address is associated with a driver that is able to handle faults 1337 * and recover from faults. 1338 */ 1339 /* ARGSUSED */ 1340 int 1341 impl_dma_check(dev_info_t *dip, const void *handle, const void *addr, 1342 const void *not_used) 1343 { 1344 ddi_dma_impl_t *mp = (ddi_dma_impl_t *)handle; 1345 pfn_t fault_pfn = mmu_btop(*(uint64_t *)addr); 1346 pfn_t comp_pfn; 1347 1348 /* 1349 * The driver has to set DDI_DMA_FLAGERR to recover from dma faults. 1350 */ 1351 int page; 1352 1353 ASSERT(mp); 1354 for (page = 0; page < mp->dmai_ndvmapages; page++) { 1355 comp_pfn = PCI_GET_MP_PFN(mp, page); 1356 if (fault_pfn == comp_pfn) 1357 return (DDI_FM_NONFATAL); 1358 } 1359 return (DDI_FM_UNKNOWN); 1360 } 1361 1362 /* 1363 * Function used to check if a given access handle owns the failing address. 1364 * Called by ndi_fmc_error, when we detect a PIO error. 1365 */ 1366 /* ARGSUSED */ 1367 static int 1368 impl_acc_check(dev_info_t *dip, const void *handle, const void *addr, 1369 const void *not_used) 1370 { 1371 pfn_t pfn, fault_pfn; 1372 ddi_acc_hdl_t *hp; 1373 1374 hp = impl_acc_hdl_get((ddi_acc_handle_t)handle); 1375 1376 ASSERT(hp); 1377 1378 if (addr != NULL) { 1379 pfn = hp->ah_pfn; 1380 fault_pfn = mmu_btop(*(uint64_t *)addr); 1381 if (fault_pfn >= pfn && fault_pfn < (pfn + hp->ah_pnum)) 1382 return (DDI_FM_NONFATAL); 1383 } 1384 return (DDI_FM_UNKNOWN); 1385 } 1386 1387 void 1388 impl_acc_err_init(ddi_acc_hdl_t *handlep) 1389 { 1390 int fmcap; 1391 ndi_err_t *errp; 1392 on_trap_data_t *otp; 1393 ddi_acc_impl_t *hp = (ddi_acc_impl_t *)handlep; 1394 1395 fmcap = ddi_fm_capable(handlep->ah_dip); 1396 1397 if (handlep->ah_acc.devacc_attr_version < DDI_DEVICE_ATTR_V1 || 1398 !DDI_FM_ACC_ERR_CAP(fmcap)) { 1399 handlep->ah_acc.devacc_attr_access = DDI_DEFAULT_ACC; 1400 } else if (DDI_FM_ACC_ERR_CAP(fmcap)) { 1401 if (handlep->ah_acc.devacc_attr_access == DDI_DEFAULT_ACC) { 1402 if (handlep->ah_xfermodes) 1403 return; 1404 i_ddi_drv_ereport_post(handlep->ah_dip, DVR_EFMCAP, 1405 NULL, DDI_NOSLEEP); 1406 } else { 1407 errp = hp->ahi_err; 1408 otp = (on_trap_data_t *)errp->err_ontrap; 1409 otp->ot_handle = (void *)(hp); 1410 otp->ot_prot = OT_DATA_ACCESS; 1411 if (handlep->ah_acc.devacc_attr_access == 1412 DDI_CAUTIOUS_ACC) 1413 otp->ot_trampoline = 1414 (uintptr_t)&i_ddi_caut_trampoline; 1415 else 1416 otp->ot_trampoline = 1417 (uintptr_t)&i_ddi_prot_trampoline; 1418 errp->err_status = DDI_FM_OK; 1419 errp->err_expected = DDI_FM_ERR_UNEXPECTED; 1420 errp->err_cf = impl_acc_check; 1421 } 1422 } 1423 } 1424 1425 void 1426 impl_acc_hdl_init(ddi_acc_hdl_t *handlep) 1427 { 1428 ddi_acc_impl_t *hp; 1429 1430 ASSERT(handlep); 1431 1432 hp = (ddi_acc_impl_t *)handlep; 1433 1434 /* 1435 * check for SW byte-swapping 1436 */ 1437 hp->ahi_get8 = i_ddi_get8; 1438 hp->ahi_put8 = i_ddi_put8; 1439 hp->ahi_rep_get8 = i_ddi_rep_get8; 1440 hp->ahi_rep_put8 = i_ddi_rep_put8; 1441 if (handlep->ah_acc.devacc_attr_endian_flags & DDI_STRUCTURE_LE_ACC) { 1442 hp->ahi_get16 = i_ddi_swap_get16; 1443 hp->ahi_get32 = i_ddi_swap_get32; 1444 hp->ahi_get64 = i_ddi_swap_get64; 1445 hp->ahi_put16 = i_ddi_swap_put16; 1446 hp->ahi_put32 = i_ddi_swap_put32; 1447 hp->ahi_put64 = i_ddi_swap_put64; 1448 hp->ahi_rep_get16 = i_ddi_swap_rep_get16; 1449 hp->ahi_rep_get32 = i_ddi_swap_rep_get32; 1450 hp->ahi_rep_get64 = i_ddi_swap_rep_get64; 1451 hp->ahi_rep_put16 = i_ddi_swap_rep_put16; 1452 hp->ahi_rep_put32 = i_ddi_swap_rep_put32; 1453 hp->ahi_rep_put64 = i_ddi_swap_rep_put64; 1454 } else { 1455 hp->ahi_get16 = i_ddi_get16; 1456 hp->ahi_get32 = i_ddi_get32; 1457 hp->ahi_get64 = i_ddi_get64; 1458 hp->ahi_put16 = i_ddi_put16; 1459 hp->ahi_put32 = i_ddi_put32; 1460 hp->ahi_put64 = i_ddi_put64; 1461 hp->ahi_rep_get16 = i_ddi_rep_get16; 1462 hp->ahi_rep_get32 = i_ddi_rep_get32; 1463 hp->ahi_rep_get64 = i_ddi_rep_get64; 1464 hp->ahi_rep_put16 = i_ddi_rep_put16; 1465 hp->ahi_rep_put32 = i_ddi_rep_put32; 1466 hp->ahi_rep_put64 = i_ddi_rep_put64; 1467 } 1468 1469 /* Legacy fault flags and support */ 1470 hp->ahi_fault_check = i_ddi_acc_fault_check; 1471 hp->ahi_fault_notify = i_ddi_acc_fault_notify; 1472 hp->ahi_fault = 0; 1473 impl_acc_err_init(handlep); 1474 } 1475 1476 void 1477 i_ddi_acc_set_fault(ddi_acc_handle_t handle) 1478 { 1479 ddi_acc_impl_t *hp = (ddi_acc_impl_t *)handle; 1480 1481 if (!hp->ahi_fault) { 1482 hp->ahi_fault = 1; 1483 (*hp->ahi_fault_notify)(hp); 1484 } 1485 } 1486 1487 void 1488 i_ddi_acc_clr_fault(ddi_acc_handle_t handle) 1489 { 1490 ddi_acc_impl_t *hp = (ddi_acc_impl_t *)handle; 1491 1492 if (hp->ahi_fault) { 1493 hp->ahi_fault = 0; 1494 (*hp->ahi_fault_notify)(hp); 1495 } 1496 } 1497 1498 /* ARGSUSED */ 1499 void 1500 i_ddi_acc_fault_notify(ddi_acc_impl_t *hp) 1501 { 1502 /* Default version, does nothing */ 1503 } 1504 1505 /* 1506 * SECTION: Misc functions 1507 */ 1508 1509 /* 1510 * instance wrappers 1511 */ 1512 /*ARGSUSED*/ 1513 uint_t 1514 impl_assign_instance(dev_info_t *dip) 1515 { 1516 return ((uint_t)-1); 1517 } 1518 1519 /*ARGSUSED*/ 1520 int 1521 impl_keep_instance(dev_info_t *dip) 1522 { 1523 return (DDI_FAILURE); 1524 } 1525 1526 /*ARGSUSED*/ 1527 int 1528 impl_free_instance(dev_info_t *dip) 1529 { 1530 return (DDI_FAILURE); 1531 } 1532 1533 /*ARGSUSED*/ 1534 int 1535 impl_check_cpu(dev_info_t *devi) 1536 { 1537 return (DDI_SUCCESS); 1538 } 1539 1540 1541 static const char *nocopydevs[] = { 1542 "SUNW,ffb", 1543 "SUNW,afb", 1544 NULL 1545 }; 1546 1547 /* 1548 * Perform a copy from a memory mapped device (whose devinfo pointer is devi) 1549 * separately mapped at devaddr in the kernel to a kernel buffer at kaddr. 1550 */ 1551 /*ARGSUSED*/ 1552 int 1553 e_ddi_copyfromdev(dev_info_t *devi, 1554 off_t off, const void *devaddr, void *kaddr, size_t len) 1555 { 1556 const char **argv; 1557 1558 for (argv = nocopydevs; *argv; argv++) 1559 if (strcmp(ddi_binding_name(devi), *argv) == 0) { 1560 bzero(kaddr, len); 1561 return (0); 1562 } 1563 1564 bcopy(devaddr, kaddr, len); 1565 return (0); 1566 } 1567 1568 /* 1569 * Perform a copy to a memory mapped device (whose devinfo pointer is devi) 1570 * separately mapped at devaddr in the kernel from a kernel buffer at kaddr. 1571 */ 1572 /*ARGSUSED*/ 1573 int 1574 e_ddi_copytodev(dev_info_t *devi, 1575 off_t off, const void *kaddr, void *devaddr, size_t len) 1576 { 1577 const char **argv; 1578 1579 for (argv = nocopydevs; *argv; argv++) 1580 if (strcmp(ddi_binding_name(devi), *argv) == 0) 1581 return (1); 1582 1583 bcopy(kaddr, devaddr, len); 1584 return (0); 1585 } 1586 1587 /* 1588 * Boot Configuration 1589 */ 1590 idprom_t idprom; 1591 1592 /* 1593 * Configure the hardware on the system. 1594 * Called before the rootfs is mounted 1595 */ 1596 void 1597 configure(void) 1598 { 1599 extern void i_ddi_init_root(); 1600 1601 /* We better have released boot by this time! */ 1602 ASSERT(!bootops); 1603 1604 /* 1605 * Determine whether or not to use the fpu, V9 SPARC cpus 1606 * always have one. Could check for existence of a fp queue, 1607 * Ultra I, II and IIa do not have a fp queue. 1608 */ 1609 if (fpu_exists) 1610 fpu_probe(); 1611 else 1612 cmn_err(CE_CONT, "FPU not in use\n"); 1613 1614 #if 0 /* XXXQ - not necessary for sun4u */ 1615 /* 1616 * This following line fixes bugid 1041296; we need to do a 1617 * prom_nextnode(0) because this call ALSO patches the DMA+ 1618 * bug in Campus-B and Phoenix. The prom uncaches the traptable 1619 * page as a side-effect of devr_next(0) (which prom_nextnode calls), 1620 * so this *must* be executed early on. (XXX This is untrue for sun4u) 1621 */ 1622 (void) prom_nextnode((pnode_t)0); 1623 #endif 1624 1625 /* 1626 * Initialize devices on the machine. 1627 * Uses configuration tree built by the PROMs to determine what 1628 * is present, and builds a tree of prototype dev_info nodes 1629 * corresponding to the hardware which identified itself. 1630 */ 1631 i_ddi_init_root(); 1632 1633 #ifdef DDI_PROP_DEBUG 1634 (void) ddi_prop_debug(1); /* Enable property debugging */ 1635 #endif /* DDI_PROP_DEBUG */ 1636 } 1637 1638 /* 1639 * The "status" property indicates the operational status of a device. 1640 * If this property is present, the value is a string indicating the 1641 * status of the device as follows: 1642 * 1643 * "okay" operational. 1644 * "disabled" not operational, but might become operational. 1645 * "fail" not operational because a fault has been detected, 1646 * and it is unlikely that the device will become 1647 * operational without repair. no additional details 1648 * are available. 1649 * "fail-xxx" not operational because a fault has been detected, 1650 * and it is unlikely that the device will become 1651 * operational without repair. "xxx" is additional 1652 * human-readable information about the particular 1653 * fault condition that was detected. 1654 * 1655 * The absence of this property means that the operational status is 1656 * unknown or okay. 1657 * 1658 * This routine checks the status property of the specified device node 1659 * and returns 0 if the operational status indicates failure, and 1 otherwise. 1660 * 1661 * The property may exist on plug-in cards the existed before IEEE 1275-1994. 1662 * And, in that case, the property may not even be a string. So we carefully 1663 * check for the value "fail", in the beginning of the string, noting 1664 * the property length. 1665 */ 1666 int 1667 status_okay(int id, char *buf, int buflen) 1668 { 1669 char status_buf[OBP_MAXPROPNAME]; 1670 char *bufp = buf; 1671 int len = buflen; 1672 int proplen; 1673 static const char *status = "status"; 1674 static const char *fail = "fail"; 1675 size_t fail_len = strlen(fail); 1676 1677 /* 1678 * Get the proplen ... if it's smaller than "fail", 1679 * or doesn't exist ... then we don't care, since 1680 * the value can't begin with the char string "fail". 1681 * 1682 * NB: proplen, if it's a string, includes the NULL in the 1683 * the size of the property, and fail_len does not. 1684 */ 1685 proplen = prom_getproplen((pnode_t)id, (caddr_t)status); 1686 if (proplen <= fail_len) /* nonexistent or uninteresting len */ 1687 return (1); 1688 1689 /* 1690 * if a buffer was provided, use it 1691 */ 1692 if ((buf == (char *)NULL) || (buflen <= 0)) { 1693 bufp = status_buf; 1694 len = sizeof (status_buf); 1695 } 1696 *bufp = (char)0; 1697 1698 /* 1699 * Get the property into the buffer, to the extent of the buffer, 1700 * and in case the buffer is smaller than the property size, 1701 * NULL terminate the buffer. (This handles the case where 1702 * a buffer was passed in and the caller wants to print the 1703 * value, but the buffer was too small). 1704 */ 1705 (void) prom_bounded_getprop((pnode_t)id, (caddr_t)status, 1706 (caddr_t)bufp, len); 1707 *(bufp + len - 1) = (char)0; 1708 1709 /* 1710 * If the value begins with the char string "fail", 1711 * then it means the node is failed. We don't care 1712 * about any other values. We assume the node is ok 1713 * although it might be 'disabled'. 1714 */ 1715 if (strncmp(bufp, fail, fail_len) == 0) 1716 return (0); 1717 1718 return (1); 1719 } 1720 1721 1722 /* 1723 * We set the cpu type from the idprom, if we can. 1724 * Note that we just read out the contents of it, for the most part. 1725 */ 1726 void 1727 setcputype(void) 1728 { 1729 /* 1730 * We cache the idprom info early on so that we don't 1731 * rummage through the NVRAM unnecessarily later. 1732 */ 1733 (void) prom_getidprom((caddr_t)&idprom, sizeof (idprom)); 1734 } 1735 1736 /* 1737 * Here is where we actually infer meanings to the members of idprom_t 1738 */ 1739 void 1740 parse_idprom(void) 1741 { 1742 if (idprom.id_format == IDFORM_1) { 1743 (void) localetheraddr((struct ether_addr *)idprom.id_ether, 1744 (struct ether_addr *)NULL); 1745 (void) snprintf(hw_serial, HW_HOSTID_LEN, "%u", 1746 (idprom.id_machine << 24) + idprom.id_serial); 1747 } else 1748 prom_printf("Invalid format code in IDprom.\n"); 1749 } 1750 1751 /* 1752 * Allow for implementation specific correction of PROM property values. 1753 */ 1754 /*ARGSUSED*/ 1755 void 1756 impl_fix_props(dev_info_t *dip, dev_info_t *ch_dip, char *name, int len, 1757 caddr_t buffer) 1758 { 1759 /* 1760 * There are no adjustments needed in this implementation. 1761 */ 1762 } 1763 1764 /* 1765 * The following functions ready a cautious request to go up to the nexus 1766 * driver. It is up to the nexus driver to decide how to process the request. 1767 * It may choose to call i_ddi_do_caut_get/put in this file, or do it 1768 * differently. 1769 */ 1770 1771 static void 1772 i_ddi_caut_getput_ctlops( 1773 ddi_acc_impl_t *hp, uint64_t host_addr, uint64_t dev_addr, size_t size, 1774 size_t repcount, uint_t flags, ddi_ctl_enum_t cmd) 1775 { 1776 peekpoke_ctlops_t cautacc_ctlops_arg; 1777 1778 cautacc_ctlops_arg.size = size; 1779 cautacc_ctlops_arg.dev_addr = dev_addr; 1780 cautacc_ctlops_arg.host_addr = host_addr; 1781 cautacc_ctlops_arg.handle = (ddi_acc_handle_t)hp; 1782 cautacc_ctlops_arg.repcount = repcount; 1783 cautacc_ctlops_arg.flags = flags; 1784 1785 (void) ddi_ctlops(hp->ahi_common.ah_dip, hp->ahi_common.ah_dip, cmd, 1786 &cautacc_ctlops_arg, NULL); 1787 } 1788 1789 uint8_t 1790 i_ddi_caut_get8(ddi_acc_impl_t *hp, uint8_t *addr) 1791 { 1792 uint8_t value; 1793 i_ddi_caut_getput_ctlops(hp, (uint64_t)&value, (uint64_t)addr, 1794 sizeof (uint8_t), 1, 0, DDI_CTLOPS_PEEK); 1795 1796 return (value); 1797 } 1798 1799 uint16_t 1800 i_ddi_caut_get16(ddi_acc_impl_t *hp, uint16_t *addr) 1801 { 1802 uint16_t value; 1803 i_ddi_caut_getput_ctlops(hp, (uint64_t)&value, (uint64_t)addr, 1804 sizeof (uint16_t), 1, 0, DDI_CTLOPS_PEEK); 1805 1806 return (value); 1807 } 1808 1809 uint32_t 1810 i_ddi_caut_get32(ddi_acc_impl_t *hp, uint32_t *addr) 1811 { 1812 uint32_t value; 1813 i_ddi_caut_getput_ctlops(hp, (uint64_t)&value, (uint64_t)addr, 1814 sizeof (uint32_t), 1, 0, DDI_CTLOPS_PEEK); 1815 1816 return (value); 1817 } 1818 1819 uint64_t 1820 i_ddi_caut_get64(ddi_acc_impl_t *hp, uint64_t *addr) 1821 { 1822 uint64_t value; 1823 i_ddi_caut_getput_ctlops(hp, (uint64_t)&value, (uint64_t)addr, 1824 sizeof (uint64_t), 1, 0, DDI_CTLOPS_PEEK); 1825 1826 return (value); 1827 } 1828 1829 void 1830 i_ddi_caut_put8(ddi_acc_impl_t *hp, uint8_t *addr, uint8_t value) 1831 { 1832 i_ddi_caut_getput_ctlops(hp, (uint64_t)&value, (uint64_t)addr, 1833 sizeof (uint8_t), 1, 0, DDI_CTLOPS_POKE); 1834 } 1835 1836 void 1837 i_ddi_caut_put16(ddi_acc_impl_t *hp, uint16_t *addr, uint16_t value) 1838 { 1839 i_ddi_caut_getput_ctlops(hp, (uint64_t)&value, (uint64_t)addr, 1840 sizeof (uint16_t), 1, 0, DDI_CTLOPS_POKE); 1841 } 1842 1843 void 1844 i_ddi_caut_put32(ddi_acc_impl_t *hp, uint32_t *addr, uint32_t value) 1845 { 1846 i_ddi_caut_getput_ctlops(hp, (uint64_t)&value, (uint64_t)addr, 1847 sizeof (uint32_t), 1, 0, DDI_CTLOPS_POKE); 1848 } 1849 1850 void 1851 i_ddi_caut_put64(ddi_acc_impl_t *hp, uint64_t *addr, uint64_t value) 1852 { 1853 i_ddi_caut_getput_ctlops(hp, (uint64_t)&value, (uint64_t)addr, 1854 sizeof (uint64_t), 1, 0, DDI_CTLOPS_POKE); 1855 } 1856 1857 void 1858 i_ddi_caut_rep_get8(ddi_acc_impl_t *hp, uint8_t *host_addr, uint8_t *dev_addr, 1859 size_t repcount, uint_t flags) 1860 { 1861 i_ddi_caut_getput_ctlops(hp, (uint64_t)host_addr, (uint64_t)dev_addr, 1862 sizeof (uint8_t), repcount, flags, DDI_CTLOPS_PEEK); 1863 } 1864 1865 void 1866 i_ddi_caut_rep_get16(ddi_acc_impl_t *hp, uint16_t *host_addr, 1867 uint16_t *dev_addr, size_t repcount, uint_t flags) 1868 { 1869 i_ddi_caut_getput_ctlops(hp, (uint64_t)host_addr, (uint64_t)dev_addr, 1870 sizeof (uint16_t), repcount, flags, DDI_CTLOPS_PEEK); 1871 } 1872 1873 void 1874 i_ddi_caut_rep_get32(ddi_acc_impl_t *hp, uint32_t *host_addr, 1875 uint32_t *dev_addr, size_t repcount, uint_t flags) 1876 { 1877 i_ddi_caut_getput_ctlops(hp, (uint64_t)host_addr, (uint64_t)dev_addr, 1878 sizeof (uint32_t), repcount, flags, DDI_CTLOPS_PEEK); 1879 } 1880 1881 void 1882 i_ddi_caut_rep_get64(ddi_acc_impl_t *hp, uint64_t *host_addr, 1883 uint64_t *dev_addr, size_t repcount, uint_t flags) 1884 { 1885 i_ddi_caut_getput_ctlops(hp, (uint64_t)host_addr, (uint64_t)dev_addr, 1886 sizeof (uint64_t), repcount, flags, DDI_CTLOPS_PEEK); 1887 } 1888 1889 void 1890 i_ddi_caut_rep_put8(ddi_acc_impl_t *hp, uint8_t *host_addr, uint8_t *dev_addr, 1891 size_t repcount, uint_t flags) 1892 { 1893 i_ddi_caut_getput_ctlops(hp, (uint64_t)host_addr, (uint64_t)dev_addr, 1894 sizeof (uint8_t), repcount, flags, DDI_CTLOPS_POKE); 1895 } 1896 1897 void 1898 i_ddi_caut_rep_put16(ddi_acc_impl_t *hp, uint16_t *host_addr, 1899 uint16_t *dev_addr, size_t repcount, uint_t flags) 1900 { 1901 i_ddi_caut_getput_ctlops(hp, (uint64_t)host_addr, (uint64_t)dev_addr, 1902 sizeof (uint16_t), repcount, flags, DDI_CTLOPS_POKE); 1903 } 1904 1905 void 1906 i_ddi_caut_rep_put32(ddi_acc_impl_t *hp, uint32_t *host_addr, 1907 uint32_t *dev_addr, size_t repcount, uint_t flags) 1908 { 1909 i_ddi_caut_getput_ctlops(hp, (uint64_t)host_addr, (uint64_t)dev_addr, 1910 sizeof (uint32_t), repcount, flags, DDI_CTLOPS_POKE); 1911 } 1912 1913 void 1914 i_ddi_caut_rep_put64(ddi_acc_impl_t *hp, uint64_t *host_addr, 1915 uint64_t *dev_addr, size_t repcount, uint_t flags) 1916 { 1917 i_ddi_caut_getput_ctlops(hp, (uint64_t)host_addr, (uint64_t)dev_addr, 1918 sizeof (uint64_t), repcount, flags, DDI_CTLOPS_POKE); 1919 } 1920 1921 /* 1922 * This is called only to process peek/poke when the DIP is NULL. 1923 * Assume that this is for memory, as nexi take care of device safe accesses. 1924 */ 1925 int 1926 peekpoke_mem(ddi_ctl_enum_t cmd, peekpoke_ctlops_t *in_args) 1927 { 1928 int err = DDI_SUCCESS; 1929 on_trap_data_t otd; 1930 1931 /* Set up protected environment. */ 1932 if (!on_trap(&otd, OT_DATA_ACCESS)) { 1933 uintptr_t tramp = otd.ot_trampoline; 1934 1935 if (cmd == DDI_CTLOPS_POKE) { 1936 otd.ot_trampoline = (uintptr_t)&poke_fault; 1937 err = do_poke(in_args->size, (void *)in_args->dev_addr, 1938 (void *)in_args->host_addr); 1939 } else { 1940 otd.ot_trampoline = (uintptr_t)&peek_fault; 1941 err = do_peek(in_args->size, (void *)in_args->dev_addr, 1942 (void *)in_args->host_addr); 1943 } 1944 otd.ot_trampoline = tramp; 1945 } else 1946 err = DDI_FAILURE; 1947 1948 /* Take down protected environment. */ 1949 no_trap(); 1950 1951 return (err); 1952 } 1953