pmap.c revision 1.16 1 /* $NetBSD: pmap.c,v 1.16 2003/10/27 23:35:41 kleink Exp $ */
2 /*-
3 * Copyright (c) 2001 The NetBSD Foundation, Inc.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Matt Thomas <matt (at) 3am-software.com> of Allegro Networks, Inc.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by the NetBSD
20 * Foundation, Inc. and its contributors.
21 * 4. Neither the name of The NetBSD Foundation nor the names of its
22 * contributors may be used to endorse or promote products derived
23 * from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 /*
39 * Copyright (C) 1995, 1996 Wolfgang Solfrank.
40 * Copyright (C) 1995, 1996 TooLs GmbH.
41 * All rights reserved.
42 *
43 * Redistribution and use in source and binary forms, with or without
44 * modification, are permitted provided that the following conditions
45 * are met:
46 * 1. Redistributions of source code must retain the above copyright
47 * notice, this list of conditions and the following disclaimer.
48 * 2. Redistributions in binary form must reproduce the above copyright
49 * notice, this list of conditions and the following disclaimer in the
50 * documentation and/or other materials provided with the distribution.
51 * 3. All advertising materials mentioning features or use of this software
52 * must display the following acknowledgement:
53 * This product includes software developed by TooLs GmbH.
54 * 4. The name of TooLs GmbH may not be used to endorse or promote products
55 * derived from this software without specific prior written permission.
56 *
57 * THIS SOFTWARE IS PROVIDED BY TOOLS GMBH ``AS IS'' AND ANY EXPRESS OR
58 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
59 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
60 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
61 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
62 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
63 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
64 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
65 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
66 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
67 */
68
69 #include <sys/cdefs.h>
70 __KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.16 2003/10/27 23:35:41 kleink Exp $");
71
72 #include "opt_altivec.h"
73 #include "opt_pmap.h"
74 #include <sys/param.h>
75 #include <sys/malloc.h>
76 #include <sys/proc.h>
77 #include <sys/user.h>
78 #include <sys/pool.h>
79 #include <sys/queue.h>
80 #include <sys/device.h> /* for evcnt */
81 #include <sys/systm.h>
82
83 #if __NetBSD_Version__ < 105010000
84 #include <vm/vm.h>
85 #include <vm/vm_kern.h>
86 #define splvm() splimp()
87 #endif
88
89 #include <uvm/uvm.h>
90
91 #include <machine/pcb.h>
92 #include <machine/powerpc.h>
93 #include <powerpc/spr.h>
94 #include <powerpc/oea/sr_601.h>
95 #if __NetBSD_Version__ > 105010000
96 #include <powerpc/oea/bat.h>
97 #else
98 #include <powerpc/bat.h>
99 #endif
100
101 #if defined(DEBUG) || defined(PMAPCHECK)
102 #define STATIC
103 #else
104 #define STATIC static
105 #endif
106
107 #ifdef ALTIVEC
108 int pmap_use_altivec;
109 #endif
110
111 volatile struct pteg *pmap_pteg_table;
112 unsigned int pmap_pteg_cnt;
113 unsigned int pmap_pteg_mask;
114 paddr_t pmap_memlimit = -PAGE_SIZE; /* there is no limit */
115
116 struct pmap kernel_pmap_;
117 unsigned int pmap_pages_stolen;
118 u_long pmap_pte_valid;
119 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
120 u_long pmap_pvo_enter_depth;
121 u_long pmap_pvo_remove_depth;
122 #endif
123
124 int physmem;
125 #ifndef MSGBUFADDR
126 extern paddr_t msgbuf_paddr;
127 #endif
128
129 static struct mem_region *mem, *avail;
130 static u_int mem_cnt, avail_cnt;
131
132 #ifdef __HAVE_PMAP_PHYSSEG
133 /*
134 * This is a cache of referenced/modified bits.
135 * Bits herein are shifted by ATTRSHFT.
136 */
137 #define ATTR_SHFT 4
138 struct pmap_physseg pmap_physseg;
139 #endif
140
141 /*
142 * The following structure is exactly 32 bytes long (one cacheline).
143 */
144 struct pvo_entry {
145 LIST_ENTRY(pvo_entry) pvo_vlink; /* Link to common virt page */
146 TAILQ_ENTRY(pvo_entry) pvo_olink; /* Link to overflow entry */
147 struct pte pvo_pte; /* Prebuilt PTE */
148 pmap_t pvo_pmap; /* ptr to owning pmap */
149 vaddr_t pvo_vaddr; /* VA of entry */
150 #define PVO_PTEGIDX_MASK 0x0007 /* which PTEG slot */
151 #define PVO_PTEGIDX_VALID 0x0008 /* slot is valid */
152 #define PVO_WIRED 0x0010 /* PVO entry is wired */
153 #define PVO_MANAGED 0x0020 /* PVO e. for managed page */
154 #define PVO_EXECUTABLE 0x0040 /* PVO e. for executable page */
155 #define PVO_ENTER_INSERT 0 /* PVO has been removed */
156 #define PVO_SPILL_UNSET 1 /* PVO has been evicted */
157 #define PVO_SPILL_SET 2 /* PVO has been spilled */
158 #define PVO_SPILL_INSERT 3 /* PVO has been inserted */
159 #define PVO_PMAP_PAGE_PROTECT 4 /* PVO has changed */
160 #define PVO_PMAP_PROTECT 5 /* PVO has changed */
161 #define PVO_REMOVE 6 /* PVO has been removed */
162 #define PVO_WHERE_MASK 15
163 #define PVO_WHERE_SHFT 8
164 };
165 #define PVO_VADDR(pvo) ((pvo)->pvo_vaddr & ~ADDR_POFF)
166 #define PVO_ISEXECUTABLE(pvo) ((pvo)->pvo_vaddr & PVO_EXECUTABLE)
167 #define PVO_PTEGIDX_GET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_MASK)
168 #define PVO_PTEGIDX_ISSET(pvo) ((pvo)->pvo_vaddr & PVO_PTEGIDX_VALID)
169 #define PVO_PTEGIDX_CLR(pvo) \
170 ((void)((pvo)->pvo_vaddr &= ~(PVO_PTEGIDX_VALID|PVO_PTEGIDX_MASK)))
171 #define PVO_PTEGIDX_SET(pvo,i) \
172 ((void)((pvo)->pvo_vaddr |= (i)|PVO_PTEGIDX_VALID))
173 #define PVO_WHERE(pvo,w) \
174 ((pvo)->pvo_vaddr &= ~(PVO_WHERE_MASK << PVO_WHERE_SHFT), \
175 (pvo)->pvo_vaddr |= ((PVO_ ## w) << PVO_WHERE_SHFT))
176
177 TAILQ_HEAD(pvo_tqhead, pvo_entry);
178 struct pvo_tqhead *pmap_pvo_table; /* pvo entries by ptegroup index */
179 struct pvo_head pmap_pvo_kunmanaged = LIST_HEAD_INITIALIZER(pmap_pvo_kunmanaged); /* list of unmanaged pages */
180 struct pvo_head pmap_pvo_unmanaged = LIST_HEAD_INITIALIZER(pmap_pvo_unmanaged); /* list of unmanaged pages */
181
182 struct pool pmap_pool; /* pool for pmap structures */
183 struct pool pmap_upvo_pool; /* pool for pvo entries for unmanaged pages */
184 struct pool pmap_mpvo_pool; /* pool for pvo entries for managed pages */
185
186 /*
187 * We keep a cache of unmanaged pages to be used for pvo entries for
188 * unmanaged pages.
189 */
190 struct pvo_page {
191 SIMPLEQ_ENTRY(pvo_page) pvop_link;
192 };
193 SIMPLEQ_HEAD(pvop_head, pvo_page);
194 struct pvop_head pmap_upvop_head = SIMPLEQ_HEAD_INITIALIZER(pmap_upvop_head);
195 struct pvop_head pmap_mpvop_head = SIMPLEQ_HEAD_INITIALIZER(pmap_mpvop_head);
196 u_long pmap_upvop_free;
197 u_long pmap_upvop_maxfree;
198 u_long pmap_mpvop_free;
199 u_long pmap_mpvop_maxfree;
200
201 STATIC void *pmap_pool_ualloc(struct pool *, int);
202 STATIC void *pmap_pool_malloc(struct pool *, int);
203
204 STATIC void pmap_pool_ufree(struct pool *, void *);
205 STATIC void pmap_pool_mfree(struct pool *, void *);
206
207 static struct pool_allocator pmap_pool_mallocator = {
208 pmap_pool_malloc, pmap_pool_mfree, 0,
209 };
210
211 static struct pool_allocator pmap_pool_uallocator = {
212 pmap_pool_ualloc, pmap_pool_ufree, 0,
213 };
214
215 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB)
216 void pmap_pte_print(volatile struct pte *);
217 #endif
218
219 #ifdef DDB
220 void pmap_pteg_check(void);
221 void pmap_pteg_dist(void);
222 void pmap_print_pte(pmap_t, vaddr_t);
223 void pmap_print_mmuregs(void);
224 #endif
225
226 #if defined(DEBUG) || defined(PMAPCHECK)
227 #ifdef PMAPCHECK
228 int pmapcheck = 1;
229 #else
230 int pmapcheck = 0;
231 #endif
232 void pmap_pvo_verify(void);
233 STATIC void pmap_pvo_check(const struct pvo_entry *);
234 #define PMAP_PVO_CHECK(pvo) \
235 do { \
236 if (pmapcheck) \
237 pmap_pvo_check(pvo); \
238 } while (0)
239 #else
240 #define PMAP_PVO_CHECK(pvo) do { } while (/*CONSTCOND*/0)
241 #endif
242 STATIC int pmap_pte_insert(int, struct pte *);
243 STATIC int pmap_pvo_enter(pmap_t, struct pool *, struct pvo_head *,
244 vaddr_t, paddr_t, register_t, int);
245 STATIC void pmap_pvo_remove(struct pvo_entry *, int);
246 STATIC struct pvo_entry *pmap_pvo_find_va(pmap_t, vaddr_t, int *);
247 STATIC volatile struct pte *pmap_pvo_to_pte(const struct pvo_entry *, int);
248 #define pmap_pvo_reclaim(pm) NULL
249 STATIC void pvo_set_exec(struct pvo_entry *);
250 STATIC void pvo_clear_exec(struct pvo_entry *);
251
252 STATIC void tlbia(void);
253
254 STATIC void pmap_release(pmap_t);
255 STATIC void *pmap_boot_find_memory(psize_t, psize_t, int);
256
257 #define VSID_NBPW (sizeof(uint32_t) * 8)
258 static uint32_t pmap_vsid_bitmap[NPMAPS / VSID_NBPW];
259
260 static int pmap_initialized;
261
262 #if defined(DEBUG) || defined(PMAPDEBUG)
263 #define PMAPDEBUG_BOOT 0x0001
264 #define PMAPDEBUG_PTE 0x0002
265 #define PMAPDEBUG_EXEC 0x0008
266 #define PMAPDEBUG_PVOENTER 0x0010
267 #define PMAPDEBUG_PVOREMOVE 0x0020
268 #define PMAPDEBUG_ACTIVATE 0x0100
269 #define PMAPDEBUG_CREATE 0x0200
270 #define PMAPDEBUG_ENTER 0x1000
271 #define PMAPDEBUG_KENTER 0x2000
272 #define PMAPDEBUG_KREMOVE 0x4000
273 #define PMAPDEBUG_REMOVE 0x8000
274 unsigned int pmapdebug = 0;
275 # define DPRINTF(x) printf x
276 # define DPRINTFN(n, x) if (pmapdebug & PMAPDEBUG_ ## n) printf x
277 #else
278 # define DPRINTF(x)
279 # define DPRINTFN(n, x)
280 #endif
281
282
283 #ifdef PMAPCOUNTERS
284 #define PMAPCOUNT(ev) ((pmap_evcnt_ ## ev).ev_count++)
285 #define PMAPCOUNT2(ev) ((ev).ev_count++)
286
287 struct evcnt pmap_evcnt_mappings =
288 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
289 "pmap", "pages mapped");
290 struct evcnt pmap_evcnt_unmappings =
291 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &pmap_evcnt_mappings,
292 "pmap", "pages unmapped");
293
294 struct evcnt pmap_evcnt_kernel_mappings =
295 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
296 "pmap", "kernel pages mapped");
297 struct evcnt pmap_evcnt_kernel_unmappings =
298 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &pmap_evcnt_kernel_mappings,
299 "pmap", "kernel pages unmapped");
300
301 struct evcnt pmap_evcnt_mappings_replaced =
302 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
303 "pmap", "page mappings replaced");
304
305 struct evcnt pmap_evcnt_exec_mappings =
306 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &pmap_evcnt_mappings,
307 "pmap", "exec pages mapped");
308 struct evcnt pmap_evcnt_exec_cached =
309 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &pmap_evcnt_mappings,
310 "pmap", "exec pages cached");
311
312 struct evcnt pmap_evcnt_exec_synced =
313 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &pmap_evcnt_exec_mappings,
314 "pmap", "exec pages synced");
315 struct evcnt pmap_evcnt_exec_synced_clear_modify =
316 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &pmap_evcnt_exec_mappings,
317 "pmap", "exec pages synced (CM)");
318
319 struct evcnt pmap_evcnt_exec_uncached_page_protect =
320 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &pmap_evcnt_exec_mappings,
321 "pmap", "exec pages uncached (PP)");
322 struct evcnt pmap_evcnt_exec_uncached_clear_modify =
323 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &pmap_evcnt_exec_mappings,
324 "pmap", "exec pages uncached (CM)");
325 struct evcnt pmap_evcnt_exec_uncached_zero_page =
326 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &pmap_evcnt_exec_mappings,
327 "pmap", "exec pages uncached (ZP)");
328 struct evcnt pmap_evcnt_exec_uncached_copy_page =
329 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, &pmap_evcnt_exec_mappings,
330 "pmap", "exec pages uncached (CP)");
331
332 struct evcnt pmap_evcnt_updates =
333 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
334 "pmap", "updates");
335 struct evcnt pmap_evcnt_collects =
336 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
337 "pmap", "collects");
338 struct evcnt pmap_evcnt_copies =
339 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
340 "pmap", "copies");
341
342 struct evcnt pmap_evcnt_ptes_spilled =
343 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
344 "pmap", "ptes spilled from overflow");
345 struct evcnt pmap_evcnt_ptes_unspilled =
346 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
347 "pmap", "ptes not spilled");
348 struct evcnt pmap_evcnt_ptes_evicted =
349 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
350 "pmap", "ptes evicted");
351
352 struct evcnt pmap_evcnt_ptes_primary[8] = {
353 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
354 "pmap", "ptes added at primary[0]"),
355 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
356 "pmap", "ptes added at primary[1]"),
357 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
358 "pmap", "ptes added at primary[2]"),
359 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
360 "pmap", "ptes added at primary[3]"),
361
362 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
363 "pmap", "ptes added at primary[4]"),
364 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
365 "pmap", "ptes added at primary[5]"),
366 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
367 "pmap", "ptes added at primary[6]"),
368 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
369 "pmap", "ptes added at primary[7]"),
370 };
371 struct evcnt pmap_evcnt_ptes_secondary[8] = {
372 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
373 "pmap", "ptes added at secondary[0]"),
374 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
375 "pmap", "ptes added at secondary[1]"),
376 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
377 "pmap", "ptes added at secondary[2]"),
378 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
379 "pmap", "ptes added at secondary[3]"),
380
381 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
382 "pmap", "ptes added at secondary[4]"),
383 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
384 "pmap", "ptes added at secondary[5]"),
385 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
386 "pmap", "ptes added at secondary[6]"),
387 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
388 "pmap", "ptes added at secondary[7]"),
389 };
390 struct evcnt pmap_evcnt_ptes_removed =
391 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
392 "pmap", "ptes removed");
393 struct evcnt pmap_evcnt_ptes_changed =
394 EVCNT_INITIALIZER(EVCNT_TYPE_MISC, NULL,
395 "pmap", "ptes changed");
396
397 /*
398 * From pmap_subr.c
399 */
400 extern struct evcnt pmap_evcnt_zeroed_pages;
401 extern struct evcnt pmap_evcnt_copied_pages;
402 extern struct evcnt pmap_evcnt_idlezeroed_pages;
403 #else
404 #define PMAPCOUNT(ev) ((void) 0)
405 #define PMAPCOUNT2(ev) ((void) 0)
406 #endif
407
408 #define TLBIE(va) __asm __volatile("tlbie %0" :: "r"(va))
409 #define TLBSYNC() __asm __volatile("tlbsync")
410 #define SYNC() __asm __volatile("sync")
411 #define EIEIO() __asm __volatile("eieio")
412 #define MFMSR() mfmsr()
413 #define MTMSR(psl) mtmsr(psl)
414 #define MFPVR() mfpvr()
415 #define MFSRIN(va) mfsrin(va)
416 #define MFTB() mfrtcltbl()
417
418 static __inline register_t
419 mfsrin(vaddr_t va)
420 {
421 register_t sr;
422 __asm __volatile ("mfsrin %0,%1" : "=r"(sr) : "r"(va));
423 return sr;
424 }
425
426 static __inline register_t
427 pmap_interrupts_off(void)
428 {
429 register_t msr = MFMSR();
430 if (msr & PSL_EE)
431 MTMSR(msr & ~PSL_EE);
432 return msr;
433 }
434
435 static void
436 pmap_interrupts_restore(register_t msr)
437 {
438 if (msr & PSL_EE)
439 MTMSR(msr);
440 }
441
442 static __inline u_int32_t
443 mfrtcltbl(void)
444 {
445
446 if ((MFPVR() >> 16) == MPC601)
447 return (mfrtcl() >> 7);
448 else
449 return (mftbl());
450 }
451
452 /*
453 * These small routines may have to be replaced,
454 * if/when we support processors other that the 604.
455 */
456
457 void
458 tlbia(void)
459 {
460 caddr_t i;
461
462 SYNC();
463 /*
464 * Why not use "tlbia"? Because not all processors implement it.
465 *
466 * This needs to be a per-cpu callback to do the appropriate thing
467 * for the CPU. XXX
468 */
469 for (i = 0; i < (caddr_t)0x00040000; i += 0x00001000) {
470 TLBIE(i);
471 EIEIO();
472 SYNC();
473 }
474 TLBSYNC();
475 SYNC();
476 }
477
478 static __inline register_t
479 va_to_vsid(const struct pmap *pm, vaddr_t addr)
480 {
481 return (pm->pm_sr[addr >> ADDR_SR_SHFT] & SR_VSID);
482 }
483
484 static __inline register_t
485 va_to_pteg(const struct pmap *pm, vaddr_t addr)
486 {
487 register_t hash;
488
489 hash = va_to_vsid(pm, addr) ^ ((addr & ADDR_PIDX) >> ADDR_PIDX_SHFT);
490 return hash & pmap_pteg_mask;
491 }
492
493 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB)
494 /*
495 * Given a PTE in the page table, calculate the VADDR that hashes to it.
496 * The only bit of magic is that the top 4 bits of the address doesn't
497 * technically exist in the PTE. But we know we reserved 4 bits of the
498 * VSID for it so that's how we get it.
499 */
500 static vaddr_t
501 pmap_pte_to_va(volatile const struct pte *pt)
502 {
503 vaddr_t va;
504 uintptr_t ptaddr = (uintptr_t) pt;
505
506 if (pt->pte_hi & PTE_HID)
507 ptaddr ^= (pmap_pteg_mask * sizeof(struct pteg));
508
509 /* PPC Bits 10-19 */
510 va = ((pt->pte_hi >> PTE_VSID_SHFT) ^ (ptaddr / sizeof(struct pteg))) & 0x3ff;
511 va <<= ADDR_PIDX_SHFT;
512
513 /* PPC Bits 4-9 */
514 va |= (pt->pte_hi & PTE_API) << ADDR_API_SHFT;
515
516 /* PPC Bits 0-3 */
517 va |= VSID_TO_SR(pt->pte_hi >> PTE_VSID_SHFT) << ADDR_SR_SHFT;
518
519 return va;
520 }
521 #endif
522
523 static __inline struct pvo_head *
524 pa_to_pvoh(paddr_t pa, struct vm_page **pg_p)
525 {
526 #ifdef __HAVE_VM_PAGE_MD
527 struct vm_page *pg;
528
529 pg = PHYS_TO_VM_PAGE(pa);
530 if (pg_p != NULL)
531 *pg_p = pg;
532 if (pg == NULL)
533 return &pmap_pvo_unmanaged;
534 return &pg->mdpage.mdpg_pvoh;
535 #endif
536 #ifdef __HAVE_PMAP_PHYSSEG
537 int bank, pg;
538
539 bank = vm_physseg_find(atop(pa), &pg);
540 if (pg_p != NULL)
541 *pg_p = pg;
542 if (bank == -1)
543 return &pmap_pvo_unmanaged;
544 return &vm_physmem[bank].pmseg.pvoh[pg];
545 #endif
546 }
547
548 static __inline struct pvo_head *
549 vm_page_to_pvoh(struct vm_page *pg)
550 {
551 #ifdef __HAVE_VM_PAGE_MD
552 return &pg->mdpage.mdpg_pvoh;
553 #endif
554 #ifdef __HAVE_PMAP_PHYSSEG
555 return pa_to_pvoh(VM_PAGE_TO_PHYS(pg), NULL);
556 #endif
557 }
558
559
560 #ifdef __HAVE_PMAP_PHYSSEG
561 static __inline char *
562 pa_to_attr(paddr_t pa)
563 {
564 int bank, pg;
565
566 bank = vm_physseg_find(atop(pa), &pg);
567 if (bank == -1)
568 return NULL;
569 return &vm_physmem[bank].pmseg.attrs[pg];
570 }
571 #endif
572
573 static __inline void
574 pmap_attr_clear(struct vm_page *pg, int ptebit)
575 {
576 #ifdef __HAVE_PMAP_PHYSSEG
577 *pa_to_attr(VM_PAGE_TO_PHYS(pg)) &= ~(ptebit >> ATTR_SHFT);
578 #endif
579 #ifdef __HAVE_VM_PAGE_MD
580 pg->mdpage.mdpg_attrs &= ~ptebit;
581 #endif
582 }
583
584 static __inline int
585 pmap_attr_fetch(struct vm_page *pg)
586 {
587 #ifdef __HAVE_PMAP_PHYSSEG
588 return *pa_to_attr(VM_PAGE_TO_PHYS(pg)) << ATTR_SHFT;
589 #endif
590 #ifdef __HAVE_VM_PAGE_MD
591 return pg->mdpage.mdpg_attrs;
592 #endif
593 }
594
595 static __inline void
596 pmap_attr_save(struct vm_page *pg, int ptebit)
597 {
598 #ifdef __HAVE_PMAP_PHYSSEG
599 *pa_to_attr(VM_PAGE_TO_PHYS(pg)) |= (ptebit >> ATTR_SHFT);
600 #endif
601 #ifdef __HAVE_VM_PAGE_MD
602 pg->mdpage.mdpg_attrs |= ptebit;
603 #endif
604 }
605
606 static __inline int
607 pmap_pte_compare(const volatile struct pte *pt, const struct pte *pvo_pt)
608 {
609 if (pt->pte_hi == pvo_pt->pte_hi
610 #if 0
611 && ((pt->pte_lo ^ pvo_pt->pte_lo) &
612 ~(PTE_REF|PTE_CHG)) == 0
613 #endif
614 )
615 return 1;
616 return 0;
617 }
618
619 static __inline void
620 pmap_pte_create(struct pte *pt, const struct pmap *pm, vaddr_t va, register_t pte_lo)
621 {
622 /*
623 * Construct the PTE. Default to IMB initially. Valid bit
624 * only gets set when the real pte is set in memory.
625 *
626 * Note: Don't set the valid bit for correct operation of tlb update.
627 */
628 pt->pte_hi = (va_to_vsid(pm, va) << PTE_VSID_SHFT)
629 | (((va & ADDR_PIDX) >> (ADDR_API_SHFT - PTE_API_SHFT)) & PTE_API);
630 pt->pte_lo = pte_lo;
631 }
632
633 static __inline void
634 pmap_pte_synch(volatile struct pte *pt, struct pte *pvo_pt)
635 {
636 pvo_pt->pte_lo |= pt->pte_lo & (PTE_REF|PTE_CHG);
637 }
638
639 static __inline void
640 pmap_pte_clear(volatile struct pte *pt, vaddr_t va, int ptebit)
641 {
642 /*
643 * As shown in Section 7.6.3.2.3
644 */
645 pt->pte_lo &= ~ptebit;
646 TLBIE(va);
647 SYNC();
648 EIEIO();
649 TLBSYNC();
650 SYNC();
651 }
652
653 static __inline void
654 pmap_pte_set(volatile struct pte *pt, struct pte *pvo_pt)
655 {
656 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
657 if (pvo_pt->pte_hi & PTE_VALID)
658 panic("pte_set: setting an already valid pte %p", pvo_pt);
659 #endif
660 pvo_pt->pte_hi |= PTE_VALID;
661 /*
662 * Update the PTE as defined in section 7.6.3.1
663 * Note that the REF/CHG bits are from pvo_pt and thus should
664 * have been saved so this routine can restore them (if desired).
665 */
666 pt->pte_lo = pvo_pt->pte_lo;
667 EIEIO();
668 pt->pte_hi = pvo_pt->pte_hi;
669 SYNC();
670 pmap_pte_valid++;
671 }
672
673 static __inline void
674 pmap_pte_unset(volatile struct pte *pt, struct pte *pvo_pt, vaddr_t va)
675 {
676 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
677 if ((pvo_pt->pte_hi & PTE_VALID) == 0)
678 panic("pte_unset: attempt to unset an inactive pte#1 %p/%p", pvo_pt, pt);
679 if ((pt->pte_hi & PTE_VALID) == 0)
680 panic("pte_unset: attempt to unset an inactive pte#2 %p/%p", pvo_pt, pt);
681 #endif
682
683 pvo_pt->pte_hi &= ~PTE_VALID;
684 /*
685 * Force the ref & chg bits back into the PTEs.
686 */
687 SYNC();
688 /*
689 * Invalidate the pte ... (Section 7.6.3.3)
690 */
691 pt->pte_hi &= ~PTE_VALID;
692 SYNC();
693 TLBIE(va);
694 SYNC();
695 EIEIO();
696 TLBSYNC();
697 SYNC();
698 /*
699 * Save the ref & chg bits ...
700 */
701 pmap_pte_synch(pt, pvo_pt);
702 pmap_pte_valid--;
703 }
704
705 static __inline void
706 pmap_pte_change(volatile struct pte *pt, struct pte *pvo_pt, vaddr_t va)
707 {
708 /*
709 * Invalidate the PTE
710 */
711 pmap_pte_unset(pt, pvo_pt, va);
712 pmap_pte_set(pt, pvo_pt);
713 }
714
715 /*
716 * Try to insert the PTE @ *pvo_pt into the pmap_pteg_table at ptegidx
717 * (either primary or secondary location).
718 *
719 * Note: both the destination and source PTEs must not have PTE_VALID set.
720 */
721
722 STATIC int
723 pmap_pte_insert(int ptegidx, struct pte *pvo_pt)
724 {
725 volatile struct pte *pt;
726 int i;
727
728 #if defined(DEBUG)
729 DPRINTFN(PTE, ("pmap_pte_insert: idx 0x%x, pte 0x%lx 0x%lx\n",
730 ptegidx, pvo_pt->pte_hi, pvo_pt->pte_lo));
731 #endif
732 /*
733 * First try primary hash.
734 */
735 for (pt = pmap_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
736 if ((pt->pte_hi & PTE_VALID) == 0) {
737 pvo_pt->pte_hi &= ~PTE_HID;
738 pmap_pte_set(pt, pvo_pt);
739 return i;
740 }
741 }
742
743 /*
744 * Now try secondary hash.
745 */
746 ptegidx ^= pmap_pteg_mask;
747 for (pt = pmap_pteg_table[ptegidx].pt, i = 0; i < 8; i++, pt++) {
748 if ((pt->pte_hi & PTE_VALID) == 0) {
749 pvo_pt->pte_hi |= PTE_HID;
750 pmap_pte_set(pt, pvo_pt);
751 return i;
752 }
753 }
754 return -1;
755 }
756
757 /*
758 * Spill handler.
759 *
760 * Tries to spill a page table entry from the overflow area.
761 * This runs in either real mode (if dealing with a exception spill)
762 * or virtual mode when dealing with manually spilling one of the
763 * kernel's pte entries. In either case, interrupts are already
764 * disabled.
765 */
766
767 int
768 pmap_pte_spill(struct pmap *pm, vaddr_t addr, boolean_t exec)
769 {
770 struct pvo_entry *source_pvo, *victim_pvo, *next_pvo;
771 struct pvo_entry *pvo;
772 /* XXX: gcc -- vpvoh is always set at either *1* or *2* */
773 struct pvo_tqhead *pvoh, *vpvoh = NULL;
774 int ptegidx, i, j;
775 volatile struct pteg *pteg;
776 volatile struct pte *pt;
777
778 ptegidx = va_to_pteg(pm, addr);
779
780 /*
781 * Have to substitute some entry. Use the primary hash for this.
782 * Use low bits of timebase as random generator. Make sure we are
783 * not picking a kernel pte for replacement.
784 */
785 pteg = &pmap_pteg_table[ptegidx];
786 i = MFTB() & 7;
787 for (j = 0; j < 8; j++) {
788 pt = &pteg->pt[i];
789 if ((pt->pte_hi & PTE_VALID) == 0 ||
790 VSID_TO_HASH((pt->pte_hi & PTE_VSID) >> PTE_VSID_SHFT)
791 != KERNEL_VSIDBITS)
792 break;
793 i = (i + 1) & 7;
794 }
795 KASSERT(j < 8);
796
797 source_pvo = NULL;
798 victim_pvo = NULL;
799 pvoh = &pmap_pvo_table[ptegidx];
800 TAILQ_FOREACH(pvo, pvoh, pvo_olink) {
801
802 /*
803 * We need to find pvo entry for this address...
804 */
805 PMAP_PVO_CHECK(pvo); /* sanity check */
806
807 /*
808 * If we haven't found the source and we come to a PVO with
809 * a valid PTE, then we know we can't find it because all
810 * evicted PVOs always are first in the list.
811 */
812 if (source_pvo == NULL && (pvo->pvo_pte.pte_hi & PTE_VALID))
813 break;
814 if (source_pvo == NULL && pm == pvo->pvo_pmap &&
815 addr == PVO_VADDR(pvo)) {
816
817 /*
818 * Now we have found the entry to be spilled into the
819 * pteg. Attempt to insert it into the page table.
820 */
821 j = pmap_pte_insert(ptegidx, &pvo->pvo_pte);
822 if (j >= 0) {
823 PVO_PTEGIDX_SET(pvo, j);
824 PMAP_PVO_CHECK(pvo); /* sanity check */
825 PVO_WHERE(pvo, SPILL_INSERT);
826 pvo->pvo_pmap->pm_evictions--;
827 PMAPCOUNT(ptes_spilled);
828 PMAPCOUNT2(((pvo->pvo_pte.pte_hi & PTE_HID)
829 ? pmap_evcnt_ptes_secondary
830 : pmap_evcnt_ptes_primary)[j]);
831
832 /*
833 * Since we keep the evicted entries at the
834 * from of the PVO list, we need move this
835 * (now resident) PVO after the evicted
836 * entries.
837 */
838 next_pvo = TAILQ_NEXT(pvo, pvo_olink);
839
840 /*
841 * If we don't have to move (either we were the
842 * last entry or the next entry was valid),
843 * don't change our position. Otherwise
844 * move ourselves to the tail of the queue.
845 */
846 if (next_pvo != NULL &&
847 !(next_pvo->pvo_pte.pte_hi & PTE_VALID)) {
848 TAILQ_REMOVE(pvoh, pvo, pvo_olink);
849 TAILQ_INSERT_TAIL(pvoh, pvo, pvo_olink);
850 }
851 return 1;
852 }
853 source_pvo = pvo;
854 if (exec && !PVO_ISEXECUTABLE(source_pvo)) {
855 return 0;
856 }
857 if (victim_pvo != NULL)
858 break;
859 }
860
861 /*
862 * We also need the pvo entry of the victim we are replacing
863 * so save the R & C bits of the PTE.
864 */
865 if ((pt->pte_hi & PTE_HID) == 0 && victim_pvo == NULL &&
866 pmap_pte_compare(pt, &pvo->pvo_pte)) {
867 vpvoh = pvoh; /* *1* */
868 victim_pvo = pvo;
869 if (source_pvo != NULL)
870 break;
871 }
872 }
873
874 if (source_pvo == NULL) {
875 PMAPCOUNT(ptes_unspilled);
876 return 0;
877 }
878
879 if (victim_pvo == NULL) {
880 if ((pt->pte_hi & PTE_HID) == 0)
881 panic("pmap_pte_spill: victim p-pte (%p) has "
882 "no pvo entry!", pt);
883
884 /*
885 * If this is a secondary PTE, we need to search
886 * its primary pvo bucket for the matching PVO.
887 */
888 vpvoh = &pmap_pvo_table[ptegidx ^ pmap_pteg_mask]; /* *2* */
889 TAILQ_FOREACH(pvo, vpvoh, pvo_olink) {
890 PMAP_PVO_CHECK(pvo); /* sanity check */
891
892 /*
893 * We also need the pvo entry of the victim we are
894 * replacing so save the R & C bits of the PTE.
895 */
896 if (pmap_pte_compare(pt, &pvo->pvo_pte)) {
897 victim_pvo = pvo;
898 break;
899 }
900 }
901 if (victim_pvo == NULL)
902 panic("pmap_pte_spill: victim s-pte (%p) has "
903 "no pvo entry!", pt);
904 }
905
906 /*
907 * The victim should be not be a kernel PVO/PTE entry.
908 */
909 KASSERT(victim_pvo->pvo_pmap != pmap_kernel());
910 KASSERT(PVO_PTEGIDX_ISSET(victim_pvo));
911 KASSERT(PVO_PTEGIDX_GET(victim_pvo) == i);
912
913 /*
914 * We are invalidating the TLB entry for the EA for the
915 * we are replacing even though its valid; If we don't
916 * we lose any ref/chg bit changes contained in the TLB
917 * entry.
918 */
919 source_pvo->pvo_pte.pte_hi &= ~PTE_HID;
920
921 /*
922 * To enforce the PVO list ordering constraint that all
923 * evicted entries should come before all valid entries,
924 * move the source PVO to the tail of its list and the
925 * victim PVO to the head of its list (which might not be
926 * the same list, if the victim was using the secondary hash).
927 */
928 TAILQ_REMOVE(pvoh, source_pvo, pvo_olink);
929 TAILQ_INSERT_TAIL(pvoh, source_pvo, pvo_olink);
930 TAILQ_REMOVE(vpvoh, victim_pvo, pvo_olink);
931 TAILQ_INSERT_HEAD(vpvoh, victim_pvo, pvo_olink);
932 pmap_pte_unset(pt, &victim_pvo->pvo_pte, victim_pvo->pvo_vaddr);
933 pmap_pte_set(pt, &source_pvo->pvo_pte);
934 victim_pvo->pvo_pmap->pm_evictions++;
935 source_pvo->pvo_pmap->pm_evictions--;
936 PVO_WHERE(victim_pvo, SPILL_UNSET);
937 PVO_WHERE(source_pvo, SPILL_SET);
938
939 PVO_PTEGIDX_CLR(victim_pvo);
940 PVO_PTEGIDX_SET(source_pvo, i);
941 PMAPCOUNT2(pmap_evcnt_ptes_primary[i]);
942 PMAPCOUNT(ptes_spilled);
943 PMAPCOUNT(ptes_evicted);
944 PMAPCOUNT(ptes_removed);
945
946 PMAP_PVO_CHECK(victim_pvo);
947 PMAP_PVO_CHECK(source_pvo);
948 return 1;
949 }
950
951 /*
952 * Restrict given range to physical memory
953 */
954 void
955 pmap_real_memory(paddr_t *start, psize_t *size)
956 {
957 struct mem_region *mp;
958
959 for (mp = mem; mp->size; mp++) {
960 if (*start + *size > mp->start
961 && *start < mp->start + mp->size) {
962 if (*start < mp->start) {
963 *size -= mp->start - *start;
964 *start = mp->start;
965 }
966 if (*start + *size > mp->start + mp->size)
967 *size = mp->start + mp->size - *start;
968 return;
969 }
970 }
971 *size = 0;
972 }
973
974 /*
975 * Initialize anything else for pmap handling.
976 * Called during vm_init().
977 */
978 void
979 pmap_init(void)
980 {
981 #ifdef __HAVE_PMAP_PHYSSEG
982 struct pvo_tqhead *pvoh;
983 int bank;
984 long sz;
985 char *attr;
986
987 pvoh = pmap_physseg.pvoh;
988 attr = pmap_physseg.attrs;
989 for (bank = 0; bank < vm_nphysseg; bank++) {
990 sz = vm_physmem[bank].end - vm_physmem[bank].start;
991 vm_physmem[bank].pmseg.pvoh = pvoh;
992 vm_physmem[bank].pmseg.attrs = attr;
993 for (; sz > 0; sz--, pvoh++, attr++) {
994 TAILQ_INIT(pvoh);
995 *attr = 0;
996 }
997 }
998 #endif
999
1000 pool_init(&pmap_mpvo_pool, sizeof(struct pvo_entry),
1001 sizeof(struct pvo_entry), 0, 0, "pmap_mpvopl",
1002 &pmap_pool_mallocator);
1003
1004 pool_setlowat(&pmap_mpvo_pool, 1008);
1005
1006 pmap_initialized = 1;
1007
1008 #ifdef PMAPCOUNTERS
1009 evcnt_attach_static(&pmap_evcnt_mappings);
1010 evcnt_attach_static(&pmap_evcnt_mappings_replaced);
1011 evcnt_attach_static(&pmap_evcnt_unmappings);
1012
1013 evcnt_attach_static(&pmap_evcnt_kernel_mappings);
1014 evcnt_attach_static(&pmap_evcnt_kernel_unmappings);
1015
1016 evcnt_attach_static(&pmap_evcnt_exec_mappings);
1017 evcnt_attach_static(&pmap_evcnt_exec_cached);
1018 evcnt_attach_static(&pmap_evcnt_exec_synced);
1019 evcnt_attach_static(&pmap_evcnt_exec_synced_clear_modify);
1020
1021 evcnt_attach_static(&pmap_evcnt_exec_uncached_page_protect);
1022 evcnt_attach_static(&pmap_evcnt_exec_uncached_clear_modify);
1023 evcnt_attach_static(&pmap_evcnt_exec_uncached_zero_page);
1024 evcnt_attach_static(&pmap_evcnt_exec_uncached_copy_page);
1025
1026 evcnt_attach_static(&pmap_evcnt_zeroed_pages);
1027 evcnt_attach_static(&pmap_evcnt_copied_pages);
1028 evcnt_attach_static(&pmap_evcnt_idlezeroed_pages);
1029
1030 evcnt_attach_static(&pmap_evcnt_updates);
1031 evcnt_attach_static(&pmap_evcnt_collects);
1032 evcnt_attach_static(&pmap_evcnt_copies);
1033
1034 evcnt_attach_static(&pmap_evcnt_ptes_spilled);
1035 evcnt_attach_static(&pmap_evcnt_ptes_unspilled);
1036 evcnt_attach_static(&pmap_evcnt_ptes_evicted);
1037 evcnt_attach_static(&pmap_evcnt_ptes_removed);
1038 evcnt_attach_static(&pmap_evcnt_ptes_changed);
1039 evcnt_attach_static(&pmap_evcnt_ptes_primary[0]);
1040 evcnt_attach_static(&pmap_evcnt_ptes_primary[1]);
1041 evcnt_attach_static(&pmap_evcnt_ptes_primary[2]);
1042 evcnt_attach_static(&pmap_evcnt_ptes_primary[3]);
1043 evcnt_attach_static(&pmap_evcnt_ptes_primary[4]);
1044 evcnt_attach_static(&pmap_evcnt_ptes_primary[5]);
1045 evcnt_attach_static(&pmap_evcnt_ptes_primary[6]);
1046 evcnt_attach_static(&pmap_evcnt_ptes_primary[7]);
1047 evcnt_attach_static(&pmap_evcnt_ptes_secondary[0]);
1048 evcnt_attach_static(&pmap_evcnt_ptes_secondary[1]);
1049 evcnt_attach_static(&pmap_evcnt_ptes_secondary[2]);
1050 evcnt_attach_static(&pmap_evcnt_ptes_secondary[3]);
1051 evcnt_attach_static(&pmap_evcnt_ptes_secondary[4]);
1052 evcnt_attach_static(&pmap_evcnt_ptes_secondary[5]);
1053 evcnt_attach_static(&pmap_evcnt_ptes_secondary[6]);
1054 evcnt_attach_static(&pmap_evcnt_ptes_secondary[7]);
1055 #endif
1056 }
1057
1058 /*
1059 * How much virtual space does the kernel get?
1060 */
1061 void
1062 pmap_virtual_space(vaddr_t *start, vaddr_t *end)
1063 {
1064 /*
1065 * For now, reserve one segment (minus some overhead) for kernel
1066 * virtual memory
1067 */
1068 *start = VM_MIN_KERNEL_ADDRESS;
1069 *end = VM_MAX_KERNEL_ADDRESS;
1070 }
1071
1072 /*
1073 * Allocate, initialize, and return a new physical map.
1074 */
1075 pmap_t
1076 pmap_create(void)
1077 {
1078 pmap_t pm;
1079
1080 pm = pool_get(&pmap_pool, PR_WAITOK);
1081 memset((caddr_t)pm, 0, sizeof *pm);
1082 pmap_pinit(pm);
1083
1084 DPRINTFN(CREATE,("pmap_create: pm %p:\n"
1085 "\t%06lx %06lx %06lx %06lx %06lx %06lx %06lx %06lx\n"
1086 "\t%06lx %06lx %06lx %06lx %06lx %06lx %06lx %06lx\n", pm,
1087 pm->pm_sr[0], pm->pm_sr[1], pm->pm_sr[2], pm->pm_sr[3],
1088 pm->pm_sr[4], pm->pm_sr[5], pm->pm_sr[6], pm->pm_sr[7],
1089 pm->pm_sr[8], pm->pm_sr[9], pm->pm_sr[10], pm->pm_sr[11],
1090 pm->pm_sr[12], pm->pm_sr[13], pm->pm_sr[14], pm->pm_sr[15]));
1091 return pm;
1092 }
1093
1094 /*
1095 * Initialize a preallocated and zeroed pmap structure.
1096 */
1097 void
1098 pmap_pinit(pmap_t pm)
1099 {
1100 register_t entropy = MFTB();
1101 register_t mask;
1102 int i;
1103
1104 /*
1105 * Allocate some segment registers for this pmap.
1106 */
1107 pm->pm_refs = 1;
1108 for (i = 0; i < NPMAPS; i += VSID_NBPW) {
1109 static register_t pmap_vsidcontext;
1110 register_t hash;
1111 unsigned int n;
1112
1113 /* Create a new value by multiplying by a prime adding in
1114 * entropy from the timebase register. This is to make the
1115 * VSID more random so that the PT Hash function collides
1116 * less often. (note that the prime causes gcc to do shifts
1117 * instead of a multiply)
1118 */
1119 pmap_vsidcontext = (pmap_vsidcontext * 0x1105) + entropy;
1120 hash = pmap_vsidcontext & (NPMAPS - 1);
1121 if (hash == 0) /* 0 is special, avoid it */
1122 continue;
1123 n = hash >> 5;
1124 mask = 1L << (hash & (VSID_NBPW-1));
1125 hash = pmap_vsidcontext;
1126 if (pmap_vsid_bitmap[n] & mask) { /* collision? */
1127 /* anything free in this bucket? */
1128 if (~pmap_vsid_bitmap[n] == 0) {
1129 entropy = hash >> PTE_VSID_SHFT;
1130 continue;
1131 }
1132 i = ffs(~pmap_vsid_bitmap[n]) - 1;
1133 mask = 1L << i;
1134 hash &= ~(VSID_NBPW-1);
1135 hash |= i;
1136 }
1137 /*
1138 * Make sure clear out SR_KEY_LEN bits because we put our
1139 * our data in those bits (to identify the segment).
1140 */
1141 hash &= PTE_VSID >> (PTE_VSID_SHFT + SR_KEY_LEN);
1142 pmap_vsid_bitmap[n] |= mask;
1143 for (i = 0; i < 16; i++)
1144 pm->pm_sr[i] = VSID_MAKE(i, hash) | SR_PRKEY |
1145 SR_NOEXEC;
1146 return;
1147 }
1148 panic("pmap_pinit: out of segments");
1149 }
1150
1151 /*
1152 * Add a reference to the given pmap.
1153 */
1154 void
1155 pmap_reference(pmap_t pm)
1156 {
1157 pm->pm_refs++;
1158 }
1159
1160 /*
1161 * Retire the given pmap from service.
1162 * Should only be called if the map contains no valid mappings.
1163 */
1164 void
1165 pmap_destroy(pmap_t pm)
1166 {
1167 if (--pm->pm_refs == 0) {
1168 pmap_release(pm);
1169 pool_put(&pmap_pool, pm);
1170 }
1171 }
1172
1173 /*
1174 * Release any resources held by the given physical map.
1175 * Called when a pmap initialized by pmap_pinit is being released.
1176 */
1177 void
1178 pmap_release(pmap_t pm)
1179 {
1180 int idx, mask;
1181
1182 if (pm->pm_sr[0] == 0)
1183 panic("pmap_release");
1184 idx = VSID_TO_HASH(pm->pm_sr[0]) & (NPMAPS-1);
1185 mask = 1 << (idx % VSID_NBPW);
1186 idx /= VSID_NBPW;
1187 pmap_vsid_bitmap[idx] &= ~mask;
1188 }
1189
1190 /*
1191 * Copy the range specified by src_addr/len
1192 * from the source map to the range dst_addr/len
1193 * in the destination map.
1194 *
1195 * This routine is only advisory and need not do anything.
1196 */
1197 void
1198 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vaddr_t dst_addr,
1199 vsize_t len, vaddr_t src_addr)
1200 {
1201 PMAPCOUNT(copies);
1202 }
1203
1204 /*
1205 * Require that all active physical maps contain no
1206 * incorrect entries NOW.
1207 */
1208 void
1209 pmap_update(struct pmap *pmap)
1210 {
1211 PMAPCOUNT(updates);
1212 TLBSYNC();
1213 }
1214
1215 /*
1216 * Garbage collects the physical map system for
1217 * pages which are no longer used.
1218 * Success need not be guaranteed -- that is, there
1219 * may well be pages which are not referenced, but
1220 * others may be collected.
1221 * Called by the pageout daemon when pages are scarce.
1222 */
1223 void
1224 pmap_collect(pmap_t pm)
1225 {
1226 PMAPCOUNT(collects);
1227 }
1228
1229 static __inline int
1230 pmap_pvo_pte_index(const struct pvo_entry *pvo, int ptegidx)
1231 {
1232 int pteidx;
1233 /*
1234 * We can find the actual pte entry without searching by
1235 * grabbing the PTEG index from 3 unused bits in pte_lo[11:9]
1236 * and by noticing the HID bit.
1237 */
1238 pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo);
1239 if (pvo->pvo_pte.pte_hi & PTE_HID)
1240 pteidx ^= pmap_pteg_mask * 8;
1241 return pteidx;
1242 }
1243
1244 volatile struct pte *
1245 pmap_pvo_to_pte(const struct pvo_entry *pvo, int pteidx)
1246 {
1247 volatile struct pte *pt;
1248
1249 #if !defined(DIAGNOSTIC) && !defined(DEBUG) && !defined(PMAPCHECK)
1250 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0)
1251 return NULL;
1252 #endif
1253
1254 /*
1255 * If we haven't been supplied the ptegidx, calculate it.
1256 */
1257 if (pteidx == -1) {
1258 int ptegidx;
1259 ptegidx = va_to_pteg(pvo->pvo_pmap, pvo->pvo_vaddr);
1260 pteidx = pmap_pvo_pte_index(pvo, ptegidx);
1261 }
1262
1263 pt = &pmap_pteg_table[pteidx >> 3].pt[pteidx & 7];
1264
1265 #if !defined(DIAGNOSTIC) && !defined(DEBUG) && !defined(PMAPCHECK)
1266 return pt;
1267 #else
1268 if ((pvo->pvo_pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) {
1269 panic("pmap_pvo_to_pte: pvo %p: has valid pte in "
1270 "pvo but no valid pte index", pvo);
1271 }
1272 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) {
1273 panic("pmap_pvo_to_pte: pvo %p: has valid pte index in "
1274 "pvo but no valid pte", pvo);
1275 }
1276
1277 if ((pt->pte_hi ^ (pvo->pvo_pte.pte_hi & ~PTE_VALID)) == PTE_VALID) {
1278 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0) {
1279 #if defined(DEBUG) || defined(PMAPCHECK)
1280 pmap_pte_print(pt);
1281 #endif
1282 panic("pmap_pvo_to_pte: pvo %p: has valid pte in "
1283 "pmap_pteg_table %p but invalid in pvo",
1284 pvo, pt);
1285 }
1286 if (((pt->pte_lo ^ pvo->pvo_pte.pte_lo) & ~(PTE_CHG|PTE_REF)) != 0) {
1287 #if defined(DEBUG) || defined(PMAPCHECK)
1288 pmap_pte_print(pt);
1289 #endif
1290 panic("pmap_pvo_to_pte: pvo %p: pvo pte does "
1291 "not match pte %p in pmap_pteg_table",
1292 pvo, pt);
1293 }
1294 return pt;
1295 }
1296
1297 if (pvo->pvo_pte.pte_hi & PTE_VALID) {
1298 #if defined(DEBUG) || defined(PMAPCHECK)
1299 pmap_pte_print(pt);
1300 #endif
1301 panic("pmap_pvo_to_pte: pvo %p: has nomatching pte %p in "
1302 "pmap_pteg_table but valid in pvo", pvo, pt);
1303 }
1304 return NULL;
1305 #endif /* !(!DIAGNOSTIC && !DEBUG && !PMAPCHECK) */
1306 }
1307
1308 struct pvo_entry *
1309 pmap_pvo_find_va(pmap_t pm, vaddr_t va, int *pteidx_p)
1310 {
1311 struct pvo_entry *pvo;
1312 int ptegidx;
1313
1314 va &= ~ADDR_POFF;
1315 ptegidx = va_to_pteg(pm, va);
1316
1317 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
1318 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1319 if ((uintptr_t) pvo >= SEGMENT_LENGTH)
1320 panic("pmap_pvo_find_va: invalid pvo %p on "
1321 "list %#x (%p)", pvo, ptegidx,
1322 &pmap_pvo_table[ptegidx]);
1323 #endif
1324 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
1325 if (pteidx_p)
1326 *pteidx_p = pmap_pvo_pte_index(pvo, ptegidx);
1327 return pvo;
1328 }
1329 }
1330 return NULL;
1331 }
1332
1333 #if defined(DEBUG) || defined(PMAPCHECK)
1334 void
1335 pmap_pvo_check(const struct pvo_entry *pvo)
1336 {
1337 struct pvo_head *pvo_head;
1338 struct pvo_entry *pvo0;
1339 volatile struct pte *pt;
1340 int failed = 0;
1341
1342 if ((uintptr_t)(pvo+1) >= SEGMENT_LENGTH)
1343 panic("pmap_pvo_check: pvo %p: invalid address", pvo);
1344
1345 if ((uintptr_t)(pvo->pvo_pmap+1) >= SEGMENT_LENGTH) {
1346 printf("pmap_pvo_check: pvo %p: invalid pmap address %p\n",
1347 pvo, pvo->pvo_pmap);
1348 failed = 1;
1349 }
1350
1351 if ((uintptr_t)TAILQ_NEXT(pvo, pvo_olink) >= SEGMENT_LENGTH ||
1352 (((uintptr_t)TAILQ_NEXT(pvo, pvo_olink)) & 0x1f) != 0) {
1353 printf("pmap_pvo_check: pvo %p: invalid ovlink address %p\n",
1354 pvo, TAILQ_NEXT(pvo, pvo_olink));
1355 failed = 1;
1356 }
1357
1358 if ((uintptr_t)LIST_NEXT(pvo, pvo_vlink) >= SEGMENT_LENGTH ||
1359 (((uintptr_t)LIST_NEXT(pvo, pvo_vlink)) & 0x1f) != 0) {
1360 printf("pmap_pvo_check: pvo %p: invalid ovlink address %p\n",
1361 pvo, LIST_NEXT(pvo, pvo_vlink));
1362 failed = 1;
1363 }
1364
1365 if (pvo->pvo_vaddr & PVO_MANAGED) {
1366 pvo_head = pa_to_pvoh(pvo->pvo_pte.pte_lo & PTE_RPGN, NULL);
1367 } else {
1368 if (pvo->pvo_vaddr < VM_MIN_KERNEL_ADDRESS) {
1369 printf("pmap_pvo_check: pvo %p: non kernel address "
1370 "on kernel unmanaged list\n", pvo);
1371 failed = 1;
1372 }
1373 pvo_head = &pmap_pvo_kunmanaged;
1374 }
1375 LIST_FOREACH(pvo0, pvo_head, pvo_vlink) {
1376 if (pvo0 == pvo)
1377 break;
1378 }
1379 if (pvo0 == NULL) {
1380 printf("pmap_pvo_check: pvo %p: not present "
1381 "on its vlist head %p\n", pvo, pvo_head);
1382 failed = 1;
1383 }
1384 if (pvo != pmap_pvo_find_va(pvo->pvo_pmap, pvo->pvo_vaddr, NULL)) {
1385 printf("pmap_pvo_check: pvo %p: not present "
1386 "on its olist head\n", pvo);
1387 failed = 1;
1388 }
1389 pt = pmap_pvo_to_pte(pvo, -1);
1390 if (pt == NULL) {
1391 if (pvo->pvo_pte.pte_hi & PTE_VALID) {
1392 printf("pmap_pvo_check: pvo %p: pte_hi VALID but "
1393 "no PTE\n", pvo);
1394 failed = 1;
1395 }
1396 } else {
1397 if ((uintptr_t) pt < (uintptr_t) &pmap_pteg_table[0] ||
1398 (uintptr_t) pt >=
1399 (uintptr_t) &pmap_pteg_table[pmap_pteg_cnt]) {
1400 printf("pmap_pvo_check: pvo %p: pte %p not in "
1401 "pteg table\n", pvo, pt);
1402 failed = 1;
1403 }
1404 if (((((uintptr_t) pt) >> 3) & 7) != PVO_PTEGIDX_GET(pvo)) {
1405 printf("pmap_pvo_check: pvo %p: pte_hi VALID but "
1406 "no PTE\n", pvo);
1407 failed = 1;
1408 }
1409 if (pvo->pvo_pte.pte_hi != pt->pte_hi) {
1410 printf("pmap_pvo_check: pvo %p: pte_hi differ: "
1411 "%#lx/%#lx\n", pvo, pvo->pvo_pte.pte_hi, pt->pte_hi);
1412 failed = 1;
1413 }
1414 if (((pvo->pvo_pte.pte_lo ^ pt->pte_lo) &
1415 (PTE_PP|PTE_WIMG|PTE_RPGN)) != 0) {
1416 printf("pmap_pvo_check: pvo %p: pte_lo differ: "
1417 "%#lx/%#lx\n", pvo,
1418 pvo->pvo_pte.pte_lo & (PTE_PP|PTE_WIMG|PTE_RPGN),
1419 pt->pte_lo & (PTE_PP|PTE_WIMG|PTE_RPGN));
1420 failed = 1;
1421 }
1422 if ((pmap_pte_to_va(pt) ^ PVO_VADDR(pvo)) & 0x0fffffff) {
1423 printf("pmap_pvo_check: pvo %p: PTE %p derived VA %#lx"
1424 " doesn't not match PVO's VA %#lx\n",
1425 pvo, pt, pmap_pte_to_va(pt), PVO_VADDR(pvo));
1426 failed = 1;
1427 }
1428 if (failed)
1429 pmap_pte_print(pt);
1430 }
1431 if (failed)
1432 panic("pmap_pvo_check: pvo %p, pm %p: bugcheck!", pvo,
1433 pvo->pvo_pmap);
1434 }
1435 #endif /* DEBUG || PMAPCHECK */
1436
1437 /*
1438 * This returns whether this is the first mapping of a page.
1439 */
1440 int
1441 pmap_pvo_enter(pmap_t pm, struct pool *pl, struct pvo_head *pvo_head,
1442 vaddr_t va, paddr_t pa, register_t pte_lo, int flags)
1443 {
1444 struct pvo_entry *pvo;
1445 struct pvo_tqhead *pvoh;
1446 register_t msr;
1447 int ptegidx;
1448 int i;
1449 int poolflags = PR_NOWAIT;
1450
1451 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1452 if (pmap_pvo_remove_depth > 0)
1453 panic("pmap_pvo_enter: called while pmap_pvo_remove active!");
1454 if (++pmap_pvo_enter_depth > 1)
1455 panic("pmap_pvo_enter: called recursively!");
1456 #endif
1457
1458 /*
1459 * Compute the PTE Group index.
1460 */
1461 va &= ~ADDR_POFF;
1462 ptegidx = va_to_pteg(pm, va);
1463
1464 msr = pmap_interrupts_off();
1465 /*
1466 * Remove any existing mapping for this page. Reuse the
1467 * pvo entry if there a mapping.
1468 */
1469 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
1470 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
1471 #ifdef DEBUG
1472 if ((pmapdebug & PMAPDEBUG_PVOENTER) &&
1473 ((pvo->pvo_pte.pte_lo ^ (pa|pte_lo)) &
1474 ~(PTE_REF|PTE_CHG)) == 0 &&
1475 va < VM_MIN_KERNEL_ADDRESS) {
1476 printf("pmap_pvo_enter: pvo %p: dup %#lx/%#lx\n",
1477 pvo, pvo->pvo_pte.pte_lo, pte_lo|pa);
1478 printf("pmap_pvo_enter: pte_hi=%#lx sr=%#lx\n",
1479 pvo->pvo_pte.pte_hi,
1480 pm->pm_sr[va >> ADDR_SR_SHFT]);
1481 pmap_pte_print(pmap_pvo_to_pte(pvo, -1));
1482 #ifdef DDBX
1483 Debugger();
1484 #endif
1485 }
1486 #endif
1487 PMAPCOUNT(mappings_replaced);
1488 pmap_pvo_remove(pvo, -1);
1489 break;
1490 }
1491 }
1492
1493 /*
1494 * If we aren't overwriting an mapping, try to allocate
1495 */
1496 pmap_interrupts_restore(msr);
1497 pvo = pool_get(pl, poolflags);
1498 msr = pmap_interrupts_off();
1499 if (pvo == NULL) {
1500 pvo = pmap_pvo_reclaim(pm);
1501 if (pvo == NULL) {
1502 if ((flags & PMAP_CANFAIL) == 0)
1503 panic("pmap_pvo_enter: failed");
1504 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1505 pmap_pvo_enter_depth--;
1506 #endif
1507 pmap_interrupts_restore(msr);
1508 return ENOMEM;
1509 }
1510 }
1511 pvo->pvo_vaddr = va;
1512 pvo->pvo_pmap = pm;
1513 pvo->pvo_vaddr &= ~ADDR_POFF;
1514 if (flags & VM_PROT_EXECUTE) {
1515 PMAPCOUNT(exec_mappings);
1516 pvo_set_exec(pvo);
1517 }
1518 if (flags & PMAP_WIRED)
1519 pvo->pvo_vaddr |= PVO_WIRED;
1520 if (pvo_head != &pmap_pvo_kunmanaged) {
1521 pvo->pvo_vaddr |= PVO_MANAGED;
1522 PMAPCOUNT(mappings);
1523 } else {
1524 PMAPCOUNT(kernel_mappings);
1525 }
1526 pmap_pte_create(&pvo->pvo_pte, pm, va, pa | pte_lo);
1527
1528 LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink);
1529 if (pvo->pvo_pte.pte_lo & PVO_WIRED)
1530 pvo->pvo_pmap->pm_stats.wired_count++;
1531 pvo->pvo_pmap->pm_stats.resident_count++;
1532 #if defined(DEBUG)
1533 if (pm != pmap_kernel() && va < VM_MIN_KERNEL_ADDRESS)
1534 DPRINTFN(PVOENTER,
1535 ("pmap_pvo_enter: pvo %p: pm %p va %#lx pa %#lx\n",
1536 pvo, pm, va, pa));
1537 #endif
1538
1539 /*
1540 * We hope this succeeds but it isn't required.
1541 */
1542 pvoh = &pmap_pvo_table[ptegidx];
1543 i = pmap_pte_insert(ptegidx, &pvo->pvo_pte);
1544 if (i >= 0) {
1545 PVO_PTEGIDX_SET(pvo, i);
1546 PVO_WHERE(pvo, ENTER_INSERT);
1547 PMAPCOUNT2(((pvo->pvo_pte.pte_hi & PTE_HID)
1548 ? pmap_evcnt_ptes_secondary : pmap_evcnt_ptes_primary)[i]);
1549 TAILQ_INSERT_TAIL(pvoh, pvo, pvo_olink);
1550 } else {
1551 /*
1552 * Since we didn't have room for this entry (which makes it
1553 * and evicted entry), place it at the head of the list.
1554 */
1555 TAILQ_INSERT_HEAD(pvoh, pvo, pvo_olink);
1556 PMAPCOUNT(ptes_evicted);
1557 pm->pm_evictions++;
1558 /*
1559 * If this is a kernel page, make sure it's active.
1560 */
1561 if (pm == pmap_kernel()) {
1562 i = pmap_pte_spill(pm, va, FALSE);
1563 KASSERT(i);
1564 }
1565 }
1566 PMAP_PVO_CHECK(pvo); /* sanity check */
1567 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1568 pmap_pvo_enter_depth--;
1569 #endif
1570 pmap_interrupts_restore(msr);
1571 return 0;
1572 }
1573
1574 void
1575 pmap_pvo_remove(struct pvo_entry *pvo, int pteidx)
1576 {
1577 volatile struct pte *pt;
1578 int ptegidx;
1579
1580 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1581 if (++pmap_pvo_remove_depth > 1)
1582 panic("pmap_pvo_remove: called recursively!");
1583 #endif
1584
1585 /*
1586 * If we haven't been supplied the ptegidx, calculate it.
1587 */
1588 if (pteidx == -1) {
1589 ptegidx = va_to_pteg(pvo->pvo_pmap, pvo->pvo_vaddr);
1590 pteidx = pmap_pvo_pte_index(pvo, ptegidx);
1591 } else {
1592 ptegidx = pteidx >> 3;
1593 if (pvo->pvo_pte.pte_hi & PTE_HID)
1594 ptegidx ^= pmap_pteg_mask;
1595 }
1596 PMAP_PVO_CHECK(pvo); /* sanity check */
1597
1598 /*
1599 * If there is an active pte entry, we need to deactivate it
1600 * (and save the ref & chg bits).
1601 */
1602 pt = pmap_pvo_to_pte(pvo, pteidx);
1603 if (pt != NULL) {
1604 pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
1605 PVO_WHERE(pvo, REMOVE);
1606 PVO_PTEGIDX_CLR(pvo);
1607 PMAPCOUNT(ptes_removed);
1608 } else {
1609 KASSERT(pvo->pvo_pmap->pm_evictions > 0);
1610 pvo->pvo_pmap->pm_evictions--;
1611 }
1612
1613 /*
1614 * Account for executable mappings.
1615 */
1616 if (PVO_ISEXECUTABLE(pvo))
1617 pvo_clear_exec(pvo);
1618
1619 /*
1620 * Update our statistics.
1621 */
1622 pvo->pvo_pmap->pm_stats.resident_count--;
1623 if (pvo->pvo_pte.pte_lo & PVO_WIRED)
1624 pvo->pvo_pmap->pm_stats.wired_count--;
1625
1626 /*
1627 * Save the REF/CHG bits into their cache if the page is managed.
1628 */
1629 if (pvo->pvo_vaddr & PVO_MANAGED) {
1630 register_t ptelo = pvo->pvo_pte.pte_lo;
1631 struct vm_page *pg = PHYS_TO_VM_PAGE(ptelo & PTE_RPGN);
1632
1633 if (pg != NULL) {
1634 pmap_attr_save(pg, ptelo & (PTE_REF|PTE_CHG));
1635 }
1636 PMAPCOUNT(unmappings);
1637 } else {
1638 PMAPCOUNT(kernel_unmappings);
1639 }
1640
1641 /*
1642 * Remove the PVO from its lists and return it to the pool.
1643 */
1644 LIST_REMOVE(pvo, pvo_vlink);
1645 TAILQ_REMOVE(&pmap_pvo_table[ptegidx], pvo, pvo_olink);
1646 pool_put(pvo->pvo_vaddr & PVO_MANAGED
1647 ? &pmap_mpvo_pool : &pmap_upvo_pool, pvo);
1648 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1649 pmap_pvo_remove_depth--;
1650 #endif
1651 }
1652
1653 /*
1654 * Mark a mapping as executable.
1655 * If this is the first executable mapping in the segment,
1656 * clear the noexec flag.
1657 */
1658 STATIC void
1659 pvo_set_exec(struct pvo_entry *pvo)
1660 {
1661 struct pmap *pm = pvo->pvo_pmap;
1662 int sr;
1663
1664 if (pm == pmap_kernel() || PVO_ISEXECUTABLE(pvo)) {
1665 return;
1666 }
1667 pvo->pvo_vaddr |= PVO_EXECUTABLE;
1668 sr = PVO_VADDR(pvo) >> ADDR_SR_SHFT;
1669 if (pm->pm_exec[sr]++ == 0) {
1670 pm->pm_sr[sr] &= ~SR_NOEXEC;
1671 }
1672 }
1673
1674 /*
1675 * Mark a mapping as non-executable.
1676 * If this was the last executable mapping in the segment,
1677 * set the noexec flag.
1678 */
1679 STATIC void
1680 pvo_clear_exec(struct pvo_entry *pvo)
1681 {
1682 struct pmap *pm = pvo->pvo_pmap;
1683 int sr;
1684
1685 if (pm == pmap_kernel() || !PVO_ISEXECUTABLE(pvo)) {
1686 return;
1687 }
1688 pvo->pvo_vaddr &= ~PVO_EXECUTABLE;
1689 sr = PVO_VADDR(pvo) >> ADDR_SR_SHFT;
1690 if (--pm->pm_exec[sr] == 0) {
1691 pm->pm_sr[sr] |= SR_NOEXEC;
1692 }
1693 }
1694
1695 /*
1696 * Insert physical page at pa into the given pmap at virtual address va.
1697 */
1698 int
1699 pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
1700 {
1701 struct mem_region *mp;
1702 struct pvo_head *pvo_head;
1703 struct vm_page *pg;
1704 struct pool *pl;
1705 register_t pte_lo;
1706 int error;
1707 u_int pvo_flags;
1708 u_int was_exec = 0;
1709
1710 if (__predict_false(!pmap_initialized)) {
1711 pvo_head = &pmap_pvo_kunmanaged;
1712 pl = &pmap_upvo_pool;
1713 pvo_flags = 0;
1714 pg = NULL;
1715 was_exec = PTE_EXEC;
1716 } else {
1717 pvo_head = pa_to_pvoh(pa, &pg);
1718 pl = &pmap_mpvo_pool;
1719 pvo_flags = PVO_MANAGED;
1720 }
1721
1722 DPRINTFN(ENTER,
1723 ("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x):",
1724 pm, va, pa, prot, flags));
1725
1726 /*
1727 * If this is a managed page, and it's the first reference to the
1728 * page clear the execness of the page. Otherwise fetch the execness.
1729 */
1730 if (pg != NULL)
1731 was_exec = pmap_attr_fetch(pg) & PTE_EXEC;
1732
1733 DPRINTFN(ENTER, (" was_exec=%d", was_exec));
1734
1735 /*
1736 * Assume the page is cache inhibited and access is guarded unless
1737 * it's in our available memory array. If it is in the memory array,
1738 * asssume it's in memory coherent memory.
1739 */
1740 pte_lo = PTE_IG;
1741 if ((flags & PMAP_NC) == 0) {
1742 for (mp = mem; mp->size; mp++) {
1743 if (pa >= mp->start && pa < mp->start + mp->size) {
1744 pte_lo = PTE_M;
1745 break;
1746 }
1747 }
1748 }
1749
1750 if (prot & VM_PROT_WRITE)
1751 pte_lo |= PTE_BW;
1752 else
1753 pte_lo |= PTE_BR;
1754
1755 /*
1756 * If this was in response to a fault, "pre-fault" the PTE's
1757 * changed/referenced bit appropriately.
1758 */
1759 if (flags & VM_PROT_WRITE)
1760 pte_lo |= PTE_CHG;
1761 if (flags & (VM_PROT_READ|VM_PROT_WRITE))
1762 pte_lo |= PTE_REF;
1763
1764 /*
1765 * We need to know if this page can be executable
1766 */
1767 flags |= (prot & VM_PROT_EXECUTE);
1768
1769 /*
1770 * Record mapping for later back-translation and pte spilling.
1771 * This will overwrite any existing mapping.
1772 */
1773 error = pmap_pvo_enter(pm, pl, pvo_head, va, pa, pte_lo, flags);
1774
1775 /*
1776 * Flush the real page from the instruction cache if this page is
1777 * mapped executable and cacheable and has not been flushed since
1778 * the last time it was modified.
1779 */
1780 if (error == 0 &&
1781 (flags & VM_PROT_EXECUTE) &&
1782 (pte_lo & PTE_I) == 0 &&
1783 was_exec == 0) {
1784 DPRINTFN(ENTER, (" syncicache"));
1785 PMAPCOUNT(exec_synced);
1786 pmap_syncicache(pa, PAGE_SIZE);
1787 if (pg != NULL) {
1788 pmap_attr_save(pg, PTE_EXEC);
1789 PMAPCOUNT(exec_cached);
1790 #if defined(DEBUG) || defined(PMAPDEBUG)
1791 if (pmapdebug & PMAPDEBUG_ENTER)
1792 printf(" marked-as-exec");
1793 else if (pmapdebug & PMAPDEBUG_EXEC)
1794 printf("[pmap_enter: %#lx: marked-as-exec]\n",
1795 pg->phys_addr);
1796
1797 #endif
1798 }
1799 }
1800
1801 DPRINTFN(ENTER, (": error=%d\n", error));
1802
1803 return error;
1804 }
1805
1806 void
1807 pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
1808 {
1809 struct mem_region *mp;
1810 register_t pte_lo;
1811 int error;
1812
1813 if (va < VM_MIN_KERNEL_ADDRESS)
1814 panic("pmap_kenter_pa: attempt to enter "
1815 "non-kernel address %#lx!", va);
1816
1817 DPRINTFN(KENTER,
1818 ("pmap_kenter_pa(%#lx,%#lx,%#x)\n", va, pa, prot));
1819
1820 /*
1821 * Assume the page is cache inhibited and access is guarded unless
1822 * it's in our available memory array. If it is in the memory array,
1823 * asssume it's in memory coherent memory.
1824 */
1825 pte_lo = PTE_IG;
1826 if ((prot & PMAP_NC) == 0) {
1827 for (mp = mem; mp->size; mp++) {
1828 if (pa >= mp->start && pa < mp->start + mp->size) {
1829 pte_lo = PTE_M;
1830 break;
1831 }
1832 }
1833 }
1834
1835 if (prot & VM_PROT_WRITE)
1836 pte_lo |= PTE_BW;
1837 else
1838 pte_lo |= PTE_BR;
1839
1840 /*
1841 * We don't care about REF/CHG on PVOs on the unmanaged list.
1842 */
1843 error = pmap_pvo_enter(pmap_kernel(), &pmap_upvo_pool,
1844 &pmap_pvo_kunmanaged, va, pa, pte_lo, prot|PMAP_WIRED);
1845
1846 if (error != 0)
1847 panic("pmap_kenter_pa: failed to enter va %#lx pa %#lx: %d",
1848 va, pa, error);
1849 }
1850
1851 void
1852 pmap_kremove(vaddr_t va, vsize_t len)
1853 {
1854 if (va < VM_MIN_KERNEL_ADDRESS)
1855 panic("pmap_kremove: attempt to remove "
1856 "non-kernel address %#lx!", va);
1857
1858 DPRINTFN(KREMOVE,("pmap_kremove(%#lx,%#lx)\n", va, len));
1859 pmap_remove(pmap_kernel(), va, va + len);
1860 }
1861
1862 /*
1863 * Remove the given range of mapping entries.
1864 */
1865 void
1866 pmap_remove(pmap_t pm, vaddr_t va, vaddr_t endva)
1867 {
1868 struct pvo_entry *pvo;
1869 register_t msr;
1870 int pteidx;
1871
1872 msr = pmap_interrupts_off();
1873 for (; va < endva; va += PAGE_SIZE) {
1874 pvo = pmap_pvo_find_va(pm, va, &pteidx);
1875 if (pvo != NULL) {
1876 pmap_pvo_remove(pvo, pteidx);
1877 }
1878 }
1879 pmap_interrupts_restore(msr);
1880 }
1881
1882 /*
1883 * Get the physical page address for the given pmap/virtual address.
1884 */
1885 boolean_t
1886 pmap_extract(pmap_t pm, vaddr_t va, paddr_t *pap)
1887 {
1888 struct pvo_entry *pvo;
1889 register_t msr;
1890
1891 /*
1892 * If this is a kernel pmap lookup, also check the battable
1893 * and if we get a hit, translate the VA to a PA using the
1894 * BAT entries. Don't check for VM_MAX_KENREL_ADDRESS is
1895 * that will wrap back to 0.
1896 */
1897 if (pm == pmap_kernel() &&
1898 (va < VM_MIN_KERNEL_ADDRESS ||
1899 (KERNEL2_SR < 15 && VM_MAX_KERNEL_ADDRESS <= va))) {
1900 register_t batu = battable[va >> ADDR_SR_SHFT].batu;
1901 KASSERT((va >> ADDR_SR_SHFT) != USER_SR);
1902 if (BAT_VALID_P(batu,0) && BAT_VA_MATCH_P(batu,va)) {
1903 register_t batl = battable[va >> ADDR_SR_SHFT].batl;
1904 register_t mask = (~(batu & BAT_BL) << 15) & ~0x1ffffL;
1905 *pap = (batl & mask) | (va & ~mask);
1906 return TRUE;
1907 }
1908 return FALSE;
1909 }
1910
1911 msr = pmap_interrupts_off();
1912 pvo = pmap_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
1913 if (pvo != NULL) {
1914 PMAP_PVO_CHECK(pvo); /* sanity check */
1915 *pap = (pvo->pvo_pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF);
1916 }
1917 pmap_interrupts_restore(msr);
1918 return pvo != NULL;
1919 }
1920
1921 /*
1922 * Lower the protection on the specified range of this pmap.
1923 */
1924 void
1925 pmap_protect(pmap_t pm, vaddr_t va, vaddr_t endva, vm_prot_t prot)
1926 {
1927 struct pvo_entry *pvo;
1928 volatile struct pte *pt;
1929 register_t msr;
1930 int pteidx;
1931
1932 /*
1933 * Since this routine only downgrades protection, we should
1934 * always be called with at least one bit not set.
1935 */
1936 KASSERT(prot != VM_PROT_ALL);
1937
1938 /*
1939 * If there is no protection, this is equivalent to
1940 * remove the pmap from the pmap.
1941 */
1942 if ((prot & VM_PROT_READ) == 0) {
1943 pmap_remove(pm, va, endva);
1944 return;
1945 }
1946
1947 msr = pmap_interrupts_off();
1948 for (; va < endva; va += PAGE_SIZE) {
1949 pvo = pmap_pvo_find_va(pm, va, &pteidx);
1950 if (pvo == NULL)
1951 continue;
1952 PMAP_PVO_CHECK(pvo); /* sanity check */
1953
1954 /*
1955 * Revoke executable if asked to do so.
1956 */
1957 if ((prot & VM_PROT_EXECUTE) == 0)
1958 pvo_clear_exec(pvo);
1959
1960 #if 0
1961 /*
1962 * If the page is already read-only, no change
1963 * needs to be made.
1964 */
1965 if ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_BR)
1966 continue;
1967 #endif
1968 /*
1969 * Grab the PTE pointer before we diddle with
1970 * the cached PTE copy.
1971 */
1972 pt = pmap_pvo_to_pte(pvo, pteidx);
1973 /*
1974 * Change the protection of the page.
1975 */
1976 pvo->pvo_pte.pte_lo &= ~PTE_PP;
1977 pvo->pvo_pte.pte_lo |= PTE_BR;
1978
1979 /*
1980 * If the PVO is in the page table, update
1981 * that pte at well.
1982 */
1983 if (pt != NULL) {
1984 pmap_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
1985 PVO_WHERE(pvo, PMAP_PROTECT);
1986 PMAPCOUNT(ptes_changed);
1987 }
1988
1989 PMAP_PVO_CHECK(pvo); /* sanity check */
1990 }
1991 pmap_interrupts_restore(msr);
1992 }
1993
1994 void
1995 pmap_unwire(pmap_t pm, vaddr_t va)
1996 {
1997 struct pvo_entry *pvo;
1998 register_t msr;
1999
2000 msr = pmap_interrupts_off();
2001 pvo = pmap_pvo_find_va(pm, va, NULL);
2002 if (pvo != NULL) {
2003 if (pvo->pvo_vaddr & PVO_WIRED) {
2004 pvo->pvo_vaddr &= ~PVO_WIRED;
2005 pm->pm_stats.wired_count--;
2006 }
2007 PMAP_PVO_CHECK(pvo); /* sanity check */
2008 }
2009 pmap_interrupts_restore(msr);
2010 }
2011
2012 /*
2013 * Lower the protection on the specified physical page.
2014 */
2015 void
2016 pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
2017 {
2018 struct pvo_head *pvo_head;
2019 struct pvo_entry *pvo, *next_pvo;
2020 volatile struct pte *pt;
2021 register_t msr;
2022
2023 KASSERT(prot != VM_PROT_ALL);
2024 msr = pmap_interrupts_off();
2025
2026 /*
2027 * When UVM reuses a page, it does a pmap_page_protect with
2028 * VM_PROT_NONE. At that point, we can clear the exec flag
2029 * since we know the page will have different contents.
2030 */
2031 if ((prot & VM_PROT_READ) == 0) {
2032 DPRINTFN(EXEC, ("[pmap_page_protect: %#lx: clear-exec]\n",
2033 pg->phys_addr));
2034 if (pmap_attr_fetch(pg) & PTE_EXEC) {
2035 PMAPCOUNT(exec_uncached_page_protect);
2036 pmap_attr_clear(pg, PTE_EXEC);
2037 }
2038 }
2039
2040 pvo_head = vm_page_to_pvoh(pg);
2041 for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) {
2042 next_pvo = LIST_NEXT(pvo, pvo_vlink);
2043 PMAP_PVO_CHECK(pvo); /* sanity check */
2044
2045 /*
2046 * Downgrading to no mapping at all, we just remove the entry.
2047 */
2048 if ((prot & VM_PROT_READ) == 0) {
2049 pmap_pvo_remove(pvo, -1);
2050 continue;
2051 }
2052
2053 /*
2054 * If EXEC permission is being revoked, just clear the
2055 * flag in the PVO.
2056 */
2057 if ((prot & VM_PROT_EXECUTE) == 0)
2058 pvo_clear_exec(pvo);
2059
2060 /*
2061 * If this entry is already RO, don't diddle with the
2062 * page table.
2063 */
2064 if ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_BR) {
2065 PMAP_PVO_CHECK(pvo);
2066 continue;
2067 }
2068
2069 /*
2070 * Grab the PTE before the we diddle the bits so
2071 * pvo_to_pte can verify the pte contents are as
2072 * expected.
2073 */
2074 pt = pmap_pvo_to_pte(pvo, -1);
2075 pvo->pvo_pte.pte_lo &= ~PTE_PP;
2076 pvo->pvo_pte.pte_lo |= PTE_BR;
2077 if (pt != NULL) {
2078 pmap_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
2079 PVO_WHERE(pvo, PMAP_PAGE_PROTECT);
2080 PMAPCOUNT(ptes_changed);
2081 }
2082 PMAP_PVO_CHECK(pvo); /* sanity check */
2083 }
2084 pmap_interrupts_restore(msr);
2085 }
2086
2087 /*
2088 * Activate the address space for the specified process. If the process
2089 * is the current process, load the new MMU context.
2090 */
2091 void
2092 pmap_activate(struct lwp *l)
2093 {
2094 struct pcb *pcb = &l->l_addr->u_pcb;
2095 pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap;
2096
2097 DPRINTFN(ACTIVATE,
2098 ("pmap_activate: lwp %p (curlwp %p)\n", l, curlwp));
2099
2100 /*
2101 * XXX Normally performed in cpu_fork().
2102 */
2103 pcb->pcb_pm = pmap;
2104 }
2105
2106 /*
2107 * Deactivate the specified process's address space.
2108 */
2109 void
2110 pmap_deactivate(struct lwp *l)
2111 {
2112 }
2113
2114 boolean_t
2115 pmap_query_bit(struct vm_page *pg, int ptebit)
2116 {
2117 struct pvo_entry *pvo;
2118 volatile struct pte *pt;
2119 register_t msr;
2120
2121 if (pmap_attr_fetch(pg) & ptebit)
2122 return TRUE;
2123
2124 msr = pmap_interrupts_off();
2125 LIST_FOREACH(pvo, vm_page_to_pvoh(pg), pvo_vlink) {
2126 PMAP_PVO_CHECK(pvo); /* sanity check */
2127 /*
2128 * See if we saved the bit off. If so cache, it and return
2129 * success.
2130 */
2131 if (pvo->pvo_pte.pte_lo & ptebit) {
2132 pmap_attr_save(pg, ptebit);
2133 PMAP_PVO_CHECK(pvo); /* sanity check */
2134 pmap_interrupts_restore(msr);
2135 return TRUE;
2136 }
2137 }
2138 /*
2139 * No luck, now go thru the hard part of looking at the ptes
2140 * themselves. Sync so any pending REF/CHG bits are flushed
2141 * to the PTEs.
2142 */
2143 SYNC();
2144 LIST_FOREACH(pvo, vm_page_to_pvoh(pg), pvo_vlink) {
2145 PMAP_PVO_CHECK(pvo); /* sanity check */
2146 /*
2147 * See if this pvo have a valid PTE. If so, fetch the
2148 * REF/CHG bits from the valid PTE. If the appropriate
2149 * ptebit is set, cache, it and return success.
2150 */
2151 pt = pmap_pvo_to_pte(pvo, -1);
2152 if (pt != NULL) {
2153 pmap_pte_synch(pt, &pvo->pvo_pte);
2154 if (pvo->pvo_pte.pte_lo & ptebit) {
2155 pmap_attr_save(pg, ptebit);
2156 PMAP_PVO_CHECK(pvo); /* sanity check */
2157 pmap_interrupts_restore(msr);
2158 return TRUE;
2159 }
2160 }
2161 }
2162 pmap_interrupts_restore(msr);
2163 return FALSE;
2164 }
2165
2166 boolean_t
2167 pmap_clear_bit(struct vm_page *pg, int ptebit)
2168 {
2169 struct pvo_head *pvoh = vm_page_to_pvoh(pg);
2170 struct pvo_entry *pvo;
2171 volatile struct pte *pt;
2172 register_t msr;
2173 int rv = 0;
2174
2175 msr = pmap_interrupts_off();
2176
2177 /*
2178 * Fetch the cache value
2179 */
2180 rv |= pmap_attr_fetch(pg);
2181
2182 /*
2183 * Clear the cached value.
2184 */
2185 pmap_attr_clear(pg, ptebit);
2186
2187 /*
2188 * Sync so any pending REF/CHG bits are flushed to the PTEs (so we
2189 * can reset the right ones). Note that since the pvo entries and
2190 * list heads are accessed via BAT0 and are never placed in the
2191 * page table, we don't have to worry about further accesses setting
2192 * the REF/CHG bits.
2193 */
2194 SYNC();
2195
2196 /*
2197 * For each pvo entry, clear pvo's ptebit. If this pvo have a
2198 * valid PTE. If so, clear the ptebit from the valid PTE.
2199 */
2200 LIST_FOREACH(pvo, pvoh, pvo_vlink) {
2201 PMAP_PVO_CHECK(pvo); /* sanity check */
2202 pt = pmap_pvo_to_pte(pvo, -1);
2203 if (pt != NULL) {
2204 /*
2205 * Only sync the PTE if the bit we are looking
2206 * for is not already set.
2207 */
2208 if ((pvo->pvo_pte.pte_lo & ptebit) == 0)
2209 pmap_pte_synch(pt, &pvo->pvo_pte);
2210 /*
2211 * If the bit we are looking for was already set,
2212 * clear that bit in the pte.
2213 */
2214 if (pvo->pvo_pte.pte_lo & ptebit)
2215 pmap_pte_clear(pt, PVO_VADDR(pvo), ptebit);
2216 }
2217 rv |= pvo->pvo_pte.pte_lo & (PTE_CHG|PTE_REF);
2218 pvo->pvo_pte.pte_lo &= ~ptebit;
2219 PMAP_PVO_CHECK(pvo); /* sanity check */
2220 }
2221 pmap_interrupts_restore(msr);
2222
2223 /*
2224 * If we are clearing the modify bit and this page was marked EXEC
2225 * and the user of the page thinks the page was modified, then we
2226 * need to clean it from the icache if it's mapped or clear the EXEC
2227 * bit if it's not mapped. The page itself might not have the CHG
2228 * bit set if the modification was done via DMA to the page.
2229 */
2230 if ((ptebit & PTE_CHG) && (rv & PTE_EXEC)) {
2231 if (LIST_EMPTY(pvoh)) {
2232 DPRINTFN(EXEC, ("[pmap_clear_bit: %#lx: clear-exec]\n",
2233 pg->phys_addr));
2234 pmap_attr_clear(pg, PTE_EXEC);
2235 PMAPCOUNT(exec_uncached_clear_modify);
2236 } else {
2237 DPRINTFN(EXEC, ("[pmap_clear_bit: %#lx: syncicache]\n",
2238 pg->phys_addr));
2239 pmap_syncicache(pg->phys_addr, PAGE_SIZE);
2240 PMAPCOUNT(exec_synced_clear_modify);
2241 }
2242 }
2243 return (rv & ptebit) != 0;
2244 }
2245
2246 void
2247 pmap_procwr(struct proc *p, vaddr_t va, size_t len)
2248 {
2249 struct pvo_entry *pvo;
2250 size_t offset = va & ADDR_POFF;
2251 int s;
2252
2253 s = splvm();
2254 while (len > 0) {
2255 size_t seglen = PAGE_SIZE - offset;
2256 if (seglen > len)
2257 seglen = len;
2258 pvo = pmap_pvo_find_va(p->p_vmspace->vm_map.pmap, va, NULL);
2259 if (pvo != NULL && PVO_ISEXECUTABLE(pvo)) {
2260 pmap_syncicache(
2261 (pvo->pvo_pte.pte_lo & PTE_RPGN) | offset, seglen);
2262 PMAP_PVO_CHECK(pvo);
2263 }
2264 va += seglen;
2265 len -= seglen;
2266 offset = 0;
2267 }
2268 splx(s);
2269 }
2270
2271 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB)
2272 void
2273 pmap_pte_print(volatile struct pte *pt)
2274 {
2275 printf("PTE %p: ", pt);
2276 /* High word: */
2277 printf("0x%08lx: [", pt->pte_hi);
2278 printf("%c ", (pt->pte_hi & PTE_VALID) ? 'v' : 'i');
2279 printf("%c ", (pt->pte_hi & PTE_HID) ? 'h' : '-');
2280 printf("0x%06lx 0x%02lx",
2281 (pt->pte_hi &~ PTE_VALID)>>PTE_VSID_SHFT,
2282 pt->pte_hi & PTE_API);
2283 printf(" (va 0x%08lx)] ", pmap_pte_to_va(pt));
2284 /* Low word: */
2285 printf(" 0x%08lx: [", pt->pte_lo);
2286 printf("0x%05lx... ", pt->pte_lo >> 12);
2287 printf("%c ", (pt->pte_lo & PTE_REF) ? 'r' : 'u');
2288 printf("%c ", (pt->pte_lo & PTE_CHG) ? 'c' : 'n');
2289 printf("%c", (pt->pte_lo & PTE_W) ? 'w' : '.');
2290 printf("%c", (pt->pte_lo & PTE_I) ? 'i' : '.');
2291 printf("%c", (pt->pte_lo & PTE_M) ? 'm' : '.');
2292 printf("%c ", (pt->pte_lo & PTE_G) ? 'g' : '.');
2293 switch (pt->pte_lo & PTE_PP) {
2294 case PTE_BR: printf("br]\n"); break;
2295 case PTE_BW: printf("bw]\n"); break;
2296 case PTE_SO: printf("so]\n"); break;
2297 case PTE_SW: printf("sw]\n"); break;
2298 }
2299 }
2300 #endif
2301
2302 #if defined(DDB)
2303 void
2304 pmap_pteg_check(void)
2305 {
2306 volatile struct pte *pt;
2307 int i;
2308 int ptegidx;
2309 u_int p_valid = 0;
2310 u_int s_valid = 0;
2311 u_int invalid = 0;
2312
2313 for (ptegidx = 0; ptegidx < pmap_pteg_cnt; ptegidx++) {
2314 for (pt = pmap_pteg_table[ptegidx].pt, i = 8; --i >= 0; pt++) {
2315 if (pt->pte_hi & PTE_VALID) {
2316 if (pt->pte_hi & PTE_HID)
2317 s_valid++;
2318 else
2319 p_valid++;
2320 } else
2321 invalid++;
2322 }
2323 }
2324 printf("pteg_check: v(p) %#x (%d), v(s) %#x (%d), i %#x (%d)\n",
2325 p_valid, p_valid, s_valid, s_valid,
2326 invalid, invalid);
2327 }
2328
2329 void
2330 pmap_print_mmuregs(void)
2331 {
2332 int i;
2333 u_int cpuvers;
2334 vaddr_t addr;
2335 register_t soft_sr[16];
2336 struct bat soft_ibat[4];
2337 struct bat soft_dbat[4];
2338 register_t sdr1;
2339
2340 cpuvers = MFPVR() >> 16;
2341
2342 __asm __volatile ("mfsdr1 %0" : "=r"(sdr1));
2343
2344 addr = 0;
2345 for (i=0; i<16; i++) {
2346 soft_sr[i] = MFSRIN(addr);
2347 addr += (1 << ADDR_SR_SHFT);
2348 }
2349
2350 /* read iBAT (601: uBAT) registers */
2351 __asm __volatile ("mfibatu %0,0" : "=r"(soft_ibat[0].batu));
2352 __asm __volatile ("mfibatl %0,0" : "=r"(soft_ibat[0].batl));
2353 __asm __volatile ("mfibatu %0,1" : "=r"(soft_ibat[1].batu));
2354 __asm __volatile ("mfibatl %0,1" : "=r"(soft_ibat[1].batl));
2355 __asm __volatile ("mfibatu %0,2" : "=r"(soft_ibat[2].batu));
2356 __asm __volatile ("mfibatl %0,2" : "=r"(soft_ibat[2].batl));
2357 __asm __volatile ("mfibatu %0,3" : "=r"(soft_ibat[3].batu));
2358 __asm __volatile ("mfibatl %0,3" : "=r"(soft_ibat[3].batl));
2359
2360
2361 if (cpuvers != MPC601) {
2362 /* read dBAT registers */
2363 __asm __volatile ("mfdbatu %0,0" : "=r"(soft_dbat[0].batu));
2364 __asm __volatile ("mfdbatl %0,0" : "=r"(soft_dbat[0].batl));
2365 __asm __volatile ("mfdbatu %0,1" : "=r"(soft_dbat[1].batu));
2366 __asm __volatile ("mfdbatl %0,1" : "=r"(soft_dbat[1].batl));
2367 __asm __volatile ("mfdbatu %0,2" : "=r"(soft_dbat[2].batu));
2368 __asm __volatile ("mfdbatl %0,2" : "=r"(soft_dbat[2].batl));
2369 __asm __volatile ("mfdbatu %0,3" : "=r"(soft_dbat[3].batu));
2370 __asm __volatile ("mfdbatl %0,3" : "=r"(soft_dbat[3].batl));
2371 }
2372
2373 printf("SDR1:\t%#lx\n", sdr1);
2374 printf("SR[]:\t");
2375 for (i=0; i<4; i++)
2376 printf("0x%08lx, ", soft_sr[i]);
2377 printf("\n\t");
2378 for ( ; i<8; i++)
2379 printf("0x%08lx, ", soft_sr[i]);
2380 printf("\n\t");
2381 for ( ; i<12; i++)
2382 printf("0x%08lx, ", soft_sr[i]);
2383 printf("\n\t");
2384 for ( ; i<16; i++)
2385 printf("0x%08lx, ", soft_sr[i]);
2386 printf("\n");
2387
2388 printf("%cBAT[]:\t", cpuvers == MPC601 ? 'u' : 'i');
2389 for (i=0; i<4; i++) {
2390 printf("0x%08lx 0x%08lx, ",
2391 soft_ibat[i].batu, soft_ibat[i].batl);
2392 if (i == 1)
2393 printf("\n\t");
2394 }
2395 if (cpuvers != MPC601) {
2396 printf("\ndBAT[]:\t");
2397 for (i=0; i<4; i++) {
2398 printf("0x%08lx 0x%08lx, ",
2399 soft_dbat[i].batu, soft_dbat[i].batl);
2400 if (i == 1)
2401 printf("\n\t");
2402 }
2403 }
2404 printf("\n");
2405 }
2406
2407 void
2408 pmap_print_pte(pmap_t pm, vaddr_t va)
2409 {
2410 struct pvo_entry *pvo;
2411 volatile struct pte *pt;
2412 int pteidx;
2413
2414 pvo = pmap_pvo_find_va(pm, va, &pteidx);
2415 if (pvo != NULL) {
2416 pt = pmap_pvo_to_pte(pvo, pteidx);
2417 if (pt != NULL) {
2418 printf("VA %#lx -> %p -> %s %#lx, %#lx\n",
2419 va, pt,
2420 pt->pte_hi & PTE_HID ? "(sec)" : "(pri)",
2421 pt->pte_hi, pt->pte_lo);
2422 } else {
2423 printf("No valid PTE found\n");
2424 }
2425 } else {
2426 printf("Address not in pmap\n");
2427 }
2428 }
2429
2430 void
2431 pmap_pteg_dist(void)
2432 {
2433 struct pvo_entry *pvo;
2434 int ptegidx;
2435 int depth;
2436 int max_depth = 0;
2437 unsigned int depths[64];
2438
2439 memset(depths, 0, sizeof(depths));
2440 for (ptegidx = 0; ptegidx < pmap_pteg_cnt; ptegidx++) {
2441 depth = 0;
2442 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
2443 depth++;
2444 }
2445 if (depth > max_depth)
2446 max_depth = depth;
2447 if (depth > 63)
2448 depth = 63;
2449 depths[depth]++;
2450 }
2451
2452 for (depth = 0; depth < 64; depth++) {
2453 printf(" [%2d]: %8u", depth, depths[depth]);
2454 if ((depth & 3) == 3)
2455 printf("\n");
2456 if (depth == max_depth)
2457 break;
2458 }
2459 if ((depth & 3) != 3)
2460 printf("\n");
2461 printf("Max depth found was %d\n", max_depth);
2462 }
2463 #endif /* DEBUG */
2464
2465 #if defined(PMAPCHECK) || defined(DEBUG)
2466 void
2467 pmap_pvo_verify(void)
2468 {
2469 int ptegidx;
2470 int s;
2471
2472 s = splvm();
2473 for (ptegidx = 0; ptegidx < pmap_pteg_cnt; ptegidx++) {
2474 struct pvo_entry *pvo;
2475 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
2476 if ((uintptr_t) pvo >= SEGMENT_LENGTH)
2477 panic("pmap_pvo_verify: invalid pvo %p "
2478 "on list %#x", pvo, ptegidx);
2479 pmap_pvo_check(pvo);
2480 }
2481 }
2482 splx(s);
2483 }
2484 #endif /* PMAPCHECK */
2485
2486
2487 void *
2488 pmap_pool_ualloc(struct pool *pp, int flags)
2489 {
2490 struct pvo_page *pvop;
2491
2492 pvop = SIMPLEQ_FIRST(&pmap_upvop_head);
2493 if (pvop != NULL) {
2494 pmap_upvop_free--;
2495 SIMPLEQ_REMOVE_HEAD(&pmap_upvop_head, pvop_link);
2496 return pvop;
2497 }
2498 if (uvm.page_init_done != TRUE) {
2499 return (void *) uvm_pageboot_alloc(PAGE_SIZE);
2500 }
2501 return pmap_pool_malloc(pp, flags);
2502 }
2503
2504 void *
2505 pmap_pool_malloc(struct pool *pp, int flags)
2506 {
2507 struct pvo_page *pvop;
2508 struct vm_page *pg;
2509
2510 pvop = SIMPLEQ_FIRST(&pmap_mpvop_head);
2511 if (pvop != NULL) {
2512 pmap_mpvop_free--;
2513 SIMPLEQ_REMOVE_HEAD(&pmap_mpvop_head, pvop_link);
2514 return pvop;
2515 }
2516 again:
2517 pg = uvm_pagealloc_strat(NULL, 0, NULL, UVM_PGA_USERESERVE,
2518 UVM_PGA_STRAT_ONLY, VM_FREELIST_FIRST256);
2519 if (__predict_false(pg == NULL)) {
2520 if (flags & PR_WAITOK) {
2521 uvm_wait("plpg");
2522 goto again;
2523 } else {
2524 return (0);
2525 }
2526 }
2527 return (void *) VM_PAGE_TO_PHYS(pg);
2528 }
2529
2530 void
2531 pmap_pool_ufree(struct pool *pp, void *va)
2532 {
2533 struct pvo_page *pvop;
2534 #if 0
2535 if (PHYS_TO_VM_PAGE((paddr_t) va) != NULL) {
2536 pmap_pool_mfree(va, size, tag);
2537 return;
2538 }
2539 #endif
2540 pvop = va;
2541 SIMPLEQ_INSERT_HEAD(&pmap_upvop_head, pvop, pvop_link);
2542 pmap_upvop_free++;
2543 if (pmap_upvop_free > pmap_upvop_maxfree)
2544 pmap_upvop_maxfree = pmap_upvop_free;
2545 }
2546
2547 void
2548 pmap_pool_mfree(struct pool *pp, void *va)
2549 {
2550 struct pvo_page *pvop;
2551
2552 pvop = va;
2553 SIMPLEQ_INSERT_HEAD(&pmap_mpvop_head, pvop, pvop_link);
2554 pmap_mpvop_free++;
2555 if (pmap_mpvop_free > pmap_mpvop_maxfree)
2556 pmap_mpvop_maxfree = pmap_mpvop_free;
2557 #if 0
2558 uvm_pagefree(PHYS_TO_VM_PAGE((paddr_t) va));
2559 #endif
2560 }
2561
2562 /*
2563 * This routine in bootstraping to steal to-be-managed memory (which will
2564 * then be unmanaged). We use it to grab from the first 256MB for our
2565 * pmap needs and above 256MB for other stuff.
2566 */
2567 vaddr_t
2568 pmap_steal_memory(vsize_t vsize, vaddr_t *vstartp, vaddr_t *vendp)
2569 {
2570 vsize_t size;
2571 vaddr_t va;
2572 paddr_t pa = 0;
2573 int npgs, bank;
2574 struct vm_physseg *ps;
2575
2576 if (uvm.page_init_done == TRUE)
2577 panic("pmap_steal_memory: called _after_ bootstrap");
2578
2579 *vstartp = VM_MIN_KERNEL_ADDRESS;
2580 *vendp = VM_MAX_KERNEL_ADDRESS;
2581
2582 size = round_page(vsize);
2583 npgs = atop(size);
2584
2585 /*
2586 * PA 0 will never be among those given to UVM so we can use it
2587 * to indicate we couldn't steal any memory.
2588 */
2589 for (ps = vm_physmem, bank = 0; bank < vm_nphysseg; bank++, ps++) {
2590 if (ps->free_list == VM_FREELIST_FIRST256 &&
2591 ps->avail_end - ps->avail_start >= npgs) {
2592 pa = ptoa(ps->avail_start);
2593 break;
2594 }
2595 }
2596
2597 if (pa == 0)
2598 panic("pmap_steal_memory: no approriate memory to steal!");
2599
2600 ps->avail_start += npgs;
2601 ps->start += npgs;
2602
2603 /*
2604 * If we've used up all the pages in the segment, remove it and
2605 * compact the list.
2606 */
2607 if (ps->avail_start == ps->end) {
2608 /*
2609 * If this was the last one, then a very bad thing has occurred
2610 */
2611 if (--vm_nphysseg == 0)
2612 panic("pmap_steal_memory: out of memory!");
2613
2614 printf("pmap_steal_memory: consumed bank %d\n", bank);
2615 for (; bank < vm_nphysseg; bank++, ps++) {
2616 ps[0] = ps[1];
2617 }
2618 }
2619
2620 va = (vaddr_t) pa;
2621 memset((caddr_t) va, 0, size);
2622 pmap_pages_stolen += npgs;
2623 #ifdef DEBUG
2624 if (pmapdebug && npgs > 1) {
2625 u_int cnt = 0;
2626 for (bank = 0, ps = vm_physmem; bank < vm_nphysseg; bank++, ps++)
2627 cnt += ps->avail_end - ps->avail_start;
2628 printf("pmap_steal_memory: stole %u (total %u) pages (%u left)\n",
2629 npgs, pmap_pages_stolen, cnt);
2630 }
2631 #endif
2632
2633 return va;
2634 }
2635
2636 /*
2637 * Find a chuck of memory with right size and alignment.
2638 */
2639 void *
2640 pmap_boot_find_memory(psize_t size, psize_t alignment, int at_end)
2641 {
2642 struct mem_region *mp;
2643 paddr_t s, e;
2644 int i, j;
2645
2646 size = round_page(size);
2647
2648 DPRINTFN(BOOT,
2649 ("pmap_boot_find_memory: size=%lx, alignment=%lx, at_end=%d",
2650 size, alignment, at_end));
2651
2652 if (alignment < PAGE_SIZE || (alignment & (alignment-1)) != 0)
2653 panic("pmap_boot_find_memory: invalid alignment %lx",
2654 alignment);
2655
2656 if (at_end) {
2657 if (alignment != PAGE_SIZE)
2658 panic("pmap_boot_find_memory: invalid ending "
2659 "alignment %lx", alignment);
2660
2661 for (mp = &avail[avail_cnt-1]; mp >= avail; mp--) {
2662 s = mp->start + mp->size - size;
2663 if (s >= mp->start && mp->size >= size) {
2664 DPRINTFN(BOOT,(": %lx\n", s));
2665 DPRINTFN(BOOT,
2666 ("pmap_boot_find_memory: b-avail[%d] start "
2667 "0x%lx size 0x%lx\n", mp - avail,
2668 mp->start, mp->size));
2669 mp->size -= size;
2670 DPRINTFN(BOOT,
2671 ("pmap_boot_find_memory: a-avail[%d] start "
2672 "0x%lx size 0x%lx\n", mp - avail,
2673 mp->start, mp->size));
2674 return (void *) s;
2675 }
2676 }
2677 panic("pmap_boot_find_memory: no available memory");
2678 }
2679
2680 for (mp = avail, i = 0; i < avail_cnt; i++, mp++) {
2681 s = (mp->start + alignment - 1) & ~(alignment-1);
2682 e = s + size;
2683
2684 /*
2685 * Is the calculated region entirely within the region?
2686 */
2687 if (s < mp->start || e > mp->start + mp->size)
2688 continue;
2689
2690 DPRINTFN(BOOT,(": %lx\n", s));
2691 if (s == mp->start) {
2692 /*
2693 * If the block starts at the beginning of region,
2694 * adjust the size & start. (the region may now be
2695 * zero in length)
2696 */
2697 DPRINTFN(BOOT,
2698 ("pmap_boot_find_memory: b-avail[%d] start "
2699 "0x%lx size 0x%lx\n", i, mp->start, mp->size));
2700 mp->start += size;
2701 mp->size -= size;
2702 DPRINTFN(BOOT,
2703 ("pmap_boot_find_memory: a-avail[%d] start "
2704 "0x%lx size 0x%lx\n", i, mp->start, mp->size));
2705 } else if (e == mp->start + mp->size) {
2706 /*
2707 * If the block starts at the beginning of region,
2708 * adjust only the size.
2709 */
2710 DPRINTFN(BOOT,
2711 ("pmap_boot_find_memory: b-avail[%d] start "
2712 "0x%lx size 0x%lx\n", i, mp->start, mp->size));
2713 mp->size -= size;
2714 DPRINTFN(BOOT,
2715 ("pmap_boot_find_memory: a-avail[%d] start "
2716 "0x%lx size 0x%lx\n", i, mp->start, mp->size));
2717 } else {
2718 /*
2719 * Block is in the middle of the region, so we
2720 * have to split it in two.
2721 */
2722 for (j = avail_cnt; j > i + 1; j--) {
2723 avail[j] = avail[j-1];
2724 }
2725 DPRINTFN(BOOT,
2726 ("pmap_boot_find_memory: b-avail[%d] start "
2727 "0x%lx size 0x%lx\n", i, mp->start, mp->size));
2728 mp[1].start = e;
2729 mp[1].size = mp[0].start + mp[0].size - e;
2730 mp[0].size = s - mp[0].start;
2731 avail_cnt++;
2732 for (; i < avail_cnt; i++) {
2733 DPRINTFN(BOOT,
2734 ("pmap_boot_find_memory: a-avail[%d] "
2735 "start 0x%lx size 0x%lx\n", i,
2736 avail[i].start, avail[i].size));
2737 }
2738 }
2739 return (void *) s;
2740 }
2741 panic("pmap_boot_find_memory: not enough memory for "
2742 "%lx/%lx allocation?", size, alignment);
2743 }
2744
2745 /*
2746 * This is not part of the defined PMAP interface and is specific to the
2747 * PowerPC architecture. This is called during initppc, before the system
2748 * is really initialized.
2749 */
2750 void
2751 pmap_bootstrap(paddr_t kernelstart, paddr_t kernelend)
2752 {
2753 struct mem_region *mp, tmp;
2754 paddr_t s, e;
2755 psize_t size;
2756 int i, j;
2757
2758 /*
2759 * Get memory.
2760 */
2761 mem_regions(&mem, &avail);
2762 #if defined(DEBUG)
2763 if (pmapdebug & PMAPDEBUG_BOOT) {
2764 printf("pmap_bootstrap: memory configuration:\n");
2765 for (mp = mem; mp->size; mp++) {
2766 printf("pmap_bootstrap: mem start 0x%lx size 0x%lx\n",
2767 mp->start, mp->size);
2768 }
2769 for (mp = avail; mp->size; mp++) {
2770 printf("pmap_bootstrap: avail start 0x%lx size 0x%lx\n",
2771 mp->start, mp->size);
2772 }
2773 }
2774 #endif
2775
2776 /*
2777 * Find out how much physical memory we have and in how many chunks.
2778 */
2779 for (mem_cnt = 0, mp = mem; mp->size; mp++) {
2780 if (mp->start >= pmap_memlimit)
2781 continue;
2782 if (mp->start + mp->size > pmap_memlimit) {
2783 size = pmap_memlimit - mp->start;
2784 physmem += btoc(size);
2785 } else {
2786 physmem += btoc(mp->size);
2787 }
2788 mem_cnt++;
2789 }
2790
2791 /*
2792 * Count the number of available entries.
2793 */
2794 for (avail_cnt = 0, mp = avail; mp->size; mp++)
2795 avail_cnt++;
2796
2797 /*
2798 * Page align all regions.
2799 */
2800 kernelstart = trunc_page(kernelstart);
2801 kernelend = round_page(kernelend);
2802 for (mp = avail, i = 0; i < avail_cnt; i++, mp++) {
2803 s = round_page(mp->start);
2804 mp->size -= (s - mp->start);
2805 mp->size = trunc_page(mp->size);
2806 mp->start = s;
2807 e = mp->start + mp->size;
2808
2809 DPRINTFN(BOOT,
2810 ("pmap_bootstrap: b-avail[%d] start 0x%lx size 0x%lx\n",
2811 i, mp->start, mp->size));
2812
2813 /*
2814 * Don't allow the end to run beyond our artificial limit
2815 */
2816 if (e > pmap_memlimit)
2817 e = pmap_memlimit;
2818
2819 /*
2820 * Is this region empty or strange? skip it.
2821 */
2822 if (e <= s) {
2823 mp->start = 0;
2824 mp->size = 0;
2825 continue;
2826 }
2827
2828 /*
2829 * Does this overlap the beginning of kernel?
2830 * Does extend past the end of the kernel?
2831 */
2832 else if (s < kernelstart && e > kernelstart) {
2833 if (e > kernelend) {
2834 avail[avail_cnt].start = kernelend;
2835 avail[avail_cnt].size = e - kernelend;
2836 avail_cnt++;
2837 }
2838 mp->size = kernelstart - s;
2839 }
2840 /*
2841 * Check whether this region overlaps the end of the kernel.
2842 */
2843 else if (s < kernelend && e > kernelend) {
2844 mp->start = kernelend;
2845 mp->size = e - kernelend;
2846 }
2847 /*
2848 * Look whether this regions is completely inside the kernel.
2849 * Nuke it if it does.
2850 */
2851 else if (s >= kernelstart && e <= kernelend) {
2852 mp->start = 0;
2853 mp->size = 0;
2854 }
2855 /*
2856 * If the user imposed a memory limit, enforce it.
2857 */
2858 else if (s >= pmap_memlimit) {
2859 mp->start = -PAGE_SIZE; /* let's know why */
2860 mp->size = 0;
2861 }
2862 else {
2863 mp->start = s;
2864 mp->size = e - s;
2865 }
2866 DPRINTFN(BOOT,
2867 ("pmap_bootstrap: a-avail[%d] start 0x%lx size 0x%lx\n",
2868 i, mp->start, mp->size));
2869 }
2870
2871 /*
2872 * Move (and uncount) all the null return to the end.
2873 */
2874 for (mp = avail, i = 0; i < avail_cnt; i++, mp++) {
2875 if (mp->size == 0) {
2876 tmp = avail[i];
2877 avail[i] = avail[--avail_cnt];
2878 avail[avail_cnt] = avail[i];
2879 }
2880 }
2881
2882 /*
2883 * (Bubble)sort them into asecnding order.
2884 */
2885 for (i = 0; i < avail_cnt; i++) {
2886 for (j = i + 1; j < avail_cnt; j++) {
2887 if (avail[i].start > avail[j].start) {
2888 tmp = avail[i];
2889 avail[i] = avail[j];
2890 avail[j] = tmp;
2891 }
2892 }
2893 }
2894
2895 /*
2896 * Make sure they don't overlap.
2897 */
2898 for (mp = avail, i = 0; i < avail_cnt - 1; i++, mp++) {
2899 if (mp[0].start + mp[0].size > mp[1].start) {
2900 mp[0].size = mp[1].start - mp[0].start;
2901 }
2902 DPRINTFN(BOOT,
2903 ("pmap_bootstrap: avail[%d] start 0x%lx size 0x%lx\n",
2904 i, mp->start, mp->size));
2905 }
2906 DPRINTFN(BOOT,
2907 ("pmap_bootstrap: avail[%d] start 0x%lx size 0x%lx\n",
2908 i, mp->start, mp->size));
2909
2910 #ifdef PTEGCOUNT
2911 pmap_pteg_cnt = PTEGCOUNT;
2912 #else /* PTEGCOUNT */
2913 pmap_pteg_cnt = 0x1000;
2914
2915 while (pmap_pteg_cnt < physmem)
2916 pmap_pteg_cnt <<= 1;
2917
2918 pmap_pteg_cnt >>= 1;
2919 #endif /* PTEGCOUNT */
2920
2921 /*
2922 * Find suitably aligned memory for PTEG hash table.
2923 */
2924 size = pmap_pteg_cnt * sizeof(struct pteg);
2925 pmap_pteg_table = pmap_boot_find_memory(size, size, 0);
2926 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
2927 if ( (uintptr_t) pmap_pteg_table + size > SEGMENT_LENGTH)
2928 panic("pmap_bootstrap: pmap_pteg_table end (%p + %lx) > 256MB",
2929 pmap_pteg_table, size);
2930 #endif
2931
2932 memset((void *)pmap_pteg_table, 0, pmap_pteg_cnt * sizeof(struct pteg));
2933 pmap_pteg_mask = pmap_pteg_cnt - 1;
2934
2935 /*
2936 * We cannot do pmap_steal_memory here since UVM hasn't been loaded
2937 * with pages. So we just steal them before giving them to UVM.
2938 */
2939 size = sizeof(pmap_pvo_table[0]) * pmap_pteg_cnt;
2940 pmap_pvo_table = pmap_boot_find_memory(size, PAGE_SIZE, 0);
2941 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
2942 if ( (uintptr_t) pmap_pvo_table + size > SEGMENT_LENGTH)
2943 panic("pmap_bootstrap: pmap_pvo_table end (%p + %lx) > 256MB",
2944 pmap_pvo_table, size);
2945 #endif
2946
2947 for (i = 0; i < pmap_pteg_cnt; i++)
2948 TAILQ_INIT(&pmap_pvo_table[i]);
2949
2950 #ifndef MSGBUFADDR
2951 /*
2952 * Allocate msgbuf in high memory.
2953 */
2954 msgbuf_paddr =
2955 (paddr_t) pmap_boot_find_memory(MSGBUFSIZE, PAGE_SIZE, 1);
2956 #endif
2957
2958 #ifdef __HAVE_PMAP_PHYSSEG
2959 {
2960 u_int npgs = 0;
2961 for (i = 0, mp = avail; i < avail_cnt; i++, mp++)
2962 npgs += btoc(mp->size);
2963 size = (sizeof(struct pvo_head) + 1) * npgs;
2964 pmap_physseg.pvoh = pmap_boot_find_memory(size, PAGE_SIZE, 0);
2965 pmap_physseg.attrs = (char *) &pmap_physseg.pvoh[npgs];
2966 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
2967 if ((uintptr_t)pmap_physseg.pvoh + size > SEGMENT_LENGTH)
2968 panic("pmap_bootstrap: PVO list end (%p + %lx) > 256MB",
2969 pmap_physseg.pvoh, size);
2970 #endif
2971 }
2972 #endif
2973
2974 for (mp = avail, i = 0; i < avail_cnt; mp++, i++) {
2975 paddr_t pfstart = atop(mp->start);
2976 paddr_t pfend = atop(mp->start + mp->size);
2977 if (mp->size == 0)
2978 continue;
2979 if (mp->start + mp->size <= SEGMENT_LENGTH) {
2980 uvm_page_physload(pfstart, pfend, pfstart, pfend,
2981 VM_FREELIST_FIRST256);
2982 } else if (mp->start >= SEGMENT_LENGTH) {
2983 uvm_page_physload(pfstart, pfend, pfstart, pfend,
2984 VM_FREELIST_DEFAULT);
2985 } else {
2986 pfend = atop(SEGMENT_LENGTH);
2987 uvm_page_physload(pfstart, pfend, pfstart, pfend,
2988 VM_FREELIST_FIRST256);
2989 pfstart = atop(SEGMENT_LENGTH);
2990 pfend = atop(mp->start + mp->size);
2991 uvm_page_physload(pfstart, pfend, pfstart, pfend,
2992 VM_FREELIST_DEFAULT);
2993 }
2994 }
2995
2996 /*
2997 * Make sure kernel vsid is allocated as well as VSID 0.
2998 */
2999 pmap_vsid_bitmap[(KERNEL_VSIDBITS & (NPMAPS-1)) / VSID_NBPW]
3000 |= 1 << (KERNEL_VSIDBITS % VSID_NBPW);
3001 pmap_vsid_bitmap[0] |= 1;
3002
3003 /*
3004 * Initialize kernel pmap and hardware.
3005 */
3006 for (i = 0; i < 16; i++) {
3007 pmap_kernel()->pm_sr[i] = EMPTY_SEGMENT;
3008 __asm __volatile ("mtsrin %0,%1"
3009 :: "r"(EMPTY_SEGMENT), "r"(i << ADDR_SR_SHFT));
3010 }
3011
3012 pmap_kernel()->pm_sr[KERNEL_SR] = KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY;
3013 __asm __volatile ("mtsr %0,%1"
3014 :: "n"(KERNEL_SR), "r"(KERNEL_SEGMENT));
3015 #ifdef KERNEL2_SR
3016 pmap_kernel()->pm_sr[KERNEL2_SR] = KERNEL2_SEGMENT|SR_SUKEY|SR_PRKEY;
3017 __asm __volatile ("mtsr %0,%1"
3018 :: "n"(KERNEL2_SR), "r"(KERNEL2_SEGMENT));
3019 #endif
3020 for (i = 0; i < 16; i++) {
3021 if (iosrtable[i] & SR601_T) {
3022 pmap_kernel()->pm_sr[i] = iosrtable[i];
3023 __asm __volatile ("mtsrin %0,%1"
3024 :: "r"(iosrtable[i]), "r"(i << ADDR_SR_SHFT));
3025 }
3026 }
3027
3028 __asm __volatile ("sync; mtsdr1 %0; isync"
3029 :: "r"((uintptr_t)pmap_pteg_table | (pmap_pteg_mask >> 10)));
3030 tlbia();
3031
3032 #ifdef ALTIVEC
3033 pmap_use_altivec = cpu_altivec;
3034 #endif
3035
3036 #ifdef DEBUG
3037 if (pmapdebug & PMAPDEBUG_BOOT) {
3038 u_int cnt;
3039 int bank;
3040 char pbuf[9];
3041 for (cnt = 0, bank = 0; bank < vm_nphysseg; bank++) {
3042 cnt += vm_physmem[bank].avail_end - vm_physmem[bank].avail_start;
3043 printf("pmap_bootstrap: vm_physmem[%d]=%#lx-%#lx/%#lx\n",
3044 bank,
3045 ptoa(vm_physmem[bank].avail_start),
3046 ptoa(vm_physmem[bank].avail_end),
3047 ptoa(vm_physmem[bank].avail_end - vm_physmem[bank].avail_start));
3048 }
3049 format_bytes(pbuf, sizeof(pbuf), ptoa((u_int64_t) cnt));
3050 printf("pmap_bootstrap: UVM memory = %s (%u pages)\n",
3051 pbuf, cnt);
3052 }
3053 #endif
3054
3055 pool_init(&pmap_upvo_pool, sizeof(struct pvo_entry),
3056 sizeof(struct pvo_entry), 0, 0, "pmap_upvopl",
3057 &pmap_pool_uallocator);
3058
3059 pool_setlowat(&pmap_upvo_pool, 252);
3060
3061 pool_init(&pmap_pool, sizeof(struct pmap),
3062 sizeof(void *), 0, 0, "pmap_pl", &pmap_pool_uallocator);
3063 }
3064