xref: /freebsd/sys/cddl/dev/dtrace/i386/dtrace_asm.S (revision 91eaf3e1831d805c9cffd85818a70213d9007e07)
191eaf3e1SJohn Birrell/*
291eaf3e1SJohn Birrell * CDDL HEADER START
391eaf3e1SJohn Birrell *
491eaf3e1SJohn Birrell * The contents of this file are subject to the terms of the
591eaf3e1SJohn Birrell * Common Development and Distribution License, Version 1.0 only
691eaf3e1SJohn Birrell * (the "License").  You may not use this file except in compliance
791eaf3e1SJohn Birrell * with the License.
891eaf3e1SJohn Birrell *
991eaf3e1SJohn Birrell * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1091eaf3e1SJohn Birrell * or http://www.opensolaris.org/os/licensing.
1191eaf3e1SJohn Birrell * See the License for the specific language governing permissions
1291eaf3e1SJohn Birrell * and limitations under the License.
1391eaf3e1SJohn Birrell *
1491eaf3e1SJohn Birrell * When distributing Covered Code, include this CDDL HEADER in each
1591eaf3e1SJohn Birrell * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1691eaf3e1SJohn Birrell * If applicable, add the following below this CDDL HEADER, with the
1791eaf3e1SJohn Birrell * fields enclosed by brackets "[]" replaced with your own identifying
1891eaf3e1SJohn Birrell * information: Portions Copyright [yyyy] [name of copyright owner]
1991eaf3e1SJohn Birrell *
2091eaf3e1SJohn Birrell * CDDL HEADER END
2191eaf3e1SJohn Birrell *
2291eaf3e1SJohn Birrell * $FreeBSD$
2391eaf3e1SJohn Birrell */
2491eaf3e1SJohn Birrell/*
2591eaf3e1SJohn Birrell * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
2691eaf3e1SJohn Birrell * Use is subject to license terms.
2791eaf3e1SJohn Birrell */
2891eaf3e1SJohn Birrell
2991eaf3e1SJohn Birrell#define _ASM
3091eaf3e1SJohn Birrell
3191eaf3e1SJohn Birrell#include <machine/asmacros.h>
3291eaf3e1SJohn Birrell#include <sys/cpuvar_defs.h>
3391eaf3e1SJohn Birrell#include <sys/dtrace.h>
3491eaf3e1SJohn Birrell
3591eaf3e1SJohn Birrell#include "assym.s"
3691eaf3e1SJohn Birrell
3791eaf3e1SJohn Birrell	.globl	calltrap
3891eaf3e1SJohn Birrell	.type	calltrap,@function
3991eaf3e1SJohn Birrell	ENTRY(dtrace_invop_start)
4091eaf3e1SJohn Birrell
4191eaf3e1SJohn Birrell	pushl	%eax			/* push %eax -- may be return value */
4291eaf3e1SJohn Birrell	pushl	%esp			/* push stack pointer */
4391eaf3e1SJohn Birrell	addl	$48, (%esp)		/* adjust to incoming args */
4491eaf3e1SJohn Birrell	pushl	40(%esp)		/* push calling EIP */
4591eaf3e1SJohn Birrell
4691eaf3e1SJohn Birrell	/*
4791eaf3e1SJohn Birrell	 * Call dtrace_invop to let it check if the exception was
4891eaf3e1SJohn Birrell	 * a fbt one. The return value in %eax will tell us what
4991eaf3e1SJohn Birrell	 * dtrace_invop wants us to do.
5091eaf3e1SJohn Birrell	 */
5191eaf3e1SJohn Birrell	call	dtrace_invop
5291eaf3e1SJohn Birrell
5391eaf3e1SJohn Birrell	/*
5491eaf3e1SJohn Birrell	 * We pushed 3 times for the arguments to dtrace_invop,
5591eaf3e1SJohn Birrell	 * so we need to increment the stack pointer to get rid of
5691eaf3e1SJohn Birrell	 * those values.
5791eaf3e1SJohn Birrell	 */
5891eaf3e1SJohn Birrell	addl	$12, %esp
5991eaf3e1SJohn Birrell	ALTENTRY(dtrace_invop_callsite)
6091eaf3e1SJohn Birrell	cmpl	$DTRACE_INVOP_PUSHL_EBP, %eax
6191eaf3e1SJohn Birrell	je	invop_push
6291eaf3e1SJohn Birrell	cmpl	$DTRACE_INVOP_POPL_EBP, %eax
6391eaf3e1SJohn Birrell	je	invop_pop
6491eaf3e1SJohn Birrell	cmpl	$DTRACE_INVOP_LEAVE, %eax
6591eaf3e1SJohn Birrell	je	invop_leave
6691eaf3e1SJohn Birrell	cmpl	$DTRACE_INVOP_NOP, %eax
6791eaf3e1SJohn Birrell	je	invop_nop
6891eaf3e1SJohn Birrell
6991eaf3e1SJohn Birrell	/* When all else fails handle the trap in the usual way. */
7091eaf3e1SJohn Birrell	jmpl	*dtrace_invop_calltrap_addr
7191eaf3e1SJohn Birrell
7291eaf3e1SJohn Birrellinvop_push:
7391eaf3e1SJohn Birrell	/*
7491eaf3e1SJohn Birrell	 * We must emulate a "pushl %ebp".  To do this, we pull the stack
7591eaf3e1SJohn Birrell	 * down 4 bytes, and then store the base pointer.
7691eaf3e1SJohn Birrell	 */
7791eaf3e1SJohn Birrell	popal
7891eaf3e1SJohn Birrell	subl	$4, %esp		/* make room for %ebp */
7991eaf3e1SJohn Birrell	pushl	%eax			/* push temp */
8091eaf3e1SJohn Birrell	movl	8(%esp), %eax		/* load calling EIP */
8191eaf3e1SJohn Birrell	incl	%eax			/* increment over LOCK prefix */
8291eaf3e1SJohn Birrell	movl	%eax, 4(%esp)		/* store calling EIP */
8391eaf3e1SJohn Birrell	movl	12(%esp), %eax		/* load calling CS */
8491eaf3e1SJohn Birrell	movl	%eax, 8(%esp)		/* store calling CS */
8591eaf3e1SJohn Birrell	movl	16(%esp), %eax		/* load calling EFLAGS */
8691eaf3e1SJohn Birrell	movl	%eax, 12(%esp)		/* store calling EFLAGS */
8791eaf3e1SJohn Birrell	movl	%ebp, 16(%esp)		/* push %ebp */
8891eaf3e1SJohn Birrell	popl	%eax			/* pop off temp */
8991eaf3e1SJohn Birrell	iret				/* Return from interrupt. */
9091eaf3e1SJohn Birrellinvop_pop:
9191eaf3e1SJohn Birrell	/*
9291eaf3e1SJohn Birrell	 * We must emulate a "popl %ebp".  To do this, we do the opposite of
9391eaf3e1SJohn Birrell	 * the above:  we remove the %ebp from the stack, and squeeze up the
9491eaf3e1SJohn Birrell	 * saved state from the trap.
9591eaf3e1SJohn Birrell	 */
9691eaf3e1SJohn Birrell	popal
9791eaf3e1SJohn Birrell	pushl	%eax			/* push temp */
9891eaf3e1SJohn Birrell	movl	16(%esp), %ebp		/* pop %ebp */
9991eaf3e1SJohn Birrell	movl	12(%esp), %eax		/* load calling EFLAGS */
10091eaf3e1SJohn Birrell	movl	%eax, 16(%esp)		/* store calling EFLAGS */
10191eaf3e1SJohn Birrell	movl	8(%esp), %eax		/* load calling CS */
10291eaf3e1SJohn Birrell	movl	%eax, 12(%esp)		/* store calling CS */
10391eaf3e1SJohn Birrell	movl	4(%esp), %eax		/* load calling EIP */
10491eaf3e1SJohn Birrell	incl	%eax			/* increment over LOCK prefix */
10591eaf3e1SJohn Birrell	movl	%eax, 8(%esp)		/* store calling EIP */
10691eaf3e1SJohn Birrell	popl	%eax			/* pop off temp */
10791eaf3e1SJohn Birrell	addl	$4, %esp		/* adjust stack pointer */
10891eaf3e1SJohn Birrell	iret				/* Return from interrupt. */
10991eaf3e1SJohn Birrellinvop_leave:
11091eaf3e1SJohn Birrell	/*
11191eaf3e1SJohn Birrell	 * We must emulate a "leave", which is the same as a "movl %ebp, %esp"
11291eaf3e1SJohn Birrell	 * followed by a "popl %ebp".  This looks similar to the above, but
11391eaf3e1SJohn Birrell	 * requires two temporaries:  one for the new base pointer, and one
11491eaf3e1SJohn Birrell	 * for the staging register.
11591eaf3e1SJohn Birrell	 */
11691eaf3e1SJohn Birrell	popa
11791eaf3e1SJohn Birrell	pushl	%eax			/* push temp */
11891eaf3e1SJohn Birrell	pushl	%ebx			/* push temp */
11991eaf3e1SJohn Birrell	movl	%ebp, %ebx		/* set temp to old %ebp */
12091eaf3e1SJohn Birrell	movl	(%ebx), %ebp		/* pop %ebp */
12191eaf3e1SJohn Birrell	movl	16(%esp), %eax		/* load calling EFLAGS */
12291eaf3e1SJohn Birrell	movl	%eax, (%ebx)		/* store calling EFLAGS */
12391eaf3e1SJohn Birrell	movl	12(%esp), %eax		/* load calling CS */
12491eaf3e1SJohn Birrell	movl	%eax, -4(%ebx)		/* store calling CS */
12591eaf3e1SJohn Birrell	movl	8(%esp), %eax		/* load calling EIP */
12691eaf3e1SJohn Birrell	incl	%eax			/* increment over LOCK prefix */
12791eaf3e1SJohn Birrell	movl	%eax, -8(%ebx)		/* store calling EIP */
12891eaf3e1SJohn Birrell	movl	%ebx, -4(%esp)		/* temporarily store new %esp */
12991eaf3e1SJohn Birrell	popl	%ebx			/* pop off temp */
13091eaf3e1SJohn Birrell	popl	%eax			/* pop off temp */
13191eaf3e1SJohn Birrell	movl	-12(%esp), %esp		/* set stack pointer */
13291eaf3e1SJohn Birrell	subl	$8, %esp		/* adjust for three pushes, one pop */
13391eaf3e1SJohn Birrell	iret				/* return from interrupt */
13491eaf3e1SJohn Birrellinvop_nop:
13591eaf3e1SJohn Birrell	/*
13691eaf3e1SJohn Birrell	 * We must emulate a "nop".  This is obviously not hard:  we need only
13791eaf3e1SJohn Birrell	 * advance the %eip by one.
13891eaf3e1SJohn Birrell	 */
13991eaf3e1SJohn Birrell	popa
14091eaf3e1SJohn Birrell	incl	(%esp)
14191eaf3e1SJohn Birrell	iret				/* return from interrupt */
14291eaf3e1SJohn Birrell
14391eaf3e1SJohn Birrell	END(dtrace_invop_start)
14491eaf3e1SJohn Birrell
14591eaf3e1SJohn Birrell/*
14691eaf3e1SJohn Birrellvoid dtrace_invop_init(void)
14791eaf3e1SJohn Birrell*/
14891eaf3e1SJohn Birrell	ENTRY(dtrace_invop_init)
14991eaf3e1SJohn Birrell	movl	$dtrace_invop_start, dtrace_invop_jump_addr
15091eaf3e1SJohn Birrell	ret
15191eaf3e1SJohn Birrell	END(dtrace_invop_init)
15291eaf3e1SJohn Birrell
15391eaf3e1SJohn Birrell/*
15491eaf3e1SJohn Birrellvoid dtrace_invop_uninit(void)
15591eaf3e1SJohn Birrell*/
15691eaf3e1SJohn Birrell	ENTRY(dtrace_invop_uninit)
15791eaf3e1SJohn Birrell	movl	$0, dtrace_invop_jump_addr
15891eaf3e1SJohn Birrell	ret
15991eaf3e1SJohn Birrell	END(dtrace_invop_uninit)
16091eaf3e1SJohn Birrell
16191eaf3e1SJohn Birrell/*
16291eaf3e1SJohn Birrellgreg_t dtrace_getfp(void)
16391eaf3e1SJohn Birrell*/
16491eaf3e1SJohn Birrell
16591eaf3e1SJohn Birrell	ENTRY(dtrace_getfp)
16691eaf3e1SJohn Birrell	movl	%ebp, %eax
16791eaf3e1SJohn Birrell	ret
16891eaf3e1SJohn Birrell	END(dtrace_getfp)
16991eaf3e1SJohn Birrell
17091eaf3e1SJohn Birrell/*
17191eaf3e1SJohn Birrelluint32_t dtrace_cas32(uint32_t *target, uint32_t cmp, uint32_t new)
17291eaf3e1SJohn Birrell*/
17391eaf3e1SJohn Birrell
17491eaf3e1SJohn Birrell	ENTRY(dtrace_cas32)
17591eaf3e1SJohn Birrell	ALTENTRY(dtrace_casptr)
17691eaf3e1SJohn Birrell	movl	4(%esp), %edx
17791eaf3e1SJohn Birrell	movl	8(%esp), %eax
17891eaf3e1SJohn Birrell	movl	12(%esp), %ecx
17991eaf3e1SJohn Birrell	lock
18091eaf3e1SJohn Birrell	cmpxchgl %ecx, (%edx)
18191eaf3e1SJohn Birrell	ret
18291eaf3e1SJohn Birrell	END(dtrace_casptr)
18391eaf3e1SJohn Birrell	END(dtrace_cas32)
18491eaf3e1SJohn Birrell
18591eaf3e1SJohn Birrell/*
18691eaf3e1SJohn Birrelluintptr_t dtrace_caller(int aframes)
18791eaf3e1SJohn Birrell*/
18891eaf3e1SJohn Birrell
18991eaf3e1SJohn Birrell	ENTRY(dtrace_caller)
19091eaf3e1SJohn Birrell	movl	$-1, %eax
19191eaf3e1SJohn Birrell	ret
19291eaf3e1SJohn Birrell	END(dtrace_caller)
19391eaf3e1SJohn Birrell
19491eaf3e1SJohn Birrell/*
19591eaf3e1SJohn Birrellvoid dtrace_copy(uintptr_t src, uintptr_t dest, size_t size)
19691eaf3e1SJohn Birrell*/
19791eaf3e1SJohn Birrell
19891eaf3e1SJohn Birrell	ENTRY(dtrace_copy)
19991eaf3e1SJohn Birrell	pushl	%ebp
20091eaf3e1SJohn Birrell	movl	%esp, %ebp
20191eaf3e1SJohn Birrell	pushl	%esi
20291eaf3e1SJohn Birrell	pushl	%edi
20391eaf3e1SJohn Birrell
20491eaf3e1SJohn Birrell	movl	8(%ebp), %esi		/* Load source address */
20591eaf3e1SJohn Birrell	movl	12(%ebp), %edi		/* Load destination address */
20691eaf3e1SJohn Birrell	movl	16(%ebp), %ecx		/* Load count */
20791eaf3e1SJohn Birrell	repz				/* Repeat for count... */
20891eaf3e1SJohn Birrell	smovb				/*   move from %ds:si to %es:di */
20991eaf3e1SJohn Birrell
21091eaf3e1SJohn Birrell	popl	%edi
21191eaf3e1SJohn Birrell	popl	%esi
21291eaf3e1SJohn Birrell	movl	%ebp, %esp
21391eaf3e1SJohn Birrell	popl	%ebp
21491eaf3e1SJohn Birrell	ret
21591eaf3e1SJohn Birrell	END(dtrace_copy)
21691eaf3e1SJohn Birrell
21791eaf3e1SJohn Birrell/*
21891eaf3e1SJohn Birrellvoid dtrace_copystr(uintptr_t uaddr, uintptr_t kaddr, size_t size)
21991eaf3e1SJohn Birrell*/
22091eaf3e1SJohn Birrell
22191eaf3e1SJohn Birrell	ENTRY(dtrace_copystr)
22291eaf3e1SJohn Birrell
22391eaf3e1SJohn Birrell	pushl	%ebp			/* Setup stack frame */
22491eaf3e1SJohn Birrell	movl	%esp, %ebp
22591eaf3e1SJohn Birrell	pushl	%ebx			/* Save registers */
22691eaf3e1SJohn Birrell
22791eaf3e1SJohn Birrell	movl	8(%ebp), %ebx		/* Load source address */
22891eaf3e1SJohn Birrell	movl	12(%ebp), %edx		/* Load destination address */
22991eaf3e1SJohn Birrell	movl	16(%ebp), %ecx		/* Load count */
23091eaf3e1SJohn Birrell
23191eaf3e1SJohn Birrell0:
23291eaf3e1SJohn Birrell	movb	(%ebx), %al		/* Load from source */
23391eaf3e1SJohn Birrell	movb	%al, (%edx)		/* Store to destination */
23491eaf3e1SJohn Birrell	incl	%ebx			/* Increment source pointer */
23591eaf3e1SJohn Birrell	incl	%edx			/* Increment destination pointer */
23691eaf3e1SJohn Birrell	decl	%ecx			/* Decrement remaining count */
23791eaf3e1SJohn Birrell	cmpb	$0, %al
23891eaf3e1SJohn Birrell	je	1f
23991eaf3e1SJohn Birrell	cmpl	$0, %ecx
24091eaf3e1SJohn Birrell	jne	0b
24191eaf3e1SJohn Birrell
24291eaf3e1SJohn Birrell1:
24391eaf3e1SJohn Birrell	popl	%ebx
24491eaf3e1SJohn Birrell	movl	%ebp, %esp
24591eaf3e1SJohn Birrell	popl	%ebp
24691eaf3e1SJohn Birrell	ret
24791eaf3e1SJohn Birrell
24891eaf3e1SJohn Birrell	END(dtrace_copystr)
24991eaf3e1SJohn Birrell
25091eaf3e1SJohn Birrell/*
25191eaf3e1SJohn Birrelluintptr_t dtrace_fulword(void *addr)
25291eaf3e1SJohn Birrell*/
25391eaf3e1SJohn Birrell
25491eaf3e1SJohn Birrell	ENTRY(dtrace_fulword)
25591eaf3e1SJohn Birrell	movl	4(%esp), %ecx
25691eaf3e1SJohn Birrell	xorl	%eax, %eax
25791eaf3e1SJohn Birrell	movl	(%ecx), %eax
25891eaf3e1SJohn Birrell	ret
25991eaf3e1SJohn Birrell	END(dtrace_fulword)
26091eaf3e1SJohn Birrell
26191eaf3e1SJohn Birrell/*
26291eaf3e1SJohn Birrelluint8_t dtrace_fuword8_nocheck(void *addr)
26391eaf3e1SJohn Birrell*/
26491eaf3e1SJohn Birrell
26591eaf3e1SJohn Birrell	ENTRY(dtrace_fuword8_nocheck)
26691eaf3e1SJohn Birrell	movl	4(%esp), %ecx
26791eaf3e1SJohn Birrell	xorl	%eax, %eax
26891eaf3e1SJohn Birrell	movzbl	(%ecx), %eax
26991eaf3e1SJohn Birrell	ret
27091eaf3e1SJohn Birrell	END(dtrace_fuword8_nocheck)
27191eaf3e1SJohn Birrell
27291eaf3e1SJohn Birrell/*
27391eaf3e1SJohn Birrelluint16_t dtrace_fuword16_nocheck(void *addr)
27491eaf3e1SJohn Birrell*/
27591eaf3e1SJohn Birrell
27691eaf3e1SJohn Birrell	ENTRY(dtrace_fuword16_nocheck)
27791eaf3e1SJohn Birrell	movl	4(%esp), %ecx
27891eaf3e1SJohn Birrell	xorl	%eax, %eax
27991eaf3e1SJohn Birrell	movzwl	(%ecx), %eax
28091eaf3e1SJohn Birrell	ret
28191eaf3e1SJohn Birrell	END(dtrace_fuword16_nocheck)
28291eaf3e1SJohn Birrell
28391eaf3e1SJohn Birrell/*
28491eaf3e1SJohn Birrelluint32_t dtrace_fuword32_nocheck(void *addr)
28591eaf3e1SJohn Birrell*/
28691eaf3e1SJohn Birrell
28791eaf3e1SJohn Birrell	ENTRY(dtrace_fuword32_nocheck)
28891eaf3e1SJohn Birrell	movl	4(%esp), %ecx
28991eaf3e1SJohn Birrell	xorl	%eax, %eax
29091eaf3e1SJohn Birrell	movl	(%ecx), %eax
29191eaf3e1SJohn Birrell	ret
29291eaf3e1SJohn Birrell	END(dtrace_fuword32_nocheck)
29391eaf3e1SJohn Birrell
29491eaf3e1SJohn Birrell/*
29591eaf3e1SJohn Birrelluint64_t dtrace_fuword64_nocheck(void *addr)
29691eaf3e1SJohn Birrell*/
29791eaf3e1SJohn Birrell
29891eaf3e1SJohn Birrell	ENTRY(dtrace_fuword64_nocheck)
29991eaf3e1SJohn Birrell	movl	4(%esp), %ecx
30091eaf3e1SJohn Birrell	xorl	%eax, %eax
30191eaf3e1SJohn Birrell	xorl	%edx, %edx
30291eaf3e1SJohn Birrell	movl	(%ecx), %eax
30391eaf3e1SJohn Birrell	movl	4(%ecx), %edx
30491eaf3e1SJohn Birrell	ret
30591eaf3e1SJohn Birrell	END(dtrace_fuword64_nocheck)
30691eaf3e1SJohn Birrell
30791eaf3e1SJohn Birrell/*
30891eaf3e1SJohn Birrellvoid dtrace_probe_error(dtrace_state_t *state, dtrace_epid_t epid, int which, int fault, int fltoffs, uintptr_t illval)
30991eaf3e1SJohn Birrell*/
31091eaf3e1SJohn Birrell
31191eaf3e1SJohn Birrell	ENTRY(dtrace_probe_error)
31291eaf3e1SJohn Birrell	pushl	%ebp
31391eaf3e1SJohn Birrell	movl	%esp, %ebp
31491eaf3e1SJohn Birrell	pushl	0x1c(%ebp)
31591eaf3e1SJohn Birrell	pushl	0x18(%ebp)
31691eaf3e1SJohn Birrell	pushl	0x14(%ebp)
31791eaf3e1SJohn Birrell	pushl	0x10(%ebp)
31891eaf3e1SJohn Birrell	pushl	0xc(%ebp)
31991eaf3e1SJohn Birrell	pushl	0x8(%ebp)
32091eaf3e1SJohn Birrell	pushl	dtrace_probeid_error
32191eaf3e1SJohn Birrell	call	dtrace_probe
32291eaf3e1SJohn Birrell	movl	%ebp, %esp
32391eaf3e1SJohn Birrell	popl	%ebp
32491eaf3e1SJohn Birrell	ret
32591eaf3e1SJohn Birrell	END(dtrace_probe_error)
32691eaf3e1SJohn Birrell
32791eaf3e1SJohn Birrell/*
32891eaf3e1SJohn Birrellvoid dtrace_membar_producer(void)
32991eaf3e1SJohn Birrell*/
33091eaf3e1SJohn Birrell
33191eaf3e1SJohn Birrell	ENTRY(dtrace_membar_producer)
33291eaf3e1SJohn Birrell	rep;	ret	/* use 2 byte return instruction when branch target */
33391eaf3e1SJohn Birrell			/* AMD Software Optimization Guide - Section 6.2 */
33491eaf3e1SJohn Birrell	END(dtrace_membar_producer)
33591eaf3e1SJohn Birrell
33691eaf3e1SJohn Birrell/*
33791eaf3e1SJohn Birrellvoid dtrace_membar_consumer(void)
33891eaf3e1SJohn Birrell*/
33991eaf3e1SJohn Birrell
34091eaf3e1SJohn Birrell	ENTRY(dtrace_membar_consumer)
34191eaf3e1SJohn Birrell	rep;	ret	/* use 2 byte return instruction when branch target */
34291eaf3e1SJohn Birrell			/* AMD Software Optimization Guide - Section 6.2 */
34391eaf3e1SJohn Birrell	END(dtrace_membar_consumer)
34491eaf3e1SJohn Birrell
34591eaf3e1SJohn Birrell/*
34691eaf3e1SJohn Birrelldtrace_icookie_t dtrace_interrupt_disable(void)
34791eaf3e1SJohn Birrell*/
34891eaf3e1SJohn Birrell	ENTRY(dtrace_interrupt_disable)
34991eaf3e1SJohn Birrell	pushfl
35091eaf3e1SJohn Birrell	popl	%eax
35191eaf3e1SJohn Birrell	cli
35291eaf3e1SJohn Birrell	ret
35391eaf3e1SJohn Birrell	END(dtrace_interrupt_disable)
35491eaf3e1SJohn Birrell
35591eaf3e1SJohn Birrell/*
35691eaf3e1SJohn Birrellvoid dtrace_interrupt_enable(dtrace_icookie_t cookie)
35791eaf3e1SJohn Birrell*/
35891eaf3e1SJohn Birrell	ENTRY(dtrace_interrupt_enable)
35991eaf3e1SJohn Birrell	movl	4(%esp), %eax
36091eaf3e1SJohn Birrell	pushl	%eax
36191eaf3e1SJohn Birrell	popfl
36291eaf3e1SJohn Birrell	ret
36391eaf3e1SJohn Birrell	END(dtrace_interrupt_enable)
36491eaf3e1SJohn Birrell
36591eaf3e1SJohn Birrell/*
36691eaf3e1SJohn Birrell * The panic() and cmn_err() functions invoke vpanic() as a common entry point
36791eaf3e1SJohn Birrell * into the panic code implemented in panicsys().  vpanic() is responsible
36891eaf3e1SJohn Birrell * for passing through the format string and arguments, and constructing a
36991eaf3e1SJohn Birrell * regs structure on the stack into which it saves the current register
37091eaf3e1SJohn Birrell * values.  If we are not dying due to a fatal trap, these registers will
37191eaf3e1SJohn Birrell * then be preserved in panicbuf as the current processor state.  Before
37291eaf3e1SJohn Birrell * invoking panicsys(), vpanic() activates the first panic trigger (see
37391eaf3e1SJohn Birrell * common/os/panic.c) and switches to the panic_stack if successful.  Note that
37491eaf3e1SJohn Birrell * DTrace takes a slightly different panic path if it must panic from probe
37591eaf3e1SJohn Birrell * context.  Instead of calling panic, it calls into dtrace_vpanic(), which
37691eaf3e1SJohn Birrell * sets up the initial stack as vpanic does, calls dtrace_panic_trigger(), and
37791eaf3e1SJohn Birrell * branches back into vpanic().
37891eaf3e1SJohn Birrell */
37991eaf3e1SJohn Birrell/*
38091eaf3e1SJohn Birrellvoid vpanic(const char *format, va_list alist)
38191eaf3e1SJohn Birrell*/
38291eaf3e1SJohn Birrell	ENTRY(vpanic)				/* Initial stack layout: */
38391eaf3e1SJohn Birrell
38491eaf3e1SJohn Birrell	pushl	%ebp				/* | %eip | 20 */
38591eaf3e1SJohn Birrell	movl	%esp, %ebp			/* | %ebp | 16 */
38691eaf3e1SJohn Birrell	pushl	%eax				/* | %eax | 12 */
38791eaf3e1SJohn Birrell	pushl	%ebx				/* | %ebx |  8 */
38891eaf3e1SJohn Birrell	pushl	%ecx				/* | %ecx |  4 */
38991eaf3e1SJohn Birrell	pushl	%edx				/* | %edx |  0 */
39091eaf3e1SJohn Birrell
39191eaf3e1SJohn Birrell	movl	%esp, %ebx			/* %ebx = current stack pointer */
39291eaf3e1SJohn Birrell
39391eaf3e1SJohn Birrell	lea	panic_quiesce, %eax		/* %eax = &panic_quiesce */
39491eaf3e1SJohn Birrell	pushl	%eax				/* push &panic_quiesce */
39591eaf3e1SJohn Birrell	call	panic_trigger			/* %eax = panic_trigger() */
39691eaf3e1SJohn Birrell	addl	$4, %esp			/* reset stack pointer */
39791eaf3e1SJohn Birrell
39891eaf3e1SJohn Birrellvpanic_common:
39991eaf3e1SJohn Birrell	cmpl	$0, %eax			/* if (%eax == 0) */
40091eaf3e1SJohn Birrell	je	0f				/*   goto 0f; */
40191eaf3e1SJohn Birrell
40291eaf3e1SJohn Birrell	/*
40391eaf3e1SJohn Birrell	 * If panic_trigger() was successful, we are the first to initiate a
40491eaf3e1SJohn Birrell	 * panic: we now switch to the reserved panic_stack before continuing.
40591eaf3e1SJohn Birrell	 */
40691eaf3e1SJohn Birrell	lea	panic_stack, %esp		/* %esp  = panic_stack */
40791eaf3e1SJohn Birrell	addl	$PANICSTKSIZE, %esp		/* %esp += PANICSTKSIZE */
40891eaf3e1SJohn Birrell
40991eaf3e1SJohn Birrell0:	subl	$REGSIZE, %esp			/* allocate struct regs */
41091eaf3e1SJohn Birrell
41191eaf3e1SJohn Birrell	/*
41291eaf3e1SJohn Birrell	 * Now that we've got everything set up, store the register values as
41391eaf3e1SJohn Birrell	 * they were when we entered vpanic() to the designated location in
41491eaf3e1SJohn Birrell	 * the regs structure we allocated on the stack.
41591eaf3e1SJohn Birrell	 */
41691eaf3e1SJohn Birrell#ifdef notyet
41791eaf3e1SJohn Birrell	mov	%gs, %edx
41891eaf3e1SJohn Birrell	mov	%edx, REGOFF_GS(%esp)
41991eaf3e1SJohn Birrell	mov	%fs, %edx
42091eaf3e1SJohn Birrell	mov	%edx, REGOFF_FS(%esp)
42191eaf3e1SJohn Birrell	mov	%es, %edx
42291eaf3e1SJohn Birrell	mov	%edx, REGOFF_ES(%esp)
42391eaf3e1SJohn Birrell	mov	%ds, %edx
42491eaf3e1SJohn Birrell	mov	%edx, REGOFF_DS(%esp)
42591eaf3e1SJohn Birrell	movl	%edi, REGOFF_EDI(%esp)
42691eaf3e1SJohn Birrell	movl	%esi, REGOFF_ESI(%esp)
42791eaf3e1SJohn Birrell	movl	16(%ebx), %ecx
42891eaf3e1SJohn Birrell	movl	%ecx, REGOFF_EBP(%esp)
42991eaf3e1SJohn Birrell	movl	%ebx, %ecx
43091eaf3e1SJohn Birrell	addl	$20, %ecx
43191eaf3e1SJohn Birrell	movl	%ecx, REGOFF_ESP(%esp)
43291eaf3e1SJohn Birrell	movl	8(%ebx), %ecx
43391eaf3e1SJohn Birrell	movl	%ecx, REGOFF_EBX(%esp)
43491eaf3e1SJohn Birrell	movl	0(%ebx), %ecx
43591eaf3e1SJohn Birrell	movl	%ecx, REGOFF_EDX(%esp)
43691eaf3e1SJohn Birrell	movl	4(%ebx), %ecx
43791eaf3e1SJohn Birrell	movl	%ecx, REGOFF_ECX(%esp)
43891eaf3e1SJohn Birrell	movl	12(%ebx), %ecx
43991eaf3e1SJohn Birrell	movl	%ecx, REGOFF_EAX(%esp)
44091eaf3e1SJohn Birrell	movl	$0, REGOFF_TRAPNO(%esp)
44191eaf3e1SJohn Birrell	movl	$0, REGOFF_ERR(%esp)
44291eaf3e1SJohn Birrell	lea	vpanic, %ecx
44391eaf3e1SJohn Birrell	movl	%ecx, REGOFF_EIP(%esp)
44491eaf3e1SJohn Birrell	mov	%cs, %edx
44591eaf3e1SJohn Birrell	movl	%edx, REGOFF_CS(%esp)
44691eaf3e1SJohn Birrell	pushfl
44791eaf3e1SJohn Birrell	popl	%ecx
44891eaf3e1SJohn Birrell	movl	%ecx, REGOFF_EFL(%esp)
44991eaf3e1SJohn Birrell	movl	$0, REGOFF_UESP(%esp)
45091eaf3e1SJohn Birrell	mov	%ss, %edx
45191eaf3e1SJohn Birrell	movl	%edx, REGOFF_SS(%esp)
45291eaf3e1SJohn Birrell
45391eaf3e1SJohn Birrell	movl	%esp, %ecx			/* %ecx = &regs */
45491eaf3e1SJohn Birrell	pushl	%eax				/* push on_panic_stack */
45591eaf3e1SJohn Birrell	pushl	%ecx				/* push &regs */
45691eaf3e1SJohn Birrell	movl	12(%ebp), %ecx			/* %ecx = alist */
45791eaf3e1SJohn Birrell	pushl	%ecx				/* push alist */
45891eaf3e1SJohn Birrell	movl	8(%ebp), %ecx			/* %ecx = format */
45991eaf3e1SJohn Birrell	pushl	%ecx				/* push format */
46091eaf3e1SJohn Birrell	call	panicsys			/* panicsys(); */
46191eaf3e1SJohn Birrell	addl	$16, %esp			/* pop arguments */
46291eaf3e1SJohn Birrell
46391eaf3e1SJohn Birrell	addl	$REGSIZE, %esp
46491eaf3e1SJohn Birrell#endif
46591eaf3e1SJohn Birrell	popl	%edx
46691eaf3e1SJohn Birrell	popl	%ecx
46791eaf3e1SJohn Birrell	popl	%ebx
46891eaf3e1SJohn Birrell	popl	%eax
46991eaf3e1SJohn Birrell	leave
47091eaf3e1SJohn Birrell	ret
47191eaf3e1SJohn Birrell	END(vpanic)
47291eaf3e1SJohn Birrell
47391eaf3e1SJohn Birrell/*
47491eaf3e1SJohn Birrellvoid dtrace_vpanic(const char *format, va_list alist)
47591eaf3e1SJohn Birrell*/
47691eaf3e1SJohn Birrell	ENTRY(dtrace_vpanic)			/* Initial stack layout: */
47791eaf3e1SJohn Birrell
47891eaf3e1SJohn Birrell	pushl	%ebp				/* | %eip | 20 */
47991eaf3e1SJohn Birrell	movl	%esp, %ebp			/* | %ebp | 16 */
48091eaf3e1SJohn Birrell	pushl	%eax				/* | %eax | 12 */
48191eaf3e1SJohn Birrell	pushl	%ebx				/* | %ebx |  8 */
48291eaf3e1SJohn Birrell	pushl	%ecx				/* | %ecx |  4 */
48391eaf3e1SJohn Birrell	pushl	%edx				/* | %edx |  0 */
48491eaf3e1SJohn Birrell
48591eaf3e1SJohn Birrell	movl	%esp, %ebx			/* %ebx = current stack pointer */
48691eaf3e1SJohn Birrell
48791eaf3e1SJohn Birrell	lea	panic_quiesce, %eax		/* %eax = &panic_quiesce */
48891eaf3e1SJohn Birrell	pushl	%eax				/* push &panic_quiesce */
48991eaf3e1SJohn Birrell	call	dtrace_panic_trigger		/* %eax = dtrace_panic_trigger() */
49091eaf3e1SJohn Birrell	addl	$4, %esp			/* reset stack pointer */
49191eaf3e1SJohn Birrell	jmp	vpanic_common			/* jump back to common code */
49291eaf3e1SJohn Birrell
49391eaf3e1SJohn Birrell	END(dtrace_vpanic)
49491eaf3e1SJohn Birrell
49591eaf3e1SJohn Birrell/*
49691eaf3e1SJohn Birrellint
49791eaf3e1SJohn Birrellpanic_trigger(int *tp)
49891eaf3e1SJohn Birrell*/
49991eaf3e1SJohn Birrell	ENTRY(panic_trigger)
50091eaf3e1SJohn Birrell	xorl	%eax, %eax
50191eaf3e1SJohn Birrell	movl	$0xdefacedd, %edx
50291eaf3e1SJohn Birrell	lock
50391eaf3e1SJohn Birrell	  xchgl	%edx, (%edi)
50491eaf3e1SJohn Birrell	cmpl	$0, %edx
50591eaf3e1SJohn Birrell	je	0f
50691eaf3e1SJohn Birrell	movl	$0, %eax
50791eaf3e1SJohn Birrell	ret
50891eaf3e1SJohn Birrell0:	movl	$1, %eax
50991eaf3e1SJohn Birrell	ret
51091eaf3e1SJohn Birrell	END(panic_trigger)
51191eaf3e1SJohn Birrell
51291eaf3e1SJohn Birrell/*
51391eaf3e1SJohn Birrellint
51491eaf3e1SJohn Birrelldtrace_panic_trigger(int *tp)
51591eaf3e1SJohn Birrell*/
51691eaf3e1SJohn Birrell	ENTRY(dtrace_panic_trigger)
51791eaf3e1SJohn Birrell	xorl	%eax, %eax
51891eaf3e1SJohn Birrell	movl	$0xdefacedd, %edx
51991eaf3e1SJohn Birrell	lock
52091eaf3e1SJohn Birrell	  xchgl	%edx, (%edi)
52191eaf3e1SJohn Birrell	cmpl	$0, %edx
52291eaf3e1SJohn Birrell	je	0f
52391eaf3e1SJohn Birrell	movl	$0, %eax
52491eaf3e1SJohn Birrell	ret
52591eaf3e1SJohn Birrell0:	movl	$1, %eax
52691eaf3e1SJohn Birrell	ret
52791eaf3e1SJohn Birrell	END(dtrace_panic_trigger)
528