2 * Copyright (c) 2005 Peter Grehan
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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
28 #include <sys/cdefs.h>
29 __FBSDID("$FreeBSD$");
32 * Dispatch MI pmap calls to the appropriate MMU implementation
33 * through a previously registered kernel object.
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.
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.
45 #include <sys/param.h>
46 #include <sys/kernel.h>
48 #include <sys/mutex.h>
49 #include <sys/systm.h>
52 #include <vm/vm_page.h>
54 #include <machine/mmuvar.h>
58 static mmu_def_t *mmu_def_impl;
60 static struct mmu_kobj mmu_kernel_obj;
61 static struct kobj_ops mmu_kernel_kops;
66 struct pmap kernel_pmap_store;
68 struct msgbuf *msgbufp;
69 vm_offset_t msgbuf_phys;
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;
76 int pmap_bootstrapped;
79 pmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired)
81 MMU_CHANGE_WIRING(mmu_obj, pmap, va, wired);
85 pmap_clear_modify(vm_page_t m)
87 MMU_CLEAR_MODIFY(mmu_obj, m);
91 pmap_clear_reference(vm_page_t m)
93 MMU_CLEAR_REFERENCE(mmu_obj, m);
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)
100 MMU_COPY(mmu_obj, dst_pmap, src_pmap, dst_addr, len, src_addr);
104 pmap_copy_page(vm_page_t src, vm_page_t dst)
106 MMU_COPY_PAGE(mmu_obj, src, dst);
110 pmap_enter(pmap_t pmap, vm_offset_t va, vm_prot_t access, vm_page_t p,
111 vm_prot_t prot, boolean_t wired)
113 MMU_ENTER(mmu_obj, pmap, va, p, prot, wired);
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)
120 MMU_ENTER_OBJECT(mmu_obj, pmap, start, end, m_start, prot);
124 pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
126 MMU_ENTER_QUICK(mmu_obj, pmap, va, m, prot);
130 pmap_extract(pmap_t pmap, vm_offset_t va)
132 return (MMU_EXTRACT(mmu_obj, pmap, va));
136 pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
138 return (MMU_EXTRACT_AND_HOLD(mmu_obj, pmap, va, prot));
142 pmap_growkernel(vm_offset_t va)
144 MMU_GROWKERNEL(mmu_obj, va);
154 pmap_is_modified(vm_page_t m)
156 return (MMU_IS_MODIFIED(mmu_obj, m));
160 pmap_is_prefaultable(pmap_t pmap, vm_offset_t va)
162 return (MMU_IS_PREFAULTABLE(mmu_obj, pmap, va));
166 pmap_ts_referenced(vm_page_t m)
168 return (MMU_TS_REFERENCED(mmu_obj, m));
172 pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
174 return (MMU_MAP(mmu_obj, virt, start, end, prot));
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)
181 MMU_OBJECT_INIT_PT(mmu_obj, pmap, addr, object, pindex, size);
185 pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
187 return (MMU_PAGE_EXISTS_QUICK(mmu_obj, pmap, m));
191 pmap_page_init(vm_page_t m)
193 MMU_PAGE_INIT(mmu_obj, m);
197 pmap_pinit(pmap_t pmap)
199 MMU_PINIT(mmu_obj, pmap);
204 pmap_pinit0(pmap_t pmap)
206 MMU_PINIT0(mmu_obj, pmap);
210 pmap_protect(pmap_t pmap, vm_offset_t start, vm_offset_t end, vm_prot_t prot)
212 MMU_PROTECT(mmu_obj, pmap, start, end, prot);
216 pmap_qenter(vm_offset_t start, vm_page_t *m, int count)
218 MMU_QENTER(mmu_obj, start, m, count);
222 pmap_qremove(vm_offset_t start, int count)
224 MMU_QREMOVE(mmu_obj, start, count);
228 pmap_release(pmap_t pmap)
230 MMU_RELEASE(mmu_obj, pmap);
234 pmap_remove(pmap_t pmap, vm_offset_t start, vm_offset_t end)
236 MMU_REMOVE(mmu_obj, pmap, start, end);
240 pmap_remove_all(vm_page_t m)
242 MMU_REMOVE_ALL(mmu_obj, m);
246 pmap_remove_pages(pmap_t pmap)
248 MMU_REMOVE_PAGES(mmu_obj, pmap);
252 pmap_remove_write(vm_page_t m)
254 MMU_REMOVE_WRITE(mmu_obj, m);
258 pmap_zero_page(vm_page_t m)
260 MMU_ZERO_PAGE(mmu_obj, m);
264 pmap_zero_page_area(vm_page_t m, int off, int size)
266 MMU_ZERO_PAGE_AREA(mmu_obj, m, off, size);
270 pmap_zero_page_idle(vm_page_t m)
272 MMU_ZERO_PAGE_IDLE(mmu_obj, m);
276 pmap_mincore(pmap_t pmap, vm_offset_t addr)
278 return (MMU_MINCORE(mmu_obj, pmap, addr));
282 pmap_activate(struct thread *td)
284 MMU_ACTIVATE(mmu_obj, td);
288 pmap_deactivate(struct thread *td)
290 MMU_DEACTIVATE(mmu_obj, td);
294 pmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
296 return (MMU_ADDR_HINT(mmu_obj, obj, addr, size));
300 * Increase the starting virtual address of the given mapping if a
301 * different alignment might result in more superpage mappings.
304 pmap_align_superpage(vm_object_t object, vm_ooffset_t offset,
305 vm_offset_t *addr, vm_size_t size)
312 * Routines used in machine-dependent code
315 pmap_bootstrap(vm_offset_t start, vm_offset_t end)
317 mmu_obj = &mmu_kernel_obj;
320 * Take care of compiling the selected class, and
321 * then statically initialise the MMU object
323 kobj_class_compile_static(mmu_def_impl, &mmu_kernel_kops);
324 kobj_init((kobj_t)mmu_obj, mmu_def_impl);
326 MMU_BOOTSTRAP(mmu_obj, start, end);
330 pmap_mapdev(vm_offset_t pa, vm_size_t size)
332 return (MMU_MAPDEV(mmu_obj, pa, size));
336 pmap_unmapdev(vm_offset_t va, vm_size_t size)
338 MMU_UNMAPDEV(mmu_obj, va, size);
342 pmap_kextract(vm_offset_t va)
344 return (MMU_KEXTRACT(mmu_obj, va));
348 pmap_kenter(vm_offset_t va, vm_offset_t pa)
350 MMU_KENTER(mmu_obj, va, pa);
354 pmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size)
356 return (MMU_DEV_DIRECT_MAPPED(mmu_obj, pa, size));
360 pmap_page_executable(vm_page_t pg)
362 return (MMU_PAGE_EXECUTABLE(mmu_obj, pg));
366 * MMU install routines. Highest priority wins, equal priority also
367 * overrides allowing last-set to win.
369 SET_DECLARE(mmu_set, mmu_def_t);
372 pmap_mmu_install(char *name, int prio)
374 mmu_def_t **mmupp, *mmup;
375 static int curr_prio = 0;
378 * Try and locate the MMU kobj corresponding to the name
380 SET_FOREACH(mmupp, mmu_set) {
384 !strcmp(mmup->name, name) &&