/* rcsid[]="$Header: pte.h,v 820.1 86/12/04 19:53:51 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.				*
*									*
************************************************************************/

#ifndef	PTE_ALREADY_DEFINED
#define	PTE_ALREADY_DEFINED

/*	pte.h	4.10	82/10/26	*/

/*
 * There are two major kinds of pte's: those which have ever existed (and are
 * thus either now in core or on the swap device), and those which have
 * never existed, but which will be filled on demand at first reference.
 * There is a structure describing each.  There is also an ancillary
 * structure used in page clustering.
 */

#ifndef LOCORE
/*
 * S/W page table entry.
 */
struct pte {
/*

<--------------------------- s/w pte --------------------------->

| |       | | | | | |d|                 |                       |
| |       | | | |m|k|e|                 |                       |
| |       | | | |p|c|r|                 |                       |
| | prot  | |D| |a|o|a|     (unused)    |         pfnum         |
| |  :4   | |O| |w|l|h|        :9       |          :12          |
|V|_______|M|F|R|s|u|s|_________________|_______________________|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|       |       |       |       |       |       |       |       |
|               |               |               |               |

*/
unsigned int	pg_v	:1,		/* Valid bit */
		pg_prot	:4,		/* Access control */
		pg_m	:1,		/* Modified bit */
		pg_fod	:1,		/* Is fill on demand (=0) */
		pg_r	:1,		/* Referenced bit */
		pg_swapm:1,		/* Have to write back to swap */
#ifdef	s32 /* LOCKPAGES */
		pg_ulock :1,		/* User has locked this page */
#if	defined(USE_CTXT) || defined(USE_COW)
		pg_shared:1,		/* Page is shared from fork() */
#else	defined(USE_CTXT) || defined(USE_COW)
			 :1,
#endif	defined(USE_CTXT) || defined(USE_COW)
			 :7,
#else	s32 /* LOCKPAGES */
			 :9,
#endif	s32 /* LOCKPAGES */
		pg_space :2,		/* "space", on-board, Multibus, etc. */
#define	PGSP_OBMEM	0x0000

#if	defined(M68000) || defined(M68010)
#define	PGSP_INVAL	0x1000		/* An invalid page	*/
#endif	defined(M68000) || defined(M68010)

#define	PGSP_MBMEM	0x2000		/* Multibus memory	*/
#define	PGSP_MBIO	0x3000		/* Multibus i/o-space	*/


		pg_pfnum:12;		/* core page frame number or 0 */
};


/*
 * Page table entry
 * for clustering.
 */
struct hpte {
/*

<----------------------- cluster pte --------------------------->

| |       | | | | |                     |                       |
| |       | | | |m|                     |                       |
| |       | | | |p|                     |                       |
| | prot  | |D| |a|       (unused)      |         pfnum         |
| |  :4   | |O| |w|         :11         |          :12          |
|V|_______|M|F|R|s|_____________________|_______________________|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|       |       |       |       |       |       |       |       |
|               |               |               |               |

*/
unsigned int	pg_high	:9,		/* special for clustering */
			:11,
		pg_pfnum:12;
};

/*
 * FILL-ON-DEMAND page table entry.
 * BUG: is the valid-bit (pg_v) ever lit?
 *
 * NOTE:	((pg_v|pg_fod)==0) ==> V_PAGE_INVALID;
 *	c.f., setsysmap()
 */
struct fpte {
/*

<--------------------------- fod pte --------------------------->

| |       |d| |         |                                       |
| |       |e| |         |                                       |
| |       |h| |         |                                       |
| | prot  |c|D|  fileno |            blkno                      |
| |  :4   |a|O|    :5   |             :20                       |
|V|_______|c|F|_________|_______________________________________|
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|       |       |       |       |       |       |       |       |
|               |               |               |               |

*/
unsigned int	pg_v	:1,
		pg_prot	:4,
#ifdef	M68020
		pg_noncached:1,		/* page is NOT to be cached */
#define	PG_NONCACHED	0x04000000	/* Don't cache in 68020 onboard cache */
#else	M68020
		:1,
#endif	M68020
		pg_fod	 :1,		/* is fill on demand (=1) */
		pg_fileno:5,		/* file mapped from or TEXT or ZERO */
		pg_blkno :20;		/* file system block number */
};
#endif LOCORE


/*
 * Bits common to ALL
 * software pte-s, which of
 * course, aren't in the h/w mmu.
 */
#define	PG_V		0x80000000	/* 1 ==> Page is valid		    */
#define	PG_PROT		0x78000000	/* Mask for all the protection bits */
#define	PG_M		0x04000000	/* 1 ==> Page has been modified	    */
#define	PG_FOD		0x02000000	/* 1 ==> Page is Fill-On-Demand     */

#if	!defined(s32) && !defined(WHITE)
/*
 * Not used by Valid...
 */
#define	PG_VREADM	0x00800000	/* 1 ==> Have to write back to swap */
#endif

#define	PG_PFNUM	0x000fffff	/* Page frame #: 20-bits */
#define	PG_PROTSHFT	27		/* Bit # where protection starts   */


#define	PG_FZERO	(NOFILE)
#define	PG_FTEXT	(NOFILE+1)

#ifdef s32
#define	PG_FPHYS	(NOFILE+2)
#define	PG_FMAX		(PG_FPHYS)
#else s32
#define	PG_FMAX		(PG_FTEXT)
#endif s32


/*
 * Software pte control:
 * Access rights to contents
 * of page.
 */
#define	PG_NOACC	0

#if	defined(s32) || defined(WHITE)
/*
 * Software page protection-bitfield definitions:
 *	PROT<3..0>:
 */
#define	PGP_UR		0x40000000		/* User   read  */
#define	PGP_KR		0x20000000		/* Kernel read  */

#define	PGP_UW		0x10000000		/* User   write */
#define	PGP_KW		0x08000000		/* Kernel write */

#define	PG_URKR	(PGP_UR|PGP_KR)			/* User read +	Kernel read  */
#define	PG_URKW	(PGP_UR|PGP_KR|PGP_KW)		/* User read +	Kernel r/w   */
#define	PG_KW	(PGP_KR|PGP_KW)			/*		Kernel r/w   */
#define	PG_KR	(PGP_KR)			/*		Kernel read  */
#define	PG_UW	(PGP_UR|PGP_KR|PGP_UW|PGP_KW)	/* User r/w  +	Kernel r/w   */

#else	defined(s32) || defined(WHITE)

#define	PG_URKR		0x60000000	/* User read +	Kernel read	*/
#define	PG_URKW		0x68000000	/* User read +	Kernel WRITE	*/

#define	PG_KW		0x28000000	/*		Kernel WRITE	*/
#define	PG_KR		0x18000000	/*		Kernel read	*/

#define	PG_UW		0x78000000	/* User WRITE			*/

#endif	defined(s32) || defined(WHITE)

/*
 * Pte related macros
 */
#ifdef	NOPAGING
/*
 * This is a KLUDGE until
 * we look at reference bits
 */
#define	dirty(pte)	((pte)->pg_fod == 0 && (pte)->pg_pfnum)
#else	NOPAGING

#ifdef s32
/*
 * We do not look at the modified bit since
 * it is not updated in the s/w pte-s.
 *
 * We only look at it in the hardware map
 * where it IS updated.
 */
#define	dirty(pte)	((pte)->pg_fod == 0 && (pte)->pg_pfnum)
#else s32
#define	dirty(pte)	((pte)->pg_fod == 0 && (pte)->pg_pfnum && \
			    ((pte)->pg_m || (pte)->pg_swapm))
#endif s32
#endif	NOPAGING


#ifndef LOCORE
#ifdef KERNEL
struct	pte *vtopte();

/* utilities defined in locore.s */
extern	struct pte Sysmap[];
extern	struct pte Usrptmap[];
#ifdef s32
extern	struct pte *usrpt;		/* Ptr to slot within Usrptmap */
#else s32
extern	struct pte usrpt[];		/* Ptr to slot within Usrptmap */
#endif s32
extern	struct pte Swapmap[];		/* UPAGES big; maps swapped process */
extern	struct pte Forkmap[];		/* UPAGES big; maps forked  process */
extern	struct pte Xswapmap[];
extern	struct pte Xswap2map[];
extern	struct pte Pushmap[];		/* UPAGES big; work-var for uaccess() */
extern	struct pte Vfmap[];		/* UPAGES big; work-var for vfork */
#ifdef s32
extern	struct pte Cmap1;
extern	struct pte Cmap2;
#endif s32
extern	struct pte mmap[];		/* Global work-var: ptr to a pte */
extern	struct pte msgbufmap[];
extern	struct pte camap[];		/* 32 entries; work-var for calloc() */
extern	struct pte Nexmap[][16];

#ifdef s32
extern	Sysbase;	/* &Sysbase is kernel virtual base */
extern	int Syssize;	/* Size of kernel virtual ( == &Syssize on Vax) */
extern	int caddr1;	/* &caddr1 is mapped by Cmap1 */
extern	int caddr2;	/* &caddr2 is mapped by Cmap2 */

struct pte *suregp0br;	/* Base address of text+data page tables */
int	    suregp0lr;	/* Number of pages in text+data area */

struct pte *suregp1br;	/* Base address of stack page tables */
int	    suregp1lr;	/* Number of pages NOT in stack area */
#endif s32

#endif	KERNEL
#endif	LOCORE
#endif	PTE_ALREADY_DEFINED
