/*
 * 5799-WZQ (C) COPYRIGHT IBM CORPORATION  1986,1987
 * LICENSED MATERIALS - PROPERTY OF IBM
 * REFER TO COPYRIGHT INSTRUCTIONS FORM NUMBER G120-2083
 */
/* $Header:vmmac.h 12.0$ */
/* $ACIS:vmmac.h 12.0$ */
/* $Source: /ibm/acis/usr/sys/h/RCS/vmmac.h,v $ */

#if !defined(lint) && !defined(LOCORE) && defined(RCS_HDRS)
static char *rcsidvmmac = "$Header:vmmac.h 12.0$";
#endif

/*	vmmac.h	6.1	83/07/29	*/

/*
 * Virtual memory related conversion macros
 */

/* Core clicks to number of pages of page tables needed to map that much */
#define	ctopt(x)	(((x)+NPTEPG-1)/NPTEPG)

/* Virtual page numbers to text|data|stack segment page numbers and back */

#if	defined(vax) || defined(ibm370)
#define	vtotp(p, v)	((int)(v)-LOWPAGES)
#define	vtodp(p, v)	((int)((v) - stoc(ctos((p)->p_tsize)) - LOWPAGES))
#endif	/* defined(vax) || defined(ibm370) */
#ifdef ibm032
#define vtotp(p, v)     ((int)(v))
#define vtodp(p, v)     ((int)((v)-((p)->p_tsize ? btop(DATABASE) : 0)))
#endif ibm032

#if	!defined(ibm370)
#define	vtosp(p, v)	((int)(btop(USRSTACK) - 1 - (v)))
#else	/* !defined(ibm370) */
#define	vtosp(p, v)	((int)(btop(USRCXAEND) - 1 - (v)))
#endif	/* !defined(ibm370) */

#if	defined(vax) || defined(ibm370)
#define	tptov(p, i)	((unsigned)(i) + LOWPAGES)
#define	dptov(p, i)	((unsigned)(stoc(ctos((p)->p_tsize)) + (i) + LOWPAGES))
#endif	/* defined(vax) || defined(ibm370) */
#ifdef ibm032
#define tptov(p, i)     ((unsigned)(i))
#define dptov(p, i)     ((unsigned)((i)+((p)->p_tsize ? btop(DATABASE) : 0)))
#endif ibm032

#if	!defined(ibm370)
#define	sptov(p, i)	((unsigned)(btop(USRSTACK) - 1 - (i)))
#else	/* !defined(ibm370) */
#define	sptov(p, i)	((unsigned)(btop(USRCXAEND) - 1 - (i)))
#endif	/* !defined(ibm370) */

/* Tell whether virtual page numbers are in text|data|stack segment */
#if	defined(vax) || defined(ibm370)
#define	isassv(p, v)	((v) >= btop(USRSTACK) - (p)->p_ssize)
#define	isatsv(p, v)	(((v) - LOWPAGES) < (p)->p_tsize)
#define	isadsv(p, v)	(((v) - LOWPAGES) >= stoc(ctos((p)->p_tsize)) && \
				!isassv(p, v))
#endif	/* defined(vax) || defined(ibm370) */

#ifdef ibm032
#define isatsv(p, v)    ((v) < (p)->p_tsize)
#define isadsv(p, v)    (!isatsv(p,v) && ISADSV(p,v))
/* use ISADSV if already have failed isatsv (isitok) */
#define ISADSV(p, v)    ((v) - ((p)->p_tsize ? btop(DATABASE) : 0) < (p)->p_dsize)
#define isassv(p, v)    ((v) < btop(USRSTACK) && \
	((v) >= btop(USRSTACK)-(p)->p_ssize))
#endif ibm032

/* Tell whether pte's are text|data|stack */
#define	isaspte(p, pte)		((pte) > sptopte(p, (p)->p_ssize))
#define	isatpte(p, pte)		((pte) < dptopte(p, 0))
#define	isadpte(p, pte)		(!isaspte(p, pte) && !isatpte(p, pte))

/* Text|data|stack pte's to segment page numbers and back */
#define	ptetotp(p, pte)		((pte) - (p)->p_p0br)
#define	ptetodp(p, pte)		((pte) - ((p)->p_p0br + (p)->p_tsize))

#if	defined(vax) || defined(ibm370)
#define	ptetosp(p, pte)	\
	(((p)->p_p0br + (p)->p_szpt*NPTEPG - UPAGES - 1) - (pte))
#endif	/* defined(vax) || defined(ibm370) */
#ifdef ibm032
#define ptetosp(p, pte) ((p)->p_p0br + (p)->p_szpt*NPTEPG-HIGHPAGES-1-(pte))
#endif ibm032

#define	tptopte(p, i)		((p)->p_p0br + (i))
#define	dptopte(p, i)		((p)->p_p0br + (p)->p_tsize + (i))

#if	defined(vax) || defined(ibm370)
#define	sptopte(p, i) \
	(((p)->p_p0br + (p)->p_szpt*NPTEPG - UPAGES - 1) - (i))
#endif	/* defined(vax) || defined(ibm370) */
#ifdef ibm032
#define sptopte(p, i)   ((p)->p_p0br + (p)->p_szpt*NPTEPG-HIGHPAGES-1-(i))
#endif ibm032

/* Bytes to pages without rounding, and back */
#define	btop(x)		(((unsigned)(x)) >> PGSHIFT)
#define	ptob(x)		((caddr_t)((x) << PGSHIFT))

/* Turn virtual addresses into kernel map indices */
#define	kmxtob(a)	(usrpt + (a) * NPTEPG)
#define	btokmx(b)	(((b) - usrpt) / NPTEPG)

#if	defined(ibm370)
/* Turn virtual addresses into kernel work space real addresses */
#define	kwxtob(a)	(kworkarea + (a-1) * DEV_BSIZE)
#define	btokwx(b)	((((b) - kworkarea) / DEV_BSIZE ) + 1)
extern char *kworkarea;

/* Turn virtual addresses into kernel work space real addresses */
extern char *argbufarea;
#define	amxtob(a)	(argbufarea + (a-1) * NCARGS)
#define	btoamx(b)	((((b) - argbufarea) / NCARGS ) +1 )
#endif

/* User area address and pcb bases */
#define	uaddr(p)	(&((p)->p_p0br[(p)->p_szpt * NPTEPG - UPAGES]))

#if defined(vax) || defined(ibm032)
#define	pcbb(p)		((p)->p_addr[0].pg_pfnum)
#endif vax|ibm032

/* Average new into old with aging factor time */
#define	ave(smooth, cnt, time) \
	smooth = ((time - 1) * (smooth) + (cnt)) / (time)

/* Abstract machine dependent operations */

#ifdef vax
#define	setp0br(x)	(u.u_pcb.pcb_p0br = (x), mtpr(P0BR, x))
#define	setp0lr(x)	(u.u_pcb.pcb_p0lr = \
			    (x) | (u.u_pcb.pcb_p0lr & AST_CLR), \
			 mtpr(P0LR, x))
#define	setp1br(x)	(u.u_pcb.pcb_p1br = (x), mtpr(P1BR, x))
#define	setp1lr(x)	(u.u_pcb.pcb_p1lr = (x), mtpr(P1LR, x))
#define	initp1br(x)	((x) - P1PAGES)
#endif vax
#if	defined(ibm032) || defined(ibm370)
#define        setp0br(x)      (u.u_pcb.pcb_p0br = (x))
#define        setp0lr(x)      (u.u_pcb.pcb_p0lr = (x))
#define        setp1br(x)      (u.u_pcb.pcb_p1br = (x))
#define        setp1lr(x)      (u.u_pcb.pcb_p1lr = (x))
#define        initp1br(x)     ((x) - P1PAGES)
#endif /* defined(ibm032) || defined(ibm370) */


#define	outofmem()	wakeup((caddr_t)&proc[2]);

/*
 * Page clustering macros.
 *
 * dirtycl(pte)			is the page cluster dirty?
 * anycl(pte,fld)		does any pte in the cluster has fld set?
 * zapcl(pte,fld) = val		set all fields fld in the cluster to val
 * distcl(pte)			distribute high bits to cluster; note that
 *				distcl copies everything but pg_pfnum,
 *				INCLUDING pg_m!!!
 *
 * In all cases, pte must be the low pte in the cluster, even if
 * the segment grows backwards (e.g. the stack).
 */
#define	H(pte)	((struct hpte *)(pte))

#if CLSIZE==1
#define	dirtycl(pte)	dirty(pte)
#define	anycl(pte,fld)	((pte)->fld)
#define	zapcl(pte,fld)	(pte)->fld
#define	distcl(pte)
#endif

#if CLSIZE==2
#define	dirtycl(pte)	(dirty(pte) || dirty((pte)+1))
#define	anycl(pte,fld)	((pte)->fld || (((pte)+1)->fld))
#define	zapcl(pte,fld)	(pte)[1].fld = (pte)[0].fld
#endif

#if CLSIZE==4
#define	dirtycl(pte) \
    (dirty(pte) || dirty((pte)+1) || dirty((pte)+2) || dirty((pte)+3))
#define	anycl(pte,fld) \
    ((pte)->fld || (((pte)+1)->fld) || (((pte)+2)->fld) || (((pte)+3)->fld))
#define	zapcl(pte,fld) \
    (pte)[3].fld = (pte)[2].fld = (pte)[1].fld = (pte)[0].fld
#endif

#if	defined(ibm370)
#define	dirtycl(pte)	dirty(pte)
#define	anycl(pte,fld)	((pte)->fld)
#define	zapcl(pte,fld)	(pte)->fld
#endif	/* defined(ibm370) */

#ifndef distcl
#define	distcl(pte)	zapcl(H(pte),pg_high)
#endif

/*
 * Lock a page frame.
 */
#define MLOCK(c) { \
	while ((c)->c_lock) { \
		(c)->c_want = 1; \
		sleep((caddr_t)(c), PSWP+1); \
	} \
	(c)->c_lock = 1; \
}
/*
 * Unlock a page frame.
 */
#define MUNLOCK(c) { \
	if (c->c_want) { \
		wakeup((caddr_t)c); \
		c->c_want = 0; \
	} \
	c->c_lock = 0; \
}
