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 <stdint.h>
34
35#if defined(__arm64__)
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
47#if defined(KERNEL)
48
49#if (__SIZEOF_POINTER__ == 8)
50
51#define DTRACE_LABEL(p, n) \
52 ".pushsection __DATA_CONST, __sdt_cstring, cstring_literals\n\t" \
53 "1: .ascii \"" DTRACE_STRINGIFY(p##___) "\\0\"\n\t" \
54 "2: .ascii \"" DTRACE_STRINGIFY(n) "\\0\"\n\t" \
55 ".popsection" "\n\t" \
56 ".pushsection __DATA_CONST, __sdt, regular, live_support\n\t" \
57 ".p2align 3\n\t" \
58 "l3_%=:\n\t" \
59 ".quad 4f""\n\t" \
60 ".quad 1b""\n\t" \
61 ".quad 2b""\n\t" \
62 ".popsection" "\n\t" \
63 "4:"
64
65#else /* Not supported on arm64_32 */
66
67#define DTRACE_LABEL(p, n)
68
69#endif /* __SIZEOF_POINTER__ == 8 */
70
71
72#else /* !KERNEL */
73
74#define DTRACE_LABEL(p, n) \
75 "__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n) ":" "\n\t"
76
77#endif /* !KERNEL */
78
79
80/*
81 * Testing mode that builds function call to the probe site instead of nops.
82 */
83#ifdef DTRACE_CALL_TEST
84
85#define DTRACE_CALL_INSN(p, n) \
86 "bl _dtracetest" DTRACE_STRINGIFY(_##p##_##n) "\n\t"
87
88#define DTRACE_CALL(p, n) \
89 DTRACE_LABEL(p,n) \
90 DTRACE_CALL_INSN(p,n)
91
92#else /* DTRACE_CALL_TEST */
93
94#define DTRACE_NOPS \
95 "nop" "\n\t"
96
97#define DTRACE_CALL(p, n) \
98 DTRACE_LABEL(p,n) \
99 DTRACE_NOPS
100
101#endif /* DTRACE_CALL_TEST */
102
103
104#define DTRACE_PROBE(provider, name) \
105 do { \
106 asm volatile ( \
107 DTRACE_CALL(provider, name) \
108 : \
109 : \
110 : "memory" \
111 ); \
112 } while(0)
113
114#define DTRACE_PROBE1(provider, name, arg0) \
115 do { \
116 register uintptr_t __dtrace_a0 asm("x0") = (uintptr_t) arg0; \
117 asm volatile ( \
118 DTRACE_CALL(provider, name) \
119 : \
120 : "r" (__dtrace_a0) \
121 : "memory" \
122 ); \
123 } while(0)
124
125#define DTRACE_PROBE2(provider, name, arg0, arg1) \
126 do { \
127 register uintptr_t __dtrace_a0 asm("x0") = (uintptr_t) arg0; \
128 register uintptr_t __dtrace_a1 asm("x1") = (uintptr_t) arg1; \
129 asm volatile ( \
130 DTRACE_CALL(provider, name) \
131 : \
132 : "r" (__dtrace_a0), "r" (__dtrace_a1) \
133 : "memory" \
134 ); \
135 } while(0)
136
137#define DTRACE_PROBE3(provider, name, arg0, arg1, arg2) \
138 do { \
139 register uintptr_t __dtrace_a0 asm("x0") = (uintptr_t) arg0; \
140 register uintptr_t __dtrace_a1 asm("x1") = (uintptr_t) arg1; \
141 register uintptr_t __dtrace_a2 asm("x2") = (uintptr_t) arg2; \
142 asm volatile ( \
143 DTRACE_CALL(provider, name) \
144 : \
145 : "r" (__dtrace_a0), "r" (__dtrace_a1), "r" (__dtrace_a2) \
146 : "memory" \
147 ); \
148 } while(0)
149
150#define DTRACE_PROBE4(provider, name, arg0, arg1, arg2, arg3) \
151 do { \
152 register uintptr_t __dtrace_a0 asm("x0") = (uintptr_t) arg0; \
153 register uintptr_t __dtrace_a1 asm("x1") = (uintptr_t) arg1; \
154 register uintptr_t __dtrace_a2 asm("x2") = (uintptr_t) arg2; \
155 register uintptr_t __dtrace_a3 asm("x3") = (uintptr_t) arg3; \
156 asm volatile ( \
157 DTRACE_CALL(provider, name) \
158 : \
159 : "r" (__dtrace_a0), "r" (__dtrace_a1), "r" (__dtrace_a2), \
160 "r" (__dtrace_a3) \
161 : "memory" \
162 ); \
163 } while(0)
164
165#define DTRACE_PROBE5(provider, name, arg0, arg1, arg2, arg3, arg4) \
166 do { \
167 register uintptr_t __dtrace_a0 asm("x0") = (uintptr_t) arg0; \
168 register uintptr_t __dtrace_a1 asm("x1") = (uintptr_t) arg1; \
169 register uintptr_t __dtrace_a2 asm("x2") = (uintptr_t) arg2; \
170 register uintptr_t __dtrace_a3 asm("x3") = (uintptr_t) arg3; \
171 register uintptr_t __dtrace_a4 asm("x4") = (uintptr_t) arg4; \
172 asm volatile ( \
173 DTRACE_CALL(provider, name) \
174 : \
175 : "r" (__dtrace_a0), "r" (__dtrace_a1), "r" (__dtrace_a2), \
176 "r" (__dtrace_a3), "r" (__dtrace_a4) \
177 : "memory" \
178 ); \
179 } while(0)
180
181#define DTRACE_PROBE6(provider, name, arg0, arg1, arg2, arg3, arg4, arg5) \
182 do { \
183 register uintptr_t __dtrace_a0 asm("x0") = (uintptr_t) arg0; \
184 register uintptr_t __dtrace_a1 asm("x1") = (uintptr_t) arg1; \
185 register uintptr_t __dtrace_a2 asm("x2") = (uintptr_t) arg2; \
186 register uintptr_t __dtrace_a3 asm("x3") = (uintptr_t) arg3; \
187 register uintptr_t __dtrace_a4 asm("x4") = (uintptr_t) arg4; \
188 register uintptr_t __dtrace_a5 asm("x5") = (uintptr_t) arg5; \
189 asm volatile ( \
190 DTRACE_CALL(provider, name) \
191 : \
192 : "r" (__dtrace_a0), "r" (__dtrace_a1), "r" (__dtrace_a2), \
193 "r" (__dtrace_a3), "r" (__dtrace_a4), "r" (__dtrace_a5) \
194 : "memory" \
195 ); \
196 } while(0)
197
198#define DTRACE_PROBE7(provider, name, arg0, arg1, arg2, arg3, arg4, arg5, arg6) \
199 do { \
200 register uintptr_t __dtrace_a0 asm("x0") = (uintptr_t) arg0; \
201 register uintptr_t __dtrace_a1 asm("x1") = (uintptr_t) arg1; \
202 register uintptr_t __dtrace_a2 asm("x2") = (uintptr_t) arg2; \
203 register uintptr_t __dtrace_a3 asm("x3") = (uintptr_t) arg3; \
204 register uintptr_t __dtrace_a4 asm("x4") = (uintptr_t) arg4; \
205 register uintptr_t __dtrace_a5 asm("x5") = (uintptr_t) arg5; \
206 register uintptr_t __dtrace_a6 asm("x6") = (uintptr_t) arg6; \
207 asm volatile ( \
208 DTRACE_CALL(provider, name) \
209 : \
210 : "r" (__dtrace_a0), "r" (__dtrace_a1), "r" (__dtrace_a2), \
211 "r" (__dtrace_a3), "r" (__dtrace_a4), "r" (__dtrace_a5), \
212 "r" (__dtrace_a6) \
213 : "memory" \
214 ); \
215 } while(0)
216
217#define DTRACE_PROBE8(provider, name, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7) \
218 do { \
219 register uintptr_t __dtrace_a0 asm("x0") = (uintptr_t) arg0; \
220 register uintptr_t __dtrace_a1 asm("x1") = (uintptr_t) arg1; \
221 register uintptr_t __dtrace_a2 asm("x2") = (uintptr_t) arg2; \
222 register uintptr_t __dtrace_a3 asm("x3") = (uintptr_t) arg3; \
223 register uintptr_t __dtrace_a4 asm("x4") = (uintptr_t) arg4; \
224 register uintptr_t __dtrace_a5 asm("x5") = (uintptr_t) arg5; \
225 register uintptr_t __dtrace_a6 asm("x6") = (uintptr_t) arg6; \
226 register uintptr_t __dtrace_a7 asm("x7") = (uintptr_t) arg7; \
227 asm volatile ( \
228 DTRACE_CALL(provider, name) \
229 : \
230 : "r" (__dtrace_a0), "r" (__dtrace_a1), "r" (__dtrace_a2), \
231 "r" (__dtrace_a3), "r" (__dtrace_a4), "r" (__dtrace_a5), \
232 "r" (__dtrace_a6), "r" (__dtrace_a7) \
233 : "memory" \
234 ); \
235 } while(0)
236
237#endif /* defined (__arm64__) */
238
239#endif /* _MACH_ARM_SDT_ISA_H */
240