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_mem_get8) 37 ALTENTRY(ddi_io_get8) 38 movl ACC_ATTR(%rdi), %edx 39 cmpl $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %edx 40 jne 1f 41 movq %rsi, %rdx 42 xorq %rax, %rax 43 inb (%dx) 44 ret 451: 46 cmpl $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %edx 47 jne 2f 48 movzbq (%rsi), %rax 49 ret 502: 51 movq ACC_GETB(%rdi), %rax 52 INDIRECT_JMP_REG(rax) 53 SET_SIZE(ddi_get8) 54 SET_SIZE(ddi_mem_get8) 55 SET_SIZE(ddi_io_get8) 56 57 58 ENTRY(ddi_get16) 59 ALTENTRY(ddi_mem_get16) 60 ALTENTRY(ddi_io_get16) 61 movl ACC_ATTR(%rdi), %edx 62 cmpl $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %edx 63 jne 3f 64 movq %rsi, %rdx 65 xorq %rax, %rax 66 inw (%dx) 67 ret 683: 69 cmpl $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %edx 70 jne 4f 71 movzwq (%rsi), %rax 72 ret 734: 74 movq ACC_GETW(%rdi), %rax 75 INDIRECT_JMP_REG(rax) 76 SET_SIZE(ddi_get16) 77 SET_SIZE(ddi_mem_get16) 78 SET_SIZE(ddi_io_get16) 79 80 81 ENTRY(ddi_get32) 82 ALTENTRY(ddi_mem_get32) 83 ALTENTRY(ddi_io_get32) 84 movl ACC_ATTR(%rdi), %edx 85 cmpl $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %edx 86 jne 5f 87 movq %rsi, %rdx 88 inl (%dx) 89 ret 905: 91 cmpl $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %edx 92 jne 6f 93 movl (%rsi), %eax 94 ret 956: 96 movq ACC_GETL(%rdi), %rax 97 INDIRECT_JMP_REG(rax) 98 SET_SIZE(ddi_get32) 99 SET_SIZE(ddi_mem_get32) 100 SET_SIZE(ddi_io_get32) 101 102 103 ENTRY(ddi_get64) 104 ALTENTRY(ddi_mem_get64) 105 movq ACC_GETLL(%rdi), %rax 106 INDIRECT_JMP_REG(rax) 107 SET_SIZE(ddi_get64) 108 SET_SIZE(ddi_mem_get64) 109 110 111 ENTRY(ddi_put8) 112 ALTENTRY(ddi_mem_put8) 113 ALTENTRY(ddi_io_put8) 114 movl ACC_ATTR(%rdi), %ecx 115 cmpl $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %ecx 116 jne 7f 117 movq %rdx, %rax 118 movq %rsi, %rdx 119 outb (%dx) 120 ret 1217: 122 cmpl $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %ecx 123 jne 8f 124 movb %dl, (%rsi) 125 ret 1268: 127 movq ACC_PUTB(%rdi), %rax 128 INDIRECT_JMP_REG(rax) 129 SET_SIZE(ddi_put8) 130 SET_SIZE(ddi_mem_put8) 131 SET_SIZE(ddi_io_put8) 132 133 134 ENTRY(ddi_put16) 135 ALTENTRY(ddi_mem_put16) 136 ALTENTRY(ddi_io_put16) 137 movl ACC_ATTR(%rdi), %ecx 138 cmpl $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %ecx 139 jne 8f 140 movq %rdx, %rax 141 movq %rsi, %rdx 142 outw (%dx) 143 ret 1448: 145 cmpl $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %ecx 146 jne 9f 147 movw %dx, (%rsi) 148 ret 1499: 150 movq ACC_PUTW(%rdi), %rax 151 INDIRECT_JMP_REG(rax) 152 SET_SIZE(ddi_put16) 153 SET_SIZE(ddi_mem_put16) 154 SET_SIZE(ddi_io_put16) 155 156 157 ENTRY(ddi_put32) 158 ALTENTRY(ddi_mem_put32) 159 ALTENTRY(ddi_io_put32) 160 movl ACC_ATTR(%rdi), %ecx 161 cmpl $_CONST(DDI_ACCATTR_IO_SPACE|DDI_ACCATTR_DIRECT), %ecx 162 jne 8f 163 movq %rdx, %rax 164 movq %rsi, %rdx 165 outl (%dx) 166 ret 1678: 168 cmpl $_CONST(DDI_ACCATTR_CPU_VADDR|DDI_ACCATTR_DIRECT), %ecx 169 jne 9f 170 movl %edx, (%rsi) 171 ret 1729: 173 movq ACC_PUTL(%rdi), %rax 174 INDIRECT_JMP_REG(rax) 175 SET_SIZE(ddi_put32) 176 SET_SIZE(ddi_mem_put32) 177 SET_SIZE(ddi_io_put32) 178 179 180 ENTRY(ddi_put64) 181 ALTENTRY(ddi_mem_put64) 182 movq ACC_PUTLL(%rdi), %rax 183 INDIRECT_JMP_REG(rax) 184 SET_SIZE(ddi_put64) 185 SET_SIZE(ddi_mem_put64) 186 187 188 ENTRY(ddi_rep_get8) 189 ALTENTRY(ddi_mem_rep_get8) 190 movq ACC_REP_GETB(%rdi), %rax 191 INDIRECT_JMP_REG(rax) 192 SET_SIZE(ddi_rep_get8) 193 SET_SIZE(ddi_mem_rep_get8) 194 195 196 ENTRY(ddi_rep_get16) 197 ALTENTRY(ddi_mem_rep_get16) 198 movq ACC_REP_GETW(%rdi), %rax 199 INDIRECT_JMP_REG(rax) 200 SET_SIZE(ddi_rep_get16) 201 SET_SIZE(ddi_mem_rep_get16) 202 203 204 ENTRY(ddi_rep_get32) 205 ALTENTRY(ddi_mem_rep_get32) 206 movq ACC_REP_GETL(%rdi), %rax 207 INDIRECT_JMP_REG(rax) 208 SET_SIZE(ddi_rep_get32) 209 SET_SIZE(ddi_mem_rep_get32) 210 211 212 ENTRY(ddi_rep_get64) 213 ALTENTRY(ddi_mem_rep_get64) 214 movq ACC_REP_GETLL(%rdi), %rax 215 INDIRECT_JMP_REG(rax) 216 SET_SIZE(ddi_rep_get64) 217 SET_SIZE(ddi_mem_rep_get64) 218 219 220 ENTRY(ddi_rep_put8) 221 ALTENTRY(ddi_mem_rep_put8) 222 movq ACC_REP_PUTB(%rdi), %rax 223 INDIRECT_JMP_REG(rax) 224 SET_SIZE(ddi_rep_put8) 225 SET_SIZE(ddi_mem_rep_put8) 226 227 228 ENTRY(ddi_rep_put16) 229 ALTENTRY(ddi_mem_rep_put16) 230 movq ACC_REP_PUTW(%rdi), %rax 231 INDIRECT_JMP_REG(rax) 232 SET_SIZE(ddi_rep_put16) 233 SET_SIZE(ddi_mem_rep_put16) 234 235 236 ENTRY(ddi_rep_put32) 237 ALTENTRY(ddi_mem_rep_put32) 238 movq ACC_REP_PUTL(%rdi), %rax 239 INDIRECT_JMP_REG(rax) 240 SET_SIZE(ddi_rep_put32) 241 SET_SIZE(ddi_mem_rep_put32) 242 243 244 ENTRY(ddi_rep_put64) 245 ALTENTRY(ddi_mem_rep_put64) 246 movq ACC_REP_PUTLL(%rdi), %rax 247 INDIRECT_JMP_REG(rax) 248 SET_SIZE(ddi_rep_put64) 249 SET_SIZE(ddi_mem_rep_put64) 250 251 ENTRY(i_ddi_vaddr_get8) 252 movzbq (%rsi), %rax 253 ret 254 SET_SIZE(i_ddi_vaddr_get8) 255 256 ENTRY(i_ddi_vaddr_get16) 257 movzwq (%rsi), %rax 258 ret 259 SET_SIZE(i_ddi_vaddr_get16) 260 261 262 ENTRY(i_ddi_vaddr_get32) 263 movl (%rsi), %eax 264 ret 265 SET_SIZE(i_ddi_vaddr_get32) 266 267 268 ENTRY(i_ddi_vaddr_get64) 269 movq (%rsi), %rax 270 ret 271 SET_SIZE(i_ddi_vaddr_get64) 272 273 274 ENTRY(i_ddi_io_get8) 275 movq %rsi, %rdx 276 inb (%dx) 277 movzbq %al, %rax 278 ret 279 SET_SIZE(i_ddi_io_get8) 280 281 282 ENTRY(i_ddi_io_get16) 283 movq %rsi, %rdx 284 inw (%dx) 285 movzwq %ax, %rax 286 ret 287 SET_SIZE(i_ddi_io_get16) 288 289 290 ENTRY(i_ddi_io_get32) 291 movq %rsi, %rdx 292 inl (%dx) 293 ret 294 SET_SIZE(i_ddi_io_get32) 295 296 ENTRY(i_ddi_vaddr_put8) 297 movb %dl, (%rsi) 298 ret 299 SET_SIZE(i_ddi_vaddr_put8) 300 301 302 ENTRY(i_ddi_vaddr_put16) 303 movw %dx, (%rsi) 304 ret 305 SET_SIZE(i_ddi_vaddr_put16) 306 307 308 ENTRY(i_ddi_vaddr_put32) 309 movl %edx, (%rsi) 310 ret 311 SET_SIZE(i_ddi_vaddr_put32) 312 313 314 ENTRY(i_ddi_vaddr_put64) 315 movq %rdx, (%rsi) 316 ret 317 SET_SIZE(i_ddi_vaddr_put64) 318 319 ENTRY(i_ddi_io_put8) 320 movq %rdx, %rax 321 movq %rsi, %rdx 322 outb (%dx) 323 ret 324 SET_SIZE(i_ddi_io_put8) 325 326 327 ENTRY(i_ddi_io_put16) 328 movq %rdx, %rax 329 movq %rsi, %rdx 330 outw (%dx) 331 ret 332 SET_SIZE(i_ddi_io_put16) 333 334 335 ENTRY(i_ddi_io_put32) 336 movq %rdx, %rax 337 movq %rsi, %rdx 338 outl (%dx) 339 ret 340 SET_SIZE(i_ddi_io_put32) 341 342 /* 343 * Incoming arguments 344 * 345 * %rdi : hdlp 346 * %rsi : host_addr 347 * %rdx : dev_addr 348 * %rcx : repcount 349 * %r8 : flags 350 * 351 * This routine will destroy values in %rdx, %rsi, %rcx. 352 */ 353 ENTRY(i_ddi_io_rep_get8) 354 355 cmpq $DDI_DEV_AUTOINCR, %r8 356 je gb_ioadv 357 movq %rsi, %rdi 358 rep 359 insb 360 ret 361 362gb_ioadv: 363 andq %rcx, %rcx 364 jz gb_ioadv_done 365gb_ioadv2: 366 inb (%dx) 367 movb %al, (%rsi) 368 incq %rdx 369 incq %rsi 370 decq %rcx 371 jg gb_ioadv2 372 373gb_ioadv_done: 374 rep; ret /* use 2 byte return instruction when branch target */ 375 /* AMD Software Optimization Guide - Section 6.2 */ 376 377 SET_SIZE(i_ddi_io_rep_get8) 378 379 380 ENTRY(i_ddi_io_rep_get16) 381 382 cmpq $DDI_DEV_AUTOINCR, %r8 383 je gw_ioadv 384 385 movq %rsi, %rdi 386 rep 387 insw 388 ret 389 390gw_ioadv: 391 andq %rcx, %rcx 392 jz gw_ioadv_done 393gw_ioadv2: 394 inw (%dx) 395 movw %ax,(%rsi) 396 addq $2, %rsi 397 addq $2, %rdx 398 decq %rcx 399 jg gw_ioadv2 400 401gw_ioadv_done: 402 rep; ret /* use 2 byte return instruction when branch target */ 403 /* AMD Software Optimization Guide - Section 6.2 */ 404 SET_SIZE(i_ddi_io_rep_get16) 405 406 407 ENTRY(i_ddi_io_rep_get32) 408 409 cmpq $DDI_DEV_AUTOINCR, %r8 410 je gl_ioadv 411 412 movq %rsi, %rdi 413 rep 414 insl 415 ret 416 417gl_ioadv: 418 andq %rcx, %rcx 419 jz gl_ioadv_done 420gl_ioadv2: 421 inl (%dx) 422 movl %eax,(%rsi) 423 addq $4, %rsi 424 addq $4, %rdx 425 decq %rcx 426 jg gl_ioadv2 427 428gl_ioadv_done: 429 rep; ret /* use 2 byte return instruction when branch target */ 430 /* AMD Software Optimization Guide - Section 6.2 */ 431 432 SET_SIZE(i_ddi_io_rep_get32) 433 434 /* 435 * Incoming arguments 436 * 437 * %rdi : hdlp 438 * %rsi : host_addr 439 * %rdx : dev_addr 440 * %rcx : repcount 441 * %r8 : flags 442 * 443 * This routine will destroy values in %rdx, %rsi, %rcx. 444 */ 445 ENTRY(i_ddi_io_rep_put8) 446 447 cmpq $DDI_DEV_AUTOINCR, %r8 448 je pb_ioadv 449 450 movq %rsi, %rdi 451 rep 452 outsb 453 ret 454 455pb_ioadv: 456 andq %rcx, %rcx 457 jz pb_ioadv_done 458pb_ioadv2: 459 movb (%rsi), %al 460 outb (%dx) 461 incq %rsi 462 incq %rdx 463 decq %rcx 464 jg pb_ioadv2 465 466pb_ioadv_done: 467 rep; ret /* use 2 byte return instruction when branch target */ 468 /* AMD Software Optimization Guide - Section 6.2 */ 469 SET_SIZE(i_ddi_io_rep_put8) 470 471 ENTRY(i_ddi_io_rep_put16) 472 473 cmpq $DDI_DEV_AUTOINCR, %r8 474 je pw_ioadv 475 476 movq %rsi, %rdi 477 rep 478 outsw 479 ret 480 481pw_ioadv: 482 andq %rcx, %rcx 483 jz pw_ioadv_done 484pw_ioadv2: 485 movw (%rsi), %ax 486 outw (%dx) 487 addq $2, %rsi 488 addq $2, %rdx 489 decq %rcx 490 jg pw_ioadv2 491 492pw_ioadv_done: 493 rep; ret /* use 2 byte return instruction when branch target */ 494 /* AMD Software Optimization Guide - Section 6.2 */ 495 SET_SIZE(i_ddi_io_rep_put16) 496 497 498 ENTRY(i_ddi_io_rep_put32) 499 500 cmpq $DDI_DEV_AUTOINCR, %r8 501 je pl_ioadv 502 503 movq %rsi, %rdi 504 rep 505 outsl 506 ret 507 508pl_ioadv: 509 andq %rcx, %rcx 510 jz pl_ioadv_done 511pl_ioadv2: 512 movl (%rsi), %eax 513 outl (%dx) 514 addq $4, %rsi 515 addq $4, %rdx 516 decq %rcx 517 jg pl_ioadv2 518 519pl_ioadv_done: 520 rep; ret /* use 2 byte return instruction when branch target */ 521 /* AMD Software Optimization Guide - Section 6.2 */ 522 SET_SIZE(i_ddi_io_rep_put32) 523