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