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