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 2005 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * Copyright 2019 Joyent, Inc.
  29  */
  30 
  31 #include <sys/asm_linkage.h>
  32 #include <sys/asm_misc.h>
  33 #include "assym.h"
  34 
  35         ENTRY(ddi_get8)
  36         ALTENTRY(ddi_getb)
  37         ALTENTRY(ddi_mem_getb)
  38         ALTENTRY(ddi_mem_get8)
  39         ALTENTRY(ddi_io_getb)
  40         ALTENTRY(ddi_io_get8)
  41         movl    ACC_ATTR(%rdi), %edx
  42         cmpl    $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %edx
  43         jne     1f
  44         movq    %rsi, %rdx
  45         xorq    %rax, %rax
  46         inb     (%dx)
  47         ret
  48 1:
  49         cmpl    $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %edx
  50         jne     2f
  51         movzbq  (%rsi), %rax
  52         ret
  53 2:
  54         movq    ACC_GETB(%rdi), %rax
  55         INDIRECT_JMP_REG(rax)
  56         SET_SIZE(ddi_get8)
  57         SET_SIZE(ddi_getb)
  58         SET_SIZE(ddi_mem_getb)
  59         SET_SIZE(ddi_mem_get8)
  60         SET_SIZE(ddi_io_getb)
  61         SET_SIZE(ddi_io_get8)
  62 
  63 
  64         ENTRY(ddi_get16)
  65         ALTENTRY(ddi_getw)
  66         ALTENTRY(ddi_mem_getw)
  67         ALTENTRY(ddi_mem_get16)
  68         ALTENTRY(ddi_io_getw)
  69         ALTENTRY(ddi_io_get16)
  70         movl    ACC_ATTR(%rdi), %edx
  71         cmpl    $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %edx
  72         jne     3f
  73         movq    %rsi, %rdx
  74         xorq    %rax, %rax
  75         inw     (%dx)
  76         ret
  77 3:
  78         cmpl    $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %edx
  79         jne     4f
  80         movzwq  (%rsi), %rax
  81         ret
  82 4:
  83         movq    ACC_GETW(%rdi), %rax
  84         INDIRECT_JMP_REG(rax)
  85         SET_SIZE(ddi_get16)
  86         SET_SIZE(ddi_getw)
  87         SET_SIZE(ddi_mem_getw)
  88         SET_SIZE(ddi_mem_get16)
  89         SET_SIZE(ddi_io_getw)
  90         SET_SIZE(ddi_io_get16)
  91 
  92 
  93         ENTRY(ddi_get32)
  94         ALTENTRY(ddi_getl)
  95         ALTENTRY(ddi_mem_getl)
  96         ALTENTRY(ddi_mem_get32)
  97         ALTENTRY(ddi_io_getl)
  98         ALTENTRY(ddi_io_get32)
  99         movl    ACC_ATTR(%rdi), %edx
 100         cmpl    $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %edx
 101         jne     5f
 102         movq    %rsi, %rdx
 103         inl     (%dx)
 104         ret
 105 5:
 106         cmpl    $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %edx
 107         jne     6f
 108         movl    (%rsi), %eax
 109         ret
 110 6:
 111         movq    ACC_GETL(%rdi), %rax
 112         INDIRECT_JMP_REG(rax)
 113         SET_SIZE(ddi_get32)
 114         SET_SIZE(ddi_getl)
 115         SET_SIZE(ddi_mem_getl)
 116         SET_SIZE(ddi_mem_get32)
 117         SET_SIZE(ddi_io_getl)
 118         SET_SIZE(ddi_io_get32)
 119 
 120 
 121         ENTRY(ddi_get64)
 122         ALTENTRY(ddi_getll)
 123         ALTENTRY(ddi_mem_getll)
 124         ALTENTRY(ddi_mem_get64)
 125         movq    ACC_GETLL(%rdi), %rax
 126         INDIRECT_JMP_REG(rax)
 127         SET_SIZE(ddi_get64)
 128         SET_SIZE(ddi_getll)
 129         SET_SIZE(ddi_mem_getll)
 130         SET_SIZE(ddi_mem_get64)
 131 
 132 
 133         ENTRY(ddi_put8)
 134         ALTENTRY(ddi_putb)
 135         ALTENTRY(ddi_mem_putb)
 136         ALTENTRY(ddi_mem_put8)
 137         ALTENTRY(ddi_io_putb)
 138         ALTENTRY(ddi_io_put8)
 139         movl    ACC_ATTR(%rdi), %ecx
 140         cmpl    $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %ecx
 141         jne     7f
 142         movq    %rdx, %rax
 143         movq    %rsi, %rdx
 144         outb    (%dx)
 145         ret
 146 7:
 147         cmpl    $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %ecx
 148         jne     8f
 149         movb    %dl, (%rsi)
 150         ret
 151 8:
 152         movq    ACC_PUTB(%rdi), %rax
 153         INDIRECT_JMP_REG(rax)
 154         SET_SIZE(ddi_put8)
 155         SET_SIZE(ddi_putb)
 156         SET_SIZE(ddi_mem_putb)
 157         SET_SIZE(ddi_mem_put8)
 158         SET_SIZE(ddi_io_putb)
 159         SET_SIZE(ddi_io_put8)
 160 
 161 
 162         ENTRY(ddi_put16)
 163         ALTENTRY(ddi_putw)
 164         ALTENTRY(ddi_mem_putw)
 165         ALTENTRY(ddi_mem_put16)
 166         ALTENTRY(ddi_io_putw)
 167         ALTENTRY(ddi_io_put16)
 168         movl    ACC_ATTR(%rdi), %ecx
 169         cmpl    $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %ecx
 170         jne     8f
 171         movq    %rdx, %rax
 172         movq    %rsi, %rdx
 173         outw    (%dx)
 174         ret
 175 8:
 176         cmpl    $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %ecx
 177         jne     9f
 178         movw    %dx, (%rsi)
 179         ret
 180 9:
 181         movq    ACC_PUTW(%rdi), %rax
 182         INDIRECT_JMP_REG(rax)
 183         SET_SIZE(ddi_put16)
 184         SET_SIZE(ddi_putw)
 185         SET_SIZE(ddi_mem_putw)
 186         SET_SIZE(ddi_mem_put16)
 187         SET_SIZE(ddi_io_putw)
 188         SET_SIZE(ddi_io_put16)
 189 
 190 
 191         ENTRY(ddi_put32)
 192         ALTENTRY(ddi_putl)
 193         ALTENTRY(ddi_mem_putl)
 194         ALTENTRY(ddi_mem_put32)
 195         ALTENTRY(ddi_io_putl)
 196         ALTENTRY(ddi_io_put32)
 197         movl    ACC_ATTR(%rdi), %ecx
 198         cmpl    $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %ecx
 199         jne     8f
 200         movq    %rdx, %rax
 201         movq    %rsi, %rdx
 202         outl    (%dx)
 203         ret
 204 8:
 205         cmpl    $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %ecx
 206         jne     9f
 207         movl    %edx, (%rsi)
 208         ret
 209 9:
 210         movq    ACC_PUTL(%rdi), %rax
 211         INDIRECT_JMP_REG(rax)
 212         SET_SIZE(ddi_put32)
 213         SET_SIZE(ddi_putl)
 214         SET_SIZE(ddi_mem_putl)
 215         SET_SIZE(ddi_mem_put32)
 216         SET_SIZE(ddi_io_putl)
 217         SET_SIZE(ddi_io_put32)
 218 
 219 
 220         ENTRY(ddi_put64)
 221         ALTENTRY(ddi_putll)
 222         ALTENTRY(ddi_mem_putll)
 223         ALTENTRY(ddi_mem_put64)
 224         movq    ACC_PUTLL(%rdi), %rax
 225         INDIRECT_JMP_REG(rax)
 226         SET_SIZE(ddi_put64)
 227         SET_SIZE(ddi_putll)
 228         SET_SIZE(ddi_mem_putll)
 229         SET_SIZE(ddi_mem_put64)
 230 
 231 
 232         ENTRY(ddi_rep_get8)
 233         ALTENTRY(ddi_rep_getb)
 234         ALTENTRY(ddi_mem_rep_getb)
 235         ALTENTRY(ddi_mem_rep_get8)
 236         movq    ACC_REP_GETB(%rdi), %rax
 237         INDIRECT_JMP_REG(rax)
 238         SET_SIZE(ddi_rep_get8)
 239         SET_SIZE(ddi_rep_getb)
 240         SET_SIZE(ddi_mem_rep_getb)
 241         SET_SIZE(ddi_mem_rep_get8)
 242 
 243 
 244         ENTRY(ddi_rep_get16)
 245         ALTENTRY(ddi_rep_getw)
 246         ALTENTRY(ddi_mem_rep_getw)
 247         ALTENTRY(ddi_mem_rep_get16)
 248         movq    ACC_REP_GETW(%rdi), %rax
 249         INDIRECT_JMP_REG(rax)
 250         SET_SIZE(ddi_rep_get16)
 251         SET_SIZE(ddi_rep_getw)
 252         SET_SIZE(ddi_mem_rep_getw)
 253         SET_SIZE(ddi_mem_rep_get16)
 254 
 255 
 256         ENTRY(ddi_rep_get32)
 257         ALTENTRY(ddi_rep_getl)
 258         ALTENTRY(ddi_mem_rep_getl)
 259         ALTENTRY(ddi_mem_rep_get32)
 260         movq    ACC_REP_GETL(%rdi), %rax
 261         INDIRECT_JMP_REG(rax)
 262         SET_SIZE(ddi_rep_get32)
 263         SET_SIZE(ddi_rep_getl)
 264         SET_SIZE(ddi_mem_rep_getl)
 265         SET_SIZE(ddi_mem_rep_get32)
 266 
 267 
 268         ENTRY(ddi_rep_get64)
 269         ALTENTRY(ddi_rep_getll)
 270         ALTENTRY(ddi_mem_rep_getll)
 271         ALTENTRY(ddi_mem_rep_get64)
 272         movq    ACC_REP_GETLL(%rdi), %rax
 273         INDIRECT_JMP_REG(rax)
 274         SET_SIZE(ddi_rep_get64)
 275         SET_SIZE(ddi_rep_getll)
 276         SET_SIZE(ddi_mem_rep_getll)
 277         SET_SIZE(ddi_mem_rep_get64)
 278 
 279 
 280         ENTRY(ddi_rep_put8)
 281         ALTENTRY(ddi_rep_putb)
 282         ALTENTRY(ddi_mem_rep_putb)
 283         ALTENTRY(ddi_mem_rep_put8)
 284         movq    ACC_REP_PUTB(%rdi), %rax
 285         INDIRECT_JMP_REG(rax)
 286         SET_SIZE(ddi_rep_put8)
 287         SET_SIZE(ddi_rep_putb)
 288         SET_SIZE(ddi_mem_rep_putb)
 289         SET_SIZE(ddi_mem_rep_put8)
 290 
 291 
 292         ENTRY(ddi_rep_put16)
 293         ALTENTRY(ddi_rep_putw)
 294         ALTENTRY(ddi_mem_rep_putw)
 295         ALTENTRY(ddi_mem_rep_put16)
 296         movq    ACC_REP_PUTW(%rdi), %rax
 297         INDIRECT_JMP_REG(rax)
 298         SET_SIZE(ddi_rep_put16)
 299         SET_SIZE(ddi_rep_putw)
 300         SET_SIZE(ddi_mem_rep_putw)
 301         SET_SIZE(ddi_mem_rep_put16)
 302 
 303 
 304         ENTRY(ddi_rep_put32)
 305         ALTENTRY(ddi_rep_putl)
 306         ALTENTRY(ddi_mem_rep_putl)
 307         ALTENTRY(ddi_mem_rep_put32)
 308         movq    ACC_REP_PUTL(%rdi), %rax
 309         INDIRECT_JMP_REG(rax)
 310         SET_SIZE(ddi_rep_put32)
 311         SET_SIZE(ddi_rep_putl)
 312         SET_SIZE(ddi_mem_rep_putl)
 313         SET_SIZE(ddi_mem_rep_put32)
 314 
 315 
 316         ENTRY(ddi_rep_put64)
 317         ALTENTRY(ddi_rep_putll)
 318         ALTENTRY(ddi_mem_rep_putll)
 319         ALTENTRY(ddi_mem_rep_put64)
 320         movq    ACC_REP_PUTLL(%rdi), %rax
 321         INDIRECT_JMP_REG(rax)
 322         SET_SIZE(ddi_rep_put64)
 323         SET_SIZE(ddi_rep_putll)
 324         SET_SIZE(ddi_mem_rep_putll)
 325         SET_SIZE(ddi_mem_rep_put64)
 326 
 327         ENTRY(i_ddi_vaddr_get8)
 328         movzbq  (%rsi), %rax
 329         ret
 330         SET_SIZE(i_ddi_vaddr_get8)
 331 
 332         ENTRY(i_ddi_vaddr_get16)
 333         movzwq  (%rsi), %rax
 334         ret
 335         SET_SIZE(i_ddi_vaddr_get16)
 336 
 337 
 338         ENTRY(i_ddi_vaddr_get32)
 339         movl    (%rsi), %eax
 340         ret
 341         SET_SIZE(i_ddi_vaddr_get32)
 342 
 343 
 344         ENTRY(i_ddi_vaddr_get64)
 345         movq    (%rsi), %rax
 346         ret
 347         SET_SIZE(i_ddi_vaddr_get64)
 348 
 349 
 350         ENTRY(i_ddi_io_get8)
 351         movq    %rsi, %rdx
 352         inb     (%dx)
 353         movzbq  %al, %rax
 354         ret
 355         SET_SIZE(i_ddi_io_get8)
 356 
 357 
 358         ENTRY(i_ddi_io_get16)
 359         movq    %rsi, %rdx
 360         inw     (%dx)
 361         movzwq  %ax, %rax
 362         ret
 363         SET_SIZE(i_ddi_io_get16)
 364 
 365 
 366         ENTRY(i_ddi_io_get32)
 367         movq    %rsi, %rdx
 368         inl     (%dx)
 369         ret
 370         SET_SIZE(i_ddi_io_get32)
 371 
 372         ENTRY(i_ddi_vaddr_put8)
 373         movb    %dl, (%rsi)
 374         ret
 375         SET_SIZE(i_ddi_vaddr_put8)
 376 
 377 
 378         ENTRY(i_ddi_vaddr_put16)
 379         movw    %dx, (%rsi)
 380         ret
 381         SET_SIZE(i_ddi_vaddr_put16)
 382 
 383 
 384         ENTRY(i_ddi_vaddr_put32)
 385         movl    %edx, (%rsi)
 386         ret
 387         SET_SIZE(i_ddi_vaddr_put32)
 388 
 389 
 390         ENTRY(i_ddi_vaddr_put64)
 391         movq    %rdx, (%rsi)
 392         ret
 393         SET_SIZE(i_ddi_vaddr_put64)
 394 
 395         ENTRY(i_ddi_io_put8)
 396         movq    %rdx, %rax
 397         movq    %rsi, %rdx
 398         outb    (%dx)
 399         ret
 400         SET_SIZE(i_ddi_io_put8)
 401 
 402 
 403         ENTRY(i_ddi_io_put16)
 404         movq    %rdx, %rax
 405         movq    %rsi, %rdx
 406         outw    (%dx)
 407         ret
 408         SET_SIZE(i_ddi_io_put16)
 409 
 410 
 411         ENTRY(i_ddi_io_put32)
 412         movq    %rdx, %rax
 413         movq    %rsi, %rdx
 414         outl    (%dx)
 415         ret
 416         SET_SIZE(i_ddi_io_put32)
 417 
 418         /*
 419          * Incoming arguments
 420          *
 421          * %rdi : hdlp
 422          * %rsi : host_addr
 423          * %rdx : dev_addr
 424          * %rcx : repcount
 425          * %r8  : flags
 426          *
 427          * This routine will destroy values in %rdx, %rsi, %rcx.
 428          */
 429         ENTRY(i_ddi_io_rep_get8)
 430 
 431         cmpq    $DDI_DEV_AUTOINCR, %r8
 432         je      gb_ioadv
 433         movq    %rsi, %rdi
 434         rep
 435         insb
 436         ret
 437 
 438 gb_ioadv:
 439         andq    %rcx, %rcx
 440         jz      gb_ioadv_done
 441 gb_ioadv2:
 442         inb     (%dx)
 443         movb    %al, (%rsi)
 444         incq    %rdx
 445         incq    %rsi
 446         decq    %rcx
 447         jg      gb_ioadv2
 448 
 449 gb_ioadv_done:
 450         rep;    ret     /* use 2 byte return instruction when branch target */
 451                         /* AMD Software Optimization Guide - Section 6.2 */
 452 
 453         SET_SIZE(i_ddi_io_rep_get8)
 454 
 455 
 456         ENTRY(i_ddi_io_rep_get16)
 457 
 458         cmpq    $DDI_DEV_AUTOINCR, %r8
 459         je      gw_ioadv
 460 
 461         movq    %rsi, %rdi
 462         rep
 463         insw
 464         ret
 465 
 466 gw_ioadv:
 467         andq    %rcx, %rcx
 468         jz      gw_ioadv_done
 469 gw_ioadv2:
 470         inw     (%dx)
 471         movw    %ax,(%rsi)
 472         addq    $2, %rsi
 473         addq    $2, %rdx
 474         decq    %rcx
 475         jg      gw_ioadv2
 476 
 477 gw_ioadv_done:
 478         rep;    ret     /* use 2 byte return instruction when branch target */
 479                         /* AMD Software Optimization Guide - Section 6.2 */
 480         SET_SIZE(i_ddi_io_rep_get16)
 481 
 482 
 483         ENTRY(i_ddi_io_rep_get32)
 484 
 485         cmpq    $DDI_DEV_AUTOINCR, %r8
 486         je      gl_ioadv
 487 
 488         movq    %rsi, %rdi
 489         rep
 490         insl
 491         ret
 492 
 493 gl_ioadv:
 494         andq    %rcx, %rcx
 495         jz      gl_ioadv_done
 496 gl_ioadv2:
 497         inl     (%dx)
 498         movl    %eax,(%rsi)
 499         addq    $4, %rsi
 500         addq    $4, %rdx
 501         decq    %rcx
 502         jg      gl_ioadv2
 503 
 504 gl_ioadv_done:
 505         rep;    ret     /* use 2 byte return instruction when branch target */
 506                         /* AMD Software Optimization Guide - Section 6.2 */
 507 
 508         SET_SIZE(i_ddi_io_rep_get32)
 509 
 510         /*
 511          * Incoming arguments
 512          *
 513          * %rdi : hdlp
 514          * %rsi : host_addr
 515          * %rdx : dev_addr
 516          * %rcx : repcount
 517          * %r8  : flags
 518          *
 519          * This routine will destroy values in %rdx, %rsi, %rcx.
 520          */
 521         ENTRY(i_ddi_io_rep_put8)
 522 
 523         cmpq    $DDI_DEV_AUTOINCR, %r8
 524         je      pb_ioadv
 525 
 526         movq    %rsi, %rdi
 527         rep
 528         outsb
 529         ret
 530 
 531 pb_ioadv:
 532         andq    %rcx, %rcx
 533         jz      pb_ioadv_done
 534 pb_ioadv2:
 535         movb    (%rsi), %al
 536         outb    (%dx)
 537         incq    %rsi
 538         incq    %rdx
 539         decq    %rcx
 540         jg      pb_ioadv2
 541 
 542 pb_ioadv_done:
 543         rep;    ret     /* use 2 byte return instruction when branch target */
 544                         /* AMD Software Optimization Guide - Section 6.2 */
 545         SET_SIZE(i_ddi_io_rep_put8)
 546 
 547         ENTRY(i_ddi_io_rep_put16)
 548 
 549         cmpq    $DDI_DEV_AUTOINCR, %r8
 550         je      pw_ioadv
 551 
 552         movq    %rsi, %rdi
 553         rep
 554         outsw
 555         ret
 556 
 557 pw_ioadv:
 558         andq    %rcx, %rcx
 559         jz      pw_ioadv_done
 560 pw_ioadv2:
 561         movw    (%rsi), %ax
 562         outw    (%dx)
 563         addq    $2, %rsi
 564         addq    $2, %rdx
 565         decq    %rcx
 566         jg      pw_ioadv2
 567 
 568 pw_ioadv_done:
 569         rep;    ret     /* use 2 byte return instruction when branch target */
 570                         /* AMD Software Optimization Guide - Section 6.2 */
 571         SET_SIZE(i_ddi_io_rep_put16)
 572 
 573 
 574         ENTRY(i_ddi_io_rep_put32)
 575 
 576         cmpq    $DDI_DEV_AUTOINCR, %r8
 577         je      pl_ioadv
 578 
 579         movq    %rsi, %rdi
 580         rep
 581         outsl
 582         ret
 583 
 584 pl_ioadv:
 585         andq    %rcx, %rcx
 586         jz      pl_ioadv_done
 587 pl_ioadv2:
 588         movl    (%rsi), %eax
 589         outl    (%dx)
 590         addq    $4, %rsi
 591         addq    $4, %rdx
 592         decq    %rcx
 593         jg      pl_ioadv2
 594 
 595 pl_ioadv_done:
 596         rep;    ret     /* use 2 byte return instruction when branch target */
 597                         /* AMD Software Optimization Guide - Section 6.2 */
 598         SET_SIZE(i_ddi_io_rep_put32)
 599