/*	Copyright (c) 1984, 1986, 1987, 1988 AT&T	*/
/*	  All Rights Reserved  	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any   	*/
/*	actual or intended publication of such source code.	*/

/*	Copyright (c) 1987, 1988 Microsoft Corporation	*/
/*	  All Rights Reserved	*/

/*	This Module contains Proprietary Information of Microsoft  */
/*	Corporation and should be treated as Confidential.	   */

#ident	"@(#)head.sys:user.h	1.5.1.7"

/*
 * The user structure.
 * One allocated per process.
 * Contains all per process data that doesn't need to be referenced
 * while the process is swapped.
 * The user block is p->p_usize*click bytes long; resides at virtual kernel
 * address 0xE0000000 for the 386;
 * contains the system stack per user for exec system call only;
 * is cross referenced with the proc structure for the same process.
 *
 ************************   NOTE  --  NOTE  ****************************
 *
 * 	WHEN THIS HEADER CHANGES, BOTH ml/misc.s AND ml/ttrap.s MUST BE
 *	   EXAMINED FOR ANY DEPENDENCIES UPON OFFSETS WITHIN THE UBLOCK.
 *	   IN PARTICULAR - .SET's ARE DONE ON:
 *				pr_base,
 *				pr_size,
 *				pr_off, and
 *				pr_scale
 *
 **********************************************************************
 * 
 */
 
#define PSARGSZ		80	/* Space in u-block for exec arguments */ 
				/* Used by ps command */

#define	PSCOMSIZ	DIRSIZ	/* For the time being set PSCOMSIZ */
				/* to DIRSIZ until we can get rid of */
				/* struct direct u_dent */

#define	SYSMASKLEN	4	/* Number of longs in syscall bit masks */

#define	KSTKSZ		3712

typedef	struct	user
{
	char	u_stack[KSTKSZ];/* kernel stack */
	char	u_stack_filler_1[2];
	/* floating point support variables */
	char    u_fpvalid;              /* flag if saved state is valid     */
	char    u_weitek;               /* flag if process uses weitek chip */
	union {
		struct  fpstate         /* floating point extension state   */
		{
			int     state[27];/* 287/387 saved state           */
			int     status;   /* status word saved at exception */
		} u_fpstate;
		struct	fp_emul
		{
			char	fp_emul[246];  /* (extras for emulator) */
			char	fp_epad[2];
		} fp_emul;
	} u_fps;
	long    u_weitek_reg[33];       /* bits needed to save weitek state */
					/* NOTE: If the WEITEK is actually  */
					/* present, only 32 longs will be   */
					/* used, but if it is not, the      */
					/* emulator will need 33.           */
	struct tss386 *u_tss;	/* pointer to user TSS */
	ushort	u_sztss;	/* size of tss (including bit map) */

	char	u_sigfault;	/* catch general protection violations
				   caused by user modifying his stack
				   where the old state info is kept */
	char	u_usigfailed;	/* allows the user to know that he caused
				   a general protection violation by
				   modifying his register save area used
				   when the user was allowed to do his own
				   signal processing */

	ulong	u_sub;		/* stack upper bound.
				   The address of the first byte of
				   the first page of user stack
				   allocated so far */
	char	u_filler1[40];	/* DON'T TOUCH--this is used by
				 * conditionally-compiled code in iget.c
				 * which checks consistency of inode locking
				 * and unlocking.  Name change to follow in
				 * a later release.
				 */
	
	int	u_caddrflt;	/* Ptr to function to handle	*/
				/* user space external memory	*/
				/* faults encountered in the	*/
				/* kernel.			*/

	char	u_nshmseg;	/* Nbr of shared memory		*/
				/* currently attached to the	*/
				/* process.			*/

 	struct rem_ids {		/* for exec'ing REMOTE text */
 		ushort	ux_uid;		/* uid of exec'd file */
 		ushort	ux_gid;		/* group of exec'd file */
 		ushort	ux_mode;	/* file mode (set uid, etc. */
 	} u_exfile;
	char	*u_comp;	/* pointer to current component */
	char	*u_nextcp;	/* pointer to beginning of next */
					/* following for Distributed UNIX */
	ushort 		u_rflags;	/* flags for distripution */
	int	u_sysabort;	/* Debugging: if set, abort syscall */
	int	u_systrap;	/* Are any syscall mask bits set? */ 
	int 		u_syscall;	/* system call number */
	int		u_mntindx;	/* mount index from sysid */
	struct sndd	*u_gift;	/* gift from message      */
	long 	u_rcstat; 	/* Client cache status flags */
	ulong	u_userstack;
	struct response	*u_copymsg;	/* copyout unfinished business */
	struct msgb	*u_copybp;	/* copyin premeditated send    */
	char 		*u_msgend;	/* last byte of copymsg + 1    */
					/* end of Distributed UNIX */
	
	long	u_bsize;		/* block size of device */
	char 	u_psargs[PSARGSZ];	/* arguments from exec */	

	int	u_pgproc;	/* use by the MAU driver */
	time_t	u_ageinterval;	/* pageing ageing countdown counter */
	label_t	u_qsav;		/* label variable for quits and	*/
				/* interrupts			*/

	char	u_segflg;	/* IO flag: 0:user D; 1:system;	*/
				/*          2:user I		*/

	unchar	u_error;	/* return error code */

	ushort	u_uid;		/* effective user id */
	ushort	u_gid;		/* effective group id */
	ushort	u_ruid;		/* real user id */
	ushort	u_rgid;		/* real group id */

	struct proc *u_procp;	/* pointer to proc structure */

	int	*u_ap;		/* pointer to arglist */

	union {			/* syscall return values */
		struct	{
			int	r_val1;
			int	r_val2;
		}r_reg;
		off_t	r_off;
		time_t	r_time;
	} u_r;

	caddr_t	u_base;		/* base address for IO */
	unsigned u_count;	/* bytes remaining for IO */
	off_t	u_offset;	/* offset in file for IO */
	short	u_fmode;	/* file mode for IO */
	ushort	u_pbsize;	/* Bytes in block for IO */
	ushort	u_pboff;	/* offset in block for IO */
	dev_t	u_pbdev;	/* real device for IO */
	daddr_t	u_rablock;	/* read ahead block address */
	short	u_errcnt;	/* syscall error count */

	struct inode *u_cdir;	/* current directory */

	struct inode *u_rdir;	/* root directory */
	caddr_t	u_dirp;		/* pathname pointer */
	struct direct u_dent;	/* current directory entry */
	struct inode *u_pdir;	/* inode of parent directory	*/
				/* of dirp			*/


	char	*u_pofile;	/* Ptr to open file flag array.	 */

	struct inode *u_ttyip;	/* inode of controlling tty (streams) */

	int	u_arg[6];	/* arguments to current system call */

	unsigned u_tsize;	/* text size (clicks) */
	unsigned u_dsize;	/* data size (clicks) */
	unsigned u_ssize;	/* stack size (clicks) */

	void (*u_signal[MAXSIG])();	/* disposition of signals */
	void (*u_sigreturn)();		/* for cleanup */

	time_t	u_utime;	/* this process user time */
	time_t	u_stime;	/* this process system time */
	time_t	u_cutime;	/* sum of childs' utimes */
	time_t	u_cstime;	/* sum of childs' stimes */

	int	*u_ar0;		/* address of users saved R0 */

/*
 *    The offsets of these elements must be reflected in ttrap.s and misc.s
 */

	struct {			/* profile arguments */
		short	*pr_base;	/* buffer base */
		unsigned pr_size;	/* buffer size */
		unsigned pr_off;	/* pc offset */
		unsigned pr_scale;	/* pc scaling */
	} u_prof;

	short  *u_ttyp;			/* pointer to pgrp in "tty" struct */
	dev_t	u_ttyd;			/* controlling tty dev */

	ulong	u_renv;			/* runtime environment. 	  */
					/*   for meaning of bits:	  */
					/*     0-15  see x_renv (x.out.h) */
					/*    16-23  see x_cpu  (x.out.h) */
					/*    24-31  see below		  */
	/*
	 * Executable file info.
	 */
	struct exdata {
			struct    inode  *ip;
			long      ux_tsize;	/* text size    */
			long      ux_dsize;	/* data size    */
			long      ux_bsize;	/* bss size     */
			long      ux_lsize;  	/* lib size     */
			long      ux_nshlibs; 	/* number of shared libs needed */
			short     ux_mag;   	/* magic number MUST be here */
			long      ux_toffset;	/* file offset to raw text      */
			long      ux_doffset;	/* file offset to raw data      */
			long      ux_loffset;	/* file offset to lib sctn      */
			long      ux_txtorg;	/* start addr. of text in mem   */
			long      ux_datorg;	/* start addr. of data in mem   */
			long      ux_entloc;	/* entry location               */
			ulong	  ux_renv;	/* runtime environment */
	} u_exdata;

	long   u_execsz;

	char	u_comm[PSCOMSIZ];

	time_t	u_start;
	time_t	u_ticks;
	long	u_mem;
	long	u_ior;
	long	u_iow;
	long	u_iosw;
	long	u_ioch;
	char	u_acflag;

	short	u_cmask;		/* mask for file creation */
	daddr_t	u_limit;		/* maximum write address */

	short	u_lock;			/* process/text locking flags */

	/* floating point support variables */
	char    u_fpvalid_filler;              /* flag if saved state is valid     */
	char    u_weitek_filler;               /* flag if process uses weitek chip */
	union {
		struct  fpstate_filler         /* floating point extension state   */
		{
			int     state[27];/* 287/387 saved state           */
			int     status;   /* status word saved at exception */
		} u_fpstate_filler;
		struct	fp_emul_filler
		{
			char	fp_emul[246];  /* (extras for emulator) */
			char	fp_epad[2];
		} fp_emul_filler;
	} u_fps_filler;
	long    u_weitek_reg_filler[33];       /* bits needed to save weitek state */
					/* NOTE: If the WEITEK is actually  */
					/* present, only 32 longs will be   */
					/* used, but if it is not, the      */
					/* emulator will need 33.           */
	int     u_fpintgate[2];         /* fp intr gate descriptor image   */

#define	WEITEK_CONTEXT	0
#define	WEITEK_CAE	0xFFFFFF00	/* clear accum. exception byte	*/

	/* i286 emulation variables */
	int    *u_callgatep;            /* pointer to call gate in gdt  */
	int     u_callgate[2];          /* call gate descriptor image   */
	int     u_ldtmodified;          /* if set, LDT was modified     */
	ushort	u_ldtlimit;		/* current size (index) of ldt */

	/* Flag single-step of lcall for a system call. */
	/* The signal is delivered after the system call*/
	char    u_debugpend;            /* SIGTRAP pending for this proc */

	/* debug registers, accessible by ptrace(2) but monitored by kernel */
	char    u_debugon;              /* Debug registers in use, set by kernel */
	int     u_debugreg[8];
	long	u_entrymask[SYSMASKLEN]; /* syscall stop-on-entry mask */
	long	u_exitmask[SYSMASKLEN];	/* syscall stop-on-exit mask */

	struct file	*u_ofile[1];	/* Start of array of pointers	*/
					/* to file table entries for	*/
					/* open files.			*/
} user_t;

extern struct user u;

#define u_exuid u_exfile.ux_uid
#define u_exgid u_exfile.ux_gid
#define u_exmode u_exfile.ux_mode

#define	u_rval1	u_r.r_reg.r_val1
#define	u_rval2	u_r.r_reg.r_val2
#define	u_roff	u_r.r_off
#define	u_rtime	u_r.r_time

/* rcstat values: for client caching */

#define	U_RCACHE	0x1

/* ioflag values: Read/Write, User/Kernel, Ins/Data */

#define	U_WUD	0
#define	U_RUD	1
#define	U_WKD	2
#define	U_RKD	3

#define	EXCLOSE	01

/* distribution: values for u_rflags */
#define FREMOTE	0x0002	/* file is remote  */

#define	U_RSYS		0x0004	/* system call has gone remote */
#define	U_DOTDOT	0x0200
#define U_RCOPY		0x0400	/* used by copyout for non-delay copy */

/* u_spop values */
#define U_SPOP_MAU	0x1L

/*
 * defines for bits 24-31 of u_renv and various macros for accessing
 * fields of u_renv.  All bits not currently defined are reserved
 * for future expansion.
 */
#define U_ISCOFF	0x1000000
#define	U_RENVMASK	0x3000000	/* runtime environment bits */

#define	U_CPUTYPE	(XC_CPU << 16)
#define	U_IS386		(XC_386 << 16)
#define	U_ISWSWAP	(XC_WSWAP << 16)

/* binary types */
#define	isCOFF		((u.u_renv & U_RENVMASK) == U_ISCOFF)	/* 386 COFF */
#define	isXOUT		((u.u_renv & U_RENVMASK) == 0)		/* 386 x.out */

#define	IS386()		(((u.u_renv >> 16) & XC_CPU) == XC_386)

/*
 * The following define is used to indicate that the program being
 * exec'd is one of the 286 emulators.  This bit is set in u_renv.
 */
#define	UE_EMUL		0x4000000	/* 286 emulator */
#define	is286EMUL	((u.u_renv & UE_EMUL) == UE_EMUL)

/*
 * Defines for badvise bits of u_renv and various macros for accessing
 * these bits.  
 */

#define UB_PRE_SV	0x8000000	/* badvise pre-System V */
#define UB_XOUT		0x10000000	/* badvise x.out */
#define UB_LOCKING	0x20000000	/* badvise locking() system call  */
					/*      (for kernel use only)     */
#define UB_FCNTL	0x40000000	/* badvise fcntl() system call    */
					/*      (for kernel use only)     */
#define UB_XSDSWTCH	0x80000000	/* badvise XENIX shared data context */
					/*	switching		     */

				/* badvise indicates x.out behavior */
#define BADVISE_XOUT	((u.u_renv & UB_XOUT) == UB_XOUT)

				/* badvise indicates pre-System V behavior */
#define BADVISE_PRE_SV	((u.u_renv & UB_PRE_SV) == UB_PRE_SV)
				/* badvise indicates XENIX locking() call */
#define ISLOCKING	((u.u_renv & UB_LOCKING) == UB_LOCKING)
				/* badvise indicates fcntl() call */
#define ISFCNTL		((u.u_renv & UB_FCNTL) == UB_FCNTL)
				/* badvise indicates XENIX shared data
				 * 	context switching is enabled
				 */
#define BADVISE_XSDSWTCH ((u.u_renv & UB_XSDSWTCH) == UB_XSDSWTCH)
				/* x.out binary or badvise indicates x.out */
#define VIRTUAL_XOUT	(isXOUT || BADVISE_XOUT)

/* flag values for NFA */
#define NFA_SERVER	0x4000	/* the NFA network server */
#define NFA_CASELESS	0x8000	/* caseless support for DOS */


/* Floating point relocation macros. Changes to floating point stuff in the
 * uarea may need changes to these macros also. Before changing uarea floating
 * point stuff revise these macros for possible changes.
 */

#define	ublk_offset(X)		((X) - (char *) &u)
/* From now on assume: X -- an offset within the ublock, e.g,. during ptrace().
 * N.B. During ptrace() only 1 word is read or written to the ublock - hence do
 * not have to worry about cases where portions of read and write falls within
 * the section being relocated.
 */
#define	old_fp_start		(&u.u_fpvalid_filler)
#define	old_fp_end		(&u.u_fpintgate[0])
#define	old_fp_offset(X)	((X) - (char *)ublk_offset(old_fp_start))
#define	fp_reloc_start		ublk_offset(&u.u_fpvalid)
#define	need_fp_reloc(X)	(((X) >= (char *)ublk_offset(old_fp_start)) \
				&& ((X) < (char *)ublk_offset((char *)old_fp_end)))
#define	reloc_fp(X)		((char *)fp_reloc_start + old_fp_offset(X))
