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 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25/* 26 * Copyright 2011 Joyent, Inc. All rights reserved. 27 */ 28 29#include <sys/asm_linkage.h> 30#include <sys/regset.h> 31 32#if defined(lint) 33#include <sys/dtrace_impl.h> 34#else 35#include "assym.h" 36#endif 37 38#if defined(lint) || defined(__lint) 39 40greg_t 41dtrace_getfp(void) 42{ return (0); } 43 44#else /* lint */ 45 46#if defined(__amd64) 47 48 ENTRY_NP(dtrace_getfp) 49 movq %rbp, %rax 50 ret 51 SET_SIZE(dtrace_getfp) 52 53#elif defined(__i386) 54 55 ENTRY_NP(dtrace_getfp) 56 movl %ebp, %eax 57 ret 58 SET_SIZE(dtrace_getfp) 59 60#endif /* __i386 */ 61#endif /* lint */ 62 63 64#if defined(lint) || defined(__lint) 65 66/*ARGSUSED*/ 67uint64_t 68dtrace_getvmreg(uint32_t reg, volatile uint16_t *flags) 69{ return (0); } 70 71#else /* lint */ 72 73#if defined(__amd64) 74 75 ENTRY_NP(dtrace_getvmreg) 76 77 movq %rdi, %rdx 78 vmread %rdx, %rax 79 ret 80 81 SET_SIZE(dtrace_getvmreg) 82 83#elif defined(__i386) 84 85 ENTRY_NP(dtrace_getvmreg) 86 pushl %ebp / Setup stack frame 87 movl %esp, %ebp 88 89 movl 12(%ebp), %eax / Load flag pointer 90 movw (%eax), %cx / Load flags 91 orw $CPU_DTRACE_ILLOP, %cx / Set ILLOP 92 movw %cx, (%eax) / Store flags 93 94 leave 95 ret 96 SET_SIZE(dtrace_getvmreg) 97 98#endif /* __i386 */ 99#endif /* lint */ 100 101 102#if defined(lint) || defined(__lint) 103 104uint32_t 105dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new) 106{ 107 uint32_t old; 108 109 if ((old = *target) == cmp) 110 *target = new; 111 return (old); 112} 113 114void * 115dtrace_casptr(void *target, void *cmp, void *new) 116{ 117 void *old; 118 119 if ((old = *(void **)target) == cmp) 120 *(void **)target = new; 121 return (old); 122} 123 124#else /* lint */ 125 126#if defined(__amd64) 127 128 ENTRY(dtrace_cas32) 129 movl %esi, %eax 130 lock 131 cmpxchgl %edx, (%rdi) 132 ret 133 SET_SIZE(dtrace_cas32) 134 135 ENTRY(dtrace_casptr) 136 movq %rsi, %rax 137 lock 138 cmpxchgq %rdx, (%rdi) 139 ret 140 SET_SIZE(dtrace_casptr) 141 142#elif defined(__i386) 143 144 ENTRY(dtrace_cas32) 145 ALTENTRY(dtrace_casptr) 146 movl 4(%esp), %edx 147 movl 8(%esp), %eax 148 movl 12(%esp), %ecx 149 lock 150 cmpxchgl %ecx, (%edx) 151 ret 152 SET_SIZE(dtrace_casptr) 153 SET_SIZE(dtrace_cas32) 154 155#endif /* __i386 */ 156#endif /* lint */ 157 158#if defined(lint) 159 160/*ARGSUSED*/ 161uintptr_t 162dtrace_caller(int aframes) 163{ 164 return (0); 165} 166 167#else /* lint */ 168 169#if defined(__amd64) 170 ENTRY(dtrace_caller) 171 movq $-1, %rax 172 ret 173 SET_SIZE(dtrace_caller) 174 175#elif defined(__i386) 176 177 ENTRY(dtrace_caller) 178 movl $-1, %eax 179 ret 180 SET_SIZE(dtrace_caller) 181 182#endif /* __i386 */ 183#endif /* lint */ 184 185#if defined(lint) 186 187/*ARGSUSED*/ 188void 189dtrace_copy(uintptr_t src, uintptr_t dest, size_t size) 190{} 191 192#else 193 194#if defined(__amd64) 195 196 ENTRY(dtrace_copy) 197 pushq %rbp 198 movq %rsp, %rbp 199 200 xchgq %rdi, %rsi /* make %rsi source, %rdi dest */ 201 movq %rdx, %rcx /* load count */ 202 repz /* repeat for count ... */ 203 smovb /* move from %ds:rsi to %ed:rdi */ 204 leave 205 ret 206 SET_SIZE(dtrace_copy) 207 208#elif defined(__i386) 209 210 ENTRY(dtrace_copy) 211 pushl %ebp 212 movl %esp, %ebp 213 pushl %esi 214 pushl %edi 215 216 movl 8(%ebp), %esi / Load source address 217 movl 12(%ebp), %edi / Load destination address 218 movl 16(%ebp), %ecx / Load count 219 repz / Repeat for count... 220 smovb / move from %ds:si to %es:di 221 222 popl %edi 223 popl %esi 224 movl %ebp, %esp 225 popl %ebp 226 ret 227 SET_SIZE(dtrace_copy) 228 229#endif /* __i386 */ 230#endif 231 232#if defined(lint) 233 234/*ARGSUSED*/ 235void 236dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size, 237 volatile uint16_t *flags) 238{} 239 240#else 241 242#if defined(__amd64) 243 244 ENTRY(dtrace_copystr) 245 pushq %rbp 246 movq %rsp, %rbp 247 2480: 249 movb (%rdi), %al /* load from source */ 250 movb %al, (%rsi) /* store to destination */ 251 addq $1, %rdi /* increment source pointer */ 252 addq $1, %rsi /* increment destination pointer */ 253 subq $1, %rdx /* decrement remaining count */ 254 cmpb $0, %al 255 je 2f 256 testq $0xfff, %rdx /* test if count is 4k-aligned */ 257 jnz 1f /* if not, continue with copying */ 258 testq $CPU_DTRACE_BADADDR, (%rcx) /* load and test dtrace flags */ 259 jnz 2f 2601: 261 cmpq $0, %rdx 262 jne 0b 2632: 264 leave 265 ret 266 267 SET_SIZE(dtrace_copystr) 268 269#elif defined(__i386) 270 271 ENTRY(dtrace_copystr) 272 273 pushl %ebp / Setup stack frame 274 movl %esp, %ebp 275 pushl %ebx / Save registers 276 277 movl 8(%ebp), %ebx / Load source address 278 movl 12(%ebp), %edx / Load destination address 279 movl 16(%ebp), %ecx / Load count 280 2810: 282 movb (%ebx), %al / Load from source 283 movb %al, (%edx) / Store to destination 284 incl %ebx / Increment source pointer 285 incl %edx / Increment destination pointer 286 decl %ecx / Decrement remaining count 287 cmpb $0, %al 288 je 2f 289 testl $0xfff, %ecx / Check if count is 4k-aligned 290 jnz 1f 291 movl 20(%ebp), %eax / load flags pointer 292 testl $CPU_DTRACE_BADADDR, (%eax) / load and test dtrace flags 293 jnz 2f 2941: 295 cmpl $0, %ecx 296 jne 0b 297 2982: 299 popl %ebx 300 movl %ebp, %esp 301 popl %ebp 302 ret 303 304 SET_SIZE(dtrace_copystr) 305 306#endif /* __i386 */ 307#endif 308 309#if defined(lint) 310 311/*ARGSUSED*/ 312uintptr_t 313dtrace_fulword(void *addr) 314{ return (0); } 315 316#else 317#if defined(__amd64) 318 319 ENTRY(dtrace_fulword) 320 movq (%rdi), %rax 321 ret 322 SET_SIZE(dtrace_fulword) 323 324#elif defined(__i386) 325 326 ENTRY(dtrace_fulword) 327 movl 4(%esp), %ecx 328 xorl %eax, %eax 329 movl (%ecx), %eax 330 ret 331 SET_SIZE(dtrace_fulword) 332 333#endif /* __i386 */ 334#endif 335 336#if defined(lint) 337 338/*ARGSUSED*/ 339uint8_t 340dtrace_fuword8_nocheck(void *addr) 341{ return (0); } 342 343#else 344#if defined(__amd64) 345 346 ENTRY(dtrace_fuword8_nocheck) 347 xorq %rax, %rax 348 movb (%rdi), %al 349 ret 350 SET_SIZE(dtrace_fuword8_nocheck) 351 352#elif defined(__i386) 353 354 ENTRY(dtrace_fuword8_nocheck) 355 movl 4(%esp), %ecx 356 xorl %eax, %eax 357 movzbl (%ecx), %eax 358 ret 359 SET_SIZE(dtrace_fuword8_nocheck) 360 361#endif /* __i386 */ 362#endif 363 364#if defined(lint) 365 366/*ARGSUSED*/ 367uint16_t 368dtrace_fuword16_nocheck(void *addr) 369{ return (0); } 370 371#else 372#if defined(__amd64) 373 374 ENTRY(dtrace_fuword16_nocheck) 375 xorq %rax, %rax 376 movw (%rdi), %ax 377 ret 378 SET_SIZE(dtrace_fuword16_nocheck) 379 380#elif defined(__i386) 381 382 ENTRY(dtrace_fuword16_nocheck) 383 movl 4(%esp), %ecx 384 xorl %eax, %eax 385 movzwl (%ecx), %eax 386 ret 387 SET_SIZE(dtrace_fuword16_nocheck) 388 389#endif /* __i386 */ 390#endif 391 392#if defined(lint) 393 394/*ARGSUSED*/ 395uint32_t 396dtrace_fuword32_nocheck(void *addr) 397{ return (0); } 398 399#else 400#if defined(__amd64) 401 402 ENTRY(dtrace_fuword32_nocheck) 403 xorq %rax, %rax 404 movl (%rdi), %eax 405 ret 406 SET_SIZE(dtrace_fuword32_nocheck) 407 408#elif defined(__i386) 409 410 ENTRY(dtrace_fuword32_nocheck) 411 movl 4(%esp), %ecx 412 xorl %eax, %eax 413 movl (%ecx), %eax 414 ret 415 SET_SIZE(dtrace_fuword32_nocheck) 416 417#endif /* __i386 */ 418#endif 419 420#if defined(lint) 421 422/*ARGSUSED*/ 423uint64_t 424dtrace_fuword64_nocheck(void *addr) 425{ return (0); } 426 427#else 428#if defined(__amd64) 429 430 ENTRY(dtrace_fuword64_nocheck) 431 movq (%rdi), %rax 432 ret 433 SET_SIZE(dtrace_fuword64_nocheck) 434 435#elif defined(__i386) 436 437 ENTRY(dtrace_fuword64_nocheck) 438 movl 4(%esp), %ecx 439 xorl %eax, %eax 440 xorl %edx, %edx 441 movl (%ecx), %eax 442 movl 4(%ecx), %edx 443 ret 444 SET_SIZE(dtrace_fuword64_nocheck) 445 446#endif /* __i386 */ 447#endif 448 449#if defined(lint) || defined(__lint) 450 451/*ARGSUSED*/ 452void 453dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which, 454 int fault, int fltoffs, uintptr_t illval) 455{} 456 457#else /* lint */ 458#if defined(__amd64) 459 460 ENTRY(dtrace_probe_error) 461 pushq %rbp 462 movq %rsp, %rbp 463 subq $0x8, %rsp 464 movq %r9, (%rsp) 465 movq %r8, %r9 466 movq %rcx, %r8 467 movq %rdx, %rcx 468 movq %rsi, %rdx 469 movq %rdi, %rsi 470 movl dtrace_probeid_error(%rip), %edi 471 call dtrace_probe 472 addq $0x8, %rsp 473 leave 474 ret 475 SET_SIZE(dtrace_probe_error) 476 477#elif defined(__i386) 478 479 ENTRY(dtrace_probe_error) 480 pushl %ebp 481 movl %esp, %ebp 482 pushl 0x1c(%ebp) 483 pushl 0x18(%ebp) 484 pushl 0x14(%ebp) 485 pushl 0x10(%ebp) 486 pushl 0xc(%ebp) 487 pushl 0x8(%ebp) 488 pushl dtrace_probeid_error 489 call dtrace_probe 490 movl %ebp, %esp 491 popl %ebp 492 ret 493 SET_SIZE(dtrace_probe_error) 494 495#endif /* __i386 */ 496#endif 497