xref: /onnv-gate/usr/src/cmd/mdb/intel/amd64/kmdb/kaif_invoke.s (revision 0:68f95e015346)
1*0Sstevel@tonic-gate/*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate/*
23*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate#pragma ident	"%Z%%M%	%I%	%E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate#include <sys/asm_linkage.h>
30*0Sstevel@tonic-gate
31*0Sstevel@tonic-gate/*
32*0Sstevel@tonic-gate * Kernel function call invocation
33*0Sstevel@tonic-gate */
34*0Sstevel@tonic-gate
35*0Sstevel@tonic-gate#if defined(__lint)
36*0Sstevel@tonic-gate/*ARGSUSED*/
37*0Sstevel@tonic-gateuintptr_t
38*0Sstevel@tonic-gatekaif_invoke(uintptr_t funcva, uint_t argc, const uintptr_t argv[])
39*0Sstevel@tonic-gate{
40*0Sstevel@tonic-gate	return (0);
41*0Sstevel@tonic-gate}
42*0Sstevel@tonic-gate#else
43*0Sstevel@tonic-gate	/*
44*0Sstevel@tonic-gate	 * A jump table containing the addresses for register argument copy
45*0Sstevel@tonic-gate	 * code.
46*0Sstevel@tonic-gate	 */
47*0Sstevel@tonic-gatecopyargs:
48*0Sstevel@tonic-gate	.quad	cp0arg
49*0Sstevel@tonic-gate	.quad	cp1arg
50*0Sstevel@tonic-gate	.quad	cp2arg
51*0Sstevel@tonic-gate	.quad	cp3arg
52*0Sstevel@tonic-gate	.quad	cp4arg
53*0Sstevel@tonic-gate	.quad	cp5arg
54*0Sstevel@tonic-gate	.quad	cp6arg
55*0Sstevel@tonic-gate
56*0Sstevel@tonic-gate	/*
57*0Sstevel@tonic-gate	 * This is going to be fun.  We were called with the function pointer
58*0Sstevel@tonic-gate	 * in in %rsi, argc in %rdx, and a pointer to an array of uintptr_t's
59*0Sstevel@tonic-gate	 * (the arguments to be passed) in %rcx.  In the worst case, we need
60*0Sstevel@tonic-gate	 * to move the first six arguments from the array to %rdi, %rsi, %rdx,
61*0Sstevel@tonic-gate	 * %rcx, %r8, and %r9.  The remaining arguments need to be copied from
62*0Sstevel@tonic-gate	 * the array to 0(%rsp), 8(%rsp), and so on.  Then we can call the
63*0Sstevel@tonic-gate	 * function.
64*0Sstevel@tonic-gate	 */
65*0Sstevel@tonic-gate
66*0Sstevel@tonic-gate	ENTRY_NP(kaif_invoke)
67*0Sstevel@tonic-gate
68*0Sstevel@tonic-gate	pushq	%rbp
69*0Sstevel@tonic-gate	movq	%rsp, %rbp
70*0Sstevel@tonic-gate	pushq	%r12			/* our extra stack space */
71*0Sstevel@tonic-gate	clrq	%r12
72*0Sstevel@tonic-gate
73*0Sstevel@tonic-gate	movq	%rdi, %rax		/* function pointer */
74*0Sstevel@tonic-gate	movq	%rdx, %rdi		/* argv */
75*0Sstevel@tonic-gate
76*0Sstevel@tonic-gate	cmpq	$6, %rsi
77*0Sstevel@tonic-gate	jle	stackdone
78*0Sstevel@tonic-gate
79*0Sstevel@tonic-gate	/*
80*0Sstevel@tonic-gate	 * More than six arguments.  Reserve space for the seventh and beyond on
81*0Sstevel@tonic-gate	 * the stack, and copy them in.  To make the copy easier, we're going to
82*0Sstevel@tonic-gate	 * pretend to reserve space on the stack for all of the arguments, thus
83*0Sstevel@tonic-gate	 * allowing us to use the same scaling for the store as we do for the
84*0Sstevel@tonic-gate	 * load.  When we're done copying the excess arguments, we'll move %rsp
85*0Sstevel@tonic-gate	 * back, reclaiming the extra space we reserved.
86*0Sstevel@tonic-gate	 */
87*0Sstevel@tonic-gate	movq	%rsi, %r12
88*0Sstevel@tonic-gate	subq	$6, %r12
89*0Sstevel@tonic-gate	shlq	$3, %r12
90*0Sstevel@tonic-gate	subq	%r12, %rsp
91*0Sstevel@tonic-gate	subq	$0x30, %rsp		/* reserve 6 arg space for scaling */
92*0Sstevel@tonic-gate
93*0Sstevel@tonic-gate1:	decq	%rsi
94*0Sstevel@tonic-gate	movq	(%rdx, %rsi, 8), %r9
95*0Sstevel@tonic-gate	movq	%r9, (%rsp, %rsi, 8)
96*0Sstevel@tonic-gate	cmpq	$6, %rsi
97*0Sstevel@tonic-gate	jg	1b
98*0Sstevel@tonic-gate
99*0Sstevel@tonic-gate	addq	$0x30, %rsp		/* restore scaling arg space */
100*0Sstevel@tonic-gate
101*0Sstevel@tonic-gatestackdone:
102*0Sstevel@tonic-gate	/*
103*0Sstevel@tonic-gate	 * Excess arguments have been copied and stripped from argc (or there
104*0Sstevel@tonic-gate	 * weren't any to begin with).  Copy the first five to their ABI-
105*0Sstevel@tonic-gate	 * designated registers.  We have to do this somewhat carefully, as
106*0Sstevel@tonic-gate	 * argc (%rdx) and argv (%rsi) are in to-be-trampled registers.
107*0Sstevel@tonic-gate	 */
108*0Sstevel@tonic-gate	leaq	copyargs(%rip), %r9
109*0Sstevel@tonic-gate	shlq	$3, %rsi
110*0Sstevel@tonic-gate	addq	%rsi, %r9
111*0Sstevel@tonic-gate	jmp	*(%r9)
112*0Sstevel@tonic-gate
113*0Sstevel@tonic-gatecp6arg:	movq	0x28(%rdi), %r9
114*0Sstevel@tonic-gatecp5arg:	movq	0x20(%rdi), %r8
115*0Sstevel@tonic-gatecp4arg:	movq	0x18(%rdi), %rcx
116*0Sstevel@tonic-gatecp3arg:	movq	0x10(%rdi), %rdx
117*0Sstevel@tonic-gatecp2arg:	movq	0x08(%rdi), %rsi
118*0Sstevel@tonic-gatecp1arg: movq	0x00(%rdi), %rdi
119*0Sstevel@tonic-gatecp0arg:
120*0Sstevel@tonic-gate
121*0Sstevel@tonic-gate	/* Arguments are copied.  Time to call the function */
122*0Sstevel@tonic-gate	call	*%rax
123*0Sstevel@tonic-gate
124*0Sstevel@tonic-gate	/*
125*0Sstevel@tonic-gate	 * Deallocate the stack-based arguments, if any, and return to the
126*0Sstevel@tonic-gate	 * caller.
127*0Sstevel@tonic-gate	 */
128*0Sstevel@tonic-gate
129*0Sstevel@tonic-gate	addq	%r12, %rsp
130*0Sstevel@tonic-gate	popq	%r12
131*0Sstevel@tonic-gate	leave
132*0Sstevel@tonic-gate	ret
133*0Sstevel@tonic-gate
134*0Sstevel@tonic-gate	SET_SIZE(kaif_invoke)
135*0Sstevel@tonic-gate
136*0Sstevel@tonic-gate#endif
137