/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* bos72D src/bos/kernel/sys/uthread.h 1.20.10.11                         */
/*                                                                        */
/* Licensed Materials - Property of IBM                                   */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 1993,2015              */
/* All Rights Reserved                                                    */
/*                                                                        */
/* US Government Users Restricted Rights - Use, duplication or            */
/* disclosure restricted by GSA ADP Schedule Contract with IBM Corp.      */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/* @(#)47       1.20.10.11  src/bos/kernel/sys/uthread.h, sysproc, bos72D, d2015_41A3 8/7/15 16:14:21 */
/*
 *   COMPONENT_NAME: SYSPROC
 *
 *   FUNCTIONS: none
 *
 *   ORIGINS: 27, 83
 *
 *
 */

/*
 * LEVEL 1,  5 Years Bull Confidential Information
 */


#ifndef _H_UTHREAD
#define _H_UTHREAD

/*
 *	The uthread structure is an extension of the user area or u-block.
 *	There is one allocated per thread, including kernel threads.
 *	It is protected to disallow any access to it by user-mode code.
 *
 *	The uthread contains information about the thread that
 *	is local to the thread and never referenced by other threads.
 *
 */

#include <sys/types.h>
#include <sys/mstsave.h>
#include <sys/timer.h>
#include <sys/ucontext.h>
#include <sys/param.h>
#include <sys/resource.h>
#include <sys/xmem.h>

#ifdef __cplusplus
extern "C" {
#endif

struct buf;
struct thrpgioframe;
struct thrpginfox;
struct tmm_handles_s;

/*
 * The ut_error field is an int.
 * This typedef is used inside the kernel to declare a pointer to an
 * error number.
 */
typedef int     ut_error_t;

#ifdef _KERNSYS
/* Structure for lightweight pool data.  Allocated by
 * lw_pool_alloc.
 */
struct lw_uthread {
	char*    ut_att_map;        /* pointer to bitmap of attachments*/
	esid_t   ut_pool_start;     /* first ESID in the pool */
        uint     ut_cursor;         /* index of next ESID in l-wt pool */ 
	uint     ut_att_count;      /* num ESIDs in pool with attaches */
};
#endif

/* Structure to define a per-thread user space region that needs to be
 * affinitized to the thread's home node.
 */
struct ut_aff_t {
	vmid_t ut_affin_sid;
	uintptr_t ut_affin_segoffset;
	size_t ut_affin_size;
};

#define MAX_UT_AFFIN 3 /* Maximum allowable number of ut_aff_t structures */

/* per-thread mapping information for Translator Memory Management.
 */
typedef struct ut_tmm_s 
{
	uintptr_t       ut_eaddr;   /* address mapped at, or 0         */
	union _ut_tmm_u
	{
		vmhandle_t      _ut_tmmvmh; /* 1 TB Window Handle      */
		struct tmm_handles_s *_ut_tmmh; /* ptr-up to 16 vmhand */
	} _u1;
} ut_tmm_t;

#define ut_tmmvmh       _u1._ut_tmmvmh
#define ut_tmmh         _u1._ut_tmmh

struct uthread {
#ifdef _KERNEL
	struct kmstsave	ut_save; 	/* machine state save area */
	/* Floating point state used to be in the mst, but it's not
	 * saved for interrupt handlers, so there's no need to reserve
	 * space for it on interrupt stacks.
	 */
        double          ut_fpr[NFPRS];  /* floating point registers     */
#else
	/* XXX - to be removed in 64bit kernel...and all ref to it */
	struct mstsave ut_save;
#endif /* _KERNEL */

	/* system call state .. ut_scsave[] must be aligned on 8 byte
	 * boundary. size of struct mstsave must be multiple of 8.
	 */
	ulong		ut_msr;		/* saved user msr */
	int		**ut_errnopp;	/* address of pointer to errno */
	char		*ut_sigsp;	/* special signal stack */
	ucontext_t	*ut_context;	/* user context to restore */
        size_t          ut_sigssz;      /* size of alternate signal stack */
	void		*ut_stkb;	/* current execution stack base */
	long		ut_scsave[8];	/* save area for system call handler */
	ut_error_t	ut_error;	/* return error code */
	int		ut_flags;	/* uthread flags */

	char		*ut_kstack;	/* own kernel stack */

	/* The thread may have VMX data or both VMX and VSX data. Because
	 * VSX is a superset of VMX, it is not possible to have VSX data
	 * without also having VMX data. Prior to 61H, VMX data, if present,
	 * was at the top of the kstack. Because we now may have VSX data
	 * between the kstack and VMX data, we have pointers to the
	 * corresponding regions. */

	char		*ut_vmxdata;	/* pointer to start of vmx data */
	char		*ut_vsxdata;	/* pointer to start of vsx data */
	struct auddata	*ut_audsvc;	/* auditing data */

	/* signal management */
	sigset_t	ut_oldmask;	/* mask from before sigpause */

	/* miscellaneous */
	uint		ut_fstid;	/* file system transaction ID */
	int		ut_ioctlrv;	/* return value for PSE ioctl's */
	void		*ut_selchn;	/* select control block */
	struct trb	*ut_timer[NTIMERS_THREAD]; /* thread timer array */
	struct uthread	*ut_link;	/* uthread blocks free list */
	void 		*ut_loginfo;	/* loginfo pointer */
	void            *ut_fselchn;    /* fast select control block   */
	ushort          ut_selbuc;      /* atomic queue bucket used in
					   select() */
	int		ut_code;	/* value for si_code from exception */

	void		*ut_jfscr;	/* pointer to jfs specific cruft */
	int		ut_fd;		/* fd # of file operation */
	short		ut_prsigno;     /* procfs si_signo */
	short           ut_prsicode;    /* procfs si_code */
	long            ut_prsiaddr;    /* procfs si_addr */
	unsigned long	ut_prsivalue;	/* procfs si_value for queued signal */
	long            ut_scargs[8];   /* procfs syscall arguments */
	struct _ut_sc {
		unsigned char	_sc_cancelable;	/* 1 if cancelable */
		unsigned char	_sc_flags;
#define UT_SC_FLAG_UTRCHOOK 0x80	/* Bit to indicate utrchook_sc */

		unsigned short	_sc_scnum;	/* syscall number */
#define UT_SC_WPAR_SYSCALL  0x00008000	/* Bit to indicate WPAR syscall. */
	} ut_sc;
#define ut_sc_cancelable	ut_sc._sc_cancelable
#define ut_sc_flags		ut_sc._sc_flags
#define ut_scnum		ut_sc._sc_scnum
#define UT_SET_CANCELABLE() \
	(curthread->t_uthreadp->ut_sc_cancelable = 1)
#define UT_SET_CANCELABLE_ut(_ut_) (_ut_->ut_sc_cancelable = 1)

	unsigned short	ut_ldr;		/* Used by debugging code in ldr */
	char            ut_prsigdlvr;   /* procfs PCSSIG delivery number */
	char		ut_pad2;
	rpn_t		ut_pgio_tail;	/* vmm nfr iotail (D_THRPGIO) */
        long		ut_chk_context; /* handler context */ 
	struct buf	*ut_pgio_bplist;/* bufs queued on thread (THRPGIO) */
	struct thrpginfox* ut_pgio_infop;/* thrpginfoxp of PDT */
        struct trusage64 ut_ru;         /* this thread resource usage value */
                                        /* If size of trusage64 changes,
                                         * padding needs to be adjust
                                         * accoringly. (currently 144 bytes)
                                         */
	struct xmem	ut_controlxm;	/* x-memory desc for control_word_t */

	ulong		ut_pgio_save[3];/* for v_thrpgio_setup() */
	void            *ut_pgio_contextp;
	struct thrpgioframe * ut_pgio_thrfp;

	struct lw_uthread *ut_lw_uthread; /* pointer to lweight pool data */
	uint		ut_lstpagex;	/* last async cli page to read ahead */

#define SLB_SAVE_BUFSIZE (8 + 44*16)
	char 		ut_slb_save[SLB_SAVE_BUFSIZE]; /* a count and 44 slbs */
	cpu_t		ut_corecpu;	/* CPU core dump exception on */

	char		*ut_frrstack;	/* address of rcovery stack*/
	ulong		ut_amr;		/* user mode storage key accesses */
	uint64_t	ut_wp_dabr;	/* watchpoint addr */
	uint64_t	ut_wp_value;	/* watched value */

	char		*ut_amrstack;	/* Start of AMR stack (highest addr) */
	struct ucred	*ut_crp;	/* pointer to process credential */
	long long	ut_sig_cfar;	/* Saved by signal processing */

	void		*ut_mcrt;	/* Used during checkpoint */
	void *		ut_bufx_desc;   /* bufx region description */
        uint            ut_hw_fru_id;   /* Processor ID saved (Part 1)     */
        uint            ut_hw_cpu_id;   /* Processor ID saved (Part 2)     */

	uint		ut_num_affin;	/* num thrd regions to affinitze */
        int             ut_clockread;
	struct ut_aff_t *ut_affin;	/* thrd regions to affinitze */
	uint		ut_crcnt;	/* reference count for ut_crp */ 
	uint		ut_mrc;		/* millicode reference count */
	int		ut_pad3;
	int             ut_capi_chan;   /* select channel for CAPI block/char 
					 * devices */

	void *		ut_tmm_exc_uaddr;  /* tmm exception structure uaddr */
#define UT_TMM_NUMWIN   3               /* 3 windows per thread mapped */
	ut_tmm_t        ut_tmm[UT_TMM_NUMWIN];  /* thread window mappings */
	char		*ut_tmdata; 	/* pointer to start of TM data area */
	uint64_t	ut_tm_fail_cnt; /* TM failures due to treclaim. */

	/* !!!IMPORTANT!!! - We are maxed out on this structure; do not extend
	 *		     any further until the next major release boundary.
	 */

#define UT_PADEND       0		/* amount of end padding */
#define UT_VCSIZE       128             /* uthread cache size boundary */
#if UT_PADEND
	char            ut_padend[UT_PADEND]; /* pad to UT_VCSIZE boundary */
#endif
};

#ifdef _KERNSYS

/*
 * Make sure that the thread structure size is cache-friendly.
 * If not, the following structure will cause a severe compilation error.
 */
struct uthreadsizevalidate{
	char		a[sizeof(struct uthread)% UT_VCSIZE ? -1 : 1];
};

/* number of full pages the uthread struct takes
 */
#define UT_PAGES ((sizeof(struct uthread)+PAGESIZE-1)/PAGESIZE)

#endif /* _KERNSYS */

#define ut_lw_pool_start ut_lw_uthread->ut_pool_start
#define ut_lw_cursor     ut_lw_uthread->ut_cursor
#define ut_lw_att_count  ut_lw_uthread->ut_att_count
#define ut_lw_att_map    ut_lw_uthread->ut_att_map

/*
 * uthread flags, ut_flags
 */

#define UTSTILLUSED	0x0001		/* albeit freed, entry still in use */
#define UTSIGONSTACK	0x0002		/* thread is on signal stack.  This */
					/* value was put into sc_onstack so */
					/* must keep the same value. */
#define UTNOULIMIT	0x0004		/* bypass ulimit check in kernel mode */
#define UTYIELD		0x0008		/* voluntarily relinquishing processor*/
#define UTSCSIG		0x0010		/* system call to sig_slih path taken */
#define UTSIGSUSP       0x0020          /* sigsuspend in effect */
#define UTASSERTSIG     0x0040          /* flag to e_block_thread */
#define UTINSIGHNDLR	0x0080		/* no Fast Watch across sig handlers */
#define UTLSLICING      0x0100          /* time slicing local thread now */
#define UT32BITFSOP     0x0200          /* 32 bit safe device operation */
#define UTCHKCALLED     0x0400          /* Running app. chkpt handler */
#define UTPROCFSVER     0x0800          /* Guarranty that user registers
                                         * saved on kernel stack through
                                         * /proc and SVC index saved 
                                         * in ut_scnum */
#define UTCHKWAKE	0x1000		/* checkpoint-restartable system call */
#define UTLCENABLE      0x2000          /* enable cancelation after ts */
#define UTISIG		0x4000		/* handling internal signal    */
#define UTISIGSC	0x8000		/* handling internal sig with context */
 
#define UAMRSTACKPINNED	0x10000		/* indicate that AMR stack is pinned */
#define UTPROBEV	0x20000		/* probevue thread */
#define UTMIGRATED	0x80000		/* thread has changed home node,
					 * uthread not yet migrated */
#ifdef __cplusplus
}
#endif

#endif /* _H_UTHREAD */
