Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/cddl/dev/dtrace/i386/dtrace_asm.S
48375 views
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, Version 1.0 only
6
* (the "License"). You may not use this file except in compliance
7
* with the License.
8
*
9
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10
* or http://www.opensolaris.org/os/licensing.
11
* See the License for the specific language governing permissions
12
* and limitations under the License.
13
*
14
* When distributing Covered Code, include this CDDL HEADER in each
15
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16
* If applicable, add the following below this CDDL HEADER, with the
17
* fields enclosed by brackets "[]" replaced with your own identifying
18
* information: Portions Copyright [yyyy] [name of copyright owner]
19
*
20
* CDDL HEADER END
21
*/
22
/*
23
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
24
* Use is subject to license terms.
25
*/
26
27
#define _ASM
28
29
#include <machine/asmacros.h>
30
#include <sys/cpuvar_defs.h>
31
#include <sys/dtrace.h>
32
33
#include "assym.inc"
34
35
ENTRY(dtrace_invop_start)
36
37
pushl %eax /* push %eax -- may be return value */
38
pushl %esp /* push stack pointer */
39
subl $8, (%esp) /* skip first arg and segment regs */
40
pushl 40(%esp) /* push calling EIP */
41
42
/*
43
* Call dtrace_invop to let it check if the exception was
44
* a fbt one. The return value in %eax will tell us what
45
* dtrace_invop wants us to do.
46
*/
47
call dtrace_invop
48
ALTENTRY(dtrace_invop_callsite)
49
addl $12, %esp
50
cmpl $DTRACE_INVOP_PUSHL_EBP, %eax
51
je invop_push
52
cmpl $DTRACE_INVOP_POPL_EBP, %eax
53
je invop_pop
54
cmpl $DTRACE_INVOP_LEAVE, %eax
55
je invop_leave
56
cmpl $DTRACE_INVOP_NOP, %eax
57
je invop_nop
58
59
/* When all else fails handle the trap in the usual way. */
60
jmpl *dtrace_invop_calltrap_addr
61
62
invop_push:
63
/*
64
* We must emulate a "pushl %ebp". To do this, we pull the stack
65
* down 4 bytes, and then store the base pointer.
66
*/
67
popal
68
subl $4, %esp /* make room for %ebp */
69
pushl %eax /* push temp */
70
movl 8(%esp), %eax /* load calling EIP */
71
incl %eax /* increment over LOCK prefix */
72
movl %eax, 4(%esp) /* store calling EIP */
73
movl 12(%esp), %eax /* load calling CS */
74
movl %eax, 8(%esp) /* store calling CS */
75
movl 16(%esp), %eax /* load calling EFLAGS */
76
movl %eax, 12(%esp) /* store calling EFLAGS */
77
movl %ebp, 16(%esp) /* push %ebp */
78
popl %eax /* pop off temp */
79
iret /* Return from interrupt. */
80
invop_pop:
81
/*
82
* We must emulate a "popl %ebp". To do this, we do the opposite of
83
* the above: we remove the %ebp from the stack, and squeeze up the
84
* saved state from the trap.
85
*/
86
popal
87
pushl %eax /* push temp */
88
movl 16(%esp), %ebp /* pop %ebp */
89
movl 12(%esp), %eax /* load calling EFLAGS */
90
movl %eax, 16(%esp) /* store calling EFLAGS */
91
movl 8(%esp), %eax /* load calling CS */
92
movl %eax, 12(%esp) /* store calling CS */
93
movl 4(%esp), %eax /* load calling EIP */
94
incl %eax /* increment over LOCK prefix */
95
movl %eax, 8(%esp) /* store calling EIP */
96
popl %eax /* pop off temp */
97
addl $4, %esp /* adjust stack pointer */
98
iret /* Return from interrupt. */
99
invop_leave:
100
/*
101
* We must emulate a "leave", which is the same as a "movl %ebp, %esp"
102
* followed by a "popl %ebp". This looks similar to the above, but
103
* requires two temporaries: one for the new base pointer, and one
104
* for the staging register.
105
*/
106
popa
107
pushl %eax /* push temp */
108
pushl %ebx /* push temp */
109
movl %ebp, %ebx /* set temp to old %ebp */
110
movl (%ebx), %ebp /* pop %ebp */
111
movl 16(%esp), %eax /* load calling EFLAGS */
112
movl %eax, (%ebx) /* store calling EFLAGS */
113
movl 12(%esp), %eax /* load calling CS */
114
movl %eax, -4(%ebx) /* store calling CS */
115
movl 8(%esp), %eax /* load calling EIP */
116
incl %eax /* increment over LOCK prefix */
117
movl %eax, -8(%ebx) /* store calling EIP */
118
subl $8, %ebx /* adjust for three pushes, one pop */
119
movl %ebx, 8(%esp) /* temporarily store new %esp */
120
popl %ebx /* pop off temp */
121
popl %eax /* pop off temp */
122
movl (%esp), %esp /* set stack pointer */
123
iret /* return from interrupt */
124
invop_nop:
125
/*
126
* We must emulate a "nop". This is obviously not hard: we need only
127
* advance the %eip by one.
128
*/
129
popa
130
incl (%esp)
131
iret /* return from interrupt */
132
133
END(dtrace_invop_start)
134
135
/*
136
greg_t dtrace_getfp(void)
137
*/
138
139
ENTRY(dtrace_getfp)
140
movl %ebp, %eax
141
ret
142
END(dtrace_getfp)
143
144
/*
145
uint32_t dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
146
*/
147
148
ENTRY(dtrace_cas32)
149
ALTENTRY(dtrace_casptr)
150
movl 4(%esp), %edx
151
movl 8(%esp), %eax
152
movl 12(%esp), %ecx
153
lock
154
cmpxchgl %ecx, (%edx)
155
ret
156
END(dtrace_casptr)
157
END(dtrace_cas32)
158
159
/*
160
uintptr_t dtrace_caller(int aframes)
161
*/
162
163
ENTRY(dtrace_caller)
164
movl $-1, %eax
165
ret
166
END(dtrace_caller)
167
168
/*
169
void dtrace_copy(uintptr_t src, uintptr_t dest, size_t size)
170
*/
171
172
ENTRY(dtrace_copy)
173
pushl %ebp
174
movl %esp, %ebp
175
pushl %esi
176
pushl %edi
177
178
movl 8(%ebp), %esi /* Load source address */
179
movl 12(%ebp), %edi /* Load destination address */
180
movl 16(%ebp), %ecx /* Load count */
181
repz /* Repeat for count... */
182
smovb /* move from %ds:si to %es:di */
183
184
popl %edi
185
popl %esi
186
movl %ebp, %esp
187
popl %ebp
188
ret
189
END(dtrace_copy)
190
191
/*
192
void dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size)
193
*/
194
195
ENTRY(dtrace_copystr)
196
197
pushl %ebp /* Setup stack frame */
198
movl %esp, %ebp
199
pushl %ebx /* Save registers */
200
201
movl 8(%ebp), %ebx /* Load source address */
202
movl 12(%ebp), %edx /* Load destination address */
203
movl 16(%ebp), %ecx /* Load count */
204
205
0:
206
movb (%ebx), %al /* Load from source */
207
movb %al, (%edx) /* Store to destination */
208
incl %ebx /* Increment source pointer */
209
incl %edx /* Increment destination pointer */
210
decl %ecx /* Decrement remaining count */
211
cmpb $0, %al
212
je 1f
213
cmpl $0, %ecx
214
jne 0b
215
216
1:
217
popl %ebx
218
movl %ebp, %esp
219
popl %ebp
220
ret
221
222
END(dtrace_copystr)
223
224
/*
225
uintptr_t dtrace_fulword(void *addr)
226
*/
227
228
ENTRY(dtrace_fulword)
229
movl 4(%esp), %ecx
230
xorl %eax, %eax
231
movl (%ecx), %eax
232
ret
233
END(dtrace_fulword)
234
235
/*
236
uint8_t dtrace_fuword8_nocheck(void *addr)
237
*/
238
239
ENTRY(dtrace_fuword8_nocheck)
240
movl 4(%esp), %ecx
241
xorl %eax, %eax
242
movzbl (%ecx), %eax
243
ret
244
END(dtrace_fuword8_nocheck)
245
246
/*
247
uint16_t dtrace_fuword16_nocheck(void *addr)
248
*/
249
250
ENTRY(dtrace_fuword16_nocheck)
251
movl 4(%esp), %ecx
252
xorl %eax, %eax
253
movzwl (%ecx), %eax
254
ret
255
END(dtrace_fuword16_nocheck)
256
257
/*
258
uint32_t dtrace_fuword32_nocheck(void *addr)
259
*/
260
261
ENTRY(dtrace_fuword32_nocheck)
262
movl 4(%esp), %ecx
263
xorl %eax, %eax
264
movl (%ecx), %eax
265
ret
266
END(dtrace_fuword32_nocheck)
267
268
/*
269
uint64_t dtrace_fuword64_nocheck(void *addr)
270
*/
271
272
ENTRY(dtrace_fuword64_nocheck)
273
movl 4(%esp), %ecx
274
xorl %eax, %eax
275
xorl %edx, %edx
276
movl (%ecx), %eax
277
movl 4(%ecx), %edx
278
ret
279
END(dtrace_fuword64_nocheck)
280
281
/*
282
void dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which, int fault, int fltoffs, uintptr_t illval)
283
*/
284
285
ENTRY(dtrace_probe_error)
286
pushl %ebp
287
movl %esp, %ebp
288
pushl 0x1c(%ebp)
289
pushl 0x18(%ebp)
290
pushl 0x14(%ebp)
291
pushl 0x10(%ebp)
292
pushl 0xc(%ebp)
293
pushl 0x8(%ebp)
294
pushl dtrace_probeid_error
295
call dtrace_probe
296
movl %ebp, %esp
297
popl %ebp
298
ret
299
END(dtrace_probe_error)
300
301
/*
302
void dtrace_membar_producer(void)
303
*/
304
305
ENTRY(dtrace_membar_producer)
306
rep; ret /* use 2 byte return instruction when branch target */
307
/* AMD Software Optimization Guide - Section 6.2 */
308
END(dtrace_membar_producer)
309
310
/*
311
void dtrace_membar_consumer(void)
312
*/
313
314
ENTRY(dtrace_membar_consumer)
315
rep; ret /* use 2 byte return instruction when branch target */
316
/* AMD Software Optimization Guide - Section 6.2 */
317
END(dtrace_membar_consumer)
318
319
/*
320
dtrace_icookie_t dtrace_interrupt_disable(void)
321
*/
322
ENTRY(dtrace_interrupt_disable)
323
pushfl
324
popl %eax
325
cli
326
ret
327
END(dtrace_interrupt_disable)
328
329
/*
330
void dtrace_interrupt_enable(dtrace_icookie_t cookie)
331
*/
332
ENTRY(dtrace_interrupt_enable)
333
movl 4(%esp), %eax
334
pushl %eax
335
popfl
336
ret
337
END(dtrace_interrupt_enable)
338
339