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 _IA32_SYS_STACK_H
28#define	_IA32_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 * In the x86 world, a stack frame looks like this:
44 *
45 *		|--------------------------|
46 * 4n+8(%ebp) ->| argument word n	   |
47 *		| ...			   |	(Previous frame)
48 *    8(%ebp) ->| argument word 0	   |
49 *		|--------------------------|--------------------
50 *    4(%ebp) ->| return address	   |
51 *		|--------------------------|
52 *    0(%ebp) ->| previous %ebp (optional) |
53 * 		|--------------------------|
54 *   -4(%ebp) ->| unspecified		   |	(Current frame)
55 *		| ...			   |
56 *    0(%esp) ->| variable size		   |
57 * 		|--------------------------|
58 */
59
60/*
61 * Stack alignment macros.
62 */
63
64#define	STACK_ALIGN32		4
65#define	STACK_ENTRY_ALIGN32	4
66#define	STACK_BIAS32		0
67#define	SA32(x)			(((x)+(STACK_ALIGN32-1)) & ~(STACK_ALIGN32-1))
68#define	STACK_RESERVE32		0
69#define	MINFRAME32		0
70
71#if defined(__amd64)
72
73/*
74 * In the amd64 world, a stack frame looks like this:
75 *
76 *		|--------------------------|
77 * 8n+16(%rbp)->| argument word n	   |
78 *		| ...			   |	(Previous frame)
79 *   16(%rbp) ->| argument word 0	   |
80 *		|--------------------------|--------------------
81 *    8(%rbp) ->| return address	   |
82 *		|--------------------------|
83 *    0(%rbp) ->| previous %rbp            |
84 * 		|--------------------------|
85 *   -8(%rbp) ->| unspecified		   |	(Current frame)
86 *		| ...			   |
87 *    0(%rsp) ->| variable size		   |
88 * 		|--------------------------|
89 * -128(%rsp) ->| reserved for function	   |
90 * 		|--------------------------|
91 *
92 * The end of the input argument area must be aligned on a 16-byte
93 * boundary; i.e. (%rsp - 8) % 16 == 0 at function entry.
94 *
95 * The 128-byte location beyond %rsp is considered to be reserved for
96 * functions and is NOT modified by signal handlers.  It can be used
97 * to store temporary data that is not needed across function calls.
98 */
99
100/*
101 * Stack alignment macros.
102 */
103
104#define	STACK_ALIGN64		16
105#define	STACK_ENTRY_ALIGN64 	8
106#define	STACK_BIAS64		0
107#define	SA64(x)			(((x)+(STACK_ALIGN64-1)) & ~(STACK_ALIGN64-1))
108#define	STACK_RESERVE64		128
109#define	MINFRAME64		0
110
111#define	STACK_ALIGN		STACK_ALIGN64
112#define	STACK_ENTRY_ALIGN	STACK_ENTRY_ALIGN64
113#define	STACK_BIAS		STACK_BIAS64
114#define	SA(x)			SA64(x)
115#define	STACK_RESERVE		STACK_RESERVE64
116#define	MINFRAME		MINFRAME64
117
118#elif defined(__i386)
119
120#define	STACK_ALIGN		STACK_ALIGN32
121#define	STACK_ENTRY_ALIGN	STACK_ENTRY_ALIGN32
122#define	STACK_BIAS		STACK_BIAS32
123#define	SA(x)			SA32(x)
124#define	STACK_RESERVE		STACK_RESERVE32
125#define	MINFRAME		MINFRAME32
126
127#endif	/* __i386 */
128
129#if defined(_KERNEL) && !defined(_ASM)
130
131#if defined(DEBUG)
132#if STACK_ALIGN == 4
133#define	ASSERT_STACK_ALIGNED()						\
134	{								\
135		uint32_t __tmp;						\
136		ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0);	\
137	}
138#elif (STACK_ALIGN == 16) && (_LONG_DOUBLE_ALIGNMENT == 16)
139#define	ASSERT_STACK_ALIGNED()						\
140	{								\
141		long double __tmp;					\
142		ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0);	\
143	}
144#endif
145#else	/* DEBUG */
146#define	ASSERT_STACK_ALIGNED()
147#endif	/* DEBUG */
148
149struct regs;
150
151void traceregs(struct regs *);
152void traceback(caddr_t);
153
154#endif /* defined(_KERNEL) && !defined(_ASM) */
155
156#define	STACK_GROWTH_DOWN /* stacks grow from high to low addresses */
157
158#ifdef	__cplusplus
159}
160#endif
161
162#endif	/* _IA32_SYS_STACK_H */
163