/*	Convergent Technologies - System V - Jun 1983	*/
/*	"@(#)pte.h	1.2"	*/

#ifndef	pte_h
#define pte_h

#include <sys/param.h>

/*
 * Incore page table entry
 *
 * 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.
 */

/*	The format of a pte in the map	*/
struct pte
{
	ushort     pt_wp:1,		/* write permission	*/
		  pt_acc:2,		/* access status	*/
			:4,		/* non h/w flags */
		pt_pfnum:9;		/* core page frame number */
};

/*	The format of a pte in memory (our RAM)	*/
struct mpte
{
unsigned int	pg_ipte:16,		/* index of hardware pte */
		pt_wp:1,		/* write permission	*/
		pg_acc:2,		/* access control */
		pg_fod:1,		/* is fill on demand (=0) */
		pg_swapm:1,		/* have to write back to swap */
		:1,			/* unused */
		pg_pageo:1,		/* page is being paged out */
		pg_pfnum:9;		/* core page frame number or 0 */
};
struct fpte
{
unsigned int	pg_blkno:16,		/* file system block number */
		pt_wp:1,		/* write permission	*/
		pg_acc:2,		/* access control */
		pg_fod:1,		/* is fill on demand (=0) */
		pg_swapm:1,		/* have to write back to swap */
		:1,			/* unused */
		pg_pageo:1,		/* page is being paged out */
		pg_last:1,		/* last data page */
		pg_lastsec:2,		/* disk sectors in the last data page*/
		:1,
		pg_fileno:5;		/* file no for the page */
};

#define PG_PROT		((ushort)0x00008000)
#define PG_STAT		((ushort)0x00006000)
#define PG_STA_SHFT	13			/* shift to get usage field */
#define PG_ACC		((ushort)0x00004000)
#define	PG_V		((ushort)0x00002000)
#define	PG_M		((ushort)0x00006000)
#define	PG_FOD		((ushort)0x00001000)
#define	PG_PFNUM	((ushort)0x000001ff)

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

/*
 * Pte related macros
 */
#define	dirty(pte)	((pte)->pg_fod == 0 && (pte)->pg_pfnum && (pte)->pg_swapm)

#define setpginvalid(hpte) ((hpte)->pt_acc = 0)

#define pagevalid(hpte) ((hpte)->pt_acc != 0)

#define reference(hpte) (*(unsigned short *)(hpte) & (unsigned short) PG_ACC)

#define resetref(hpte) (*(unsigned short *)(hpte) = (*(unsigned short *)(hpte) & (~PG_STAT)) | PG_V)

#define modified(hpte) ((*(unsigned short *)(hpte) & PG_STAT) == PG_M)

struct vaddress {
	unsigned v_region:2,	/* Region of memory(ram,map+regs,rom,i/o) */
		v_vpn:10,	/* Virtual page number */
		v_byte:12;	/* Byte within the page */
};

/*	Definition of a physical address.	*/
struct paddress {
	unsigned p_mbz:11,	/* Must be zero */
		p_pfn:9,	/* Page frame number */
		p_byte:12;	/* Byte within the page */
};

/*	Memory mapping hardware		*/

#define PG_BASE		((unsigned short *)0x400000)	/* address of page table */
#define USER_MAP	(unsigned short *)(0x400100) /* address of user part of page table */
#define MAP_TOP		(unsigned short *)(0x400800) /* address past end of memory map */
#define DMA_MAP		(unsigned short *)(0x4000c0) /* Disk dma uses segment 6 for i/o */
#define DMA_XFR_ADR	0x60000	 /* virtual address corresponding to DMA_MAP */

/*	Page table entry.
 *	WE	 bit 15		=1 user can write page, =0 user can read page
 *	USE	 bits 14-13	value 0=not present, 1=present, not accessed
 *				value 2=accessed not written, 3=written to
 *	PAGEADDR bits 8-0	PHYSADDR=(PAGEADDR*4096) + byte within page
 *	STATES:
 *	page not in memory:	WE set as needed and rest=0
 *	page in memory:		WE, PAGEADDR set as needed and USE non zero
 */
#define PROT_MASK	((ushort)0x8000)	/* mask for write bit */
#define USE_MASK	((ushort)0x6000)	/* mask for usage bits */
#define PG_MASK		0x1ff			/* page address mask */
#define PG_WRITE	((ushort)0x8000)	/* user write enable */
#define NO_PAGE		0x0			/* to initialize pte's */
#define PG_IN		0x7fff			/* AND mask */
#define PG_PRESENT	0x2000			/* pte&USE_MASK page just in */ 
#define PG_NOT_DIRTY	0x4000			/* pte&USE_MASK = accessed */ 
#define PAGE_DIRTY	0x6000			/* pte&USE_MASK = written to */
#define P_ACCESS_CHECK	0x6000			/* AND mask */
#define NO_ACCESS	0

/*	2 Mbyte physical address space */
#define MAX_PHYS_MEM		0x200000

#endif pte_h
