1 /*-
2 * Copyright (c) 2005 Peter Grehan
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
30
31 /*
32 * Dispatch MI pmap calls to the appropriate MMU implementation
33 * through a previously registered kernel object.
34 *
35 * Before pmap_bootstrap() can be called, a CPU module must have
36 * called pmap_mmu_install(). This may be called multiple times:
37 * the highest priority call will be installed as the default
38 * MMU handler when pmap_bootstrap() is called.
39 *
40 * It is required that kobj_machdep_init() be called before
41 * pmap_bootstrap() to allow the kobj subsystem to initialise. This
42 * in turn requires that mutex_init() has been called.
43 */
44
45 #include <sys/param.h>
46 #include <sys/kernel.h>
47 #include <sys/lock.h>
48 #include <sys/mutex.h>
49 #include <sys/systm.h>
50
51 #include <vm/vm.h>
52 #include <vm/vm_page.h>
53
54 #include <machine/mmuvar.h>
55
56 #include "mmu_if.h"
57
58 static mmu_def_t *mmu_def_impl;
59 static mmu_t mmu_obj;
60 static struct mmu_kobj mmu_kernel_obj;
61 static struct kobj_ops mmu_kernel_kops;
62
63 /*
64 * pmap globals
65 */
66 struct pmap kernel_pmap_store;
67
68 struct msgbuf *msgbufp;
69 vm_offset_t msgbuf_phys;
70
71 vm_offset_t kernel_vm_end;
72 vm_offset_t phys_avail[PHYS_AVAIL_SZ];
73 vm_offset_t virtual_avail;
74 vm_offset_t virtual_end;
75
76 int pmap_bootstrapped;
77
78 void
79 pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired)
80 {
81 MMU_CHANGE_WIRING(mmu_obj, pmap, va, wired);
82 }
83
84 void
85 pmap_clear_modify(vm_page_t m)
86 {
87 MMU_CLEAR_MODIFY(mmu_obj, m);
88 }
89
90 void
91 pmap_clear_reference(vm_page_t m)
92 {
93 MMU_CLEAR_REFERENCE(mmu_obj, m);
94 }
95
96 void
97 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr,
98 vm_size_t len, vm_offset_t src_addr)
99 {
100 MMU_COPY(mmu_obj, dst_pmap, src_pmap, dst_addr, len, src_addr);
101 }
102
103 void
104 pmap_copy_page(vm_page_t src, vm_page_t dst)
105 {
106 MMU_COPY_PAGE(mmu_obj, src, dst);
107 }
108
109 void
110 pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t p, vm_prot_t prot,
111 boolean_t wired)
112 {
113 MMU_ENTER(mmu_obj, pmap, va, p, prot, wired);
114 }
115
116 void
117 pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
118 vm_page_t m_start, vm_prot_t prot)
119 {
120 MMU_ENTER_OBJECT(mmu_obj, pmap, start, end, m_start, prot);
121 }
122
123 void
124 pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
125 {
126 MMU_ENTER_QUICK(mmu_obj, pmap, va, m, prot);
127 }
128
129 vm_paddr_t
130 pmap_extract(pmap_t pmap, vm_offset_t va)
131 {
132 return (MMU_EXTRACT(mmu_obj, pmap, va));
133 }
134
135 vm_page_t
136 pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
137 {
138 return (MMU_EXTRACT_AND_HOLD(mmu_obj, pmap, va, prot));
139 }
140
141 void
142 pmap_growkernel(vm_offset_t va)
143 {
144 MMU_GROWKERNEL(mmu_obj, va);
145 }
146
147 void
148 pmap_init(void)
149 {
150 MMU_INIT(mmu_obj);
151 }
152
153 boolean_t
154 pmap_is_modified(vm_page_t m)
155 {
156 return (MMU_IS_MODIFIED(mmu_obj, m));
157 }
158
159 boolean_t
160 pmap_is_prefaultable(pmap_t pmap, vm_offset_t va)
161 {
162 return (MMU_IS_PREFAULTABLE(mmu_obj, pmap, va));
163 }
164
165 boolean_t
166 pmap_ts_referenced(vm_page_t m)
167 {
168 return (MMU_TS_REFERENCED(mmu_obj, m));
169 }
170
171 vm_offset_t
172 pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
173 {
174 return (MMU_MAP(mmu_obj, virt, start, end, prot));
175 }
176
177 void
178 pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object,
179 vm_pindex_t pindex, vm_size_t size)
180 {
181 MMU_OBJECT_INIT_PT(mmu_obj, pmap, addr, object, pindex, size);
182 }
183
184 boolean_t
185 pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
186 {
187 return (MMU_PAGE_EXISTS_QUICK(mmu_obj, pmap, m));
188 }
189
190 void
191 pmap_page_init(vm_page_t m)
192 {
193 MMU_PAGE_INIT(mmu_obj, m);
194 }
195
196 int
197 pmap_pinit(pmap_t pmap)
198 {
199 MMU_PINIT(mmu_obj, pmap);
200 return (1);
201 }
202
203 void
204 pmap_pinit0(pmap_t pmap)
205 {
206 MMU_PINIT0(mmu_obj, pmap);
207 }
208
209 void
210 pmap_protect(pmap_t pmap, vm_offset_t start, vm_offset_t end, vm_prot_t prot)
211 {
212 MMU_PROTECT(mmu_obj, pmap, start, end, prot);
213 }
214
215 void
216 pmap_qenter(vm_offset_t start, vm_page_t *m, int count)
217 {
218 MMU_QENTER(mmu_obj, start, m, count);
219 }
220
221 void
222 pmap_qremove(vm_offset_t start, int count)
223 {
224 MMU_QREMOVE(mmu_obj, start, count);
225 }
226
227 void
228 pmap_release(pmap_t pmap)
229 {
230 MMU_RELEASE(mmu_obj, pmap);
231 }
232
233 void
234 pmap_remove(pmap_t pmap, vm_offset_t start, vm_offset_t end)
235 {
236 MMU_REMOVE(mmu_obj, pmap, start, end);
237 }
238
239 void
240 pmap_remove_all(vm_page_t m)
241 {
242 MMU_REMOVE_ALL(mmu_obj, m);
243 }
244
245 void
246 pmap_remove_pages(pmap_t pmap)
247 {
248 MMU_REMOVE_PAGES(mmu_obj, pmap);
249 }
250
251 void
252 pmap_remove_write(vm_page_t m)
253 {
254 MMU_REMOVE_WRITE(mmu_obj, m);
255 }
256
257 void
258 pmap_zero_page(vm_page_t m)
259 {
260 MMU_ZERO_PAGE(mmu_obj, m);
261 }
262
263 void
264 pmap_zero_page_area(vm_page_t m, int off, int size)
265 {
266 MMU_ZERO_PAGE_AREA(mmu_obj, m, off, size);
267 }
268
269 void
270 pmap_zero_page_idle(vm_page_t m)
271 {
272 MMU_ZERO_PAGE_IDLE(mmu_obj, m);
273 }
274
275 int
276 pmap_mincore(pmap_t pmap, vm_offset_t addr)
277 {
278 return (MMU_MINCORE(mmu_obj, pmap, addr));
279 }
280
281 void
282 pmap_activate(struct thread *td)
283 {
284 MMU_ACTIVATE(mmu_obj, td);
285 }
286
287 void
288 pmap_deactivate(struct thread *td)
289 {
290 MMU_DEACTIVATE(mmu_obj, td);
291 }
292
293 vm_offset_t
294 pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
295 {
296 return (MMU_ADDR_HINT(mmu_obj, obj, addr, size));
297 }
298
299
300
301 /*
302 * Routines used in machine-dependent code
303 */
304 void
305 pmap_bootstrap(vm_offset_t start, vm_offset_t end)
306 {
307 mmu_obj = &mmu_kernel_obj;
308
309 /*
310 * Take care of compiling the selected class, and
311 * then statically initialise the MMU object
312 */
313 kobj_class_compile_static(mmu_def_impl, &mmu_kernel_kops);
314 kobj_init((kobj_t)mmu_obj, mmu_def_impl);
315
316 MMU_BOOTSTRAP(mmu_obj, start, end);
317 }
318
319 void *
320 pmap_mapdev(vm_offset_t pa, vm_size_t size)
321 {
322 return (MMU_MAPDEV(mmu_obj, pa, size));
323 }
324
325 void
326 pmap_unmapdev(vm_offset_t va, vm_size_t size)
327 {
328 MMU_UNMAPDEV(mmu_obj, va, size);
329 }
330
331 vm_offset_t
332 pmap_kextract(vm_offset_t va)
333 {
334 return (MMU_KEXTRACT(mmu_obj, va));
335 }
336
337 void
338 pmap_kenter(vm_offset_t va, vm_offset_t pa)
339 {
340 MMU_KENTER(mmu_obj, va, pa);
341 }
342
343 boolean_t
344 pmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size)
345 {
346 return (MMU_DEV_DIRECT_MAPPED(mmu_obj, pa, size));
347 }
348
349 boolean_t
350 pmap_page_executable(vm_page_t pg)
351 {
352 return (MMU_PAGE_EXECUTABLE(mmu_obj, pg));
353 }
354
355 /*
356 * MMU install routines. Highest priority wins, equal priority also
357 * overrides allowing last-set to win.
358 */
359 SET_DECLARE(mmu_set, mmu_def_t);
360
361 boolean_t
362 pmap_mmu_install(char *name, int prio)
363 {
364 mmu_def_t **mmupp, *mmup;
365 static int curr_prio = 0;
366
367 /*
368 * Try and locate the MMU kobj corresponding to the name
369 */
370 SET_FOREACH(mmupp, mmu_set) {
371 mmup = *mmupp;
372
373 if (mmup->name &&
374 !strcmp(mmup->name, name) &&
375 prio >= curr_prio) {
376 curr_prio = prio;
377 mmu_def_impl = mmup;
378 return (TRUE);
379 }
380 }
381
382 return (FALSE);
383 }
Cache object: 8cd77ca3ea07b3c7004a731cea7df7c4
|