xref: /titanic_50/usr/src/uts/intel/dtrace/dtrace_asm.s (revision 5d0e1406420f52cc4d3d0543044034c4894b5865)
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