OpenSolaris_b135/uts/sparc/sys/stack.h

/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
 * or http://www.opensolaris.org/os/licensing.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
 * If applicable, add the following below this CDDL HEADER, with the
 * fields enclosed by brackets "[]" replaced with your own identifying
 * information: Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 */
/*
 * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
 * Use is subject to license terms.
 */

#ifndef _SYS_STACK_H
#define	_SYS_STACK_H

#pragma ident	"%Z%%M%	%I%	%E% SMI"

#if !defined(_ASM)

#include <sys/types.h>

#endif

#ifdef	__cplusplus
extern "C" {
#endif

/*
 * A stack frame looks like:
 *
 * %fp->|				|
 *	|-------------------------------|
 *	|  Locals, temps, saved floats	|
 *	|-------------------------------|
 *	|  outgoing parameters past 6	|
 *	|-------------------------------|-\
 *	|  6 words for callee to dump	| |
 *	|  register arguments		| |
 *	|-------------------------------|  > minimum stack frame
 *	|  One word struct-ret address	| |
 *	|-------------------------------| |
 *	|  16 words to save IN and	| |
 * %sp->|  LOCAL register on overflow	| |
 *	|-------------------------------|-/
 */

/*
 * Constants defining a 32-bit stack frame.
 */
#define	WINDOWSIZE32	(16*4)		/* size of window save area */
#define	ARGPUSHSIZE32	(6*4)		/* size of arg dump area */
#define	ARGPUSH32	(WINDOWSIZE32 + 4)	/* arg dump area offset */
#define	MINFRAME32	(WINDOWSIZE32 + ARGPUSHSIZE32 + 4) /* min frame */

#define	STACK_GROWTH_DOWN /* stacks grow from high to low addresses */

/*
 * Stack alignment macros.
 */
#define	STACK_ALIGN32		8
#define	STACK_ENTRY_ALIGN32	8
#define	SA32(X)			(((X)+(STACK_ALIGN32-1)) & ~(STACK_ALIGN32-1))

#if defined(__sparcv9)
/*
 * The 64-bit C ABI uses a stack frame that looks like:
 *
 *      |				|
 *	|-------------------------------|
 *	|  Locals, temps, saved floats	|
 *	|-------------------------------|
 *	|  outgoing parameters past 6	|
 *	|-------------------------------|-\
 *	|  outgoing parameters thru 6	| |
 *	|-------------------------------|  > minimum stack frame
 *	|  16 xwords to save IN and	| |
 *      |  LOCAL register on overflow	| |
 *	|-------------------------------|-/-\
 *      |				|   |
 *      |				|    > v9 abi bias
 *      |				|   |
 * %sp->|-------------------------------|---/
 */

/*
 * Constants defining a stack frame.
 */
#define	WINDOWSIZE64		(16*8)		/* size of window save area */
#define	ARGPUSHSIZE64		(6*8)		/* size of arg dump area */
#define	MINFRAME64		(WINDOWSIZE64 + 48)	/* min frame */
#define	ARGPUSH64		(WINDOWSIZE64)	/* arg dump area offset */
#define	V9BIAS64		(2048-1)	/* v9 abi stack bias */

#define	STACK_ALIGN64		16
#define	STACK_ENTRY_ALIGN64	16
#define	SA64(X)			(((X)+(STACK_ALIGN64-1)) & ~(STACK_ALIGN64-1))

#define	IS_V9STACK(x)		((((uintptr_t)(x) + V9BIAS64) & \
				(STACK_ALIGN64-1)) == 0)

#define	WINDOWSIZE		WINDOWSIZE64
#define	ARGPUSHSIZE		ARGPUSHSIZE64
#define	ARGPUSH			ARGPUSH64
#define	MINFRAME		MINFRAME64
#define	STACK_ALIGN		STACK_ALIGN64
#define	STACK_ENTRY_ALIGN	STACK_ENTRY_ALIGN64
#define	STACK_BIAS		V9BIAS64
#define	SA(x)			SA64(x)

#else

#define	WINDOWSIZE		WINDOWSIZE32
#define	ARGPUSHSIZE		ARGPUSHSIZE32
#define	ARGPUSH			ARGPUSH32
#define	MINFRAME		MINFRAME32
#define	STACK_ALIGN		STACK_ALIGN32
#define	STACK_ENTRY_ALIGN	STACK_ENTRY_ALIGN32
#define	STACK_BIAS		0
#define	SA(x)			SA32(x)
#define	STACK_V9BIAS64		(2048-1)	/* v9 abi stack bias */

#endif /* __sparcv9 */

#if defined(_KERNEL) && !defined(_ASM)

#if defined(DEBUG)
#if STACK_ALIGN == 8
#define	ASSERT_STACK_ALIGNED()						\
	{								\
		uint64_t __tmp;						\
		ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0);	\
	}
#elif (STACK_ALIGN == 16) && (_LONG_DOUBLE_ALIGNMENT == 16)
#define	ASSERT_STACK_ALIGNED()						\
	{								\
		long double __tmp;					\
		ASSERT((((uintptr_t)&__tmp) & (STACK_ALIGN - 1)) == 0);	\
	}
#endif
#else	/* DEBUG */
#define	ASSERT_STACK_ALIGNED()
#endif	/* DEBUG */

struct regs;

void flush_windows(void);
void flush_user_windows(void);
int  flush_user_windows_to_stack(caddr_t *);
void trash_user_windows(void);
void traceregs(struct regs *);
void traceback(caddr_t);

#endif	/* defined(_KERNEL) && !defined(_ASM) */

#ifdef	__cplusplus
}
#endif

#endif	/* _SYS_STACK_H */