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/asi.h> 29#include <sys/asm_linkage.h> 30#include <sys/machthread.h> 31#include <sys/privregs.h> 32#include <sys/ontrap.h> 33#include <sys/dditypes.h> 34 35#ifndef lint 36#include "assym.h" 37#endif 38 39#if defined(lint) 40#include <sys/isa_defs.h> 41#include <sys/types.h> 42#include <sys/sunddi.h> 43#endif /* lint */ 44 45/* 46 * This file implements the following ddi common access 47 * functions: 48 * 49 * ddi_get{8,16,32,64} 50 * ddi_put{8,16,32,64} 51 * 52 * and the underlying "trivial" implementations 53 * 54 * i_ddi_{get,put}{8,16,32,64} 55 * 56 * which assume that there is no need to check the access handle - 57 * byte swapping will be done by the mmu and the address is always 58 * accessible via ld/st instructions. 59 */ 60 61#if defined(lint) 62 63/*ARGSUSED*/ 64uint8_t 65ddi_get8(ddi_acc_handle_t handle, uint8_t *addr) 66{ 67 return (0); 68} 69 70/*ARGSUSED*/ 71uint8_t 72ddi_mem_get8(ddi_acc_handle_t handle, uint8_t *addr) 73{ 74 return (0); 75} 76 77/*ARGSUSED*/ 78uint8_t 79ddi_io_get8(ddi_acc_handle_t handle, uint8_t *dev_addr) 80{ 81 return (0); 82} 83 84/*ARGSUSED*/ 85uint16_t 86ddi_get16(ddi_acc_handle_t handle, uint16_t *addr) 87{ 88 return (0); 89} 90 91/*ARGSUSED*/ 92uint16_t 93ddi_mem_get16(ddi_acc_handle_t handle, uint16_t *addr) 94{ 95 return (0); 96} 97 98/*ARGSUSED*/ 99uint16_t 100ddi_io_get16(ddi_acc_handle_t handle, uint16_t *dev_addr) 101{ 102 return (0); 103} 104 105/*ARGSUSED*/ 106uint32_t 107ddi_get32(ddi_acc_handle_t handle, uint32_t *addr) 108{ 109 return (0); 110} 111 112/*ARGSUSED*/ 113uint32_t 114ddi_mem_get32(ddi_acc_handle_t handle, uint32_t *addr) 115{ 116 return (0); 117} 118 119/*ARGSUSED*/ 120uint32_t 121ddi_io_get32(ddi_acc_handle_t handle, uint32_t *dev_addr) 122{ 123 return (0); 124} 125 126/*ARGSUSED*/ 127uint64_t 128ddi_get64(ddi_acc_handle_t handle, uint64_t *addr) 129{ 130 return (0); 131} 132 133/*ARGSUSED*/ 134uint64_t 135ddi_mem_get64(ddi_acc_handle_t handle, uint64_t *addr) 136{ 137 return (0); 138} 139 140/*ARGSUSED*/ 141void 142ddi_put8(ddi_acc_handle_t handle, uint8_t *addr, uint8_t value) {} 143 144/*ARGSUSED*/ 145void 146ddi_mem_put8(ddi_acc_handle_t handle, uint8_t *dev_addr, uint8_t value) {} 147 148/*ARGSUSED*/ 149void 150ddi_io_put8(ddi_acc_handle_t handle, uint8_t *dev_addr, uint8_t value) {} 151 152/*ARGSUSED*/ 153void 154ddi_put16(ddi_acc_handle_t handle, uint16_t *addr, uint16_t value) {} 155 156/*ARGSUSED*/ 157void 158ddi_mem_put16(ddi_acc_handle_t handle, uint16_t *dev_addr, uint16_t value) {} 159 160/*ARGSUSED*/ 161void 162ddi_io_put16(ddi_acc_handle_t handle, uint16_t *dev_addr, uint16_t value) {} 163 164/*ARGSUSED*/ 165void 166ddi_put32(ddi_acc_handle_t handle, uint32_t *addr, uint32_t value) {} 167 168/*ARGSUSED*/ 169void 170ddi_mem_put32(ddi_acc_handle_t handle, uint32_t *dev_addr, uint32_t value) {} 171 172/*ARGSUSED*/ 173void 174ddi_io_put32(ddi_acc_handle_t handle, uint32_t *dev_addr, uint32_t value) {} 175 176/*ARGSUSED*/ 177void 178ddi_put64(ddi_acc_handle_t handle, uint64_t *addr, uint64_t value) {} 179 180/*ARGSUSED*/ 181void 182ddi_mem_put64(ddi_acc_handle_t handle, uint64_t *dev_addr, uint64_t value) {} 183 184/*ARGSUSED*/ 185void 186ddi_rep_get8(ddi_acc_handle_t handle, uint8_t *host_addr, uint8_t *dev_addr, 187 size_t repcount, uint_t flags) 188{ 189} 190 191/*ARGSUSED*/ 192void 193ddi_rep_get16(ddi_acc_handle_t handle, uint16_t *host_addr, uint16_t *dev_addr, 194 size_t repcount, uint_t flags) 195{ 196} 197 198/*ARGSUSED*/ 199void 200ddi_rep_get32(ddi_acc_handle_t handle, uint32_t *host_addr, uint32_t *dev_addr, 201 size_t repcount, uint_t flags) 202{ 203} 204 205/*ARGSUSED*/ 206void 207ddi_rep_get64(ddi_acc_handle_t handle, uint64_t *host_addr, uint64_t *dev_addr, 208 size_t repcount, uint_t flags) 209{ 210} 211 212/*ARGSUSED*/ 213void 214ddi_rep_put8(ddi_acc_handle_t handle, uint8_t *host_addr, uint8_t *dev_addr, 215 size_t repcount, uint_t flags) 216{ 217} 218 219/*ARGSUSED*/ 220void 221ddi_rep_put16(ddi_acc_handle_t handle, uint16_t *host_addr, uint16_t *dev_addr, 222 size_t repcount, uint_t flags) 223{ 224} 225 226/*ARGSUSED*/ 227void 228ddi_rep_put32(ddi_acc_handle_t handle, uint32_t *host_addr, uint32_t *dev_addr, 229 size_t repcount, uint_t flags) 230{ 231} 232 233/*ARGSUSED*/ 234void 235ddi_rep_put64(ddi_acc_handle_t handle, uint64_t *host_addr, uint64_t *dev_addr, 236 size_t repcount, uint_t flags) 237{ 238} 239 240/*ARGSUSED*/ 241void 242ddi_mem_rep_get8(ddi_acc_handle_t handle, uint8_t *host_addr, 243 uint8_t *dev_addr, size_t repcount, uint_t flags) 244{ 245} 246 247/*ARGSUSED*/ 248void 249ddi_mem_rep_get16(ddi_acc_handle_t handle, uint16_t *host_addr, 250 uint16_t *dev_addr, size_t repcount, uint_t flags) 251{ 252} 253 254/*ARGSUSED*/ 255void 256ddi_mem_rep_get32(ddi_acc_handle_t handle, uint32_t *host_addr, 257 uint32_t *dev_addr, size_t repcount, uint_t flags) 258{ 259} 260 261/*ARGSUSED*/ 262void 263ddi_mem_rep_get64(ddi_acc_handle_t handle, uint64_t *host_addr, 264 uint64_t *dev_addr, size_t repcount, uint_t flags) 265{ 266} 267 268/*ARGSUSED*/ 269void 270ddi_mem_rep_put8(ddi_acc_handle_t handle, uint8_t *host_addr, 271 uint8_t *dev_addr, size_t repcount, uint_t flags) 272{ 273} 274 275/*ARGSUSED*/ 276void 277ddi_mem_rep_put16(ddi_acc_handle_t handle, uint16_t *host_addr, 278 uint16_t *dev_addr, size_t repcount, uint_t flags) 279{ 280} 281 282/*ARGSUSED*/ 283void 284ddi_mem_rep_put32(ddi_acc_handle_t handle, uint32_t *host_addr, 285 uint32_t *dev_addr, size_t repcount, uint_t flags) 286{ 287} 288 289/*ARGSUSED*/ 290void 291ddi_mem_rep_put64(ddi_acc_handle_t handle, uint64_t *host_addr, 292 uint64_t *dev_addr, size_t repcount, uint_t flags) 293{ 294} 295 296/*ARGSUSED*/ 297void 298ddi_io_rep_get8(ddi_acc_handle_t handle, 299 uint8_t *host_addr, uint8_t *dev_addr, size_t repcount) {} 300 301/*ARGSUSED*/ 302void 303ddi_io_rep_get16(ddi_acc_handle_t handle, 304 uint16_t *host_addr, uint16_t *dev_addr, size_t repcount) {} 305 306/*ARGSUSED*/ 307void 308ddi_io_rep_get32(ddi_acc_handle_t handle, 309 uint32_t *host_addr, uint32_t *dev_addr, size_t repcount) {} 310 311/*ARGSUSED*/ 312void 313ddi_io_rep_put8(ddi_acc_handle_t handle, 314 uint8_t *host_addr, uint8_t *dev_addr, size_t repcount) {} 315 316/*ARGSUSED*/ 317void 318ddi_io_rep_put16(ddi_acc_handle_t handle, 319 uint16_t *host_addr, uint16_t *dev_addr, size_t repcount) {} 320 321 322/*ARGSUSED*/ 323void 324ddi_io_rep_put32(ddi_acc_handle_t handle, 325 uint32_t *host_addr, uint32_t *dev_addr, size_t repcount) {} 326 327/*ARGSUSED*/ 328uint8_t 329i_ddi_get8(ddi_acc_impl_t *hdlp, uint8_t *addr) 330{ 331 return (0); 332} 333 334/*ARGSUSED*/ 335uint16_t 336i_ddi_get16(ddi_acc_impl_t *hdlp, uint16_t *addr) 337{ 338 return (0); 339} 340 341/*ARGSUSED*/ 342uint32_t 343i_ddi_get32(ddi_acc_impl_t *hdlp, uint32_t *addr) 344{ 345 return (0); 346} 347 348/*ARGSUSED*/ 349uint64_t 350i_ddi_get64(ddi_acc_impl_t *hdlp, uint64_t *addr) 351{ 352 return (0); 353} 354 355/*ARGSUSED*/ 356void 357i_ddi_put8(ddi_acc_impl_t *hdlp, uint8_t *addr, uint8_t value) {} 358 359/*ARGSUSED*/ 360void 361i_ddi_put16(ddi_acc_impl_t *hdlp, uint16_t *addr, uint16_t value) {} 362 363/*ARGSUSED*/ 364void 365i_ddi_put32(ddi_acc_impl_t *hdlp, uint32_t *addr, uint32_t value) {} 366 367/*ARGSUSED*/ 368void 369i_ddi_put64(ddi_acc_impl_t *hdlp, uint64_t *addr, uint64_t value) {} 370 371/*ARGSUSED*/ 372void 373i_ddi_rep_get8(ddi_acc_impl_t *hdlp, uint8_t *host_addr, uint8_t *dev_addr, 374 size_t repcount, uint_t flags) 375{ 376} 377 378/*ARGSUSED*/ 379void 380i_ddi_rep_get16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 381 uint16_t *dev_addr, size_t repcount, uint_t flags) 382{ 383} 384 385/*ARGSUSED*/ 386void 387i_ddi_rep_get32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 388 uint32_t *dev_addr, size_t repcount, uint_t flags) 389{ 390} 391 392/*ARGSUSED*/ 393void 394i_ddi_rep_get64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 395 uint64_t *dev_addr, size_t repcount, uint_t flags) 396{ 397} 398 399/*ARGSUSED*/ 400void 401i_ddi_rep_put8(ddi_acc_impl_t *hdlp, uint8_t *host_addr, uint8_t *dev_addr, 402 size_t repcount, uint_t flags) 403{ 404} 405 406/*ARGSUSED*/ 407void 408i_ddi_rep_put16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 409 uint16_t *dev_addr, size_t repcount, uint_t flags) 410{ 411} 412 413/*ARGSUSED*/ 414void 415i_ddi_rep_put32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 416 uint32_t *dev_addr, size_t repcount, uint_t flags) 417{ 418} 419 420/*ARGSUSED*/ 421void 422i_ddi_rep_put64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 423 uint64_t *dev_addr, size_t repcount, uint_t flags) 424{ 425} 426 427/*ARGSUSED*/ 428uint8_t 429i_ddi_prot_get8(ddi_acc_impl_t *hdlp, uint8_t *addr) 430{ 431 return (0); 432} 433 434/*ARGSUSED*/ 435uint16_t 436i_ddi_prot_get16(ddi_acc_impl_t *hdlp, uint16_t *addr) 437{ 438 return (0); 439} 440 441/*ARGSUSED*/ 442uint32_t 443i_ddi_prot_get32(ddi_acc_impl_t *hdlp, uint32_t *addr) 444{ 445 return (0); 446} 447 448/*ARGSUSED*/ 449uint64_t 450i_ddi_prot_get64(ddi_acc_impl_t *hdlp, uint64_t *addr) 451{ 452 return (0); 453} 454 455/*ARGSUSED*/ 456void 457i_ddi_prot_put8(ddi_acc_impl_t *hdlp, uint8_t *addr, uint8_t value) {} 458 459/*ARGSUSED*/ 460void 461i_ddi_prot_put16(ddi_acc_impl_t *hdlp, uint16_t *addr, uint16_t value) {} 462 463/*ARGSUSED*/ 464void 465i_ddi_prot_put32(ddi_acc_impl_t *hdlp, uint32_t *addr, uint32_t value) {} 466 467/*ARGSUSED*/ 468void 469i_ddi_prot_put64(ddi_acc_impl_t *hdlp, uint64_t *addr, uint64_t value) {} 470 471/*ARGSUSED*/ 472void 473i_ddi_prot_rep_get8(ddi_acc_impl_t *hdlp, uint8_t *host_addr, uint8_t *dev_addr, 474 size_t repcount, uint_t flags) 475{ 476} 477 478/*ARGSUSED*/ 479void 480i_ddi_prot_rep_get16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 481 uint16_t *dev_addr, size_t repcount, uint_t flags) 482{ 483} 484 485/*ARGSUSED*/ 486void 487i_ddi_prot_rep_get32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 488 uint32_t *dev_addr, size_t repcount, uint_t flags) 489{ 490} 491 492/*ARGSUSED*/ 493void 494i_ddi_prot_rep_get64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 495 uint64_t *dev_addr, size_t repcount, uint_t flags) 496{ 497} 498 499/*ARGSUSED*/ 500void 501i_ddi_prot_rep_put8(ddi_acc_impl_t *hdlp, uint8_t *host_addr, uint8_t *dev_addr, 502 size_t repcount, uint_t flags) 503{ 504} 505 506/*ARGSUSED*/ 507void 508i_ddi_prot_rep_put16(ddi_acc_impl_t *hdlp, uint16_t *host_addr, 509 uint16_t *dev_addr, size_t repcount, uint_t flags) 510{ 511} 512 513/*ARGSUSED*/ 514void 515i_ddi_prot_rep_put32(ddi_acc_impl_t *hdlp, uint32_t *host_addr, 516 uint32_t *dev_addr, size_t repcount, uint_t flags) 517{ 518} 519 520/*ARGSUSED*/ 521void 522i_ddi_prot_rep_put64(ddi_acc_impl_t *hdlp, uint64_t *host_addr, 523 uint64_t *dev_addr, size_t repcount, uint_t flags) 524{ 525} 526 527/*ARGSUSED*/ 528int 529i_ddi_ontrap(ddi_acc_handle_t handle) 530{ 531 return (0); 532} 533 534/*ARGSUSED*/ 535void 536i_ddi_notrap(ddi_acc_handle_t handle) 537{ 538} 539 540/*ARGSUSED*/ 541void 542i_ddi_caut_get(size_t getsz, void *addr, void *value) 543{ 544} 545 546#else 547 548/* 549 * The functionality of each of the ddi_get/put routines is performed by 550 * the respective indirect function defined in the access handle. Use of 551 * the access handle functions provides compatibility across platforms for 552 * drivers. 553 * 554 * By default, the indirect access handle functions are initialized to the 555 * i_ddi_get/put routines to perform memory mapped IO. If memory mapped IO 556 * is not possible or desired, the access handle must be intialized to another 557 * valid routine to perform the sepcified IO operation. 558 * 559 * The alignment and placement of the following functions have been optimized 560 * such that the implementation specific versions, i_ddi*, fall within the 561 * same cache-line of the generic versions, ddi_*. This insures that an 562 * I-cache hit will occur thus minimizing the performance impact of using the 563 * access handle. 564 */ 565 566 .align 32 567 ENTRY(ddi_get8) 568 ALTENTRY(ddi_getb) 569 ALTENTRY(ddi_io_get8) 570 ALTENTRY(ddi_io_getb) 571 ALTENTRY(ddi_mem_get8) 572 ALTENTRY(ddi_mem_getb) 573 ldn [%o0 + AHI_GET8], %g1 /* hdl->ahi_get8 access hndl */ 574 jmpl %g1, %g0 /* jump to access handle routine */ 575 nop 576 SET_SIZE(ddi_get8) 577 SET_SIZE(ddi_getb) 578 SET_SIZE(ddi_io_get8) 579 SET_SIZE(ddi_io_getb) 580 SET_SIZE(ddi_mem_get8) 581 SET_SIZE(ddi_mem_getb) 582 583 .align 16 584 ENTRY(i_ddi_get8) 585 retl 586 ldub [%o1], %o0 587 SET_SIZE(i_ddi_get8) 588 589 .align 32 590 ENTRY(ddi_get16) 591 ALTENTRY(ddi_getw) 592 ALTENTRY(ddi_io_get16) 593 ALTENTRY(ddi_io_getw) 594 ALTENTRY(ddi_mem_get16) 595 ALTENTRY(ddi_mem_getw) 596 ldn [%o0 + AHI_GET16], %g1 /* hdl->ahi_get16 access hndl */ 597 jmpl %g1, %g0 /* jump to access handle routine */ 598 nop 599 SET_SIZE(ddi_get16) 600 SET_SIZE(ddi_getw) 601 SET_SIZE(ddi_io_get16) 602 SET_SIZE(ddi_io_getw) 603 SET_SIZE(ddi_mem_get16) 604 SET_SIZE(ddi_mem_getw) 605 606 .align 16 607 ENTRY(i_ddi_get16) 608 ALTENTRY(i_ddi_swap_get16) 609 retl 610 lduh [%o1], %o0 611 SET_SIZE(i_ddi_get16) 612 SET_SIZE(i_ddi_swap_get16) 613 614 .align 32 615 ENTRY(ddi_get32) 616 ALTENTRY(ddi_getl) 617 ALTENTRY(ddi_io_get32) 618 ALTENTRY(ddi_io_getl) 619 ALTENTRY(ddi_mem_get32) 620 ALTENTRY(ddi_mem_getl) 621 ldn [%o0 + AHI_GET32], %g1 /* hdl->ahi_get32 access handle */ 622 jmpl %g1, %g0 /* jump to access handle routine */ 623 nop 624 SET_SIZE(ddi_get32) 625 SET_SIZE(ddi_getl) 626 SET_SIZE(ddi_io_get32) 627 SET_SIZE(ddi_io_getl) 628 SET_SIZE(ddi_mem_get32) 629 SET_SIZE(ddi_mem_getl) 630 631 .align 16 632 ENTRY(i_ddi_get32) 633 ALTENTRY(i_ddi_swap_get32) 634 retl 635 ld [%o1], %o0 636 SET_SIZE(i_ddi_get32) 637 SET_SIZE(i_ddi_swap_get32) 638 639 .align 32 640 ENTRY(ddi_get64) 641 ALTENTRY(ddi_getll) 642 ALTENTRY(ddi_io_get64) 643 ALTENTRY(ddi_io_getll) 644 ALTENTRY(ddi_mem_get64) 645 ALTENTRY(ddi_mem_getll) 646 ldn [%o0 + AHI_GET64], %g1 /* hdl->ahi_get64 access handle */ 647 jmpl %g1, %g0 /* jump to access handle routine */ 648 nop 649 SET_SIZE(ddi_get64) 650 SET_SIZE(ddi_getll) 651 SET_SIZE(ddi_io_get64) 652 SET_SIZE(ddi_io_getll) 653 SET_SIZE(ddi_mem_get64) 654 SET_SIZE(ddi_mem_getll) 655 656 .align 16 657 ENTRY(i_ddi_get64) 658 ALTENTRY(i_ddi_swap_get64) 659 retl 660 ldx [%o1], %o0 661 SET_SIZE(i_ddi_get64) 662 SET_SIZE(i_ddi_swap_get64) 663 664 .align 32 665 ENTRY(ddi_put8) 666 ALTENTRY(ddi_putb) 667 ALTENTRY(ddi_io_put8) 668 ALTENTRY(ddi_io_putb) 669 ALTENTRY(ddi_mem_put8) 670 ALTENTRY(ddi_mem_putb) 671 ldn [%o0 + AHI_PUT8], %g1 /* hdl->ahi_put8 access handle */ 672 jmpl %g1, %g0 /* jump to access handle routine */ 673 nop 674 SET_SIZE(ddi_put8) 675 SET_SIZE(ddi_putb) 676 SET_SIZE(ddi_io_put8) 677 SET_SIZE(ddi_io_putb) 678 SET_SIZE(ddi_mem_put8) 679 SET_SIZE(ddi_mem_putb) 680 681 .align 16 682 ENTRY(i_ddi_put8) 683 retl 684 stub %o2, [%o1] 685 SET_SIZE(i_ddi_put8) 686 687 .align 32 688 ENTRY(ddi_put16) 689 ALTENTRY(ddi_putw) 690 ALTENTRY(ddi_io_put16) 691 ALTENTRY(ddi_io_putw) 692 ALTENTRY(ddi_mem_put16) 693 ALTENTRY(ddi_mem_putw) 694 ldn [%o0 + AHI_PUT16], %g1 /* hdl->ahi_put16 access handle */ 695 jmpl %g1, %g0 /* jump to access handle routine */ 696 nop 697 SET_SIZE(ddi_put16) 698 SET_SIZE(ddi_putw) 699 SET_SIZE(ddi_io_put16) 700 SET_SIZE(ddi_io_putw) 701 SET_SIZE(ddi_mem_put16) 702 SET_SIZE(ddi_mem_putw) 703 704 .align 16 705 ENTRY(i_ddi_put16) 706 ALTENTRY(i_ddi_swap_put16) 707 retl 708 stuh %o2, [%o1] 709 SET_SIZE(i_ddi_put16) 710 SET_SIZE(i_ddi_swap_put16) 711 712 .align 32 713 ENTRY(ddi_put32) 714 ALTENTRY(ddi_putl) 715 ALTENTRY(ddi_io_put32) 716 ALTENTRY(ddi_io_putl) 717 ALTENTRY(ddi_mem_put32) 718 ALTENTRY(ddi_mem_putl) 719 ldn [%o0 + AHI_PUT32], %g1 /* hdl->ahi_put16 access handle */ 720 jmpl %g1, %g0 /* jump to access handle routine */ 721 nop 722 SET_SIZE(ddi_put32) 723 SET_SIZE(ddi_putl) 724 SET_SIZE(ddi_io_put32) 725 SET_SIZE(ddi_io_putl) 726 SET_SIZE(ddi_mem_put32) 727 SET_SIZE(ddi_mem_putl) 728 729 .align 16 730 ENTRY(i_ddi_put32) 731 ALTENTRY(i_ddi_swap_put32) 732 retl 733 st %o2, [%o1] 734 SET_SIZE(i_ddi_put32) 735 SET_SIZE(i_ddi_swap_put32) 736 737 .align 32 738 ENTRY(ddi_put64) 739 ALTENTRY(ddi_putll) 740 ALTENTRY(ddi_io_put64) 741 ALTENTRY(ddi_io_putll) 742 ALTENTRY(ddi_mem_put64) 743 ALTENTRY(ddi_mem_putll) 744 ldn [%o0 + AHI_PUT64], %g1 /* hdl->ahi_put64 access handle */ 745 jmpl %g1, %g0 /* jump to access handle routine */ 746 nop 747 SET_SIZE(ddi_put64) 748 SET_SIZE(ddi_putll) 749 SET_SIZE(ddi_io_put64) 750 SET_SIZE(ddi_io_putll) 751 SET_SIZE(ddi_mem_put64) 752 SET_SIZE(ddi_mem_putll) 753 754 .align 16 755 ENTRY(i_ddi_put64) 756 ALTENTRY(i_ddi_swap_put64) 757 retl 758 stx %o2, [%o1] 759 SET_SIZE(i_ddi_put64) 760 SET_SIZE(i_ddi_swap_put64) 761 762/* 763 * The ddi_io_rep_get/put routines don't take a flag argument like the "plain" 764 * and mem versions do. This flag is used to determine whether or not the 765 * device address or port should be automatically incremented. For IO space, 766 * the device port is never incremented and as such, the flag is always set 767 * to DDI_DEV_NO_AUTOINCR. 768 * 769 * This define processes the repetitive get functionality. Automatic 770 * incrementing of the device address is determined by the flag field 771 * %o4. If this is set for AUTOINCR, %o4 is updated with 1 for the 772 * subsequent increment in 2:. 773 * 774 * If this flag is not set for AUTOINCR, %o4 is update with a value of 0 thus 775 * making the increment operation a non-operation. 776 */ 777 778#define DDI_REP_GET(n,s) \ 779 cmp DDI_DEV_NO_AUTOINCR, %o4; \ 780 mov %g0, %o4; \ 781 brz,pn %o3, 1f; \ 782 movnz %xcc, n, %o4; \ 7832: \ 784 dec %o3; \ 785 ld/**/s [%o2], %g4; \ 786 add %o2, %o4, %o2; \ 787 st/**/s %g4, [%o1]; \ 788 brnz,pt %o3, 2b; \ 789 add %o1, n, %o1; \ 7901: 791 792 .align 32 793 ENTRY(ddi_rep_get8) 794 ALTENTRY(ddi_rep_getb) 795 ALTENTRY(ddi_mem_rep_get8) 796 ALTENTRY(ddi_mem_rep_getb) 797 ldn [%o0 + AHI_REP_GET8], %g1 798 jmpl %g1, %g0 799 nop 800 SET_SIZE(ddi_rep_get8) 801 SET_SIZE(ddi_rep_getb) 802 SET_SIZE(ddi_mem_rep_get8) 803 SET_SIZE(ddi_mem_rep_getb) 804 805 .align 16 806 ENTRY(i_ddi_rep_get8) 807 DDI_REP_GET(1,ub) 808 retl 809 nop 810 SET_SIZE(i_ddi_rep_get8) 811 812 .align 32 813 ENTRY(ddi_rep_get16) 814 ALTENTRY(ddi_rep_getw) 815 ALTENTRY(ddi_mem_rep_get16) 816 ALTENTRY(ddi_mem_rep_getw) 817 ldn [%o0 + AHI_REP_GET16], %g1 818 jmpl %g1, %g0 819 nop 820 SET_SIZE(ddi_rep_get16) 821 SET_SIZE(ddi_rep_getw) 822 SET_SIZE(ddi_mem_rep_get16) 823 SET_SIZE(ddi_mem_rep_getw) 824 825 .align 16 826 ENTRY(i_ddi_rep_get16) 827 ALTENTRY(i_ddi_swap_rep_get16) 828 DDI_REP_GET(2,uh) 829 retl 830 nop 831 SET_SIZE(i_ddi_rep_get16) 832 SET_SIZE(i_ddi_swap_rep_get16) 833 834 .align 32 835 ENTRY(ddi_rep_get32) 836 ALTENTRY(ddi_rep_getl) 837 ALTENTRY(ddi_mem_rep_get32) 838 ALTENTRY(ddi_mem_rep_getl) 839 ldn [%o0 + AHI_REP_GET32], %g1 840 jmpl %g1, %g0 841 nop 842 SET_SIZE(ddi_rep_get32) 843 SET_SIZE(ddi_rep_getl) 844 SET_SIZE(ddi_mem_rep_get32) 845 SET_SIZE(ddi_mem_rep_getl) 846 847 .align 16 848 ENTRY(i_ddi_rep_get32) 849 ALTENTRY(i_ddi_swap_rep_get32) 850 DDI_REP_GET(4,/**/) 851 retl 852 nop 853 SET_SIZE(i_ddi_rep_get32) 854 SET_SIZE(i_ddi_swap_rep_get32) 855 856 .align 32 857 ENTRY(ddi_rep_get64) 858 ALTENTRY(ddi_rep_getll) 859 ALTENTRY(ddi_mem_rep_get64) 860 ALTENTRY(ddi_mem_rep_getll) 861 ldn [%o0 + AHI_REP_GET64], %g1 862 jmpl %g1, %g0 863 nop 864 SET_SIZE(ddi_rep_get64) 865 SET_SIZE(ddi_rep_getll) 866 SET_SIZE(ddi_mem_rep_get64) 867 SET_SIZE(ddi_mem_rep_getll) 868 869 .align 16 870 ENTRY(i_ddi_rep_get64) 871 ALTENTRY(i_ddi_swap_rep_get64) 872 DDI_REP_GET(8,x) 873 retl 874 nop 875 SET_SIZE(i_ddi_rep_get64) 876 SET_SIZE(i_ddi_swap_rep_get64) 877 878/* 879 * This define processes the repetitive put functionality. Automatic 880 * incrementing of the device address is determined by the flag field 881 * %o4. If this is set for AUTOINCR, %o4 is updated with 1 for the 882 * subsequent increment in 2:. 883 * 884 * If this flag is not set for AUTOINCR, %o4 is update with a value of 0 thus 885 * making the increment operation a non-operation. 886 */ 887#define DDI_REP_PUT(n,s) \ 888 cmp DDI_DEV_NO_AUTOINCR, %o4; \ 889 mov %g0, %o4; \ 890 brz,pn %o3, 1f; \ 891 movnz %xcc, n, %o4; \ 8922: \ 893 dec %o3; \ 894 ld/**/s [%o1], %g4; \ 895 add %o1, n, %o1; \ 896 st/**/s %g4, [%o2]; \ 897 brnz,pt %o3, 2b; \ 898 add %o2, %o4, %o2; \ 8991: 900 901 .align 32 902 ENTRY(ddi_rep_put8) 903 ALTENTRY(ddi_rep_putb) 904 ALTENTRY(ddi_mem_rep_put8) 905 ALTENTRY(ddi_mem_rep_putb) 906 ldn [%o0 + AHI_REP_PUT8], %g1 907 jmpl %g1, %g0 908 nop 909 SET_SIZE(ddi_rep_put8) 910 SET_SIZE(ddi_rep_putb) 911 SET_SIZE(ddi_mem_rep_put8) 912 SET_SIZE(ddi_mem_rep_putb) 913 914 .align 16 915 ENTRY(i_ddi_rep_put8) 916 DDI_REP_PUT(1,ub) 917 retl 918 nop 919 SET_SIZE(i_ddi_rep_put8) 920 921 .align 32 922 ENTRY(ddi_rep_put16) 923 ALTENTRY(ddi_rep_putw) 924 ALTENTRY(ddi_mem_rep_put16) 925 ALTENTRY(ddi_mem_rep_putw) 926 ldn [%o0 + AHI_REP_PUT16], %g1 927 jmpl %g1, %g0 928 nop 929 SET_SIZE(ddi_rep_put16) 930 SET_SIZE(ddi_rep_putw) 931 SET_SIZE(ddi_mem_rep_put16) 932 SET_SIZE(ddi_mem_rep_putw) 933 934 .align 16 935 ENTRY(i_ddi_rep_put16) 936 ALTENTRY(i_ddi_swap_rep_put16) 937 DDI_REP_PUT(2,uh) 938 retl 939 nop 940 SET_SIZE(i_ddi_rep_put16) 941 SET_SIZE(i_ddi_swap_rep_put16) 942 943 .align 32 944 ENTRY(ddi_rep_put32) 945 ALTENTRY(ddi_rep_putl) 946 ALTENTRY(ddi_mem_rep_put32) 947 ALTENTRY(ddi_mem_rep_putl) 948 ldn [%o0 + AHI_REP_PUT32], %g1 949 jmpl %g1, %g0 950 nop 951 SET_SIZE(ddi_rep_put32) 952 SET_SIZE(ddi_rep_putl) 953 SET_SIZE(ddi_mem_rep_put32) 954 SET_SIZE(ddi_mem_rep_putl) 955 956 .align 16 957 ENTRY(i_ddi_rep_put32) 958 ALTENTRY(i_ddi_swap_rep_put32) 959 DDI_REP_PUT(4,/**/) 960 retl 961 nop 962 SET_SIZE(i_ddi_rep_put32) 963 SET_SIZE(i_ddi_swap_rep_put32) 964 965 .align 32 966 ENTRY(ddi_rep_put64) 967 ALTENTRY(ddi_rep_putll) 968 ALTENTRY(ddi_mem_rep_put64) 969 ALTENTRY(ddi_mem_rep_putll) 970 ldn [%o0 + AHI_REP_PUT64], %g1 971 jmpl %g1, %g0 972 nop 973 SET_SIZE(ddi_rep_put64) 974 SET_SIZE(ddi_rep_putll) 975 SET_SIZE(ddi_mem_rep_put64) 976 SET_SIZE(ddi_mem_rep_putll) 977 978 .align 16 979 ENTRY(i_ddi_rep_put64) 980 ALTENTRY(i_ddi_swap_rep_put64) 981 DDI_REP_PUT(8,x) 982 retl 983 nop 984 SET_SIZE(i_ddi_rep_put64) 985 SET_SIZE(i_ddi_swap_rep_put64) 986 987 .align 16 988 ENTRY(ddi_io_rep_get8) 989 ALTENTRY(ddi_io_rep_getb) 990 set DDI_DEV_NO_AUTOINCR, %o4 /* Set flag to DDI_DEV_NO_AUTOINCR */ 991 ldn [%o0 + AHI_REP_GET8], %g1 992 jmpl %g1, %g0 993 nop 994 SET_SIZE(ddi_io_rep_get8) 995 SET_SIZE(ddi_io_rep_getb) 996 997 .align 16 998 ENTRY(ddi_io_rep_get16) 999 ALTENTRY(ddi_io_rep_getw) 1000 set DDI_DEV_NO_AUTOINCR, %o4 /* Set flag to DDI_DEV_NO_AUTOINCR */ 1001 ldn [%o0 + AHI_REP_GET16], %g1 1002 jmpl %g1, %g0 1003 nop 1004 SET_SIZE(ddi_io_rep_get16) 1005 SET_SIZE(ddi_io_rep_getw) 1006 1007 .align 16 1008 ENTRY(ddi_io_rep_get32) 1009 ALTENTRY(ddi_io_rep_getl) 1010 set DDI_DEV_NO_AUTOINCR, %o4 /* Set flag to DDI_DEV_NO_AUTOINCR */ 1011 ldn [%o0 + AHI_REP_GET32], %g1 1012 jmpl %g1, %g0 1013 nop 1014 SET_SIZE(ddi_io_rep_get32) 1015 SET_SIZE(ddi_io_rep_getl) 1016 1017 .align 16 1018 ENTRY(ddi_io_rep_get64) 1019 ALTENTRY(ddi_io_rep_getll) 1020 set DDI_DEV_NO_AUTOINCR, %o4 /* Set flag to DDI_DEV_NO_AUTOINCR */ 1021 ldn [%o0 + AHI_REP_GET64], %g1 1022 jmpl %g1, %g0 1023 nop 1024 SET_SIZE(ddi_io_rep_get64) 1025 SET_SIZE(ddi_io_rep_getll) 1026 1027 .align 64 1028 ENTRY(ddi_check_acc_handle) 1029 save %sp, -SA(WINDOWSIZE), %sp ! get a new window 1030 ldn [%i0 + AHI_FAULT_CHECK], %g1 1031 jmpl %g1, %o7 1032 mov %i0, %o0 1033 brnz,a,pn %o0, 0f ! if (return_value != 0) 1034 mov -1, %o0 ! return (DDI_FAILURE) 10350: ! else return (DDI_SUCCESS) 1036 sra %o0, 0, %i0 1037 ret 1038 restore 1039 SET_SIZE(ddi_check_acc_handle) 1040 1041 .align 16 1042 ENTRY(i_ddi_acc_fault_check) 1043 retl 1044 ld [%o0 + AHI_FAULT], %o0 1045 SET_SIZE(i_ddi_acc_fault_check) 1046 1047 .align 16 1048 ENTRY(ddi_io_rep_put8) 1049 ALTENTRY(ddi_io_rep_putb) 1050 set DDI_DEV_NO_AUTOINCR, %o4 /* Set flag to DDI_DEV_NO_AUTOINCR */ 1051 ldn [%o0 + AHI_REP_PUT8], %g1 1052 jmpl %g1, %g0 1053 nop 1054 SET_SIZE(ddi_io_rep_put8) 1055 SET_SIZE(ddi_io_rep_putb) 1056 1057 .align 16 1058 ENTRY(ddi_io_rep_put16) 1059 ALTENTRY(ddi_io_rep_putw) 1060 set DDI_DEV_NO_AUTOINCR, %o4 /* Set flag to DDI_DEV_NO_AUTOINCR */ 1061 ldn [%o0 + AHI_REP_PUT16], %g1 1062 jmpl %g1, %g0 1063 nop 1064 SET_SIZE(ddi_io_rep_put16) 1065 SET_SIZE(ddi_io_rep_putw) 1066 1067 .align 16 1068 ENTRY(ddi_io_rep_put32) 1069 ALTENTRY(ddi_io_rep_putl) 1070 set DDI_DEV_NO_AUTOINCR, %o4 /* Set flag to DDI_DEV_NO_AUTOINCR */ 1071 ldn [%o0 + AHI_REP_PUT32], %g1 1072 jmpl %g1, %g0 1073 nop 1074 SET_SIZE(ddi_io_rep_put32) 1075 SET_SIZE(ddi_io_rep_putl) 1076 1077 .align 16 1078 ENTRY(ddi_io_rep_put64) 1079 ALTENTRY(ddi_io_rep_putll) 1080 set DDI_DEV_NO_AUTOINCR, %o4 /* Set flag to DDI_DEV_NO_AUTOINCR */ 1081 ldn [%o0 + AHI_REP_PUT64], %g1 1082 jmpl %g1, %g0 1083 nop 1084 SET_SIZE(ddi_io_rep_put64) 1085 SET_SIZE(ddi_io_rep_putll) 1086 1087 ENTRY(do_peek) 1088 rdpr %pstate, %o3 ! check ints 1089 andcc %o3, PSTATE_IE, %g0 1090 bz,a done 1091 or %g0, 1, %o0 ! Return failure if ints are disabled 1092 wrpr %o3, PSTATE_IE, %pstate 1093 cmp %o0, 8 ! 64-bit? 1094 bne,a .peek_int 1095 cmp %o0, 4 ! 32-bit? 1096 ldx [%o1], %g1 1097 ba .peekdone 1098 stx %g1, [%o2] 1099.peek_int: 1100 bne,a .peek_half 1101 cmp %o0, 2 ! 16-bit? 1102 lduw [%o1], %g1 1103 ba .peekdone 1104 stuw %g1, [%o2] 1105.peek_half: 1106 bne,a .peek_byte 1107 ldub [%o1], %g1 ! 8-bit! 1108 lduh [%o1], %g1 1109 ba .peekdone 1110 stuh %g1, [%o2] 1111.peek_byte: 1112 stub %g1, [%o2] 1113.peekdone: 1114 membar #Sync ! Make sure the loads take 1115 rdpr %pstate, %o3 ! check&enable ints 1116 andcc %o3, PSTATE_IE, %g0 1117 bnz 1f 1118 nop 1119 wrpr %o3, PSTATE_IE, %pstate 11201: 1121 mov %g0, %o0 1122done: 1123 retl 1124 nop 1125 SET_SIZE(do_peek) 1126 1127 ENTRY(do_poke) 1128 cmp %o0, 8 ! 64 bit? 1129 bne,a .poke_int 1130 cmp %o0, 4 ! 32-bit? 1131 ldx [%o2], %g1 1132 ba .pokedone 1133 stx %g1, [%o1] 1134.poke_int: 1135 bne,a .poke_half 1136 cmp %o0, 2 ! 16-bit? 1137 lduw [%o2], %g1 1138 ba .pokedone 1139 stuw %g1, [%o1] 1140.poke_half: 1141 bne,a .poke_byte 1142 ldub [%o2], %g1 ! 8-bit! 1143 lduh [%o2], %g1 1144 ba .pokedone 1145 stuh %g1, [%o1] 1146.poke_byte: 1147 stub %g1, [%o1] 1148.pokedone: 1149 membar #Sync 1150 retl 1151 mov %g0, %o0 1152 SET_SIZE(do_poke) 1153 1154 1155/* 1156 * The peek_fault() and poke_fault() routines below are used as on_trap() 1157 * trampoline routines. i_ddi_peek and i_ddi_poke execute do_peek and do_poke 1158 * under on_trap protection (see <sys/ontrap.h>), but modify ot_trampoline to 1159 * refer to the corresponding routine below. If a trap occurs, the trap code 1160 * will bounce back to the trampoline code, which will effectively cause 1161 * do_peek or do_poke to return DDI_FAILURE, instead of longjmp'ing back to 1162 * on_trap. In the case of a peek, we may also need to re-enable interrupts. 1163 */ 1164 .seg ".data" 1165.peek_panic: 1166 .asciz "peek_fault: missing or invalid on_trap_data" 1167.poke_panic: 1168 .asciz "poke_fault: missing or invalid on_trap_data" 1169 1170 ENTRY(peek_fault) 1171 ldn [THREAD_REG + T_ONTRAP], %o0 ! %o0 = on_trap_data pointer 1172 brz,pn %o0, .peekfail ! if (%o0 == NULL) panic 1173 nop 1174 lduh [%o0 + OT_PROT], %o1 ! %o1 = %o0->ot_prot 1175 andcc %o1, OT_DATA_ACCESS, %g0 ! if (!(%o1 & OT_DATA_ACCESS)) 1176 bz,pn %icc, .peekfail ! panic 1177 rdpr %pstate, %o3 1178 1179 andcc %o3, PSTATE_IE, %g0 ! enable interrupts 1180 bnz 1f 1181 nop 1182 wrpr %o3, PSTATE_IE, %pstate 11831: 1184 retl 1185 sub %g0, 1, %o0 ! return (DDI_FAILURE); 1186.peekfail: 1187 set .peek_panic, %o0 ! Load panic message 1188 call panic ! Panic if bad t_ontrap data 1189 nop 1190 SET_SIZE(peek_fault) 1191 1192 1193 ENTRY(poke_fault) 1194 ldn [THREAD_REG + T_ONTRAP], %o0 ! %o0 = on_trap_data pointer 1195 brz,pn %o0, .pokefail ! if (%o0 == NULL) panic 1196 nop 1197 lduh [%o0 + OT_PROT], %o1 ! %o1 = %o0->ot_prot 1198 andcc %o1, OT_DATA_ACCESS, %g0 ! if (!(%o1 & OT_DATA_ACCESS)) 1199 bz,pn %icc, .pokefail ! panic 1200 nop 1201 retl 1202 sub %g0, 1, %o0 ! return (DDI_FAILURE); 1203.pokefail: 1204 set .poke_panic, %o0 ! Load panic message 1205 call panic ! Panic if bad t_ontrap data 1206 nop 1207 SET_SIZE(poke_fault) 1208 1209 1210/* 1211 * IO Fault Services 1212 * 1213 * Support for protected IO accesses is implemented in the following 1214 * functions. A driver may request one of three protection mechanisms 1215 * that enable the system to survive an access errors. The protection 1216 * mechansim is set-up during ddi_regs_map_setup time and may be one of: 1217 * 1218 * DDI_DEFAULT_ACC - no error protection requested. We will 1219 * use the standard ddi_get/ddi_put operations 1220 * defined above. 1221 * 1222 * DDI_FLAGERR - Driver requests that errors encountered will 1223 * be flagged by the system. The driver is 1224 * responsible for checking the error status 1225 * of the access with a call to ddi_acc_err_get() 1226 * upon return of ddi_get or ddi_put. To prevent 1227 * an access from causing a system we use internal 1228 * on_trap semantics. 1229 * 1230 * The system, depending upon the error, 1231 * may or may not panic. 1232 * 1233 * DDI_CAUTIOUS_ACC - Driver expects that the access may cause 1234 * an error to occur. The system will return 1235 * an error status but will not generate an ereport. 1236 * The system will also ensure synchronous and 1237 * exclusive access to the IO space accessed by 1238 * the caller. 1239 * 1240 * To prevent an access from causing a system panic, 1241 * we use on_trap semantics to catch the error and 1242 * set error status. 1243 * 1244 * If a read access error is detected and DDI_CAUTIOUS_ACC or 1245 * DDI_FLAGERR_ACC protection was requested, we will trampoline to the 1246 * error handler, i_ddi_trampoline. i_ddi_trampoline will: 1247 * - check for proper protection semantics 1248 * - set the error status of the access handle to DDI_FM_NONFATAL 1249 * - re-enable interrupts if neccessary 1250 * - longjmp back to the initiating access function. 1251 1252 * If a write access error is detected, an interrupt is typically 1253 * generated and claimed by a bus nexus responsible for the write 1254 * transaction. The nexus error handler is expected to set the 1255 * error status and the IO initiating driver is expected to check 1256 * for a failed transaction via ddi_fm_acc_err_get(). 1257 * 1258 */ 1259 1260 .seg ".data" 1261.acc_panic: 1262 .asciz "DDI access: missing or invalid on_trap_data" 1263 1264 ENTRY(i_ddi_caut_trampoline) 1265 ldn [THREAD_REG + T_ONTRAP], %o5 ! %o5 = curthread->t_ontrap 1266 lduh [%o5 + OT_PROT], %o1 ! %o1 = %o0->ot_prot 1267 andcc %o1, OT_DATA_ACCESS, %g0 ! if (!(%o1 & OT_DATA_ACCESS)) 1268 bz,pn %icc, .cautaccfail ! panic 1269 rdpr %pstate, %o3 1270 andcc %o3, PSTATE_IE, %g0 ! enable interrupts 1271 bnz 1f 1272 nop 1273 wrpr %o3, PSTATE_IE, %pstate 12741: 1275 ldn [%o5 + OT_HANDLE], %o0 ! %o0 = ot_handle 1276 brz,pn %o0, .cautaccfail ! if (ot_handle == NULL) panic 1277 nop 1278 ldn [%o0 + AHI_ERR], %o4 ! %o4 = hp->ahi_err 1279 membar #Sync 1280 stx %g0, [%o4 + ERR_ENA] ! ahi_err->err_ena = 0 1281 mov -2, %o0 1282 st %o0, [%o4 + ERR_STATUS] ! ahi_err->err_status = NONFATAL 1283 b longjmp ! longjmp back 1284 add %o5, OT_JMPBUF, %o0 ! %o0 = &ot_jmpbuf 1285.cautaccfail: 1286 set .acc_panic, %o0 ! Load panic message 1287 call panic ! Panic if bad t_ontrap data 1288 nop 1289 SET_SIZE(i_ddi_caut_trampoline) 1290 1291/* 1292 * DDI on_trap set-up functions, i_ddi_ontrap() and i_ddinotrap() are used 1293 * to protect * ddi_get accesses for DDI_CAUT_ACC. i_ddi_ontrap() sets 1294 * the jumpbuf (setjmp) that will return back to the access routine from 1295 * i_ddi_trampoline(). DDI_NOPROTECT() clears the ontrap set-up. 1296 */ 1297 ENTRY(i_ddi_ontrap) 1298 ldn [%o0 + AHI_ERR], %o4 1299 ldn [%o4 + ERR_ONTRAP], %o4 ! %o4 = hp->ahi_err->err_ontrap 1300 ldn [THREAD_REG + T_ONTRAP], %o5 ! %o5 = curthread->t_ontrap 1301 stn %o5, [%o4 + OT_PREV] ! ot_prev = t_ontrap 1302 membar #Sync ! force error barrier 1303 stn %o4, [THREAD_REG + T_ONTRAP] ! t_ontrap = err_ontrap 1304 b setjmp 1305 add %o4, OT_JMPBUF, %o0 1306 SET_SIZE(i_ddi_ontrap) 1307 1308 ENTRY(i_ddi_notrap) 1309 membar #Sync ! force error barrier 1310 ldn [%o0 + AHI_ERR], %o4 1311 ldn [%o4 + ERR_ONTRAP], %o4 ! %o4 = hp->ahi_err->err_ontrap 1312 ldn [%o4 + OT_PREV], %o4 1313 retl 1314 stn %o4, [THREAD_REG + T_ONTRAP] ! restore curthread->t_ontrap 1315 SET_SIZE(i_ddi_notrap) 1316 1317/* 1318 * Internal on_trap set-up macros. DDI_PROTECT() and DDI_NOPROTECT() are used 1319 * to protect * ddi_get accesses for DDI_FLAGERR_ACC. DDI_NOPROTECT() sets 1320 * the jumpbuf that will return back to the access routine from 1321 * i_ddi_protect_trampoline(). DDI_NOPROTECT() clears the ontrap set-up. 1322 */ 1323 ENTRY(i_ddi_prot_trampoline) 1324 ldn [THREAD_REG + T_ONTRAP], %o5 ! %o5 = curthread->t_ontrap 1325 lduh [%o5 + OT_PROT], %o1 ! %o1 = %o0->ot_prot 1326 andcc %o1, OT_DATA_ACCESS, %g0 ! if (!(%o1 & OT_DATA_ACCESS)) 1327 bz,pn %icc, .protaccfail ! panic 1328 rdpr %pstate, %o3 1329 andcc %o3, PSTATE_IE, %g0 ! enable interrupts 1330 bnz 1f 1331 nop 1332 wrpr %o3, PSTATE_IE, %pstate 13331: 1334 ldn [%o5 + OT_HANDLE], %o0 ! %o0 = ot_handle 1335 brz,pn %o0, .protaccfail ! if (ot_handle == NULL) panic 1336 nop 1337 ldn [%o0 + AHI_ERR], %o4 ! %o4 = hp->ahi_err 1338 stn %g0, [%o4 + ERR_ENA] ! ahi_err->err_ena = 0 1339 mov -2, %o0 1340 st %o0, [%o4 + ERR_STATUS] ! ahi_err->err_status = NONFATAL 1341 ldn [%o5 + OT_PREV], %o0 ! restore ontrap 1342 membar #Sync ! force error barrier 1343 stn %o0, [THREAD_REG + T_ONTRAP]; 1344 b longjmp ! longjmp back 1345 add %o5, OT_JMPBUF, %o0 ! %o0 = &ot_jmpbuf 1346.protaccfail: 1347 set .acc_panic, %o0 ! Load panic message 1348 call panic ! Panic if bad t_ontrap data 1349 nop 1350 SET_SIZE(i_ddi_prot_trampoline) 1351 1352#define DDI_PROTECT() \ 1353 ldn [%o0 + AHI_ERR], %o4; \ 1354 ldn [%o4 + ERR_ONTRAP], %o4; \ 1355 ldn [THREAD_REG + T_ONTRAP], %o5; \ 1356 stn %o5, [%o4 + OT_PREV]; \ 1357 membar #Sync; \ 1358 stn %o4, [THREAD_REG + T_ONTRAP]; \ 1359 add %o4, OT_JMPBUF, %o0; \ 1360 stn %o7, [%o0 + L_PC]; \ 1361 stn %sp, [%o0 + L_SP]; \ 1362 clr %o0; 1363 1364#define DDI_NOPROTECT() \ 1365 ldn [THREAD_REG + T_ONTRAP], %o4; \ 1366 ldn [%o4 + OT_PREV], %o5; \ 1367 membar #Sync; \ 1368 stn %o5, [THREAD_REG + T_ONTRAP]; 1369 1370/* 1371 * DDI_FLAGERR_ACC specific get/put routines. 1372 */ 1373 .align 16 1374 ENTRY(i_ddi_prot_get8) 1375 DDI_PROTECT() ! set ontrap protection 1376 ldub [%o1], %o2 ! do the io access 1377 DDI_NOPROTECT() ! remove protection & ret 1378 retl 1379 mov %o2, %o0 ! set return value 1380 SET_SIZE(i_ddi_prot_get8) 1381 1382 .align 16 1383 ENTRY(i_ddi_prot_get16) 1384 DDI_PROTECT() ! set ontrap protection 1385 lduh [%o1], %o2 ! do the io access 1386 DDI_NOPROTECT() ! remove protection & ret 1387 retl 1388 mov %o2, %o0 ! set return value 1389 SET_SIZE(i_ddi_prot_get16) 1390 1391 .align 16 1392 ENTRY(i_ddi_prot_get32) 1393 DDI_PROTECT() ! set ontrap protection 1394 ld [%o1], %o2 ! do the io access 1395 DDI_NOPROTECT() ! remove protection & ret 1396 retl 1397 mov %o2, %o0 ! set return value 1398 SET_SIZE(i_ddi_prot_get32) 1399 1400 .align 16 1401 ENTRY(i_ddi_prot_get64) 1402 DDI_PROTECT() ! set ontrap protection 1403 ldx [%o1], %o2 ! do the io access 1404 DDI_NOPROTECT() ! remove protection & ret 1405 retl 1406 mov %o2, %o0 ! set return value 1407 SET_SIZE(i_ddi_prot_get64) 1408 1409 .align 16 1410 ENTRY(i_ddi_prot_put8) 1411 stub %o2, [%o1] ! do the io access 1412 retl 1413 membar #Sync; 1414 SET_SIZE(i_ddi_prot_put8) 1415 1416 .align 16 1417 ENTRY(i_ddi_prot_put16) 1418 stuh %o2, [%o1] ! do the io access 1419 retl 1420 membar #Sync; 1421 SET_SIZE(i_ddi_prot_put16) 1422 1423 .align 16 1424 ENTRY(i_ddi_prot_put32) 1425 st %o2, [%o1] ! do the io access 1426 retl 1427 membar #Sync; 1428 SET_SIZE(i_ddi_prot_put32) 1429 1430 .align 16 1431 ENTRY(i_ddi_prot_put64) 1432 stx %o2, [%o1] ! do the io access 1433 retl 1434 membar #Sync; 1435 SET_SIZE(i_ddi_prot_put64) 1436 1437 .align 16 1438 ENTRY(i_ddi_prot_rep_get8) 1439 DDI_PROTECT() ! set ontrap protection 1440 tst %o0 ! check access error 1441 bnz,a 1f 1442 nop 1443 DDI_REP_GET(1,ub) 14441: 1445 DDI_NOPROTECT() ! remove protection & ret 1446 retl 1447 nop 1448 SET_SIZE(i_ddi_prot_rep_get8) 1449 1450 .align 16 1451 ENTRY(i_ddi_prot_rep_get16) 1452 DDI_PROTECT() ! set ontrap protection 1453 tst %o0 ! check access error 1454 bnz,a 1f 1455 nop 1456 DDI_REP_GET(2,uh) 14571: 1458 DDI_NOPROTECT() ! remove protection & ret 1459 retl 1460 nop 1461 SET_SIZE(i_ddi_prot_rep_get16) 1462 1463 .align 16 1464 ENTRY(i_ddi_prot_rep_get32) 1465 DDI_PROTECT() ! set ontrap protection 1466 tst %o0 ! check access error 1467 bnz,a 1f 1468 nop 1469 DDI_REP_GET(4,/**/) 14701: 1471 DDI_NOPROTECT() ! remove protection & ret 1472 retl 1473 nop 1474 SET_SIZE(i_ddi_prot_rep_get32) 1475 1476 .align 16 1477 ENTRY(i_ddi_prot_rep_get64) 1478 DDI_PROTECT() ! set ontrap protection 1479 tst %o0 ! check access error 1480 bnz,a 1f 1481 nop 1482 DDI_REP_GET(8,x) 14831: 1484 DDI_NOPROTECT() ! remove protection & ret 1485 retl 1486 nop 1487 SET_SIZE(i_ddi_prot_rep_get64) 1488 1489 .align 16 1490 ENTRY(i_ddi_prot_rep_put8) 1491 DDI_REP_PUT(1,ub) 1492 retl 1493 membar #Sync; 1494 SET_SIZE(i_ddi_prot_rep_put8) 1495 1496 .align 16 1497 ENTRY(i_ddi_prot_rep_put16) 1498 DDI_REP_PUT(2,uh) 1499 retl 1500 membar #Sync; 1501 SET_SIZE(i_ddi_prot_rep_put16) 1502 1503 .align 16 1504 ENTRY(i_ddi_prot_rep_put32) 1505 DDI_REP_PUT(4,/**/) 1506 retl 1507 membar #Sync; 1508 SET_SIZE(i_ddi_prot_rep_put32) 1509 1510 .align 16 1511 ENTRY(i_ddi_prot_rep_put64) 1512 DDI_REP_PUT(8,x) 1513 retl 1514 membar #Sync; 1515 SET_SIZE(i_ddi_prot_rep_put64) 1516 1517/* 1518 * Common DDI_CAUTIOUS_ACC routine called from cautious access routines 1519 * in ddi_impl.c 1520 */ 1521 ENTRY(i_ddi_caut_get) 1522 rdpr %pstate, %o3 ! check ints 1523 andcc %o3, PSTATE_IE, %g0 1524 bz,a cautdone 1525 nop 1526 wrpr %o3, PSTATE_IE, %pstate 1527 cmp %o0, 8 ! 64-bit? 1528 bne,a .get_int 1529 cmp %o0, 4 ! 32-bit? 1530 ldx [%o1], %g1 1531 ba .getdone 1532 stx %g1, [%o2] 1533.get_int: 1534 bne,a .get_half 1535 cmp %o0, 2 ! 16-bit? 1536 lduw [%o1], %g1 1537 ba .getdone 1538 stuw %g1, [%o2] 1539.get_half: 1540 bne,a .get_byte 1541 ldub [%o1], %g1 ! 8-bit! 1542 lduh [%o1], %g1 1543 ba .getdone 1544 stuh %g1, [%o2] 1545.get_byte: 1546 stub %g1, [%o2] 1547.getdone: 1548 rdpr %pstate, %o3 ! check&enable ints 1549 andcc %o3, PSTATE_IE, %g0 1550 bnz,a cautdone 1551 nop 1552 wrpr %o3, PSTATE_IE, %pstate 1553cautdone: 1554 retl 1555 nop 1556 SET_SIZE(i_ddi_caut_get) 1557 1558#endif /* lint */ 1559