]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/powerpc/aim/mmu_oea64.c
MFV illumos r266986:
[FreeBSD/FreeBSD.git] / sys / powerpc / aim / mmu_oea64.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  *
17  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27  * POSSIBILITY OF SUCH DAMAGE.
28  */
29 /*-
30  * Copyright (C) 1995, 1996 Wolfgang Solfrank.
31  * Copyright (C) 1995, 1996 TooLs GmbH.
32  * All rights reserved.
33  *
34  * Redistribution and use in source and binary forms, with or without
35  * modification, are permitted provided that the following conditions
36  * are met:
37  * 1. Redistributions of source code must retain the above copyright
38  *    notice, this list of conditions and the following disclaimer.
39  * 2. Redistributions in binary form must reproduce the above copyright
40  *    notice, this list of conditions and the following disclaimer in the
41  *    documentation and/or other materials provided with the distribution.
42  * 3. All advertising materials mentioning features or use of this software
43  *    must display the following acknowledgement:
44  *      This product includes software developed by TooLs GmbH.
45  * 4. The name of TooLs GmbH may not be used to endorse or promote products
46  *    derived from this software without specific prior written permission.
47  *
48  * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
49  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
50  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
51  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
53  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
54  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
55  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
56  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
57  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58  *
59  * $NetBSD: pmap.c,v 1.28 2000/03/26 20:42:36 kleink Exp $
60  */
61 /*-
62  * Copyright (C) 2001 Benno Rice.
63  * All rights reserved.
64  *
65  * Redistribution and use in source and binary forms, with or without
66  * modification, are permitted provided that the following conditions
67  * are met:
68  * 1. Redistributions of source code must retain the above copyright
69  *    notice, this list of conditions and the following disclaimer.
70  * 2. Redistributions in binary form must reproduce the above copyright
71  *    notice, this list of conditions and the following disclaimer in the
72  *    documentation and/or other materials provided with the distribution.
73  *
74  * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
75  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
76  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
77  * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
78  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
79  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
80  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
81  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
82  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
83  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
84  */
85
86 #include <sys/cdefs.h>
87 __FBSDID("$FreeBSD$");
88
89 /*
90  * Manages physical address maps.
91  *
92  * Since the information managed by this module is also stored by the
93  * logical address mapping module, this module may throw away valid virtual
94  * to physical mappings at almost any time.  However, invalidations of
95  * mappings must be done as requested.
96  *
97  * In order to cope with hardware architectures which make virtual to
98  * physical map invalidates expensive, this module may delay invalidate
99  * reduced protection operations until such time as they are actually
100  * necessary.  This module is given full information as to which processors
101  * are currently using which maps, and to when physical maps must be made
102  * correct.
103  */
104
105 #include "opt_compat.h"
106 #include "opt_kstack_pages.h"
107
108 #include <sys/param.h>
109 #include <sys/kernel.h>
110 #include <sys/queue.h>
111 #include <sys/cpuset.h>
112 #include <sys/ktr.h>
113 #include <sys/lock.h>
114 #include <sys/msgbuf.h>
115 #include <sys/malloc.h>
116 #include <sys/mutex.h>
117 #include <sys/proc.h>
118 #include <sys/rwlock.h>
119 #include <sys/sched.h>
120 #include <sys/sysctl.h>
121 #include <sys/systm.h>
122 #include <sys/vmmeter.h>
123
124 #include <sys/kdb.h>
125
126 #include <dev/ofw/openfirm.h>
127
128 #include <vm/vm.h>
129 #include <vm/vm_param.h>
130 #include <vm/vm_kern.h>
131 #include <vm/vm_page.h>
132 #include <vm/vm_map.h>
133 #include <vm/vm_object.h>
134 #include <vm/vm_extern.h>
135 #include <vm/vm_pageout.h>
136 #include <vm/uma.h>
137
138 #include <machine/_inttypes.h>
139 #include <machine/cpu.h>
140 #include <machine/platform.h>
141 #include <machine/frame.h>
142 #include <machine/md_var.h>
143 #include <machine/psl.h>
144 #include <machine/bat.h>
145 #include <machine/hid.h>
146 #include <machine/pte.h>
147 #include <machine/sr.h>
148 #include <machine/trap.h>
149 #include <machine/mmuvar.h>
150
151 #include "mmu_oea64.h"
152 #include "mmu_if.h"
153 #include "moea64_if.h"
154
155 void moea64_release_vsid(uint64_t vsid);
156 uintptr_t moea64_get_unique_vsid(void); 
157
158 #define DISABLE_TRANS(msr)      msr = mfmsr(); mtmsr(msr & ~PSL_DR)
159 #define ENABLE_TRANS(msr)       mtmsr(msr)
160
161 #define VSID_MAKE(sr, hash)     ((sr) | (((hash) & 0xfffff) << 4))
162 #define VSID_TO_HASH(vsid)      (((vsid) >> 4) & 0xfffff)
163 #define VSID_HASH_MASK          0x0000007fffffffffULL
164
165 /*
166  * Locking semantics:
167  * -- Read lock: if no modifications are being made to either the PVO lists
168  *    or page table or if any modifications being made result in internal
169  *    changes (e.g. wiring, protection) such that the existence of the PVOs
170  *    is unchanged and they remain associated with the same pmap (in which
171  *    case the changes should be protected by the pmap lock)
172  * -- Write lock: required if PTEs/PVOs are being inserted or removed.
173  */
174
175 #define LOCK_TABLE_RD() rw_rlock(&moea64_table_lock)
176 #define UNLOCK_TABLE_RD() rw_runlock(&moea64_table_lock)
177 #define LOCK_TABLE_WR() rw_wlock(&moea64_table_lock)
178 #define UNLOCK_TABLE_WR() rw_wunlock(&moea64_table_lock)
179
180 struct ofw_map {
181         cell_t  om_va;
182         cell_t  om_len;
183         uint64_t om_pa;
184         cell_t  om_mode;
185 };
186
187 extern unsigned char _etext[];
188 extern unsigned char _end[];
189
190 extern int dumpsys_minidump;
191
192 /*
193  * Map of physical memory regions.
194  */
195 static struct   mem_region *regions;
196 static struct   mem_region *pregions;
197 static u_int    phys_avail_count;
198 static int      regions_sz, pregions_sz;
199
200 extern void bs_remap_earlyboot(void);
201
202 /*
203  * Lock for the pteg and pvo tables.
204  */
205 struct rwlock   moea64_table_lock;
206 struct mtx      moea64_slb_mutex;
207
208 /*
209  * PTEG data.
210  */
211 u_int           moea64_pteg_count;
212 u_int           moea64_pteg_mask;
213
214 /*
215  * PVO data.
216  */
217 struct  pvo_head *moea64_pvo_table;             /* pvo entries by pteg index */
218
219 uma_zone_t      moea64_upvo_zone; /* zone for pvo entries for unmanaged pages */
220 uma_zone_t      moea64_mpvo_zone; /* zone for pvo entries for managed pages */
221
222 #define BPVO_POOL_SIZE  327680
223 static struct   pvo_entry *moea64_bpvo_pool;
224 static int      moea64_bpvo_pool_index = 0;
225
226 #define VSID_NBPW       (sizeof(u_int32_t) * 8)
227 #ifdef __powerpc64__
228 #define NVSIDS          (NPMAPS * 16)
229 #define VSID_HASHMASK   0xffffffffUL
230 #else
231 #define NVSIDS          NPMAPS
232 #define VSID_HASHMASK   0xfffffUL
233 #endif
234 static u_int    moea64_vsid_bitmap[NVSIDS / VSID_NBPW];
235
236 static boolean_t moea64_initialized = FALSE;
237
238 /*
239  * Statistics.
240  */
241 u_int   moea64_pte_valid = 0;
242 u_int   moea64_pte_overflow = 0;
243 u_int   moea64_pvo_entries = 0;
244 u_int   moea64_pvo_enter_calls = 0;
245 u_int   moea64_pvo_remove_calls = 0;
246 SYSCTL_INT(_machdep, OID_AUTO, moea64_pte_valid, CTLFLAG_RD, 
247     &moea64_pte_valid, 0, "");
248 SYSCTL_INT(_machdep, OID_AUTO, moea64_pte_overflow, CTLFLAG_RD,
249     &moea64_pte_overflow, 0, "");
250 SYSCTL_INT(_machdep, OID_AUTO, moea64_pvo_entries, CTLFLAG_RD, 
251     &moea64_pvo_entries, 0, "");
252 SYSCTL_INT(_machdep, OID_AUTO, moea64_pvo_enter_calls, CTLFLAG_RD,
253     &moea64_pvo_enter_calls, 0, "");
254 SYSCTL_INT(_machdep, OID_AUTO, moea64_pvo_remove_calls, CTLFLAG_RD,
255     &moea64_pvo_remove_calls, 0, "");
256
257 vm_offset_t     moea64_scratchpage_va[2];
258 struct pvo_entry *moea64_scratchpage_pvo[2];
259 uintptr_t       moea64_scratchpage_pte[2];
260 struct  mtx     moea64_scratchpage_mtx;
261
262 uint64_t        moea64_large_page_mask = 0;
263 uint64_t        moea64_large_page_size = 0;
264 int             moea64_large_page_shift = 0;
265
266 /*
267  * PVO calls.
268  */
269 static int      moea64_pvo_enter(mmu_t, pmap_t, uma_zone_t, struct pvo_head *,
270                     vm_offset_t, vm_offset_t, uint64_t, int);
271 static void     moea64_pvo_remove(mmu_t, struct pvo_entry *);
272 static struct   pvo_entry *moea64_pvo_find_va(pmap_t, vm_offset_t);
273
274 /*
275  * Utility routines.
276  */
277 static boolean_t        moea64_query_bit(mmu_t, vm_page_t, u_int64_t);
278 static u_int            moea64_clear_bit(mmu_t, vm_page_t, u_int64_t);
279 static void             moea64_kremove(mmu_t, vm_offset_t);
280 static void             moea64_syncicache(mmu_t, pmap_t pmap, vm_offset_t va, 
281                             vm_offset_t pa, vm_size_t sz);
282
283 /*
284  * Kernel MMU interface
285  */
286 void moea64_change_wiring(mmu_t, pmap_t, vm_offset_t, boolean_t);
287 void moea64_clear_modify(mmu_t, vm_page_t);
288 void moea64_copy_page(mmu_t, vm_page_t, vm_page_t);
289 void moea64_copy_pages(mmu_t mmu, vm_page_t *ma, vm_offset_t a_offset,
290     vm_page_t *mb, vm_offset_t b_offset, int xfersize);
291 void moea64_enter(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t, boolean_t);
292 void moea64_enter_object(mmu_t, pmap_t, vm_offset_t, vm_offset_t, vm_page_t,
293     vm_prot_t);
294 void moea64_enter_quick(mmu_t, pmap_t, vm_offset_t, vm_page_t, vm_prot_t);
295 vm_paddr_t moea64_extract(mmu_t, pmap_t, vm_offset_t);
296 vm_page_t moea64_extract_and_hold(mmu_t, pmap_t, vm_offset_t, vm_prot_t);
297 void moea64_init(mmu_t);
298 boolean_t moea64_is_modified(mmu_t, vm_page_t);
299 boolean_t moea64_is_prefaultable(mmu_t, pmap_t, vm_offset_t);
300 boolean_t moea64_is_referenced(mmu_t, vm_page_t);
301 int moea64_ts_referenced(mmu_t, vm_page_t);
302 vm_offset_t moea64_map(mmu_t, vm_offset_t *, vm_paddr_t, vm_paddr_t, int);
303 boolean_t moea64_page_exists_quick(mmu_t, pmap_t, vm_page_t);
304 int moea64_page_wired_mappings(mmu_t, vm_page_t);
305 void moea64_pinit(mmu_t, pmap_t);
306 void moea64_pinit0(mmu_t, pmap_t);
307 void moea64_protect(mmu_t, pmap_t, vm_offset_t, vm_offset_t, vm_prot_t);
308 void moea64_qenter(mmu_t, vm_offset_t, vm_page_t *, int);
309 void moea64_qremove(mmu_t, vm_offset_t, int);
310 void moea64_release(mmu_t, pmap_t);
311 void moea64_remove(mmu_t, pmap_t, vm_offset_t, vm_offset_t);
312 void moea64_remove_pages(mmu_t, pmap_t);
313 void moea64_remove_all(mmu_t, vm_page_t);
314 void moea64_remove_write(mmu_t, vm_page_t);
315 void moea64_zero_page(mmu_t, vm_page_t);
316 void moea64_zero_page_area(mmu_t, vm_page_t, int, int);
317 void moea64_zero_page_idle(mmu_t, vm_page_t);
318 void moea64_activate(mmu_t, struct thread *);
319 void moea64_deactivate(mmu_t, struct thread *);
320 void *moea64_mapdev(mmu_t, vm_paddr_t, vm_size_t);
321 void *moea64_mapdev_attr(mmu_t, vm_offset_t, vm_size_t, vm_memattr_t);
322 void moea64_unmapdev(mmu_t, vm_offset_t, vm_size_t);
323 vm_paddr_t moea64_kextract(mmu_t, vm_offset_t);
324 void moea64_page_set_memattr(mmu_t, vm_page_t m, vm_memattr_t ma);
325 void moea64_kenter_attr(mmu_t, vm_offset_t, vm_offset_t, vm_memattr_t ma);
326 void moea64_kenter(mmu_t, vm_offset_t, vm_paddr_t);
327 boolean_t moea64_dev_direct_mapped(mmu_t, vm_paddr_t, vm_size_t);
328 static void moea64_sync_icache(mmu_t, pmap_t, vm_offset_t, vm_size_t);
329 vm_offset_t moea64_dumpsys_map(mmu_t mmu, struct pmap_md *md, vm_size_t ofs,
330     vm_size_t *sz);
331 struct pmap_md * moea64_scan_md(mmu_t mmu, struct pmap_md *prev);
332
333 static mmu_method_t moea64_methods[] = {
334         MMUMETHOD(mmu_change_wiring,    moea64_change_wiring),
335         MMUMETHOD(mmu_clear_modify,     moea64_clear_modify),
336         MMUMETHOD(mmu_copy_page,        moea64_copy_page),
337         MMUMETHOD(mmu_copy_pages,       moea64_copy_pages),
338         MMUMETHOD(mmu_enter,            moea64_enter),
339         MMUMETHOD(mmu_enter_object,     moea64_enter_object),
340         MMUMETHOD(mmu_enter_quick,      moea64_enter_quick),
341         MMUMETHOD(mmu_extract,          moea64_extract),
342         MMUMETHOD(mmu_extract_and_hold, moea64_extract_and_hold),
343         MMUMETHOD(mmu_init,             moea64_init),
344         MMUMETHOD(mmu_is_modified,      moea64_is_modified),
345         MMUMETHOD(mmu_is_prefaultable,  moea64_is_prefaultable),
346         MMUMETHOD(mmu_is_referenced,    moea64_is_referenced),
347         MMUMETHOD(mmu_ts_referenced,    moea64_ts_referenced),
348         MMUMETHOD(mmu_map,              moea64_map),
349         MMUMETHOD(mmu_page_exists_quick,moea64_page_exists_quick),
350         MMUMETHOD(mmu_page_wired_mappings,moea64_page_wired_mappings),
351         MMUMETHOD(mmu_pinit,            moea64_pinit),
352         MMUMETHOD(mmu_pinit0,           moea64_pinit0),
353         MMUMETHOD(mmu_protect,          moea64_protect),
354         MMUMETHOD(mmu_qenter,           moea64_qenter),
355         MMUMETHOD(mmu_qremove,          moea64_qremove),
356         MMUMETHOD(mmu_release,          moea64_release),
357         MMUMETHOD(mmu_remove,           moea64_remove),
358         MMUMETHOD(mmu_remove_pages,     moea64_remove_pages),
359         MMUMETHOD(mmu_remove_all,       moea64_remove_all),
360         MMUMETHOD(mmu_remove_write,     moea64_remove_write),
361         MMUMETHOD(mmu_sync_icache,      moea64_sync_icache),
362         MMUMETHOD(mmu_zero_page,        moea64_zero_page),
363         MMUMETHOD(mmu_zero_page_area,   moea64_zero_page_area),
364         MMUMETHOD(mmu_zero_page_idle,   moea64_zero_page_idle),
365         MMUMETHOD(mmu_activate,         moea64_activate),
366         MMUMETHOD(mmu_deactivate,       moea64_deactivate),
367         MMUMETHOD(mmu_page_set_memattr, moea64_page_set_memattr),
368
369         /* Internal interfaces */
370         MMUMETHOD(mmu_mapdev,           moea64_mapdev),
371         MMUMETHOD(mmu_mapdev_attr,      moea64_mapdev_attr),
372         MMUMETHOD(mmu_unmapdev,         moea64_unmapdev),
373         MMUMETHOD(mmu_kextract,         moea64_kextract),
374         MMUMETHOD(mmu_kenter,           moea64_kenter),
375         MMUMETHOD(mmu_kenter_attr,      moea64_kenter_attr),
376         MMUMETHOD(mmu_dev_direct_mapped,moea64_dev_direct_mapped),
377         MMUMETHOD(mmu_scan_md,          moea64_scan_md),
378         MMUMETHOD(mmu_dumpsys_map,      moea64_dumpsys_map),
379
380         { 0, 0 }
381 };
382
383 MMU_DEF(oea64_mmu, "mmu_oea64_base", moea64_methods, 0);
384
385 static __inline u_int
386 va_to_pteg(uint64_t vsid, vm_offset_t addr, int large)
387 {
388         uint64_t hash;
389         int shift;
390
391         shift = large ? moea64_large_page_shift : ADDR_PIDX_SHFT;
392         hash = (vsid & VSID_HASH_MASK) ^ (((uint64_t)addr & ADDR_PIDX) >>
393             shift);
394         return (hash & moea64_pteg_mask);
395 }
396
397 static __inline struct pvo_head *
398 vm_page_to_pvoh(vm_page_t m)
399 {
400
401         return (&m->md.mdpg_pvoh);
402 }
403
404 static __inline void
405 moea64_pte_create(struct lpte *pt, uint64_t vsid, vm_offset_t va, 
406     uint64_t pte_lo, int flags)
407 {
408
409         /*
410          * Construct a PTE.  Default to IMB initially.  Valid bit only gets
411          * set when the real pte is set in memory.
412          *
413          * Note: Don't set the valid bit for correct operation of tlb update.
414          */
415         pt->pte_hi = (vsid << LPTE_VSID_SHIFT) |
416             (((uint64_t)(va & ADDR_PIDX) >> ADDR_API_SHFT64) & LPTE_API);
417
418         if (flags & PVO_LARGE)
419                 pt->pte_hi |= LPTE_BIG;
420
421         pt->pte_lo = pte_lo;
422 }
423
424 static __inline uint64_t
425 moea64_calc_wimg(vm_offset_t pa, vm_memattr_t ma)
426 {
427         uint64_t pte_lo;
428         int i;
429
430         if (ma != VM_MEMATTR_DEFAULT) {
431                 switch (ma) {
432                 case VM_MEMATTR_UNCACHEABLE:
433                         return (LPTE_I | LPTE_G);
434                 case VM_MEMATTR_WRITE_COMBINING:
435                 case VM_MEMATTR_WRITE_BACK:
436                 case VM_MEMATTR_PREFETCHABLE:
437                         return (LPTE_I);
438                 case VM_MEMATTR_WRITE_THROUGH:
439                         return (LPTE_W | LPTE_M);
440                 }
441         }
442
443         /*
444          * Assume the page is cache inhibited and access is guarded unless
445          * it's in our available memory array.
446          */
447         pte_lo = LPTE_I | LPTE_G;
448         for (i = 0; i < pregions_sz; i++) {
449                 if ((pa >= pregions[i].mr_start) &&
450                     (pa < (pregions[i].mr_start + pregions[i].mr_size))) {
451                         pte_lo &= ~(LPTE_I | LPTE_G);
452                         pte_lo |= LPTE_M;
453                         break;
454                 }
455         }
456
457         return pte_lo;
458 }
459
460 /*
461  * Quick sort callout for comparing memory regions.
462  */
463 static int      om_cmp(const void *a, const void *b);
464
465 static int
466 om_cmp(const void *a, const void *b)
467 {
468         const struct    ofw_map *mapa;
469         const struct    ofw_map *mapb;
470
471         mapa = a;
472         mapb = b;
473         if (mapa->om_pa < mapb->om_pa)
474                 return (-1);
475         else if (mapa->om_pa > mapb->om_pa)
476                 return (1);
477         else
478                 return (0);
479 }
480
481 static void
482 moea64_add_ofw_mappings(mmu_t mmup, phandle_t mmu, size_t sz)
483 {
484         struct ofw_map  translations[sz/(4*sizeof(cell_t))]; /*>= 4 cells per */
485         pcell_t         acells, trans_cells[sz/sizeof(cell_t)];
486         register_t      msr;
487         vm_offset_t     off;
488         vm_paddr_t      pa_base;
489         int             i, j;
490
491         bzero(translations, sz);
492         OF_getprop(OF_finddevice("/"), "#address-cells", &acells,
493             sizeof(acells));
494         if (OF_getprop(mmu, "translations", trans_cells, sz) == -1)
495                 panic("moea64_bootstrap: can't get ofw translations");
496
497         CTR0(KTR_PMAP, "moea64_add_ofw_mappings: translations");
498         sz /= sizeof(cell_t);
499         for (i = 0, j = 0; i < sz; j++) {
500                 translations[j].om_va = trans_cells[i++];
501                 translations[j].om_len = trans_cells[i++];
502                 translations[j].om_pa = trans_cells[i++];
503                 if (acells == 2) {
504                         translations[j].om_pa <<= 32;
505                         translations[j].om_pa |= trans_cells[i++];
506                 }
507                 translations[j].om_mode = trans_cells[i++];
508         }
509         KASSERT(i == sz, ("Translations map has incorrect cell count (%d/%zd)",
510             i, sz));
511
512         sz = j;
513         qsort(translations, sz, sizeof (*translations), om_cmp);
514
515         for (i = 0; i < sz; i++) {
516                 pa_base = translations[i].om_pa;
517               #ifndef __powerpc64__
518                 if ((translations[i].om_pa >> 32) != 0)
519                         panic("OFW translations above 32-bit boundary!");
520               #endif
521
522                 if (pa_base % PAGE_SIZE)
523                         panic("OFW translation not page-aligned (phys)!");
524                 if (translations[i].om_va % PAGE_SIZE)
525                         panic("OFW translation not page-aligned (virt)!");
526
527                 CTR3(KTR_PMAP, "translation: pa=%#zx va=%#x len=%#x",
528                     pa_base, translations[i].om_va, translations[i].om_len);
529
530                 /* Now enter the pages for this mapping */
531
532                 DISABLE_TRANS(msr);
533                 for (off = 0; off < translations[i].om_len; off += PAGE_SIZE) {
534                         if (moea64_pvo_find_va(kernel_pmap,
535                             translations[i].om_va + off) != NULL)
536                                 continue;
537
538                         moea64_kenter(mmup, translations[i].om_va + off,
539                             pa_base + off);
540                 }
541                 ENABLE_TRANS(msr);
542         }
543 }
544
545 #ifdef __powerpc64__
546 static void
547 moea64_probe_large_page(void)
548 {
549         uint16_t pvr = mfpvr() >> 16;
550
551         switch (pvr) {
552         case IBM970:
553         case IBM970FX:
554         case IBM970MP:
555                 powerpc_sync(); isync();
556                 mtspr(SPR_HID4, mfspr(SPR_HID4) & ~HID4_970_DISABLE_LG_PG);
557                 powerpc_sync(); isync();
558                 
559                 /* FALLTHROUGH */
560         default:
561                 moea64_large_page_size = 0x1000000; /* 16 MB */
562                 moea64_large_page_shift = 24;
563         }
564
565         moea64_large_page_mask = moea64_large_page_size - 1;
566 }
567
568 static void
569 moea64_bootstrap_slb_prefault(vm_offset_t va, int large)
570 {
571         struct slb *cache;
572         struct slb entry;
573         uint64_t esid, slbe;
574         uint64_t i;
575
576         cache = PCPU_GET(slb);
577         esid = va >> ADDR_SR_SHFT;
578         slbe = (esid << SLBE_ESID_SHIFT) | SLBE_VALID;
579
580         for (i = 0; i < 64; i++) {
581                 if (cache[i].slbe == (slbe | i))
582                         return;
583         }
584
585         entry.slbe = slbe;
586         entry.slbv = KERNEL_VSID(esid) << SLBV_VSID_SHIFT;
587         if (large)
588                 entry.slbv |= SLBV_L;
589
590         slb_insert_kernel(entry.slbe, entry.slbv);
591 }
592 #endif
593
594 static void
595 moea64_setup_direct_map(mmu_t mmup, vm_offset_t kernelstart,
596     vm_offset_t kernelend)
597 {
598         register_t msr;
599         vm_paddr_t pa;
600         vm_offset_t size, off;
601         uint64_t pte_lo;
602         int i;
603
604         if (moea64_large_page_size == 0) 
605                 hw_direct_map = 0;
606
607         DISABLE_TRANS(msr);
608         if (hw_direct_map) {
609                 LOCK_TABLE_WR();
610                 PMAP_LOCK(kernel_pmap);
611                 for (i = 0; i < pregions_sz; i++) {
612                   for (pa = pregions[i].mr_start; pa < pregions[i].mr_start +
613                      pregions[i].mr_size; pa += moea64_large_page_size) {
614                         pte_lo = LPTE_M;
615
616                         /*
617                          * Set memory access as guarded if prefetch within
618                          * the page could exit the available physmem area.
619                          */
620                         if (pa & moea64_large_page_mask) {
621                                 pa &= moea64_large_page_mask;
622                                 pte_lo |= LPTE_G;
623                         }
624                         if (pa + moea64_large_page_size >
625                             pregions[i].mr_start + pregions[i].mr_size)
626                                 pte_lo |= LPTE_G;
627
628                         moea64_pvo_enter(mmup, kernel_pmap, moea64_upvo_zone,
629                                     NULL, pa, pa, pte_lo,
630                                     PVO_WIRED | PVO_LARGE);
631                   }
632                 }
633                 PMAP_UNLOCK(kernel_pmap);
634                 UNLOCK_TABLE_WR();
635         } else {
636                 size = sizeof(struct pvo_head) * moea64_pteg_count;
637                 off = (vm_offset_t)(moea64_pvo_table);
638                 for (pa = off; pa < off + size; pa += PAGE_SIZE) 
639                         moea64_kenter(mmup, pa, pa);
640                 size = BPVO_POOL_SIZE*sizeof(struct pvo_entry);
641                 off = (vm_offset_t)(moea64_bpvo_pool);
642                 for (pa = off; pa < off + size; pa += PAGE_SIZE) 
643                 moea64_kenter(mmup, pa, pa);
644
645                 /*
646                  * Map certain important things, like ourselves.
647                  *
648                  * NOTE: We do not map the exception vector space. That code is
649                  * used only in real mode, and leaving it unmapped allows us to
650                  * catch NULL pointer deferences, instead of making NULL a valid
651                  * address.
652                  */
653
654                 for (pa = kernelstart & ~PAGE_MASK; pa < kernelend;
655                     pa += PAGE_SIZE) 
656                         moea64_kenter(mmup, pa, pa);
657         }
658         ENABLE_TRANS(msr);
659
660         /*
661          * Allow user to override unmapped_buf_allowed for testing.
662          * XXXKIB Only direct map implementation was tested.
663          */
664         if (!TUNABLE_INT_FETCH("vfs.unmapped_buf_allowed",
665             &unmapped_buf_allowed))
666                 unmapped_buf_allowed = hw_direct_map;
667 }
668
669 void
670 moea64_early_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
671 {
672         int             i, j;
673         vm_size_t       physsz, hwphyssz;
674
675 #ifndef __powerpc64__
676         /* We don't have a direct map since there is no BAT */
677         hw_direct_map = 0;
678
679         /* Make sure battable is zero, since we have no BAT */
680         for (i = 0; i < 16; i++) {
681                 battable[i].batu = 0;
682                 battable[i].batl = 0;
683         }
684 #else
685         moea64_probe_large_page();
686
687         /* Use a direct map if we have large page support */
688         if (moea64_large_page_size > 0)
689                 hw_direct_map = 1;
690         else
691                 hw_direct_map = 0;
692 #endif
693
694         /* Get physical memory regions from firmware */
695         mem_regions(&pregions, &pregions_sz, &regions, &regions_sz);
696         CTR0(KTR_PMAP, "moea64_bootstrap: physical memory");
697
698         if (sizeof(phys_avail)/sizeof(phys_avail[0]) < regions_sz)
699                 panic("moea64_bootstrap: phys_avail too small");
700
701         phys_avail_count = 0;
702         physsz = 0;
703         hwphyssz = 0;
704         TUNABLE_ULONG_FETCH("hw.physmem", (u_long *) &hwphyssz);
705         for (i = 0, j = 0; i < regions_sz; i++, j += 2) {
706                 CTR3(KTR_PMAP, "region: %#zx - %#zx (%#zx)",
707                     regions[i].mr_start, regions[i].mr_start +
708                     regions[i].mr_size, regions[i].mr_size);
709                 if (hwphyssz != 0 &&
710                     (physsz + regions[i].mr_size) >= hwphyssz) {
711                         if (physsz < hwphyssz) {
712                                 phys_avail[j] = regions[i].mr_start;
713                                 phys_avail[j + 1] = regions[i].mr_start +
714                                     hwphyssz - physsz;
715                                 physsz = hwphyssz;
716                                 phys_avail_count++;
717                         }
718                         break;
719                 }
720                 phys_avail[j] = regions[i].mr_start;
721                 phys_avail[j + 1] = regions[i].mr_start + regions[i].mr_size;
722                 phys_avail_count++;
723                 physsz += regions[i].mr_size;
724         }
725
726         /* Check for overlap with the kernel and exception vectors */
727         for (j = 0; j < 2*phys_avail_count; j+=2) {
728                 if (phys_avail[j] < EXC_LAST)
729                         phys_avail[j] += EXC_LAST;
730
731                 if (kernelstart >= phys_avail[j] &&
732                     kernelstart < phys_avail[j+1]) {
733                         if (kernelend < phys_avail[j+1]) {
734                                 phys_avail[2*phys_avail_count] =
735                                     (kernelend & ~PAGE_MASK) + PAGE_SIZE;
736                                 phys_avail[2*phys_avail_count + 1] =
737                                     phys_avail[j+1];
738                                 phys_avail_count++;
739                         }
740
741                         phys_avail[j+1] = kernelstart & ~PAGE_MASK;
742                 }
743
744                 if (kernelend >= phys_avail[j] &&
745                     kernelend < phys_avail[j+1]) {
746                         if (kernelstart > phys_avail[j]) {
747                                 phys_avail[2*phys_avail_count] = phys_avail[j];
748                                 phys_avail[2*phys_avail_count + 1] =
749                                     kernelstart & ~PAGE_MASK;
750                                 phys_avail_count++;
751                         }
752
753                         phys_avail[j] = (kernelend & ~PAGE_MASK) + PAGE_SIZE;
754                 }
755         }
756
757         physmem = btoc(physsz);
758
759 #ifdef PTEGCOUNT
760         moea64_pteg_count = PTEGCOUNT;
761 #else
762         moea64_pteg_count = 0x1000;
763
764         while (moea64_pteg_count < physmem)
765                 moea64_pteg_count <<= 1;
766
767         moea64_pteg_count >>= 1;
768 #endif /* PTEGCOUNT */
769 }
770
771 void
772 moea64_mid_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
773 {
774         vm_size_t       size;
775         register_t      msr;
776         int             i;
777
778         /*
779          * Set PTEG mask
780          */
781         moea64_pteg_mask = moea64_pteg_count - 1;
782
783         /*
784          * Allocate pv/overflow lists.
785          */
786         size = sizeof(struct pvo_head) * moea64_pteg_count;
787
788         moea64_pvo_table = (struct pvo_head *)moea64_bootstrap_alloc(size,
789             PAGE_SIZE);
790         CTR1(KTR_PMAP, "moea64_bootstrap: PVO table at %p", moea64_pvo_table);
791
792         DISABLE_TRANS(msr);
793         for (i = 0; i < moea64_pteg_count; i++)
794                 LIST_INIT(&moea64_pvo_table[i]);
795         ENABLE_TRANS(msr);
796
797         /*
798          * Initialize the lock that synchronizes access to the pteg and pvo
799          * tables.
800          */
801         rw_init_flags(&moea64_table_lock, "pmap tables", RW_RECURSE);
802         mtx_init(&moea64_slb_mutex, "SLB table", NULL, MTX_DEF);
803
804         /*
805          * Initialise the unmanaged pvo pool.
806          */
807         moea64_bpvo_pool = (struct pvo_entry *)moea64_bootstrap_alloc(
808                 BPVO_POOL_SIZE*sizeof(struct pvo_entry), 0);
809         moea64_bpvo_pool_index = 0;
810
811         /*
812          * Make sure kernel vsid is allocated as well as VSID 0.
813          */
814         #ifndef __powerpc64__
815         moea64_vsid_bitmap[(KERNEL_VSIDBITS & (NVSIDS - 1)) / VSID_NBPW]
816                 |= 1 << (KERNEL_VSIDBITS % VSID_NBPW);
817         moea64_vsid_bitmap[0] |= 1;
818         #endif
819
820         /*
821          * Initialize the kernel pmap (which is statically allocated).
822          */
823         #ifdef __powerpc64__
824         for (i = 0; i < 64; i++) {
825                 pcpup->pc_slb[i].slbv = 0;
826                 pcpup->pc_slb[i].slbe = 0;
827         }
828         #else
829         for (i = 0; i < 16; i++) 
830                 kernel_pmap->pm_sr[i] = EMPTY_SEGMENT + i;
831         #endif
832
833         kernel_pmap->pmap_phys = kernel_pmap;
834         CPU_FILL(&kernel_pmap->pm_active);
835         RB_INIT(&kernel_pmap->pmap_pvo);
836
837         PMAP_LOCK_INIT(kernel_pmap);
838
839         /*
840          * Now map in all the other buffers we allocated earlier
841          */
842
843         moea64_setup_direct_map(mmup, kernelstart, kernelend);
844 }
845
846 void
847 moea64_late_bootstrap(mmu_t mmup, vm_offset_t kernelstart, vm_offset_t kernelend)
848 {
849         ihandle_t       mmui;
850         phandle_t       chosen;
851         phandle_t       mmu;
852         size_t          sz;
853         int             i;
854         vm_offset_t     pa, va;
855         void            *dpcpu;
856
857         /*
858          * Set up the Open Firmware pmap and add its mappings if not in real
859          * mode.
860          */
861
862         chosen = OF_finddevice("/chosen");
863         if (chosen != -1 && OF_getprop(chosen, "mmu", &mmui, 4) != -1) {
864             mmu = OF_instance_to_package(mmui);
865             if (mmu == -1 || (sz = OF_getproplen(mmu, "translations")) == -1)
866                 sz = 0;
867             if (sz > 6144 /* tmpstksz - 2 KB headroom */)
868                 panic("moea64_bootstrap: too many ofw translations");
869
870             if (sz > 0)
871                 moea64_add_ofw_mappings(mmup, mmu, sz);
872         }
873
874         /*
875          * Calculate the last available physical address.
876          */
877         for (i = 0; phys_avail[i + 2] != 0; i += 2)
878                 ;
879         Maxmem = powerpc_btop(phys_avail[i + 1]);
880
881         /*
882          * Initialize MMU and remap early physical mappings
883          */
884         MMU_CPU_BOOTSTRAP(mmup,0);
885         mtmsr(mfmsr() | PSL_DR | PSL_IR);
886         pmap_bootstrapped++;
887         bs_remap_earlyboot();
888
889         /*
890          * Set the start and end of kva.
891          */
892         virtual_avail = VM_MIN_KERNEL_ADDRESS;
893         virtual_end = VM_MAX_SAFE_KERNEL_ADDRESS; 
894
895         /*
896          * Map the entire KVA range into the SLB. We must not fault there.
897          */
898         #ifdef __powerpc64__
899         for (va = virtual_avail; va < virtual_end; va += SEGMENT_LENGTH)
900                 moea64_bootstrap_slb_prefault(va, 0);
901         #endif
902
903         /*
904          * Figure out how far we can extend virtual_end into segment 16
905          * without running into existing mappings. Segment 16 is guaranteed
906          * to contain neither RAM nor devices (at least on Apple hardware),
907          * but will generally contain some OFW mappings we should not
908          * step on.
909          */
910
911         #ifndef __powerpc64__   /* KVA is in high memory on PPC64 */
912         PMAP_LOCK(kernel_pmap);
913         while (virtual_end < VM_MAX_KERNEL_ADDRESS &&
914             moea64_pvo_find_va(kernel_pmap, virtual_end+1) == NULL)
915                 virtual_end += PAGE_SIZE;
916         PMAP_UNLOCK(kernel_pmap);
917         #endif
918
919         /*
920          * Allocate a kernel stack with a guard page for thread0 and map it
921          * into the kernel page map.
922          */
923         pa = moea64_bootstrap_alloc(KSTACK_PAGES * PAGE_SIZE, PAGE_SIZE);
924         va = virtual_avail + KSTACK_GUARD_PAGES * PAGE_SIZE;
925         virtual_avail = va + KSTACK_PAGES * PAGE_SIZE;
926         CTR2(KTR_PMAP, "moea64_bootstrap: kstack0 at %#x (%#x)", pa, va);
927         thread0.td_kstack = va;
928         thread0.td_kstack_pages = KSTACK_PAGES;
929         for (i = 0; i < KSTACK_PAGES; i++) {
930                 moea64_kenter(mmup, va, pa);
931                 pa += PAGE_SIZE;
932                 va += PAGE_SIZE;
933         }
934
935         /*
936          * Allocate virtual address space for the message buffer.
937          */
938         pa = msgbuf_phys = moea64_bootstrap_alloc(msgbufsize, PAGE_SIZE);
939         msgbufp = (struct msgbuf *)virtual_avail;
940         va = virtual_avail;
941         virtual_avail += round_page(msgbufsize);
942         while (va < virtual_avail) {
943                 moea64_kenter(mmup, va, pa);
944                 pa += PAGE_SIZE;
945                 va += PAGE_SIZE;
946         }
947
948         /*
949          * Allocate virtual address space for the dynamic percpu area.
950          */
951         pa = moea64_bootstrap_alloc(DPCPU_SIZE, PAGE_SIZE);
952         dpcpu = (void *)virtual_avail;
953         va = virtual_avail;
954         virtual_avail += DPCPU_SIZE;
955         while (va < virtual_avail) {
956                 moea64_kenter(mmup, va, pa);
957                 pa += PAGE_SIZE;
958                 va += PAGE_SIZE;
959         }
960         dpcpu_init(dpcpu, 0);
961
962         /*
963          * Allocate some things for page zeroing. We put this directly
964          * in the page table, marked with LPTE_LOCKED, to avoid any
965          * of the PVO book-keeping or other parts of the VM system
966          * from even knowing that this hack exists.
967          */
968
969         if (!hw_direct_map) {
970                 mtx_init(&moea64_scratchpage_mtx, "pvo zero page", NULL,
971                     MTX_DEF);
972                 for (i = 0; i < 2; i++) {
973                         moea64_scratchpage_va[i] = (virtual_end+1) - PAGE_SIZE;
974                         virtual_end -= PAGE_SIZE;
975
976                         moea64_kenter(mmup, moea64_scratchpage_va[i], 0);
977
978                         moea64_scratchpage_pvo[i] = moea64_pvo_find_va(
979                             kernel_pmap, (vm_offset_t)moea64_scratchpage_va[i]);
980                         LOCK_TABLE_RD();
981                         moea64_scratchpage_pte[i] = MOEA64_PVO_TO_PTE(
982                             mmup, moea64_scratchpage_pvo[i]);
983                         moea64_scratchpage_pvo[i]->pvo_pte.lpte.pte_hi
984                             |= LPTE_LOCKED;
985                         MOEA64_PTE_CHANGE(mmup, moea64_scratchpage_pte[i],
986                             &moea64_scratchpage_pvo[i]->pvo_pte.lpte,
987                             moea64_scratchpage_pvo[i]->pvo_vpn);
988                         UNLOCK_TABLE_RD();
989                 }
990         }
991 }
992
993 /*
994  * Activate a user pmap.  The pmap must be activated before its address
995  * space can be accessed in any way.
996  */
997 void
998 moea64_activate(mmu_t mmu, struct thread *td)
999 {
1000         pmap_t  pm;
1001
1002         pm = &td->td_proc->p_vmspace->vm_pmap;
1003         CPU_SET(PCPU_GET(cpuid), &pm->pm_active);
1004
1005         #ifdef __powerpc64__
1006         PCPU_SET(userslb, pm->pm_slb);
1007         #else
1008         PCPU_SET(curpmap, pm->pmap_phys);
1009         #endif
1010 }
1011
1012 void
1013 moea64_deactivate(mmu_t mmu, struct thread *td)
1014 {
1015         pmap_t  pm;
1016
1017         pm = &td->td_proc->p_vmspace->vm_pmap;
1018         CPU_CLR(PCPU_GET(cpuid), &pm->pm_active);
1019         #ifdef __powerpc64__
1020         PCPU_SET(userslb, NULL);
1021         #else
1022         PCPU_SET(curpmap, NULL);
1023         #endif
1024 }
1025
1026 void
1027 moea64_change_wiring(mmu_t mmu, pmap_t pm, vm_offset_t va, boolean_t wired)
1028 {
1029         struct  pvo_entry *pvo;
1030         uintptr_t pt;
1031         uint64_t vsid;
1032         int     i, ptegidx;
1033
1034         LOCK_TABLE_WR();
1035         PMAP_LOCK(pm);
1036         pvo = moea64_pvo_find_va(pm, va & ~ADDR_POFF);
1037
1038         if (pvo != NULL) {
1039                 pt = MOEA64_PVO_TO_PTE(mmu, pvo);
1040
1041                 if (wired) {
1042                         if ((pvo->pvo_vaddr & PVO_WIRED) == 0)
1043                                 pm->pm_stats.wired_count++;
1044                         pvo->pvo_vaddr |= PVO_WIRED;
1045                         pvo->pvo_pte.lpte.pte_hi |= LPTE_WIRED;
1046                 } else {
1047                         if ((pvo->pvo_vaddr & PVO_WIRED) != 0)
1048                                 pm->pm_stats.wired_count--;
1049                         pvo->pvo_vaddr &= ~PVO_WIRED;
1050                         pvo->pvo_pte.lpte.pte_hi &= ~LPTE_WIRED;
1051                 }
1052
1053                 if (pt != -1) {
1054                         /* Update wiring flag in page table. */
1055                         MOEA64_PTE_CHANGE(mmu, pt, &pvo->pvo_pte.lpte,
1056                             pvo->pvo_vpn);
1057                 } else if (wired) {
1058                         /*
1059                          * If we are wiring the page, and it wasn't in the
1060                          * page table before, add it.
1061                          */
1062                         vsid = PVO_VSID(pvo);
1063                         ptegidx = va_to_pteg(vsid, PVO_VADDR(pvo),
1064                             pvo->pvo_vaddr & PVO_LARGE);
1065
1066                         i = MOEA64_PTE_INSERT(mmu, ptegidx, &pvo->pvo_pte.lpte);
1067                         
1068                         if (i >= 0) {
1069                                 PVO_PTEGIDX_CLR(pvo);
1070                                 PVO_PTEGIDX_SET(pvo, i);
1071                         }
1072                 }
1073                         
1074         }
1075         UNLOCK_TABLE_WR();
1076         PMAP_UNLOCK(pm);
1077 }
1078
1079 /*
1080  * This goes through and sets the physical address of our
1081  * special scratch PTE to the PA we want to zero or copy. Because
1082  * of locking issues (this can get called in pvo_enter() by
1083  * the UMA allocator), we can't use most other utility functions here
1084  */
1085
1086 static __inline
1087 void moea64_set_scratchpage_pa(mmu_t mmup, int which, vm_offset_t pa) {
1088
1089         KASSERT(!hw_direct_map, ("Using OEA64 scratchpage with a direct map!"));
1090         mtx_assert(&moea64_scratchpage_mtx, MA_OWNED);
1091
1092         moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo &=
1093             ~(LPTE_WIMG | LPTE_RPGN);
1094         moea64_scratchpage_pvo[which]->pvo_pte.lpte.pte_lo |=
1095             moea64_calc_wimg(pa, VM_MEMATTR_DEFAULT) | (uint64_t)pa;
1096         MOEA64_PTE_CHANGE(mmup, moea64_scratchpage_pte[which],
1097             &moea64_scratchpage_pvo[which]->pvo_pte.lpte,
1098             moea64_scratchpage_pvo[which]->pvo_vpn);
1099         isync();
1100 }
1101
1102 void
1103 moea64_copy_page(mmu_t mmu, vm_page_t msrc, vm_page_t mdst)
1104 {
1105         vm_offset_t     dst;
1106         vm_offset_t     src;
1107
1108         dst = VM_PAGE_TO_PHYS(mdst);
1109         src = VM_PAGE_TO_PHYS(msrc);
1110
1111         if (hw_direct_map) {
1112                 bcopy((void *)src, (void *)dst, PAGE_SIZE);
1113         } else {
1114                 mtx_lock(&moea64_scratchpage_mtx);
1115
1116                 moea64_set_scratchpage_pa(mmu, 0, src);
1117                 moea64_set_scratchpage_pa(mmu, 1, dst);
1118
1119                 bcopy((void *)moea64_scratchpage_va[0], 
1120                     (void *)moea64_scratchpage_va[1], PAGE_SIZE);
1121
1122                 mtx_unlock(&moea64_scratchpage_mtx);
1123         }
1124 }
1125
1126 static inline void
1127 moea64_copy_pages_dmap(mmu_t mmu, vm_page_t *ma, vm_offset_t a_offset,
1128     vm_page_t *mb, vm_offset_t b_offset, int xfersize)
1129 {
1130         void *a_cp, *b_cp;
1131         vm_offset_t a_pg_offset, b_pg_offset;
1132         int cnt;
1133
1134         while (xfersize > 0) {
1135                 a_pg_offset = a_offset & PAGE_MASK;
1136                 cnt = min(xfersize, PAGE_SIZE - a_pg_offset);
1137                 a_cp = (char *)VM_PAGE_TO_PHYS(ma[a_offset >> PAGE_SHIFT]) +
1138                     a_pg_offset;
1139                 b_pg_offset = b_offset & PAGE_MASK;
1140                 cnt = min(cnt, PAGE_SIZE - b_pg_offset);
1141                 b_cp = (char *)VM_PAGE_TO_PHYS(mb[b_offset >> PAGE_SHIFT]) +
1142                     b_pg_offset;
1143                 bcopy(a_cp, b_cp, cnt);
1144                 a_offset += cnt;
1145                 b_offset += cnt;
1146                 xfersize -= cnt;
1147         }
1148 }
1149
1150 static inline void
1151 moea64_copy_pages_nodmap(mmu_t mmu, vm_page_t *ma, vm_offset_t a_offset,
1152     vm_page_t *mb, vm_offset_t b_offset, int xfersize)
1153 {
1154         void *a_cp, *b_cp;
1155         vm_offset_t a_pg_offset, b_pg_offset;
1156         int cnt;
1157
1158         mtx_lock(&moea64_scratchpage_mtx);
1159         while (xfersize > 0) {
1160                 a_pg_offset = a_offset & PAGE_MASK;
1161                 cnt = min(xfersize, PAGE_SIZE - a_pg_offset);
1162                 moea64_set_scratchpage_pa(mmu, 0,
1163                     VM_PAGE_TO_PHYS(ma[a_offset >> PAGE_SHIFT]));
1164                 a_cp = (char *)moea64_scratchpage_va[0] + a_pg_offset;
1165                 b_pg_offset = b_offset & PAGE_MASK;
1166                 cnt = min(cnt, PAGE_SIZE - b_pg_offset);
1167                 moea64_set_scratchpage_pa(mmu, 1,
1168                     VM_PAGE_TO_PHYS(mb[b_offset >> PAGE_SHIFT]));
1169                 b_cp = (char *)moea64_scratchpage_va[1] + b_pg_offset;
1170                 bcopy(a_cp, b_cp, cnt);
1171                 a_offset += cnt;
1172                 b_offset += cnt;
1173                 xfersize -= cnt;
1174         }
1175         mtx_unlock(&moea64_scratchpage_mtx);
1176 }
1177
1178 void
1179 moea64_copy_pages(mmu_t mmu, vm_page_t *ma, vm_offset_t a_offset,
1180     vm_page_t *mb, vm_offset_t b_offset, int xfersize)
1181 {
1182
1183         if (hw_direct_map) {
1184                 moea64_copy_pages_dmap(mmu, ma, a_offset, mb, b_offset,
1185                     xfersize);
1186         } else {
1187                 moea64_copy_pages_nodmap(mmu, ma, a_offset, mb, b_offset,
1188                     xfersize);
1189         }
1190 }
1191
1192 void
1193 moea64_zero_page_area(mmu_t mmu, vm_page_t m, int off, int size)
1194 {
1195         vm_offset_t pa = VM_PAGE_TO_PHYS(m);
1196
1197         if (size + off > PAGE_SIZE)
1198                 panic("moea64_zero_page: size + off > PAGE_SIZE");
1199
1200         if (hw_direct_map) {
1201                 bzero((caddr_t)pa + off, size);
1202         } else {
1203                 mtx_lock(&moea64_scratchpage_mtx);
1204                 moea64_set_scratchpage_pa(mmu, 0, pa);
1205                 bzero((caddr_t)moea64_scratchpage_va[0] + off, size);
1206                 mtx_unlock(&moea64_scratchpage_mtx);
1207         }
1208 }
1209
1210 /*
1211  * Zero a page of physical memory by temporarily mapping it
1212  */
1213 void
1214 moea64_zero_page(mmu_t mmu, vm_page_t m)
1215 {
1216         vm_offset_t pa = VM_PAGE_TO_PHYS(m);
1217         vm_offset_t va, off;
1218
1219         if (!hw_direct_map) {
1220                 mtx_lock(&moea64_scratchpage_mtx);
1221
1222                 moea64_set_scratchpage_pa(mmu, 0, pa);
1223                 va = moea64_scratchpage_va[0];
1224         } else {
1225                 va = pa;
1226         }
1227
1228         for (off = 0; off < PAGE_SIZE; off += cacheline_size)
1229                 __asm __volatile("dcbz 0,%0" :: "r"(va + off));
1230
1231         if (!hw_direct_map)
1232                 mtx_unlock(&moea64_scratchpage_mtx);
1233 }
1234
1235 void
1236 moea64_zero_page_idle(mmu_t mmu, vm_page_t m)
1237 {
1238
1239         moea64_zero_page(mmu, m);
1240 }
1241
1242 /*
1243  * Map the given physical page at the specified virtual address in the
1244  * target pmap with the protection requested.  If specified the page
1245  * will be wired down.
1246  */
1247
1248 void
1249 moea64_enter(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_page_t m, 
1250     vm_prot_t prot, boolean_t wired)
1251 {
1252         struct          pvo_head *pvo_head;
1253         uma_zone_t      zone;
1254         vm_page_t       pg;
1255         uint64_t        pte_lo;
1256         u_int           pvo_flags;
1257         int             error;
1258
1259         if (!moea64_initialized) {
1260                 pvo_head = NULL;
1261                 pg = NULL;
1262                 zone = moea64_upvo_zone;
1263                 pvo_flags = 0;
1264         } else {
1265                 pvo_head = vm_page_to_pvoh(m);
1266                 pg = m;
1267                 zone = moea64_mpvo_zone;
1268                 pvo_flags = PVO_MANAGED;
1269         }
1270
1271         if ((m->oflags & VPO_UNMANAGED) == 0 && !vm_page_xbusied(m))
1272                 VM_OBJECT_ASSERT_LOCKED(m->object);
1273
1274         /* XXX change the pvo head for fake pages */
1275         if ((m->oflags & VPO_UNMANAGED) != 0) {
1276                 pvo_flags &= ~PVO_MANAGED;
1277                 pvo_head = NULL;
1278                 zone = moea64_upvo_zone;
1279         }
1280
1281         pte_lo = moea64_calc_wimg(VM_PAGE_TO_PHYS(m), pmap_page_get_memattr(m));
1282
1283         if (prot & VM_PROT_WRITE) {
1284                 pte_lo |= LPTE_BW;
1285                 if (pmap_bootstrapped &&
1286                     (m->oflags & VPO_UNMANAGED) == 0)
1287                         vm_page_aflag_set(m, PGA_WRITEABLE);
1288         } else
1289                 pte_lo |= LPTE_BR;
1290
1291         if ((prot & VM_PROT_EXECUTE) == 0)
1292                 pte_lo |= LPTE_NOEXEC;
1293
1294         if (wired)
1295                 pvo_flags |= PVO_WIRED;
1296
1297         LOCK_TABLE_WR();
1298         PMAP_LOCK(pmap);
1299         error = moea64_pvo_enter(mmu, pmap, zone, pvo_head, va,
1300             VM_PAGE_TO_PHYS(m), pte_lo, pvo_flags);
1301         PMAP_UNLOCK(pmap);
1302         UNLOCK_TABLE_WR();
1303
1304         /*
1305          * Flush the page from the instruction cache if this page is
1306          * mapped executable and cacheable.
1307          */
1308         if (pmap != kernel_pmap && !(m->aflags & PGA_EXECUTABLE) &&
1309             (pte_lo & (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) {
1310                 vm_page_aflag_set(m, PGA_EXECUTABLE);
1311                 moea64_syncicache(mmu, pmap, va, VM_PAGE_TO_PHYS(m), PAGE_SIZE);
1312         }
1313 }
1314
1315 static void
1316 moea64_syncicache(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_offset_t pa,
1317     vm_size_t sz)
1318 {
1319
1320         /*
1321          * This is much trickier than on older systems because
1322          * we can't sync the icache on physical addresses directly
1323          * without a direct map. Instead we check a couple of cases
1324          * where the memory is already mapped in and, failing that,
1325          * use the same trick we use for page zeroing to create
1326          * a temporary mapping for this physical address.
1327          */
1328
1329         if (!pmap_bootstrapped) {
1330                 /*
1331                  * If PMAP is not bootstrapped, we are likely to be
1332                  * in real mode.
1333                  */
1334                 __syncicache((void *)pa, sz);
1335         } else if (pmap == kernel_pmap) {
1336                 __syncicache((void *)va, sz);
1337         } else if (hw_direct_map) {
1338                 __syncicache((void *)pa, sz);
1339         } else {
1340                 /* Use the scratch page to set up a temp mapping */
1341
1342                 mtx_lock(&moea64_scratchpage_mtx);
1343
1344                 moea64_set_scratchpage_pa(mmu, 1, pa & ~ADDR_POFF);
1345                 __syncicache((void *)(moea64_scratchpage_va[1] + 
1346                     (va & ADDR_POFF)), sz);
1347
1348                 mtx_unlock(&moea64_scratchpage_mtx);
1349         }
1350 }
1351
1352 /*
1353  * Maps a sequence of resident pages belonging to the same object.
1354  * The sequence begins with the given page m_start.  This page is
1355  * mapped at the given virtual address start.  Each subsequent page is
1356  * mapped at a virtual address that is offset from start by the same
1357  * amount as the page is offset from m_start within the object.  The
1358  * last page in the sequence is the page with the largest offset from
1359  * m_start that can be mapped at a virtual address less than the given
1360  * virtual address end.  Not every virtual page between start and end
1361  * is mapped; only those for which a resident page exists with the
1362  * corresponding offset from m_start are mapped.
1363  */
1364 void
1365 moea64_enter_object(mmu_t mmu, pmap_t pm, vm_offset_t start, vm_offset_t end,
1366     vm_page_t m_start, vm_prot_t prot)
1367 {
1368         vm_page_t m;
1369         vm_pindex_t diff, psize;
1370
1371         VM_OBJECT_ASSERT_LOCKED(m_start->object);
1372
1373         psize = atop(end - start);
1374         m = m_start;
1375         while (m != NULL && (diff = m->pindex - m_start->pindex) < psize) {
1376                 moea64_enter(mmu, pm, start + ptoa(diff), m, prot &
1377                     (VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
1378                 m = TAILQ_NEXT(m, listq);
1379         }
1380 }
1381
1382 void
1383 moea64_enter_quick(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_page_t m,
1384     vm_prot_t prot)
1385 {
1386
1387         moea64_enter(mmu, pm, va, m,
1388             prot & (VM_PROT_READ | VM_PROT_EXECUTE), FALSE);
1389 }
1390
1391 vm_paddr_t
1392 moea64_extract(mmu_t mmu, pmap_t pm, vm_offset_t va)
1393 {
1394         struct  pvo_entry *pvo;
1395         vm_paddr_t pa;
1396
1397         PMAP_LOCK(pm);
1398         pvo = moea64_pvo_find_va(pm, va);
1399         if (pvo == NULL)
1400                 pa = 0;
1401         else
1402                 pa = (pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN) |
1403                     (va - PVO_VADDR(pvo));
1404         PMAP_UNLOCK(pm);
1405         return (pa);
1406 }
1407
1408 /*
1409  * Atomically extract and hold the physical page with the given
1410  * pmap and virtual address pair if that mapping permits the given
1411  * protection.
1412  */
1413 vm_page_t
1414 moea64_extract_and_hold(mmu_t mmu, pmap_t pmap, vm_offset_t va, vm_prot_t prot)
1415 {
1416         struct  pvo_entry *pvo;
1417         vm_page_t m;
1418         vm_paddr_t pa;
1419         
1420         m = NULL;
1421         pa = 0;
1422         PMAP_LOCK(pmap);
1423 retry:
1424         pvo = moea64_pvo_find_va(pmap, va & ~ADDR_POFF);
1425         if (pvo != NULL && (pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) &&
1426             ((pvo->pvo_pte.lpte.pte_lo & LPTE_PP) == LPTE_RW ||
1427              (prot & VM_PROT_WRITE) == 0)) {
1428                 if (vm_page_pa_tryrelock(pmap,
1429                         pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN, &pa))
1430                         goto retry;
1431                 m = PHYS_TO_VM_PAGE(pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN);
1432                 vm_page_hold(m);
1433         }
1434         PA_UNLOCK_COND(pa);
1435         PMAP_UNLOCK(pmap);
1436         return (m);
1437 }
1438
1439 static mmu_t installed_mmu;
1440
1441 static void *
1442 moea64_uma_page_alloc(uma_zone_t zone, int bytes, u_int8_t *flags, int wait) 
1443 {
1444         /*
1445          * This entire routine is a horrible hack to avoid bothering kmem
1446          * for new KVA addresses. Because this can get called from inside
1447          * kmem allocation routines, calling kmem for a new address here
1448          * can lead to multiply locking non-recursive mutexes.
1449          */
1450         vm_offset_t va;
1451
1452         vm_page_t m;
1453         int pflags, needed_lock;
1454
1455         *flags = UMA_SLAB_PRIV;
1456         needed_lock = !PMAP_LOCKED(kernel_pmap);
1457         pflags = malloc2vm_flags(wait) | VM_ALLOC_WIRED;
1458
1459         for (;;) {
1460                 m = vm_page_alloc(NULL, 0, pflags | VM_ALLOC_NOOBJ);
1461                 if (m == NULL) {
1462                         if (wait & M_NOWAIT)
1463                                 return (NULL);
1464                         VM_WAIT;
1465                 } else
1466                         break;
1467         }
1468
1469         va = VM_PAGE_TO_PHYS(m);
1470
1471         LOCK_TABLE_WR();
1472         if (needed_lock)
1473                 PMAP_LOCK(kernel_pmap);
1474
1475         moea64_pvo_enter(installed_mmu, kernel_pmap, moea64_upvo_zone,
1476             NULL, va, VM_PAGE_TO_PHYS(m), LPTE_M, PVO_WIRED | PVO_BOOTSTRAP);
1477
1478         if (needed_lock)
1479                 PMAP_UNLOCK(kernel_pmap);
1480         UNLOCK_TABLE_WR();
1481         
1482         if ((wait & M_ZERO) && (m->flags & PG_ZERO) == 0)
1483                 bzero((void *)va, PAGE_SIZE);
1484
1485         return (void *)va;
1486 }
1487
1488 extern int elf32_nxstack;
1489
1490 void
1491 moea64_init(mmu_t mmu)
1492 {
1493
1494         CTR0(KTR_PMAP, "moea64_init");
1495
1496         moea64_upvo_zone = uma_zcreate("UPVO entry", sizeof (struct pvo_entry),
1497             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
1498             UMA_ZONE_VM | UMA_ZONE_NOFREE);
1499         moea64_mpvo_zone = uma_zcreate("MPVO entry", sizeof(struct pvo_entry),
1500             NULL, NULL, NULL, NULL, UMA_ALIGN_PTR,
1501             UMA_ZONE_VM | UMA_ZONE_NOFREE);
1502
1503         if (!hw_direct_map) {
1504                 installed_mmu = mmu;
1505                 uma_zone_set_allocf(moea64_upvo_zone,moea64_uma_page_alloc);
1506                 uma_zone_set_allocf(moea64_mpvo_zone,moea64_uma_page_alloc);
1507         }
1508
1509 #ifdef COMPAT_FREEBSD32
1510         elf32_nxstack = 1;
1511 #endif
1512
1513         moea64_initialized = TRUE;
1514 }
1515
1516 boolean_t
1517 moea64_is_referenced(mmu_t mmu, vm_page_t m)
1518 {
1519
1520         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1521             ("moea64_is_referenced: page %p is not managed", m));
1522         return (moea64_query_bit(mmu, m, PTE_REF));
1523 }
1524
1525 boolean_t
1526 moea64_is_modified(mmu_t mmu, vm_page_t m)
1527 {
1528
1529         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1530             ("moea64_is_modified: page %p is not managed", m));
1531
1532         /*
1533          * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
1534          * concurrently set while the object is locked.  Thus, if PGA_WRITEABLE
1535          * is clear, no PTEs can have LPTE_CHG set.
1536          */
1537         VM_OBJECT_ASSERT_LOCKED(m->object);
1538         if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
1539                 return (FALSE);
1540         return (moea64_query_bit(mmu, m, LPTE_CHG));
1541 }
1542
1543 boolean_t
1544 moea64_is_prefaultable(mmu_t mmu, pmap_t pmap, vm_offset_t va)
1545 {
1546         struct pvo_entry *pvo;
1547         boolean_t rv;
1548
1549         PMAP_LOCK(pmap);
1550         pvo = moea64_pvo_find_va(pmap, va & ~ADDR_POFF);
1551         rv = pvo == NULL || (pvo->pvo_pte.lpte.pte_hi & LPTE_VALID) == 0;
1552         PMAP_UNLOCK(pmap);
1553         return (rv);
1554 }
1555
1556 void
1557 moea64_clear_modify(mmu_t mmu, vm_page_t m)
1558 {
1559
1560         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1561             ("moea64_clear_modify: page %p is not managed", m));
1562         VM_OBJECT_ASSERT_WLOCKED(m->object);
1563         KASSERT(!vm_page_xbusied(m),
1564             ("moea64_clear_modify: page %p is exclusive busied", m));
1565
1566         /*
1567          * If the page is not PGA_WRITEABLE, then no PTEs can have LPTE_CHG
1568          * set.  If the object containing the page is locked and the page is
1569          * not exclusive busied, then PGA_WRITEABLE cannot be concurrently set.
1570          */
1571         if ((m->aflags & PGA_WRITEABLE) == 0)
1572                 return;
1573         moea64_clear_bit(mmu, m, LPTE_CHG);
1574 }
1575
1576 /*
1577  * Clear the write and modified bits in each of the given page's mappings.
1578  */
1579 void
1580 moea64_remove_write(mmu_t mmu, vm_page_t m)
1581 {
1582         struct  pvo_entry *pvo;
1583         uintptr_t pt;
1584         pmap_t  pmap;
1585         uint64_t lo = 0;
1586
1587         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1588             ("moea64_remove_write: page %p is not managed", m));
1589
1590         /*
1591          * If the page is not exclusive busied, then PGA_WRITEABLE cannot be
1592          * set by another thread while the object is locked.  Thus,
1593          * if PGA_WRITEABLE is clear, no page table entries need updating.
1594          */
1595         VM_OBJECT_ASSERT_WLOCKED(m->object);
1596         if (!vm_page_xbusied(m) && (m->aflags & PGA_WRITEABLE) == 0)
1597                 return;
1598         powerpc_sync();
1599         LOCK_TABLE_RD();
1600         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
1601                 pmap = pvo->pvo_pmap;
1602                 PMAP_LOCK(pmap);
1603                 if ((pvo->pvo_pte.lpte.pte_lo & LPTE_PP) != LPTE_BR) {
1604                         pt = MOEA64_PVO_TO_PTE(mmu, pvo);
1605                         pvo->pvo_pte.lpte.pte_lo &= ~LPTE_PP;
1606                         pvo->pvo_pte.lpte.pte_lo |= LPTE_BR;
1607                         if (pt != -1) {
1608                                 MOEA64_PTE_SYNCH(mmu, pt, &pvo->pvo_pte.lpte);
1609                                 lo |= pvo->pvo_pte.lpte.pte_lo;
1610                                 pvo->pvo_pte.lpte.pte_lo &= ~LPTE_CHG;
1611                                 MOEA64_PTE_CHANGE(mmu, pt,
1612                                     &pvo->pvo_pte.lpte, pvo->pvo_vpn);
1613                                 if (pvo->pvo_pmap == kernel_pmap)
1614                                         isync();
1615                         }
1616                 }
1617                 if ((lo & LPTE_CHG) != 0) 
1618                         vm_page_dirty(m);
1619                 PMAP_UNLOCK(pmap);
1620         }
1621         UNLOCK_TABLE_RD();
1622         vm_page_aflag_clear(m, PGA_WRITEABLE);
1623 }
1624
1625 /*
1626  *      moea64_ts_referenced:
1627  *
1628  *      Return a count of reference bits for a page, clearing those bits.
1629  *      It is not necessary for every reference bit to be cleared, but it
1630  *      is necessary that 0 only be returned when there are truly no
1631  *      reference bits set.
1632  *
1633  *      XXX: The exact number of bits to check and clear is a matter that
1634  *      should be tested and standardized at some point in the future for
1635  *      optimal aging of shared pages.
1636  */
1637 int
1638 moea64_ts_referenced(mmu_t mmu, vm_page_t m)
1639 {
1640
1641         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1642             ("moea64_ts_referenced: page %p is not managed", m));
1643         return (moea64_clear_bit(mmu, m, LPTE_REF));
1644 }
1645
1646 /*
1647  * Modify the WIMG settings of all mappings for a page.
1648  */
1649 void
1650 moea64_page_set_memattr(mmu_t mmu, vm_page_t m, vm_memattr_t ma)
1651 {
1652         struct  pvo_entry *pvo;
1653         struct  pvo_head *pvo_head;
1654         uintptr_t pt;
1655         pmap_t  pmap;
1656         uint64_t lo;
1657
1658         if ((m->oflags & VPO_UNMANAGED) != 0) {
1659                 m->md.mdpg_cache_attrs = ma;
1660                 return;
1661         }
1662
1663         pvo_head = vm_page_to_pvoh(m);
1664         lo = moea64_calc_wimg(VM_PAGE_TO_PHYS(m), ma);
1665         LOCK_TABLE_RD();
1666         LIST_FOREACH(pvo, pvo_head, pvo_vlink) {
1667                 pmap = pvo->pvo_pmap;
1668                 PMAP_LOCK(pmap);
1669                 pt = MOEA64_PVO_TO_PTE(mmu, pvo);
1670                 pvo->pvo_pte.lpte.pte_lo &= ~LPTE_WIMG;
1671                 pvo->pvo_pte.lpte.pte_lo |= lo;
1672                 if (pt != -1) {
1673                         MOEA64_PTE_CHANGE(mmu, pt, &pvo->pvo_pte.lpte,
1674                             pvo->pvo_vpn);
1675                         if (pvo->pvo_pmap == kernel_pmap)
1676                                 isync();
1677                 }
1678                 PMAP_UNLOCK(pmap);
1679         }
1680         UNLOCK_TABLE_RD();
1681         m->md.mdpg_cache_attrs = ma;
1682 }
1683
1684 /*
1685  * Map a wired page into kernel virtual address space.
1686  */
1687 void
1688 moea64_kenter_attr(mmu_t mmu, vm_offset_t va, vm_offset_t pa, vm_memattr_t ma)
1689 {
1690         uint64_t        pte_lo;
1691         int             error;  
1692
1693         pte_lo = moea64_calc_wimg(pa, ma);
1694
1695         LOCK_TABLE_WR();
1696         PMAP_LOCK(kernel_pmap);
1697         error = moea64_pvo_enter(mmu, kernel_pmap, moea64_upvo_zone,
1698             NULL, va, pa, pte_lo, PVO_WIRED);
1699         PMAP_UNLOCK(kernel_pmap);
1700         UNLOCK_TABLE_WR();
1701
1702         if (error != 0 && error != ENOENT)
1703                 panic("moea64_kenter: failed to enter va %#zx pa %#zx: %d", va,
1704                     pa, error);
1705 }
1706
1707 void
1708 moea64_kenter(mmu_t mmu, vm_offset_t va, vm_paddr_t pa)
1709 {
1710
1711         moea64_kenter_attr(mmu, va, pa, VM_MEMATTR_DEFAULT);
1712 }
1713
1714 /*
1715  * Extract the physical page address associated with the given kernel virtual
1716  * address.
1717  */
1718 vm_paddr_t
1719 moea64_kextract(mmu_t mmu, vm_offset_t va)
1720 {
1721         struct          pvo_entry *pvo;
1722         vm_paddr_t pa;
1723
1724         /*
1725          * Shortcut the direct-mapped case when applicable.  We never put
1726          * anything but 1:1 mappings below VM_MIN_KERNEL_ADDRESS.
1727          */
1728         if (va < VM_MIN_KERNEL_ADDRESS)
1729                 return (va);
1730
1731         PMAP_LOCK(kernel_pmap);
1732         pvo = moea64_pvo_find_va(kernel_pmap, va);
1733         KASSERT(pvo != NULL, ("moea64_kextract: no addr found for %#" PRIxPTR,
1734             va));
1735         pa = (pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN) | (va - PVO_VADDR(pvo));
1736         PMAP_UNLOCK(kernel_pmap);
1737         return (pa);
1738 }
1739
1740 /*
1741  * Remove a wired page from kernel virtual address space.
1742  */
1743 void
1744 moea64_kremove(mmu_t mmu, vm_offset_t va)
1745 {
1746         moea64_remove(mmu, kernel_pmap, va, va + PAGE_SIZE);
1747 }
1748
1749 /*
1750  * Map a range of physical addresses into kernel virtual address space.
1751  *
1752  * The value passed in *virt is a suggested virtual address for the mapping.
1753  * Architectures which can support a direct-mapped physical to virtual region
1754  * can return the appropriate address within that region, leaving '*virt'
1755  * unchanged.  We cannot and therefore do not; *virt is updated with the
1756  * first usable address after the mapped region.
1757  */
1758 vm_offset_t
1759 moea64_map(mmu_t mmu, vm_offset_t *virt, vm_paddr_t pa_start,
1760     vm_paddr_t pa_end, int prot)
1761 {
1762         vm_offset_t     sva, va;
1763
1764         sva = *virt;
1765         va = sva;
1766         for (; pa_start < pa_end; pa_start += PAGE_SIZE, va += PAGE_SIZE)
1767                 moea64_kenter(mmu, va, pa_start);
1768         *virt = va;
1769
1770         return (sva);
1771 }
1772
1773 /*
1774  * Returns true if the pmap's pv is one of the first
1775  * 16 pvs linked to from this page.  This count may
1776  * be changed upwards or downwards in the future; it
1777  * is only necessary that true be returned for a small
1778  * subset of pmaps for proper page aging.
1779  */
1780 boolean_t
1781 moea64_page_exists_quick(mmu_t mmu, pmap_t pmap, vm_page_t m)
1782 {
1783         int loops;
1784         struct pvo_entry *pvo;
1785         boolean_t rv;
1786
1787         KASSERT((m->oflags & VPO_UNMANAGED) == 0,
1788             ("moea64_page_exists_quick: page %p is not managed", m));
1789         loops = 0;
1790         rv = FALSE;
1791         LOCK_TABLE_RD();
1792         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
1793                 if (pvo->pvo_pmap == pmap) {
1794                         rv = TRUE;
1795                         break;
1796                 }
1797                 if (++loops >= 16)
1798                         break;
1799         }
1800         UNLOCK_TABLE_RD();
1801         return (rv);
1802 }
1803
1804 /*
1805  * Return the number of managed mappings to the given physical page
1806  * that are wired.
1807  */
1808 int
1809 moea64_page_wired_mappings(mmu_t mmu, vm_page_t m)
1810 {
1811         struct pvo_entry *pvo;
1812         int count;
1813
1814         count = 0;
1815         if ((m->oflags & VPO_UNMANAGED) != 0)
1816                 return (count);
1817         LOCK_TABLE_RD();
1818         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink)
1819                 if ((pvo->pvo_vaddr & PVO_WIRED) != 0)
1820                         count++;
1821         UNLOCK_TABLE_RD();
1822         return (count);
1823 }
1824
1825 static uintptr_t        moea64_vsidcontext;
1826
1827 uintptr_t
1828 moea64_get_unique_vsid(void) {
1829         u_int entropy;
1830         register_t hash;
1831         uint32_t mask;
1832         int i;
1833
1834         entropy = 0;
1835         __asm __volatile("mftb %0" : "=r"(entropy));
1836
1837         mtx_lock(&moea64_slb_mutex);
1838         for (i = 0; i < NVSIDS; i += VSID_NBPW) {
1839                 u_int   n;
1840
1841                 /*
1842                  * Create a new value by mutiplying by a prime and adding in
1843                  * entropy from the timebase register.  This is to make the
1844                  * VSID more random so that the PT hash function collides
1845                  * less often.  (Note that the prime casues gcc to do shifts
1846                  * instead of a multiply.)
1847                  */
1848                 moea64_vsidcontext = (moea64_vsidcontext * 0x1105) + entropy;
1849                 hash = moea64_vsidcontext & (NVSIDS - 1);
1850                 if (hash == 0)          /* 0 is special, avoid it */
1851                         continue;
1852                 n = hash >> 5;
1853                 mask = 1 << (hash & (VSID_NBPW - 1));
1854                 hash = (moea64_vsidcontext & VSID_HASHMASK);
1855                 if (moea64_vsid_bitmap[n] & mask) {     /* collision? */
1856                         /* anything free in this bucket? */
1857                         if (moea64_vsid_bitmap[n] == 0xffffffff) {
1858                                 entropy = (moea64_vsidcontext >> 20);
1859                                 continue;
1860                         }
1861                         i = ffs(~moea64_vsid_bitmap[n]) - 1;
1862                         mask = 1 << i;
1863                         hash &= VSID_HASHMASK & ~(VSID_NBPW - 1);
1864                         hash |= i;
1865                 }
1866                 KASSERT(!(moea64_vsid_bitmap[n] & mask),
1867                     ("Allocating in-use VSID %#zx\n", hash));
1868                 moea64_vsid_bitmap[n] |= mask;
1869                 mtx_unlock(&moea64_slb_mutex);
1870                 return (hash);
1871         }
1872
1873         mtx_unlock(&moea64_slb_mutex);
1874         panic("%s: out of segments",__func__);
1875 }
1876
1877 #ifdef __powerpc64__
1878 void
1879 moea64_pinit(mmu_t mmu, pmap_t pmap)
1880 {
1881
1882         RB_INIT(&pmap->pmap_pvo);
1883
1884         pmap->pm_slb_tree_root = slb_alloc_tree();
1885         pmap->pm_slb = slb_alloc_user_cache();
1886         pmap->pm_slb_len = 0;
1887 }
1888 #else
1889 void
1890 moea64_pinit(mmu_t mmu, pmap_t pmap)
1891 {
1892         int     i;
1893         uint32_t hash;
1894
1895         RB_INIT(&pmap->pmap_pvo);
1896
1897         if (pmap_bootstrapped)
1898                 pmap->pmap_phys = (pmap_t)moea64_kextract(mmu,
1899                     (vm_offset_t)pmap);
1900         else
1901                 pmap->pmap_phys = pmap;
1902
1903         /*
1904          * Allocate some segment registers for this pmap.
1905          */
1906         hash = moea64_get_unique_vsid();
1907
1908         for (i = 0; i < 16; i++) 
1909                 pmap->pm_sr[i] = VSID_MAKE(i, hash);
1910
1911         KASSERT(pmap->pm_sr[0] != 0, ("moea64_pinit: pm_sr[0] = 0"));
1912 }
1913 #endif
1914
1915 /*
1916  * Initialize the pmap associated with process 0.
1917  */
1918 void
1919 moea64_pinit0(mmu_t mmu, pmap_t pm)
1920 {
1921
1922         PMAP_LOCK_INIT(pm);
1923         moea64_pinit(mmu, pm);
1924         bzero(&pm->pm_stats, sizeof(pm->pm_stats));
1925 }
1926
1927 /*
1928  * Set the physical protection on the specified range of this map as requested.
1929  */
1930 static void
1931 moea64_pvo_protect(mmu_t mmu,  pmap_t pm, struct pvo_entry *pvo, vm_prot_t prot)
1932 {
1933         uintptr_t pt;
1934         struct  vm_page *pg;
1935         uint64_t oldlo;
1936
1937         PMAP_LOCK_ASSERT(pm, MA_OWNED);
1938
1939         /*
1940          * Grab the PTE pointer before we diddle with the cached PTE
1941          * copy.
1942          */
1943         pt = MOEA64_PVO_TO_PTE(mmu, pvo);
1944
1945         /*
1946          * Change the protection of the page.
1947          */
1948         oldlo = pvo->pvo_pte.lpte.pte_lo;
1949         pvo->pvo_pte.lpte.pte_lo &= ~LPTE_PP;
1950         pvo->pvo_pte.lpte.pte_lo &= ~LPTE_NOEXEC;
1951         if ((prot & VM_PROT_EXECUTE) == 0) 
1952                 pvo->pvo_pte.lpte.pte_lo |= LPTE_NOEXEC;
1953         if (prot & VM_PROT_WRITE) 
1954                 pvo->pvo_pte.lpte.pte_lo |= LPTE_BW;
1955         else
1956                 pvo->pvo_pte.lpte.pte_lo |= LPTE_BR;
1957
1958         pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN);
1959
1960         /*
1961          * If the PVO is in the page table, update that pte as well.
1962          */
1963         if (pt != -1)
1964                 MOEA64_PTE_CHANGE(mmu, pt, &pvo->pvo_pte.lpte,
1965                     pvo->pvo_vpn);
1966         if (pm != kernel_pmap && pg != NULL && !(pg->aflags & PGA_EXECUTABLE) &&
1967             (pvo->pvo_pte.lpte.pte_lo & (LPTE_I | LPTE_G | LPTE_NOEXEC)) == 0) {
1968                 if ((pg->oflags & VPO_UNMANAGED) == 0)
1969                         vm_page_aflag_set(pg, PGA_EXECUTABLE);
1970                 moea64_syncicache(mmu, pm, PVO_VADDR(pvo),
1971                     pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN, PAGE_SIZE);
1972         }
1973
1974         /*
1975          * Update vm about the REF/CHG bits if the page is managed and we have
1976          * removed write access.
1977          */
1978         if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED && 
1979             (oldlo & LPTE_PP) != LPTE_BR && !(prot & VM_PROT_WRITE)) {
1980                 if (pg != NULL) {
1981                         if (pvo->pvo_pte.lpte.pte_lo & LPTE_CHG)
1982                                 vm_page_dirty(pg);
1983                         if (pvo->pvo_pte.lpte.pte_lo & LPTE_REF)
1984                                 vm_page_aflag_set(pg, PGA_REFERENCED);
1985                 }
1986         }
1987 }
1988
1989 void
1990 moea64_protect(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva,
1991     vm_prot_t prot)
1992 {
1993         struct  pvo_entry *pvo, *tpvo, key;
1994
1995         CTR4(KTR_PMAP, "moea64_protect: pm=%p sva=%#x eva=%#x prot=%#x", pm,
1996             sva, eva, prot);
1997
1998         KASSERT(pm == &curproc->p_vmspace->vm_pmap || pm == kernel_pmap,
1999             ("moea64_protect: non current pmap"));
2000
2001         if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
2002                 moea64_remove(mmu, pm, sva, eva);
2003                 return;
2004         }
2005
2006         LOCK_TABLE_RD();
2007         PMAP_LOCK(pm);
2008         key.pvo_vaddr = sva;
2009         for (pvo = RB_NFIND(pvo_tree, &pm->pmap_pvo, &key);
2010             pvo != NULL && PVO_VADDR(pvo) < eva; pvo = tpvo) {
2011                 tpvo = RB_NEXT(pvo_tree, &pm->pmap_pvo, pvo);
2012                 moea64_pvo_protect(mmu, pm, pvo, prot);
2013         }
2014         UNLOCK_TABLE_RD();
2015         PMAP_UNLOCK(pm);
2016 }
2017
2018 /*
2019  * Map a list of wired pages into kernel virtual address space.  This is
2020  * intended for temporary mappings which do not need page modification or
2021  * references recorded.  Existing mappings in the region are overwritten.
2022  */
2023 void
2024 moea64_qenter(mmu_t mmu, vm_offset_t va, vm_page_t *m, int count)
2025 {
2026         while (count-- > 0) {
2027                 moea64_kenter(mmu, va, VM_PAGE_TO_PHYS(*m));
2028                 va += PAGE_SIZE;
2029                 m++;
2030         }
2031 }
2032
2033 /*
2034  * Remove page mappings from kernel virtual address space.  Intended for
2035  * temporary mappings entered by moea64_qenter.
2036  */
2037 void
2038 moea64_qremove(mmu_t mmu, vm_offset_t va, int count)
2039 {
2040         while (count-- > 0) {
2041                 moea64_kremove(mmu, va);
2042                 va += PAGE_SIZE;
2043         }
2044 }
2045
2046 void
2047 moea64_release_vsid(uint64_t vsid)
2048 {
2049         int idx, mask;
2050
2051         mtx_lock(&moea64_slb_mutex);
2052         idx = vsid & (NVSIDS-1);
2053         mask = 1 << (idx % VSID_NBPW);
2054         idx /= VSID_NBPW;
2055         KASSERT(moea64_vsid_bitmap[idx] & mask,
2056             ("Freeing unallocated VSID %#jx", vsid));
2057         moea64_vsid_bitmap[idx] &= ~mask;
2058         mtx_unlock(&moea64_slb_mutex);
2059 }
2060         
2061
2062 void
2063 moea64_release(mmu_t mmu, pmap_t pmap)
2064 {
2065         
2066         /*
2067          * Free segment registers' VSIDs
2068          */
2069     #ifdef __powerpc64__
2070         slb_free_tree(pmap);
2071         slb_free_user_cache(pmap->pm_slb);
2072     #else
2073         KASSERT(pmap->pm_sr[0] != 0, ("moea64_release: pm_sr[0] = 0"));
2074
2075         moea64_release_vsid(VSID_TO_HASH(pmap->pm_sr[0]));
2076     #endif
2077 }
2078
2079 /*
2080  * Remove all pages mapped by the specified pmap
2081  */
2082 void
2083 moea64_remove_pages(mmu_t mmu, pmap_t pm)
2084 {
2085         struct  pvo_entry *pvo, *tpvo;
2086
2087         LOCK_TABLE_WR();
2088         PMAP_LOCK(pm);
2089         RB_FOREACH_SAFE(pvo, pvo_tree, &pm->pmap_pvo, tpvo) {
2090                 if (!(pvo->pvo_vaddr & PVO_WIRED))
2091                         moea64_pvo_remove(mmu, pvo);
2092         }
2093         UNLOCK_TABLE_WR();
2094         PMAP_UNLOCK(pm);
2095 }
2096
2097 /*
2098  * Remove the given range of addresses from the specified map.
2099  */
2100 void
2101 moea64_remove(mmu_t mmu, pmap_t pm, vm_offset_t sva, vm_offset_t eva)
2102 {
2103         struct  pvo_entry *pvo, *tpvo, key;
2104
2105         /*
2106          * Perform an unsynchronized read.  This is, however, safe.
2107          */
2108         if (pm->pm_stats.resident_count == 0)
2109                 return;
2110
2111         LOCK_TABLE_WR();
2112         PMAP_LOCK(pm);
2113         key.pvo_vaddr = sva;
2114         for (pvo = RB_NFIND(pvo_tree, &pm->pmap_pvo, &key);
2115             pvo != NULL && PVO_VADDR(pvo) < eva; pvo = tpvo) {
2116                 tpvo = RB_NEXT(pvo_tree, &pm->pmap_pvo, pvo);
2117                 moea64_pvo_remove(mmu, pvo);
2118         }
2119         UNLOCK_TABLE_WR();
2120         PMAP_UNLOCK(pm);
2121 }
2122
2123 /*
2124  * Remove physical page from all pmaps in which it resides. moea64_pvo_remove()
2125  * will reflect changes in pte's back to the vm_page.
2126  */
2127 void
2128 moea64_remove_all(mmu_t mmu, vm_page_t m)
2129 {
2130         struct  pvo_entry *pvo, *next_pvo;
2131         pmap_t  pmap;
2132
2133         LOCK_TABLE_WR();
2134         LIST_FOREACH_SAFE(pvo, vm_page_to_pvoh(m), pvo_vlink, next_pvo) {
2135                 pmap = pvo->pvo_pmap;
2136                 PMAP_LOCK(pmap);
2137                 moea64_pvo_remove(mmu, pvo);
2138                 PMAP_UNLOCK(pmap);
2139         }
2140         UNLOCK_TABLE_WR();
2141         if ((m->aflags & PGA_WRITEABLE) && moea64_is_modified(mmu, m))
2142                 vm_page_dirty(m);
2143         vm_page_aflag_clear(m, PGA_WRITEABLE);
2144         vm_page_aflag_clear(m, PGA_EXECUTABLE);
2145 }
2146
2147 /*
2148  * Allocate a physical page of memory directly from the phys_avail map.
2149  * Can only be called from moea64_bootstrap before avail start and end are
2150  * calculated.
2151  */
2152 vm_offset_t
2153 moea64_bootstrap_alloc(vm_size_t size, u_int align)
2154 {
2155         vm_offset_t     s, e;
2156         int             i, j;
2157
2158         size = round_page(size);
2159         for (i = 0; phys_avail[i + 1] != 0; i += 2) {
2160                 if (align != 0)
2161                         s = (phys_avail[i] + align - 1) & ~(align - 1);
2162                 else
2163                         s = phys_avail[i];
2164                 e = s + size;
2165
2166                 if (s < phys_avail[i] || e > phys_avail[i + 1])
2167                         continue;
2168
2169                 if (s + size > platform_real_maxaddr())
2170                         continue;
2171
2172                 if (s == phys_avail[i]) {
2173                         phys_avail[i] += size;
2174                 } else if (e == phys_avail[i + 1]) {
2175                         phys_avail[i + 1] -= size;
2176                 } else {
2177                         for (j = phys_avail_count * 2; j > i; j -= 2) {
2178                                 phys_avail[j] = phys_avail[j - 2];
2179                                 phys_avail[j + 1] = phys_avail[j - 1];
2180                         }
2181
2182                         phys_avail[i + 3] = phys_avail[i + 1];
2183                         phys_avail[i + 1] = s;
2184                         phys_avail[i + 2] = e;
2185                         phys_avail_count++;
2186                 }
2187
2188                 return (s);
2189         }
2190         panic("moea64_bootstrap_alloc: could not allocate memory");
2191 }
2192
2193 static int
2194 moea64_pvo_enter(mmu_t mmu, pmap_t pm, uma_zone_t zone,
2195     struct pvo_head *pvo_head, vm_offset_t va, vm_offset_t pa,
2196     uint64_t pte_lo, int flags)
2197 {
2198         struct   pvo_entry *pvo;
2199         uint64_t vsid;
2200         int      first;
2201         u_int    ptegidx;
2202         int      i;
2203         int      bootstrap;
2204
2205         /*
2206          * One nasty thing that can happen here is that the UMA calls to
2207          * allocate new PVOs need to map more memory, which calls pvo_enter(),
2208          * which calls UMA...
2209          *
2210          * We break the loop by detecting recursion and allocating out of
2211          * the bootstrap pool.
2212          */
2213
2214         first = 0;
2215         bootstrap = (flags & PVO_BOOTSTRAP);
2216
2217         if (!moea64_initialized)
2218                 bootstrap = 1;
2219
2220         PMAP_LOCK_ASSERT(pm, MA_OWNED);
2221         rw_assert(&moea64_table_lock, RA_WLOCKED);
2222
2223         /*
2224          * Compute the PTE Group index.
2225          */
2226         va &= ~ADDR_POFF;
2227         vsid = va_to_vsid(pm, va);
2228         ptegidx = va_to_pteg(vsid, va, flags & PVO_LARGE);
2229
2230         /*
2231          * Remove any existing mapping for this page.  Reuse the pvo entry if
2232          * there is a mapping.
2233          */
2234         moea64_pvo_enter_calls++;
2235
2236         LIST_FOREACH(pvo, &moea64_pvo_table[ptegidx], pvo_olink) {
2237                 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
2238                         if ((pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN) == pa &&
2239                             (pvo->pvo_pte.lpte.pte_lo & (LPTE_NOEXEC | LPTE_PP))
2240                             == (pte_lo & (LPTE_NOEXEC | LPTE_PP))) {
2241                                 if (!(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID)) {
2242                                         /* Re-insert if spilled */
2243                                         i = MOEA64_PTE_INSERT(mmu, ptegidx,
2244                                             &pvo->pvo_pte.lpte);
2245                                         if (i >= 0)
2246                                                 PVO_PTEGIDX_SET(pvo, i);
2247                                         moea64_pte_overflow--;
2248                                 }
2249                                 return (0);
2250                         }
2251                         moea64_pvo_remove(mmu, pvo);
2252                         break;
2253                 }
2254         }
2255
2256         /*
2257          * If we aren't overwriting a mapping, try to allocate.
2258          */
2259         if (bootstrap) {
2260                 if (moea64_bpvo_pool_index >= BPVO_POOL_SIZE) {
2261                         panic("moea64_enter: bpvo pool exhausted, %d, %d, %zd",
2262                               moea64_bpvo_pool_index, BPVO_POOL_SIZE, 
2263                               BPVO_POOL_SIZE * sizeof(struct pvo_entry));
2264                 }
2265                 pvo = &moea64_bpvo_pool[moea64_bpvo_pool_index];
2266                 moea64_bpvo_pool_index++;
2267                 bootstrap = 1;
2268         } else {
2269                 pvo = uma_zalloc(zone, M_NOWAIT);
2270         }
2271
2272         if (pvo == NULL)
2273                 return (ENOMEM);
2274
2275         moea64_pvo_entries++;
2276         pvo->pvo_vaddr = va;
2277         pvo->pvo_vpn = (uint64_t)((va & ADDR_PIDX) >> ADDR_PIDX_SHFT)
2278             | (vsid << 16);
2279         pvo->pvo_pmap = pm;
2280         LIST_INSERT_HEAD(&moea64_pvo_table[ptegidx], pvo, pvo_olink);
2281         pvo->pvo_vaddr &= ~ADDR_POFF;
2282
2283         if (flags & PVO_WIRED)
2284                 pvo->pvo_vaddr |= PVO_WIRED;
2285         if (pvo_head != NULL)
2286                 pvo->pvo_vaddr |= PVO_MANAGED;
2287         if (bootstrap)
2288                 pvo->pvo_vaddr |= PVO_BOOTSTRAP;
2289         if (flags & PVO_LARGE)
2290                 pvo->pvo_vaddr |= PVO_LARGE;
2291
2292         moea64_pte_create(&pvo->pvo_pte.lpte, vsid, va, 
2293             (uint64_t)(pa) | pte_lo, flags);
2294
2295         /*
2296          * Add to pmap list
2297          */
2298         RB_INSERT(pvo_tree, &pm->pmap_pvo, pvo);
2299
2300         /*
2301          * Remember if the list was empty and therefore will be the first
2302          * item.
2303          */
2304         if (pvo_head != NULL) {
2305                 if (LIST_FIRST(pvo_head) == NULL)
2306                         first = 1;
2307                 LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink);
2308         }
2309
2310         if (pvo->pvo_vaddr & PVO_WIRED) {
2311                 pvo->pvo_pte.lpte.pte_hi |= LPTE_WIRED;
2312                 pm->pm_stats.wired_count++;
2313         }
2314         pm->pm_stats.resident_count++;
2315
2316         /*
2317          * We hope this succeeds but it isn't required.
2318          */
2319         i = MOEA64_PTE_INSERT(mmu, ptegidx, &pvo->pvo_pte.lpte);
2320         if (i >= 0) {
2321                 PVO_PTEGIDX_SET(pvo, i);
2322         } else {
2323                 panic("moea64_pvo_enter: overflow");
2324                 moea64_pte_overflow++;
2325         }
2326
2327         if (pm == kernel_pmap)
2328                 isync();
2329
2330 #ifdef __powerpc64__
2331         /*
2332          * Make sure all our bootstrap mappings are in the SLB as soon
2333          * as virtual memory is switched on.
2334          */
2335         if (!pmap_bootstrapped)
2336                 moea64_bootstrap_slb_prefault(va, flags & PVO_LARGE);
2337 #endif
2338
2339         return (first ? ENOENT : 0);
2340 }
2341
2342 static void
2343 moea64_pvo_remove(mmu_t mmu, struct pvo_entry *pvo)
2344 {
2345         struct  vm_page *pg;
2346         uintptr_t pt;
2347
2348         PMAP_LOCK_ASSERT(pvo->pvo_pmap, MA_OWNED);
2349         rw_assert(&moea64_table_lock, RA_WLOCKED);
2350
2351         /*
2352          * If there is an active pte entry, we need to deactivate it (and
2353          * save the ref & cfg bits).
2354          */
2355         pt = MOEA64_PVO_TO_PTE(mmu, pvo);
2356         if (pt != -1) {
2357                 MOEA64_PTE_UNSET(mmu, pt, &pvo->pvo_pte.lpte, pvo->pvo_vpn);
2358                 PVO_PTEGIDX_CLR(pvo);
2359         } else {
2360                 moea64_pte_overflow--;
2361         }
2362
2363         /*
2364          * Update our statistics.
2365          */
2366         pvo->pvo_pmap->pm_stats.resident_count--;
2367         if (pvo->pvo_vaddr & PVO_WIRED)
2368                 pvo->pvo_pmap->pm_stats.wired_count--;
2369
2370         /*
2371          * Remove this PVO from the pmap list.
2372          */
2373         RB_REMOVE(pvo_tree, &pvo->pvo_pmap->pmap_pvo, pvo);
2374
2375         /*
2376          * Remove this from the overflow list and return it to the pool
2377          * if we aren't going to reuse it.
2378          */
2379         LIST_REMOVE(pvo, pvo_olink);
2380
2381         /*
2382          * Update vm about the REF/CHG bits if the page is managed.
2383          */
2384         pg = PHYS_TO_VM_PAGE(pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN);
2385
2386         if ((pvo->pvo_vaddr & PVO_MANAGED) == PVO_MANAGED && pg != NULL) {
2387                 LIST_REMOVE(pvo, pvo_vlink);
2388                 if ((pvo->pvo_pte.lpte.pte_lo & LPTE_PP) != LPTE_BR) {
2389                         if (pvo->pvo_pte.lpte.pte_lo & LPTE_CHG)
2390                                 vm_page_dirty(pg);
2391                         if (pvo->pvo_pte.lpte.pte_lo & LPTE_REF)
2392                                 vm_page_aflag_set(pg, PGA_REFERENCED);
2393                         if (LIST_EMPTY(vm_page_to_pvoh(pg)))
2394                                 vm_page_aflag_clear(pg, PGA_WRITEABLE);
2395                 }
2396                 if (LIST_EMPTY(vm_page_to_pvoh(pg)))
2397                         vm_page_aflag_clear(pg, PGA_EXECUTABLE);
2398         }
2399
2400         moea64_pvo_entries--;
2401         moea64_pvo_remove_calls++;
2402
2403         if (!(pvo->pvo_vaddr & PVO_BOOTSTRAP))
2404                 uma_zfree((pvo->pvo_vaddr & PVO_MANAGED) ? moea64_mpvo_zone :
2405                     moea64_upvo_zone, pvo);
2406 }
2407
2408 static struct pvo_entry *
2409 moea64_pvo_find_va(pmap_t pm, vm_offset_t va)
2410 {
2411         struct pvo_entry key;
2412
2413         key.pvo_vaddr = va & ~ADDR_POFF;
2414         return (RB_FIND(pvo_tree, &pm->pmap_pvo, &key));
2415 }
2416
2417 static boolean_t
2418 moea64_query_bit(mmu_t mmu, vm_page_t m, u_int64_t ptebit)
2419 {
2420         struct  pvo_entry *pvo;
2421         uintptr_t pt;
2422
2423         LOCK_TABLE_RD();
2424         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
2425                 /*
2426                  * See if we saved the bit off.  If so, return success.
2427                  */
2428                 if (pvo->pvo_pte.lpte.pte_lo & ptebit) {
2429                         UNLOCK_TABLE_RD();
2430                         return (TRUE);
2431                 }
2432         }
2433
2434         /*
2435          * No luck, now go through the hard part of looking at the PTEs
2436          * themselves.  Sync so that any pending REF/CHG bits are flushed to
2437          * the PTEs.
2438          */
2439         powerpc_sync();
2440         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
2441
2442                 /*
2443                  * See if this pvo has a valid PTE.  if so, fetch the
2444                  * REF/CHG bits from the valid PTE.  If the appropriate
2445                  * ptebit is set, return success.
2446                  */
2447                 PMAP_LOCK(pvo->pvo_pmap);
2448                 pt = MOEA64_PVO_TO_PTE(mmu, pvo);
2449                 if (pt != -1) {
2450                         MOEA64_PTE_SYNCH(mmu, pt, &pvo->pvo_pte.lpte);
2451                         if (pvo->pvo_pte.lpte.pte_lo & ptebit) {
2452                                 PMAP_UNLOCK(pvo->pvo_pmap);
2453                                 UNLOCK_TABLE_RD();
2454                                 return (TRUE);
2455                         }
2456                 }
2457                 PMAP_UNLOCK(pvo->pvo_pmap);
2458         }
2459
2460         UNLOCK_TABLE_RD();
2461         return (FALSE);
2462 }
2463
2464 static u_int
2465 moea64_clear_bit(mmu_t mmu, vm_page_t m, u_int64_t ptebit)
2466 {
2467         u_int   count;
2468         struct  pvo_entry *pvo;
2469         uintptr_t pt;
2470
2471         /*
2472          * Sync so that any pending REF/CHG bits are flushed to the PTEs (so
2473          * we can reset the right ones).  note that since the pvo entries and
2474          * list heads are accessed via BAT0 and are never placed in the page
2475          * table, we don't have to worry about further accesses setting the
2476          * REF/CHG bits.
2477          */
2478         powerpc_sync();
2479
2480         /*
2481          * For each pvo entry, clear the pvo's ptebit.  If this pvo has a
2482          * valid pte clear the ptebit from the valid pte.
2483          */
2484         count = 0;
2485         LOCK_TABLE_RD();
2486         LIST_FOREACH(pvo, vm_page_to_pvoh(m), pvo_vlink) {
2487                 PMAP_LOCK(pvo->pvo_pmap);
2488                 pt = MOEA64_PVO_TO_PTE(mmu, pvo);
2489                 if (pt != -1) {
2490                         MOEA64_PTE_SYNCH(mmu, pt, &pvo->pvo_pte.lpte);
2491                         if (pvo->pvo_pte.lpte.pte_lo & ptebit) {
2492                                 count++;
2493                                 MOEA64_PTE_CLEAR(mmu, pt, &pvo->pvo_pte.lpte,
2494                                     pvo->pvo_vpn, ptebit);
2495                         }
2496                 }
2497                 pvo->pvo_pte.lpte.pte_lo &= ~ptebit;
2498                 PMAP_UNLOCK(pvo->pvo_pmap);
2499         }
2500
2501         UNLOCK_TABLE_RD();
2502         return (count);
2503 }
2504
2505 boolean_t
2506 moea64_dev_direct_mapped(mmu_t mmu, vm_paddr_t pa, vm_size_t size)
2507 {
2508         struct pvo_entry *pvo, key;
2509         vm_offset_t ppa;
2510         int error = 0;
2511
2512         PMAP_LOCK(kernel_pmap);
2513         key.pvo_vaddr = ppa = pa & ~ADDR_POFF;
2514         for (pvo = RB_FIND(pvo_tree, &kernel_pmap->pmap_pvo, &key);
2515             ppa < pa + size; ppa += PAGE_SIZE,
2516             pvo = RB_NEXT(pvo_tree, &kernel_pmap->pmap_pvo, pvo)) {
2517                 if (pvo == NULL ||
2518                     (pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN) != ppa) {
2519                         error = EFAULT;
2520                         break;
2521                 }
2522         }
2523         PMAP_UNLOCK(kernel_pmap);
2524
2525         return (error);
2526 }
2527
2528 /*
2529  * Map a set of physical memory pages into the kernel virtual
2530  * address space. Return a pointer to where it is mapped. This
2531  * routine is intended to be used for mapping device memory,
2532  * NOT real memory.
2533  */
2534 void *
2535 moea64_mapdev_attr(mmu_t mmu, vm_offset_t pa, vm_size_t size, vm_memattr_t ma)
2536 {
2537         vm_offset_t va, tmpva, ppa, offset;
2538
2539         ppa = trunc_page(pa);
2540         offset = pa & PAGE_MASK;
2541         size = roundup2(offset + size, PAGE_SIZE);
2542
2543         va = kva_alloc(size);
2544
2545         if (!va)
2546                 panic("moea64_mapdev: Couldn't alloc kernel virtual memory");
2547
2548         for (tmpva = va; size > 0;) {
2549                 moea64_kenter_attr(mmu, tmpva, ppa, ma);
2550                 size -= PAGE_SIZE;
2551                 tmpva += PAGE_SIZE;
2552                 ppa += PAGE_SIZE;
2553         }
2554
2555         return ((void *)(va + offset));
2556 }
2557
2558 void *
2559 moea64_mapdev(mmu_t mmu, vm_paddr_t pa, vm_size_t size)
2560 {
2561
2562         return moea64_mapdev_attr(mmu, pa, size, VM_MEMATTR_DEFAULT);
2563 }
2564
2565 void
2566 moea64_unmapdev(mmu_t mmu, vm_offset_t va, vm_size_t size)
2567 {
2568         vm_offset_t base, offset;
2569
2570         base = trunc_page(va);
2571         offset = va & PAGE_MASK;
2572         size = roundup2(offset + size, PAGE_SIZE);
2573
2574         kva_free(base, size);
2575 }
2576
2577 void
2578 moea64_sync_icache(mmu_t mmu, pmap_t pm, vm_offset_t va, vm_size_t sz)
2579 {
2580         struct pvo_entry *pvo;
2581         vm_offset_t lim;
2582         vm_paddr_t pa;
2583         vm_size_t len;
2584
2585         PMAP_LOCK(pm);
2586         while (sz > 0) {
2587                 lim = round_page(va);
2588                 len = MIN(lim - va, sz);
2589                 pvo = moea64_pvo_find_va(pm, va & ~ADDR_POFF);
2590                 if (pvo != NULL && !(pvo->pvo_pte.lpte.pte_lo & LPTE_I)) {
2591                         pa = (pvo->pvo_pte.lpte.pte_lo & LPTE_RPGN) |
2592                             (va & ADDR_POFF);
2593                         moea64_syncicache(mmu, pm, va, pa, len);
2594                 }
2595                 va += len;
2596                 sz -= len;
2597         }
2598         PMAP_UNLOCK(pm);
2599 }
2600
2601 vm_offset_t
2602 moea64_dumpsys_map(mmu_t mmu, struct pmap_md *md, vm_size_t ofs,
2603     vm_size_t *sz)
2604 {
2605         if (md->md_vaddr == ~0UL)
2606             return (md->md_paddr + ofs);
2607         else
2608             return (md->md_vaddr + ofs);
2609 }
2610
2611 struct pmap_md *
2612 moea64_scan_md(mmu_t mmu, struct pmap_md *prev)
2613 {
2614         static struct pmap_md md;
2615         struct pvo_entry *pvo;
2616         vm_offset_t va;
2617  
2618         if (dumpsys_minidump) {
2619                 md.md_paddr = ~0UL;     /* Minidumps use virtual addresses. */
2620                 if (prev == NULL) {
2621                         /* 1st: kernel .data and .bss. */
2622                         md.md_index = 1;
2623                         md.md_vaddr = trunc_page((uintptr_t)_etext);
2624                         md.md_size = round_page((uintptr_t)_end) - md.md_vaddr;
2625                         return (&md);
2626                 }
2627                 switch (prev->md_index) {
2628                 case 1:
2629                         /* 2nd: msgbuf and tables (see pmap_bootstrap()). */
2630                         md.md_index = 2;
2631                         md.md_vaddr = (vm_offset_t)msgbufp->msg_ptr;
2632                         md.md_size = round_page(msgbufp->msg_size);
2633                         break;
2634                 case 2:
2635                         /* 3rd: kernel VM. */
2636                         va = prev->md_vaddr + prev->md_size;
2637                         /* Find start of next chunk (from va). */
2638                         while (va < virtual_end) {
2639                                 /* Don't dump the buffer cache. */
2640                                 if (va >= kmi.buffer_sva &&
2641                                     va < kmi.buffer_eva) {
2642                                         va = kmi.buffer_eva;
2643                                         continue;
2644                                 }
2645                                 pvo = moea64_pvo_find_va(kernel_pmap,
2646                                     va & ~ADDR_POFF);
2647                                 if (pvo != NULL &&
2648                                     (pvo->pvo_pte.lpte.pte_hi & LPTE_VALID))
2649                                         break;
2650                                 va += PAGE_SIZE;
2651                         }
2652                         if (va < virtual_end) {
2653                                 md.md_vaddr = va;
2654                                 va += PAGE_SIZE;
2655                                 /* Find last page in chunk. */
2656                                 while (va < virtual_end) {
2657                                         /* Don't run into the buffer cache. */
2658                                         if (va == kmi.buffer_sva)
2659                                                 break;
2660                                         pvo = moea64_pvo_find_va(kernel_pmap,
2661                                             va & ~ADDR_POFF);
2662                                         if (pvo == NULL ||
2663                                             !(pvo->pvo_pte.lpte.pte_hi & LPTE_VALID))
2664                                                 break;
2665                                         va += PAGE_SIZE;
2666                                 }
2667                                 md.md_size = va - md.md_vaddr;
2668                                 break;
2669                         }
2670                         md.md_index = 3;
2671                         /* FALLTHROUGH */
2672                 default:
2673                         return (NULL);
2674                 }
2675         } else { /* minidumps */
2676                 if (prev == NULL) {
2677                         /* first physical chunk. */
2678                         md.md_paddr = pregions[0].mr_start;
2679                         md.md_size = pregions[0].mr_size;
2680                         md.md_vaddr = ~0UL;
2681                         md.md_index = 1;
2682                 } else if (md.md_index < pregions_sz) {
2683                         md.md_paddr = pregions[md.md_index].mr_start;
2684                         md.md_size = pregions[md.md_index].mr_size;
2685                         md.md_vaddr = ~0UL;
2686                         md.md_index++;
2687                 } else {
2688                         /* There's no next physical chunk. */
2689                         return (NULL);
2690                 }
2691         }
2692
2693         return (&md);
2694 }