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#ifndef _SYS_STACK_H
28#define	_SYS_STACK_H
29
30#pragma ident	"%Z%%M%	%I%	%E% SMI"
31
32#if !defined(_ASM)
33
34#include <sys/types.h>
35
36#endif
37
38#ifdef	__cplusplus
39extern "C" {
40#endif
41
42/*
43 * A stack frame looks like:
44 *
45 * %fp->|				|
46 *	|-------------------------------|
47 *	|  Locals, temps, saved floats	|
48 *	|-------------------------------|
49 *	|  outgoing parameters past 6	|
50 *	|-------------------------------|-\
51 *	|  6 words for callee to dump	| |
52 *	|  register arguments		| |
53 *	|-------------------------------|  > minimum stack frame
54 *	|  One word struct-ret address	| |
55 *	|-------------------------------| |
56 *	|  16 words to save IN and	| |
57 * %sp->|  LOCAL register on overflow	| |
58 *	|-------------------------------|-/
59 */
60
61/*
62 * Constants defining a 32-bit stack frame.
63 */
64#define	WINDOWSIZE32	(16*4)		/* size of window save area */
65#define	ARGPUSHSIZE32	(6*4)		/* size of arg dump area */
66#define	ARGPUSH32	(WINDOWSIZE32 + 4)	/* arg dump area offset */
67#define	MINFRAME32	(WINDOWSIZE32 + ARGPUSHSIZE32 + 4) /* min frame */
68
69#define	STACK_GROWTH_DOWN /* stacks grow from high to low addresses */
70
71/*
72 * Stack alignment macros.
73 */
74#define	STACK_ALIGN32		8
75#define	STACK_ENTRY_ALIGN32	8
76#define	SA32(X)			(((X)+(STACK_ALIGN32-1)) & ~(STACK_ALIGN32-1))
77
78#if defined(__sparcv9)
79/*
80 * The 64-bit C ABI uses a stack frame that looks like:
81 *
82 *      |				|
83 *	|-------------------------------|
84 *	|  Locals, temps, saved floats	|
85 *	|-------------------------------|
86 *	|  outgoing parameters past 6	|
87 *	|-------------------------------|-\
88 *	|  outgoing parameters thru 6	| |
89 *	|-------------------------------|  > minimum stack frame
90 *	|  16 xwords to save IN and	| |
91 *      |  LOCAL register on overflow	| |
92 *	|-------------------------------|-/-\
93 *      |				|   |
94 *      |				|    > v9 abi bias
95 *      |				|   |
96 * %sp->|-------------------------------|---/
97 */
98
99/*
100 * Constants defining a stack frame.
101 */
102#define	WINDOWSIZE64		(16*8)		/* size of window save area */
103#define	ARGPUSHSIZE64		(6*8)		/* size of arg dump area */
104#define	MINFRAME64		(WINDOWSIZE64 + 48)	/* min frame */
105#define	ARGPUSH64		(WINDOWSIZE64)	/* arg dump area offset */
106#define	V9BIAS64		(2048-1)	/* v9 abi stack bias */
107
108#define	STACK_ALIGN64		16
109#define	STACK_ENTRY_ALIGN64	16
110#define	SA64(X)			(((X)+(STACK_ALIGN64-1)) & ~(STACK_ALIGN64-1))
111
112#define	IS_V9STACK(x)		((((uintptr_t)(x) + V9BIAS64) & \
113				(STACK_ALIGN64-1)) == 0)
114
115#define	WINDOWSIZE		WINDOWSIZE64
116#define	ARGPUSHSIZE		ARGPUSHSIZE64
117#define	ARGPUSH			ARGPUSH64
118#define	MINFRAME		MINFRAME64
119#define	STACK_ALIGN		STACK_ALIGN64
120#define	STACK_ENTRY_ALIGN	STACK_ENTRY_ALIGN64
121#define	STACK_BIAS		V9BIAS64
122#define	SA(x)			SA64(x)
123
124#else
125
126#define	WINDOWSIZE		WINDOWSIZE32
127#define	ARGPUSHSIZE		ARGPUSHSIZE32
128#define	ARGPUSH			ARGPUSH32
129#define	MINFRAME		MINFRAME32
130#define	STACK_ALIGN		STACK_ALIGN32
131#define	STACK_ENTRY_ALIGN	STACK_ENTRY_ALIGN32
132#define	STACK_BIAS		0
133#define	SA(x)			SA32(x)
134#define	STACK_V9BIAS64		(2048-1)	/* v9 abi stack bias */
135
136#endif /* __sparcv9 */
137
138#if defined(_KERNEL) && !defined(_ASM)
139
140#if defined(DEBUG)
141#if STACK_ALIGN == 8
142#define	ASSERT_STACK_ALIGNED()						\
143	{								\
144		uint64_t __tmp;						\
145		ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0);	\
146	}
147#elif (STACK_ALIGN == 16) && (_LONG_DOUBLE_ALIGNMENT == 16)
148#define	ASSERT_STACK_ALIGNED()						\
149	{								\
150		long double __tmp;					\
151		ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0);	\
152	}
153#endif
154#else	/* DEBUG */
155#define	ASSERT_STACK_ALIGNED()
156#endif	/* DEBUG */
157
158struct regs;
159
160void flush_windows(void);
161void flush_user_windows(void);
162int  flush_user_windows_to_stack(caddr_t *);
163void trash_user_windows(void);
164void traceregs(struct regs *);
165void traceback(caddr_t);
166
167#endif	/* defined(_KERNEL) && !defined(_ASM) */
168
169#ifdef	__cplusplus
170}
171#endif
172
173#endif	/* _SYS_STACK_H */
174