/* rcsid[]="$Header: user.h,v 820.1 86/12/04 19:49:38 root Exp $" */
/* sccsid[]="%W% %Y% %Q% %G%" */

/************************************************************************
*									*
*				Copyright 1984				*
*			VALID LOGIC SYSTEMS INCORPORATED		*
*									*
*	This listing contains confidential proprietary information	*
*	which is not to be disclosed to unauthorized persons without	*
*	written consent of an officer of Valid Logic Systems 		*
*	Incorporated.							*
*									*
*	The copyright notice appearing above is included to provide	*
*	statutory protection in the event of unauthorized or 		*
*	unintentional public disclosure.				*
*									*
************************************************************************/

/*	user.h	6.1	83/07/29	*/

#ifdef KERNEL
#include "../machine/pcb.h"
#include "../h/dmap.h"
#include "../h/time.h"
#include "../h/resource.h"
#include "../h/signal.h"
#ifdef	M68881
#include "../s32/fpu68881.h"
#endif	M68881
#ifdef	QUOTA
#include "../h/quota.h"
#endif	QUOTA
#include "../h/inode.h"
#include "../h/file.h"
#include "../h/fs.h"
#include "../h/tty.h"
#include "../h/dir.h"

#else	KERNEL
#include <machine/pcb.h>
#include <sys/dmap.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/signal.h>
#ifdef	M68881
#include <s32/fpu68881.h>
#endif	M68881
#ifdef	QUOTA
#include <sys/quota.h>
#endif	QUOTA
#include <sys/inode.h>
#include <sys/file.h>
#include <sys/fs.h>
#include <sys/tty.h>
#include <sys/dir.h>
#endif	KERNEL

/*
 * Per process structure containing data that
 * isn't needed in core when the process is swapped out.
 */
 
#define	SHSIZE		32
#define	MAXCOMLEN	16		/* <= MAXNAMLEN, >= sizeof(a_comm) */
 
struct	user {
	struct	pcb u_pcb;
	struct	proc *u_procp;		/* pointer to proc structure */
	int	*u_ar0;			/* address of users saved R0 */
	char	u_comm[MAXNAMLEN + 1];

/* syscall parameters, results and catches */
	int	u_arg[8];		/* arguments to current system call */
	int	*u_ap;			/* pointer to arglist */
	label_t	u_qsave;		/* for non-local gotos on interrupts */
	char	u_error;		/* return error code */
	union {				/* syscall return values */
		struct	{
			int	R_val1;
			int	R_val2;
		} u_rv;
#define	r_val1	u_rv.R_val1
#define	r_val2	u_rv.R_val2
		off_t	r_off;
		time_t	r_time;
	} u_r;
	char	u_eosys;		/* special action on end of syscall */

/* 1.1 - processes and protection */
	short	u_uid;			/* effective user id */
	short	u_gid;			/* effective group id */
	int	u_groups[NGROUPS];	/* groups, 0 terminated */
	short	u_ruid;			/* real user id */
	short	u_rgid;			/* real group id */

/* 1.2 - memory management */
	size_t	u_tsize;		/* text size (clicks) */
#ifdef s32
					/* u_tsize represents a whole number
					   of segments (x_size is the actual
					   number of clicks) */
#endif s32
	size_t	u_dsize;		/* data size (clicks) */
	size_t	u_ssize;		/* stack size (clicks) */
	struct	dmap u_dmap;		/* disk map for data segment */
	struct	dmap u_smap;		/* disk map for stack segment */
	struct	dmap u_cdmap, u_csmap;	/* shadows of u_dmap, u_smap, for
					   use of parent during fork */
	label_t u_ssave;		/* label variable for swapping */
	size_t	u_odsize, u_ossize;	/* for (clumsy) expansion swaps */
	time_t	u_outime;		/* user time at last sample */

/* 1.3 - signal management */
	int	(*u_signal[NSIG])();	/* disposition of signals */
	int	u_sigmask[NSIG];	/* signals to be blocked */
	int	u_sigonstack;		/* signals to take on sigstack */
	int	u_oldmask;		/* saved mask from before sigpause */
	int	u_code;			/* ``code'' to trap */
	struct	sigstack u_sigstack;	/* sp & on stack state variable */
#define	u_onstack	u_sigstack.ss_onstack
#define	u_sigsp		u_sigstack.ss_sp

/* 1.4 - descriptor management */
	struct	file *u_ofile[NOFILE];	/* file structures for open files */
	char	u_pofile[NOFILE];	/* per-process flags of open files */
#define	UF_EXCLOSE 	0x1		/* auto-close on exec */
#define	UF_MAPPED 	0x2		/* mapped from device */
	struct	inode *u_cdir;		/* current directory */
	struct	inode *u_rdir;		/* root directory of current process */
	struct	tty *u_ttyp;		/* controlling tty pointer */
	dev_t	u_ttyd;			/* controlling tty dev */
	short	u_cmask;		/* mask for file creation */

/* 1.5 - timing and statistics */
	struct	rusage u_ru;		/* stats for this proc */
	struct	rusage u_cru;		/* sum of stats for reaped children */
	struct	itimerval u_timer[3];
	int	u_XXX[3];
	time_t	u_start;
	short	u_acflag;

/* 1.6 - resource controls */
	struct	rlimit u_rlimit[RLIM_NLIMITS];
#ifdef	QUOTA
	struct	quota *u_quota;		/* user's quota structure */
	int	u_qflags;		/* per process quota flags */
#endif	QUOTA

/* BEGIN TRASH */
	char	u_segflg;		/* 0:user D; 1:system; 2:user I */
	caddr_t	u_base;			/* base address for IO */
	unsigned int u_count;		/* bytes remaining for IO */
	off_t	u_offset;		/* offset in file for IO */
	union {
	   struct {			/* header of executable file */
		int	Ux_mag;		/* magic number */
		unsigned Ux_tsize;	/* text size */
		unsigned Ux_dsize;	/* data size */
		unsigned Ux_bsize;	/* bss size */
		unsigned Ux_ssize;	/* symbol table size */
		unsigned Ux_entloc;	/* entry location */
		unsigned Ux_unused;
		unsigned Ux_relflg;
	   } Ux_A;
	   char ux_shell[SHSIZE];	/* #! and name of interpreter */
	} u_exdata;
#define	ux_mag		Ux_A.Ux_mag
#define	ux_tsize	Ux_A.Ux_tsize
#define	ux_dsize	Ux_A.Ux_dsize
#define	ux_bsize	Ux_A.Ux_bsize
#define	ux_ssize	Ux_A.Ux_ssize
#define	ux_entloc	Ux_A.Ux_entloc
#define	ux_unused	Ux_A.Ux_unused
#define	ux_relflg	Ux_A.Ux_relflg
	caddr_t	u_dirp;			/* pathname pointer */
	struct	direct u_dent;		/* current directory entry */
	struct	inode *u_pdir;		/* inode of parent directory of dirp */
/* END TRASH */
	struct uprof {			/* profile arguments */
		short	*pr_base;	/* buffer base */
		unsigned pr_size;	/* buffer size */
		unsigned pr_off;	/* pc offset */
		unsigned pr_scale;	/* pc scaling */
	} u_prof;

#ifdef s32
	struct	exceptionInfo_t {	/* Exception-related information */
#if	defined(M68000) || defined(M68010) || defined(M68020)
		/*
		 * Common to all members of the M68000 family
		 * of microprocessor CPUs.
		 */
		u_short U_ssr;		/* System Status Register (ps)	      */
		u_long	U_aAddr;	/* Access Address on bus errors	      */
		u_short	U_iReg;		/* Instruction Register on bus errors */
#define	u_ssr	exceptionInfo.U_ssr
#define	u_aAddr	exceptionInfo.U_aAddr
#define	u_iReg	exceptionInfo.U_iReg
#endif	defined(M68000) || defined(M68010) || defined(M68020)
#ifdef	M68000
		/*
		 * Only in the M68000/M68008
		 */
		u_short	U_fCode;	/* Function Code on bus errors	      */
#define	u_fCode	exceptionInfo.U_fCode
#endif	M68000

#if	defined(M68010)  && !defined(M68020)
		/*
		 * Different in the M68010 & M68020
		 */
		u_short U_diBuf;	/* Data  input buffer */
		u_short U_doBuf;	/* Data output buffer */
#define	u_diBuf	exceptionInfo.U_diBuf
#define	u_doBuf	exceptionInfo.U_doBuf
#endif	defined(M68010)  && !defined(M68020)

#if	defined(M68010) || defined(M68020)
		/*
		 * Common to both M68010 and M68020
		 */
		u_short	U_effn;		/* Exception frame fmt # */
		u_short	U_ssw;
#define	u_effn	exceptionInfo.U_effn
#define	u_ssw	exceptionInfo.U_ssw
#endif	defined(M68010) || defined(M68020)

#ifdef	M68020
		/*
		 * Found only in the M68020:
		 * More extensive pipeline info,
		 * and larger data buffers.
		 */
		u_short	U_iRegB;	/* Stage B instruction pipe   */
		u_short	U_iRegC;	/* Stage C instruction pipe   */
		u_long	U_aAddrB;	/* "B" inst-stream addr error */
		u_long	U_aAddrC;	/* "C" inst-stream addr error */
		u_long	U_diBuf;	/* Data  input buffer	      */
		u_long	U_doBuf;	/* Data output buffer	      */
#define	u_iRegB	 exceptionInfo.U_iRegB
#define	u_iRegC	 exceptionInfo.U_iRegC
#define	u_aAddrB exceptionInfo.U_aAddrB
#define	u_aAddrC exceptionInfo.U_aAddrC
#define	u_diBuf	 exceptionInfo.U_diBuf
#define	u_doBuf	 exceptionInfo.U_doBuf

#endif	M68020
	} exceptionInfo;

	u_long	u_fpsav[8];		/* floating point registers */
	u_long	u_vmvec[64];		/* vectors for virtual machine */
	u_short	u_usrtop;		/* page number of top of stack */
	u_short	u_fppc;			/* floating point pc */
	caddr_t	u_sighandler;		/* generic signal handler */
	u_short	u_xxspare[12];		/* reserved space */
#endif s32

#ifdef	M68881
	/*
	 * Motorola MC68881 Floating Point Co-Processor support.
	 * FPU present only with the REV_B M68020 and later cpu board sets.
	 *
	 * Savearea for:
	 *	a) 8 32-bit FPU data    registers;
	 *	b) 3 32-bit FPU control registers;	C.f., ../s32/reg.h
	 *	c) Maximum of 0xb8 bytes worth of FPU system internals;
	 *		NULL:	0x04 bytes of system state frame;
	 *		IDLE:	0x1c bytes;
	 *		BUSY:	0xB8 bytes.
	 */
	fpu68881DataReg_t	U_fpu68881DataRegs[8];	/* FPU Data Regs     */
#define	u_FPDR			U_fpu68881DataRegs
#define	u_fpu68881_signBit	U_fpu68881DataRegs.fpu_signBit_B
#define	u_fpu68881_exponent	U_fpu68881DataRegs.fpu_exponent_B
#define	u_fpu68881_mantissa	U_fpu68881DataRegs.fpu_mantissa_B

	fpu68881CntlReg_t	u_fpu68881CntlReg;	/* FPU Control Reg   */
#define	u_FPCR			u_fpu68881CntlReg

	fpu68881StatReg_t	u_fpu68881StatReg;	/* FPU Status Reg    */
#define	u_FPSR			u_fpu68881StatReg

	fpu68881AddrReg_t	u_fpu68881AddrReg;	/* Instruction Addr. */
#define	u_FPIAR			u_fpu68881AddrReg

	caddr_t			u_fpssfp;		/* Start of u_FPSSF  */
	fpu68881SysStateFrame_t	u_fpu68881SystemStateFrame;	/* Sys Info  */
#define	u_FPSSF			u_fpu68881SystemStateFrame
#define	u_FPSSFp		u_fpssfp
#endif	M68881

#ifndef	M68020_REV_B
	int	u_stack[1];		/* Absolute bottom of user stack*/
#else	M68020_REV_B

	/*
	 * The VIRTUAL address space for a process can have
	 * a covering set of segments that is larger than NSMAPS,
	 * the covering set of segments that map the maximum amount
	 * of PHYSICAL memory possible in the h/w.
	 * Therefore, we need a (LRU management) scheme
	 * to map the larger set of virtual segments
	 * onto the smaller set of physical segments.
	 *
	 * 'u_smaps' is a array whose size is that of the number
	 * of segments that would completely cover the VIRTUAL address space
	 * of the process, and which contains a linear (LRU-ordered) list
	 * of smaps whose cardinality <= NSMAPS,
	 * which maps the PHYSICAL address space.
	 *
	 * Recall that we really need a linear list whose length is less than
	 * or equal to 'ptos(maxpage+1-kvarea)' smaps
	 * to map the user process, more or less exclusive of kernal areas.
	 *
	 * The balance of 'u_smaps' reflects whether a particular smap
	 * is a bonifide member of the current virtual address space allocations
	 * which manifest the process:
	 *
	 *	 NOSMAP==0	 ==> non-membership;
	 *	~NOSMAP==(-1)	 ==>     membership;
	 *
	 * Obviously NOSMAP must be chosen with care to be compatible
	 * with the linear list with which it must coexist.
	 * 
	 * To facilitate matters, we maintain head and tail indices
	 * into the (LRU-ordered) linear list of physical smaps.
	 */
	smap_t	u_smapLRU_HEAD;		/* Head of the LRU list		      */
	smap_t	u_smapLRU_TAIL;		/* Tail of the LRU list		      */
	int	u_vSmapsInUse;		/* # of virt smaps in use	      */
	int	u_hndlrState;		/* Set in busaddr(); Reset in sureg() */

	/*
	 * System call and kernel stack.
	 * 'u_stack[0]' is the bottom of the stack.
	 * The size should be AT LEAST one full page.
	 * The final consideration is that 'u_smaps'
	 * should be page-aligned
	 */
	int	u_stack[1];		/* Absolute bottom of user stack*/

#endif	M68020_REV_B
};

/* u_eosys values */
#define	JUSTRETURN	0
#define	RESTARTSYS	1
#define	SIMULATERTI	2
#define	REALLYRETURN	3

/* u_error codes */
#ifdef KERNEL
#include "../h/errno.h"
#else
#include <errno.h>
#endif

#ifdef KERNEL
extern	struct user u;
extern	struct user swaputl;
extern	struct user forkutl;
extern	struct user xswaputl;
extern	struct user xswap2utl;
extern	struct user pushutl;
extern	struct user vfutl;
#endif
