xref: /csrg-svn/sys/sparc/include/pte.h (revision 63320)
155124Storek /*
2*63320Sbostic  * Copyright (c) 1992, 1993
3*63320Sbostic  *	The Regents of the University of California.  All rights reserved.
455124Storek  *
555124Storek  * This software was developed by the Computer Systems Engineering group
655124Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
755124Storek  * contributed to Berkeley.
855124Storek  *
955501Sbostic  * All advertising materials mentioning features or use of this software
1055501Sbostic  * must display the following acknowledgement:
1155501Sbostic  *	This product includes software developed by the University of
1259210Storek  *	California, Lawrence Berkeley Laboratory.
1355501Sbostic  *
1455124Storek  * %sccs.include.redist.c%
1555124Storek  *
16*63320Sbostic  *	@(#)pte.h	8.1 (Berkeley) 06/11/93
1755124Storek  *
1859210Storek  * from: $Header: pte.h,v 1.5 92/11/26 02:04:43 torek Exp $
1955124Storek  */
2055124Storek 
2155124Storek /*
2255124Storek  * Sun-4 (sort of) and 4c (SparcStation) Page Table Entries
2355124Storek  * (Sun call them `Page Map Entries').
2455124Storek  */
2555124Storek 
2655124Storek #ifndef LOCORE
2755124Storek /*
2855124Storek  * Segment maps contain `pmeg' (Page Map Entry Group) numbers.
2955124Storek  * A PMEG is simply an index that names a group of 32 (sun4) or
3055124Storek  * 64 (sun4c) PTEs.
3155124Storek  */
3255124Storek #ifdef SUN4
3355124Storek typedef u_short pmeg_t;		/* 9 bits needed per Sun-4 segmap entry */
3455124Storek #else
3555124Storek typedef u_char pmeg_t;		/* 7 bits needed per Sun-4c segmap entry */
3655124Storek #endif
3755124Storek #endif
3855124Storek 
3955124Storek /*
4055124Storek  * Address translation works as follows:
4155124Storek  *
4255124Storek  *	1. test va<31:29> -- these must be 000 or 111 (or you get a fault)
4355124Storek  *	2. concatenate context_reg<2:0> and va<29:18> to get a 15 bit number;
4455124Storek  *	   use this to index the segment maps, yeilding a 7 or 9 bit value.
4555124Storek  * (for sun4c)
4655124Storek  *	3. take the value from (2) above and concatenate va<17:12> to
4755124Storek  *	   get a `page map entry' index.  This gives a 32-bit PTE.
4855124Storek  * (for sun4)
4955124Storek  *	3. take the value from (2) above and concatenate va<17:13> to
5055124Storek  *	   get a `page map entry' index.  This gives a 32-bit PTE.
5155124Storek  *
5255124Storek  * In other words:
5355124Storek  *
5455124Storek  *	struct sun4_virtual_addr {
5555124Storek  *		u_int	:2,		(required to be the same as bit 29)
5655124Storek  *			va_seg:12,	(virtual segment)
5755124Storek  *			va_pg:5,	(virtual page within segment)
5855124Storek  *			va_off:13;	(offset within page)
5955124Storek  *	};
6055124Storek  *	struct sun4c_virtual_addr {
6155124Storek  *		u_int	:2,		(required to be the same as bit 29)
6255124Storek  *			va_seg:12,	(virtual segment)
6355124Storek  *			va_pg:6,	(virtual page within segment)
6455124Storek  *			va_off:12;	(offset within page)
6555124Storek  *	};
6655124Storek  *
6755124Storek  * Then, given any `va':
6855124Storek  *
6955124Storek  *	extern pmeg_t segmap[8][1<<12];		([16][1<<12] for sun4)
7055124Storek  *	extern int ptetable[128][1<<6];		([512][1<<5] for sun4)
7155124Storek  *
7255124Storek  * (the above being in the hardware, accessed as Alternate Address Spaces)
7355124Storek  *
7455124Storek  *	physseg = segmap[curr_ctx][va.va_seg];
7555124Storek  *	pte = ptetable[physseg][va.va_pg];
7655124Storek  *	if (!(pte & PG_V)) TRAP();
7755124Storek  *	if (writing && !pte.pg_w) TRAP();
7855124Storek  *	if (usermode && pte.pg_s) TRAP();
7955124Storek  *	if (pte & PG_NC) DO_NOT_USE_CACHE_FOR_THIS_ACCESS();
8055124Storek  *	pte |= PG_U;					(mark used/accessed)
8155124Storek  *	if (writing) pte |= PG_M;			(mark modified)
8255124Storek  *	ptetable[physseg][va.va_pg] = pte;
8355124Storek  *	physadr = ((pte & PG_PFNUM) << PGSHIFT) | va.va_off;
8455124Storek  */
8555124Storek 
8655124Storek #define	NBPSG	(1 << 18)	/* bytes per segment */
8755124Storek #define	SGSHIFT	18		/* log2(NBPSG) */
8855124Storek #define	SGOFSET	(NBPSG - 1)	/* mask for segment offset */
8955124Storek 
9055124Storek /* number of PTEs that map one segment (not number that fit in one segment!) */
9155124Storek #if defined(SUN4) && defined(SUN4C)
9255124Storek #define	NPTESG	nptesg		/* (which someone will have to init) */
9355124Storek #else
9455124Storek #define	NPTESG	(NBPSG / NBPG)
9555124Storek #endif
9655124Storek 
9755124Storek /* virtual address to virtual segment number */
9855124Storek #define	VA_VSEG(va)	(((int)(va) >> SGSHIFT) & 0xfff)
9955124Storek 
10055124Storek /* virtual address to virtual page number, for Sun-4 and Sun-4c */
10155124Storek #define	VA_SUN4_VPG(va)		(((int)(va) >> 13) & 31)
10255124Storek #define	VA_SUN4C_VPG(va)	(((int)(va) >> 12) & 63)
10355124Storek 
10455124Storek /* truncate virtual address to segment base */
10555124Storek #define	VA_ROUNDDOWNTOSEG(va)	((int)(va) & ~SGOFSET)
10655124Storek 
10755124Storek /* virtual segment to virtual address (must sign extend!) */
10855124Storek #define	VSTOVA(vseg)	(((int)(vseg) << 20) >> 2)
10955124Storek 
11055124Storek #ifdef SUN4
11155124Storek #ifdef SUN4C
11255124Storek int	issun4c;
11355124Storek #define VA_VPG(va)	(issun4c ? VA_SUN4C_VPG(va) : VA_SUN4_VPG(va))
11455124Storek #else /* sun4 and not sun4c */
11555124Storek #define VA_VPG(va)	VA_SUN4_VPG(va)
11655124Storek #endif
11755124Storek #else /* not sun4; must be 4c */
11855124Storek #define	VA_VPG(va)	VA_SUN4C_VPG(va)
11955124Storek #endif
12055124Storek 
12155124Storek /* there is no `struct pte'; we just use `int' */
12255124Storek #define	PG_V		0x80000000
12355124Storek #define	PG_PROT		0x60000000	/* both protection bits */
12455124Storek #define	PG_W		0x40000000	/* allowed to write */
12555124Storek #define	PG_S		0x20000000	/* supervisor only */
12655124Storek #define	PG_NC		0x10000000	/* non-cacheable */
12755124Storek #define	PG_TYPE		0x0c000000	/* both type bits */
12855124Storek 
12955124Storek #define	PG_OBMEM	0x00000000	/* on board memory */
13055124Storek #define	PG_OBIO		0x04000000	/* on board I/O (incl. Sbus on 4c) */
13155124Storek #ifdef SUN4
13255124Storek #define	PG_VME16	0x08000000	/* 16-bit-data VME space */
13355124Storek #define	PG_VME32	0x0c000000	/* 32-bit-data VME space */
13455124Storek #endif
13555124Storek 
13655124Storek #define	PG_U		0x02000000
13755124Storek #define	PG_M		0x01000000
13855124Storek #define	PG_MBZ		0x00f80000	/* unused; must be zero (oh really?) */
13955124Storek #define	PG_PFNUM	0x0007ffff	/* n.b.: only 16 bits on sun4c */
14055124Storek 
14155124Storek #define	PG_TNC_SHIFT	26		/* shift to get PG_TYPE + PG_NC */
14255124Storek #define	PG_M_SHIFT	24		/* shift to get PG_M, PG_U */
14355124Storek 
14455124Storek /*efine	PG_NOACC	0		** XXX */
14555124Storek #define	PG_KR		0x20000000
14655124Storek #define	PG_KW		0x60000000
14755124Storek #define	PG_URKR		0
14855124Storek #define	PG_UW		0x40000000
14955124Storek 
15055124Storek #ifdef KGDB
15155124Storek /* but we will define one for gdb anyway */
15255124Storek struct pte {
15355124Storek 	u_int	pg_v:1,
15455124Storek 		pg_w:1,
15555124Storek 		pg_s:1,
15655124Storek 		pg_nc:1;
15755124Storek 	enum pgtype { pg_obmem, pg_obio, pg_vme16, pg_vme32 } pg_type:2;
15855124Storek 	u_int	pg_u:1,
15955124Storek 		pg_m:1,
16055124Storek 		pg_mbz:5,
16155124Storek 		pg_pfnum:19;
16255124Storek };
16355124Storek #endif
16455124Storek 
16555124Storek /*
16655124Storek  * These are needed in the register window code
16755124Storek  * to check the validity of (ostensible) user stack PTEs.
16855124Storek  */
16955124Storek #define	PG_VSHIFT	30		/* (va>>vshift)==0 or -1 => valid */
17055124Storek 	/* XXX fix this name, it is a va shift not a pte bit shift! */
17155124Storek 
17255124Storek #define	PG_PROTSHIFT	29
17355124Storek #define	PG_PROTUWRITE	6		/* PG_V,PG_W,!PG_S */
17455124Storek #define	PG_PROTUREAD	4		/* PG_V,!PG_W,!PG_S */
17555124Storek 
17655124Storek /* static __inline int PG_VALID(void *va) {
17755124Storek 	register int t = va; t >>= PG_VSHIFT; return (t == 0 || t == -1);
17855124Storek } */
179