/*	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:region.h	1.10"

/*	The page table entries are paired with a list of disk block 
 *	descriptors which give the location on disk where a
 *	copy of the corresponding page is found.  If the page
 *	is on swap, it is always a single block.  However, if
 *	it is on a regular file, a single page may correspond
 *	to a number of non-consecutive disk blocks.
 */

typedef struct dbd {
	uint	dbd_type  :  3;	/* The values for this field are given	*/
				/* below.				*/
	uint	dbd_cw	  :  1;	/* Copy of the Bit pg_cw, if dbd is	*/
				/* swapped out				*/
#define DB_CW		8
	uint	dbd_swpi  :  4;	/* The index into swaptab for the	*/
				/* device this page is on if dbd_type	*/
				/* is DBD_SWAP.				*/
	uint	dbd_blkno : 24;	/* The block number or i_map index.	*/
} dbd_t;

/*
 * Per region descriptor.  One is allocated for
 * every active region in the system.
 */

typedef	struct	region	{
	short	r_flags;	/* Various flags defined below. */
	short	r_dbdnone;	/* size of invalid DBD_NONE pages */
	long	r_pgsz;		/* size in pages */
	long	r_nvalid;	/* number of valid pages in region */
	short	r_refcnt;	/* number of users pointing at region */
	short	r_swapcnt;	/* number of users pointing at region */
				/* and being swapped out */
	short	r_type;		/* type of region */
	short	r_waitcnt;	/* number of processes waiting for load */
	short	r_noswapcnt;	/* Count of nbr of processes which have	*/
				/* requested that this region not be	*/
				/* swapped out.				*/
#ifdef VPIX /* (page equiv) */
	short   r_v86tab;       /* hook to the v86tab structure for this*/
				/* region.                              */
#endif /* VPIX (page equiv) */
	int	r_filesz;	/* Size in bytes of section of file	*/
				/* from which this region is loaded.	*/
	pde_t	**r_list;	/* Pointer to a list of pointers to	*/
				/* page tables.				*/
	dbd_t	**r_dlist;	/* Pointer to a list of pointers to dbd */
				/* tables.				*/
	int	r_fill1;
	short	r_passn;	/* vhand shredding pass number */
	pde_t	*r_pgptr;       /* regions smaller than 4 Mb            */
	dbd_t	*r_dbdptr;
	struct inode   *r_iptr;	/* pointer to inode where blocks are */
	struct region  *r_forw;	/* forward link */
	struct region  *r_back;	/* backward link */
#ifdef MERGE386
	struct mregion *r_mreg; /* pointer to merge region structure */
#endif

} reg_t;

#define PAGETABSIZ(rp)	(ctos(rp->r_pgsz) << 1)

/*
 *	dbd table flags
 */

#define	DBD_NONE	0	/* There is no copy of this page on 	*/
				/* disk.				*/
#define	DBD_SWAP	1	/* A copy of this page is on block nbr	*/
				/* dbd_blkno of the swap file		*/
				/* swptbl[dbd_swpi].			*/
#define	DBD_FILE	2	/* A copy of this page is on the file	*/
				/* described by the inode r_iptr.  The	*/
				/* dbd_blkno field is an index into the	*/
				/* i_map list pointed to by the inode.	*/
				/* It is the start of a list of block	*/
				/* number which contain a copy of the	*/
				/* page.				*/
#define DBD_LSTFILE	3	/* Same as DBD_FILE except that		*/
				/* this is the last page of the region	*/
#define	DBD_DZERO	4	/* This is a demand zero page.  No	*/
				/* space is allocated now.  When a 	*/
				/* fault occurs, allocate a page and	*/
				/* initialize it to all zeros.		*/
#define	DBD_DFILL	5	/* This is a demand fill page.  No	*/
				/* space is allocated now.  When a	*/
				/* fault occurs, allocate a page and	*/
				/* do not initialize it at all.  It	*/
				/* will be initialized by reading in 	*/
				/* data from disk.			*/
#define	DBD_IOMAP	6	/* This is a page mapped to physical	*/
				/* memory.  No space is allocated. 	*/
#define DBD_WINDOW	7	/* Special type used for EMS and wrap   */
				/* pages by MERGE386. Signifies multiple*/
                                /* mapping to same physical page.       */
                                /* dbd_blkno points at corresponding    */
                                /* page with valid dbd  		*/

/*
 * Region flags
 */
#define	RG_NOFREE	0x0001	/* Don't free region on last detach */
#define	RG_DONE		0x0002	/* Region is initialized */
#define	RG_NOSHARE	0x0004	/* Don't share the region. */
#define RG_LOCK		0x0008	/* Region is locked */
#define RG_WANTED	0x0010	/* Wakeup rp after clearing RG_LOCK */
#define RG_WAITING	0x0020	/* Wakeup rp->r_flags when RG_DONE is set */
#define RG_WASTEXT	0x0040	/* Region was shared text, is now private */
#define	RG_DOWN		0x0080	/* region grows down (stack) */
#define	RG_SWAP		0x0100	/* region page tables are swapped to disk */

#define RG_WEITEK       0x0200  /* region is associated with Weitek chip */
#define RG_VPIX         0x0400  /* region is a vpix region */
#define RG_AGED	0x0800	/* region has been aged since last shredded */

/*
 * Region types
 */
#define	RT_UNUSED	0	/* Region not being used.	*/
#define	RT_PRIVATE	1	/* Private (non-shared) region. */
#define RT_STEXT	2	/* Shared text region */
#define RT_SHMEM	3	/* Shared memory region */
#define RT_MAPFILE	4	/* Mapped file region */
#define RT_VM86		19	/* VM86 type region used by MERGE386
                                 * Attributes are: 
				 * Ability to be shared among >1 process but 
				 * (pages) not kept around after last detach 
				 * (in swap) for any process anytime to use 
				 * again.  Associated w/multiple inodes/files.
				 */

/*	Each process has a number of pregions which describe the
 *	regions which are attached to the process.
 */

typedef struct pregion {
	struct region	*p_reg;		/* Pointer to the region.	*/
	caddr_t		p_regva;	/* User virtual address of	*/
					/* region.			*/
	short		p_flags;	/* Flags.			*/
	short		p_type;		/* Type.			*/
} preg_t;

/*	Pregion flags.
 */

#define	PF_RDONLY	0x0001		/* Read-only attach.		*/

/*	Pregion types.
 */

#define	PT_UNUSED	0x00		/* Unused region.		*/
#define	PT_TEXT		0x01		/* Text region.			*/
#define	PT_DATA		0x02		/* Data region.			*/
#define	PT_STACK	0x03		/* Stack region.		*/
#define	PT_SHMEM	0x04		/* Shared memory region.	*/
#define	PT_DMM		0x05		/* Double mapped memory.	*/
#define	PT_LIBTXT	0x06		/* Shared library text region.	*/
#define	PT_LIBDAT	0x07		/* Shared library data region.	*/
#define	PT_V86		0x08		/* Virtual 8086 mode region	*/
#define	PT_SHFIL	0x09		/* Memory mapped file		*/
#define	PT_XDATA0	0x0f		/* XENIX data region, virtual 0	*/
#define	PT_VM86		0x19		/* vm86 region used by MERGE386 */

extern preg_t	nullpregion;		/* A null preg_t. */
extern int	rlist_lock;		/* Lock for the region list.	*/
extern int	pregpp;			/* Number of pregions per	*/
					/* process including null one.	*/

extern reg_t	region[];	/* Global array of regions */
extern reg_t	ractive;	/* List of active regions */
extern reg_t	rfree;		/* List of free regions */
extern reg_t	sysreg;		/* System region. */
extern reg_t	nullregion;	/* A null region. */

reg_t		*allocreg();	/* region allocator */
void		freereg();	/* region free routine */
preg_t		*attachreg();	/* Attach region to process. */
void		detachreg();	/* Detach region from process. */
reg_t		*dupreg();	/* Duplicate region (fork). */
int		growreg();	/* Grow region. */
int		loadreg();	/* Load region from file. */
int		mapreg();	/* Map region to 413 file. */
reg_t		*findreg();	/* Find region from virtual address. */
preg_t		*findpreg();	/* Find pregion of given type. */
void		chgprot();	/* Change protection for region. */
void		reginit();	/* Initialize the region table. */



