dtrace_asm.S revision 227430
1179237Sjb/*
2179237Sjb * CDDL HEADER START
3179237Sjb *
4179237Sjb * The contents of this file are subject to the terms of the
5179237Sjb * Common Development and Distribution License, Version 1.0 only
6179237Sjb * (the "License").  You may not use this file except in compliance
7179237Sjb * with the License.
8179237Sjb *
9179237Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10179237Sjb * or http://www.opensolaris.org/os/licensing.
11179237Sjb * See the License for the specific language governing permissions
12179237Sjb * and limitations under the License.
13179237Sjb *
14179237Sjb * When distributing Covered Code, include this CDDL HEADER in each
15179237Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16179237Sjb * If applicable, add the following below this CDDL HEADER, with the
17179237Sjb * fields enclosed by brackets "[]" replaced with your own identifying
18179237Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
19179237Sjb *
20179237Sjb * CDDL HEADER END
21179237Sjb *
22179237Sjb * $FreeBSD: head/sys/cddl/dev/dtrace/i386/dtrace_asm.S 227430 2011-11-10 22:03:35Z rstone $
23179237Sjb */
24179237Sjb/*
25179237Sjb * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
26179237Sjb * Use is subject to license terms.
27179237Sjb */
28179237Sjb
29179237Sjb#define _ASM
30179237Sjb
31179237Sjb#include <machine/asmacros.h>
32179237Sjb#include <sys/cpuvar_defs.h>
33179237Sjb#include <sys/dtrace.h>
34179237Sjb
35179237Sjb#include "assym.s"
36179237Sjb
37179237Sjb	.globl	calltrap
38179237Sjb	.type	calltrap,@function
39179237Sjb	ENTRY(dtrace_invop_start)
40179237Sjb
41179237Sjb	pushl	%eax			/* push %eax -- may be return value */
42179237Sjb	pushl	%esp			/* push stack pointer */
43179237Sjb	addl	$48, (%esp)		/* adjust to incoming args */
44179237Sjb	pushl	40(%esp)		/* push calling EIP */
45179237Sjb
46179237Sjb	/*
47179237Sjb	 * Call dtrace_invop to let it check if the exception was
48179237Sjb	 * a fbt one. The return value in %eax will tell us what
49179237Sjb	 * dtrace_invop wants us to do.
50179237Sjb	 */
51179237Sjb	call	dtrace_invop
52179237Sjb
53179237Sjb	/*
54179237Sjb	 * We pushed 3 times for the arguments to dtrace_invop,
55179237Sjb	 * so we need to increment the stack pointer to get rid of
56179237Sjb	 * those values.
57179237Sjb	 */
58179237Sjb	addl	$12, %esp
59179237Sjb	ALTENTRY(dtrace_invop_callsite)
60179237Sjb	cmpl	$DTRACE_INVOP_PUSHL_EBP, %eax
61179237Sjb	je	invop_push
62179237Sjb	cmpl	$DTRACE_INVOP_POPL_EBP, %eax
63179237Sjb	je	invop_pop
64179237Sjb	cmpl	$DTRACE_INVOP_LEAVE, %eax
65179237Sjb	je	invop_leave
66179237Sjb	cmpl	$DTRACE_INVOP_NOP, %eax
67179237Sjb	je	invop_nop
68179237Sjb
69179237Sjb	/* When all else fails handle the trap in the usual way. */
70179237Sjb	jmpl	*dtrace_invop_calltrap_addr
71179237Sjb
72179237Sjbinvop_push:
73179237Sjb	/*
74179237Sjb	 * We must emulate a "pushl %ebp".  To do this, we pull the stack
75179237Sjb	 * down 4 bytes, and then store the base pointer.
76179237Sjb	 */
77179237Sjb	popal
78179237Sjb	subl	$4, %esp		/* make room for %ebp */
79179237Sjb	pushl	%eax			/* push temp */
80179237Sjb	movl	8(%esp), %eax		/* load calling EIP */
81179237Sjb	incl	%eax			/* increment over LOCK prefix */
82179237Sjb	movl	%eax, 4(%esp)		/* store calling EIP */
83179237Sjb	movl	12(%esp), %eax		/* load calling CS */
84179237Sjb	movl	%eax, 8(%esp)		/* store calling CS */
85179237Sjb	movl	16(%esp), %eax		/* load calling EFLAGS */
86179237Sjb	movl	%eax, 12(%esp)		/* store calling EFLAGS */
87179237Sjb	movl	%ebp, 16(%esp)		/* push %ebp */
88179237Sjb	popl	%eax			/* pop off temp */
89179237Sjb	iret				/* Return from interrupt. */
90179237Sjbinvop_pop:
91179237Sjb	/*
92179237Sjb	 * We must emulate a "popl %ebp".  To do this, we do the opposite of
93179237Sjb	 * the above:  we remove the %ebp from the stack, and squeeze up the
94179237Sjb	 * saved state from the trap.
95179237Sjb	 */
96179237Sjb	popal
97179237Sjb	pushl	%eax			/* push temp */
98179237Sjb	movl	16(%esp), %ebp		/* pop %ebp */
99179237Sjb	movl	12(%esp), %eax		/* load calling EFLAGS */
100179237Sjb	movl	%eax, 16(%esp)		/* store calling EFLAGS */
101179237Sjb	movl	8(%esp), %eax		/* load calling CS */
102179237Sjb	movl	%eax, 12(%esp)		/* store calling CS */
103179237Sjb	movl	4(%esp), %eax		/* load calling EIP */
104179237Sjb	incl	%eax			/* increment over LOCK prefix */
105179237Sjb	movl	%eax, 8(%esp)		/* store calling EIP */
106179237Sjb	popl	%eax			/* pop off temp */
107179237Sjb	addl	$4, %esp		/* adjust stack pointer */
108179237Sjb	iret				/* Return from interrupt. */
109179237Sjbinvop_leave:
110179237Sjb	/*
111179237Sjb	 * We must emulate a "leave", which is the same as a "movl %ebp, %esp"
112179237Sjb	 * followed by a "popl %ebp".  This looks similar to the above, but
113179237Sjb	 * requires two temporaries:  one for the new base pointer, and one
114179237Sjb	 * for the staging register.
115179237Sjb	 */
116179237Sjb	popa
117179237Sjb	pushl	%eax			/* push temp */
118179237Sjb	pushl	%ebx			/* push temp */
119179237Sjb	movl	%ebp, %ebx		/* set temp to old %ebp */
120179237Sjb	movl	(%ebx), %ebp		/* pop %ebp */
121179237Sjb	movl	16(%esp), %eax		/* load calling EFLAGS */
122179237Sjb	movl	%eax, (%ebx)		/* store calling EFLAGS */
123179237Sjb	movl	12(%esp), %eax		/* load calling CS */
124179237Sjb	movl	%eax, -4(%ebx)		/* store calling CS */
125179237Sjb	movl	8(%esp), %eax		/* load calling EIP */
126179237Sjb	incl	%eax			/* increment over LOCK prefix */
127179237Sjb	movl	%eax, -8(%ebx)		/* store calling EIP */
128227430Srstone	subl	$8, %ebx		/* adjust for three pushes, one pop */
129227430Srstone	movl	%ebx, 8(%esp)		/* temporarily store new %esp */
130179237Sjb	popl	%ebx			/* pop off temp */
131179237Sjb	popl	%eax			/* pop off temp */
132227430Srstone	movl	(%esp), %esp		/* set stack pointer */
133179237Sjb	iret				/* return from interrupt */
134179237Sjbinvop_nop:
135179237Sjb	/*
136179237Sjb	 * We must emulate a "nop".  This is obviously not hard:  we need only
137179237Sjb	 * advance the %eip by one.
138179237Sjb	 */
139179237Sjb	popa
140179237Sjb	incl	(%esp)
141179237Sjb	iret				/* return from interrupt */
142179237Sjb
143179237Sjb	END(dtrace_invop_start)
144179237Sjb
145179237Sjb/*
146179237Sjbvoid dtrace_invop_init(void)
147179237Sjb*/
148179237Sjb	ENTRY(dtrace_invop_init)
149179237Sjb	movl	$dtrace_invop_start, dtrace_invop_jump_addr
150179237Sjb	ret
151179237Sjb	END(dtrace_invop_init)
152179237Sjb
153179237Sjb/*
154179237Sjbvoid dtrace_invop_uninit(void)
155179237Sjb*/
156179237Sjb	ENTRY(dtrace_invop_uninit)
157179237Sjb	movl	$0, dtrace_invop_jump_addr
158179237Sjb	ret
159179237Sjb	END(dtrace_invop_uninit)
160179237Sjb
161179237Sjb/*
162179237Sjbgreg_t dtrace_getfp(void)
163179237Sjb*/
164179237Sjb
165179237Sjb	ENTRY(dtrace_getfp)
166179237Sjb	movl	%ebp, %eax
167179237Sjb	ret
168179237Sjb	END(dtrace_getfp)
169179237Sjb
170179237Sjb/*
171179237Sjbuint32_t dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
172179237Sjb*/
173179237Sjb
174179237Sjb	ENTRY(dtrace_cas32)
175179237Sjb	ALTENTRY(dtrace_casptr)
176179237Sjb	movl	4(%esp), %edx
177179237Sjb	movl	8(%esp), %eax
178179237Sjb	movl	12(%esp), %ecx
179179237Sjb	lock
180179237Sjb	cmpxchgl %ecx, (%edx)
181179237Sjb	ret
182179237Sjb	END(dtrace_casptr)
183179237Sjb	END(dtrace_cas32)
184179237Sjb
185179237Sjb/*
186179237Sjbuintptr_t dtrace_caller(int aframes)
187179237Sjb*/
188179237Sjb
189179237Sjb	ENTRY(dtrace_caller)
190179237Sjb	movl	$-1, %eax
191179237Sjb	ret
192179237Sjb	END(dtrace_caller)
193179237Sjb
194179237Sjb/*
195179237Sjbvoid dtrace_copy(uintptr_t src, uintptr_t dest, size_t size)
196179237Sjb*/
197179237Sjb
198179237Sjb	ENTRY(dtrace_copy)
199179237Sjb	pushl	%ebp
200179237Sjb	movl	%esp, %ebp
201179237Sjb	pushl	%esi
202179237Sjb	pushl	%edi
203179237Sjb
204179237Sjb	movl	8(%ebp), %esi		/* Load source address */
205179237Sjb	movl	12(%ebp), %edi		/* Load destination address */
206179237Sjb	movl	16(%ebp), %ecx		/* Load count */
207179237Sjb	repz				/* Repeat for count... */
208179237Sjb	smovb				/*   move from %ds:si to %es:di */
209179237Sjb
210179237Sjb	popl	%edi
211179237Sjb	popl	%esi
212179237Sjb	movl	%ebp, %esp
213179237Sjb	popl	%ebp
214179237Sjb	ret
215179237Sjb	END(dtrace_copy)
216179237Sjb
217179237Sjb/*
218179237Sjbvoid dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size)
219179237Sjb*/
220179237Sjb
221179237Sjb	ENTRY(dtrace_copystr)
222179237Sjb
223179237Sjb	pushl	%ebp			/* Setup stack frame */
224179237Sjb	movl	%esp, %ebp
225179237Sjb	pushl	%ebx			/* Save registers */
226179237Sjb
227179237Sjb	movl	8(%ebp), %ebx		/* Load source address */
228179237Sjb	movl	12(%ebp), %edx		/* Load destination address */
229179237Sjb	movl	16(%ebp), %ecx		/* Load count */
230179237Sjb
231179237Sjb0:
232179237Sjb	movb	(%ebx), %al		/* Load from source */
233179237Sjb	movb	%al, (%edx)		/* Store to destination */
234179237Sjb	incl	%ebx			/* Increment source pointer */
235179237Sjb	incl	%edx			/* Increment destination pointer */
236179237Sjb	decl	%ecx			/* Decrement remaining count */
237179237Sjb	cmpb	$0, %al
238179237Sjb	je	1f
239179237Sjb	cmpl	$0, %ecx
240179237Sjb	jne	0b
241179237Sjb
242179237Sjb1:
243179237Sjb	popl	%ebx
244179237Sjb	movl	%ebp, %esp
245179237Sjb	popl	%ebp
246179237Sjb	ret
247179237Sjb
248179237Sjb	END(dtrace_copystr)
249179237Sjb
250179237Sjb/*
251179237Sjbuintptr_t dtrace_fulword(void *addr)
252179237Sjb*/
253179237Sjb
254179237Sjb	ENTRY(dtrace_fulword)
255179237Sjb	movl	4(%esp), %ecx
256179237Sjb	xorl	%eax, %eax
257179237Sjb	movl	(%ecx), %eax
258179237Sjb	ret
259179237Sjb	END(dtrace_fulword)
260179237Sjb
261179237Sjb/*
262179237Sjbuint8_t dtrace_fuword8_nocheck(void *addr)
263179237Sjb*/
264179237Sjb
265179237Sjb	ENTRY(dtrace_fuword8_nocheck)
266179237Sjb	movl	4(%esp), %ecx
267179237Sjb	xorl	%eax, %eax
268179237Sjb	movzbl	(%ecx), %eax
269179237Sjb	ret
270179237Sjb	END(dtrace_fuword8_nocheck)
271179237Sjb
272179237Sjb/*
273179237Sjbuint16_t dtrace_fuword16_nocheck(void *addr)
274179237Sjb*/
275179237Sjb
276179237Sjb	ENTRY(dtrace_fuword16_nocheck)
277179237Sjb	movl	4(%esp), %ecx
278179237Sjb	xorl	%eax, %eax
279179237Sjb	movzwl	(%ecx), %eax
280179237Sjb	ret
281179237Sjb	END(dtrace_fuword16_nocheck)
282179237Sjb
283179237Sjb/*
284179237Sjbuint32_t dtrace_fuword32_nocheck(void *addr)
285179237Sjb*/
286179237Sjb
287179237Sjb	ENTRY(dtrace_fuword32_nocheck)
288179237Sjb	movl	4(%esp), %ecx
289179237Sjb	xorl	%eax, %eax
290179237Sjb	movl	(%ecx), %eax
291179237Sjb	ret
292179237Sjb	END(dtrace_fuword32_nocheck)
293179237Sjb
294179237Sjb/*
295179237Sjbuint64_t dtrace_fuword64_nocheck(void *addr)
296179237Sjb*/
297179237Sjb
298179237Sjb	ENTRY(dtrace_fuword64_nocheck)
299179237Sjb	movl	4(%esp), %ecx
300179237Sjb	xorl	%eax, %eax
301179237Sjb	xorl	%edx, %edx
302179237Sjb	movl	(%ecx), %eax
303179237Sjb	movl	4(%ecx), %edx
304179237Sjb	ret
305179237Sjb	END(dtrace_fuword64_nocheck)
306179237Sjb
307179237Sjb/*
308179237Sjbvoid dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which, int fault, int fltoffs, uintptr_t illval)
309179237Sjb*/
310179237Sjb
311179237Sjb	ENTRY(dtrace_probe_error)
312179237Sjb	pushl	%ebp
313179237Sjb	movl	%esp, %ebp
314179237Sjb	pushl	0x1c(%ebp)
315179237Sjb	pushl	0x18(%ebp)
316179237Sjb	pushl	0x14(%ebp)
317179237Sjb	pushl	0x10(%ebp)
318179237Sjb	pushl	0xc(%ebp)
319179237Sjb	pushl	0x8(%ebp)
320179237Sjb	pushl	dtrace_probeid_error
321179237Sjb	call	dtrace_probe
322179237Sjb	movl	%ebp, %esp
323179237Sjb	popl	%ebp
324179237Sjb	ret
325179237Sjb	END(dtrace_probe_error)
326179237Sjb
327179237Sjb/*
328179237Sjbvoid dtrace_membar_producer(void)
329179237Sjb*/
330179237Sjb
331179237Sjb	ENTRY(dtrace_membar_producer)
332179237Sjb	rep;	ret	/* use 2 byte return instruction when branch target */
333179237Sjb			/* AMD Software Optimization Guide - Section 6.2 */
334179237Sjb	END(dtrace_membar_producer)
335179237Sjb
336179237Sjb/*
337179237Sjbvoid dtrace_membar_consumer(void)
338179237Sjb*/
339179237Sjb
340179237Sjb	ENTRY(dtrace_membar_consumer)
341179237Sjb	rep;	ret	/* use 2 byte return instruction when branch target */
342179237Sjb			/* AMD Software Optimization Guide - Section 6.2 */
343179237Sjb	END(dtrace_membar_consumer)
344179237Sjb
345179237Sjb/*
346179237Sjbdtrace_icookie_t dtrace_interrupt_disable(void)
347179237Sjb*/
348179237Sjb	ENTRY(dtrace_interrupt_disable)
349179237Sjb	pushfl
350179237Sjb	popl	%eax
351179237Sjb	cli
352179237Sjb	ret
353179237Sjb	END(dtrace_interrupt_disable)
354179237Sjb
355179237Sjb/*
356179237Sjbvoid dtrace_interrupt_enable(dtrace_icookie_t cookie)
357179237Sjb*/
358179237Sjb	ENTRY(dtrace_interrupt_enable)
359179237Sjb	movl	4(%esp), %eax
360179237Sjb	pushl	%eax
361179237Sjb	popfl
362179237Sjb	ret
363179237Sjb	END(dtrace_interrupt_enable)
364179237Sjb
365179237Sjb/*
366179237Sjb * The panic() and cmn_err() functions invoke vpanic() as a common entry point
367179237Sjb * into the panic code implemented in panicsys().  vpanic() is responsible
368179237Sjb * for passing through the format string and arguments, and constructing a
369179237Sjb * regs structure on the stack into which it saves the current register
370179237Sjb * values.  If we are not dying due to a fatal trap, these registers will
371179237Sjb * then be preserved in panicbuf as the current processor state.  Before
372179237Sjb * invoking panicsys(), vpanic() activates the first panic trigger (see
373179237Sjb * common/os/panic.c) and switches to the panic_stack if successful.  Note that
374179237Sjb * DTrace takes a slightly different panic path if it must panic from probe
375179237Sjb * context.  Instead of calling panic, it calls into dtrace_vpanic(), which
376179237Sjb * sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
377179237Sjb * branches back into vpanic().
378179237Sjb */
379179237Sjb/*
380179237Sjbvoid vpanic(const char *format, va_list alist)
381179237Sjb*/
382179237Sjb	ENTRY(vpanic)				/* Initial stack layout: */
383179237Sjb
384179237Sjb	pushl	%ebp				/* | %eip | 20 */
385179237Sjb	movl	%esp, %ebp			/* | %ebp | 16 */
386179237Sjb	pushl	%eax				/* | %eax | 12 */
387179237Sjb	pushl	%ebx				/* | %ebx |  8 */
388179237Sjb	pushl	%ecx				/* | %ecx |  4 */
389179237Sjb	pushl	%edx				/* | %edx |  0 */
390179237Sjb
391179237Sjb	movl	%esp, %ebx			/* %ebx = current stack pointer */
392179237Sjb
393179237Sjb	lea	panic_quiesce, %eax		/* %eax = &panic_quiesce */
394179237Sjb	pushl	%eax				/* push &panic_quiesce */
395179237Sjb	call	panic_trigger			/* %eax = panic_trigger() */
396179237Sjb	addl	$4, %esp			/* reset stack pointer */
397179237Sjb
398179237Sjbvpanic_common:
399179237Sjb	cmpl	$0, %eax			/* if (%eax == 0) */
400179237Sjb	je	0f				/*   goto 0f; */
401179237Sjb
402179237Sjb	/*
403179237Sjb	 * If panic_trigger() was successful, we are the first to initiate a
404179237Sjb	 * panic: we now switch to the reserved panic_stack before continuing.
405179237Sjb	 */
406179237Sjb	lea	panic_stack, %esp		/* %esp  = panic_stack */
407179237Sjb	addl	$PANICSTKSIZE, %esp		/* %esp += PANICSTKSIZE */
408179237Sjb
409179237Sjb0:	subl	$REGSIZE, %esp			/* allocate struct regs */
410179237Sjb
411179237Sjb	/*
412179237Sjb	 * Now that we've got everything set up, store the register values as
413179237Sjb	 * they were when we entered vpanic() to the designated location in
414179237Sjb	 * the regs structure we allocated on the stack.
415179237Sjb	 */
416179237Sjb#ifdef notyet
417179237Sjb	mov	%gs, %edx
418179237Sjb	mov	%edx, REGOFF_GS(%esp)
419179237Sjb	mov	%fs, %edx
420179237Sjb	mov	%edx, REGOFF_FS(%esp)
421179237Sjb	mov	%es, %edx
422179237Sjb	mov	%edx, REGOFF_ES(%esp)
423179237Sjb	mov	%ds, %edx
424179237Sjb	mov	%edx, REGOFF_DS(%esp)
425179237Sjb	movl	%edi, REGOFF_EDI(%esp)
426179237Sjb	movl	%esi, REGOFF_ESI(%esp)
427179237Sjb	movl	16(%ebx), %ecx
428179237Sjb	movl	%ecx, REGOFF_EBP(%esp)
429179237Sjb	movl	%ebx, %ecx
430179237Sjb	addl	$20, %ecx
431179237Sjb	movl	%ecx, REGOFF_ESP(%esp)
432179237Sjb	movl	8(%ebx), %ecx
433179237Sjb	movl	%ecx, REGOFF_EBX(%esp)
434179237Sjb	movl	0(%ebx), %ecx
435179237Sjb	movl	%ecx, REGOFF_EDX(%esp)
436179237Sjb	movl	4(%ebx), %ecx
437179237Sjb	movl	%ecx, REGOFF_ECX(%esp)
438179237Sjb	movl	12(%ebx), %ecx
439179237Sjb	movl	%ecx, REGOFF_EAX(%esp)
440179237Sjb	movl	$0, REGOFF_TRAPNO(%esp)
441179237Sjb	movl	$0, REGOFF_ERR(%esp)
442179237Sjb	lea	vpanic, %ecx
443179237Sjb	movl	%ecx, REGOFF_EIP(%esp)
444179237Sjb	mov	%cs, %edx
445179237Sjb	movl	%edx, REGOFF_CS(%esp)
446179237Sjb	pushfl
447179237Sjb	popl	%ecx
448179237Sjb	movl	%ecx, REGOFF_EFL(%esp)
449179237Sjb	movl	$0, REGOFF_UESP(%esp)
450179237Sjb	mov	%ss, %edx
451179237Sjb	movl	%edx, REGOFF_SS(%esp)
452179237Sjb
453179237Sjb	movl	%esp, %ecx			/* %ecx = &regs */
454179237Sjb	pushl	%eax				/* push on_panic_stack */
455179237Sjb	pushl	%ecx				/* push &regs */
456179237Sjb	movl	12(%ebp), %ecx			/* %ecx = alist */
457179237Sjb	pushl	%ecx				/* push alist */
458179237Sjb	movl	8(%ebp), %ecx			/* %ecx = format */
459179237Sjb	pushl	%ecx				/* push format */
460179237Sjb	call	panicsys			/* panicsys(); */
461179237Sjb	addl	$16, %esp			/* pop arguments */
462179237Sjb
463179237Sjb	addl	$REGSIZE, %esp
464179237Sjb#endif
465179237Sjb	popl	%edx
466179237Sjb	popl	%ecx
467179237Sjb	popl	%ebx
468179237Sjb	popl	%eax
469179237Sjb	leave
470179237Sjb	ret
471179237Sjb	END(vpanic)
472179237Sjb
473179237Sjb/*
474179237Sjbvoid dtrace_vpanic(const char *format, va_list alist)
475179237Sjb*/
476179237Sjb	ENTRY(dtrace_vpanic)			/* Initial stack layout: */
477179237Sjb
478179237Sjb	pushl	%ebp				/* | %eip | 20 */
479179237Sjb	movl	%esp, %ebp			/* | %ebp | 16 */
480179237Sjb	pushl	%eax				/* | %eax | 12 */
481179237Sjb	pushl	%ebx				/* | %ebx |  8 */
482179237Sjb	pushl	%ecx				/* | %ecx |  4 */
483179237Sjb	pushl	%edx				/* | %edx |  0 */
484179237Sjb
485179237Sjb	movl	%esp, %ebx			/* %ebx = current stack pointer */
486179237Sjb
487179237Sjb	lea	panic_quiesce, %eax		/* %eax = &panic_quiesce */
488179237Sjb	pushl	%eax				/* push &panic_quiesce */
489179237Sjb	call	dtrace_panic_trigger		/* %eax = dtrace_panic_trigger() */
490179237Sjb	addl	$4, %esp			/* reset stack pointer */
491179237Sjb	jmp	vpanic_common			/* jump back to common code */
492179237Sjb
493179237Sjb	END(dtrace_vpanic)
494179237Sjb
495179237Sjb/*
496179237Sjbint
497179237Sjbpanic_trigger(int *tp)
498179237Sjb*/
499179237Sjb	ENTRY(panic_trigger)
500179237Sjb	xorl	%eax, %eax
501179237Sjb	movl	$0xdefacedd, %edx
502179237Sjb	lock
503179237Sjb	  xchgl	%edx, (%edi)
504179237Sjb	cmpl	$0, %edx
505179237Sjb	je	0f
506179237Sjb	movl	$0, %eax
507179237Sjb	ret
508179237Sjb0:	movl	$1, %eax
509179237Sjb	ret
510179237Sjb	END(panic_trigger)
511179237Sjb
512179237Sjb/*
513179237Sjbint
514179237Sjbdtrace_panic_trigger(int *tp)
515179237Sjb*/
516179237Sjb	ENTRY(dtrace_panic_trigger)
517179237Sjb	xorl	%eax, %eax
518179237Sjb	movl	$0xdefacedd, %edx
519179237Sjb	lock
520179237Sjb	  xchgl	%edx, (%edi)
521179237Sjb	cmpl	$0, %edx
522179237Sjb	je	0f
523179237Sjb	movl	$0, %eax
524179237Sjb	ret
525179237Sjb0:	movl	$1, %eax
526179237Sjb	ret
527179237Sjb	END(dtrace_panic_trigger)
528