/*static char *SCCSID = "@(#)pglocal.h  6.8 92/03/15";*/

/*
 *	IBM/Microsoft Confidential
 *
 *	Copyright (c) IBM Corporation 1987, 1989
 *	Copyright (c) Microsoft Corporation 1987, 1989
 *
 *	All Rights Reserved
 */


/*
 * Private page manager definitions.
 */

#define CPAGETCBSKIP	8	/* Pages to skip address CurrTCB in KStack */
#define CPAGETSDSKIP	4	/* Pages to skip address CurrTSD in KStack */
#define PGMAXLOOKAHEAD	50	/* max number of idle pfs to search thru */

/***LT+ pte_s - page table entry structure (4 bytes per linear page) */
/* bit fields are allocated low to high */
struct _ppte_s {	/* present and common pte fields */
    unsigned long pu_present:1,     /* set if present */
		  pu_ring3write:1,  /* set if ring 3 writeable */
		  pu_ring3access:1, /* set if ring 3 accessible */
		  pu_writethrough:1,	/* write-through cache (486 ignores) */
		  pu_cachedisable:1,	/* cache disable */
		  pu_accessed:1,    /* set by H.W. when accessed */
		  pu_dirty:1,	    /* set by H.W. when written */
		  pu_res:2,	    /* must be 0 when present */
		  pu_uvirt:1,	    /* set if uvirt */
		  pu_resident:1,    /* set if not swappable or discardable */
		  pu_reserved:1,    /* available for use */
		  pu_frame:20;	    /* physical page frame */
};
struct _lpte_s {	/* to treat pte as a long */
    unsigned long lpu_long;
};
union _pte_u {
    struct _ppte_s ppte_s;
    struct _lpte_s lpte_s;
};
struct pte_s {
    union _pte_u pte_u;
};
#define pt_present	pte_u.ppte_s.pu_present
#define pt_ring3write	pte_u.ppte_s.pu_ring3write
#define pt_ring3access	pte_u.ppte_s.pu_ring3access
#define pt_writethrough pte_u.ppte_s.pu_writethrough
#define pt_cachedisable pte_u.ppte_s.pu_cachedisable
#define pt_accessed	pte_u.ppte_s.pu_accessed
#define pt_dirty	pte_u.ppte_s.pu_dirty
#define pt_res		pte_u.ppte_s.pu_res
#define pt_uvirt	pte_u.ppte_s.pu_uvirt
#define pt_resident	pte_u.ppte_s.pu_resident
#define pt_frame	pte_u.ppte_s.pu_frame

#define pt_npguard	pt_dirty		  /* np guard page indicator */
#define pt_npswapid	pt_frame		  /* np swapid */
#define pt_npblockno	pt_frame		  /* np block number */

#define pt_long 	pte_u.lpte_s.lpu_long	  /* to access pte as a long */


/* Bit masks for Page Table Entries */
#define PT_PRESENT	0x00000001
#define PT_RING3WRITE	0x00000002
#define PT_RING3ACCESS	0x00000004
#define PT_WRITETHROUGH 0x00000008
#define PT_CACHEDISABLE 0x00000010
#define PT_ACCESSED	0x00000020
#define PT_DIRTY	0x00000040
#define PT_RES		0x00000180  /* 2 bits	   PT_NPSEM */
#define PT_UVIRT	0x00000200
#define PT_RESIDENT	0x00000400
#define PT_STATE	0x00000e00  /* 3 bits */
#define PT_FRAME	0xfffff000  /* 20 bits	   PT_NPSWAPID, PT_NPBLOCKNO */

#define PT_NPGUARD	PT_DIRTY

/* useful pte shift counts */
#define PT_FRAMESHIFT		12		/* pt_frame */

/* useful pte increments */
#define PT_FRAMEINCR		(1 << PT_FRAMESHIFT)
/*end*/

/***LT+ vp_s - virtual page structure (10 bytes per committed page) */
struct _avp_s { 			/* active vp */
    unsigned long  avp_busy:1,		/* page semaphore taken */
		   avp_wanted:1,	/* page semaphore requested */
		   avp_cache:1, 	/* search page cache for frame */
		   avp_pfidle:1,	/* cross linked to idle pf */
		   avp_pf:1,		/* cross linked to a pf */
		   avp_df:1,		/* has swap file disk frame */
		   avp_dirty:1, 	/* page contents have been written to */
		   avp_shdirty:1,	/* shadow dirty bit (for VDMs) */
		   avp_sow:1,		/* change to swappable on write */
		   avp_res:1,		/* unused */
		   avp_resident:1,	/* cannot be moved or paged */
		   avp_discardable:1,	/* 1 = discardable, 0 = swappable */
		   avp_frame:20;	/* frame, swp or ldr block # */
    unsigned short avp_obpg;		/* object relative page number */
    unsigned short avp_hob;		/* handle to object record */
    unsigned short avp_refcount;	/* virtual page reference count */
};
struct _nvp_s { 			/* active vp w/o enumerated flags */
    unsigned long  nvp_flags:12,	/* flags */
		   nvp_pad1:20; 	/* pad */
    unsigned long  nvp_pad2;		/* pad */
    unsigned short nvp_pad3;		/* pad */
};
struct _fvp_s { 			/* free vp */
    struct vp_s *  fvp_flink;		/* forward link */
    struct vp_s *  fvp_blink;		/* backward link */
    unsigned short fvp_pad;		/* pad */
};
union _vp_u {
    struct _avp_s avp_s;		/* active vp */
    struct _nvp_s nvp_s;		/* active vp w/o bit flags */
    struct _fvp_s fvp_s;		/* free vp */
};
#ifdef	PGSTRICT
struct vp_s {
    union  _vp_u vp_u;
    unsigned short	vp_semowner;	/* slot number of semaphore owner */
};
#else
struct vp_s {
    union  _vp_u vp_u;
};
#endif

#define vp_frame	vp_u.avp_s.avp_frame
#define vp_block	vp_frame
#define vp_obpg 	vp_u.avp_s.avp_obpg
#define vp_hob		vp_u.avp_s.avp_hob
#define vp_refcount	vp_u.avp_s.avp_refcount
#define vp_flink	vp_u.fvp_s.fvp_flink
#define vp_blink	vp_u.fvp_s.fvp_blink
#define vp_flags	vp_u.nvp_s.nvp_flags
#define vp_discardable	vp_u.avp_s.avp_discardable
#define vp_sow		vp_u.avp_s.avp_sow
#define vp_resident	vp_u.avp_s.avp_resident
#define vp_cache	vp_u.avp_s.avp_cache
#define vp_busy 	vp_u.avp_s.avp_busy
#define vp_wanted	vp_u.avp_s.avp_wanted
#define vp_dirty	vp_u.avp_s.avp_dirty
#define vp_shdirty	vp_u.avp_s.avp_shdirty
#define vp_pfidle	vp_u.avp_s.avp_pfidle
#define vp_pf		vp_u.avp_s.avp_pf
#define vp_df		vp_u.avp_s.avp_df

/* vp flags, bit masks */
#define VP_BUSY 	0x001		/* page semaphore taken */
#define VP_WANTED	0x002		/* page semaphore requested */
#define VP_CACHE	0x004		/* search page cache for pf */
#define VP_PFIDLE	0x008		/* cross linked to idle pf */
#define VP_PF		0x010		/* cross linked to pf */
#define VP_DF		0x020		/* has swap file disk frame */
#define VP_DIRTY	0x040		/* contents written to - from pte */
#define VP_SHDIRTY	0x080		/* shadow dirty bit (for VDMs) */
#define VP_SOW		0x100		/* change to swappable on write */
#define VP_PRIVATIZED	0x200		/* vp privatized */
#define VP_RESIDENT	0x400		/* cannot be moved - value from pte */
#define VP_DISCARDABLE	0x800		/* 1 = discardable, 0 = swappable */

/*
 * Values of vp_block field when the page is swappable and does not
 * have a disk frame.
 */
#define VPB_DFBROKEN	2		/* page is in a broken disk frame */
#define VPB_ZEROFILL	1		/* aod zero-fill page */
#define VPB_AOD 	0		/* allocate on demand */
/*end*/

#define PG_COMMITSHIFT	10		/* shift flags by this and get an index
					 * into a table of commit counts used
					 * by PGFree */
/*XLATOFF*/


/***LT+ pf_s - page frame structure (12 bytes per physical page) */
struct _apf1_s {			/* active pf non-bit fields */
	struct vp_s *	apf1_pvp;	/* vp cross link */
	unsigned short	apf1_refcount;	/* count of ptes marked present */
	unsigned char	apf1_pad;	/* pad */
	unsigned char	apf1_llock;	/* count of long term locks */
	unsigned char	apf1_slock;	/* count of short term locks */
	unsigned char	apf1_pad2;	/* pad */
	unsigned short	apf1_pad3;	/* pad */
};
struct _apf2_s {			/* active pf bit fields */
	unsigned long	apf2_pad1;	/* pad */
	unsigned long	apf2_pad2:20,	/* pad */
			apf2_fast:1,	/* set if memory is fast */
			apf2_busy:1,	/* set if frame is busy */
			apf2_free:1,	/* set if frame is free */
			apf2_res:1,	/* available */
			apf2_pad3:8;	/* pad */
	unsigned long	apf2_pad4:12,	/* pad */
			apf2_block:20;	/* swp disk frame or ldr block number */
};


union _apf_s {				/* active pf */
	struct _apf1_s apf1_s;		/* non-bit fields */
	struct _apf2_s apf2_s;		/* bit fields */
};

struct _ipf_s { 			/* idle pf */
	struct vp_s *	ipf_pvp;	/* vp cross link */
	unsigned long	ipf_blink:20,	/* backward link frame index */
			ipf_flags:4,	/* flags */
			ipf_flink1:8;	/* forward link frame index, part 1 */
	unsigned long	ipf_flink2:12,	/* forward link frame index, part 2 */
			ipf_block:20;	/* swp disk frame or ldr block number */
};

struct _fpf_s { 			/* free pf */
	unsigned long	fpf_pad1;	/* pad */
	unsigned long	fpf_blink:20,	/* backward link frame index */
			fpf_fast:1,	/* set if memory is fast */
			fpf_busy:1,	/* set if frame is busy */
			fpf_free:1,	/* set if frame is free */
			fpf_res:1,	/* available */
			fpf_flink1:8;	/* forward link frame index, part 1 */
	unsigned long	fpf_flink2:12,	/* forward link frame index, part 2 */
			fpf_pad:20;	/* pad */
};

union _pf_u {
    union  _apf_s apf_s;
    struct _ipf_s ipf_s;
    struct _fpf_s fpf_s;
};
struct pf_s {
    union _pf_u pf_u;
};

#define pf_pvp		pf_u.apf_s.apf1_s.apf1_pvp
#define pf_refcount	pf_u.apf_s.apf1_s.apf1_refcount
#define pf_fast 	pf_u.apf_s.apf2_s.apf2_fast
#define pf_busy 	pf_u.apf_s.apf2_s.apf2_busy
#define pf_free 	pf_u.apf_s.apf2_s.apf2_free
#define pf_flags	pf_u.ipf_s.ipf_flags
#define pf_llock	pf_u.apf_s.apf1_s.apf1_llock
#define pf_slock	pf_u.apf_s.apf1_s.apf1_slock
#define pf_blink	pf_u.ipf_s.ipf_blink
#define pf_flink	invalid field
#define pf_block	pf_u.apf_s.apf2_s.apf2_block

#define PF_FAST 	0x1			/* frame is fast memory */
#define PF_BUSY 	0x2			/* frame is busy */
#define PF_FREE 	0x4			/* frame is free */
#define PF_RES		0x8			/* reserved */

#define LOCKS(ppf)	(*(unsigned short *)(&(ppf)->pf_llock))

#define BLINK(ppf)	((ppf)->pf_blink)
#define FLINK(ppf)	(((struct pf_s *)((char *)(ppf) + 3))->pf_blink)

#define ppfBLINK(ppf)	pgFrameToPF(BLINK(ppf))
#define ppfFLINK(ppf)	pgFrameToPF(FLINK(ppf))

/*end*/

struct savePF_s {
   struct vp_s *pvp;
   struct pf_s *ppf;
   struct savePF_s *next;
};

/*XLATON*/

/* list data */
struct list_s {
    struct pf_s *li_headppf;		/* pointer to pf of list head */
    frame_t	 li_headframe;		/* pseudo frame number of list head */
    ulong_t	 li_count;		/* number of elements on list */
    ushort_t	 li_flags;		/* flags */
};

/* list structure flags */
#define LI_BLOCKED	0x0001		/* someone needs one or more pages */

/* physical boundary data */
struct physboundary_s {
    frame_t pb_frame;			/* last frame before boundary */
    struct pf_s *pb_ppf;		/* last pf before boundary */
    struct pagerange_s *pb_ppr; 	/* page range containing boundary */
};

/***LT+ pagerange_s - page range structure */
struct pagerange_s {
    frame_t pr_lastframe;		/* last valid page in range */
    frame_t pr_firstframe;		/* first valid page in range */
};
/*end*/

/***LT+ physical arena information structure */
struct physarena_s {
    struct pagerange_s	 *pai_pprt;	/* pointer to page range table */
    int 		  pai_nranges;	/* number of ranges in range table */
    struct physboundary_s pai_1M;	/* 1M boundary structure */
    struct physboundary_s pai_16M;	/* 16M boundary structure */
    struct physboundary_s pai_end;	/* end of memory boundary structure */
};
/*end*/

/***LT+ VMScanMaps worker parameter structure */
struct pgmappte_s {
    frame_t	   mp_framedes; 	/* destination frame */
    frame_t	   mp_framesrc; 	/* source frame */
    struct pf_s   *mp_ppfdes;		/* destination pf */
    struct pf_s   *mp_ppfsrc;		/* source pf */
    struct vp_s   *mp_pvp;		/* pointer to vp */
    int 	   mp_kill;		/* TRUE if illegal write was caught */
    page_t	   mp_page;		/* page number of illegal write */
    struct ptda_s *mp_pptda;		/* context of illegal write */
};
/*end*/


/***LT+ agerate_s - describes a set of page aging parameters */
struct agerate_s {
	unsigned long	ar_minidle;	/* min idle list size for this rate */
	unsigned long	ar_maxidle;	/* max idle list size for this rate */
	unsigned long	ar_sleepms;	/* length of sleeps between aging */
	unsigned short	ar_prtyclass;	/* priority class for aging thread */
	short		ar_prtydelta;	/* priority delta for aging thread */
	unsigned short	ar_ntables;	/* tables to age between sleeps */
};

#define NRATES	5			/* size of pgAgeRateTable array */
/*end*/


/* pgAllocArena flags: */
#define AA_LINEAR	0x00000001	/* Allocate linear memory */
#define AA_PHYSICAL	0x00000002	/* Allocate physical memory */
#define AA_SPECIFIC	0x00000004	/* Allocate at a specific offset */

/* misc equates */
#define PADPAGES	10		/* minimum of 10 pageable pages */
#define NPTEPPT 	(PAGESIZE / sizeof(struct pte_s)) /* ptes/page table */
#define VDMALIASSIG	0xb5b5		/* if in a pt's alloc count, this pt
					 * is a vdm alias.  Value should be
					 * negative so pin thinks it's bad */

/***LK+ 32 bit linear address composition:
 *
 *  dddddddddd				10 bit page directory entry index
 *	      tttttttttt		10 bit page table entry index
 *			oooooooooooo	12 bit page data offset
 */

#define PAGEDIRMASK	0xffc00000	/* page directory index mask */
#define PAGETABLEMASK	0x003ff000	/* page table index mask */
/*#define PAGEMASK	(PAGESIZE - 1)	/* page offset mask */
#define PAGEDIRSHIFT	22		/* to convert from laddr to pde */
/*#define PAGESHIFT	12		/* to convert from laddr to pte */

#define PAGEDIRSIZE	(1 << PAGEDIRSHIFT)	/* 4 m per pde */
/*end*/


/* page fault exception error code bit fields */
#define PER_PROTECT	0x00000001	/* flt caused by protection violation */
#define PER_WRITE	0x00000002	/* write access */
#define PER_USER	0x00000004	/* user mode access */
#define PER_RESERVED	0xfffffff8	/* undefined */


/***LT+ pgdata_s - per arena data */
struct pgdata_s {
	struct pte_s	*pd_ppte;	/* pointer to ptes */
	struct pte_s	*pd_ppde;	/* pointer to pdes */
	ushort_t	*pd_pcalloc;	/* count of allocated ptes per pde */
	ushort_t	*pd_pcpresent;	/* count of present ptes per pde */
//	ulong_t 	*pd_pcresident; /* count of locked/resident ptes */ //d25306
	ushort_t	*pd_pcresident; // removing d25306
	ulong_t 	pd_base;	/* base virtual page number */
	ulong_t 	pd_pvdmalias;	/* base of vdm alias region */
	ushort_t	pd_maxpde;	/* max potential pdes for this arena*/
	ushort_t	pd_cpdelow;	/* count of low in-use pdes */
	ushort_t	pd_cpdehigh;	/* count of high in-use pdes */
	ushort_t	pd_ptcontext;	/* page table context */
	ushort_t	pd_flags;	/* per-process page manager flags */
};

/* pd_flags values */
#define PD_AGINGNEEDED	1		/* process not aged in this sweep */

struct pgpc_s { 			/* per PTDA pde & count arrays */
// GSR start
//	ushort_t     pp_calloc[MAXCRPDE];  /* count of alloc'd ptes per pde */
//	ushort_t     pp_cpresent[MAXCRPDE];/* count of present ptes per pde */
//	ulong_t      pp_cresident[MAXCRPDE];/* count of locked/resident ptes */ //d25306
//	ushort_t     pp_cresident[MAXCRPDE]; // removing d25306
	ushort_t  pp_calloc[MAXCR_PDE];  /* count of alloc'd ptes per pde */
	ushort_t  pp_cpresent[MAXCR_PDE];/* count of present ptes per pde */
	ushort_t  pp_cresident[MAXCR_PDE];/* count of locked/resident ptes */
// GSR end
};
/*end*/


struct pginfo_s {
	page_t		pi_page;
	struct ptda_s	*pi_pptda;
	struct pte_s	*pi_ppte;
	struct pte_s	pi_pte; 	/* image of pte at *ppte */
	struct pgdata_s *pi_ppd;
	struct vp_s	*pi_pvp;
	struct pf_s	*pi_ppf;	/* if pte is present, pointer pf */
	ulong_t 	pi_flags;
	ulong_t 	pi_pdi; 	/* page directory index */
	ulong_t 	pi_data1;	/* free form data */
	ulong_t 	pi_data2;	/* free form data */
	ulong_t 	pi_data3;	/* free form data */
};

struct _PerfMap {	 /* R1 = [1M,16M),  R2 = [16M,4G]	    F/SMS    */
    unsigned short len;  /* number of significant bytes 	    F/SMS    */
			 /* returned (exclusive)		    F/SMS    */
			 /*					    F/SMS    */
			 /* number of 1K blocks:		    F/SMS    */
    unsigned long  L1;	 /*	 of local memory in R1		    F/SMS    */
    unsigned long  L2;	 /*	 of local memory in R2		    F/SMS    */
    unsigned long  S1;	 /*	 of system memory in R1 	    F/SMS    */
    unsigned long  S2;	 /*	 of system memory in R2 	    F/SMS    */
    unsigned long  C1;	 /*	 of cacheable memory in R1	    F/SMS    */
    unsigned long  C2;	 /*	 of cacheable memory in R2	    F/SMS    */
    unsigned long  N1;	 /*	 before non-system memory in R1     F/SMS    */
    unsigned long  N2;	 /*	 before non-system memory in R2     F/SMS    */
			 /*					    F/SMS    */
    unsigned long  R[8]; /* reserved				    F/SMS    */
};			 /*					    F/SMS    */

/*XLATOFF*/



/* page manager local macros */

// min number of discardable pages accounted for during swap file
//    size calculations
#define PGMINDISC    0x100

#define pgNPagesToNPT(page, np) ((np + (page & (NPTEPPT-1)) + (NPTEPPT - 1)) /\
				NPTEPPT)

#define pgSwapAddr(ppf, saddr) ((pgSwapAddrType & PIS_PADDR) ? \
				(pgPFToFrame((ppf)) << PAGESHIFT) : (saddr))

#define pgIdlePF(ppf, frame)	\
	pgInsertPF((ppf), (frame), pgIdleList.li_headppf)
#define pgFreePF(ppf, frame)	\
	ppf->pf_free = 1, pgInsertPF((ppf), (frame), pgFreeList.li_headppf)
#define pgAllocBit(pbm,cnt)	(AllocBit((pbm),(cnt))+1)
#define pgFreeBit(pbm,cnt)	(FreeBit((pbm), ((cnt)-1)))

/***LP	pgFrameToPF - Convert frame number to pf pointer
 *
 *	ENTRY:	frame number
 *	EXIT:	pointer to pf structure
 */
#ifdef	PGSTRICT
extern struct pf_s *pgFrameToPF(frame_t frame);
#else
#   define pgFrameToPF(frame) (pft + (frame))
#endif

/***LP	pgPFToFrame - Convert pf pointer to frame number
 *
 *	ENTRY:	pointer to pf structure
 *	EXIT:	frame number
 */
#define pgPFToFrame(ppf) ((ppf) - pft)

/***LP	pgAssert - page manager assertion macro, turned on by PGSTRICT
 *
 *	ENTRY:	expression
 *	EXIT:	halt kernel if expression is false, otherwise no effect
 */
#ifdef PGSTRICT
#   define pgAssert(exp) _assert(exp)
#else
#   define pgAssert(exp)
#endif


/***LP	pgPageToPd - convert page, pptda pair to pd pointer
 *
 *	This macro converts a page, pptda pair to a pd (pgdata_s) pointer,
 *	and checks page for validity.
 *
 *	ENTRY:	page - virtual page number
 *		pptda - pointer to ptda structure
 *		ppd - pointer to pgdata_s structure to receive result
 *	EXIT:	0 on success, else error code
 */
//#ifdef  PGSTRICT
//#define pgPageToPd(page, pptda, ppd)						\
//    (((page) < MAXCRPAGE) ?							\
//	  (((pptda)->ptda_signature[0] != 'T' ||                                \
//	  (pptda)->ptda_signature[1] != 'D') ?                                  \
//	  panic(("pgPageToPd")) :                                               \
//	  ((ppd) = (struct pgdata_s *) &((pptda)->ptda_pgdata), 0)) :		\
//	  (((page) < MINSYSPAGE || (page) >= MAXSYSPAGE) ? ERROR_ACCESS_DENIED :\
//	      ((ppd) = &pgData, 0)))
//#else
//#define pgPageToPd(page, pptda, ppd)						\
//    (((page) < MAXCRPAGE) ?							\
//	  ((ppd) = (struct pgdata_s *) &(pptda)->ptda_pgdata, 0) :		\
//	  (((page) < MINSYSPAGE || (page) >= MAXSYSPAGE) ? ERROR_ACCESS_DENIED :\
//	      ((ppd) = &pgData, 0)))
//#endif



/***LP	pgPagePdTopPte - convert page, pgdata_s pair to pte pointer
 *
 *	Warning:  No error checking (beyond asserts) is done on the parameters
 *		  to this macro because the numbers should have been
 *		  validated in a previous pgPinPt or pgPageToPd call.
 *
 *	ENTRY:	page - virtual page number caller wants pte pointer for
 *		ppd - pointer to pgdata_s structure for target arena
 *	EXIT:	pte pointer
 */
#ifdef	PGSTRICT
#define pgPagePdTopPte(page, ppd)					      \
    (((page) < (ppd)->pd_base ||					      \
    (page) >= (ppd)->pd_base + ((ppd)->pd_maxpde << (PAGEDIRSHIFT-PAGESHIFT)))\
    ? ((struct pte_s *) panic("pgPagePdTopPte"))                              \
    : ((struct pte_s *) &(ppd)->pd_ppte[(page) - (ppd)->pd_base]))
#else
#define pgPagePdTopPte(page, ppd)					      \
    ((struct pte_s *) &(ppd)->pd_ppte[(page) - (ppd)->pd_base])
#endif

/***LP	pgPagePdToPDI - convert page, pgdata_s pair to page directory index
 *
 *	The PDI returned is relative to the pgdata_s structure specified, e.g.,
 *	if the page at the base of system arena is specified along with the
 *	pgdata_s structure for system space, the returned pdi will be 0 --
 *	the pde offset within the system arena, not from the base of linear
 *	memory.
 *
 *	Warning:  No error checking (beyond asserts) is done on the parameters
 *		  to this macro because the numbers should have been
 *		  validated in a previous pgPinPt or pgPageToPd call.
 *
 *	ENTRY:	page - target virtual page number
 *		ppd - pointer to pgdata_s structure for target arena
 *	EXIT:	page directory index (see note above)
 */
#ifdef	PGSTRICT
#define pgPagePdToPDI(page, ppd)					       \
    (((page) < (ppd)->pd_base ||						\
    (page) >= (ppd)->pd_base + ((ppd)->pd_maxpde << (PAGEDIRSHIFT-PAGESHIFT))) \
	? panic("pgPagePDToPDI")                                               \
	: (((page) - (ppd)->pd_base) >> (PAGEDIRSHIFT-PAGESHIFT)))
#else
#define pgPagePdToPDI(page, ppd)					       \
    (((page) - (ppd)->pd_base) >> (PAGEDIRSHIFT-PAGESHIFT))
#endif


/***LP	pgAssertPF - page frame manager assertion macro, turned on by PGSTRICT
 *
 *	pgAssertPF verifies that the specified pointer is valid, that
 *	both flink and blink in the pf structure are also valid, and
 *	that flink and blink are both null or neither are null.
 *
 *	ENTRY:	ppf - pointer to pf
 *	EXIT:	halt kernel if ppf is invalid, otherwise no effect
 */
#ifdef	PGSTRICT
#define pgAssertPF(ppf) pgAssert(((ppf) >= pft && \
	(ppf) <= pgPageablePAI.pai_end.pb_ppf + 2 && \
	((ulong_t)(ppf) & 0x3) == 0))
#else
#define pgAssertPF(ppf)
#endif


/***LP	pgPinPtFault - pin a single page table for the page fault handler
 *
 *	This macro is the same as pgPinOnePt except there are no VDM or
 *	resident checks.
 *
 *	ENTRY:	pdi - page directory index (ppd-relative) of pt to pin
 *		ppd - pgdata_s structure for target arena
 *		flags - pgPinPt flags
 *		rc - on exit, set to return code
 *	EXIT:	rc = 0 if success, else error code
 */
#define pgPinPtFault(pdi, ppd, flags, rc) {				      \
    pgAssert((int)((ppd)->pd_pcpresent[pdi]) >= 0 &&			      \
	     (int)((ppd)->pd_pcalloc[(pdi)]) >= 0);			      \
    /*									      \
     *	Call pgPinForcePresent if the pde for the page table is zero.	      \
     *	We need to allocate it or at least make it present.		      \
     */ 								      \
    (rc) = 0;								      \
    if ((ppd)->pd_pcpresent[(pdi)] > 0 ||				      \
	((rc) = pgPinForcePresent((pdi), (ppd), (flags))) == 0) {	      \
	/*								      \
	 *  Increment present and allocated counts to keep page table	      \
	 *  present.							      \
	 */								      \
	(ppd)->pd_pcalloc[(pdi)]++;					      \
	(ppd)->pd_pcpresent[(pdi)]++;					      \
    }									      \
}


/***LP	pgPinOnePt - pin a single page table
 *
 *	Forces a page table present, allocating it if needed.
 *	See pgPinPt() for details.
 *
 *	If this macro is invoked twice in a procedure, the parameter
 *	pdi should be different text each time since it is used to
 *	generate a label.
 *
 *	ENTRY:	pdi - page directory index (ppd-relative) of pt to pin
 *		ppd - pgdata_s structure for target arena
 *		flags - pgPinPt flags
 *		rc - on exit, set to return code
 *		c - number of times invoken in this procedure
 *	EXIT:	rc = 0 if success, else error code
 */
#define pgPinOnePt(pdi, ppd, flags, rc, c)  {				      \
	/*								      \
	 *  Don't allow operations on VDM aliases.                            \
	 *  Also, here catch underflows or overflows of counts		      \
	 */								      \
	if ((ppd) == &pgData && pgcPteAllocated[(pdi)] == VDMALIASSIG) {      \
	    (rc) = ERROR_ACCESS_DENIED; 				      \
	    goto exit_##c;						      \
	}								      \
	pgAssert((int)((ppd)->pd_pcpresent[(pdi)]) >= 0 &&		      \
		 (int)((ppd)->pd_pcalloc[(pdi)]) >= 0); 		      \
	/*								      \
	 *  Call pgPinForcePresent if either:				      \
	 *    1)The pde for the page table is zero.  We need to allocate it   \
	 *	or at least make it present.				      \
	 *    2)Resident overcommit is requested for the page table	      \
	 *	and the resident pte count for the pt is zero.	We need       \
	 *	resident overcommit.					      \
	 */								      \
	if ((flags) & PG_RESIDENT) {					      \
	    if ((ppd)->pd_pcresident[(pdi)] == 0) {			      \
		if ((rc) = pgPinForcePresent((pdi), (ppd), (flags))) {	      \
		    goto exit_##c;					      \
		}							      \
	    }								      \
	    (ppd)->pd_pcresident[(pdi)]++;				      \
									      \
	} else if ((ppd)->pd_pcpresent[(pdi)] == 0) {			      \
	    if ((rc) = pgPinForcePresent((pdi), (ppd), (flags))) {	      \
		goto exit_##c;						      \
	    }								      \
	}								      \
	/*								      \
	 *  Increment present and allocated counts to keep present.	      \
	 */								      \
	(ppd)->pd_pcalloc[(pdi)]++;					      \
	(ppd)->pd_pcpresent[(pdi)]++;					      \
	(rc) = 0;							      \
    exit_##c: ; 							      \
}


/***LP	pgUnpinOnePt - unpin a singe page table
 *
 *	Undo the work done by pgPinOnePt.
 *	See pgUnpinPt() for details.
 *
 *	ENTRY:	pdi - page directory index (ppd-relative) of pt to pin
 *		ppd - pgdata_s structure for target arena
 *		flags - 0 or PG_RESIDENT
 *		f - 0 - bare bones unpin for PGPageFault
 *		    1 - above plus PG_RESIDENT processing for other callers
 *	EXIT:	NONE
 */
#define pgUnpinOnePt(pdi, ppd, flags, f)  {					 \
	pgAssert((int)((ppd)->pd_pcpresent[(pdi)]) > 0 &&		      \
		 (int)((ppd)->pd_pcalloc[(pdi)]) > 0);	    /* underflow? */  \
	if (f >= 1) {							      \
	    if ((flags) & PG_RESIDENT) {				      \
		pgAssert((int)((ppd)->pd_pcresident[(pdi)]) > 0);	      \
		if (--((ppd)->pd_pcresident[(pdi)]) == 0) {		      \
		    pgReleasePt((ppd), (pdi), PG_RESIDENT);		      \
		}							      \
	    }								      \
	}								      \
	--(ppd)->pd_pcalloc[(pdi)];					      \
	if (--((ppd)->pd_pcpresent[(pdi)]) == 0) {			      \
	    pgReleasePt((ppd), (pdi), 0);				      \
	}								      \
	pgAssert((int)((ppd)->pd_pcpresent[(pdi)]) >= 0 &&		      \
		 (int)((ppd)->pd_pcalloc[(pdi)]) >= 0);     /* underflow? */  \
}


/***LP	pgSwapFileSize - compute needed size of swap file from commit counts
 *
 *	ENTRY:	NONE, except pgPhysPages, pgSwappablePages, pgDiscardablePages,
 *		and pgResidentPages must all be initialized to the amount
 *		of overcommit for each of the appropriate types.
 *
 *	EXIT:	new size of swap file, in pages
 */
#define pgSwapFileSize() (max(0, (int) (pgSwappablePages -		      \
					max(0, (int) (pgPhysPages -	      \
						      pgResidentPages -       \
				 (max (PG_MIN_DISC_IN_MEM,pgDiscardableInmem))	  \
						      )))))

/***LP	pgUnlockTSD - short-term unlock a TSD that is in the swapper
 *
 *	ENTRY:	NONE
 *	EXIT:	NONE
 */
#define pgUnlockTSD() pgShortLockCommitFree(1); 			     \
    pgFrameToPF(pgPagePdTopPte((((page_t)pTSDCur)+TSDSTART) >> PAGESHIFT,    \
			       &pgData)->pt_frame)->pf_slock--;

/***LP	pgBuildCmd - builds a SMPageCmdList cmd
 *
 *	pgBuildCmd - sets a single SMPageCmdList output cmd to its
 *		     appropriate values
 *
 *	ENTRY	pSMpc  - pointer to a WSPageCmdList_s
 *		index  - index of cmd tobe set
 *		ppf    - pointer to pf tobe swapped out
 *		la     - linear address
 *		va     - virtual address
 *	EXIT	PageCmd set for output
 */

#define pgBuildCmd(pSMpc,index,ppf,la,va)			       \
    pSMpc->Swp[index].pPF      = ppf;				       \
    pSMpc->Swp[index].pVP      = ppf->pf_pvp;			       \
    pSMpc->Swp[index].laddr    = la;				       \
    pSMpc->Cmd[index].pgcmd_cmd      = PB_WRITE_X;		       \
    pSMpc->Cmd[index].pgcmd_priority = PRIO_PAGER_HIGH; 	       \
    pSMpc->Cmd[index].pgcmd_status   = 0;			       \
    pSMpc->Cmd[index].pgcmd_addr     = pgSwapAddr(ppf,va);


/***LP	pgSetSem - take free vp semaphore
 *
 *	ENTRY:	pvp - pointer to vp of page to take semaphore of
 *	EXIT:	none
 */
#ifndef PGSTRICT

#define pgSetSem(pvp)	(pvp)->vp_busy = 1;

#else
#define pgSetSem(pvp)						\
		    if ((pvp)->vp_busy) {			\
			panic("pgSetSem: semaphore busy");      \
		    }						\
		    (pvp)->vp_busy = 1; 			\
		    (pvp)->vp_semowner = pTCBCur->TCBNumber;
#endif


/***LP	pgClearSemVP - free a vp semaphore
 *
 *	ENTRY:	pvp - pointer to vp of page to free semaphore of
 *	EXIT:	none
 */
#ifndef PGSTRICT

#define pgClearSemVP(pvp) {					\
		    if (pvp->vp_wanted) {			\
			TKWakeup(pvp, 0, 0);			\
		    }						\
		    pvp->vp_flags &= ~(VP_WANTED | VP_BUSY);	\
		}

#else

#define pgClearSemVP(pvp) {					\
		    if (pvp->vp_wanted) {			\
			TKWakeup(pvp, 0, 0);			\
		    }						\
		    pvp->vp_flags &= ~(VP_WANTED | VP_BUSY);	\
		    pvp->vp_semowner = 0;			\
		}
#endif


/***LP	pgIsResident - query physical location of a frame
 *
 *	Returns TRUE if the frame is within the resident/long locked region
 *	of physical memory.
 *
 *	ENTRY:	ppf - pf structure to check
 *	EXIT:	TRUE - pf is within the resident region,
 *		FALSE - pf is not within the resident region
 */

#define pgIsResident(ppf) ((ppf) <= pgLoResBoundppf || (ppf) >= pgHiResBoundppf)


/***EP	PGIsAbove16Meg - query physical below-16meg-ness of a linear address
 *
 *	The target linear address must be a resident memory object
 *	in the system arena.
 *
 *	ENTRY:	p - linear address to query
 *	EXIT:	0 - physical address is below 16 meg
 *		non-0 - physical address is above or equal to 16 meg
 */
#ifdef	PGSTRICT
#define PGIsAbove16Meg(p)						    \
    ((p < MINSYSLADDR) ? panic("PGIsAbove16Meg") :                           \
    pgpSysPageTables[(p - MINSYSLADDR) >> PAGESHIFT].pt_long & ~(_16MEG - 1))
#else
#define PGIsAbove16Meg(p)						    \
    (pgpSysPageTables[(p - MINSYSLADDR) >> PAGESHIFT].pt_long & ~(_16MEG - 1))
#endif


/***LP	pgpVPToVPI - convert a pointer to a vp structure, to index in vp array
 *
 *	ENTRY:	pvp - pointer to vp structure
 *	EXIT:	index into vp array
 */
#define pgpVPToVPI(pvp)   ((pvp) - pgpVPBase)

/***LP	pgFrameToVP - convert an index into the vp array into a vp pointer
/***LP	pgVPITopVP - convert an index into the vp array into a vp pointer
 *
 *	ENTRY:	vpi - index into vp array
 *	EXIT:	pointer to vp
 */
#ifdef PGSTRICT
#define pgFrameToVP(vpi)						     \
	(((vpi > 0) && (vpi < pgpVPEnd - pgpVPBase)) ? (pgpVPBase + (vpi)) : \
	(struct vp_s *)(panic("Bad VP index")))
#else
#    define pgFrameToVP(vpi)	    (pgpVPBase + (vpi))
#endif
#define pgVPITopVP(vpi) 	pgFrameToVP(vpi)

/***  pgIsMustSwap(pvp)
 *    1 if pvp must be swapped out else 0 (discardable)
 */
#define pgIsMustSwap(pvpM) ((pvpM->vp_flags & (VP_DF|VP_DISCARDABLE)) == 0 || \
            ((pvpM->vp_flags & (VP_SOW|VP_DIRTY)) == (VP_SOW|VP_DIRTY)))

/* page manager local procedures */
extern int pgTakeSem(struct pte_s *ppte, int npages, int flags);
extern void pgClearSem(struct pte_s *ppte, int npages);
extern struct pte_s *pgPageToPte(page_t page, struct ptda_s *pptda);
extern int pgCommit(ulong_t npages, int flags);
extern void pgCommitFree(ulong_t npages, int flags);
extern int pgShortLockCommit(ulong_t npages, int flags);
extern void pgShortLockCommitFree(ulong_t npages);
extern int pgPinPt(page_t page, struct ptda_s *pptda, int npages, int flags,
		   struct pgdata_s **pppd);
extern int pgPinForcePresent(ulong_t pdi, struct pgdata_s *ppd, ulong_t flags);
extern void pgUnpinPt(page_t page, struct pgdata_s *ppd, int npages,
		      int flags);
extern int pgReleasePt(struct pgdata_s *ppd, int pti, int flags);
extern void pgLockTSD(void);

extern int pgAgePt(ulong_t pdi, struct tcb_s **pptcb, struct pgdata_s *ppd,
		   ulong_t *pcidled);
extern void pgIllegalWrite(struct vp_s *pvp);
extern void PGMarkNP(void *pdata, page_t page, struct ptda_s *pptda);
extern int pgIdle(struct pte_s *ppte, struct pf_s *pf_s, ulong_t pdi,
		  struct pgdata_s *ppd);
extern void pgAgeRate(struct agerate_s *par);

extern void pgInitPrt(int cpgreslow, int cpgpag);
extern paddr_t pgAllocArena(struct arena_s *arenainfo, ulong_t size, int flags,
			    ulong_t offset, laddr_t *pladdr, VMHOB owner);
extern void pgFreeArena(struct arena_s *arenainfo, paddr_t paddr);
extern void pgDecommitArena(struct arena_s *arenainfo, laddr_t laddr, int size);
extern void pgSetBoundary(struct physarena_s *pa, struct physboundary_s *pb,
			  frame_t bound);
extern laddr_t pgAliasTemp(frame_t frame, int f);
extern void pgEnablePaging(paddr_t pdpaddr);
extern void pgFlushTLB(void);
extern void pgInsertPF(struct pf_s *ppf, frame_t frame, struct pf_s *ppfL);
extern void pgDeletePF(struct pf_s *ppf);
extern int pgAllocPF(struct pte_s *ppte, page_t page, int npages, int flags,
		     page_t boundary);
extern int pgGetPF(page_t page, int flags, struct pf_s **pppf);
extern int pgFindFrame(page_t page, int flags, struct pf_s **pppf);
extern int pgMovePF(struct pte_s *ppte, page_t page, struct ptda_s *pptda,
		    struct pf_s *ppf, int npages, int flags, page_t *pgpage);
extern int pgLockPF(struct pte_s *ppte, page_t page, struct ptda_s *pptda,
		    int npages, int flags, page_t *pgpage);
extern int pgForcePresent(struct pte_s *ppte, page_t page, struct ptda_s *pptda,
			  struct vp_s *pvp, int flags, frame_t lobound,
			  frame_t hibound);
extern int pgFindContig(page_t page, int npages, int flags, struct pf_s **pppf,
			page_t boundary);
extern int pgValidateContig(struct pte_s *ppte, page_t page, int npages,
			    int flags, struct pf_s **pppf);
extern void pgCopyPF(struct pf_s *srcppf, struct pf_s *desppf);
extern ulong_t pgIsInCore(struct pte_s pte);
extern struct vp_s *pgAllocVP(void);
extern void pgFreeVP(struct vp_s *pvp);
extern void pgMapPte(struct pgmappte_s *pgmp, page_t page,
		     struct ptda_s *pptda);

typedef int (*pgpfnDriver_t)(struct pginfo_s *ppgi);

extern int pgDriver(struct pginfo_s *ppgi,
	     ulong_t npages,
	     pgpfnDriver_t pfnworker,
	     pgpfnDriver_t pfnerror);
extern int pgDriver2(struct pginfo_s *ppgi,
	      int npages,
	      pgpfnDriver_t pfnworker,
	      pgpfnDriver_t pfnerror);
extern int pgwRemapUvirt(struct pginfo_s *ppgi);
extern int pgwFree(struct pginfo_s *ppgi);
extern int pgwAlloc(struct pginfo_s *ppgi);
extern int pgwAllocPte(struct pginfo_s *ppgi);
extern int pgwSetAccess(struct pginfo_s *ppgi);
extern int pgwGetAccess(struct pginfo_s *ppgi);
extern int pgwDiscToZFill(struct pginfo_s *ppgi);
extern int pgwResToSwap(struct pginfo_s *ppgi);
extern int pgwSwapToRes(struct pginfo_s *ppgi);
extern int pgwAttach(struct pginfo_s *ppgi);
extern int pgwPreload(struct pginfo_s *ppgi);
extern int pgwSetTypeLDT(struct pginfo_s *ppgi);
extern int pgwQueryAccess(struct pginfo_s *ppgi);
extern int pgwQueryState(struct pginfo_s *ppgi);
extern int pgResizeVP(int dpg);
extern int pgReloadFrame(page_t page, struct vp_s *pvp, struct ptda_s *pptda,
			 int flags, struct pf_s *ppfcaller);
extern int pgMoveFrame(struct pte_s *ppte, page_t page, struct vp_s *pvp,
		       int flags, struct pf_s *ppfcaller);
#ifdef	PGSTRICT
extern void pgStrict(struct pte_s *ppte, struct vp_s *pvp);
#else
#define pgStrict(ppte, pvp)
#endif
extern ulong_t pgSavePF(struct vp_s *pvp, struct pf_s *ppf);
extern struct pf_s *pgFindPF(struct vp_s *pvp, ulong_t free);
extern struct vp_s *pgFindDF(ulong_t iDF);

/* page manager local data */
extern struct pte_s *pgpPageDir;
extern paddr_t pgPhysPageDir;
extern struct pte_s *pgpSysPageTables;
extern struct pte_s *pgpCRPageTables;
extern ushort_t pgSysPtHOB;
extern ushort_t pgCRPtHOB;
extern page_t pgSysPtpg;
extern struct pgdata_s pgData;
extern int pgSwapAddrType;
extern ushort_t pgBufSels[];
extern ushort_t pgAllocBufHob;
extern struct savePF_s *pgpSavePF;
extern laddr_t pgAliasLaddr;
extern laddr_t pgSwapPageBufLaddr;
extern laddr_t pgLdrPageBufLaddr;
extern ulong_t pgbmContext[];
extern ulong_t pgbmSegBuf[];
extern ulong_t pgbmLdrPageBuf[];
extern ulong_t pgbmSwapPageBuf[];
extern ushort_t pgSegBufOwner[];
#ifdef PGSTRICT
extern ushort_t pgLdrBufOwner[];
extern ushort_t pgSwapBufOwner[];
#endif
extern uchar_t pgSegBufWanted;
extern uchar_t pgLdrBufWanted;
extern uchar_t pgSwapBufWanted;
extern ulong_t pgSegBufPte[];
extern ushort_t pgcPteAllocated[];
extern ushort_t pgcPtePresent[];
// extern ulong_t  pgcPteResident[];		    //d25306
extern ushort_t pgcPteResident[];		 // removing d25306
extern ulong_t pgPhysPages;
extern ulong_t pgPhysMax;
extern ulong_t pgMaxResPages;
extern ulong_t pgResidentPages;
extern ulong_t pgSwappablePages;
extern ulong_t pgDiscardablePages;

extern ulong_t pgDiscardableInmem;
extern ulong_t pgMinInmemDisc;

extern ulong_t pgShortLockPages;
extern uchar_t pgShortLockWanted;
extern int pgResPT;
extern ulong_t pgFlagMask;
extern ulong_t pgcPageFaults;
extern ulong_t pgcPageFaultsActive;
extern struct agerate_s *pgCurAgeRate;
extern struct agerate_s pgAgeRateTable[];
extern ulong_t pgAgerAsleep;
extern struct tcb_s *pgpAgerTCB;
extern struct pte_s *pgAliasPte;
extern int pgErrCdMask;
extern int pgflPinFault;
extern int pg64Kerrata;
extern ulong_t baseladdr;
extern struct arena_s *paPend;
extern struct arena_s *paVend;
extern struct arena_s *pa1M;

extern int pgnranges;
extern struct physarena_s pgPageablePAI;
extern struct physarena_s pgResidentPAI;
extern frame_t pgLoResBoundfr;
extern struct pf_s *pgLoResBoundppf;
extern frame_t pgHiResBoundfr;
extern struct pf_s *pgHiResBoundppf;
extern struct pf_s *pft;
extern struct list_s pgIdleList;
extern struct list_s pgFreeList;
extern int pgListCount;
extern struct vp_s *pgpVPBase;
extern ulong_t pgVPBasePg;
extern struct vp_s pgVPHead;
extern struct vp_s *pgpVPEnd;
extern struct vp_s *pgpZeroFillVP;
extern ulong_t pgVPEndPg;
extern VMHOB pgVPHob;
extern ulong_t pgZeroFillPte;
extern struct vp_s pgListHeadVP;
extern void *pKStackBase;
extern struct pte_s *ppteKStackBase;
extern KSEMMTX pgCommitSem;


/***	Definitions and external declarations needed for the
 *	the Dos32QueryPageUsageCode. PROFILE
 */

struct puinfo_s {	// Stuctures returned by Dos32QueryAppPageUsage
    page_t  page ;	// Page number
    frame_t frame ;	// Page frame
    ulong_t size ;	// Size of object if first page in object.  Otherwise 0.
    ushort_t hobowner ; // Owner of object if first page in object. Otherwise 0.
    ushort_t hobmte ;	// More ownership info if first page in object. Else 0.
    ushort_t flags ;	// Page flags:
			//	Bit 0 - access bit for the page
			//	Bit 1 - on if first page of app's shared arena
			//	Bit 2 - on if resident page
			//	Bit 3 - on if uvirt page
			//	Bit 4 - on if first page of shared object
			//	Bit 5 - on if first page of loader object
			//	Bit 6 - on if unmapped page in GSR
} ;

typedef struct puinfo_s PUINFO ;
typedef PUINFO *PPUINFO ;

struct qpuinfo_s {	  // Stuctures returned by Dos32QueryAppPageUsage
	ulong_t  cpgi;	  // count of puinfo structs for this app
	ushort_t hobptda ;// ptda_handle
	ushort_t hmte ;   // ptda_module
	ushort_t hldt ;   // ptda_ldthandle
	ushort_t pid ;	  // process identifier
} ;

typedef struct qpuinfo_s QPUINFO ;
typedef QPUINFO *PQPUINFO ;

struct qpucontrol_s {	    // Info on apps involved in page usage monitoring
    struct ptda_s *pptda ;  // Ptr to PTDA of app
    ushort_t pid ;	    // Pid of app
    ushort_t slot ;	    // Slot number of thread 1 of app
} ;

typedef struct qpucontrol_s QPUCONTROL ;
typedef QPUCONTROL *PQPUCONTROL ;

#define APUFIRSTSHAREDFLAG  0x02    // Used to set/test puinfo_s.flags bit 1
#define APURESBITFLAG	    0x04    // Used to set/test puinfo_s.flags bit 2
#define APUUVIRTFLAG	    0x08    // Used to set/test puinfo_s.flags bit 3
#define APUSHAREDOBJFLAG    0x10    // Used to set/test puinfo_s.flags bit 4
#define APULOADEROBJFLAG    0x20    // Used to set/test pginfo_s.flags bit 5
#define APUUNMAPOBJFLAG     0x40    // Used to set/test pginfo_s.flags bit 6

#define QPU_REGAPP  0	// Dos32QueryPageUsage subfunctions
#define QPU_GETAPP  1	// See memory\vmapi.c VR32QueryPageUsage() for details
#define QPU_REGSYS  2
#define QPU_GETSYS  3
#define QPU_DEREG   4
#define QPU_GETGSR  5	// for Global Shared Region

// If qpucontrol pptda == QPU_ALLAPPS, monitor all apps

#define QPU_ALLAPPS  (struct ptda_s *) -1

// Argument structure for TKScanTasks use

struct qpuArgs_s {
	PQPUINFO	*ppbuf; 	// ptr to buffer for storing info
	ulong_t 	*pbufsize;	// ptr to size variable
	page_t		pgstart;	// start of search
} ;
typedef struct qpuArgs_s qpuArgs_t ;

/* Procedures used by Dos32QueryPageUsage */

extern ulong_t qpuFindApp(char *szappname) ;
extern ulong_t qpuFAWorker(struct ptda_s *pptda, ulong_t args[]) ;
extern ulong_t qpuGetPageInfo(struct ptda_s *pptda, struct qpuArgs_s *pqpuArgs);
extern ulong_t qpuwScanPages(struct pginfo_s *ppgi) ;
extern ulong_t qpuSharedAndSize(page_t pgstart, struct pgdata_s *ppd,
				PPUINFO pbuf, ulong_t celts,
				struct ptda_s *pptda) ;

/* Variables used by Dos32QueryPageUsage */

extern QPUCONTROL ApuOwner ;
extern QPUCONTROL MonApp ;
extern QPUCONTROL MonSys ;
extern PQPUINFO pResInfBuf ;
extern ulong_t cbRIB ;
extern ushort_t fRegistered ;



/* Variables used in NOHIGHMEM support */

extern struct pf_s *pgHighMemHeadppf;
extern frame_t pgHighMemHeadframe;
extern struct pf_s *pgHighMemTailppf;
extern frame_t pgHighMemTailframe;
extern ulong_t pgHighPages;
extern ulong_t pgTruePhysMax;
extern struct pte_s *pgTSDStart;
extern struct pte_s *pgTSDEnd;
extern ushort_t pgHighInitPending;

/* Variables that should be elsewhere */
typedef void (*pfnScanMaps)(void *pdata, page_t ipg, struct ptda_s *pptda);

extern void VMScanMaps(pfnScanMaps pfworker, void *pdata, ushort_t dpg,
		       VMHOB hob);
/* Procedures for saving and restoring FAT TCB info */
extern void SaveFatTCBInfo(void *pTCBBuf);
extern void RestoreFatTCBInfo(void *pTCBBuf);
// DCR 32500
extern ulong_t pgHighPagesUsed;
extern int pgAllocPFHighMem(register struct pte_s *ppte, page_t page,
			    int npages, int flags, page_t boundary);
// end

/* min. amount of in memory discardable pages before turning off discard only
 * aging, only used when PGGlobalFlags bit PG_DISC_ONLY_AGING is on
 */
#define PG_MIN_DISC_IN_MEM 0x80

// GSR start
extern struct pte_s *pgpShrCRPageTables;
extern VMHOB   pgShrCRPtHOB;
extern struct pgdata_s pgShrData;		  /* global page directory data */
extern ushort_t pgcShrPteAllocated[MAXGLOBALSHRPDE];	/* count of allocated pages */
extern ushort_t pgcShrPtePresent[MAXGLOBALSHRPDE];	/* count of present pages */
extern ushort_t pgcShrPteResident[MAXGLOBALSHRPDE];	/* count of resident/locked pages */
extern int pgPageToPd(page_t page, struct ptda_s *pptda,
		      struct pgdata_s **pppd);
// GSR end

// GSR end
#ifdef PMDEBUG
/*
* Entry point to call if a discarded page is reloaded from disk (so breakpoints
* can be reestablished)
*/
void DebugPageLoaded(ushort_t hMTE,ulong_t pageaddr);
#endif
