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/* #pragma ident "@(#)sdt.h 1.7 05/06/08 SMI" */
34
35/*
36 * Only define when testing. This makes the calls into actual calls to
37 * test functions.
38 */
39/* #define DTRACE_CALL_TEST */
40
41#define DTRACE_STRINGIFY(s) #s
42#define DTRACE_TOSTRING(s) DTRACE_STRINGIFY(s)
43
44#if defined(KERNEL)
45/*
46 * For the kernel, set an explicit global label so the symbol can be located
47 */
48#ifdef __arm__
49#define DTRACE_LAB(p, n) \
50 "__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n)
51
52#define DTRACE_LABEL(p, n) \
53 ".pushsection __DATA, __data\n\t" \
54 ".p2align 2\n\t" \
55 ".globl " DTRACE_LAB(p, n) "\n\t" \
56 DTRACE_LAB(p, n) ":" ".long 1f""\n\t" \
57 ".popsection" "\n\t" \
58 "1:"
59#else /* __arm64__ */
60#define DTRACE_LAB(p, n) \
61 "__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n)
62
63#define DTRACE_LABEL(p, n) \
64 ".pushsection __DATA, __data\n\t" \
65 ".p2align 3\n\t" \
66 ".globl " DTRACE_LAB(p, n) "\n\t" \
67 DTRACE_LAB(p, n) ":" ".quad 1f""\n\t" \
68 ".popsection" "\n\t" \
69 "1:"
70#endif
71#else /* !KERNEL */
72#define DTRACE_LABEL(p, n) \
73 "__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n) ":" "\n\t"
74#endif /* !KERNEL */
75
76#ifdef DTRACE_CALL_TEST
77
78#define DTRACE_CALL(p,n) \
79 DTRACE_LABEL(p,n) \
80 DTRACE_CALL_INSN(p,n)
81
82#else /* !DTRACE_CALL_TEST */
83
84#define DTRACE_CALL(p,n) \
85 DTRACE_LABEL(p,n) \
86 DTRACE_NOPS
87
88#endif /* !DTRACE_CALL_TEST */
89
90#if defined(__arm__)
91
92#define DTRACE_NOPS \
93 "nop" "\n\t"
94
95#define DTRACE_CALL_INSN(p,n) \
96 "blx _dtracetest" DTRACE_STRINGIFY(_##p##_##n) "\n\t"
97
98#ifdef __thumb__
99#define DTRACE_ALLOC_STACK(n) \
100 "sub sp, #" #n "\n\t"
101#define DTRACE_DEALLOC_STACK(n) \
102 "add sp, #" #n "\n\t"
103#else
104#define DTRACE_ALLOC_STACK(n) \
105 "sub sp, sp, #" #n "\n\t"
106#define DTRACE_DEALLOC_STACK(n) \
107 "add sp, sp, #" #n "\n\t"
108#endif
109
110#define ARG1_EXTENT 1
111#define ARGS2_EXTENT 2
112#define ARGS3_EXTENT 3
113#define ARGS4_EXTENT 4
114#define ARGS5_EXTENT 5
115#define ARGS6_EXTENT 6
116#define ARGS7_EXTENT 7
117#define ARGS8_EXTENT 8
118#define ARGS9_EXTENT 9
119#define ARGS10_EXTENT 10
120
121#define DTRACE_CALL0ARGS(provider, name) \
122 asm volatile ( \
123 DTRACE_CALL(provider, name) \
124 "# eat trailing nl+tab from DTRACE_CALL" \
125 : \
126 : \
127 );
128
129#define DTRACE_CALL1ARG(provider, name) \
130 asm volatile ("ldr r0, [%0]" "\n\t" \
131 DTRACE_CALL(provider, name) \
132 : \
133 : "l" (__dtrace_args) \
134 : "memory", "r0" \
135 );
136
137#define DTRACE_CALL2ARGS(provider, name) \
138 asm volatile ("ldr r1, [%0, #4]" "\n\t" \
139 "ldr r0, [%0]" "\n\t" \
140 DTRACE_CALL(provider, name) \
141 : \
142 : "l" (__dtrace_args) \
143 : "memory", "r0", "r1" \
144 );
145
146#define DTRACE_CALL3ARGS(provider, name) \
147 asm volatile ("ldr r2, [%0, #8]" "\n\t" \
148 "ldr r1, [%0, #4]" "\n\t" \
149 "ldr r0, [%0]" "\n\t" \
150 DTRACE_CALL(provider, name) \
151 : \
152 : "l" (__dtrace_args) \
153 : "memory", "r0", "r1", "r2" \
154 );
155
156#define DTRACE_CALL4ARGS(provider, name) \
157 asm volatile ("ldr r3, [%0, #12]" "\n\t" \
158 "ldr r2, [%0, #8]" "\n\t" \
159 "ldr r1, [%0, #4]" "\n\t" \
160 "ldr r0, [%0]" "\n\t" \
161 DTRACE_CALL(provider, name) \
162 : \
163 : "l" (__dtrace_args) \
164 : "memory", "r0", "r1", "r2", "r3" \
165 );
166
167/*
168 * One of our ARM32 ABIs (armv7k) mandates that the stack be aligned to 16 bytes.
169 * We currently apply this constraint to all ARM32 DTRACE_CALL macros; hence the
170 * macros below will overallocate for some ABIs.
171 */
172#define DTRACE_CALL5ARGS(provider, name) \
173 asm volatile ( \
174 DTRACE_ALLOC_STACK(16) \
175 "ldr r0, [%0, #16]" "\n\t" \
176 "str r0, [sp]" "\n\t" \
177 "ldr r3, [%0, #12]" "\n\t" \
178 "ldr r2, [%0, #8]" "\n\t" \
179 "ldr r1, [%0, #4]" "\n\t" \
180 "ldr r0, [%0]" "\n\t" \
181 DTRACE_CALL(provider, name) \
182 DTRACE_DEALLOC_STACK(16) \
183 : \
184 : "l" (__dtrace_args) \
185 : "memory", "r0", "r1", "r2", "r3" \
186 );
187
188#define DTRACE_CALL6ARGS(provider, name) \
189 asm volatile ( \
190 DTRACE_ALLOC_STACK(16) \
191 "ldr r1, [%0, #20]" "\n\t" \
192 "ldr r0, [%0, #16]" "\n\t" \
193 "str r1, [sp, #4]" "\n\t" \
194 "str r0, [sp]" "\n\t" \
195 "ldr r3, [%0, #12]" "\n\t" \
196 "ldr r2, [%0, #8]" "\n\t" \
197 "ldr r1, [%0, #4]" "\n\t" \
198 "ldr r0, [%0]" "\n\t" \
199 DTRACE_CALL(provider, name) \
200 DTRACE_DEALLOC_STACK(16) \
201 : \
202 : "l" (__dtrace_args) \
203 : "memory", "r0", "r1", "r2", "r3" \
204 );
205
206#define DTRACE_CALL7ARGS(provider, name) \
207 asm volatile ( \
208 DTRACE_ALLOC_STACK(16) \
209 "ldr r2, [%0, #24]" "\n\t" \
210 "ldr r1, [%0, #20]" "\n\t" \
211 "ldr r0, [%0, #16]" "\n\t" \
212 "str r2, [sp, #8]" "\n\t" \
213 "str r1, [sp, #4]" "\n\t" \
214 "str r0, [sp]" "\n\t" \
215 "ldr r3, [%0, #12]" "\n\t" \
216 "ldr r2, [%0, #8]" "\n\t" \
217 "ldr r1, [%0, #4]" "\n\t" \
218 "ldr r0, [%0]" "\n\t" \
219 DTRACE_CALL(provider, name) \
220 DTRACE_DEALLOC_STACK(16) \
221 : \
222 : "l" (__dtrace_args) \
223 : "memory", "r0", "r1", "r2", "r3" \
224 );
225
226#define DTRACE_CALL8ARGS(provider, name) \
227 asm volatile ( \
228 DTRACE_ALLOC_STACK(16) \
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(16) \
243 : \
244 : "l" (__dtrace_args) \
245 : "memory", "r0", "r1", "r2", "r3" \
246 );
247
248#define DTRACE_CALL9ARGS(provider, name) \
249 asm volatile ( \
250 DTRACE_ALLOC_STACK(32) \
251 "ldr r0, [%0, #32]" "\n\t" \
252 "str r0, [sp, #16]" "\n\t" \
253 "ldr r3, [%0, #28]" "\n\t" \
254 "ldr r2, [%0, #24]" "\n\t" \
255 "ldr r1, [%0, #20]" "\n\t" \
256 "ldr r0, [%0, #16]" "\n\t" \
257 "str r3, [sp, #12]" "\n\t" \
258 "str r2, [sp, #8]" "\n\t" \
259 "str r1, [sp, #4]" "\n\t" \
260 "str r0, [sp]" "\n\t" \
261 "ldr r3, [%0, #12]" "\n\t" \
262 "ldr r2, [%0, #8]" "\n\t" \
263 "ldr r1, [%0, #4]" "\n\t" \
264 "ldr r0, [%0]" "\n\t" \
265 DTRACE_CALL(provider, name) \
266 DTRACE_DEALLOC_STACK(32) \
267 : \
268 : "l" (__dtrace_args) \
269 : "memory", "r0", "r1", "r2", "r3" \
270 );
271
272#define DTRACE_CALL10ARGS(provider, name) \
273 asm volatile ( \
274 DTRACE_ALLOC_STACK(32) \
275 "ldr r1, [%0, #36]" "\n\t" \
276 "ldr r0, [%0, #32]" "\n\t" \
277 "str r1, [sp, #20]" "\n\t" \
278 "str r0, [sp, #16]" "\n\t" \
279 "ldr r3, [%0, #28]" "\n\t" \
280 "ldr r2, [%0, #24]" "\n\t" \
281 "ldr r1, [%0, #20]" "\n\t" \
282 "ldr r0, [%0, #16]" "\n\t" \
283 "str r3, [sp, #12]" "\n\t" \
284 "str r2, [sp, #8]" "\n\t" \
285 "str r1, [sp, #4]" "\n\t" \
286 "str r0, [sp]" "\n\t" \
287 "ldr r3, [%0, #12]" "\n\t" \
288 "ldr r2, [%0, #8]" "\n\t" \
289 "ldr r1, [%0, #4]" "\n\t" \
290 "ldr r0, [%0]" "\n\t" \
291 DTRACE_CALL(provider, name) \
292 DTRACE_DEALLOC_STACK(32) \
293 : \
294 : "l" (__dtrace_args) \
295 : "memory", "r0", "r1", "r2", "r3" \
296 );
297
298#elif defined(__arm64__)
299
300#define DTRACE_NOPS \
301 "nop" "\n\t"
302
303
304#define DTRACE_CALL_INSN(p,n) \
305 "bl _dtracetest" DTRACE_STRINGIFY(_##p##_##n) "\n\t"
306
307#define DTRACE_ALLOC_STACK(n) \
308 "sub sp, sp, #" #n "\n\t"
309#define DTRACE_DEALLOC_STACK(n) \
310 "add sp, sp, #" #n "\n\t"
311
312#define ARG1_EXTENT 1
313#define ARGS2_EXTENT 2
314#define ARGS3_EXTENT 3
315#define ARGS4_EXTENT 4
316#define ARGS5_EXTENT 5
317#define ARGS6_EXTENT 6
318#define ARGS7_EXTENT 7
319#define ARGS8_EXTENT 8
320#define ARGS9_EXTENT 9
321#define ARGS10_EXTENT 10
322
323#define DTRACE_CALL0ARGS(provider, name) \
324 asm volatile ( \
325 DTRACE_CALL(provider, name) \
326 "# eat trailing nl+tab from DTRACE_CALL" \
327 : \
328 : \
329 );
330
331#define DTRACE_CALL1ARG(provider, name) \
332 asm volatile ("ldr x0, [%0]" "\n\t" \
333 DTRACE_CALL(provider, name) \
334 : \
335 : "r" (__dtrace_args) \
336 : "memory", "x0" \
337 );
338
339#define DTRACE_CALL2ARGS(provider, name) \
340 asm volatile ("ldp x0, x1, [%0]" "\n\t" \
341 DTRACE_CALL(provider, name) \
342 : \
343 : "r" (__dtrace_args) \
344 : "memory", "x0", "x1" \
345 );
346
347#define DTRACE_CALL3ARGS(provider, name) \
348 asm volatile ("ldr x2, [%0, #16]" "\n\t" \
349 "ldp x0, x1, [%0]" "\n\t" \
350 DTRACE_CALL(provider, name) \
351 : \
352 : "r" (__dtrace_args) \
353 : "memory", "x0", "x1", "x2" \
354 );
355
356#define DTRACE_CALL4ARGS(provider, name) \
357 asm volatile ("ldp x2, x3, [%0, #16]" "\n\t" \
358 "ldp x0, x1, [%0]" "\n\t" \
359 DTRACE_CALL(provider, name) \
360 : \
361 : "r" (__dtrace_args) \
362 : "memory", "x0", "x1", "x2", "x3" \
363 );
364
365#define DTRACE_CALL5ARGS(provider, name) \
366 asm volatile ("ldr x4, [%0, #32]" "\n\t" \
367 "ldp x2, x3, [%0, #16]" "\n\t" \
368 "ldp x0, x1, [%0]" "\n\t" \
369 DTRACE_CALL(provider, name) \
370 : \
371 : "r" (__dtrace_args) \
372 : "memory", "x0", "x1", "x2", "x3", "x4" \
373 );
374
375#define DTRACE_CALL6ARGS(provider, name) \
376 asm volatile ("ldp x4, x5, [%0, #32]" "\n\t" \
377 "ldp x2, x3, [%0, #16]" "\n\t" \
378 "ldp x0, x1, [%0]" "\n\t" \
379 DTRACE_CALL(provider, name) \
380 : \
381 : "r" (__dtrace_args) \
382 : "memory", "x0", "x1", "x2", "x3", "x4", "x5" \
383 );
384
385#define DTRACE_CALL7ARGS(provider, name) \
386 asm volatile ("ldr x6, [%0, #48]" "\n\t" \
387 "ldp x4, x5, [%0, #32]" "\n\t" \
388 "ldp x2, x3, [%0, #16]" "\n\t" \
389 "ldp x0, x1, [%0]" "\n\t" \
390 DTRACE_CALL(provider, name) \
391 : \
392 : "r" (__dtrace_args) \
393 : "memory", "x0", "x1", "x2", "x3", "x4", "x5", "x6" \
394 );
395
396#define DTRACE_CALL8ARGS(provider, name) \
397 asm volatile ("ldp x6, x7, [%0, #48]" "\n\t" \
398 "ldp x4, x5, [%0, #32]" "\n\t" \
399 "ldp x2, x3, [%0, #16]" "\n\t" \
400 "ldp x0, x1, [%0]" "\n\t" \
401 DTRACE_CALL(provider, name) \
402 : \
403 : "r" (__dtrace_args) \
404 : "memory", "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7" \
405 );
406
407/* Keep stack 16 byte aligned per ABI requirements */
408#define DTRACE_CALL9ARGS(provider, name) \
409 asm volatile ( \
410 DTRACE_ALLOC_STACK(16) \
411 "ldr x0, [%0, #64]" "\n\t" \
412 "str x0, [sp]" "\n\t" \
413 "ldp x6, x7, [%0, #48]" "\n\t" \
414 "ldp x4, x5, [%0, #32]" "\n\t" \
415 "ldp x2, x3, [%0, #16]" "\n\t" \
416 "ldp x0, x1, [%0]" "\n\t" \
417 DTRACE_CALL(provider, name) \
418 DTRACE_DEALLOC_STACK(16) \
419 : \
420 : "r" (__dtrace_args) \
421 : "memory", "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7" \
422 );
423
424#define DTRACE_CALL10ARGS(provider, name) \
425 asm volatile ( \
426 DTRACE_ALLOC_STACK(16) \
427 "ldp x0, x1, [%0, #64]" "\n\t" \
428 "stp x0, x1, [sp]" "\n\t" \
429 "ldp x6, x7, [%0, #48]" "\n\t" \
430 "ldp x4, x5, [%0, #32]" "\n\t" \
431 "ldp x2, x3, [%0, #16]" "\n\t" \
432 "ldp x0, x1, [%0]" "\n\t" \
433 DTRACE_CALL(provider, name) \
434 DTRACE_DEALLOC_STACK(16) \
435 : \
436 : "r" (__dtrace_args) \
437 : "memory", "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7" \
438 );
439
440#endif /* __arm__ */
441
442#endif /* _MACH_ARM_SDT_ISA_H */
443