/*
 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 *
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 *
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 *
 * @APPLE_LICENSE_HEADER_END@
 */
/*
 * Copyright (c) 1992 NeXT Computer, Inc.
 *
 * Intel386 Family:	Processor exception frame.
 *
 * HISTORY
 *
 * 31 August 1992 ? at NeXT
 *	Added v86 mode stuff.
 *
 * 8 June 1992 ? at NeXT
 *	Changed name of write field in err_code_t
 *	which collided with write() in shlib.
 *
 * 30 March 1992 ? at NeXT
 *	Created.
 */

#ifndef _ARCH_I386_FRAME_H_
#define _ARCH_I386_FRAME_H_

/*
 * Format of the error code
 * generated by the hardware
 * for certain exceptions.
 */

typedef union err_code {
    struct err_code_normal {
	unsigned int	ext	:1,
			tbl	:2,
#define ERR_GDT		0
#define ERR_IDT		1
#define ERR_LDT		2
			index	:13,
				:16;
    } normal;
    struct err_code_pgfault {
	unsigned int	prot	:1,
			wrtflt	:1,
			user	:1,
				:29;
    } pgfault;
} err_code_t;

#include <architecture/i386/sel.h>

/*
 * The actual hardware exception frame
 * is variable in size.  An error code is
 * only pushed for certain exceptions.
 * Previous stack information is only
 * pushed for exceptions that cause a
 * change in privilege level.  The dpl
 * field of the saved CS selector can be
 * used to determine whether this is the
 * case.  If the interrupted task was
 * executing in v86 mode, then the data
 * segment registers are also present in
 * the exception frame (in addition to
 * previous stack information).  This
 * case can be determined by examining
 * eflags.
 */

typedef struct except_frame {
    err_code_t		err;
    unsigned int	eip;
    sel_t		cs;
    unsigned int		:0;
    unsigned int	eflags;
    unsigned int	esp;
    sel_t		ss;
    unsigned int		:0;
    unsigned short	v_es;
    unsigned int		:0;
    unsigned short	v_ds;
    unsigned int		:0;
    unsigned short	v_fs;
    unsigned int		:0;
    unsigned short	v_gs;
    unsigned int		:0;
} except_frame_t;

/*
 * Values in eflags.
 */

#define EFL_CF		0x00001
#define EFL_PF		0x00004
#define EFL_AF		0x00010
#define EFL_ZF		0x00040
#define EFL_SF		0x00080
#define EFL_TF		0x00100
#define EFL_IF		0x00200
#define EFL_DF		0x00400
#define EFL_OF		0x00800
#define EFL_IOPL	0x03000
#define EFL_NT		0x04000
#define EFL_RF		0x10000
#define EFL_VM		0x20000
#define EFL_AC		0x40000

#define EFL_CLR		0xfff88028
#define EFL_SET		0x00000002

#endif	/* _ARCH_I386_FRAME_H_ */
