]> CyberLeo.Net >> Repos - FreeBSD/releng/9.0.git/blob - sys/powerpc/aim/mmu_oea.c
Copy stable/9 to releng/9.0 as part of the FreeBSD 9.0-RELEASE release
[FreeBSD/releng/9.0.git] / sys / powerpc / aim / mmu_oea.c
1 /*-
2  * Copyright (c) 2001 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Matt Thomas <matt@3am-software.com> of Allegro Networks, Inc.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *        This product includes software developed by the NetBSD
19  *        Foundation, Inc. and its contributors.
20  * 4. Neither the name of The NetBSD Foundation nor the names of its
21  *    contributors may be used to endorse or promote products derived
22  *    from this software without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 /*-
37  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
38  * Copyright (C) 1995, 1996 TooLs GmbH.
39  * All rights reserved.
40  *
41  * Redistribution and use in source and binary forms, with or without
42  * modification, are permitted provided that the following conditions
43  * are met:
44  * 1. Redistributions of source code must retain the above copyright
45  *    notice, this list of conditions and the following disclaimer.
46  * 2. Redistributions in binary form must reproduce the above copyright
47  *    notice, this list of conditions and the following disclaimer in the
48  *    documentation and/or other materials provided with the distribution.
49  * 3. All advertising materials mentioning features or use of this software
50  *    must display the following acknowledgement:
51  *      This product includes software developed by TooLs GmbH.
52  * 4. The name of TooLs GmbH may not be used to endorse or promote products
53  *    derived from this software without specific prior written permission.
54  *
55  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
56  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
57  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
58  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
59  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
60  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
61  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
62  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
63  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
64  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
65  *
66  * $NetBSD: pmap.c,v 1.28 2000/03/26 20:42:36 kleink Exp $
67  */
68 /*-
69  * Copyright (C) 2001 Benno Rice.
70  * All rights reserved.
71  *
72  * Redistribution and use in source and binary forms, with or without
73  * modification, are permitted provided that the following conditions
74  * are met:
75  * 1. Redistributions of source code must retain the above copyright
76  *    notice, this list of conditions and the following disclaimer.
77  * 2. Redistributions in binary form must reproduce the above copyright
78  *    notice, this list of conditions and the following disclaimer in the
79  *    documentation and/or other materials provided with the distribution.
80  *
81  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
82  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
83  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
84  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
85  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
86  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
87  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
88  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
89  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
90  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
91  */
92
93 #include <sys/cdefs.h>
94 __FBSDID("$FreeBSD$");
95
96 /*
97  * Manages physical address maps.
98  *
99  * In addition to hardware address maps, this module is called upon to
100  * provide software-use-only maps which may or may not be stored in the
101  * same form as hardware maps.  These pseudo-maps are used to store
102  * intermediate results from copy operations to and from address spaces.
103  *
104  * Since the information managed by this module is also stored by the
105  * logical address mapping module, this module may throw away valid virtual
106  * to physical mappings at almost any time.  However, invalidations of
107  * mappings must be done as requested.
108  *
109  * In order to cope with hardware architectures which make virtual to
110  * physical map invalidates expensive, this module may delay invalidate
111  * reduced protection operations until such time as they are actually
112  * necessary.  This module is given full information as to which processors
113  * are currently using which maps, and to when physical maps must be made
114  * correct.
115  */
116
117 #include "opt_kstack_pages.h"
118
119 #include <sys/param.h>
120 #include <sys/kernel.h>
121 #include <sys/queue.h>
122 #include <sys/cpuset.h>
123 #include <sys/ktr.h>
124 #include <sys/lock.h>
125 #include <sys/msgbuf.h>
126 #include <sys/mutex.h>
127 #include <sys/proc.h>
128 #include <sys/sched.h>
129 #include <sys/sysctl.h>
130 #include <sys/systm.h>
131 #include <sys/vmmeter.h>
132
133 #include <dev/ofw/openfirm.h>
134
135 #include <vm/vm.h>
136 #include <vm/vm_param.h>
137 #include <vm/vm_kern.h>
138 #include <vm/vm_page.h>
139 #include <vm/vm_map.h>
140 #include <vm/vm_object.h>
141 #include <vm/vm_extern.h>
142 #include <vm/vm_pageout.h>
143 #include <vm/vm_pager.h>
144 #include <vm/uma.h>
145
146 #include <machine/cpu.h>
147 #include <machine/platform.h>
148 #include <machine/bat.h>
149 #include <machine/frame.h>
150 #include <machine/md_var.h>
151 #include <machine/psl.h>
152 #include <machine/pte.h>
153 #include <machine/smp.h>
154 #include <machine/sr.h>
155 #include <machine/mmuvar.h>
156
157 #include "mmu_if.h"
158
159 #define MOEA_DEBUG
160
161 #define TODO    panic("%s: not implemented", __func__);
162
163 #define VSID_MAKE(sr, hash)     ((sr) | (((hash) & 0xfffff) << 4))
164 #define VSID_TO_SR(vsid)        ((vsid) & 0xf)
165 #define VSID_TO_HASH(vsid)      (((vsid) >> 4) & 0xfffff)
166
167 struct ofw_map {
168         vm_offset_t     om_va;
169         vm_size_t       om_len;
170         vm_offset_t     om_pa;
171         u_int           om_mode;
172 };
173
174 /*
175  * Map of physical memory regions.
176  */
177 static struct   mem_region *regions;
178 static struct   mem_region *pregions;
179 static u_int    phys_avail_count;
180 static int      regions_sz, pregions_sz;
181 static struct   ofw_map *translations;
182
183 /*
184  * Lock for the pteg and pvo tables.
185  */
186 struct mtx      moea_table_mutex;
187 struct mtx      moea_vsid_mutex;
188
189 /* tlbie instruction synchronization */
190 static struct mtx tlbie_mtx;
191
192 /*
193  * PTEG data.
194  */
195 static struct   pteg *moea_pteg_table;
196 u_int           moea_pteg_count;
197 u_int           moea_pteg_mask;
198
199 /*
200  * PVO data.
201  */
202 struct  pvo_head *moea_pvo_table;               /* pvo entries by pteg index */
203 struct  pvo_head moea_pvo_kunmanaged =
204     LIST_HEAD_INITIALIZER(moea_pvo_kunmanaged); /* list of unmanaged pages */
205
206 uma_zone_t      moea_upvo_zone; /* zone for pvo entries for unmanaged pages */
207 uma_zone_t      moea_mpvo_zone; /* zone for pvo entries for managed pages */
208
209 #define BPVO_POOL_SIZE  32768
210 static struct   pvo_entry *moea_bpvo_pool;
211 static int      moea_bpvo_pool_index = 0;
212
213 #define VSID_NBPW       (sizeof(u_int32_t) * 8)
214 static u_int    moea_vsid_bitmap[NPMAPS / VSID_NBPW];
215
216 static boolean_t moea_initialized = FALSE;
217
218 /*
219  * Statistics.
220  */
221 u_int   moea_pte_valid = 0;
222 u_int   moea_pte_overflow = 0;
223 u_int   moea_pte_replacements = 0;
224 u_int   moea_pvo_entries = 0;
225 u_int   moea_pvo_enter_calls = 0;
226 u_int   moea_pvo_remove_calls = 0;
227 u_int   moea_pte_spills = 0;
228 SYSCTL_INT(_machdep, OID_AUTO, moea_pte_valid, CTLFLAG_RD, &moea_pte_valid,
229     0, "");
230 SYSCTL_INT(_machdep, OID_AUTO, moea_pte_overflow, CTLFLAG_RD,
231     &moea_pte_overflow, 0, "");
232 SYSCTL_INT(_machdep, OID_AUTO, moea_pte_replacements, CTLFLAG_RD,
233     &moea_pte_replacements, 0, "");
234 SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_entries, CTLFLAG_RD, &moea_pvo_entries,
235     0, "");
236 SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_enter_calls, CTLFLAG_RD,
237     &moea_pvo_enter_calls, 0, "");
238 SYSCTL_INT(_machdep, OID_AUTO, moea_pvo_remove_calls, CTLFLAG_RD,
239     &moea_pvo_remove_calls, 0, "");
240 SYSCTL_INT(_machdep, OID_AUTO, moea_pte_spills, CTLFLAG_RD,
241     &moea_pte_spills, 0, "");
242
243 /*
244  * Allocate physical memory for use in moea_bootstrap.
245  */
246 static vm_offset_t      moea_bootstrap_alloc(vm_size_t, u_int);
247
248 /*
249  * PTE calls.
250  */
251 static int              moea_pte_insert(u_int, struct pte *);
252
253 /*
254  * PVO calls.
255  */
256 static int      moea_pvo_enter(pmap_t, uma_zone_t, struct pvo_head *,
257                     vm_offset_t, vm_offset_t, u_int, int);
258 static void     moea_pvo_remove(struct pvo_entry *, int);
259 static struct   pvo_entry *moea_pvo_find_va(pmap_t, vm_offset_t, int *);
260 static struct   pte *moea_pvo_to_pte(const struct pvo_entry *, int);
261
262 /*
263  * Utility routines.
264  */
265 static void             moea_enter_locked(pmap_t, vm_offset_t, vm_page_t,
266                             vm_prot_t, boolean_t);
267 static void             moea_syncicache(vm_offset_t, vm_size_t);
268 static boolean_t        moea_query_bit(vm_page_t, int);
269 static u_int            moea_clear_bit(vm_page_t, int);
270 static void             moea_kremove(mmu_t, vm_offset_t);
271 int             moea_pte_spill(vm_offset_t);
272
273 /*
274  * Kernel MMU interface
275  */
276 void moea_change_wiring(mmu_t, pmap_t, vm_offset_t, boolean_t);
277 void moea_clear_modify(mmu_t, vm_page_t);
278 void moea_clear_reference(mmu_t, vm_page_t);
279 void moea_copy_page(mmu_t, vm_page_t, vm_page_t);
280 void moea_enter(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t, boolean_t);
281 void moea_enter_object(mmu_t, pmap_t, vm_offset_t, vm_offset_t, vm_page_t,
282     vm_prot_t);
283 void moea_enter_quick(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t);
284 vm_paddr_t moea_extract(mmu_t, pmap_t, vm_offset_t);
285 vm_page_t moea_extract_and_hold(mmu_t, pmap_t, vm_offset_t, vm_prot_t);
286 void moea_init(mmu_t);
287 boolean_t moea_is_modified(mmu_t, vm_page_t);
288 boolean_t moea_is_prefaultable(mmu_t, pmap_t, vm_offset_t);
289 boolean_t moea_is_referenced(mmu_t, vm_page_t);
290 boolean_t moea_ts_referenced(mmu_t, vm_page_t);
291 vm_offset_t moea_map(mmu_t, vm_offset_t *, vm_offset_t, vm_offset_t, int);
292 boolean_t moea_page_exists_quick(mmu_t, pmap_t, vm_page_t);
293 int moea_page_wired_mappings(mmu_t, vm_page_t);
294 void moea_pinit(mmu_t, pmap_t);
295 void moea_pinit0(mmu_t, pmap_t);
296 void moea_protect(mmu_t, pmap_t, vm_offset_t, vm_offset_t, vm_prot_t);
297 void moea_qenter(mmu_t, vm_offset_t, vm_page_t *, int);
298 void moea_qremove(mmu_t, vm_offset_t, int);
299 void moea_release(mmu_t, pmap_t);
300 void moea_remove(mmu_t, pmap_t, vm_offset_t, vm_offset_t);
301 void moea_remove_all(mmu_t, vm_page_t);
302 void moea_remove_write(mmu_t, vm_page_t);
303 void moea_zero_page(mmu_t, vm_page_t);
304 void moea_zero_page_area(mmu_t, vm_page_t, int, int);
305 void moea_zero_page_idle(mmu_t, vm_page_t);
306 void moea_activate(mmu_t, struct thread *);
307 void moea_deactivate(mmu_t, struct thread *);
308 void moea_cpu_bootstrap(mmu_t, int);
309 void moea_bootstrap(mmu_t, vm_offset_t, vm_offset_t);
310 void *moea_mapdev(mmu_t, vm_offset_t, vm_size_t);
311 void *moea_mapdev_attr(mmu_t, vm_offset_t, vm_size_t, vm_memattr_t);
312 void moea_unmapdev(mmu_t, vm_offset_t, vm_size_t);
313 vm_offset_t moea_kextract(mmu_t, vm_offset_t);
314 void moea_kenter_attr(mmu_t, vm_offset_t, vm_offset_t, vm_memattr_t);
315 void moea_kenter(mmu_t, vm_offset_t, vm_offset_t);
316 void moea_page_set_memattr(mmu_t mmu, vm_page_t m, vm_memattr_t ma);
317 boolean_t moea_dev_direct_mapped(mmu_t, vm_offset_t, vm_size_t);
318 static void moea_sync_icache(mmu_t, pmap_t, vm_offset_t, vm_size_t);
319
320 static mmu_method_t moea_methods[] = {
321         MMUMETHOD(mmu_change_wiring,    moea_change_wiring),
322         MMUMETHOD(mmu_clear_modify,     moea_clear_modify),
323         MMUMETHOD(mmu_clear_reference,  moea_clear_reference),
324         MMUMETHOD(mmu_copy_page,        moea_copy_page),
325         MMUMETHOD(mmu_enter,            moea_enter),
326         MMUMETHOD(mmu_enter_object,     moea_enter_object),
327         MMUMETHOD(mmu_enter_quick,      moea_enter_quick),
328         MMUMETHOD(mmu_extract,          moea_extract),
329         MMUMETHOD(mmu_extract_and_hold, moea_extract_and_hold),
330         MMUMETHOD(mmu_init,             moea_init),
331         MMUMETHOD(mmu_is_modified,      moea_is_modified),
332         MMUMETHOD(mmu_is_prefaultable,  moea_is_prefaultable),
333         MMUMETHOD(mmu_is_referenced,    moea_is_referenced),
334         MMUMETHOD(mmu_ts_referenced,    moea_ts_referenced),
335         MMUMETHOD(mmu_map,              moea_map),
336         MMUMETHOD(mmu_page_exists_quick,moea_page_exists_quick),
337         MMUMETHOD(mmu_page_wired_mappings,moea_page_wired_mappings),
338         MMUMETHOD(mmu_pinit,            moea_pinit),
339         MMUMETHOD(mmu_pinit0,           moea_pinit0),
340         MMUMETHOD(mmu_protect,          moea_protect),
341         MMUMETHOD(mmu_qenter,           moea_qenter),
342         MMUMETHOD(mmu_qremove,          moea_qremove),
343         MMUMETHOD(mmu_release,          moea_release),
344         MMUMETHOD(mmu_remove,           moea_remove),
345         MMUMETHOD(mmu_remove_all,       moea_remove_all),
346         MMUMETHOD(mmu_remove_write,     moea_remove_write),
347         MMUMETHOD(mmu_sync_icache,      moea_sync_icache),
348         MMUMETHOD(mmu_zero_page,        moea_zero_page),
349         MMUMETHOD(mmu_zero_page_area,   moea_zero_page_area),
350         MMUMETHOD(mmu_zero_page_idle,   moea_zero_page_idle),
351         MMUMETHOD(mmu_activate,         moea_activate),
352         MMUMETHOD(mmu_deactivate,       moea_deactivate),
353         MMUMETHOD(mmu_page_set_memattr, moea_page_set_memattr),
354
355         /* Internal interfaces */
356         MMUMETHOD(mmu_bootstrap,        moea_bootstrap),
357         MMUMETHOD(mmu_cpu_bootstrap,    moea_cpu_bootstrap),
358         MMUMETHOD(mmu_mapdev_attr,      moea_mapdev_attr),
359         MMUMETHOD(mmu_mapdev,           moea_mapdev),
360         MMUMETHOD(mmu_unmapdev,         moea_unmapdev),
361         MMUMETHOD(mmu_kextract,         moea_kextract),
362         MMUMETHOD(mmu_kenter,           moea_kenter),
363         MMUMETHOD(mmu_kenter_attr,      moea_kenter_attr),
364         MMUMETHOD(mmu_dev_direct_mapped,moea_dev_direct_mapped),
365
366         { 0, 0 }
367 };
368
369 MMU_DEF(oea_mmu, MMU_TYPE_OEA, moea_methods, 0);
370
371 static __inline uint32_t
372 moea_calc_wimg(vm_offset_t pa, vm_memattr_t ma)
373 {
374         uint32_t pte_lo;
375         int i;
376
377         if (ma != VM_MEMATTR_DEFAULT) {
378                 switch (ma) {
379                 case VM_MEMATTR_UNCACHEABLE:
380                         return (PTE_I | PTE_G);
381                 case VM_MEMATTR_WRITE_COMBINING:
382                 case VM_MEMATTR_WRITE_BACK:
383                 case VM_MEMATTR_PREFETCHABLE:
384                         return (PTE_I);
385                 case VM_MEMATTR_WRITE_THROUGH:
386                         return (PTE_W | PTE_M);
387                 }
388         }
389
390         /*
391          * Assume the page is cache inhibited and access is guarded unless
392          * it's in our available memory array.
393          */
394         pte_lo = PTE_I | PTE_G;
395         for (i = 0; i < pregions_sz; i++) {
396                 if ((pa >= pregions[i].mr_start) &&
397                     (pa < (pregions[i].mr_start + pregions[i].mr_size))) {
398                         pte_lo = PTE_M;
399                         break;
400                 }
401         }
402
403         return pte_lo;
404 }
405
406 static void
407 tlbie(vm_offset_t va)
408 {
409
410         mtx_lock_spin(&tlbie_mtx);
411         __asm __volatile("ptesync");
412         __asm __volatile("tlbie %0" :: "r"(va));
413         __asm __volatile("eieio; tlbsync; ptesync");
414         mtx_unlock_spin(&tlbie_mtx);
415 }
416
417 static void
418 tlbia(void)
419 {
420         vm_offset_t va;
421  
422         for (va = 0; va < 0x00040000; va += 0x00001000) {
423                 __asm __volatile("tlbie %0" :: "r"(va));
424                 powerpc_sync();
425         }
426         __asm __volatile("tlbsync");
427         powerpc_sync();
428 }
429
430 static __inline int
431 va_to_sr(u_int *sr, vm_offset_t va)
432 {
433         return (sr[(uintptr_t)va >> ADDR_SR_SHFT]);
434 }
435
436 static __inline u_int
437 va_to_pteg(u_int sr, vm_offset_t addr)
438 {
439         u_int hash;
440
441         hash = (sr & SR_VSID_MASK) ^ (((u_int)addr & ADDR_PIDX) >>
442             ADDR_PIDX_SHFT);
443         return (hash & moea_pteg_mask);
444 }
445
446 static __inline struct pvo_head *
447 vm_page_to_pvoh(vm_page_t m)
448 {
449
450         return (&m->md.mdpg_pvoh);
451 }
452
453 static __inline void
454 moea_attr_clear(vm_page_t m, int ptebit)
455 {
456
457         mtx_assert(&vm_page_queue_mtx, MA_OWNED);
458         m->md.mdpg_attrs &= ~ptebit;
459 }
460
461 static __inline int
462 moea_attr_fetch(vm_page_t m)
463 {
464
465         return (m->md.mdpg_attrs);
466 }
467
468 static __inline void
469 moea_attr_save(vm_page_t m, int ptebit)
470 {
471
472         mtx_assert(&vm_page_queue_mtx, MA_OWNED);
473         m->md.mdpg_attrs |= ptebit;
474 }
475
476 static __inline int
477 moea_pte_compare(const struct pte *pt, const struct pte *pvo_pt)
478 {
479         if (pt->pte_hi == pvo_pt->pte_hi)
480                 return (1);
481
482         return (0);
483 }
484
485 static __inline int
486 moea_pte_match(struct pte *pt, u_int sr, vm_offset_t va, int which)
487 {
488         return (pt->pte_hi & ~PTE_VALID) ==
489             (((sr & SR_VSID_MASK) << PTE_VSID_SHFT) |
490             ((va >> ADDR_API_SHFT) & PTE_API) | which);
491 }
492
493 static __inline void
494 moea_pte_create(struct pte *pt, u_int sr, vm_offset_t va, u_int pte_lo)
495 {
496
497         mtx_assert(&moea_table_mutex, MA_OWNED);
498
499         /*
500          * Construct a PTE.  Default to IMB initially.  Valid bit only gets
501          * set when the real pte is set in memory.
502          *
503          * Note: Don't set the valid bit for correct operation of tlb update.
504          */
505         pt->pte_hi = ((sr & SR_VSID_MASK) << PTE_VSID_SHFT) |
506             (((va & ADDR_PIDX) >> ADDR_API_SHFT) & PTE_API);
507         pt->pte_lo = pte_lo;
508 }
509
510 static __inline void
511 moea_pte_synch(struct pte *pt, struct pte *pvo_pt)
512 {
513
514         mtx_assert(&moea_table_mutex, MA_OWNED);
515         pvo_pt->pte_lo |= pt->pte_lo & (PTE_REF | PTE_CHG);
516 }
517
518 static __inline void
519 moea_pte_clear(struct pte *pt, vm_offset_t va, int ptebit)
520 {
521
522         mtx_assert(&moea_table_mutex, MA_OWNED);
523
524         /*
525          * As shown in Section 7.6.3.2.3
526          */
527         pt->pte_lo &= ~ptebit;
528         tlbie(va);
529 }
530
531 static __inline void
532 moea_pte_set(struct pte *pt, struct pte *pvo_pt)
533 {
534
535         mtx_assert(&moea_table_mutex, MA_OWNED);
536         pvo_pt->pte_hi |= PTE_VALID;
537
538         /*
539          * Update the PTE as defined in section 7.6.3.1.
540          * Note that the REF/CHG bits are from pvo_pt and thus should havce
541          * been saved so this routine can restore them (if desired).
542          */
543         pt->pte_lo = pvo_pt->pte_lo;
544         powerpc_sync();
545         pt->pte_hi = pvo_pt->pte_hi;
546         powerpc_sync();
547         moea_pte_valid++;
548 }
549
550 static __inline void
551 moea_pte_unset(struct pte *pt, struct pte *pvo_pt, vm_offset_t va)
552 {
553
554         mtx_assert(&moea_table_mutex, MA_OWNED);
555         pvo_pt->pte_hi &= ~PTE_VALID;
556
557         /*
558          * Force the reg & chg bits back into the PTEs.
559          */
560         powerpc_sync();
561
562         /*
563          * Invalidate the pte.
564          */
565         pt->pte_hi &= ~PTE_VALID;
566
567         tlbie(va);
568
569         /*
570          * Save the reg & chg bits.
571          */
572         moea_pte_synch(pt, pvo_pt);
573         moea_pte_valid--;
574 }
575
576 static __inline void
577 moea_pte_change(struct pte *pt, struct pte *pvo_pt, vm_offset_t va)
578 {
579
580         /*
581          * Invalidate the PTE
582          */
583         moea_pte_unset(pt, pvo_pt, va);
584         moea_pte_set(pt, pvo_pt);
585 }
586
587 /*
588  * Quick sort callout for comparing memory regions.
589  */
590 static int      om_cmp(const void *a, const void *b);
591
592 static int
593 om_cmp(const void *a, const void *b)
594 {
595         const struct    ofw_map *mapa;
596         const struct    ofw_map *mapb;
597
598         mapa = a;
599         mapb = b;
600         if (mapa->om_pa < mapb->om_pa)
601                 return (-1);
602         else if (mapa->om_pa > mapb->om_pa)
603                 return (1);
604         else
605                 return (0);
606 }
607
608 void
609 moea_cpu_bootstrap(mmu_t mmup, int ap)
610 {
611         u_int sdr;
612         int i;
613
614         if (ap) {
615                 powerpc_sync();
616                 __asm __volatile("mtdbatu 0,%0" :: "r"(battable[0].batu));
617                 __asm __volatile("mtdbatl 0,%0" :: "r"(battable[0].batl));
618                 isync();
619                 __asm __volatile("mtibatu 0,%0" :: "r"(battable[0].batu));
620                 __asm __volatile("mtibatl 0,%0" :: "r"(battable[0].batl));
621                 isync();
622         }
623
624         __asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
625         __asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
626         isync();
627
628         __asm __volatile("mtibatu 1,%0" :: "r"(0));
629         __asm __volatile("mtdbatu 2,%0" :: "r"(0));
630         __asm __volatile("mtibatu 2,%0" :: "r"(0));
631         __asm __volatile("mtdbatu 3,%0" :: "r"(0));
632         __asm __volatile("mtibatu 3,%0" :: "r"(0));
633         isync();
634
635         for (i = 0; i < 16; i++)
636                 mtsrin(i << ADDR_SR_SHFT, kernel_pmap->pm_sr[i]);
637         powerpc_sync();
638
639         sdr = (u_int)moea_pteg_table | (moea_pteg_mask >> 10);
640         __asm __volatile("mtsdr1 %0" :: "r"(sdr));
641         isync();
642
643         tlbia();
644 }
645
646 void
647 moea_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
648 {
649         ihandle_t       mmui;
650         phandle_t       chosen, mmu;
651         int             sz;
652         int             i, j;
653         vm_size_t       size, physsz, hwphyssz;
654         vm_offset_t     pa, va, off;
655         void            *dpcpu;
656         register_t      msr;
657
658         /*
659          * Set up BAT0 to map the lowest 256 MB area
660          */
661         battable[0x0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
662         battable[0x0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
663
664         /*
665          * Map PCI memory space.
666          */
667         battable[0x8].batl = BATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW);
668         battable[0x8].batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs);
669
670         battable[0x9].batl = BATL(0x90000000, BAT_I|BAT_G, BAT_PP_RW);
671         battable[0x9].batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs);
672
673         battable[0xa].batl = BATL(0xa0000000, BAT_I|BAT_G, BAT_PP_RW);
674         battable[0xa].batu = BATU(0xa0000000, BAT_BL_256M, BAT_Vs);
675
676         battable[0xb].batl = BATL(0xb0000000, BAT_I|BAT_G, BAT_PP_RW);
677         battable[0xb].batu = BATU(0xb0000000, BAT_BL_256M, BAT_Vs);
678
679         /*
680          * Map obio devices.
681          */
682         battable[0xf].batl = BATL(0xf0000000, BAT_I|BAT_G, BAT_PP_RW);
683         battable[0xf].batu = BATU(0xf0000000, BAT_BL_256M, BAT_Vs);
684
685         /*
686          * Use an IBAT and a DBAT to map the bottom segment of memory
687          * where we are. Turn off instruction relocation temporarily
688          * to prevent faults while reprogramming the IBAT.
689          */
690         msr = mfmsr();
691         mtmsr(msr & ~PSL_IR);
692         __asm (".balign 32; \n"
693                "mtibatu 0,%0; mtibatl 0,%1; isync; \n"
694                "mtdbatu 0,%0; mtdbatl 0,%1; isync"
695             :: "r"(battable[0].batu), "r"(battable[0].batl));
696         mtmsr(msr);
697
698         /* map pci space */
699         __asm __volatile("mtdbatu 1,%0" :: "r"(battable[8].batu));
700         __asm __volatile("mtdbatl 1,%0" :: "r"(battable[8].batl));
701         isync();
702
703         /* set global direct map flag */
704         hw_direct_map = 1;
705
706         mem_regions(&pregions, &pregions_sz, &regions, &regions_sz);
707         CTR0(KTR_PMAP, "moea_bootstrap: physical memory");
708
709         for (i = 0; i < pregions_sz; i++) {
710                 vm_offset_t pa;
711                 vm_offset_t end;
712
713                 CTR3(KTR_PMAP, "physregion: %#x - %#x (%#x)",
714                         pregions[i].mr_start,
715                         pregions[i].mr_start + pregions[i].mr_size,
716                         pregions[i].mr_size);
717                 /*
718                  * Install entries into the BAT table to allow all
719                  * of physmem to be convered by on-demand BAT entries.
720                  * The loop will sometimes set the same battable element
721                  * twice, but that's fine since they won't be used for
722                  * a while yet.
723                  */
724                 pa = pregions[i].mr_start & 0xf0000000;
725                 end = pregions[i].mr_start + pregions[i].mr_size;
726                 do {
727                         u_int n = pa >> ADDR_SR_SHFT;
728
729                         battable[n].batl = BATL(pa, BAT_M, BAT_PP_RW);
730                         battable[n].batu = BATU(pa, BAT_BL_256M, BAT_Vs);
731                         pa += SEGMENT_LENGTH;
732                 } while (pa < end);
733         }
734
735         if (sizeof(phys_avail)/sizeof(phys_avail[0]) < regions_sz)
736                 panic("moea_bootstrap: phys_avail too small");
737
738         phys_avail_count = 0;
739         physsz = 0;
740         hwphyssz = 0;
741         TUNABLE_ULONG_FETCH("hw.physmem", (u_long *) &hwphyssz);
742         for (i = 0, j = 0; i < regions_sz; i++, j += 2) {
743                 CTR3(KTR_PMAP, "region: %#x - %#x (%#x)", regions[i].mr_start,
744                     regions[i].mr_start + regions[i].mr_size,
745                     regions[i].mr_size);
746                 if (hwphyssz != 0 &&
747                     (physsz + regions[i].mr_size) >= hwphyssz) {
748                         if (physsz < hwphyssz) {
749                                 phys_avail[j] = regions[i].mr_start;
750                                 phys_avail[j + 1] = regions[i].mr_start +
751                                     hwphyssz - physsz;
752                                 physsz = hwphyssz;
753                                 phys_avail_count++;
754                         }
755                         break;
756                 }
757                 phys_avail[j] = regions[i].mr_start;
758                 phys_avail[j + 1] = regions[i].mr_start + regions[i].mr_size;
759                 phys_avail_count++;
760                 physsz += regions[i].mr_size;
761         }
762         physmem = btoc(physsz);
763
764         /*
765          * Allocate PTEG table.
766          */
767 #ifdef PTEGCOUNT
768         moea_pteg_count = PTEGCOUNT;
769 #else
770         moea_pteg_count = 0x1000;
771
772         while (moea_pteg_count < physmem)
773                 moea_pteg_count <<= 1;
774
775         moea_pteg_count >>= 1;
776 #endif /* PTEGCOUNT */
777
778         size = moea_pteg_count * sizeof(struct pteg);
779         CTR2(KTR_PMAP, "moea_bootstrap: %d PTEGs, %d bytes", moea_pteg_count,
780             size);
781         moea_pteg_table = (struct pteg *)moea_bootstrap_alloc(size, size);
782         CTR1(KTR_PMAP, "moea_bootstrap: PTEG table at %p", moea_pteg_table);
783         bzero((void *)moea_pteg_table, moea_pteg_count * sizeof(struct pteg));
784         moea_pteg_mask = moea_pteg_count - 1;
785
786         /*
787          * Allocate pv/overflow lists.
788          */
789         size = sizeof(struct pvo_head) * moea_pteg_count;
790         moea_pvo_table = (struct pvo_head *)moea_bootstrap_alloc(size,
791             PAGE_SIZE);
792         CTR1(KTR_PMAP, "moea_bootstrap: PVO table at %p", moea_pvo_table);
793         for (i = 0; i < moea_pteg_count; i++)
794                 LIST_INIT(&moea_pvo_table[i]);
795
796         /*
797          * Initialize the lock that synchronizes access to the pteg and pvo
798          * tables.
799          */
800         mtx_init(&moea_table_mutex, "pmap table", NULL, MTX_DEF |
801             MTX_RECURSE);
802         mtx_init(&moea_vsid_mutex, "VSID table", NULL, MTX_DEF);
803
804         mtx_init(&tlbie_mtx, "tlbie", NULL, MTX_SPIN);
805
806         /*
807          * Initialise the unmanaged pvo pool.
808          */
809         moea_bpvo_pool = (struct pvo_entry *)moea_bootstrap_alloc(
810                 BPVO_POOL_SIZE*sizeof(struct pvo_entry), 0);
811         moea_bpvo_pool_index = 0;
812
813         /*
814          * Make sure kernel vsid is allocated as well as VSID 0.
815          */
816         moea_vsid_bitmap[(KERNEL_VSIDBITS & (NPMAPS - 1)) / VSID_NBPW]
817                 |= 1 << (KERNEL_VSIDBITS % VSID_NBPW);
818         moea_vsid_bitmap[0] |= 1;
819
820         /*
821          * Initialize the kernel pmap (which is statically allocated).
822          */
823         PMAP_LOCK_INIT(kernel_pmap);
824         for (i = 0; i < 16; i++)
825                 kernel_pmap->pm_sr[i] = EMPTY_SEGMENT + i;
826         CPU_FILL(&kernel_pmap->pm_active);
827
828         /*
829          * Set up the Open Firmware mappings
830          */
831         if ((chosen = OF_finddevice("/chosen")) == -1)
832                 panic("moea_bootstrap: can't find /chosen");
833         OF_getprop(chosen, "mmu", &mmui, 4);
834         if ((mmu = OF_instance_to_package(mmui)) == -1)
835                 panic("moea_bootstrap: can't get mmu package");
836         if ((sz = OF_getproplen(mmu, "translations")) == -1)
837                 panic("moea_bootstrap: can't get ofw translation count");
838         translations = NULL;
839         for (i = 0; phys_avail[i] != 0; i += 2) {
840                 if (phys_avail[i + 1] >= sz) {
841                         translations = (struct ofw_map *)phys_avail[i];
842                         break;
843                 }
844         }
845         if (translations == NULL)
846                 panic("moea_bootstrap: no space to copy translations");
847         bzero(translations, sz);
848         if (OF_getprop(mmu, "translations", translations, sz) == -1)
849                 panic("moea_bootstrap: can't get ofw translations");
850         CTR0(KTR_PMAP, "moea_bootstrap: translations");
851         sz /= sizeof(*translations);
852         qsort(translations, sz, sizeof (*translations), om_cmp);
853         for (i = 0; i < sz; i++) {
854                 CTR3(KTR_PMAP, "translation: pa=%#x va=%#x len=%#x",
855                     translations[i].om_pa, translations[i].om_va,
856                     translations[i].om_len);
857
858                 /*
859                  * If the mapping is 1:1, let the RAM and device on-demand
860                  * BAT tables take care of the translation.
861                  */
862                 if (translations[i].om_va == translations[i].om_pa)
863                         continue;
864
865                 /* Enter the pages */
866                 for (off = 0; off < translations[i].om_len; off += PAGE_SIZE)
867                         moea_kenter(mmup, translations[i].om_va + off, 
868                                     translations[i].om_pa + off);
869         }
870
871         /*
872          * Calculate the last available physical address.
873          */
874         for (i = 0; phys_avail[i + 2] != 0; i += 2)
875                 ;
876         Maxmem = powerpc_btop(phys_avail[i + 1]);
877
878         moea_cpu_bootstrap(mmup,0);
879
880         pmap_bootstrapped++;
881
882         /*
883          * Set the start and end of kva.
884          */
885         virtual_avail = VM_MIN_KERNEL_ADDRESS;
886         virtual_end = VM_MAX_SAFE_KERNEL_ADDRESS;
887
888         /*
889          * Allocate a kernel stack with a guard page for thread0 and map it
890          * into the kernel page map.
891          */
892         pa = moea_bootstrap_alloc(KSTACK_PAGES * PAGE_SIZE, PAGE_SIZE);
893         va = virtual_avail + KSTACK_GUARD_PAGES * PAGE_SIZE;
894         virtual_avail = va + KSTACK_PAGES * PAGE_SIZE;
895         CTR2(KTR_PMAP, "moea_bootstrap: kstack0 at %#x (%#x)", pa, va);
896         thread0.td_kstack = va;
897         thread0.td_kstack_pages = KSTACK_PAGES;
898         for (i = 0; i < KSTACK_PAGES; i++) {
899                 moea_kenter(mmup, va, pa);
900                 pa += PAGE_SIZE;
901                 va += PAGE_SIZE;
902         }
903
904         /*
905          * Allocate virtual address space for the message buffer.
906          */
907         pa = msgbuf_phys = moea_bootstrap_alloc(msgbufsize, PAGE_SIZE);
908         msgbufp = (struct msgbuf *)virtual_avail;
909         va = virtual_avail;
910         virtual_avail += round_page(msgbufsize);
911         while (va < virtual_avail) {
912                 moea_kenter(mmup, va, pa);
913                 pa += PAGE_SIZE;
914                 va += PAGE_SIZE;
915         }
916
917         /*
918          * Allocate virtual address space for the dynamic percpu area.
919          */
920         pa = moea_bootstrap_alloc(DPCPU_SIZE, PAGE_SIZE);
921         dpcpu = (void *)virtual_avail;
922         va = virtual_avail;
923         virtual_avail += DPCPU_SIZE;
924         while (va < virtual_avail) {
925                 moea_kenter(mmup, va, pa);
926                 pa += PAGE_SIZE;
927                 va += PAGE_SIZE;
928         }
929         dpcpu_init(dpcpu, 0);
930 }
931
932 /*
933  * Activate a user pmap.  The pmap must be activated before it's address
934  * space can be accessed in any way.
935  */
936 void
937 moea_activate(mmu_t mmu, struct thread *td)
938 {
939         pmap_t  pm, pmr;
940
941         /*
942          * Load all the data we need up front to encourage the compiler to
943          * not issue any loads while we have interrupts disabled below.
944          */
945         pm = &td->td_proc->p_vmspace->vm_pmap;
946         pmr = pm->pmap_phys;
947
948         CPU_SET(PCPU_GET(cpuid), &pm->pm_active);
949         PCPU_SET(curpmap, pmr);
950 }
951
952 void
953 moea_deactivate(mmu_t mmu, struct thread *td)
954 {
955         pmap_t  pm;
956
957         pm = &td->td_proc->p_vmspace->vm_pmap;
958         CPU_CLR(PCPU_GET(cpuid), &pm->pm_active);
959         PCPU_SET(curpmap, NULL);
960 }
961
962 void
963 moea_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired)
964 {
965         struct  pvo_entry *pvo;
966
967         PMAP_LOCK(pm);
968         pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
969
970         if (pvo != NULL) {
971                 if (wired) {
972                         if ((pvo->pvo_vaddr & PVO_WIRED) == 0)
973                                 pm->pm_stats.wired_count++;
974                         pvo->pvo_vaddr |= PVO_WIRED;
975                 } else {
976                         if ((pvo->pvo_vaddr & PVO_WIRED) != 0)
977                                 pm->pm_stats.wired_count--;
978                         pvo->pvo_vaddr &= ~PVO_WIRED;
979                 }
980         }
981         PMAP_UNLOCK(pm);
982 }
983
984 void
985 moea_copy_page(mmu_t mmu, vm_page_t msrc, vm_page_t mdst)
986 {
987         vm_offset_t     dst;
988         vm_offset_t     src;
989
990         dst = VM_PAGE_TO_PHYS(mdst);
991         src = VM_PAGE_TO_PHYS(msrc);
992
993         kcopy((void *)src, (void *)dst, PAGE_SIZE);
994 }
995
996 /*
997  * Zero a page of physical memory by temporarily mapping it into the tlb.
998  */
999 void
1000 moea_zero_page(mmu_t mmu, vm_page_t m)
1001 {
1002         vm_offset_t pa = VM_PAGE_TO_PHYS(m);
1003         void *va = (void *)pa;
1004
1005         bzero(va, PAGE_SIZE);
1006 }
1007
1008 void
1009 moea_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size)
1010 {
1011         vm_offset_t pa = VM_PAGE_TO_PHYS(m);
1012         void *va = (void *)(pa + off);
1013
1014         bzero(va, size);
1015 }
1016
1017 void
1018 moea_zero_page_idle(mmu_t mmu, vm_page_t m)
1019 {
1020         vm_offset_t pa = VM_PAGE_TO_PHYS(m);
1021         void *va = (void *)pa;
1022
1023         bzero(va, PAGE_SIZE);
1024 }
1025
1026 /*
1027  * Map the given physical page at the specified virtual address in the
1028  * target pmap with the protection requested.  If specified the page
1029  * will be wired down.
1030  */
1031 void
1032 moea_enter(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
1033            boolean_t wired)
1034 {
1035
1036         vm_page_lock_queues();
1037         PMAP_LOCK(pmap);
1038         moea_enter_locked(pmap, va, m, prot, wired);
1039         vm_page_unlock_queues();
1040         PMAP_UNLOCK(pmap);
1041 }
1042
1043 /*
1044  * Map the given physical page at the specified virtual address in the
1045  * target pmap with the protection requested.  If specified the page
1046  * will be wired down.
1047  *
1048  * The page queues and pmap must be locked.
1049  */
1050 static void
1051 moea_enter_locked(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
1052     boolean_t wired)
1053 {
1054         struct          pvo_head *pvo_head;
1055         uma_zone_t      zone;
1056         vm_page_t       pg;
1057         u_int           pte_lo, pvo_flags, was_exec;
1058         int             error;
1059
1060         if (!moea_initialized) {
1061                 pvo_head = &moea_pvo_kunmanaged;
1062                 zone = moea_upvo_zone;
1063                 pvo_flags = 0;
1064                 pg = NULL;
1065                 was_exec = PTE_EXEC;
1066         } else {
1067                 pvo_head = vm_page_to_pvoh(m);
1068                 pg = m;
1069                 zone = moea_mpvo_zone;
1070                 pvo_flags = PVO_MANAGED;
1071                 was_exec = 0;
1072         }
1073         if (pmap_bootstrapped)
1074                 mtx_assert(&vm_page_queue_mtx, MA_OWNED);
1075         PMAP_LOCK_ASSERT(pmap, MA_OWNED);
1076         KASSERT((m->oflags & (VPO_UNMANAGED | VPO_BUSY)) != 0 ||
1077             VM_OBJECT_LOCKED(m->object),
1078             ("moea_enter_locked: page %p is not busy", m));
1079
1080         /* XXX change the pvo head for fake pages */
1081         if ((m->oflags & VPO_UNMANAGED) != 0) {
1082                 pvo_flags &= ~PVO_MANAGED;
1083                 pvo_head = &moea_pvo_kunmanaged;
1084                 zone = moea_upvo_zone;
1085         }
1086
1087         /*
1088          * If this is a managed page, and it's the first reference to the page,
1089          * clear the execness of the page.  Otherwise fetch the execness.
1090          */
1091         if ((pg != NULL) && ((m->oflags & VPO_UNMANAGED) == 0)) {
1092                 if (LIST_EMPTY(pvo_head)) {
1093                         moea_attr_clear(pg, PTE_EXEC);
1094                 } else {
1095                         was_exec = moea_attr_fetch(pg) & PTE_EXEC;
1096                 }
1097         }
1098
1099         pte_lo = moea_calc_wimg(VM_PAGE_TO_PHYS(m), pmap_page_get_memattr(m));
1100
1101         if (prot & VM_PROT_WRITE) {
1102                 pte_lo |= PTE_BW;
1103                 if (pmap_bootstrapped &&
1104                     (m->oflags & VPO_UNMANAGED) == 0)
1105                         vm_page_aflag_set(m, PGA_WRITEABLE);
1106         } else
1107                 pte_lo |= PTE_BR;
1108
1109         if (prot & VM_PROT_EXECUTE)
1110                 pvo_flags |= PVO_EXECUTABLE;
1111
1112         if (wired)
1113                 pvo_flags |= PVO_WIRED;
1114
1115         error = moea_pvo_enter(pmap, zone, pvo_head, va, VM_PAGE_TO_PHYS(m),
1116             pte_lo, pvo_flags);
1117
1118         /*
1119          * Flush the real page from the instruction cache if this page is
1120          * mapped executable and cacheable and was not previously mapped (or
1121          * was not mapped executable).
1122          */
1123         if (error == 0 && (pvo_flags & PVO_EXECUTABLE) &&
1124             (pte_lo & PTE_I) == 0 && was_exec == 0) {
1125                 /*
1126                  * Flush the real memory from the cache.
1127                  */
1128                 moea_syncicache(VM_PAGE_TO_PHYS(m), PAGE_SIZE);
1129                 if (pg != NULL)
1130                         moea_attr_save(pg, PTE_EXEC);
1131         }
1132
1133         /* XXX syncicache always until problems are sorted */
1134         moea_syncicache(VM_PAGE_TO_PHYS(m), PAGE_SIZE);
1135 }
1136
1137 /*
1138  * Maps a sequence of resident pages belonging to the same object.
1139  * The sequence begins with the given page m_start.  This page is
1140  * mapped at the given virtual address start.  Each subsequent page is
1141  * mapped at a virtual address that is offset from start by the same
1142  * amount as the page is offset from m_start within the object.  The
1143  * last page in the sequence is the page with the largest offset from
1144  * m_start that can be mapped at a virtual address less than the given
1145  * virtual address end.  Not every virtual page between start and end
1146  * is mapped; only those for which a resident page exists with the
1147  * corresponding offset from m_start are mapped.
1148  */
1149 void
1150 moea_enter_object(mmu_t mmu, pmap_t pm, vm_offset_t start, vm_offset_t end,
1151     vm_page_t m_start, vm_prot_t prot)
1152 {
1153         vm_page_t m;
1154         vm_pindex_t diff, psize;
1155
1156         psize = atop(end - start);
1157         m = m_start;
1158         vm_page_lock_queues();
1159         PMAP_LOCK(pm);
1160         while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
1161                 moea_enter_locked(pm, start + ptoa(diff), m, prot &
1162                     (VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
1163                 m = TAILQ_NEXT(m, listq);
1164         }
1165         vm_page_unlock_queues();
1166         PMAP_UNLOCK(pm);
1167 }
1168
1169 void
1170 moea_enter_quick(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_page_t m,
1171     vm_prot_t prot)
1172 {
1173
1174         vm_page_lock_queues();
1175         PMAP_LOCK(pm);
1176         moea_enter_locked(pm, va, m, prot & (VM_PROT_READ | VM_PROT_EXECUTE),
1177             FALSE);
1178         vm_page_unlock_queues();
1179         PMAP_UNLOCK(pm);
1180 }
1181
1182 vm_paddr_t
1183 moea_extract(mmu_t mmu, pmap_t pm, vm_offset_t va)
1184 {
1185         struct  pvo_entry *pvo;
1186         vm_paddr_t pa;
1187
1188         PMAP_LOCK(pm);
1189         pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
1190         if (pvo == NULL)
1191                 pa = 0;
1192         else
1193                 pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF);
1194         PMAP_UNLOCK(pm);
1195         return (pa);
1196 }
1197
1198 /*
1199  * Atomically extract and hold the physical page with the given
1200  * pmap and virtual address pair if that mapping permits the given
1201  * protection.
1202  */
1203 vm_page_t
1204 moea_extract_and_hold(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_prot_t prot)
1205 {
1206         struct  pvo_entry *pvo;
1207         vm_page_t m;
1208         vm_paddr_t pa;
1209
1210         m = NULL;
1211         pa = 0;
1212         PMAP_LOCK(pmap);
1213 retry:
1214         pvo = moea_pvo_find_va(pmap, va & ~ADDR_POFF, NULL);
1215         if (pvo != NULL && (pvo->pvo_pte.pte.pte_hi & PTE_VALID) &&
1216             ((pvo->pvo_pte.pte.pte_lo & PTE_PP) == PTE_RW ||
1217              (prot & VM_PROT_WRITE) == 0)) {
1218                 if (vm_page_pa_tryrelock(pmap, pvo->pvo_pte.pte.pte_lo & PTE_RPGN, &pa))
1219                         goto retry;
1220                 m = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte.pte_lo & PTE_RPGN);
1221                 vm_page_hold(m);
1222         }
1223         PA_UNLOCK_COND(pa);
1224         PMAP_UNLOCK(pmap);
1225         return (m);
1226 }
1227
1228 void
1229 moea_init(mmu_t mmu)
1230 {
1231
1232         moea_upvo_zone = uma_zcreate("UPVO entry", sizeof (struct pvo_entry),
1233             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
1234             UMA_ZONE_VM | UMA_ZONE_NOFREE);
1235         moea_mpvo_zone = uma_zcreate("MPVO entry", sizeof(struct pvo_entry),
1236             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
1237             UMA_ZONE_VM | UMA_ZONE_NOFREE);
1238         moea_initialized = TRUE;
1239 }
1240
1241 boolean_t
1242 moea_is_referenced(mmu_t mmu, vm_page_t m)
1243 {
1244
1245         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1246             ("moea_is_referenced: page %p is not managed", m));
1247         return (moea_query_bit(m, PTE_REF));
1248 }
1249
1250 boolean_t
1251 moea_is_modified(mmu_t mmu, vm_page_t m)
1252 {
1253
1254         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1255             ("moea_is_modified: page %p is not managed", m));
1256
1257         /*
1258          * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be
1259          * concurrently set while the object is locked.  Thus, if PGA_WRITEABLE
1260          * is clear, no PTEs can have PTE_CHG set.
1261          */
1262         VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
1263         if ((m->oflags & VPO_BUSY) == 0 &&
1264             (m->aflags & PGA_WRITEABLE) == 0)
1265                 return (FALSE);
1266         return (moea_query_bit(m, PTE_CHG));
1267 }
1268
1269 boolean_t
1270 moea_is_prefaultable(mmu_t mmu, pmap_t pmap, vm_offset_t va)
1271 {
1272         struct pvo_entry *pvo;
1273         boolean_t rv;
1274
1275         PMAP_LOCK(pmap);
1276         pvo = moea_pvo_find_va(pmap, va & ~ADDR_POFF, NULL);
1277         rv = pvo == NULL || (pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0;
1278         PMAP_UNLOCK(pmap);
1279         return (rv);
1280 }
1281
1282 void
1283 moea_clear_reference(mmu_t mmu, vm_page_t m)
1284 {
1285
1286         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1287             ("moea_clear_reference: page %p is not managed", m));
1288         moea_clear_bit(m, PTE_REF);
1289 }
1290
1291 void
1292 moea_clear_modify(mmu_t mmu, vm_page_t m)
1293 {
1294
1295         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1296             ("moea_clear_modify: page %p is not managed", m));
1297         VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
1298         KASSERT((m->oflags & VPO_BUSY) == 0,
1299             ("moea_clear_modify: page %p is busy", m));
1300
1301         /*
1302          * If the page is not PGA_WRITEABLE, then no PTEs can have PTE_CHG
1303          * set.  If the object containing the page is locked and the page is
1304          * not VPO_BUSY, then PGA_WRITEABLE cannot be concurrently set.
1305          */
1306         if ((m->aflags & PGA_WRITEABLE) == 0)
1307                 return;
1308         moea_clear_bit(m, PTE_CHG);
1309 }
1310
1311 /*
1312  * Clear the write and modified bits in each of the given page's mappings.
1313  */
1314 void
1315 moea_remove_write(mmu_t mmu, vm_page_t m)
1316 {
1317         struct  pvo_entry *pvo;
1318         struct  pte *pt;
1319         pmap_t  pmap;
1320         u_int   lo;
1321
1322         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1323             ("moea_remove_write: page %p is not managed", m));
1324
1325         /*
1326          * If the page is not VPO_BUSY, then PGA_WRITEABLE cannot be set by
1327          * another thread while the object is locked.  Thus, if PGA_WRITEABLE
1328          * is clear, no page table entries need updating.
1329          */
1330         VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
1331         if ((m->oflags & VPO_BUSY) == 0 &&
1332             (m->aflags & PGA_WRITEABLE) == 0)
1333                 return;
1334         vm_page_lock_queues();
1335         lo = moea_attr_fetch(m);
1336         powerpc_sync();
1337         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
1338                 pmap = pvo->pvo_pmap;
1339                 PMAP_LOCK(pmap);
1340                 if ((pvo->pvo_pte.pte.pte_lo & PTE_PP) != PTE_BR) {
1341                         pt = moea_pvo_to_pte(pvo, -1);
1342                         pvo->pvo_pte.pte.pte_lo &= ~PTE_PP;
1343                         pvo->pvo_pte.pte.pte_lo |= PTE_BR;
1344                         if (pt != NULL) {
1345                                 moea_pte_synch(pt, &pvo->pvo_pte.pte);
1346                                 lo |= pvo->pvo_pte.pte.pte_lo;
1347                                 pvo->pvo_pte.pte.pte_lo &= ~PTE_CHG;
1348                                 moea_pte_change(pt, &pvo->pvo_pte.pte,
1349                                     pvo->pvo_vaddr);
1350                                 mtx_unlock(&moea_table_mutex);
1351                         }
1352                 }
1353                 PMAP_UNLOCK(pmap);
1354         }
1355         if ((lo & PTE_CHG) != 0) {
1356                 moea_attr_clear(m, PTE_CHG);
1357                 vm_page_dirty(m);
1358         }
1359         vm_page_aflag_clear(m, PGA_WRITEABLE);
1360         vm_page_unlock_queues();
1361 }
1362
1363 /*
1364  *      moea_ts_referenced:
1365  *
1366  *      Return a count of reference bits for a page, clearing those bits.
1367  *      It is not necessary for every reference bit to be cleared, but it
1368  *      is necessary that 0 only be returned when there are truly no
1369  *      reference bits set.
1370  *
1371  *      XXX: The exact number of bits to check and clear is a matter that
1372  *      should be tested and standardized at some point in the future for
1373  *      optimal aging of shared pages.
1374  */
1375 boolean_t
1376 moea_ts_referenced(mmu_t mmu, vm_page_t m)
1377 {
1378
1379         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1380             ("moea_ts_referenced: page %p is not managed", m));
1381         return (moea_clear_bit(m, PTE_REF));
1382 }
1383
1384 /*
1385  * Modify the WIMG settings of all mappings for a page.
1386  */
1387 void
1388 moea_page_set_memattr(mmu_t mmu, vm_page_t m, vm_memattr_t ma)
1389 {
1390         struct  pvo_entry *pvo;
1391         struct  pvo_head *pvo_head;
1392         struct  pte *pt;
1393         pmap_t  pmap;
1394         u_int   lo;
1395
1396         if ((m->oflags & VPO_UNMANAGED) != 0) {
1397                 m->md.mdpg_cache_attrs = ma;
1398                 return;
1399         }
1400
1401         vm_page_lock_queues();
1402         pvo_head = vm_page_to_pvoh(m);
1403         lo = moea_calc_wimg(VM_PAGE_TO_PHYS(m), ma);
1404
1405         LIST_FOREACH(pvo, pvo_head, pvo_vlink) {
1406                 pmap = pvo->pvo_pmap;
1407                 PMAP_LOCK(pmap);
1408                 pt = moea_pvo_to_pte(pvo, -1);
1409                 pvo->pvo_pte.pte.pte_lo &= ~PTE_WIMG;
1410                 pvo->pvo_pte.pte.pte_lo |= lo;
1411                 if (pt != NULL) {
1412                         moea_pte_change(pt, &pvo->pvo_pte.pte,
1413                             pvo->pvo_vaddr);
1414                         if (pvo->pvo_pmap == kernel_pmap)
1415                                 isync();
1416                 }
1417                 mtx_unlock(&moea_table_mutex);
1418                 PMAP_UNLOCK(pmap);
1419         }
1420         m->md.mdpg_cache_attrs = ma;
1421         vm_page_unlock_queues();
1422 }
1423
1424 /*
1425  * Map a wired page into kernel virtual address space.
1426  */
1427 void
1428 moea_kenter(mmu_t mmu, vm_offset_t va, vm_offset_t pa)
1429 {
1430
1431         moea_kenter_attr(mmu, va, pa, VM_MEMATTR_DEFAULT);
1432 }
1433
1434 void
1435 moea_kenter_attr(mmu_t mmu, vm_offset_t va, vm_offset_t pa, vm_memattr_t ma)
1436 {
1437         u_int           pte_lo;
1438         int             error;  
1439
1440 #if 0
1441         if (va < VM_MIN_KERNEL_ADDRESS)
1442                 panic("moea_kenter: attempt to enter non-kernel address %#x",
1443                     va);
1444 #endif
1445
1446         pte_lo = moea_calc_wimg(pa, ma);
1447
1448         PMAP_LOCK(kernel_pmap);
1449         error = moea_pvo_enter(kernel_pmap, moea_upvo_zone,
1450             &moea_pvo_kunmanaged, va, pa, pte_lo, PVO_WIRED);
1451
1452         if (error != 0 && error != ENOENT)
1453                 panic("moea_kenter: failed to enter va %#x pa %#x: %d", va,
1454                     pa, error);
1455
1456         /*
1457          * Flush the real memory from the instruction cache.
1458          */
1459         if ((pte_lo & (PTE_I | PTE_G)) == 0) {
1460                 moea_syncicache(pa, PAGE_SIZE);
1461         }
1462         PMAP_UNLOCK(kernel_pmap);
1463 }
1464
1465 /*
1466  * Extract the physical page address associated with the given kernel virtual
1467  * address.
1468  */
1469 vm_offset_t
1470 moea_kextract(mmu_t mmu, vm_offset_t va)
1471 {
1472         struct          pvo_entry *pvo;
1473         vm_paddr_t pa;
1474
1475         /*
1476          * Allow direct mappings on 32-bit OEA
1477          */
1478         if (va < VM_MIN_KERNEL_ADDRESS) {
1479                 return (va);
1480         }
1481
1482         PMAP_LOCK(kernel_pmap);
1483         pvo = moea_pvo_find_va(kernel_pmap, va & ~ADDR_POFF, NULL);
1484         KASSERT(pvo != NULL, ("moea_kextract: no addr found"));
1485         pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF);
1486         PMAP_UNLOCK(kernel_pmap);
1487         return (pa);
1488 }
1489
1490 /*
1491  * Remove a wired page from kernel virtual address space.
1492  */
1493 void
1494 moea_kremove(mmu_t mmu, vm_offset_t va)
1495 {
1496
1497         moea_remove(mmu, kernel_pmap, va, va + PAGE_SIZE);
1498 }
1499
1500 /*
1501  * Map a range of physical addresses into kernel virtual address space.
1502  *
1503  * The value passed in *virt is a suggested virtual address for the mapping.
1504  * Architectures which can support a direct-mapped physical to virtual region
1505  * can return the appropriate address within that region, leaving '*virt'
1506  * unchanged.  We cannot and therefore do not; *virt is updated with the
1507  * first usable address after the mapped region.
1508  */
1509 vm_offset_t
1510 moea_map(mmu_t mmu, vm_offset_t *virt, vm_offset_t pa_start,
1511     vm_offset_t pa_end, int prot)
1512 {
1513         vm_offset_t     sva, va;
1514
1515         sva = *virt;
1516         va = sva;
1517         for (; pa_start < pa_end; pa_start += PAGE_SIZE, va += PAGE_SIZE)
1518                 moea_kenter(mmu, va, pa_start);
1519         *virt = va;
1520         return (sva);
1521 }
1522
1523 /*
1524  * Returns true if the pmap's pv is one of the first
1525  * 16 pvs linked to from this page.  This count may
1526  * be changed upwards or downwards in the future; it
1527  * is only necessary that true be returned for a small
1528  * subset of pmaps for proper page aging.
1529  */
1530 boolean_t
1531 moea_page_exists_quick(mmu_t mmu, pmap_t pmap, vm_page_t m)
1532 {
1533         int loops;
1534         struct pvo_entry *pvo;
1535         boolean_t rv;
1536
1537         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1538             ("moea_page_exists_quick: page %p is not managed", m));
1539         loops = 0;
1540         rv = FALSE;
1541         vm_page_lock_queues();
1542         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
1543                 if (pvo->pvo_pmap == pmap) {
1544                         rv = TRUE;
1545                         break;
1546                 }
1547                 if (++loops >= 16)
1548                         break;
1549         }
1550         vm_page_unlock_queues();
1551         return (rv);
1552 }
1553
1554 /*
1555  * Return the number of managed mappings to the given physical page
1556  * that are wired.
1557  */
1558 int
1559 moea_page_wired_mappings(mmu_t mmu, vm_page_t m)
1560 {
1561         struct pvo_entry *pvo;
1562         int count;
1563
1564         count = 0;
1565         if ((m->oflags & VPO_UNMANAGED) != 0)
1566                 return (count);
1567         vm_page_lock_queues();
1568         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink)
1569                 if ((pvo->pvo_vaddr & PVO_WIRED) != 0)
1570                         count++;
1571         vm_page_unlock_queues();
1572         return (count);
1573 }
1574
1575 static u_int    moea_vsidcontext;
1576
1577 void
1578 moea_pinit(mmu_t mmu, pmap_t pmap)
1579 {
1580         int     i, mask;
1581         u_int   entropy;
1582
1583         KASSERT((int)pmap < VM_MIN_KERNEL_ADDRESS, ("moea_pinit: virt pmap"));
1584         PMAP_LOCK_INIT(pmap);
1585
1586         entropy = 0;
1587         __asm __volatile("mftb %0" : "=r"(entropy));
1588
1589         if ((pmap->pmap_phys = (pmap_t)moea_kextract(mmu, (vm_offset_t)pmap))
1590             == NULL) {
1591                 pmap->pmap_phys = pmap;
1592         }
1593         
1594
1595         mtx_lock(&moea_vsid_mutex);
1596         /*
1597          * Allocate some segment registers for this pmap.
1598          */
1599         for (i = 0; i < NPMAPS; i += VSID_NBPW) {
1600                 u_int   hash, n;
1601
1602                 /*
1603                  * Create a new value by mutiplying by a prime and adding in
1604                  * entropy from the timebase register.  This is to make the
1605                  * VSID more random so that the PT hash function collides
1606                  * less often.  (Note that the prime casues gcc to do shifts
1607                  * instead of a multiply.)
1608                  */
1609                 moea_vsidcontext = (moea_vsidcontext * 0x1105) + entropy;
1610                 hash = moea_vsidcontext & (NPMAPS - 1);
1611                 if (hash == 0)          /* 0 is special, avoid it */
1612                         continue;
1613                 n = hash >> 5;
1614                 mask = 1 << (hash & (VSID_NBPW - 1));
1615                 hash = (moea_vsidcontext & 0xfffff);
1616                 if (moea_vsid_bitmap[n] & mask) {       /* collision? */
1617                         /* anything free in this bucket? */
1618                         if (moea_vsid_bitmap[n] == 0xffffffff) {
1619                                 entropy = (moea_vsidcontext >> 20);
1620                                 continue;
1621                         }
1622                         i = ffs(~moea_vsid_bitmap[n]) - 1;
1623                         mask = 1 << i;
1624                         hash &= 0xfffff & ~(VSID_NBPW - 1);
1625                         hash |= i;
1626                 }
1627                 moea_vsid_bitmap[n] |= mask;
1628                 for (i = 0; i < 16; i++)
1629                         pmap->pm_sr[i] = VSID_MAKE(i, hash);
1630                 mtx_unlock(&moea_vsid_mutex);
1631                 return;
1632         }
1633
1634         mtx_unlock(&moea_vsid_mutex);
1635         panic("moea_pinit: out of segments");
1636 }
1637
1638 /*
1639  * Initialize the pmap associated with process 0.
1640  */
1641 void
1642 moea_pinit0(mmu_t mmu, pmap_t pm)
1643 {
1644
1645         moea_pinit(mmu, pm);
1646         bzero(&pm->pm_stats, sizeof(pm->pm_stats));
1647 }
1648
1649 /*
1650  * Set the physical protection on the specified range of this map as requested.
1651  */
1652 void
1653 moea_protect(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva,
1654     vm_prot_t prot)
1655 {
1656         struct  pvo_entry *pvo;
1657         struct  pte *pt;
1658         int     pteidx;
1659
1660         KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
1661             ("moea_protect: non current pmap"));
1662
1663         if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
1664                 moea_remove(mmu, pm, sva, eva);
1665                 return;
1666         }
1667
1668         vm_page_lock_queues();
1669         PMAP_LOCK(pm);
1670         for (; sva < eva; sva += PAGE_SIZE) {
1671                 pvo = moea_pvo_find_va(pm, sva, &pteidx);
1672                 if (pvo == NULL)
1673                         continue;
1674
1675                 if ((prot & VM_PROT_EXECUTE) == 0)
1676                         pvo->pvo_vaddr &= ~PVO_EXECUTABLE;
1677
1678                 /*
1679                  * Grab the PTE pointer before we diddle with the cached PTE
1680                  * copy.
1681                  */
1682                 pt = moea_pvo_to_pte(pvo, pteidx);
1683                 /*
1684                  * Change the protection of the page.
1685                  */
1686                 pvo->pvo_pte.pte.pte_lo &= ~PTE_PP;
1687                 pvo->pvo_pte.pte.pte_lo |= PTE_BR;
1688
1689                 /*
1690                  * If the PVO is in the page table, update that pte as well.
1691                  */
1692                 if (pt != NULL) {
1693                         moea_pte_change(pt, &pvo->pvo_pte.pte, pvo->pvo_vaddr);
1694                         mtx_unlock(&moea_table_mutex);
1695                 }
1696         }
1697         vm_page_unlock_queues();
1698         PMAP_UNLOCK(pm);
1699 }
1700
1701 /*
1702  * Map a list of wired pages into kernel virtual address space.  This is
1703  * intended for temporary mappings which do not need page modification or
1704  * references recorded.  Existing mappings in the region are overwritten.
1705  */
1706 void
1707 moea_qenter(mmu_t mmu, vm_offset_t sva, vm_page_t *m, int count)
1708 {
1709         vm_offset_t va;
1710
1711         va = sva;
1712         while (count-- > 0) {
1713                 moea_kenter(mmu, va, VM_PAGE_TO_PHYS(*m));
1714                 va += PAGE_SIZE;
1715                 m++;
1716         }
1717 }
1718
1719 /*
1720  * Remove page mappings from kernel virtual address space.  Intended for
1721  * temporary mappings entered by moea_qenter.
1722  */
1723 void
1724 moea_qremove(mmu_t mmu, vm_offset_t sva, int count)
1725 {
1726         vm_offset_t va;
1727
1728         va = sva;
1729         while (count-- > 0) {
1730                 moea_kremove(mmu, va);
1731                 va += PAGE_SIZE;
1732         }
1733 }
1734
1735 void
1736 moea_release(mmu_t mmu, pmap_t pmap)
1737 {
1738         int idx, mask;
1739         
1740         /*
1741          * Free segment register's VSID
1742          */
1743         if (pmap->pm_sr[0] == 0)
1744                 panic("moea_release");
1745
1746         mtx_lock(&moea_vsid_mutex);
1747         idx = VSID_TO_HASH(pmap->pm_sr[0]) & (NPMAPS-1);
1748         mask = 1 << (idx % VSID_NBPW);
1749         idx /= VSID_NBPW;
1750         moea_vsid_bitmap[idx] &= ~mask;
1751         mtx_unlock(&moea_vsid_mutex);
1752         PMAP_LOCK_DESTROY(pmap);
1753 }
1754
1755 /*
1756  * Remove the given range of addresses from the specified map.
1757  */
1758 void
1759 moea_remove(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva)
1760 {
1761         struct  pvo_entry *pvo;
1762         int     pteidx;
1763
1764         vm_page_lock_queues();
1765         PMAP_LOCK(pm);
1766         for (; sva < eva; sva += PAGE_SIZE) {
1767                 pvo = moea_pvo_find_va(pm, sva, &pteidx);
1768                 if (pvo != NULL) {
1769                         moea_pvo_remove(pvo, pteidx);
1770                 }
1771         }
1772         PMAP_UNLOCK(pm);
1773         vm_page_unlock_queues();
1774 }
1775
1776 /*
1777  * Remove physical page from all pmaps in which it resides. moea_pvo_remove()
1778  * will reflect changes in pte's back to the vm_page.
1779  */
1780 void
1781 moea_remove_all(mmu_t mmu, vm_page_t m)
1782 {
1783         struct  pvo_head *pvo_head;
1784         struct  pvo_entry *pvo, *next_pvo;
1785         pmap_t  pmap;
1786
1787         vm_page_lock_queues();
1788         pvo_head = vm_page_to_pvoh(m);
1789         for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) {
1790                 next_pvo = LIST_NEXT(pvo, pvo_vlink);
1791
1792                 pmap = pvo->pvo_pmap;
1793                 PMAP_LOCK(pmap);
1794                 moea_pvo_remove(pvo, -1);
1795                 PMAP_UNLOCK(pmap);
1796         }
1797         if ((m->aflags & PGA_WRITEABLE) && moea_is_modified(mmu, m)) {
1798                 moea_attr_clear(m, PTE_CHG);
1799                 vm_page_dirty(m);
1800         }
1801         vm_page_aflag_clear(m, PGA_WRITEABLE);
1802         vm_page_unlock_queues();
1803 }
1804
1805 /*
1806  * Allocate a physical page of memory directly from the phys_avail map.
1807  * Can only be called from moea_bootstrap before avail start and end are
1808  * calculated.
1809  */
1810 static vm_offset_t
1811 moea_bootstrap_alloc(vm_size_t size, u_int align)
1812 {
1813         vm_offset_t     s, e;
1814         int             i, j;
1815
1816         size = round_page(size);
1817         for (i = 0; phys_avail[i + 1] != 0; i += 2) {
1818                 if (align != 0)
1819                         s = (phys_avail[i] + align - 1) & ~(align - 1);
1820                 else
1821                         s = phys_avail[i];
1822                 e = s + size;
1823
1824                 if (s < phys_avail[i] || e > phys_avail[i + 1])
1825                         continue;
1826
1827                 if (s == phys_avail[i]) {
1828                         phys_avail[i] += size;
1829                 } else if (e == phys_avail[i + 1]) {
1830                         phys_avail[i + 1] -= size;
1831                 } else {
1832                         for (j = phys_avail_count * 2; j > i; j -= 2) {
1833                                 phys_avail[j] = phys_avail[j - 2];
1834                                 phys_avail[j + 1] = phys_avail[j - 1];
1835                         }
1836
1837                         phys_avail[i + 3] = phys_avail[i + 1];
1838                         phys_avail[i + 1] = s;
1839                         phys_avail[i + 2] = e;
1840                         phys_avail_count++;
1841                 }
1842
1843                 return (s);
1844         }
1845         panic("moea_bootstrap_alloc: could not allocate memory");
1846 }
1847
1848 static void
1849 moea_syncicache(vm_offset_t pa, vm_size_t len)
1850 {
1851         __syncicache((void *)pa, len);
1852 }
1853
1854 static int
1855 moea_pvo_enter(pmap_t pm, uma_zone_t zone, struct pvo_head *pvo_head,
1856     vm_offset_t va, vm_offset_t pa, u_int pte_lo, int flags)
1857 {
1858         struct  pvo_entry *pvo;
1859         u_int   sr;
1860         int     first;
1861         u_int   ptegidx;
1862         int     i;
1863         int     bootstrap;
1864
1865         moea_pvo_enter_calls++;
1866         first = 0;
1867         bootstrap = 0;
1868
1869         /*
1870          * Compute the PTE Group index.
1871          */
1872         va &= ~ADDR_POFF;
1873         sr = va_to_sr(pm->pm_sr, va);
1874         ptegidx = va_to_pteg(sr, va);
1875
1876         /*
1877          * Remove any existing mapping for this page.  Reuse the pvo entry if
1878          * there is a mapping.
1879          */
1880         mtx_lock(&moea_table_mutex);
1881         LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) {
1882                 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
1883                         if ((pvo->pvo_pte.pte.pte_lo & PTE_RPGN) == pa &&
1884                             (pvo->pvo_pte.pte.pte_lo & PTE_PP) ==
1885                             (pte_lo & PTE_PP)) {
1886                                 mtx_unlock(&moea_table_mutex);
1887                                 return (0);
1888                         }
1889                         moea_pvo_remove(pvo, -1);
1890                         break;
1891                 }
1892         }
1893
1894         /*
1895          * If we aren't overwriting a mapping, try to allocate.
1896          */
1897         if (moea_initialized) {
1898                 pvo = uma_zalloc(zone, M_NOWAIT);
1899         } else {
1900                 if (moea_bpvo_pool_index >= BPVO_POOL_SIZE) {
1901                         panic("moea_enter: bpvo pool exhausted, %d, %d, %d",
1902                               moea_bpvo_pool_index, BPVO_POOL_SIZE, 
1903                               BPVO_POOL_SIZE * sizeof(struct pvo_entry));
1904                 }
1905                 pvo = &moea_bpvo_pool[moea_bpvo_pool_index];
1906                 moea_bpvo_pool_index++;
1907                 bootstrap = 1;
1908         }
1909
1910         if (pvo == NULL) {
1911                 mtx_unlock(&moea_table_mutex);
1912                 return (ENOMEM);
1913         }
1914
1915         moea_pvo_entries++;
1916         pvo->pvo_vaddr = va;
1917         pvo->pvo_pmap = pm;
1918         LIST_INSERT_HEAD(&moea_pvo_table[ptegidx], pvo, pvo_olink);
1919         pvo->pvo_vaddr &= ~ADDR_POFF;
1920         if (flags & VM_PROT_EXECUTE)
1921                 pvo->pvo_vaddr |= PVO_EXECUTABLE;
1922         if (flags & PVO_WIRED)
1923                 pvo->pvo_vaddr |= PVO_WIRED;
1924         if (pvo_head != &moea_pvo_kunmanaged)
1925                 pvo->pvo_vaddr |= PVO_MANAGED;
1926         if (bootstrap)
1927                 pvo->pvo_vaddr |= PVO_BOOTSTRAP;
1928
1929         moea_pte_create(&pvo->pvo_pte.pte, sr, va, pa | pte_lo);
1930
1931         /*
1932          * Remember if the list was empty and therefore will be the first
1933          * item.
1934          */
1935         if (LIST_FIRST(pvo_head) == NULL)
1936                 first = 1;
1937         LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink);
1938
1939         if (pvo->pvo_pte.pte.pte_lo & PVO_WIRED)
1940                 pm->pm_stats.wired_count++;
1941         pm->pm_stats.resident_count++;
1942
1943         /*
1944          * We hope this succeeds but it isn't required.
1945          */
1946         i = moea_pte_insert(ptegidx, &pvo->pvo_pte.pte);
1947         if (i >= 0) {
1948                 PVO_PTEGIDX_SET(pvo, i);
1949         } else {
1950                 panic("moea_pvo_enter: overflow");
1951                 moea_pte_overflow++;
1952         }
1953         mtx_unlock(&moea_table_mutex);
1954
1955         return (first ? ENOENT : 0);
1956 }
1957
1958 static void
1959 moea_pvo_remove(struct pvo_entry *pvo, int pteidx)
1960 {
1961         struct  pte *pt;
1962
1963         /*
1964          * If there is an active pte entry, we need to deactivate it (and
1965          * save the ref & cfg bits).
1966          */
1967         pt = moea_pvo_to_pte(pvo, pteidx);
1968         if (pt != NULL) {
1969                 moea_pte_unset(pt, &pvo->pvo_pte.pte, pvo->pvo_vaddr);
1970                 mtx_unlock(&moea_table_mutex);
1971                 PVO_PTEGIDX_CLR(pvo);
1972         } else {
1973                 moea_pte_overflow--;
1974         }
1975
1976         /*
1977          * Update our statistics.
1978          */
1979         pvo->pvo_pmap->pm_stats.resident_count--;
1980         if (pvo->pvo_pte.pte.pte_lo & PVO_WIRED)
1981                 pvo->pvo_pmap->pm_stats.wired_count--;
1982
1983         /*
1984          * Save the REF/CHG bits into their cache if the page is managed.
1985          */
1986         if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED) {
1987                 struct  vm_page *pg;
1988
1989                 pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.pte.pte_lo & PTE_RPGN);
1990                 if (pg != NULL) {
1991                         moea_attr_save(pg, pvo->pvo_pte.pte.pte_lo &
1992                             (PTE_REF | PTE_CHG));
1993                 }
1994         }
1995
1996         /*
1997          * Remove this PVO from the PV list.
1998          */
1999         LIST_REMOVE(pvo, pvo_vlink);
2000
2001         /*
2002          * Remove this from the overflow list and return it to the pool
2003          * if we aren't going to reuse it.
2004          */
2005         LIST_REMOVE(pvo, pvo_olink);
2006         if (!(pvo->pvo_vaddr & PVO_BOOTSTRAP))
2007                 uma_zfree(pvo->pvo_vaddr & PVO_MANAGED ? moea_mpvo_zone :
2008                     moea_upvo_zone, pvo);
2009         moea_pvo_entries--;
2010         moea_pvo_remove_calls++;
2011 }
2012
2013 static __inline int
2014 moea_pvo_pte_index(const struct pvo_entry *pvo, int ptegidx)
2015 {
2016         int     pteidx;
2017
2018         /*
2019          * We can find the actual pte entry without searching by grabbing
2020          * the PTEG index from 3 unused bits in pte_lo[11:9] and by
2021          * noticing the HID bit.
2022          */
2023         pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo);
2024         if (pvo->pvo_pte.pte.pte_hi & PTE_HID)
2025                 pteidx ^= moea_pteg_mask * 8;
2026
2027         return (pteidx);
2028 }
2029
2030 static struct pvo_entry *
2031 moea_pvo_find_va(pmap_t pm, vm_offset_t va, int *pteidx_p)
2032 {
2033         struct  pvo_entry *pvo;
2034         int     ptegidx;
2035         u_int   sr;
2036
2037         va &= ~ADDR_POFF;
2038         sr = va_to_sr(pm->pm_sr, va);
2039         ptegidx = va_to_pteg(sr, va);
2040
2041         mtx_lock(&moea_table_mutex);
2042         LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) {
2043                 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
2044                         if (pteidx_p)
2045                                 *pteidx_p = moea_pvo_pte_index(pvo, ptegidx);
2046                         break;
2047                 }
2048         }
2049         mtx_unlock(&moea_table_mutex);
2050
2051         return (pvo);
2052 }
2053
2054 static struct pte *
2055 moea_pvo_to_pte(const struct pvo_entry *pvo, int pteidx)
2056 {
2057         struct  pte *pt;
2058
2059         /*
2060          * If we haven't been supplied the ptegidx, calculate it.
2061          */
2062         if (pteidx == -1) {
2063                 int     ptegidx;
2064                 u_int   sr;
2065
2066                 sr = va_to_sr(pvo->pvo_pmap->pm_sr, pvo->pvo_vaddr);
2067                 ptegidx = va_to_pteg(sr, pvo->pvo_vaddr);
2068                 pteidx = moea_pvo_pte_index(pvo, ptegidx);
2069         }
2070
2071         pt = &moea_pteg_table[pteidx >> 3].pt[pteidx & 7];
2072         mtx_lock(&moea_table_mutex);
2073
2074         if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) {
2075                 panic("moea_pvo_to_pte: pvo %p has valid pte in pvo but no "
2076                     "valid pte index", pvo);
2077         }
2078
2079         if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) {
2080                 panic("moea_pvo_to_pte: pvo %p has valid pte index in pvo "
2081                     "pvo but no valid pte", pvo);
2082         }
2083
2084         if ((pt->pte_hi ^ (pvo->pvo_pte.pte.pte_hi & ~PTE_VALID)) == PTE_VALID) {
2085                 if ((pvo->pvo_pte.pte.pte_hi & PTE_VALID) == 0) {
2086                         panic("moea_pvo_to_pte: pvo %p has valid pte in "
2087                             "moea_pteg_table %p but invalid in pvo", pvo, pt);
2088                 }
2089
2090                 if (((pt->pte_lo ^ pvo->pvo_pte.pte.pte_lo) & ~(PTE_CHG|PTE_REF))
2091                     != 0) {
2092                         panic("moea_pvo_to_pte: pvo %p pte does not match "
2093                             "pte %p in moea_pteg_table", pvo, pt);
2094                 }
2095
2096                 mtx_assert(&moea_table_mutex, MA_OWNED);
2097                 return (pt);
2098         }
2099
2100         if (pvo->pvo_pte.pte.pte_hi & PTE_VALID) {
2101                 panic("moea_pvo_to_pte: pvo %p has invalid pte %p in "
2102                     "moea_pteg_table but valid in pvo", pvo, pt);
2103         }
2104
2105         mtx_unlock(&moea_table_mutex);
2106         return (NULL);
2107 }
2108
2109 /*
2110  * XXX: THIS STUFF SHOULD BE IN pte.c?
2111  */
2112 int
2113 moea_pte_spill(vm_offset_t addr)
2114 {
2115         struct  pvo_entry *source_pvo, *victim_pvo;
2116         struct  pvo_entry *pvo;
2117         int     ptegidx, i, j;
2118         u_int   sr;
2119         struct  pteg *pteg;
2120         struct  pte *pt;
2121
2122         moea_pte_spills++;
2123
2124         sr = mfsrin(addr);
2125         ptegidx = va_to_pteg(sr, addr);
2126
2127         /*
2128          * Have to substitute some entry.  Use the primary hash for this.
2129          * Use low bits of timebase as random generator.
2130          */
2131         pteg = &moea_pteg_table[ptegidx];
2132         mtx_lock(&moea_table_mutex);
2133         __asm __volatile("mftb %0" : "=r"(i));
2134         i &= 7;
2135         pt = &pteg->pt[i];
2136
2137         source_pvo = NULL;
2138         victim_pvo = NULL;
2139         LIST_FOREACH(pvo, &moea_pvo_table[ptegidx], pvo_olink) {
2140                 /*
2141                  * We need to find a pvo entry for this address.
2142                  */
2143                 if (source_pvo == NULL &&
2144                     moea_pte_match(&pvo->pvo_pte.pte, sr, addr,
2145                     pvo->pvo_pte.pte.pte_hi & PTE_HID)) {
2146                         /*
2147                          * Now found an entry to be spilled into the pteg.
2148                          * The PTE is now valid, so we know it's active.
2149                          */
2150                         j = moea_pte_insert(ptegidx, &pvo->pvo_pte.pte);
2151
2152                         if (j >= 0) {
2153                                 PVO_PTEGIDX_SET(pvo, j);
2154                                 moea_pte_overflow--;
2155                                 mtx_unlock(&moea_table_mutex);
2156                                 return (1);
2157                         }
2158
2159                         source_pvo = pvo;
2160
2161                         if (victim_pvo != NULL)
2162                                 break;
2163                 }
2164
2165                 /*
2166                  * We also need the pvo entry of the victim we are replacing
2167                  * so save the R & C bits of the PTE.
2168                  */
2169                 if ((pt->pte_hi & PTE_HID) == 0 && victim_pvo == NULL &&
2170                     moea_pte_compare(pt, &pvo->pvo_pte.pte)) {
2171                         victim_pvo = pvo;
2172                         if (source_pvo != NULL)
2173                                 break;
2174                 }
2175         }
2176
2177         if (source_pvo == NULL) {
2178                 mtx_unlock(&moea_table_mutex);
2179                 return (0);
2180         }
2181
2182         if (victim_pvo == NULL) {
2183                 if ((pt->pte_hi & PTE_HID) == 0)
2184                         panic("moea_pte_spill: victim p-pte (%p) has no pvo"
2185                             "entry", pt);
2186
2187                 /*
2188                  * If this is a secondary PTE, we need to search it's primary
2189                  * pvo bucket for the matching PVO.
2190                  */
2191                 LIST_FOREACH(pvo, &moea_pvo_table[ptegidx ^ moea_pteg_mask],
2192                     pvo_olink) {
2193                         /*
2194                          * We also need the pvo entry of the victim we are
2195                          * replacing so save the R & C bits of the PTE.
2196                          */
2197                         if (moea_pte_compare(pt, &pvo->pvo_pte.pte)) {
2198                                 victim_pvo = pvo;
2199                                 break;
2200                         }
2201                 }
2202
2203                 if (victim_pvo == NULL)
2204                         panic("moea_pte_spill: victim s-pte (%p) has no pvo"
2205                             "entry", pt);
2206         }
2207
2208         /*
2209          * We are invalidating the TLB entry for the EA we are replacing even
2210          * though it's valid.  If we don't, we lose any ref/chg bit changes
2211          * contained in the TLB entry.
2212          */
2213         source_pvo->pvo_pte.pte.pte_hi &= ~PTE_HID;
2214
2215         moea_pte_unset(pt, &victim_pvo->pvo_pte.pte, victim_pvo->pvo_vaddr);
2216         moea_pte_set(pt, &source_pvo->pvo_pte.pte);
2217
2218         PVO_PTEGIDX_CLR(victim_pvo);
2219         PVO_PTEGIDX_SET(source_pvo, i);
2220         moea_pte_replacements++;
2221
2222         mtx_unlock(&moea_table_mutex);
2223         return (1);
2224 }
2225
2226 static int
2227 moea_pte_insert(u_int ptegidx, struct pte *pvo_pt)
2228 {
2229         struct  pte *pt;
2230         int     i;
2231
2232         mtx_assert(&moea_table_mutex, MA_OWNED);
2233
2234         /*
2235          * First try primary hash.
2236          */
2237         for (pt = moea_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
2238                 if ((pt->pte_hi & PTE_VALID) == 0) {
2239                         pvo_pt->pte_hi &= ~PTE_HID;
2240                         moea_pte_set(pt, pvo_pt);
2241                         return (i);
2242                 }
2243         }
2244
2245         /*
2246          * Now try secondary hash.
2247          */
2248         ptegidx ^= moea_pteg_mask;
2249
2250         for (pt = moea_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
2251                 if ((pt->pte_hi & PTE_VALID) == 0) {
2252                         pvo_pt->pte_hi |= PTE_HID;
2253                         moea_pte_set(pt, pvo_pt);
2254                         return (i);
2255                 }
2256         }
2257
2258         panic("moea_pte_insert: overflow");
2259         return (-1);
2260 }
2261
2262 static boolean_t
2263 moea_query_bit(vm_page_t m, int ptebit)
2264 {
2265         struct  pvo_entry *pvo;
2266         struct  pte *pt;
2267
2268         if (moea_attr_fetch(m) & ptebit)
2269                 return (TRUE);
2270
2271         vm_page_lock_queues();
2272         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
2273
2274                 /*
2275                  * See if we saved the bit off.  If so, cache it and return
2276                  * success.
2277                  */
2278                 if (pvo->pvo_pte.pte.pte_lo & ptebit) {
2279                         moea_attr_save(m, ptebit);
2280                         vm_page_unlock_queues();
2281                         return (TRUE);
2282                 }
2283         }
2284
2285         /*
2286          * No luck, now go through the hard part of looking at the PTEs
2287          * themselves.  Sync so that any pending REF/CHG bits are flushed to
2288          * the PTEs.
2289          */
2290         powerpc_sync();
2291         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
2292
2293                 /*
2294                  * See if this pvo has a valid PTE.  if so, fetch the
2295                  * REF/CHG bits from the valid PTE.  If the appropriate
2296                  * ptebit is set, cache it and return success.
2297                  */
2298                 pt = moea_pvo_to_pte(pvo, -1);
2299                 if (pt != NULL) {
2300                         moea_pte_synch(pt, &pvo->pvo_pte.pte);
2301                         mtx_unlock(&moea_table_mutex);
2302                         if (pvo->pvo_pte.pte.pte_lo & ptebit) {
2303                                 moea_attr_save(m, ptebit);
2304                                 vm_page_unlock_queues();
2305                                 return (TRUE);
2306                         }
2307                 }
2308         }
2309
2310         vm_page_unlock_queues();
2311         return (FALSE);
2312 }
2313
2314 static u_int
2315 moea_clear_bit(vm_page_t m, int ptebit)
2316 {
2317         u_int   count;
2318         struct  pvo_entry *pvo;
2319         struct  pte *pt;
2320
2321         vm_page_lock_queues();
2322
2323         /*
2324          * Clear the cached value.
2325          */
2326         moea_attr_clear(m, ptebit);
2327
2328         /*
2329          * Sync so that any pending REF/CHG bits are flushed to the PTEs (so
2330          * we can reset the right ones).  note that since the pvo entries and
2331          * list heads are accessed via BAT0 and are never placed in the page
2332          * table, we don't have to worry about further accesses setting the
2333          * REF/CHG bits.
2334          */
2335         powerpc_sync();
2336
2337         /*
2338          * For each pvo entry, clear the pvo's ptebit.  If this pvo has a
2339          * valid pte clear the ptebit from the valid pte.
2340          */
2341         count = 0;
2342         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
2343                 pt = moea_pvo_to_pte(pvo, -1);
2344                 if (pt != NULL) {
2345                         moea_pte_synch(pt, &pvo->pvo_pte.pte);
2346                         if (pvo->pvo_pte.pte.pte_lo & ptebit) {
2347                                 count++;
2348                                 moea_pte_clear(pt, PVO_VADDR(pvo), ptebit);
2349                         }
2350                         mtx_unlock(&moea_table_mutex);
2351                 }
2352                 pvo->pvo_pte.pte.pte_lo &= ~ptebit;
2353         }
2354
2355         vm_page_unlock_queues();
2356         return (count);
2357 }
2358
2359 /*
2360  * Return true if the physical range is encompassed by the battable[idx]
2361  */
2362 static int
2363 moea_bat_mapped(int idx, vm_offset_t pa, vm_size_t size)
2364 {
2365         u_int prot;
2366         u_int32_t start;
2367         u_int32_t end;
2368         u_int32_t bat_ble;
2369
2370         /*
2371          * Return immediately if not a valid mapping
2372          */
2373         if (!(battable[idx].batu & BAT_Vs))
2374                 return (EINVAL);
2375
2376         /*
2377          * The BAT entry must be cache-inhibited, guarded, and r/w
2378          * so it can function as an i/o page
2379          */
2380         prot = battable[idx].batl & (BAT_I|BAT_G|BAT_PP_RW);
2381         if (prot != (BAT_I|BAT_G|BAT_PP_RW))
2382                 return (EPERM); 
2383
2384         /*
2385          * The address should be within the BAT range. Assume that the
2386          * start address in the BAT has the correct alignment (thus
2387          * not requiring masking)
2388          */
2389         start = battable[idx].batl & BAT_PBS;
2390         bat_ble = (battable[idx].batu & ~(BAT_EBS)) | 0x03;
2391         end = start | (bat_ble << 15) | 0x7fff;
2392
2393         if ((pa < start) || ((pa + size) > end))
2394                 return (ERANGE);
2395
2396         return (0);
2397 }
2398
2399 boolean_t
2400 moea_dev_direct_mapped(mmu_t mmu, vm_offset_t pa, vm_size_t size)
2401 {
2402         int i;
2403
2404         /*
2405          * This currently does not work for entries that 
2406          * overlap 256M BAT segments.
2407          */
2408
2409         for(i = 0; i < 16; i++)
2410                 if (moea_bat_mapped(i, pa, size) == 0)
2411                         return (0);
2412
2413         return (EFAULT);
2414 }
2415
2416 /*
2417  * Map a set of physical memory pages into the kernel virtual
2418  * address space. Return a pointer to where it is mapped. This
2419  * routine is intended to be used for mapping device memory,
2420  * NOT real memory.
2421  */
2422 void *
2423 moea_mapdev(mmu_t mmu, vm_offset_t pa, vm_size_t size)
2424 {
2425
2426         return (moea_mapdev_attr(mmu, pa, size, VM_MEMATTR_DEFAULT));
2427 }
2428
2429 void *
2430 moea_mapdev_attr(mmu_t mmu, vm_offset_t pa, vm_size_t size, vm_memattr_t ma)
2431 {
2432         vm_offset_t va, tmpva, ppa, offset;
2433         int i;
2434
2435         ppa = trunc_page(pa);
2436         offset = pa & PAGE_MASK;
2437         size = roundup(offset + size, PAGE_SIZE);
2438         
2439         /*
2440          * If the physical address lies within a valid BAT table entry,
2441          * return the 1:1 mapping. This currently doesn't work
2442          * for regions that overlap 256M BAT segments.
2443          */
2444         for (i = 0; i < 16; i++) {
2445                 if (moea_bat_mapped(i, pa, size) == 0)
2446                         return ((void *) pa);
2447         }
2448
2449         va = kmem_alloc_nofault(kernel_map, size);
2450         if (!va)
2451                 panic("moea_mapdev: Couldn't alloc kernel virtual memory");
2452
2453         for (tmpva = va; size > 0;) {
2454                 moea_kenter_attr(mmu, tmpva, ppa, ma);
2455                 tlbie(tmpva);
2456                 size -= PAGE_SIZE;
2457                 tmpva += PAGE_SIZE;
2458                 ppa += PAGE_SIZE;
2459         }
2460
2461         return ((void *)(va + offset));
2462 }
2463
2464 void
2465 moea_unmapdev(mmu_t mmu, vm_offset_t va, vm_size_t size)
2466 {
2467         vm_offset_t base, offset;
2468
2469         /*
2470          * If this is outside kernel virtual space, then it's a
2471          * battable entry and doesn't require unmapping
2472          */
2473         if ((va >= VM_MIN_KERNEL_ADDRESS) && (va <= virtual_end)) {
2474                 base = trunc_page(va);
2475                 offset = va & PAGE_MASK;
2476                 size = roundup(offset + size, PAGE_SIZE);
2477                 kmem_free(kernel_map, base, size);
2478         }
2479 }
2480
2481 static void
2482 moea_sync_icache(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_size_t sz)
2483 {
2484         struct pvo_entry *pvo;
2485         vm_offset_t lim;
2486         vm_paddr_t pa;
2487         vm_size_t len;
2488
2489         PMAP_LOCK(pm);
2490         while (sz > 0) {
2491                 lim = round_page(va);
2492                 len = MIN(lim - va, sz);
2493                 pvo = moea_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
2494                 if (pvo != NULL) {
2495                         pa = (pvo->pvo_pte.pte.pte_lo & PTE_RPGN) |
2496                             (va & ADDR_POFF);
2497                         moea_syncicache(pa, len);
2498                 }
2499                 va += len;
2500                 sz -= len;
2501         }
2502         PMAP_UNLOCK(pm);
2503 }