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