Deleted Added
full compact
pmap.h (1045) pmap.h (1246)
1/*
2 * Copyright (c) 1991 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * the Systems Programming Group of the University of Utah Computer
7 * Science Department and William Jolitz of UUNET Technologies Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * Derived from hp300 version by Mike Hibler, this version by William
38 * Jolitz uses a recursive map [a pde points to the page directory] to
39 * map the page tables using the pagetables themselves. This is done to
40 * reduce the impact on kernel virtual memory for lots of sparse address
41 * space, and to reduce the cost of memory to each process.
42 *
43 * from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
44 * from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
1/*
2 * Copyright (c) 1991 Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * the Systems Programming Group of the University of Utah Computer
7 * Science Department and William Jolitz of UUNET Technologies Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the University of
20 * California, Berkeley and its contributors.
21 * 4. Neither the name of the University nor the names of its contributors
22 * may be used to endorse or promote products derived from this software
23 * without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
36 *
37 * Derived from hp300 version by Mike Hibler, this version by William
38 * Jolitz uses a recursive map [a pde points to the page directory] to
39 * map the page tables using the pagetables themselves. This is done to
40 * reduce the impact on kernel virtual memory for lots of sparse address
41 * space, and to reduce the cost of memory to each process.
42 *
43 * from: hp300: @(#)pmap.h 7.2 (Berkeley) 12/16/90
44 * from: @(#)pmap.h 7.4 (Berkeley) 5/12/91
45 * $Id: pmap.h,v 1.9 1994/01/27 03:36:14 davidg Exp $
45 * $Id: pmap.h,v 1.10 1994/01/31 04:19:00 davidg Exp $
46 */
47
48#ifndef _PMAP_MACHINE_
49#define _PMAP_MACHINE_ 1
50
51#include "vm/vm_prot.h"
52/*
53 * 386 page table entry and page table directory
54 * W.Jolitz, 8/89
55 */
56struct pde
57{
58unsigned int
59 pd_v:1, /* valid bit */
60 pd_prot:2, /* access control */
61 pd_mbz1:2, /* reserved, must be zero */
62 pd_u:1, /* hardware maintained 'used' bit */
63 :1, /* not used */
64 pd_mbz2:2, /* reserved, must be zero */
65 :3, /* reserved for software */
66 pd_pfnum:20; /* physical page frame number of pte's*/
67};
68
69#define PD_MASK 0xffc00000UL /* page directory address bits */
70#define PT_MASK 0x003ff000UL /* page table address bits */
71#define PD_SHIFT 22 /* page directory address shift */
72#define PG_SHIFT 12 /* page table address shift */
73
74struct pte
75{
76unsigned int
77 pg_v:1, /* valid bit */
78 pg_prot:2, /* access control */
79 pg_mbz1:2, /* reserved, must be zero */
80 pg_u:1, /* hardware maintained 'used' bit */
81 pg_m:1, /* hardware maintained modified bit */
82 pg_mbz2:2, /* reserved, must be zero */
83 pg_w:1, /* software, wired down page */
84 :1, /* software (unused) */
85 pg_nc:1, /* 'uncacheable page' bit */
86 pg_pfnum:20; /* physical page frame number */
87};
88
89#define PG_V 0x00000001
90#define PG_RO 0x00000000
91#define PG_RW 0x00000002
92#define PG_u 0x00000004
93#define PG_PROT 0x00000006 /* all protection bits . */
94#define PG_W 0x00000200
95#define PG_N 0x00000800 /* Non-cacheable */
96#define PG_M 0x00000040
97#define PG_U 0x00000020
98#define PG_FRAME 0xfffff000UL
99
100#define PG_NOACC 0
101#define PG_KR 0x00000000
102#define PG_KW 0x00000002
103#define PG_URKR 0x00000004
104#define PG_URKW 0x00000004
105#define PG_UW 0x00000006
106
107/* Garbage for current bastardized pager that assumes a hp300 */
108#define PG_NV 0
109#define PG_CI 0
110
111/*
112 * Page Protection Exception bits
113 */
114#define PGEX_P 0x01 /* Protection violation vs. not present */
115#define PGEX_W 0x02 /* during a Write cycle */
116#define PGEX_U 0x04 /* access from User mode (UPL) */
117
46 */
47
48#ifndef _PMAP_MACHINE_
49#define _PMAP_MACHINE_ 1
50
51#include "vm/vm_prot.h"
52/*
53 * 386 page table entry and page table directory
54 * W.Jolitz, 8/89
55 */
56struct pde
57{
58unsigned int
59 pd_v:1, /* valid bit */
60 pd_prot:2, /* access control */
61 pd_mbz1:2, /* reserved, must be zero */
62 pd_u:1, /* hardware maintained 'used' bit */
63 :1, /* not used */
64 pd_mbz2:2, /* reserved, must be zero */
65 :3, /* reserved for software */
66 pd_pfnum:20; /* physical page frame number of pte's*/
67};
68
69#define PD_MASK 0xffc00000UL /* page directory address bits */
70#define PT_MASK 0x003ff000UL /* page table address bits */
71#define PD_SHIFT 22 /* page directory address shift */
72#define PG_SHIFT 12 /* page table address shift */
73
74struct pte
75{
76unsigned int
77 pg_v:1, /* valid bit */
78 pg_prot:2, /* access control */
79 pg_mbz1:2, /* reserved, must be zero */
80 pg_u:1, /* hardware maintained 'used' bit */
81 pg_m:1, /* hardware maintained modified bit */
82 pg_mbz2:2, /* reserved, must be zero */
83 pg_w:1, /* software, wired down page */
84 :1, /* software (unused) */
85 pg_nc:1, /* 'uncacheable page' bit */
86 pg_pfnum:20; /* physical page frame number */
87};
88
89#define PG_V 0x00000001
90#define PG_RO 0x00000000
91#define PG_RW 0x00000002
92#define PG_u 0x00000004
93#define PG_PROT 0x00000006 /* all protection bits . */
94#define PG_W 0x00000200
95#define PG_N 0x00000800 /* Non-cacheable */
96#define PG_M 0x00000040
97#define PG_U 0x00000020
98#define PG_FRAME 0xfffff000UL
99
100#define PG_NOACC 0
101#define PG_KR 0x00000000
102#define PG_KW 0x00000002
103#define PG_URKR 0x00000004
104#define PG_URKW 0x00000004
105#define PG_UW 0x00000006
106
107/* Garbage for current bastardized pager that assumes a hp300 */
108#define PG_NV 0
109#define PG_CI 0
110
111/*
112 * Page Protection Exception bits
113 */
114#define PGEX_P 0x01 /* Protection violation vs. not present */
115#define PGEX_W 0x02 /* during a Write cycle */
116#define PGEX_U 0x04 /* access from User mode (UPL) */
117
118typedef struct pde pd_entry_t; /* page directory entry */
119typedef struct pte pt_entry_t; /* Mach page table entry */
118/* typedef struct pde pd_entry_t; */ /* page directory entry */
119/* typedef struct pte pt_entry_t; */ /* Mach page table entry */
120typedef unsigned int *pd_entry_t;
121typedef unsigned int *pt_entry_t;
120
121/*
122 * NKPDE controls the virtual space of the kernel, what ever is left, minus
123 * the alternate page table area is given to the user (NUPDE)
124 */
125/*
126 * NKPDE controls the virtual space of the kernel, what ever is left is
127 * given to the user (NUPDE)
128 */
129#ifndef NKPT
130#define NKPT 15 /* actual number of kernel pte's */
131#endif
132#ifndef NKPDE
133#define NKPDE 63 /* addressable number of kpte's */
134#endif
135
136#define NUPDE (NPTEPG-NKPDE) /* number of user pde's */
137
138/*
139 * The *PTDI values control the layout of virtual memory
140 *
141 * XXX This works for now, but I am not real happy with it, I'll fix it
142 * right after I fix locore.s and the magic 28K hole
143 */
144#define APTDPTDI (NPTEPG-1) /* alt ptd entry that points to APTD */
145#define KPTDI (APTDPTDI-NKPDE)/* start of kernel virtual pde's */
146#define PTDPTDI (KPTDI-1) /* ptd entry that points to ptd! */
147#define KSTKPTDI (PTDPTDI-1) /* ptd entry for u./kernel&user stack */
122
123/*
124 * NKPDE controls the virtual space of the kernel, what ever is left, minus
125 * the alternate page table area is given to the user (NUPDE)
126 */
127/*
128 * NKPDE controls the virtual space of the kernel, what ever is left is
129 * given to the user (NUPDE)
130 */
131#ifndef NKPT
132#define NKPT 15 /* actual number of kernel pte's */
133#endif
134#ifndef NKPDE
135#define NKPDE 63 /* addressable number of kpte's */
136#endif
137
138#define NUPDE (NPTEPG-NKPDE) /* number of user pde's */
139
140/*
141 * The *PTDI values control the layout of virtual memory
142 *
143 * XXX This works for now, but I am not real happy with it, I'll fix it
144 * right after I fix locore.s and the magic 28K hole
145 */
146#define APTDPTDI (NPTEPG-1) /* alt ptd entry that points to APTD */
147#define KPTDI (APTDPTDI-NKPDE)/* start of kernel virtual pde's */
148#define PTDPTDI (KPTDI-1) /* ptd entry that points to ptd! */
149#define KSTKPTDI (PTDPTDI-1) /* ptd entry for u./kernel&user stack */
148#define KSTKPTEOFF (NBPG/sizeof(struct pde)-UPAGES) /* pte entry for kernel stack */
150#define KSTKPTEOFF (NBPG/sizeof(pd_entry_t)-UPAGES) /* pte entry for kernel stack */
149
151
150#define PDESIZE sizeof(struct pde) /* for assembly files */
151#define PTESIZE sizeof(struct pte) /* for assembly files */
152#define PDESIZE sizeof(pd_entry_t) /* for assembly files */
153#define PTESIZE sizeof(pt_entry_t) /* for assembly files */
152
153/*
154 * Address of current and alternate address space page table maps
155 * and directories.
156 */
157#ifdef KERNEL
154
155/*
156 * Address of current and alternate address space page table maps
157 * and directories.
158 */
159#ifdef KERNEL
158extern struct pte PTmap[], APTmap[], Upte;
159extern struct pde PTD[], APTD[], PTDpde, APTDpde, Upde;
160extern pt_entry_t PTmap[], APTmap[], Upte;
161extern pd_entry_t PTD[], APTD[], PTDpde, APTDpde, Upde;
160extern pt_entry_t *Sysmap;
161
162extern int IdlePTD; /* physical address of "Idle" state directory */
163#endif
164
165/*
166 * virtual address to page table entry and
167 * to physical address. Likewise for alternate address space.
168 * Note: these work recursively, thus vtopte of a pte will give
169 * the corresponding pde that in turn maps it.
170 */
171#define vtopte(va) (PTmap + i386_btop(va))
172#define kvtopte(va) vtopte(va)
173#define ptetov(pt) (i386_ptob(pt - PTmap))
162extern pt_entry_t *Sysmap;
163
164extern int IdlePTD; /* physical address of "Idle" state directory */
165#endif
166
167/*
168 * virtual address to page table entry and
169 * to physical address. Likewise for alternate address space.
170 * Note: these work recursively, thus vtopte of a pte will give
171 * the corresponding pde that in turn maps it.
172 */
173#define vtopte(va) (PTmap + i386_btop(va))
174#define kvtopte(va) vtopte(va)
175#define ptetov(pt) (i386_ptob(pt - PTmap))
174#define vtophys(va) (i386_ptob(vtopte(va)->pg_pfnum) | ((int)(va) & PGOFSET))
176#define vtophys(va) (((int) (*vtopte(va))&PG_FRAME) | ((int)(va) & PGOFSET))
175#define ispt(va) ((va) >= UPT_MIN_ADDRESS && (va) <= KPT_MAX_ADDRESS)
176
177#define avtopte(va) (APTmap + i386_btop(va))
178#define ptetoav(pt) (i386_ptob(pt - APTmap))
177#define ispt(va) ((va) >= UPT_MIN_ADDRESS && (va) <= KPT_MAX_ADDRESS)
178
179#define avtopte(va) (APTmap + i386_btop(va))
180#define ptetoav(pt) (i386_ptob(pt - APTmap))
179#define avtophys(va) (i386_ptob(avtopte(va)->pg_pfnum) | ((int)(va) & PGOFSET))
181#define avtophys(va) (((int) (*avtopte(va))&PG_FRAME) | ((int)(va) & PGOFSET))
180
181/*
182 * macros to generate page directory/table indicies
183 */
184
185#define pdei(va) (((va)&PD_MASK)>>PD_SHIFT)
186#define ptei(va) (((va)&PT_MASK)>>PG_SHIFT)
187
188/*
189 * Pmap stuff
190 */
191
192struct pmap {
193 pd_entry_t *pm_pdir; /* KVA of page directory */
194 boolean_t pm_pdchanged; /* pdir changed */
195 short pm_dref; /* page directory ref count */
196 short pm_count; /* pmap reference count */
197 simple_lock_data_t pm_lock; /* lock on pmap */
198 struct pmap_statistics pm_stats; /* pmap statistics */
199 long pm_ptpages; /* more stats: PT pages */
200};
201
202typedef struct pmap *pmap_t;
203
204#ifdef KERNEL
205extern pmap_t kernel_pmap;
206#endif
207
208/*
209 * Macros for speed
210 */
211#define PMAP_ACTIVATE(pmapp, pcbp) \
212 if ((pmapp) != NULL /*&& (pmapp)->pm_pdchanged */) { \
213 (pcbp)->pcb_cr3 = \
214 pmap_extract(kernel_pmap, (vm_offset_t)(pmapp)->pm_pdir); \
215 if ((pmapp) == &curproc->p_vmspace->vm_pmap) \
216 load_cr3((pcbp)->pcb_cr3); \
217 (pmapp)->pm_pdchanged = FALSE; \
218 }
219
220#define PMAP_DEACTIVATE(pmapp, pcbp)
221
222/*
223 * For each vm_page_t, there is a list of all currently valid virtual
224 * mappings of that page. An entry is a pv_entry_t, the list is pv_table.
225 */
226typedef struct pv_entry {
227 struct pv_entry *pv_next; /* next pv_entry */
228 pmap_t pv_pmap; /* pmap where mapping lies */
229 vm_offset_t pv_va; /* virtual address for mapping */
230} *pv_entry_t;
231
232#define PV_ENTRY_NULL ((pv_entry_t) 0)
233
234#define PV_CI 0x01 /* all entries must be cache inhibited */
235#define PV_PTPAGE 0x02 /* entry maps a page table page */
236
237#ifdef KERNEL
238
239pv_entry_t pv_table; /* array of entries, one per page */
240
241#define pa_index(pa) atop(pa - vm_first_phys)
242#define pa_to_pvh(pa) (&pv_table[pa_index(pa)])
243
244#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
245
246extern pmap_t pmap_create(vm_size_t);
247extern void pmap_pinit(struct pmap *);
248extern void pmap_destroy(pmap_t);
249extern void pmap_release(struct pmap *);
250extern void pmap_reference(pmap_t);
251extern void pmap_remove(struct pmap *, vm_offset_t, vm_offset_t);
252extern void pmap_protect(struct pmap *, vm_offset_t, vm_offset_t, vm_prot_t);
253extern void pmap_enter(pmap_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t);
254extern void pmap_change_wiring(pmap_t, vm_offset_t, boolean_t);
182
183/*
184 * macros to generate page directory/table indicies
185 */
186
187#define pdei(va) (((va)&PD_MASK)>>PD_SHIFT)
188#define ptei(va) (((va)&PT_MASK)>>PG_SHIFT)
189
190/*
191 * Pmap stuff
192 */
193
194struct pmap {
195 pd_entry_t *pm_pdir; /* KVA of page directory */
196 boolean_t pm_pdchanged; /* pdir changed */
197 short pm_dref; /* page directory ref count */
198 short pm_count; /* pmap reference count */
199 simple_lock_data_t pm_lock; /* lock on pmap */
200 struct pmap_statistics pm_stats; /* pmap statistics */
201 long pm_ptpages; /* more stats: PT pages */
202};
203
204typedef struct pmap *pmap_t;
205
206#ifdef KERNEL
207extern pmap_t kernel_pmap;
208#endif
209
210/*
211 * Macros for speed
212 */
213#define PMAP_ACTIVATE(pmapp, pcbp) \
214 if ((pmapp) != NULL /*&& (pmapp)->pm_pdchanged */) { \
215 (pcbp)->pcb_cr3 = \
216 pmap_extract(kernel_pmap, (vm_offset_t)(pmapp)->pm_pdir); \
217 if ((pmapp) == &curproc->p_vmspace->vm_pmap) \
218 load_cr3((pcbp)->pcb_cr3); \
219 (pmapp)->pm_pdchanged = FALSE; \
220 }
221
222#define PMAP_DEACTIVATE(pmapp, pcbp)
223
224/*
225 * For each vm_page_t, there is a list of all currently valid virtual
226 * mappings of that page. An entry is a pv_entry_t, the list is pv_table.
227 */
228typedef struct pv_entry {
229 struct pv_entry *pv_next; /* next pv_entry */
230 pmap_t pv_pmap; /* pmap where mapping lies */
231 vm_offset_t pv_va; /* virtual address for mapping */
232} *pv_entry_t;
233
234#define PV_ENTRY_NULL ((pv_entry_t) 0)
235
236#define PV_CI 0x01 /* all entries must be cache inhibited */
237#define PV_PTPAGE 0x02 /* entry maps a page table page */
238
239#ifdef KERNEL
240
241pv_entry_t pv_table; /* array of entries, one per page */
242
243#define pa_index(pa) atop(pa - vm_first_phys)
244#define pa_to_pvh(pa) (&pv_table[pa_index(pa)])
245
246#define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
247
248extern pmap_t pmap_create(vm_size_t);
249extern void pmap_pinit(struct pmap *);
250extern void pmap_destroy(pmap_t);
251extern void pmap_release(struct pmap *);
252extern void pmap_reference(pmap_t);
253extern void pmap_remove(struct pmap *, vm_offset_t, vm_offset_t);
254extern void pmap_protect(struct pmap *, vm_offset_t, vm_offset_t, vm_prot_t);
255extern void pmap_enter(pmap_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t);
256extern void pmap_change_wiring(pmap_t, vm_offset_t, boolean_t);
255extern inline struct pte *pmap_pte(pmap_t, vm_offset_t);
257extern inline pt_entry_t *pmap_pte(pmap_t, vm_offset_t);
256extern vm_offset_t pmap_extract(pmap_t, vm_offset_t);
257extern void pmap_copy(pmap_t, pmap_t, vm_offset_t, vm_size_t, vm_offset_t);
258extern void pmap_collect(pmap_t);
259struct pcb; extern void pmap_activate(pmap_t, struct pcb *);
260extern pmap_t pmap_kernel(void);
261extern void pmap_pageable(pmap_t, vm_offset_t, vm_offset_t, boolean_t);
262
263
264#endif /* KERNEL */
265
266#endif /* _PMAP_MACHINE_ */
258extern vm_offset_t pmap_extract(pmap_t, vm_offset_t);
259extern void pmap_copy(pmap_t, pmap_t, vm_offset_t, vm_size_t, vm_offset_t);
260extern void pmap_collect(pmap_t);
261struct pcb; extern void pmap_activate(pmap_t, struct pcb *);
262extern pmap_t pmap_kernel(void);
263extern void pmap_pageable(pmap_t, vm_offset_t, vm_offset_t, boolean_t);
264
265
266#endif /* KERNEL */
267
268#endif /* _PMAP_MACHINE_ */