xref: /netbsd-src/sys/arch/i386/include/pmap.h (revision ae9172d6cd9432a6a1a56760d86b32c57a66c39c)
1 /*	$NetBSD: pmap.h,v 1.16 1994/10/31 06:30:52 andrew Exp $	*/
2 
3 /*
4  * Copyright (c) 1991 Regents of the University of California.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to Berkeley by
8  * the Systems Programming Group of the University of Utah Computer
9  * Science Department and William Jolitz of UUNET Technologies Inc.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by the University of
22  *	California, Berkeley and its contributors.
23  * 4. Neither the name of the University nor the names of its contributors
24  *    may be used to endorse or promote products derived from this software
25  *    without specific prior written permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  *	@(#)pmap.h	7.4 (Berkeley) 5/12/91
40  */
41 
42 /*
43  * Derived from hp300 version by Mike Hibler, this version by William
44  * Jolitz uses a recursive map [a pde points to the page directory] to
45  * map the page tables using the pagetables themselves. This is done to
46  * reduce the impact on kernel virtual memory for lots of sparse address
47  * space, and to reduce the cost of memory to each process.
48  *
49  * from hp300:	@(#)pmap.h	7.2 (Berkeley) 12/16/90
50  */
51 
52 #ifndef	_I386_PMAP_H_
53 #define	_I386_PMAP_H_
54 
55 #include <machine/cpufunc.h>
56 #include <machine/pte.h>
57 
58 /*
59  * 386 page table entry and page table directory
60  * W.Jolitz, 8/89
61  */
62 
63 /*
64  * One page directory, shared between
65  * kernel and user modes.
66  */
67 #define	UPTDI		0x3de		/* ptd entry for u./kernel&user stack */
68 #define	PTDPTDI		0x3df		/* ptd entry that points to ptd! */
69 #define	KPTDI		0x3e0		/* start of kernel virtual pde's */
70 #define	NKPDE		12
71 #define	APTDPTDI	0x3ff		/* start of alternate page directory */
72 
73 /*
74  * Address of current and alternate address space page table maps
75  * and directories.
76  */
77 #ifdef KERNEL
78 extern pt_entry_t	PTmap[], APTmap[], Upte;
79 extern pd_entry_t	PTD[], APTD[], PTDpde, APTDpde, Upde;
80 extern pt_entry_t	*Sysmap;
81 
82 extern int	IdlePTD;	/* physical address of "Idle" state directory */
83 
84 void pmap_bootstrap __P((vm_offset_t start));
85 boolean_t pmap_testbit __P((vm_offset_t, int));
86 void pmap_changebit __P((vm_offset_t, int, int));
87 __pure u_int pmap_page_index __P((vm_offset_t));
88 #endif
89 
90 /*
91  * virtual address to page table entry and
92  * to physical address. Likewise for alternate address space.
93  * Note: these work recursively, thus vtopte of a pte will give
94  * the corresponding pde that in turn maps it.
95  */
96 #define	vtopte(va)	(PTmap + i386_btop(va))
97 #define	kvtopte(va)	vtopte(va)
98 #define	ptetov(pt)	(i386_ptob(pt - PTmap))
99 #define	vtophys(va) \
100 	((*vtopte(va) & PG_FRAME) | ((unsigned)(va) & ~PG_FRAME))
101 
102 #define	avtopte(va)	(APTmap + i386_btop(va))
103 #define	ptetoav(pt)	(i386_ptob(pt - APTmap))
104 #define	avtophys(va) \
105 	((*avtopte(va) & PG_FRAME) | ((unsigned)(va) & ~PG_FRAME))
106 
107 /*
108  * macros to generate page directory/table indicies
109  */
110 #define	pdei(va)	(((va) & PD_MASK) >> PDSHIFT)
111 #define	ptei(va)	(((va) & PT_MASK) >> PGSHIFT)
112 
113 /*
114  * Pmap stuff
115  */
116 typedef struct pmap {
117 	pd_entry_t		*pm_pdir;	/* KVA of page directory */
118 	boolean_t		pm_pdchanged;	/* pdir changed */
119 	short			pm_dref;	/* page directory ref count */
120 	short			pm_count;	/* pmap reference count */
121 	simple_lock_data_t	pm_lock;	/* lock on pmap */
122 	struct pmap_statistics	pm_stats;	/* pmap statistics */
123 	long			pm_ptpages;	/* more stats: PT pages */
124 } *pmap_t;
125 
126 /*
127  * For each vm_page_t, there is a list of all currently valid virtual
128  * mappings of that page.  An entry is a pv_entry, the list is pv_table.
129  */
130 struct pv_entry {
131 	struct pv_entry	*pv_next;	/* next pv_entry */
132 	pmap_t		pv_pmap;	/* pmap where mapping lies */
133 	vm_offset_t	pv_va;		/* virtual address for mapping */
134 };
135 
136 struct pv_page;
137 
138 struct pv_page_info {
139 	TAILQ_ENTRY(pv_page) pgi_list;
140 	struct pv_entry *pgi_freelist;
141 	int pgi_nfree;
142 };
143 
144 /*
145  * This is basically:
146  * ((NBPG - sizeof(struct pv_page_info)) / sizeof(struct pv_entry))
147  */
148 #define	NPVPPG	340
149 
150 struct pv_page {
151 	struct pv_page_info pvp_pgi;
152 	struct pv_entry pvp_pv[NPVPPG];
153 };
154 
155 #ifdef	KERNEL
156 extern struct pmap	kernel_pmap_store;
157 struct pv_entry		*pv_table;	/* array of entries, one per page */
158 
159 #define	kernel_pmap			(&kernel_pmap_store)
160 #define	pmap_resident_count(pmap)	((pmap)->pm_stats.resident_count)
161 #define	pmap_update()			tlbflush()
162 
163 static __inline void
164 pmap_clear_modify(vm_offset_t pa)
165 {
166 	pmap_changebit(pa, 0, ~PG_M);
167 }
168 
169 static __inline void
170 pmap_clear_reference(vm_offset_t pa)
171 {
172 	pmap_changebit(pa, 0, ~PG_U);
173 }
174 
175 static __inline void
176 pmap_copy_on_write(vm_offset_t pa)
177 {
178 	pmap_changebit(pa, PG_RO, ~PG_RW);
179 }
180 
181 static __inline boolean_t
182 pmap_is_modified(vm_offset_t pa)
183 {
184 	return pmap_testbit(pa, PG_M);
185 }
186 
187 static __inline boolean_t
188 pmap_is_referenced(vm_offset_t pa)
189 {
190 	return pmap_testbit(pa, PG_U);
191 }
192 
193 static __inline vm_offset_t
194 pmap_phys_address(int ppn)
195 {
196 	return i386_ptob(ppn);
197 }
198 
199 #endif	/* KERNEL */
200 
201 #endif /* _I386_PMAP_H_ */
202