]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/powerpc/powerpc/pmap_dispatch.c
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / powerpc / powerpc / pmap_dispatch.c
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_prot_t access, vm_page_t p,
111     vm_prot_t prot, 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  *      Increase the starting virtual address of the given mapping if a
301  *      different alignment might result in more superpage mappings.
302  */
303 void
304 pmap_align_superpage(vm_object_t object, vm_ooffset_t offset,
305     vm_offset_t *addr, vm_size_t size)
306 {
307 }
308
309
310
311 /*
312  * Routines used in machine-dependent code
313  */
314 void
315 pmap_bootstrap(vm_offset_t start, vm_offset_t end)
316 {
317         mmu_obj = &mmu_kernel_obj;
318
319         /*
320          * Take care of compiling the selected class, and
321          * then statically initialise the MMU object
322          */
323         kobj_class_compile_static(mmu_def_impl, &mmu_kernel_kops);
324         kobj_init((kobj_t)mmu_obj, mmu_def_impl);
325
326         MMU_BOOTSTRAP(mmu_obj, start, end);
327 }
328
329 void *
330 pmap_mapdev(vm_offset_t pa, vm_size_t size)
331 {
332         return (MMU_MAPDEV(mmu_obj, pa, size));
333 }
334
335 void
336 pmap_unmapdev(vm_offset_t va, vm_size_t size)
337 {
338         MMU_UNMAPDEV(mmu_obj, va, size);
339 }
340
341 vm_offset_t
342 pmap_kextract(vm_offset_t va)
343 {
344         return (MMU_KEXTRACT(mmu_obj, va));
345 }
346
347 void
348 pmap_kenter(vm_offset_t va, vm_offset_t pa)
349 {
350         MMU_KENTER(mmu_obj, va, pa);
351 }
352
353 boolean_t
354 pmap_dev_direct_mapped(vm_offset_t pa, vm_size_t size)
355 {
356         return (MMU_DEV_DIRECT_MAPPED(mmu_obj, pa, size));
357 }
358
359 boolean_t
360 pmap_page_executable(vm_page_t pg)
361 {
362         return (MMU_PAGE_EXECUTABLE(mmu_obj, pg));
363 }
364
365 /*
366  * MMU install routines. Highest priority wins, equal priority also
367  * overrides allowing last-set to win.
368  */
369 SET_DECLARE(mmu_set, mmu_def_t);
370
371 boolean_t
372 pmap_mmu_install(char *name, int prio)
373 {
374         mmu_def_t       **mmupp, *mmup;
375         static int      curr_prio = 0;
376
377         /*
378          * Try and locate the MMU kobj corresponding to the name
379          */
380         SET_FOREACH(mmupp, mmu_set) {
381                 mmup = *mmupp;
382
383                 if (mmup->name &&
384                     !strcmp(mmup->name, name) &&
385                     prio >= curr_prio) {
386                         curr_prio = prio;
387                         mmu_def_impl = mmup;
388                         return (TRUE);
389                 }
390         }
391
392         return (FALSE);
393 }