1/*
2 * Copyright (c) 2007 Apple Inc. All rights reserved.
3 */
4/*
5 * CDDL HEADER START
6 *
7 * The contents of this file are subject to the terms of the
8 * Common Development and Distribution License, Version 1.0 only
9 * (the "License").  You may not use this file except in compliance
10 * with the License.
11 *
12 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
13 * or http://www.opensolaris.org/os/licensing.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 *
17 * When distributing Covered Code, include this CDDL HEADER in each
18 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
19 * If applicable, add the following below this CDDL HEADER, with the
20 * fields enclosed by brackets "[]" replaced with your own identifying
21 * information: Portions Copyright [yyyy] [name of copyright owner]
22 *
23 * CDDL HEADER END
24 */
25/*
26 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
27 * Use is subject to license terms.
28 */
29
30#ifndef _MACH_ARM_SDT_ISA_H
31#define	_MACH_ARM_SDT_ISA_H
32
33#include <arm/arch.h>
34
35/* #pragma ident	"@(#)sdt.h	1.7	05/06/08 SMI" */
36
37/*
38 * Only define when testing.  This makes the calls into actual calls to
39 * test functions.
40 */
41/* #define DTRACE_CALL_TEST */
42
43#define DTRACE_STRINGIFY(s) #s
44#define DTRACE_TOSTRING(s) DTRACE_STRINGIFY(s)
45
46#define DTRACE_LABEL(p, n)									\
47    ".align 4\n" \
48	"__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n) ":"	"\n\t"
49
50#ifdef DTRACE_CALL_TEST
51
52#define DTRACE_CALL(p,n)	\
53	DTRACE_LABEL(p,n)	\
54	DTRACE_CALL_INSN(p,n)
55
56#else	/* !DTRACE_CALL_TEST */
57
58#define DTRACE_CALL(p,n)	\
59	DTRACE_LABEL(p,n)	\
60	DTRACE_NOPS
61
62#endif	/* !DTRACE_CALL_TEST */
63
64#ifdef __arm__
65
66#ifdef _ARM_ARCH_7
67#define DTRACE_NOPS			\
68	"nop"			"\n\t"
69#else
70#define DTRACE_NOPS			\
71	""			"\n\t"
72#endif
73
74#define DTRACE_CALL_INSN(p,n)						\
75	"blx _dtracetest" DTRACE_STRINGIFY(_##p##_##n)	"\n\t"
76
77#ifdef __thumb__
78#define DTRACE_ALLOC_STACK(n)		\
79	"add sp, #-" #n		"\n\t"
80#define DTRACE_DEALLOC_STACK(n)		\
81	"add sp, #" #n		"\n\t"
82#else
83#define DTRACE_ALLOC_STACK(n)		\
84	"sub sp, sp, #" #n	"\n\t"
85#define DTRACE_DEALLOC_STACK(n)		\
86	"add sp, sp, #" #n	"\n\t"
87#endif
88
89#define ARG1_EXTENT	1
90#define ARGS2_EXTENT	2
91#define ARGS3_EXTENT	3
92#define ARGS4_EXTENT	4
93#define ARGS5_EXTENT	5
94#define ARGS6_EXTENT	6
95#define ARGS7_EXTENT	7
96#define ARGS8_EXTENT	8
97#define ARGS9_EXTENT	9
98#define ARGS10_EXTENT	10
99
100#ifndef __LP64__
101
102#define DTRACE_CALL0ARGS(provider, name)			\
103	asm volatile (						\
104		DTRACE_CALL(provider, name)			\
105		"# eat trailing nl+tab from DTRACE_CALL"	\
106		:						\
107		:						\
108	);
109
110#define DTRACE_CALL1ARG(provider, name)				\
111	asm volatile ("ldr r0, [%0]"							"\n\t"	\
112		      DTRACE_CALL(provider, name)						\
113		      :										\
114		      : "l" (__dtrace_args)							\
115		      : "memory", "r0"								\
116	);
117
118#define DTRACE_CALL2ARGS(provider, name)			\
119	asm volatile ("ldr r1, [%0, #4]"						"\n\t"	\
120		      "ldr r0, [%0]"							"\n\t"	\
121		      DTRACE_CALL(provider, name)						\
122		      :										\
123		      : "l" (__dtrace_args)							\
124		      : "memory", "r0", "r1"							\
125	);
126
127#define DTRACE_CALL3ARGS(provider, name)			\
128	asm volatile ("ldr r2, [%0, #8]"						"\n\t"	\
129		      "ldr r1, [%0, #4]"						"\n\t"	\
130		      "ldr r0, [%0]"							"\n\t"	\
131		      DTRACE_CALL(provider, name)						\
132		      :										\
133		      : "l" (__dtrace_args)							\
134		      : "memory", "r0", "r1", "r2"						\
135	);
136
137#define DTRACE_CALL4ARGS(provider, name)			\
138	asm volatile ("ldr r3, [%0, #12]"						"\n\t"	\
139		      "ldr r2, [%0, #8]"						"\n\t"	\
140		      "ldr r1, [%0, #4]"						"\n\t"	\
141		      "ldr r0, [%0]"							"\n\t"	\
142		      DTRACE_CALL(provider, name)						\
143		      :										\
144		      : "l" (__dtrace_args)							\
145		      : "memory", "r0", "r1", "r2", "r3"					\
146	);
147
148#define DTRACE_CALL5ARGS(provider, name)			\
149	asm volatile (										\
150		      DTRACE_ALLOC_STACK(4)							\
151		      "ldr r0, [%0, #16]"						"\n\t"	\
152		      "str r0, [sp]"							"\n\t"	\
153		      "ldr r3, [%0, #12]"						"\n\t"	\
154		      "ldr r2, [%0, #8]"						"\n\t"	\
155		      "ldr r1, [%0, #4]"						"\n\t"	\
156		      "ldr r0, [%0]"							"\n\t"	\
157		      DTRACE_CALL(provider, name)						\
158		      DTRACE_DEALLOC_STACK(4)							\
159		      :										\
160		      : "l" (__dtrace_args)							\
161		      : "memory", "r0", "r1", "r2", "r3"					\
162	);
163
164#define DTRACE_CALL6ARGS(provider, name)			\
165	asm volatile (										\
166		      DTRACE_ALLOC_STACK(8)							\
167		      "ldr r1, [%0, #20]"						"\n\t"	\
168		      "ldr r0, [%0, #16]"						"\n\t"	\
169		      "str r1, [sp, #4]"						"\n\t"	\
170		      "str r0, [sp]"							"\n\t"	\
171		      "ldr r3, [%0, #12]"						"\n\t"	\
172		      "ldr r2, [%0, #8]"						"\n\t"	\
173		      "ldr r1, [%0, #4]"						"\n\t"	\
174		      "ldr r0, [%0]"							"\n\t"	\
175		      DTRACE_CALL(provider, name)						\
176		      DTRACE_DEALLOC_STACK(8)							\
177		      :										\
178		      : "l" (__dtrace_args)							\
179		      : "memory", "r0", "r1", "r2", "r3"					\
180	);
181
182#define DTRACE_CALL7ARGS(provider, name)			\
183	asm volatile (										\
184		      DTRACE_ALLOC_STACK(12)							\
185		      "ldr r2, [%0, #24]"						"\n\t"	\
186		      "ldr r1, [%0, #20]"						"\n\t"	\
187		      "ldr r0, [%0, #16]"						"\n\t"	\
188		      "str r2, [sp, #8]"						"\n\t"	\
189		      "str r1, [sp, #4]"						"\n\t"	\
190		      "str r0, [sp]"							"\n\t"	\
191		      "ldr r3, [%0, #12]"						"\n\t"	\
192		      "ldr r2, [%0, #8]"						"\n\t"	\
193		      "ldr r1, [%0, #4]"						"\n\t"	\
194		      "ldr r0, [%0]"							"\n\t"	\
195		      DTRACE_CALL(provider, name)						\
196		      DTRACE_DEALLOC_STACK(12)							\
197		      :										\
198		      : "l" (__dtrace_args)							\
199		      : "memory", "r0", "r1", "r2", "r3"					\
200	);
201
202#define DTRACE_CALL8ARGS(provider, name)			\
203	asm volatile (										\
204		      DTRACE_ALLOC_STACK(16)							\
205		      "ldr r3, [%0, #28]"						"\n\t"	\
206		      "ldr r2, [%0, #24]"						"\n\t"	\
207		      "ldr r1, [%0, #20]"						"\n\t"	\
208		      "ldr r0, [%0, #16]"						"\n\t"	\
209		      "str r3, [sp, #12]"						"\n\t"	\
210		      "str r2, [sp, #8]"						"\n\t"	\
211		      "str r1, [sp, #4]"						"\n\t"	\
212		      "str r0, [sp]"							"\n\t"	\
213		      "ldr r3, [%0, #12]"						"\n\t"	\
214		      "ldr r2, [%0, #8]"						"\n\t"	\
215		      "ldr r1, [%0, #4]"						"\n\t"	\
216		      "ldr r0, [%0]"							"\n\t"	\
217		      DTRACE_CALL(provider, name)						\
218		      DTRACE_DEALLOC_STACK(16)							\
219		      :										\
220		      : "l" (__dtrace_args)							\
221		      : "memory", "r0", "r1", "r2", "r3"					\
222	);
223
224#define DTRACE_CALL9ARGS(provider, name)			\
225	asm volatile (										\
226		      DTRACE_ALLOC_STACK(20)							\
227		      "ldr r0, [%0, #32]"						"\n\t"	\
228		      "str r0, [sp, #16]"						"\n\t"	\
229		      "ldr r3, [%0, #28]"						"\n\t"	\
230		      "ldr r2, [%0, #24]"						"\n\t"	\
231		      "ldr r1, [%0, #20]"						"\n\t"	\
232		      "ldr r0, [%0, #16]"						"\n\t"	\
233		      "str r3, [sp, #12]"						"\n\t"	\
234		      "str r2, [sp, #8]"						"\n\t"	\
235		      "str r1, [sp, #4]"						"\n\t"	\
236		      "str r0, [sp]"							"\n\t"	\
237		      "ldr r3, [%0, #12]"						"\n\t"	\
238		      "ldr r2, [%0, #8]"						"\n\t"	\
239		      "ldr r1, [%0, #4]"						"\n\t"	\
240		      "ldr r0, [%0]"							"\n\t"	\
241		      DTRACE_CALL(provider, name)						\
242		      DTRACE_DEALLOC_STACK(20)							\
243		      :										\
244		      : "l" (__dtrace_args)							\
245		      : "memory", "r0", "r1", "r2", "r3"					\
246	);
247
248#define DTRACE_CALL10ARGS(provider, name)			\
249	asm volatile (										\
250		      DTRACE_ALLOC_STACK(24)							\
251		      "ldr r1, [%0, #36]"						"\n\t"	\
252		      "ldr r0, [%0, #32]"						"\n\t"	\
253		      "str r1, [sp, #20]"						"\n\t"	\
254		      "str r0, [sp, #16]"						"\n\t"	\
255		      "ldr r3, [%0, #28]"						"\n\t"	\
256		      "ldr r2, [%0, #24]"						"\n\t"	\
257		      "ldr r1, [%0, #20]"						"\n\t"	\
258		      "ldr r0, [%0, #16]"						"\n\t"	\
259		      "str r3, [sp, #12]"						"\n\t"	\
260		      "str r2, [sp, #8]"						"\n\t"	\
261		      "str r1, [sp, #4]"						"\n\t"	\
262		      "str r0, [sp]"							"\n\t"	\
263		      "ldr r3, [%0, #12]"						"\n\t"	\
264		      "ldr r2, [%0, #8]"						"\n\t"	\
265		      "ldr r1, [%0, #4]"						"\n\t"	\
266		      "ldr r0, [%0]"							"\n\t"	\
267		      DTRACE_CALL(provider, name)						\
268		      DTRACE_DEALLOC_STACK(24)							\
269		      :										\
270		      : "l" (__dtrace_args)							\
271		      : "memory", "r0", "r1", "r2", "r3"					\
272	);
273
274#else
275
276/* We have no Dtrace on 64-bit. */
277#define DTRACE_CALL0ARGS(provider, name)
278#define DTRACE_CALL1ARG(provider, name)
279#define DTRACE_CALL2ARGS(provider, name)
280#define DTRACE_CALL3ARGS(provider, name)
281#define DTRACE_CALL4ARGS(provider, name)
282#define DTRACE_CALL5ARGS(provider, name)
283#define DTRACE_CALL6ARGS(provider, name)
284#define DTRACE_CALL7ARGS(provider, name)
285#define DTRACE_CALL8ARGS(provider, name)
286#define DTRACE_CALL9ARGS(provider, name)
287#define DTRACE_CALL10ARGS(provider, name)
288
289
290#endif
291
292#endif /* __arm__ */
293
294#endif	/* _MACH_ARM_SDT_ISA_H */
295
296