pmap_dispatch.c revision 173361
1152179Sgrehan/*-
2152179Sgrehan * Copyright (c) 2005 Peter Grehan
3152179Sgrehan * All rights reserved.
4152179Sgrehan *
5152179Sgrehan * Redistribution and use in source and binary forms, with or without
6152179Sgrehan * modification, are permitted provided that the following conditions
7152179Sgrehan * are met:
8152179Sgrehan * 1. Redistributions of source code must retain the above copyright
9152179Sgrehan *    notice, this list of conditions and the following disclaimer.
10152179Sgrehan * 2. Redistributions in binary form must reproduce the above copyright
11152179Sgrehan *    notice, this list of conditions and the following disclaimer in the
12152179Sgrehan *    documentation and/or other materials provided with the distribution.
13152179Sgrehan *
14152179Sgrehan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15152179Sgrehan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16152179Sgrehan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17152179Sgrehan * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18152179Sgrehan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19152179Sgrehan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20152179Sgrehan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21152179Sgrehan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22152179Sgrehan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23152179Sgrehan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24152179Sgrehan * SUCH DAMAGE.
25152179Sgrehan *
26152179Sgrehan */
27152179Sgrehan
28152179Sgrehan#include <sys/cdefs.h>
29152179Sgrehan__FBSDID("$FreeBSD: head/sys/powerpc/powerpc/pmap_dispatch.c 173361 2007-11-05 11:36:16Z kib $");
30152179Sgrehan
31152179Sgrehan/*
32152179Sgrehan * Dispatch MI pmap calls to the appropriate MMU implementation
33152179Sgrehan * through a previously registered kernel object.
34152179Sgrehan *
35152179Sgrehan * Before pmap_bootstrap() can be called, a CPU module must have
36152179Sgrehan * called pmap_mmu_install(). This may be called multiple times:
37152179Sgrehan * the highest priority call will be installed as the default
38152179Sgrehan * MMU handler when pmap_bootstrap() is called.
39152179Sgrehan *
40152179Sgrehan * It is required that kobj_machdep_init() be called before
41152179Sgrehan * pmap_bootstrap() to allow the kobj subsystem to initialise. This
42152179Sgrehan * in turn requires that mutex_init() has been called.
43152179Sgrehan */
44152179Sgrehan
45152179Sgrehan#include <sys/param.h>
46152179Sgrehan#include <sys/kernel.h>
47152179Sgrehan#include <sys/lock.h>
48152179Sgrehan#include <sys/mutex.h>
49152179Sgrehan#include <sys/systm.h>
50152179Sgrehan
51152179Sgrehan#include <vm/vm.h>
52152179Sgrehan#include <vm/vm_page.h>
53152179Sgrehan
54152179Sgrehan#include <machine/mmuvar.h>
55152179Sgrehan
56152179Sgrehan#include "mmu_if.h"
57152179Sgrehan
58152179Sgrehanstatic mmu_def_t	*mmu_def_impl;
59152179Sgrehanstatic mmu_t		mmu_obj;
60152179Sgrehanstatic struct mmu_kobj	mmu_kernel_obj;
61152179Sgrehanstatic struct kobj_ops	mmu_kernel_kops;
62152179Sgrehan
63152179Sgrehan/*
64152179Sgrehan * pmap globals
65152179Sgrehan */
66152179Sgrehanstruct pmap kernel_pmap_store;
67152179Sgrehan
68152179Sgrehanstruct msgbuf *msgbufp;
69152179Sgrehanvm_offset_t    msgbuf_phys;
70152179Sgrehan
71152179Sgrehanvm_offset_t kernel_vm_end;
72152179Sgrehanvm_offset_t phys_avail[PHYS_AVAIL_SZ];
73152179Sgrehanvm_offset_t virtual_avail;
74152179Sgrehanvm_offset_t virtual_end;
75152179Sgrehan
76152179Sgrehanint pmap_bootstrapped;
77152179Sgrehan
78152179Sgrehanvoid
79152179Sgrehanpmap_change_wiring(pmap_t pmap, vm_offset_t va, boolean_t wired)
80152179Sgrehan{
81152179Sgrehan	MMU_CHANGE_WIRING(mmu_obj, pmap, va, wired);
82152179Sgrehan}
83152179Sgrehan
84152179Sgrehanvoid
85152179Sgrehanpmap_clear_modify(vm_page_t m)
86152179Sgrehan{
87152179Sgrehan	MMU_CLEAR_MODIFY(mmu_obj, m);
88152179Sgrehan}
89152179Sgrehan
90152179Sgrehanvoid
91152179Sgrehanpmap_clear_reference(vm_page_t m)
92152179Sgrehan{
93152179Sgrehan	MMU_CLEAR_REFERENCE(mmu_obj, m);
94152179Sgrehan}
95152179Sgrehan
96152179Sgrehanvoid
97152179Sgrehanpmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr,
98152179Sgrehan    vm_size_t len, vm_offset_t src_addr)
99152179Sgrehan{
100152179Sgrehan	MMU_COPY(mmu_obj, dst_pmap, src_pmap, dst_addr, len, src_addr);
101152179Sgrehan}
102152179Sgrehan
103152179Sgrehanvoid
104152179Sgrehanpmap_copy_page(vm_page_t src, vm_page_t dst)
105152179Sgrehan{
106152179Sgrehan	MMU_COPY_PAGE(mmu_obj, src, dst);
107152179Sgrehan}
108152179Sgrehan
109152179Sgrehanvoid
110152179Sgrehanpmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t p, vm_prot_t prot,
111152179Sgrehan    boolean_t wired)
112152179Sgrehan{
113152179Sgrehan	MMU_ENTER(mmu_obj, pmap, va, p, prot, wired);
114152179Sgrehan}
115152179Sgrehan
116159323Salcvoid
117159323Salcpmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
118159323Salc    vm_page_t m_start, vm_prot_t prot)
119159323Salc{
120159323Salc	MMU_ENTER_OBJECT(mmu_obj, pmap, start, end, m_start, prot);
121159323Salc}
122159323Salc
123159627Supsvoid
124159627Supspmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
125152179Sgrehan{
126159627Sups	MMU_ENTER_QUICK(mmu_obj, pmap, va, m, prot);
127152179Sgrehan}
128152179Sgrehan
129152179Sgrehanvm_paddr_t
130152179Sgrehanpmap_extract(pmap_t pmap, vm_offset_t va)
131152179Sgrehan{
132152179Sgrehan	return (MMU_EXTRACT(mmu_obj, pmap, va));
133152179Sgrehan}
134152179Sgrehan
135152179Sgrehanvm_page_t
136152179Sgrehanpmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
137152179Sgrehan{
138152179Sgrehan	return (MMU_EXTRACT_AND_HOLD(mmu_obj, pmap, va, prot));
139152179Sgrehan}
140152179Sgrehan
141152179Sgrehanvoid
142152179Sgrehanpmap_growkernel(vm_offset_t va)
143152179Sgrehan{
144152179Sgrehan	MMU_GROWKERNEL(mmu_obj, va);
145152179Sgrehan}
146152179Sgrehan
147152179Sgrehanvoid
148152179Sgrehanpmap_init(void)
149152179Sgrehan{
150152179Sgrehan	MMU_INIT(mmu_obj);
151152179Sgrehan}
152152179Sgrehan
153152179Sgrehanboolean_t
154152179Sgrehanpmap_is_modified(vm_page_t m)
155152179Sgrehan{
156152179Sgrehan	return (MMU_IS_MODIFIED(mmu_obj, m));
157152179Sgrehan}
158152179Sgrehan
159152179Sgrehanboolean_t
160152179Sgrehanpmap_is_prefaultable(pmap_t pmap, vm_offset_t va)
161152179Sgrehan{
162152179Sgrehan	return (MMU_IS_PREFAULTABLE(mmu_obj, pmap, va));
163152179Sgrehan}
164152179Sgrehan
165152179Sgrehanboolean_t
166152179Sgrehanpmap_ts_referenced(vm_page_t m)
167152179Sgrehan{
168152179Sgrehan	return (MMU_TS_REFERENCED(mmu_obj, m));
169152179Sgrehan}
170152179Sgrehan
171152179Sgrehanvm_offset_t
172152179Sgrehanpmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
173152179Sgrehan{
174152179Sgrehan	return (MMU_MAP(mmu_obj, virt, start, end, prot));
175152179Sgrehan}
176152179Sgrehan
177152179Sgrehanvoid
178152179Sgrehanpmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object,
179152179Sgrehan    vm_pindex_t pindex, vm_size_t size)
180152179Sgrehan{
181152179Sgrehan	MMU_OBJECT_INIT_PT(mmu_obj, pmap, addr, object, pindex, size);
182152179Sgrehan}
183152179Sgrehan
184152179Sgrehanboolean_t
185152179Sgrehanpmap_page_exists_quick(pmap_t pmap, vm_page_t m)
186152179Sgrehan{
187152179Sgrehan	return (MMU_PAGE_EXISTS_QUICK(mmu_obj, pmap, m));
188152179Sgrehan}
189152179Sgrehan
190152179Sgrehanvoid
191152179Sgrehanpmap_page_init(vm_page_t m)
192152179Sgrehan{
193152179Sgrehan	MMU_PAGE_INIT(mmu_obj, m);
194152179Sgrehan}
195152179Sgrehan
196173361Skibint
197152179Sgrehanpmap_pinit(pmap_t pmap)
198152179Sgrehan{
199152179Sgrehan	MMU_PINIT(mmu_obj, pmap);
200173361Skib	return (1);
201152179Sgrehan}
202152179Sgrehan
203152179Sgrehanvoid
204152179Sgrehanpmap_pinit0(pmap_t pmap)
205152179Sgrehan{
206152179Sgrehan	MMU_PINIT0(mmu_obj, pmap);
207152179Sgrehan}
208152179Sgrehan
209152179Sgrehanvoid
210152179Sgrehanpmap_protect(pmap_t pmap, vm_offset_t start, vm_offset_t end, vm_prot_t prot)
211152179Sgrehan{
212152179Sgrehan	MMU_PROTECT(mmu_obj, pmap, start, end, prot);
213152179Sgrehan}
214152179Sgrehan
215152179Sgrehanvoid
216152179Sgrehanpmap_qenter(vm_offset_t start, vm_page_t *m, int count)
217152179Sgrehan{
218152179Sgrehan	MMU_QENTER(mmu_obj, start, m, count);
219152179Sgrehan}
220152179Sgrehan
221152179Sgrehanvoid
222152179Sgrehanpmap_qremove(vm_offset_t start, int count)
223152179Sgrehan{
224152179Sgrehan	MMU_QREMOVE(mmu_obj, start, count);
225152179Sgrehan}
226152179Sgrehan
227152179Sgrehanvoid
228152179Sgrehanpmap_release(pmap_t pmap)
229152179Sgrehan{
230152179Sgrehan	MMU_RELEASE(mmu_obj, pmap);
231152179Sgrehan}
232152179Sgrehan
233152179Sgrehanvoid
234152179Sgrehanpmap_remove(pmap_t pmap, vm_offset_t start, vm_offset_t end)
235152179Sgrehan{
236152179Sgrehan	MMU_REMOVE(mmu_obj, pmap, start, end);
237152179Sgrehan}
238152179Sgrehan
239152179Sgrehanvoid
240152179Sgrehanpmap_remove_all(vm_page_t m)
241152179Sgrehan{
242152179Sgrehan	MMU_REMOVE_ALL(mmu_obj, m);
243152179Sgrehan}
244152179Sgrehan
245152179Sgrehanvoid
246157443Speterpmap_remove_pages(pmap_t pmap)
247152179Sgrehan{
248157443Speter	MMU_REMOVE_PAGES(mmu_obj, pmap);
249152179Sgrehan}
250152179Sgrehan
251152179Sgrehanvoid
252160889Salcpmap_remove_write(vm_page_t m)
253160889Salc{
254160889Salc	MMU_REMOVE_WRITE(mmu_obj, m);
255160889Salc}
256160889Salc
257160889Salcvoid
258152179Sgrehanpmap_zero_page(vm_page_t m)
259152179Sgrehan{
260152179Sgrehan	MMU_ZERO_PAGE(mmu_obj, m);
261152179Sgrehan}
262152179Sgrehan
263152179Sgrehanvoid
264152179Sgrehanpmap_zero_page_area(vm_page_t m, int off, int size)
265152179Sgrehan{
266152179Sgrehan	MMU_ZERO_PAGE_AREA(mmu_obj, m, off, size);
267152179Sgrehan}
268152179Sgrehan
269152179Sgrehanvoid
270152179Sgrehanpmap_zero_page_idle(vm_page_t m)
271152179Sgrehan{
272152179Sgrehan	MMU_ZERO_PAGE_IDLE(mmu_obj, m);
273152179Sgrehan}
274152179Sgrehan
275152179Sgrehanint
276152179Sgrehanpmap_mincore(pmap_t pmap, vm_offset_t addr)
277152179Sgrehan{
278152179Sgrehan	return (MMU_MINCORE(mmu_obj, pmap, addr));
279152179Sgrehan}
280152179Sgrehan
281152179Sgrehanvoid
282152179Sgrehanpmap_activate(struct thread *td)
283152179Sgrehan{
284152179Sgrehan	MMU_ACTIVATE(mmu_obj, td);
285152179Sgrehan}
286152179Sgrehan
287152179Sgrehanvoid
288152179Sgrehanpmap_deactivate(struct thread *td)
289152179Sgrehan{
290152179Sgrehan	MMU_DEACTIVATE(mmu_obj, td);
291152179Sgrehan}
292152179Sgrehan
293152179Sgrehanvm_offset_t
294152179Sgrehanpmap_addr_hint(vm_object_t obj, vm_offset_t addr, vm_size_t size)
295152179Sgrehan{
296152179Sgrehan	return (MMU_ADDR_HINT(mmu_obj, obj, addr, size));
297152179Sgrehan}
298152179Sgrehan
299152179Sgrehan
300152179Sgrehan
301152179Sgrehan/*
302152179Sgrehan * Routines used in machine-dependent code
303152179Sgrehan */
304152179Sgrehanvoid
305152179Sgrehanpmap_bootstrap(vm_offset_t start, vm_offset_t end)
306152179Sgrehan{
307152179Sgrehan	mmu_obj = &mmu_kernel_obj;
308152179Sgrehan
309152179Sgrehan	/*
310152179Sgrehan	 * Take care of compiling the selected class, and
311152179Sgrehan	 * then statically initialise the MMU object
312152179Sgrehan	 */
313152179Sgrehan	kobj_class_compile_static(mmu_def_impl, &mmu_kernel_kops);
314152179Sgrehan	kobj_init((kobj_t)mmu_obj, mmu_def_impl);
315152179Sgrehan
316152179Sgrehan	MMU_BOOTSTRAP(mmu_obj, start, end);
317152179Sgrehan}
318152179Sgrehan
319152179Sgrehanvoid *
320152179Sgrehanpmap_mapdev(vm_offset_t pa, vm_size_t size)
321152179Sgrehan{
322152179Sgrehan	return (MMU_MAPDEV(mmu_obj, pa, size));
323152179Sgrehan}
324152179Sgrehan
325152179Sgrehanvoid
326152179Sgrehanpmap_unmapdev(vm_offset_t va, vm_size_t size)
327152179Sgrehan{
328152179Sgrehan	MMU_UNMAPDEV(mmu_obj, va, size);
329152179Sgrehan}
330152179Sgrehan
331152179Sgrehanvm_offset_t
332152179Sgrehanpmap_kextract(vm_offset_t va)
333152179Sgrehan{
334152179Sgrehan	return (MMU_KEXTRACT(mmu_obj, va));
335152179Sgrehan}
336152179Sgrehan
337152179Sgrehanvoid
338152179Sgrehanpmap_kenter(vm_offset_t va, vm_offset_t pa)
339152179Sgrehan{
340152179Sgrehan	MMU_KENTER(mmu_obj, va, pa);
341152179Sgrehan}
342152179Sgrehan
343152179Sgrehanboolean_t
344152179Sgrehanpmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size)
345152179Sgrehan{
346152179Sgrehan	return (MMU_DEV_DIRECT_MAPPED(mmu_obj, pa, size));
347152179Sgrehan}
348152179Sgrehan
349164895Sgrehanboolean_t
350164895Sgrehanpmap_page_executable(vm_page_t pg)
351164895Sgrehan{
352164895Sgrehan	return (MMU_PAGE_EXECUTABLE(mmu_obj, pg));
353164895Sgrehan}
354152179Sgrehan
355152179Sgrehan/*
356152179Sgrehan * MMU install routines. Highest priority wins, equal priority also
357152179Sgrehan * overrides allowing last-set to win.
358152179Sgrehan */
359152179SgrehanSET_DECLARE(mmu_set, mmu_def_t);
360152179Sgrehan
361152179Sgrehanboolean_t
362152179Sgrehanpmap_mmu_install(char *name, int prio)
363152179Sgrehan{
364152179Sgrehan	mmu_def_t	**mmupp, *mmup;
365152179Sgrehan	static int	curr_prio = 0;
366152179Sgrehan
367152179Sgrehan	/*
368152179Sgrehan	 * Try and locate the MMU kobj corresponding to the name
369152179Sgrehan	 */
370152179Sgrehan	SET_FOREACH(mmupp, mmu_set) {
371152179Sgrehan		mmup = *mmupp;
372152179Sgrehan
373152179Sgrehan		if (mmup->name &&
374152179Sgrehan		    !strcmp(mmup->name, name) &&
375152179Sgrehan		    prio >= curr_prio) {
376152179Sgrehan			curr_prio = prio;
377152179Sgrehan			mmu_def_impl = mmup;
378152179Sgrehan			return (TRUE);
379152179Sgrehan		}
380152179Sgrehan	}
381152179Sgrehan
382152179Sgrehan	return (FALSE);
383152179Sgrehan}
384