pmap.c revision 1.14 1 /* $NetBSD: pmap.c,v 1.14 2003/08/24 17:52:35 chs 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.14 2003/08/24 17:52:35 chs 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 struct pvo_tqhead *pvoh, *vpvoh;
773 int ptegidx, i, j;
774 volatile struct pteg *pteg;
775 volatile struct pte *pt;
776
777 ptegidx = va_to_pteg(pm, addr);
778
779 /*
780 * Have to substitute some entry. Use the primary hash for this.
781 * Use low bits of timebase as random generator. Make sure we are
782 * not picking a kernel pte for replacement.
783 */
784 pteg = &pmap_pteg_table[ptegidx];
785 i = MFTB() & 7;
786 for (j = 0; j < 8; j++) {
787 pt = &pteg->pt[i];
788 if ((pt->pte_hi & PTE_VALID) == 0 ||
789 VSID_TO_HASH((pt->pte_hi & PTE_VSID) >> PTE_VSID_SHFT)
790 != KERNEL_VSIDBITS)
791 break;
792 i = (i + 1) & 7;
793 }
794 KASSERT(j < 8);
795
796 source_pvo = NULL;
797 victim_pvo = NULL;
798 pvoh = &pmap_pvo_table[ptegidx];
799 TAILQ_FOREACH(pvo, pvoh, pvo_olink) {
800
801 /*
802 * We need to find pvo entry for this address...
803 */
804 PMAP_PVO_CHECK(pvo); /* sanity check */
805
806 /*
807 * If we haven't found the source and we come to a PVO with
808 * a valid PTE, then we know we can't find it because all
809 * evicted PVOs always are first in the list.
810 */
811 if (source_pvo == NULL && (pvo->pvo_pte.pte_hi & PTE_VALID))
812 break;
813 if (source_pvo == NULL && pm == pvo->pvo_pmap &&
814 addr == PVO_VADDR(pvo)) {
815
816 /*
817 * Now we have found the entry to be spilled into the
818 * pteg. Attempt to insert it into the page table.
819 */
820 j = pmap_pte_insert(ptegidx, &pvo->pvo_pte);
821 if (j >= 0) {
822 PVO_PTEGIDX_SET(pvo, j);
823 PMAP_PVO_CHECK(pvo); /* sanity check */
824 PVO_WHERE(pvo, SPILL_INSERT);
825 pvo->pvo_pmap->pm_evictions--;
826 PMAPCOUNT(ptes_spilled);
827 PMAPCOUNT2(((pvo->pvo_pte.pte_hi & PTE_HID)
828 ? pmap_evcnt_ptes_secondary
829 : pmap_evcnt_ptes_primary)[j]);
830
831 /*
832 * Since we keep the evicted entries at the
833 * from of the PVO list, we need move this
834 * (now resident) PVO after the evicted
835 * entries.
836 */
837 next_pvo = TAILQ_NEXT(pvo, pvo_olink);
838
839 /*
840 * If we don't have to move (either we were the
841 * last entry or the next entry was valid),
842 * don't change our position. Otherwise
843 * move ourselves to the tail of the queue.
844 */
845 if (next_pvo != NULL &&
846 !(next_pvo->pvo_pte.pte_hi & PTE_VALID)) {
847 TAILQ_REMOVE(pvoh, pvo, pvo_olink);
848 TAILQ_INSERT_TAIL(pvoh, pvo, pvo_olink);
849 }
850 return 1;
851 }
852 source_pvo = pvo;
853 if (exec && !PVO_ISEXECUTABLE(source_pvo)) {
854 return 0;
855 }
856 if (victim_pvo != NULL)
857 break;
858 }
859
860 /*
861 * We also need the pvo entry of the victim we are replacing
862 * so save the R & C bits of the PTE.
863 */
864 if ((pt->pte_hi & PTE_HID) == 0 && victim_pvo == NULL &&
865 pmap_pte_compare(pt, &pvo->pvo_pte)) {
866 vpvoh = pvoh;
867 victim_pvo = pvo;
868 if (source_pvo != NULL)
869 break;
870 }
871 }
872
873 if (source_pvo == NULL) {
874 PMAPCOUNT(ptes_unspilled);
875 return 0;
876 }
877
878 if (victim_pvo == NULL) {
879 if ((pt->pte_hi & PTE_HID) == 0)
880 panic("pmap_pte_spill: victim p-pte (%p) has "
881 "no pvo entry!", pt);
882
883 /*
884 * If this is a secondary PTE, we need to search
885 * its primary pvo bucket for the matching PVO.
886 */
887 vpvoh = &pmap_pvo_table[ptegidx ^ pmap_pteg_mask];
888 TAILQ_FOREACH(pvo, vpvoh, pvo_olink) {
889 PMAP_PVO_CHECK(pvo); /* sanity check */
890
891 /*
892 * We also need the pvo entry of the victim we are
893 * replacing so save the R & C bits of the PTE.
894 */
895 if (pmap_pte_compare(pt, &pvo->pvo_pte)) {
896 victim_pvo = pvo;
897 break;
898 }
899 }
900 if (victim_pvo == NULL)
901 panic("pmap_pte_spill: victim s-pte (%p) has "
902 "no pvo entry!", pt);
903 }
904
905 /*
906 * The victim should be not be a kernel PVO/PTE entry.
907 */
908 KASSERT(victim_pvo->pvo_pmap != pmap_kernel());
909 KASSERT(PVO_PTEGIDX_ISSET(victim_pvo));
910 KASSERT(PVO_PTEGIDX_GET(victim_pvo) == i);
911
912 /*
913 * We are invalidating the TLB entry for the EA for the
914 * we are replacing even though its valid; If we don't
915 * we lose any ref/chg bit changes contained in the TLB
916 * entry.
917 */
918 source_pvo->pvo_pte.pte_hi &= ~PTE_HID;
919
920 /*
921 * To enforce the PVO list ordering constraint that all
922 * evicted entries should come before all valid entries,
923 * move the source PVO to the tail of its list and the
924 * victim PVO to the head of its list (which might not be
925 * the same list, if the victim was using the secondary hash).
926 */
927 TAILQ_REMOVE(pvoh, source_pvo, pvo_olink);
928 TAILQ_INSERT_TAIL(pvoh, source_pvo, pvo_olink);
929 TAILQ_REMOVE(vpvoh, victim_pvo, pvo_olink);
930 TAILQ_INSERT_HEAD(vpvoh, victim_pvo, pvo_olink);
931 pmap_pte_unset(pt, &victim_pvo->pvo_pte, victim_pvo->pvo_vaddr);
932 pmap_pte_set(pt, &source_pvo->pvo_pte);
933 victim_pvo->pvo_pmap->pm_evictions++;
934 source_pvo->pvo_pmap->pm_evictions--;
935 PVO_WHERE(victim_pvo, SPILL_UNSET);
936 PVO_WHERE(source_pvo, SPILL_SET);
937
938 PVO_PTEGIDX_CLR(victim_pvo);
939 PVO_PTEGIDX_SET(source_pvo, i);
940 PMAPCOUNT2(pmap_evcnt_ptes_primary[i]);
941 PMAPCOUNT(ptes_spilled);
942 PMAPCOUNT(ptes_evicted);
943 PMAPCOUNT(ptes_removed);
944
945 PMAP_PVO_CHECK(victim_pvo);
946 PMAP_PVO_CHECK(source_pvo);
947 return 1;
948 }
949
950 /*
951 * Restrict given range to physical memory
952 */
953 void
954 pmap_real_memory(paddr_t *start, psize_t *size)
955 {
956 struct mem_region *mp;
957
958 for (mp = mem; mp->size; mp++) {
959 if (*start + *size > mp->start
960 && *start < mp->start + mp->size) {
961 if (*start < mp->start) {
962 *size -= mp->start - *start;
963 *start = mp->start;
964 }
965 if (*start + *size > mp->start + mp->size)
966 *size = mp->start + mp->size - *start;
967 return;
968 }
969 }
970 *size = 0;
971 }
972
973 /*
974 * Initialize anything else for pmap handling.
975 * Called during vm_init().
976 */
977 void
978 pmap_init(void)
979 {
980 #ifdef __HAVE_PMAP_PHYSSEG
981 struct pvo_tqhead *pvoh;
982 int bank;
983 long sz;
984 char *attr;
985
986 pvoh = pmap_physseg.pvoh;
987 attr = pmap_physseg.attrs;
988 for (bank = 0; bank < vm_nphysseg; bank++) {
989 sz = vm_physmem[bank].end - vm_physmem[bank].start;
990 vm_physmem[bank].pmseg.pvoh = pvoh;
991 vm_physmem[bank].pmseg.attrs = attr;
992 for (; sz > 0; sz--, pvoh++, attr++) {
993 TAILQ_INIT(pvoh);
994 *attr = 0;
995 }
996 }
997 #endif
998
999 pool_init(&pmap_mpvo_pool, sizeof(struct pvo_entry),
1000 sizeof(struct pvo_entry), 0, 0, "pmap_mpvopl",
1001 &pmap_pool_mallocator);
1002
1003 pool_setlowat(&pmap_mpvo_pool, 1008);
1004
1005 pmap_initialized = 1;
1006
1007 #ifdef PMAPCOUNTERS
1008 evcnt_attach_static(&pmap_evcnt_mappings);
1009 evcnt_attach_static(&pmap_evcnt_mappings_replaced);
1010 evcnt_attach_static(&pmap_evcnt_unmappings);
1011
1012 evcnt_attach_static(&pmap_evcnt_kernel_mappings);
1013 evcnt_attach_static(&pmap_evcnt_kernel_unmappings);
1014
1015 evcnt_attach_static(&pmap_evcnt_exec_mappings);
1016 evcnt_attach_static(&pmap_evcnt_exec_cached);
1017 evcnt_attach_static(&pmap_evcnt_exec_synced);
1018 evcnt_attach_static(&pmap_evcnt_exec_synced_clear_modify);
1019
1020 evcnt_attach_static(&pmap_evcnt_exec_uncached_page_protect);
1021 evcnt_attach_static(&pmap_evcnt_exec_uncached_clear_modify);
1022 evcnt_attach_static(&pmap_evcnt_exec_uncached_zero_page);
1023 evcnt_attach_static(&pmap_evcnt_exec_uncached_copy_page);
1024
1025 evcnt_attach_static(&pmap_evcnt_zeroed_pages);
1026 evcnt_attach_static(&pmap_evcnt_copied_pages);
1027 evcnt_attach_static(&pmap_evcnt_idlezeroed_pages);
1028
1029 evcnt_attach_static(&pmap_evcnt_updates);
1030 evcnt_attach_static(&pmap_evcnt_collects);
1031 evcnt_attach_static(&pmap_evcnt_copies);
1032
1033 evcnt_attach_static(&pmap_evcnt_ptes_spilled);
1034 evcnt_attach_static(&pmap_evcnt_ptes_unspilled);
1035 evcnt_attach_static(&pmap_evcnt_ptes_evicted);
1036 evcnt_attach_static(&pmap_evcnt_ptes_removed);
1037 evcnt_attach_static(&pmap_evcnt_ptes_changed);
1038 evcnt_attach_static(&pmap_evcnt_ptes_primary[0]);
1039 evcnt_attach_static(&pmap_evcnt_ptes_primary[1]);
1040 evcnt_attach_static(&pmap_evcnt_ptes_primary[2]);
1041 evcnt_attach_static(&pmap_evcnt_ptes_primary[3]);
1042 evcnt_attach_static(&pmap_evcnt_ptes_primary[4]);
1043 evcnt_attach_static(&pmap_evcnt_ptes_primary[5]);
1044 evcnt_attach_static(&pmap_evcnt_ptes_primary[6]);
1045 evcnt_attach_static(&pmap_evcnt_ptes_primary[7]);
1046 evcnt_attach_static(&pmap_evcnt_ptes_secondary[0]);
1047 evcnt_attach_static(&pmap_evcnt_ptes_secondary[1]);
1048 evcnt_attach_static(&pmap_evcnt_ptes_secondary[2]);
1049 evcnt_attach_static(&pmap_evcnt_ptes_secondary[3]);
1050 evcnt_attach_static(&pmap_evcnt_ptes_secondary[4]);
1051 evcnt_attach_static(&pmap_evcnt_ptes_secondary[5]);
1052 evcnt_attach_static(&pmap_evcnt_ptes_secondary[6]);
1053 evcnt_attach_static(&pmap_evcnt_ptes_secondary[7]);
1054 #endif
1055 }
1056
1057 /*
1058 * How much virtual space does the kernel get?
1059 */
1060 void
1061 pmap_virtual_space(vaddr_t *start, vaddr_t *end)
1062 {
1063 /*
1064 * For now, reserve one segment (minus some overhead) for kernel
1065 * virtual memory
1066 */
1067 *start = VM_MIN_KERNEL_ADDRESS;
1068 *end = VM_MAX_KERNEL_ADDRESS;
1069 }
1070
1071 /*
1072 * Allocate, initialize, and return a new physical map.
1073 */
1074 pmap_t
1075 pmap_create(void)
1076 {
1077 pmap_t pm;
1078
1079 pm = pool_get(&pmap_pool, PR_WAITOK);
1080 memset((caddr_t)pm, 0, sizeof *pm);
1081 pmap_pinit(pm);
1082
1083 DPRINTFN(CREATE,("pmap_create: pm %p:\n"
1084 "\t%06lx %06lx %06lx %06lx %06lx %06lx %06lx %06lx\n"
1085 "\t%06lx %06lx %06lx %06lx %06lx %06lx %06lx %06lx\n", pm,
1086 pm->pm_sr[0], pm->pm_sr[1], pm->pm_sr[2], pm->pm_sr[3],
1087 pm->pm_sr[4], pm->pm_sr[5], pm->pm_sr[6], pm->pm_sr[7],
1088 pm->pm_sr[8], pm->pm_sr[9], pm->pm_sr[10], pm->pm_sr[11],
1089 pm->pm_sr[12], pm->pm_sr[13], pm->pm_sr[14], pm->pm_sr[15]));
1090 return pm;
1091 }
1092
1093 /*
1094 * Initialize a preallocated and zeroed pmap structure.
1095 */
1096 void
1097 pmap_pinit(pmap_t pm)
1098 {
1099 register_t entropy = MFTB();
1100 register_t mask;
1101 int i;
1102
1103 /*
1104 * Allocate some segment registers for this pmap.
1105 */
1106 pm->pm_refs = 1;
1107 for (i = 0; i < NPMAPS; i += VSID_NBPW) {
1108 static register_t pmap_vsidcontext;
1109 register_t hash;
1110 unsigned int n;
1111
1112 /* Create a new value by multiplying by a prime adding in
1113 * entropy from the timebase register. This is to make the
1114 * VSID more random so that the PT Hash function collides
1115 * less often. (note that the prime causes gcc to do shifts
1116 * instead of a multiply)
1117 */
1118 pmap_vsidcontext = (pmap_vsidcontext * 0x1105) + entropy;
1119 hash = pmap_vsidcontext & (NPMAPS - 1);
1120 if (hash == 0) /* 0 is special, avoid it */
1121 continue;
1122 n = hash >> 5;
1123 mask = 1L << (hash & (VSID_NBPW-1));
1124 hash = pmap_vsidcontext;
1125 if (pmap_vsid_bitmap[n] & mask) { /* collision? */
1126 /* anything free in this bucket? */
1127 if (~pmap_vsid_bitmap[n] == 0) {
1128 entropy = hash >> PTE_VSID_SHFT;
1129 continue;
1130 }
1131 i = ffs(~pmap_vsid_bitmap[n]) - 1;
1132 mask = 1L << i;
1133 hash &= ~(VSID_NBPW-1);
1134 hash |= i;
1135 }
1136 /*
1137 * Make sure clear out SR_KEY_LEN bits because we put our
1138 * our data in those bits (to identify the segment).
1139 */
1140 hash &= PTE_VSID >> (PTE_VSID_SHFT + SR_KEY_LEN);
1141 pmap_vsid_bitmap[n] |= mask;
1142 for (i = 0; i < 16; i++)
1143 pm->pm_sr[i] = VSID_MAKE(i, hash) | SR_PRKEY |
1144 SR_NOEXEC;
1145 return;
1146 }
1147 panic("pmap_pinit: out of segments");
1148 }
1149
1150 /*
1151 * Add a reference to the given pmap.
1152 */
1153 void
1154 pmap_reference(pmap_t pm)
1155 {
1156 pm->pm_refs++;
1157 }
1158
1159 /*
1160 * Retire the given pmap from service.
1161 * Should only be called if the map contains no valid mappings.
1162 */
1163 void
1164 pmap_destroy(pmap_t pm)
1165 {
1166 if (--pm->pm_refs == 0) {
1167 pmap_release(pm);
1168 pool_put(&pmap_pool, pm);
1169 }
1170 }
1171
1172 /*
1173 * Release any resources held by the given physical map.
1174 * Called when a pmap initialized by pmap_pinit is being released.
1175 */
1176 void
1177 pmap_release(pmap_t pm)
1178 {
1179 int idx, mask;
1180
1181 if (pm->pm_sr[0] == 0)
1182 panic("pmap_release");
1183 idx = VSID_TO_HASH(pm->pm_sr[0]) & (NPMAPS-1);
1184 mask = 1 << (idx % VSID_NBPW);
1185 idx /= VSID_NBPW;
1186 pmap_vsid_bitmap[idx] &= ~mask;
1187 }
1188
1189 /*
1190 * Copy the range specified by src_addr/len
1191 * from the source map to the range dst_addr/len
1192 * in the destination map.
1193 *
1194 * This routine is only advisory and need not do anything.
1195 */
1196 void
1197 pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vaddr_t dst_addr,
1198 vsize_t len, vaddr_t src_addr)
1199 {
1200 PMAPCOUNT(copies);
1201 }
1202
1203 /*
1204 * Require that all active physical maps contain no
1205 * incorrect entries NOW.
1206 */
1207 void
1208 pmap_update(struct pmap *pmap)
1209 {
1210 PMAPCOUNT(updates);
1211 TLBSYNC();
1212 }
1213
1214 /*
1215 * Garbage collects the physical map system for
1216 * pages which are no longer used.
1217 * Success need not be guaranteed -- that is, there
1218 * may well be pages which are not referenced, but
1219 * others may be collected.
1220 * Called by the pageout daemon when pages are scarce.
1221 */
1222 void
1223 pmap_collect(pmap_t pm)
1224 {
1225 PMAPCOUNT(collects);
1226 }
1227
1228 static __inline int
1229 pmap_pvo_pte_index(const struct pvo_entry *pvo, int ptegidx)
1230 {
1231 int pteidx;
1232 /*
1233 * We can find the actual pte entry without searching by
1234 * grabbing the PTEG index from 3 unused bits in pte_lo[11:9]
1235 * and by noticing the HID bit.
1236 */
1237 pteidx = ptegidx * 8 + PVO_PTEGIDX_GET(pvo);
1238 if (pvo->pvo_pte.pte_hi & PTE_HID)
1239 pteidx ^= pmap_pteg_mask * 8;
1240 return pteidx;
1241 }
1242
1243 volatile struct pte *
1244 pmap_pvo_to_pte(const struct pvo_entry *pvo, int pteidx)
1245 {
1246 volatile struct pte *pt;
1247
1248 #if !defined(DIAGNOSTIC) && !defined(DEBUG) && !defined(PMAPCHECK)
1249 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0)
1250 return NULL;
1251 #endif
1252
1253 /*
1254 * If we haven't been supplied the ptegidx, calculate it.
1255 */
1256 if (pteidx == -1) {
1257 int ptegidx;
1258 ptegidx = va_to_pteg(pvo->pvo_pmap, pvo->pvo_vaddr);
1259 pteidx = pmap_pvo_pte_index(pvo, ptegidx);
1260 }
1261
1262 pt = &pmap_pteg_table[pteidx >> 3].pt[pteidx & 7];
1263
1264 #if !defined(DIAGNOSTIC) && !defined(DEBUG) && !defined(PMAPCHECK)
1265 return pt;
1266 #else
1267 if ((pvo->pvo_pte.pte_hi & PTE_VALID) && !PVO_PTEGIDX_ISSET(pvo)) {
1268 panic("pmap_pvo_to_pte: pvo %p: has valid pte in "
1269 "pvo but no valid pte index", pvo);
1270 }
1271 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0 && PVO_PTEGIDX_ISSET(pvo)) {
1272 panic("pmap_pvo_to_pte: pvo %p: has valid pte index in "
1273 "pvo but no valid pte", pvo);
1274 }
1275
1276 if ((pt->pte_hi ^ (pvo->pvo_pte.pte_hi & ~PTE_VALID)) == PTE_VALID) {
1277 if ((pvo->pvo_pte.pte_hi & PTE_VALID) == 0) {
1278 #if defined(DEBUG) || defined(PMAPCHECK)
1279 pmap_pte_print(pt);
1280 #endif
1281 panic("pmap_pvo_to_pte: pvo %p: has valid pte in "
1282 "pmap_pteg_table %p but invalid in pvo",
1283 pvo, pt);
1284 }
1285 if (((pt->pte_lo ^ pvo->pvo_pte.pte_lo) & ~(PTE_CHG|PTE_REF)) != 0) {
1286 #if defined(DEBUG) || defined(PMAPCHECK)
1287 pmap_pte_print(pt);
1288 #endif
1289 panic("pmap_pvo_to_pte: pvo %p: pvo pte does "
1290 "not match pte %p in pmap_pteg_table",
1291 pvo, pt);
1292 }
1293 return pt;
1294 }
1295
1296 if (pvo->pvo_pte.pte_hi & PTE_VALID) {
1297 #if defined(DEBUG) || defined(PMAPCHECK)
1298 pmap_pte_print(pt);
1299 #endif
1300 panic("pmap_pvo_to_pte: pvo %p: has nomatching pte %p in "
1301 "pmap_pteg_table but valid in pvo", pvo, pt);
1302 }
1303 return NULL;
1304 #endif /* !(!DIAGNOSTIC && !DEBUG && !PMAPCHECK) */
1305 }
1306
1307 struct pvo_entry *
1308 pmap_pvo_find_va(pmap_t pm, vaddr_t va, int *pteidx_p)
1309 {
1310 struct pvo_entry *pvo;
1311 int ptegidx;
1312
1313 va &= ~ADDR_POFF;
1314 ptegidx = va_to_pteg(pm, va);
1315
1316 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
1317 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1318 if ((uintptr_t) pvo >= SEGMENT_LENGTH)
1319 panic("pmap_pvo_find_va: invalid pvo %p on "
1320 "list %#x (%p)", pvo, ptegidx,
1321 &pmap_pvo_table[ptegidx]);
1322 #endif
1323 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
1324 if (pteidx_p)
1325 *pteidx_p = pmap_pvo_pte_index(pvo, ptegidx);
1326 return pvo;
1327 }
1328 }
1329 return NULL;
1330 }
1331
1332 #if defined(DEBUG) || defined(PMAPCHECK)
1333 void
1334 pmap_pvo_check(const struct pvo_entry *pvo)
1335 {
1336 struct pvo_head *pvo_head;
1337 struct pvo_entry *pvo0;
1338 volatile struct pte *pt;
1339 int failed = 0;
1340
1341 if ((uintptr_t)(pvo+1) >= SEGMENT_LENGTH)
1342 panic("pmap_pvo_check: pvo %p: invalid address", pvo);
1343
1344 if ((uintptr_t)(pvo->pvo_pmap+1) >= SEGMENT_LENGTH) {
1345 printf("pmap_pvo_check: pvo %p: invalid pmap address %p\n",
1346 pvo, pvo->pvo_pmap);
1347 failed = 1;
1348 }
1349
1350 if ((uintptr_t)TAILQ_NEXT(pvo, pvo_olink) >= SEGMENT_LENGTH ||
1351 (((uintptr_t)TAILQ_NEXT(pvo, pvo_olink)) & 0x1f) != 0) {
1352 printf("pmap_pvo_check: pvo %p: invalid ovlink address %p\n",
1353 pvo, TAILQ_NEXT(pvo, pvo_olink));
1354 failed = 1;
1355 }
1356
1357 if ((uintptr_t)LIST_NEXT(pvo, pvo_vlink) >= SEGMENT_LENGTH ||
1358 (((uintptr_t)LIST_NEXT(pvo, pvo_vlink)) & 0x1f) != 0) {
1359 printf("pmap_pvo_check: pvo %p: invalid ovlink address %p\n",
1360 pvo, LIST_NEXT(pvo, pvo_vlink));
1361 failed = 1;
1362 }
1363
1364 if (pvo->pvo_vaddr & PVO_MANAGED) {
1365 pvo_head = pa_to_pvoh(pvo->pvo_pte.pte_lo & PTE_RPGN, NULL);
1366 } else {
1367 if (pvo->pvo_vaddr < VM_MIN_KERNEL_ADDRESS) {
1368 printf("pmap_pvo_check: pvo %p: non kernel address "
1369 "on kernel unmanaged list\n", pvo);
1370 failed = 1;
1371 }
1372 pvo_head = &pmap_pvo_kunmanaged;
1373 }
1374 LIST_FOREACH(pvo0, pvo_head, pvo_vlink) {
1375 if (pvo0 == pvo)
1376 break;
1377 }
1378 if (pvo0 == NULL) {
1379 printf("pmap_pvo_check: pvo %p: not present "
1380 "on its vlist head %p\n", pvo, pvo_head);
1381 failed = 1;
1382 }
1383 if (pvo != pmap_pvo_find_va(pvo->pvo_pmap, pvo->pvo_vaddr, NULL)) {
1384 printf("pmap_pvo_check: pvo %p: not present "
1385 "on its olist head\n", pvo);
1386 failed = 1;
1387 }
1388 pt = pmap_pvo_to_pte(pvo, -1);
1389 if (pt == NULL) {
1390 if (pvo->pvo_pte.pte_hi & PTE_VALID) {
1391 printf("pmap_pvo_check: pvo %p: pte_hi VALID but "
1392 "no PTE\n", pvo);
1393 failed = 1;
1394 }
1395 } else {
1396 if ((uintptr_t) pt < (uintptr_t) &pmap_pteg_table[0] ||
1397 (uintptr_t) pt >=
1398 (uintptr_t) &pmap_pteg_table[pmap_pteg_cnt]) {
1399 printf("pmap_pvo_check: pvo %p: pte %p not in "
1400 "pteg table\n", pvo, pt);
1401 failed = 1;
1402 }
1403 if (((((uintptr_t) pt) >> 3) & 7) != PVO_PTEGIDX_GET(pvo)) {
1404 printf("pmap_pvo_check: pvo %p: pte_hi VALID but "
1405 "no PTE\n", pvo);
1406 failed = 1;
1407 }
1408 if (pvo->pvo_pte.pte_hi != pt->pte_hi) {
1409 printf("pmap_pvo_check: pvo %p: pte_hi differ: "
1410 "%#lx/%#lx\n", pvo, pvo->pvo_pte.pte_hi, pt->pte_hi);
1411 failed = 1;
1412 }
1413 if (((pvo->pvo_pte.pte_lo ^ pt->pte_lo) &
1414 (PTE_PP|PTE_WIMG|PTE_RPGN)) != 0) {
1415 printf("pmap_pvo_check: pvo %p: pte_lo differ: "
1416 "%#lx/%#lx\n", pvo,
1417 pvo->pvo_pte.pte_lo & (PTE_PP|PTE_WIMG|PTE_RPGN),
1418 pt->pte_lo & (PTE_PP|PTE_WIMG|PTE_RPGN));
1419 failed = 1;
1420 }
1421 if ((pmap_pte_to_va(pt) ^ PVO_VADDR(pvo)) & 0x0fffffff) {
1422 printf("pmap_pvo_check: pvo %p: PTE %p derived VA %#lx"
1423 " doesn't not match PVO's VA %#lx\n",
1424 pvo, pt, pmap_pte_to_va(pt), PVO_VADDR(pvo));
1425 failed = 1;
1426 }
1427 if (failed)
1428 pmap_pte_print(pt);
1429 }
1430 if (failed)
1431 panic("pmap_pvo_check: pvo %p, pm %p: bugcheck!", pvo,
1432 pvo->pvo_pmap);
1433 }
1434 #endif /* DEBUG || PMAPCHECK */
1435
1436 /*
1437 * This returns whether this is the first mapping of a page.
1438 */
1439 int
1440 pmap_pvo_enter(pmap_t pm, struct pool *pl, struct pvo_head *pvo_head,
1441 vaddr_t va, paddr_t pa, register_t pte_lo, int flags)
1442 {
1443 struct pvo_entry *pvo;
1444 struct pvo_tqhead *pvoh;
1445 register_t msr;
1446 int ptegidx;
1447 int i;
1448 int poolflags = PR_NOWAIT;
1449
1450 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1451 if (pmap_pvo_remove_depth > 0)
1452 panic("pmap_pvo_enter: called while pmap_pvo_remove active!");
1453 if (++pmap_pvo_enter_depth > 1)
1454 panic("pmap_pvo_enter: called recursively!");
1455 #endif
1456
1457 /*
1458 * Compute the PTE Group index.
1459 */
1460 va &= ~ADDR_POFF;
1461 ptegidx = va_to_pteg(pm, va);
1462
1463 msr = pmap_interrupts_off();
1464 /*
1465 * Remove any existing mapping for this page. Reuse the
1466 * pvo entry if there a mapping.
1467 */
1468 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
1469 if (pvo->pvo_pmap == pm && PVO_VADDR(pvo) == va) {
1470 #ifdef DEBUG
1471 if ((pmapdebug & PMAPDEBUG_PVOENTER) &&
1472 ((pvo->pvo_pte.pte_lo ^ (pa|pte_lo)) &
1473 ~(PTE_REF|PTE_CHG)) == 0 &&
1474 va < VM_MIN_KERNEL_ADDRESS) {
1475 printf("pmap_pvo_enter: pvo %p: dup %#lx/%#lx\n",
1476 pvo, pvo->pvo_pte.pte_lo, pte_lo|pa);
1477 printf("pmap_pvo_enter: pte_hi=%#lx sr=%#lx\n",
1478 pvo->pvo_pte.pte_hi,
1479 pm->pm_sr[va >> ADDR_SR_SHFT]);
1480 pmap_pte_print(pmap_pvo_to_pte(pvo, -1));
1481 #ifdef DDBX
1482 Debugger();
1483 #endif
1484 }
1485 #endif
1486 PMAPCOUNT(mappings_replaced);
1487 pmap_pvo_remove(pvo, -1);
1488 break;
1489 }
1490 }
1491
1492 /*
1493 * If we aren't overwriting an mapping, try to allocate
1494 */
1495 pmap_interrupts_restore(msr);
1496 pvo = pool_get(pl, poolflags);
1497 msr = pmap_interrupts_off();
1498 if (pvo == NULL) {
1499 pvo = pmap_pvo_reclaim(pm);
1500 if (pvo == NULL) {
1501 if ((flags & PMAP_CANFAIL) == 0)
1502 panic("pmap_pvo_enter: failed");
1503 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1504 pmap_pvo_enter_depth--;
1505 #endif
1506 pmap_interrupts_restore(msr);
1507 return ENOMEM;
1508 }
1509 }
1510 pvo->pvo_vaddr = va;
1511 pvo->pvo_pmap = pm;
1512 pvo->pvo_vaddr &= ~ADDR_POFF;
1513 if (flags & VM_PROT_EXECUTE) {
1514 PMAPCOUNT(exec_mappings);
1515 pvo_set_exec(pvo);
1516 }
1517 if (flags & PMAP_WIRED)
1518 pvo->pvo_vaddr |= PVO_WIRED;
1519 if (pvo_head != &pmap_pvo_kunmanaged) {
1520 pvo->pvo_vaddr |= PVO_MANAGED;
1521 PMAPCOUNT(mappings);
1522 } else {
1523 PMAPCOUNT(kernel_mappings);
1524 }
1525 pmap_pte_create(&pvo->pvo_pte, pm, va, pa | pte_lo);
1526
1527 LIST_INSERT_HEAD(pvo_head, pvo, pvo_vlink);
1528 if (pvo->pvo_pte.pte_lo & PVO_WIRED)
1529 pvo->pvo_pmap->pm_stats.wired_count++;
1530 pvo->pvo_pmap->pm_stats.resident_count++;
1531 #if defined(DEBUG)
1532 if (pm != pmap_kernel() && va < VM_MIN_KERNEL_ADDRESS)
1533 DPRINTFN(PVOENTER,
1534 ("pmap_pvo_enter: pvo %p: pm %p va %#lx pa %#lx\n",
1535 pvo, pm, va, pa));
1536 #endif
1537
1538 /*
1539 * We hope this succeeds but it isn't required.
1540 */
1541 pvoh = &pmap_pvo_table[ptegidx];
1542 i = pmap_pte_insert(ptegidx, &pvo->pvo_pte);
1543 if (i >= 0) {
1544 PVO_PTEGIDX_SET(pvo, i);
1545 PVO_WHERE(pvo, ENTER_INSERT);
1546 PMAPCOUNT2(((pvo->pvo_pte.pte_hi & PTE_HID)
1547 ? pmap_evcnt_ptes_secondary : pmap_evcnt_ptes_primary)[i]);
1548 TAILQ_INSERT_TAIL(pvoh, pvo, pvo_olink);
1549 } else {
1550 /*
1551 * Since we didn't have room for this entry (which makes it
1552 * and evicted entry), place it at the head of the list.
1553 */
1554 TAILQ_INSERT_HEAD(pvoh, pvo, pvo_olink);
1555 PMAPCOUNT(ptes_evicted);
1556 pm->pm_evictions++;
1557 /*
1558 * If this is a kernel page, make sure it's active.
1559 */
1560 if (pm == pmap_kernel()) {
1561 i = pmap_pte_spill(pm, va, FALSE);
1562 KASSERT(i);
1563 }
1564 }
1565 PMAP_PVO_CHECK(pvo); /* sanity check */
1566 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1567 pmap_pvo_enter_depth--;
1568 #endif
1569 pmap_interrupts_restore(msr);
1570 return 0;
1571 }
1572
1573 void
1574 pmap_pvo_remove(struct pvo_entry *pvo, int pteidx)
1575 {
1576 volatile struct pte *pt;
1577 int ptegidx;
1578
1579 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1580 if (++pmap_pvo_remove_depth > 1)
1581 panic("pmap_pvo_remove: called recursively!");
1582 #endif
1583
1584 /*
1585 * If we haven't been supplied the ptegidx, calculate it.
1586 */
1587 if (pteidx == -1) {
1588 ptegidx = va_to_pteg(pvo->pvo_pmap, pvo->pvo_vaddr);
1589 pteidx = pmap_pvo_pte_index(pvo, ptegidx);
1590 } else {
1591 ptegidx = pteidx >> 3;
1592 if (pvo->pvo_pte.pte_hi & PTE_HID)
1593 ptegidx ^= pmap_pteg_mask;
1594 }
1595 PMAP_PVO_CHECK(pvo); /* sanity check */
1596
1597 /*
1598 * If there is an active pte entry, we need to deactivate it
1599 * (and save the ref & chg bits).
1600 */
1601 pt = pmap_pvo_to_pte(pvo, pteidx);
1602 if (pt != NULL) {
1603 pmap_pte_unset(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
1604 PVO_WHERE(pvo, REMOVE);
1605 PVO_PTEGIDX_CLR(pvo);
1606 PMAPCOUNT(ptes_removed);
1607 } else {
1608 KASSERT(pvo->pvo_pmap->pm_evictions > 0);
1609 pvo->pvo_pmap->pm_evictions--;
1610 }
1611
1612 /*
1613 * Account for executable mappings.
1614 */
1615 if (PVO_ISEXECUTABLE(pvo))
1616 pvo_clear_exec(pvo);
1617
1618 /*
1619 * Update our statistics.
1620 */
1621 pvo->pvo_pmap->pm_stats.resident_count--;
1622 if (pvo->pvo_pte.pte_lo & PVO_WIRED)
1623 pvo->pvo_pmap->pm_stats.wired_count--;
1624
1625 /*
1626 * Save the REF/CHG bits into their cache if the page is managed.
1627 */
1628 if (pvo->pvo_vaddr & PVO_MANAGED) {
1629 register_t ptelo = pvo->pvo_pte.pte_lo;
1630 struct vm_page *pg = PHYS_TO_VM_PAGE(ptelo & PTE_RPGN);
1631
1632 if (pg != NULL) {
1633 pmap_attr_save(pg, ptelo & (PTE_REF|PTE_CHG));
1634 }
1635 PMAPCOUNT(unmappings);
1636 } else {
1637 PMAPCOUNT(kernel_unmappings);
1638 }
1639
1640 /*
1641 * Remove the PVO from its lists and return it to the pool.
1642 */
1643 LIST_REMOVE(pvo, pvo_vlink);
1644 TAILQ_REMOVE(&pmap_pvo_table[ptegidx], pvo, pvo_olink);
1645 pool_put(pvo->pvo_vaddr & PVO_MANAGED
1646 ? &pmap_mpvo_pool : &pmap_upvo_pool, pvo);
1647 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
1648 pmap_pvo_remove_depth--;
1649 #endif
1650 }
1651
1652 /*
1653 * Mark a mapping as executable.
1654 * If this is the first executable mapping in the segment,
1655 * clear the noexec flag.
1656 */
1657 STATIC void
1658 pvo_set_exec(struct pvo_entry *pvo)
1659 {
1660 struct pmap *pm = pvo->pvo_pmap;
1661 int sr;
1662
1663 if (pm == pmap_kernel() || PVO_ISEXECUTABLE(pvo)) {
1664 return;
1665 }
1666 pvo->pvo_vaddr |= PVO_EXECUTABLE;
1667 sr = PVO_VADDR(pvo) >> ADDR_SR_SHFT;
1668 if (pm->pm_exec[sr]++ == 0) {
1669 pm->pm_sr[sr] &= ~SR_NOEXEC;
1670 }
1671 }
1672
1673 /*
1674 * Mark a mapping as non-executable.
1675 * If this was the last executable mapping in the segment,
1676 * set the noexec flag.
1677 */
1678 STATIC void
1679 pvo_clear_exec(struct pvo_entry *pvo)
1680 {
1681 struct pmap *pm = pvo->pvo_pmap;
1682 int sr;
1683
1684 if (pm == pmap_kernel() || !PVO_ISEXECUTABLE(pvo)) {
1685 return;
1686 }
1687 pvo->pvo_vaddr &= ~PVO_EXECUTABLE;
1688 sr = PVO_VADDR(pvo) >> ADDR_SR_SHFT;
1689 if (--pm->pm_exec[sr] == 0) {
1690 pm->pm_sr[sr] |= SR_NOEXEC;
1691 }
1692 }
1693
1694 /*
1695 * Insert physical page at pa into the given pmap at virtual address va.
1696 */
1697 int
1698 pmap_enter(pmap_t pm, vaddr_t va, paddr_t pa, vm_prot_t prot, int flags)
1699 {
1700 struct mem_region *mp;
1701 struct pvo_head *pvo_head;
1702 struct vm_page *pg;
1703 struct pool *pl;
1704 register_t pte_lo;
1705 int error;
1706 u_int pvo_flags;
1707 u_int was_exec = 0;
1708
1709 if (__predict_false(!pmap_initialized)) {
1710 pvo_head = &pmap_pvo_kunmanaged;
1711 pl = &pmap_upvo_pool;
1712 pvo_flags = 0;
1713 pg = NULL;
1714 was_exec = PTE_EXEC;
1715 } else {
1716 pvo_head = pa_to_pvoh(pa, &pg);
1717 pl = &pmap_mpvo_pool;
1718 pvo_flags = PVO_MANAGED;
1719 }
1720
1721 DPRINTFN(ENTER,
1722 ("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x):",
1723 pm, va, pa, prot, flags));
1724
1725 /*
1726 * If this is a managed page, and it's the first reference to the
1727 * page clear the execness of the page. Otherwise fetch the execness.
1728 */
1729 if (pg != NULL)
1730 was_exec = pmap_attr_fetch(pg) & PTE_EXEC;
1731
1732 DPRINTFN(ENTER, (" was_exec=%d", was_exec));
1733
1734 /*
1735 * Assume the page is cache inhibited and access is guarded unless
1736 * it's in our available memory array. If it is in the memory array,
1737 * asssume it's in memory coherent memory.
1738 */
1739 pte_lo = PTE_IG;
1740 if ((flags & PMAP_NC) == 0) {
1741 for (mp = mem; mp->size; mp++) {
1742 if (pa >= mp->start && pa < mp->start + mp->size) {
1743 pte_lo = PTE_M;
1744 break;
1745 }
1746 }
1747 }
1748
1749 if (prot & VM_PROT_WRITE)
1750 pte_lo |= PTE_BW;
1751 else
1752 pte_lo |= PTE_BR;
1753
1754 /*
1755 * If this was in response to a fault, "pre-fault" the PTE's
1756 * changed/referenced bit appropriately.
1757 */
1758 if (flags & VM_PROT_WRITE)
1759 pte_lo |= PTE_CHG;
1760 if (flags & (VM_PROT_READ|VM_PROT_WRITE))
1761 pte_lo |= PTE_REF;
1762
1763 /*
1764 * We need to know if this page can be executable
1765 */
1766 flags |= (prot & VM_PROT_EXECUTE);
1767
1768 /*
1769 * Record mapping for later back-translation and pte spilling.
1770 * This will overwrite any existing mapping.
1771 */
1772 error = pmap_pvo_enter(pm, pl, pvo_head, va, pa, pte_lo, flags);
1773
1774 /*
1775 * Flush the real page from the instruction cache if this page is
1776 * mapped executable and cacheable and has not been flushed since
1777 * the last time it was modified.
1778 */
1779 if (error == 0 &&
1780 (flags & VM_PROT_EXECUTE) &&
1781 (pte_lo & PTE_I) == 0 &&
1782 was_exec == 0) {
1783 DPRINTFN(ENTER, (" syncicache"));
1784 PMAPCOUNT(exec_synced);
1785 pmap_syncicache(pa, PAGE_SIZE);
1786 if (pg != NULL) {
1787 pmap_attr_save(pg, PTE_EXEC);
1788 PMAPCOUNT(exec_cached);
1789 #if defined(DEBUG) || defined(PMAPDEBUG)
1790 if (pmapdebug & PMAPDEBUG_ENTER)
1791 printf(" marked-as-exec");
1792 else if (pmapdebug & PMAPDEBUG_EXEC)
1793 printf("[pmap_enter: %#lx: marked-as-exec]\n",
1794 pg->phys_addr);
1795
1796 #endif
1797 }
1798 }
1799
1800 DPRINTFN(ENTER, (": error=%d\n", error));
1801
1802 return error;
1803 }
1804
1805 void
1806 pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot)
1807 {
1808 struct mem_region *mp;
1809 register_t pte_lo;
1810 int error;
1811
1812 if (va < VM_MIN_KERNEL_ADDRESS)
1813 panic("pmap_kenter_pa: attempt to enter "
1814 "non-kernel address %#lx!", va);
1815
1816 DPRINTFN(KENTER,
1817 ("pmap_kenter_pa(%#lx,%#lx,%#x)\n", va, pa, prot));
1818
1819 /*
1820 * Assume the page is cache inhibited and access is guarded unless
1821 * it's in our available memory array. If it is in the memory array,
1822 * asssume it's in memory coherent memory.
1823 */
1824 pte_lo = PTE_IG;
1825 if ((prot & PMAP_NC) == 0) {
1826 for (mp = mem; mp->size; mp++) {
1827 if (pa >= mp->start && pa < mp->start + mp->size) {
1828 pte_lo = PTE_M;
1829 break;
1830 }
1831 }
1832 }
1833
1834 if (prot & VM_PROT_WRITE)
1835 pte_lo |= PTE_BW;
1836 else
1837 pte_lo |= PTE_BR;
1838
1839 /*
1840 * We don't care about REF/CHG on PVOs on the unmanaged list.
1841 */
1842 error = pmap_pvo_enter(pmap_kernel(), &pmap_upvo_pool,
1843 &pmap_pvo_kunmanaged, va, pa, pte_lo, prot|PMAP_WIRED);
1844
1845 if (error != 0)
1846 panic("pmap_kenter_pa: failed to enter va %#lx pa %#lx: %d",
1847 va, pa, error);
1848 }
1849
1850 void
1851 pmap_kremove(vaddr_t va, vsize_t len)
1852 {
1853 if (va < VM_MIN_KERNEL_ADDRESS)
1854 panic("pmap_kremove: attempt to remove "
1855 "non-kernel address %#lx!", va);
1856
1857 DPRINTFN(KREMOVE,("pmap_kremove(%#lx,%#lx)\n", va, len));
1858 pmap_remove(pmap_kernel(), va, va + len);
1859 }
1860
1861 /*
1862 * Remove the given range of mapping entries.
1863 */
1864 void
1865 pmap_remove(pmap_t pm, vaddr_t va, vaddr_t endva)
1866 {
1867 struct pvo_entry *pvo;
1868 register_t msr;
1869 int pteidx;
1870
1871 msr = pmap_interrupts_off();
1872 for (; va < endva; va += PAGE_SIZE) {
1873 pvo = pmap_pvo_find_va(pm, va, &pteidx);
1874 if (pvo != NULL) {
1875 pmap_pvo_remove(pvo, pteidx);
1876 }
1877 }
1878 pmap_interrupts_restore(msr);
1879 }
1880
1881 /*
1882 * Get the physical page address for the given pmap/virtual address.
1883 */
1884 boolean_t
1885 pmap_extract(pmap_t pm, vaddr_t va, paddr_t *pap)
1886 {
1887 struct pvo_entry *pvo;
1888 register_t msr;
1889
1890 /*
1891 * If this is a kernel pmap lookup, also check the battable
1892 * and if we get a hit, translate the VA to a PA using the
1893 * BAT entries. Don't check for VM_MAX_KENREL_ADDRESS is
1894 * that will wrap back to 0.
1895 */
1896 if (pm == pmap_kernel() &&
1897 (va < VM_MIN_KERNEL_ADDRESS ||
1898 (KERNEL2_SR < 15 && VM_MAX_KERNEL_ADDRESS <= va))) {
1899 register_t batu = battable[va >> ADDR_SR_SHFT].batu;
1900 KASSERT((va >> ADDR_SR_SHFT) != USER_SR);
1901 if (BAT_VALID_P(batu,0) && BAT_VA_MATCH_P(batu,va)) {
1902 register_t batl = battable[va >> ADDR_SR_SHFT].batl;
1903 register_t mask = (~(batu & BAT_BL) << 15) & ~0x1ffffL;
1904 *pap = (batl & mask) | (va & ~mask);
1905 return TRUE;
1906 }
1907 return FALSE;
1908 }
1909
1910 msr = pmap_interrupts_off();
1911 pvo = pmap_pvo_find_va(pm, va & ~ADDR_POFF, NULL);
1912 if (pvo != NULL) {
1913 PMAP_PVO_CHECK(pvo); /* sanity check */
1914 *pap = (pvo->pvo_pte.pte_lo & PTE_RPGN) | (va & ADDR_POFF);
1915 }
1916 pmap_interrupts_restore(msr);
1917 return pvo != NULL;
1918 }
1919
1920 /*
1921 * Lower the protection on the specified range of this pmap.
1922 */
1923 void
1924 pmap_protect(pmap_t pm, vaddr_t va, vaddr_t endva, vm_prot_t prot)
1925 {
1926 struct pvo_entry *pvo;
1927 volatile struct pte *pt;
1928 register_t msr;
1929 int pteidx;
1930
1931 /*
1932 * Since this routine only downgrades protection, we should
1933 * always be called with at least one bit not set.
1934 */
1935 KASSERT(prot != VM_PROT_ALL);
1936
1937 /*
1938 * If there is no protection, this is equivalent to
1939 * remove the pmap from the pmap.
1940 */
1941 if ((prot & VM_PROT_READ) == 0) {
1942 pmap_remove(pm, va, endva);
1943 return;
1944 }
1945
1946 msr = pmap_interrupts_off();
1947 for (; va < endva; va += PAGE_SIZE) {
1948 pvo = pmap_pvo_find_va(pm, va, &pteidx);
1949 if (pvo == NULL)
1950 continue;
1951 PMAP_PVO_CHECK(pvo); /* sanity check */
1952
1953 /*
1954 * Revoke executable if asked to do so.
1955 */
1956 if ((prot & VM_PROT_EXECUTE) == 0)
1957 pvo_clear_exec(pvo);
1958
1959 #if 0
1960 /*
1961 * If the page is already read-only, no change
1962 * needs to be made.
1963 */
1964 if ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_BR)
1965 continue;
1966 #endif
1967 /*
1968 * Grab the PTE pointer before we diddle with
1969 * the cached PTE copy.
1970 */
1971 pt = pmap_pvo_to_pte(pvo, pteidx);
1972 /*
1973 * Change the protection of the page.
1974 */
1975 pvo->pvo_pte.pte_lo &= ~PTE_PP;
1976 pvo->pvo_pte.pte_lo |= PTE_BR;
1977
1978 /*
1979 * If the PVO is in the page table, update
1980 * that pte at well.
1981 */
1982 if (pt != NULL) {
1983 pmap_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
1984 PVO_WHERE(pvo, PMAP_PROTECT);
1985 PMAPCOUNT(ptes_changed);
1986 }
1987
1988 PMAP_PVO_CHECK(pvo); /* sanity check */
1989 }
1990 pmap_interrupts_restore(msr);
1991 }
1992
1993 void
1994 pmap_unwire(pmap_t pm, vaddr_t va)
1995 {
1996 struct pvo_entry *pvo;
1997 register_t msr;
1998
1999 msr = pmap_interrupts_off();
2000 pvo = pmap_pvo_find_va(pm, va, NULL);
2001 if (pvo != NULL) {
2002 if (pvo->pvo_vaddr & PVO_WIRED) {
2003 pvo->pvo_vaddr &= ~PVO_WIRED;
2004 pm->pm_stats.wired_count--;
2005 }
2006 PMAP_PVO_CHECK(pvo); /* sanity check */
2007 }
2008 pmap_interrupts_restore(msr);
2009 }
2010
2011 /*
2012 * Lower the protection on the specified physical page.
2013 */
2014 void
2015 pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
2016 {
2017 struct pvo_head *pvo_head;
2018 struct pvo_entry *pvo, *next_pvo;
2019 volatile struct pte *pt;
2020 register_t msr;
2021
2022 KASSERT(prot != VM_PROT_ALL);
2023 msr = pmap_interrupts_off();
2024
2025 /*
2026 * When UVM reuses a page, it does a pmap_page_protect with
2027 * VM_PROT_NONE. At that point, we can clear the exec flag
2028 * since we know the page will have different contents.
2029 */
2030 if ((prot & VM_PROT_READ) == 0) {
2031 DPRINTFN(EXEC, ("[pmap_page_protect: %#lx: clear-exec]\n",
2032 pg->phys_addr));
2033 if (pmap_attr_fetch(pg) & PTE_EXEC) {
2034 PMAPCOUNT(exec_uncached_page_protect);
2035 pmap_attr_clear(pg, PTE_EXEC);
2036 }
2037 }
2038
2039 pvo_head = vm_page_to_pvoh(pg);
2040 for (pvo = LIST_FIRST(pvo_head); pvo != NULL; pvo = next_pvo) {
2041 next_pvo = LIST_NEXT(pvo, pvo_vlink);
2042 PMAP_PVO_CHECK(pvo); /* sanity check */
2043
2044 /*
2045 * Downgrading to no mapping at all, we just remove the entry.
2046 */
2047 if ((prot & VM_PROT_READ) == 0) {
2048 pmap_pvo_remove(pvo, -1);
2049 continue;
2050 }
2051
2052 /*
2053 * If EXEC permission is being revoked, just clear the
2054 * flag in the PVO.
2055 */
2056 if ((prot & VM_PROT_EXECUTE) == 0)
2057 pvo_clear_exec(pvo);
2058
2059 /*
2060 * If this entry is already RO, don't diddle with the
2061 * page table.
2062 */
2063 if ((pvo->pvo_pte.pte_lo & PTE_PP) == PTE_BR) {
2064 PMAP_PVO_CHECK(pvo);
2065 continue;
2066 }
2067
2068 /*
2069 * Grab the PTE before the we diddle the bits so
2070 * pvo_to_pte can verify the pte contents are as
2071 * expected.
2072 */
2073 pt = pmap_pvo_to_pte(pvo, -1);
2074 pvo->pvo_pte.pte_lo &= ~PTE_PP;
2075 pvo->pvo_pte.pte_lo |= PTE_BR;
2076 if (pt != NULL) {
2077 pmap_pte_change(pt, &pvo->pvo_pte, pvo->pvo_vaddr);
2078 PVO_WHERE(pvo, PMAP_PAGE_PROTECT);
2079 PMAPCOUNT(ptes_changed);
2080 }
2081 PMAP_PVO_CHECK(pvo); /* sanity check */
2082 }
2083 pmap_interrupts_restore(msr);
2084 }
2085
2086 /*
2087 * Activate the address space for the specified process. If the process
2088 * is the current process, load the new MMU context.
2089 */
2090 void
2091 pmap_activate(struct lwp *l)
2092 {
2093 struct pcb *pcb = &l->l_addr->u_pcb;
2094 pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap;
2095
2096 DPRINTFN(ACTIVATE,
2097 ("pmap_activate: lwp %p (curlwp %p)\n", l, curlwp));
2098
2099 /*
2100 * XXX Normally performed in cpu_fork().
2101 */
2102 pcb->pcb_pm = pmap;
2103 }
2104
2105 /*
2106 * Deactivate the specified process's address space.
2107 */
2108 void
2109 pmap_deactivate(struct lwp *l)
2110 {
2111 }
2112
2113 boolean_t
2114 pmap_query_bit(struct vm_page *pg, int ptebit)
2115 {
2116 struct pvo_entry *pvo;
2117 volatile struct pte *pt;
2118 register_t msr;
2119
2120 if (pmap_attr_fetch(pg) & ptebit)
2121 return TRUE;
2122
2123 msr = pmap_interrupts_off();
2124 LIST_FOREACH(pvo, vm_page_to_pvoh(pg), pvo_vlink) {
2125 PMAP_PVO_CHECK(pvo); /* sanity check */
2126 /*
2127 * See if we saved the bit off. If so cache, it and return
2128 * success.
2129 */
2130 if (pvo->pvo_pte.pte_lo & ptebit) {
2131 pmap_attr_save(pg, ptebit);
2132 PMAP_PVO_CHECK(pvo); /* sanity check */
2133 pmap_interrupts_restore(msr);
2134 return TRUE;
2135 }
2136 }
2137 /*
2138 * No luck, now go thru the hard part of looking at the ptes
2139 * themselves. Sync so any pending REF/CHG bits are flushed
2140 * to the PTEs.
2141 */
2142 SYNC();
2143 LIST_FOREACH(pvo, vm_page_to_pvoh(pg), pvo_vlink) {
2144 PMAP_PVO_CHECK(pvo); /* sanity check */
2145 /*
2146 * See if this pvo have a valid PTE. If so, fetch the
2147 * REF/CHG bits from the valid PTE. If the appropriate
2148 * ptebit is set, cache, it and return success.
2149 */
2150 pt = pmap_pvo_to_pte(pvo, -1);
2151 if (pt != NULL) {
2152 pmap_pte_synch(pt, &pvo->pvo_pte);
2153 if (pvo->pvo_pte.pte_lo & ptebit) {
2154 pmap_attr_save(pg, ptebit);
2155 PMAP_PVO_CHECK(pvo); /* sanity check */
2156 pmap_interrupts_restore(msr);
2157 return TRUE;
2158 }
2159 }
2160 }
2161 pmap_interrupts_restore(msr);
2162 return FALSE;
2163 }
2164
2165 boolean_t
2166 pmap_clear_bit(struct vm_page *pg, int ptebit)
2167 {
2168 struct pvo_head *pvoh = vm_page_to_pvoh(pg);
2169 struct pvo_entry *pvo;
2170 volatile struct pte *pt;
2171 register_t msr;
2172 int rv = 0;
2173
2174 msr = pmap_interrupts_off();
2175
2176 /*
2177 * Fetch the cache value
2178 */
2179 rv |= pmap_attr_fetch(pg);
2180
2181 /*
2182 * Clear the cached value.
2183 */
2184 pmap_attr_clear(pg, ptebit);
2185
2186 /*
2187 * Sync so any pending REF/CHG bits are flushed to the PTEs (so we
2188 * can reset the right ones). Note that since the pvo entries and
2189 * list heads are accessed via BAT0 and are never placed in the
2190 * page table, we don't have to worry about further accesses setting
2191 * the REF/CHG bits.
2192 */
2193 SYNC();
2194
2195 /*
2196 * For each pvo entry, clear pvo's ptebit. If this pvo have a
2197 * valid PTE. If so, clear the ptebit from the valid PTE.
2198 */
2199 LIST_FOREACH(pvo, pvoh, pvo_vlink) {
2200 PMAP_PVO_CHECK(pvo); /* sanity check */
2201 pt = pmap_pvo_to_pte(pvo, -1);
2202 if (pt != NULL) {
2203 /*
2204 * Only sync the PTE if the bit we are looking
2205 * for is not already set.
2206 */
2207 if ((pvo->pvo_pte.pte_lo & ptebit) == 0)
2208 pmap_pte_synch(pt, &pvo->pvo_pte);
2209 /*
2210 * If the bit we are looking for was already set,
2211 * clear that bit in the pte.
2212 */
2213 if (pvo->pvo_pte.pte_lo & ptebit)
2214 pmap_pte_clear(pt, PVO_VADDR(pvo), ptebit);
2215 }
2216 rv |= pvo->pvo_pte.pte_lo & (PTE_CHG|PTE_REF);
2217 pvo->pvo_pte.pte_lo &= ~ptebit;
2218 PMAP_PVO_CHECK(pvo); /* sanity check */
2219 }
2220 pmap_interrupts_restore(msr);
2221
2222 /*
2223 * If we are clearing the modify bit and this page was marked EXEC
2224 * and the user of the page thinks the page was modified, then we
2225 * need to clean it from the icache if it's mapped or clear the EXEC
2226 * bit if it's not mapped. The page itself might not have the CHG
2227 * bit set if the modification was done via DMA to the page.
2228 */
2229 if ((ptebit & PTE_CHG) && (rv & PTE_EXEC)) {
2230 if (LIST_EMPTY(pvoh)) {
2231 DPRINTFN(EXEC, ("[pmap_clear_bit: %#lx: clear-exec]\n",
2232 pg->phys_addr));
2233 pmap_attr_clear(pg, PTE_EXEC);
2234 PMAPCOUNT(exec_uncached_clear_modify);
2235 } else {
2236 DPRINTFN(EXEC, ("[pmap_clear_bit: %#lx: syncicache]\n",
2237 pg->phys_addr));
2238 pmap_syncicache(pg->phys_addr, PAGE_SIZE);
2239 PMAPCOUNT(exec_synced_clear_modify);
2240 }
2241 }
2242 return (rv & ptebit) != 0;
2243 }
2244
2245 void
2246 pmap_procwr(struct proc *p, vaddr_t va, size_t len)
2247 {
2248 struct pvo_entry *pvo;
2249 size_t offset = va & ADDR_POFF;
2250 int s;
2251
2252 s = splvm();
2253 while (len > 0) {
2254 size_t seglen = PAGE_SIZE - offset;
2255 if (seglen > len)
2256 seglen = len;
2257 pvo = pmap_pvo_find_va(p->p_vmspace->vm_map.pmap, va, NULL);
2258 if (pvo != NULL && PVO_ISEXECUTABLE(pvo)) {
2259 pmap_syncicache(
2260 (pvo->pvo_pte.pte_lo & PTE_RPGN) | offset, seglen);
2261 PMAP_PVO_CHECK(pvo);
2262 }
2263 va += seglen;
2264 len -= seglen;
2265 offset = 0;
2266 }
2267 splx(s);
2268 }
2269
2270 #if defined(DEBUG) || defined(PMAPCHECK) || defined(DDB)
2271 void
2272 pmap_pte_print(volatile struct pte *pt)
2273 {
2274 printf("PTE %p: ", pt);
2275 /* High word: */
2276 printf("0x%08lx: [", pt->pte_hi);
2277 printf("%c ", (pt->pte_hi & PTE_VALID) ? 'v' : 'i');
2278 printf("%c ", (pt->pte_hi & PTE_HID) ? 'h' : '-');
2279 printf("0x%06lx 0x%02lx",
2280 (pt->pte_hi &~ PTE_VALID)>>PTE_VSID_SHFT,
2281 pt->pte_hi & PTE_API);
2282 printf(" (va 0x%08lx)] ", pmap_pte_to_va(pt));
2283 /* Low word: */
2284 printf(" 0x%08lx: [", pt->pte_lo);
2285 printf("0x%05lx... ", pt->pte_lo >> 12);
2286 printf("%c ", (pt->pte_lo & PTE_REF) ? 'r' : 'u');
2287 printf("%c ", (pt->pte_lo & PTE_CHG) ? 'c' : 'n');
2288 printf("%c", (pt->pte_lo & PTE_W) ? 'w' : '.');
2289 printf("%c", (pt->pte_lo & PTE_I) ? 'i' : '.');
2290 printf("%c", (pt->pte_lo & PTE_M) ? 'm' : '.');
2291 printf("%c ", (pt->pte_lo & PTE_G) ? 'g' : '.');
2292 switch (pt->pte_lo & PTE_PP) {
2293 case PTE_BR: printf("br]\n"); break;
2294 case PTE_BW: printf("bw]\n"); break;
2295 case PTE_SO: printf("so]\n"); break;
2296 case PTE_SW: printf("sw]\n"); break;
2297 }
2298 }
2299 #endif
2300
2301 #if defined(DDB)
2302 void
2303 pmap_pteg_check(void)
2304 {
2305 volatile struct pte *pt;
2306 int i;
2307 int ptegidx;
2308 u_int p_valid = 0;
2309 u_int s_valid = 0;
2310 u_int invalid = 0;
2311
2312 for (ptegidx = 0; ptegidx < pmap_pteg_cnt; ptegidx++) {
2313 for (pt = pmap_pteg_table[ptegidx].pt, i = 8; --i >= 0; pt++) {
2314 if (pt->pte_hi & PTE_VALID) {
2315 if (pt->pte_hi & PTE_HID)
2316 s_valid++;
2317 else
2318 p_valid++;
2319 } else
2320 invalid++;
2321 }
2322 }
2323 printf("pteg_check: v(p) %#x (%d), v(s) %#x (%d), i %#x (%d)\n",
2324 p_valid, p_valid, s_valid, s_valid,
2325 invalid, invalid);
2326 }
2327
2328 void
2329 pmap_print_mmuregs(void)
2330 {
2331 int i;
2332 u_int cpuvers;
2333 vaddr_t addr;
2334 register_t soft_sr[16];
2335 struct bat soft_ibat[4];
2336 struct bat soft_dbat[4];
2337 register_t sdr1;
2338
2339 cpuvers = MFPVR() >> 16;
2340
2341 __asm __volatile ("mfsdr1 %0" : "=r"(sdr1));
2342 for (i=0; i<16; i++) {
2343 soft_sr[i] = MFSRIN(addr);
2344 addr += (1 << ADDR_SR_SHFT);
2345 }
2346
2347 /* read iBAT (601: uBAT) registers */
2348 __asm __volatile ("mfibatu %0,0" : "=r"(soft_ibat[0].batu));
2349 __asm __volatile ("mfibatl %0,0" : "=r"(soft_ibat[0].batl));
2350 __asm __volatile ("mfibatu %0,1" : "=r"(soft_ibat[1].batu));
2351 __asm __volatile ("mfibatl %0,1" : "=r"(soft_ibat[1].batl));
2352 __asm __volatile ("mfibatu %0,2" : "=r"(soft_ibat[2].batu));
2353 __asm __volatile ("mfibatl %0,2" : "=r"(soft_ibat[2].batl));
2354 __asm __volatile ("mfibatu %0,3" : "=r"(soft_ibat[3].batu));
2355 __asm __volatile ("mfibatl %0,3" : "=r"(soft_ibat[3].batl));
2356
2357
2358 if (cpuvers != MPC601) {
2359 /* read dBAT registers */
2360 __asm __volatile ("mfdbatu %0,0" : "=r"(soft_dbat[0].batu));
2361 __asm __volatile ("mfdbatl %0,0" : "=r"(soft_dbat[0].batl));
2362 __asm __volatile ("mfdbatu %0,1" : "=r"(soft_dbat[1].batu));
2363 __asm __volatile ("mfdbatl %0,1" : "=r"(soft_dbat[1].batl));
2364 __asm __volatile ("mfdbatu %0,2" : "=r"(soft_dbat[2].batu));
2365 __asm __volatile ("mfdbatl %0,2" : "=r"(soft_dbat[2].batl));
2366 __asm __volatile ("mfdbatu %0,3" : "=r"(soft_dbat[3].batu));
2367 __asm __volatile ("mfdbatl %0,3" : "=r"(soft_dbat[3].batl));
2368 }
2369
2370 printf("SDR1:\t%#lx\n", sdr1);
2371 printf("SR[]:\t");
2372 addr = 0;
2373 for (i=0; i<4; i++)
2374 printf("0x%08lx, ", soft_sr[i]);
2375 printf("\n\t");
2376 for ( ; i<8; i++)
2377 printf("0x%08lx, ", soft_sr[i]);
2378 printf("\n\t");
2379 for ( ; i<12; i++)
2380 printf("0x%08lx, ", soft_sr[i]);
2381 printf("\n\t");
2382 for ( ; i<16; i++)
2383 printf("0x%08lx, ", soft_sr[i]);
2384 printf("\n");
2385
2386 printf("%cBAT[]:\t", cpuvers == MPC601 ? 'u' : 'i');
2387 for (i=0; i<4; i++) {
2388 printf("0x%08lx 0x%08lx, ",
2389 soft_ibat[i].batu, soft_ibat[i].batl);
2390 if (i == 1)
2391 printf("\n\t");
2392 }
2393 if (cpuvers != MPC601) {
2394 printf("\ndBAT[]:\t");
2395 for (i=0; i<4; i++) {
2396 printf("0x%08lx 0x%08lx, ",
2397 soft_dbat[i].batu, soft_dbat[i].batl);
2398 if (i == 1)
2399 printf("\n\t");
2400 }
2401 }
2402 printf("\n");
2403 }
2404
2405 void
2406 pmap_print_pte(pmap_t pm, vaddr_t va)
2407 {
2408 struct pvo_entry *pvo;
2409 volatile struct pte *pt;
2410 int pteidx;
2411
2412 pvo = pmap_pvo_find_va(pm, va, &pteidx);
2413 if (pvo != NULL) {
2414 pt = pmap_pvo_to_pte(pvo, pteidx);
2415 if (pt != NULL) {
2416 printf("VA %#lx -> %p -> %s %#lx, %#lx\n",
2417 va, pt,
2418 pt->pte_hi & PTE_HID ? "(sec)" : "(pri)",
2419 pt->pte_hi, pt->pte_lo);
2420 } else {
2421 printf("No valid PTE found\n");
2422 }
2423 } else {
2424 printf("Address not in pmap\n");
2425 }
2426 }
2427
2428 void
2429 pmap_pteg_dist(void)
2430 {
2431 struct pvo_entry *pvo;
2432 int ptegidx;
2433 int depth;
2434 int max_depth = 0;
2435 unsigned int depths[64];
2436
2437 memset(depths, 0, sizeof(depths));
2438 for (ptegidx = 0; ptegidx < pmap_pteg_cnt; ptegidx++) {
2439 depth = 0;
2440 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
2441 depth++;
2442 }
2443 if (depth > max_depth)
2444 max_depth = depth;
2445 if (depth > 63)
2446 depth = 63;
2447 depths[depth]++;
2448 }
2449
2450 for (depth = 0; depth < 64; depth++) {
2451 printf(" [%2d]: %8u", depth, depths[depth]);
2452 if ((depth & 3) == 3)
2453 printf("\n");
2454 if (depth == max_depth)
2455 break;
2456 }
2457 if ((depth & 3) != 3)
2458 printf("\n");
2459 printf("Max depth found was %d\n", max_depth);
2460 }
2461 #endif /* DEBUG */
2462
2463 #if defined(PMAPCHECK) || defined(DEBUG)
2464 void
2465 pmap_pvo_verify(void)
2466 {
2467 int ptegidx;
2468 int s;
2469
2470 s = splvm();
2471 for (ptegidx = 0; ptegidx < pmap_pteg_cnt; ptegidx++) {
2472 struct pvo_entry *pvo;
2473 TAILQ_FOREACH(pvo, &pmap_pvo_table[ptegidx], pvo_olink) {
2474 if ((uintptr_t) pvo >= SEGMENT_LENGTH)
2475 panic("pmap_pvo_verify: invalid pvo %p "
2476 "on list %#x", pvo, ptegidx);
2477 pmap_pvo_check(pvo);
2478 }
2479 }
2480 splx(s);
2481 }
2482 #endif /* PMAPCHECK */
2483
2484
2485 void *
2486 pmap_pool_ualloc(struct pool *pp, int flags)
2487 {
2488 struct pvo_page *pvop;
2489
2490 pvop = SIMPLEQ_FIRST(&pmap_upvop_head);
2491 if (pvop != NULL) {
2492 pmap_upvop_free--;
2493 SIMPLEQ_REMOVE_HEAD(&pmap_upvop_head, pvop_link);
2494 return pvop;
2495 }
2496 if (uvm.page_init_done != TRUE) {
2497 return (void *) uvm_pageboot_alloc(PAGE_SIZE);
2498 }
2499 return pmap_pool_malloc(pp, flags);
2500 }
2501
2502 void *
2503 pmap_pool_malloc(struct pool *pp, int flags)
2504 {
2505 struct pvo_page *pvop;
2506 struct vm_page *pg;
2507
2508 pvop = SIMPLEQ_FIRST(&pmap_mpvop_head);
2509 if (pvop != NULL) {
2510 pmap_mpvop_free--;
2511 SIMPLEQ_REMOVE_HEAD(&pmap_mpvop_head, pvop_link);
2512 return pvop;
2513 }
2514 again:
2515 pg = uvm_pagealloc_strat(NULL, 0, NULL, UVM_PGA_USERESERVE,
2516 UVM_PGA_STRAT_ONLY, VM_FREELIST_FIRST256);
2517 if (__predict_false(pg == NULL)) {
2518 if (flags & PR_WAITOK) {
2519 uvm_wait("plpg");
2520 goto again;
2521 } else {
2522 return (0);
2523 }
2524 }
2525 return (void *) VM_PAGE_TO_PHYS(pg);
2526 }
2527
2528 void
2529 pmap_pool_ufree(struct pool *pp, void *va)
2530 {
2531 struct pvo_page *pvop;
2532 #if 0
2533 if (PHYS_TO_VM_PAGE((paddr_t) va) != NULL) {
2534 pmap_pool_mfree(va, size, tag);
2535 return;
2536 }
2537 #endif
2538 pvop = va;
2539 SIMPLEQ_INSERT_HEAD(&pmap_upvop_head, pvop, pvop_link);
2540 pmap_upvop_free++;
2541 if (pmap_upvop_free > pmap_upvop_maxfree)
2542 pmap_upvop_maxfree = pmap_upvop_free;
2543 }
2544
2545 void
2546 pmap_pool_mfree(struct pool *pp, void *va)
2547 {
2548 struct pvo_page *pvop;
2549
2550 pvop = va;
2551 SIMPLEQ_INSERT_HEAD(&pmap_mpvop_head, pvop, pvop_link);
2552 pmap_mpvop_free++;
2553 if (pmap_mpvop_free > pmap_mpvop_maxfree)
2554 pmap_mpvop_maxfree = pmap_mpvop_free;
2555 #if 0
2556 uvm_pagefree(PHYS_TO_VM_PAGE((paddr_t) va));
2557 #endif
2558 }
2559
2560 /*
2561 * This routine in bootstraping to steal to-be-managed memory (which will
2562 * then be unmanaged). We use it to grab from the first 256MB for our
2563 * pmap needs and above 256MB for other stuff.
2564 */
2565 vaddr_t
2566 pmap_steal_memory(vsize_t vsize, vaddr_t *vstartp, vaddr_t *vendp)
2567 {
2568 vsize_t size;
2569 vaddr_t va;
2570 paddr_t pa = 0;
2571 int npgs, bank;
2572 struct vm_physseg *ps;
2573
2574 if (uvm.page_init_done == TRUE)
2575 panic("pmap_steal_memory: called _after_ bootstrap");
2576
2577 *vstartp = VM_MIN_KERNEL_ADDRESS;
2578 *vendp = VM_MAX_KERNEL_ADDRESS;
2579
2580 size = round_page(vsize);
2581 npgs = atop(size);
2582
2583 /*
2584 * PA 0 will never be among those given to UVM so we can use it
2585 * to indicate we couldn't steal any memory.
2586 */
2587 for (ps = vm_physmem, bank = 0; bank < vm_nphysseg; bank++, ps++) {
2588 if (ps->free_list == VM_FREELIST_FIRST256 &&
2589 ps->avail_end - ps->avail_start >= npgs) {
2590 pa = ptoa(ps->avail_start);
2591 break;
2592 }
2593 }
2594
2595 if (pa == 0)
2596 panic("pmap_steal_memory: no approriate memory to steal!");
2597
2598 ps->avail_start += npgs;
2599 ps->start += npgs;
2600
2601 /*
2602 * If we've used up all the pages in the segment, remove it and
2603 * compact the list.
2604 */
2605 if (ps->avail_start == ps->end) {
2606 /*
2607 * If this was the last one, then a very bad thing has occurred
2608 */
2609 if (--vm_nphysseg == 0)
2610 panic("pmap_steal_memory: out of memory!");
2611
2612 printf("pmap_steal_memory: consumed bank %d\n", bank);
2613 for (; bank < vm_nphysseg; bank++, ps++) {
2614 ps[0] = ps[1];
2615 }
2616 }
2617
2618 va = (vaddr_t) pa;
2619 memset((caddr_t) va, 0, size);
2620 pmap_pages_stolen += npgs;
2621 #ifdef DEBUG
2622 if (pmapdebug && npgs > 1) {
2623 u_int cnt = 0;
2624 for (bank = 0, ps = vm_physmem; bank < vm_nphysseg; bank++, ps++)
2625 cnt += ps->avail_end - ps->avail_start;
2626 printf("pmap_steal_memory: stole %u (total %u) pages (%u left)\n",
2627 npgs, pmap_pages_stolen, cnt);
2628 }
2629 #endif
2630
2631 return va;
2632 }
2633
2634 /*
2635 * Find a chuck of memory with right size and alignment.
2636 */
2637 void *
2638 pmap_boot_find_memory(psize_t size, psize_t alignment, int at_end)
2639 {
2640 struct mem_region *mp;
2641 paddr_t s, e;
2642 int i, j;
2643
2644 size = round_page(size);
2645
2646 DPRINTFN(BOOT,
2647 ("pmap_boot_find_memory: size=%lx, alignment=%lx, at_end=%d",
2648 size, alignment, at_end));
2649
2650 if (alignment < PAGE_SIZE || (alignment & (alignment-1)) != 0)
2651 panic("pmap_boot_find_memory: invalid alignment %lx",
2652 alignment);
2653
2654 if (at_end) {
2655 if (alignment != PAGE_SIZE)
2656 panic("pmap_boot_find_memory: invalid ending "
2657 "alignment %lx", alignment);
2658
2659 for (mp = &avail[avail_cnt-1]; mp >= avail; mp--) {
2660 s = mp->start + mp->size - size;
2661 if (s >= mp->start && mp->size >= size) {
2662 DPRINTFN(BOOT,(": %lx\n", s));
2663 DPRINTFN(BOOT,
2664 ("pmap_boot_find_memory: b-avail[%d] start "
2665 "0x%lx size 0x%lx\n", mp - avail,
2666 mp->start, mp->size));
2667 mp->size -= size;
2668 DPRINTFN(BOOT,
2669 ("pmap_boot_find_memory: a-avail[%d] start "
2670 "0x%lx size 0x%lx\n", mp - avail,
2671 mp->start, mp->size));
2672 return (void *) s;
2673 }
2674 }
2675 panic("pmap_boot_find_memory: no available memory");
2676 }
2677
2678 for (mp = avail, i = 0; i < avail_cnt; i++, mp++) {
2679 s = (mp->start + alignment - 1) & ~(alignment-1);
2680 e = s + size;
2681
2682 /*
2683 * Is the calculated region entirely within the region?
2684 */
2685 if (s < mp->start || e > mp->start + mp->size)
2686 continue;
2687
2688 DPRINTFN(BOOT,(": %lx\n", s));
2689 if (s == mp->start) {
2690 /*
2691 * If the block starts at the beginning of region,
2692 * adjust the size & start. (the region may now be
2693 * zero in length)
2694 */
2695 DPRINTFN(BOOT,
2696 ("pmap_boot_find_memory: b-avail[%d] start "
2697 "0x%lx size 0x%lx\n", i, mp->start, mp->size));
2698 mp->start += size;
2699 mp->size -= size;
2700 DPRINTFN(BOOT,
2701 ("pmap_boot_find_memory: a-avail[%d] start "
2702 "0x%lx size 0x%lx\n", i, mp->start, mp->size));
2703 } else if (e == mp->start + mp->size) {
2704 /*
2705 * If the block starts at the beginning of region,
2706 * adjust only the size.
2707 */
2708 DPRINTFN(BOOT,
2709 ("pmap_boot_find_memory: b-avail[%d] start "
2710 "0x%lx size 0x%lx\n", i, mp->start, mp->size));
2711 mp->size -= size;
2712 DPRINTFN(BOOT,
2713 ("pmap_boot_find_memory: a-avail[%d] start "
2714 "0x%lx size 0x%lx\n", i, mp->start, mp->size));
2715 } else {
2716 /*
2717 * Block is in the middle of the region, so we
2718 * have to split it in two.
2719 */
2720 for (j = avail_cnt; j > i + 1; j--) {
2721 avail[j] = avail[j-1];
2722 }
2723 DPRINTFN(BOOT,
2724 ("pmap_boot_find_memory: b-avail[%d] start "
2725 "0x%lx size 0x%lx\n", i, mp->start, mp->size));
2726 mp[1].start = e;
2727 mp[1].size = mp[0].start + mp[0].size - e;
2728 mp[0].size = s - mp[0].start;
2729 avail_cnt++;
2730 for (; i < avail_cnt; i++) {
2731 DPRINTFN(BOOT,
2732 ("pmap_boot_find_memory: a-avail[%d] "
2733 "start 0x%lx size 0x%lx\n", i,
2734 avail[i].start, avail[i].size));
2735 }
2736 }
2737 return (void *) s;
2738 }
2739 panic("pmap_boot_find_memory: not enough memory for "
2740 "%lx/%lx allocation?", size, alignment);
2741 }
2742
2743 /*
2744 * This is not part of the defined PMAP interface and is specific to the
2745 * PowerPC architecture. This is called during initppc, before the system
2746 * is really initialized.
2747 */
2748 void
2749 pmap_bootstrap(paddr_t kernelstart, paddr_t kernelend)
2750 {
2751 struct mem_region *mp, tmp;
2752 paddr_t s, e;
2753 psize_t size;
2754 int i, j;
2755
2756 /*
2757 * Get memory.
2758 */
2759 mem_regions(&mem, &avail);
2760 #if defined(DEBUG)
2761 if (pmapdebug & PMAPDEBUG_BOOT) {
2762 printf("pmap_bootstrap: memory configuration:\n");
2763 for (mp = mem; mp->size; mp++) {
2764 printf("pmap_bootstrap: mem start 0x%lx size 0x%lx\n",
2765 mp->start, mp->size);
2766 }
2767 for (mp = avail; mp->size; mp++) {
2768 printf("pmap_bootstrap: avail start 0x%lx size 0x%lx\n",
2769 mp->start, mp->size);
2770 }
2771 }
2772 #endif
2773
2774 /*
2775 * Find out how much physical memory we have and in how many chunks.
2776 */
2777 for (mem_cnt = 0, mp = mem; mp->size; mp++) {
2778 if (mp->start >= pmap_memlimit)
2779 continue;
2780 if (mp->start + mp->size > pmap_memlimit) {
2781 size = pmap_memlimit - mp->start;
2782 physmem += btoc(size);
2783 } else {
2784 physmem += btoc(mp->size);
2785 }
2786 mem_cnt++;
2787 }
2788
2789 /*
2790 * Count the number of available entries.
2791 */
2792 for (avail_cnt = 0, mp = avail; mp->size; mp++)
2793 avail_cnt++;
2794
2795 /*
2796 * Page align all regions.
2797 */
2798 kernelstart = trunc_page(kernelstart);
2799 kernelend = round_page(kernelend);
2800 for (mp = avail, i = 0; i < avail_cnt; i++, mp++) {
2801 s = round_page(mp->start);
2802 mp->size -= (s - mp->start);
2803 mp->size = trunc_page(mp->size);
2804 mp->start = s;
2805 e = mp->start + mp->size;
2806
2807 DPRINTFN(BOOT,
2808 ("pmap_bootstrap: b-avail[%d] start 0x%lx size 0x%lx\n",
2809 i, mp->start, mp->size));
2810
2811 /*
2812 * Don't allow the end to run beyond our artificial limit
2813 */
2814 if (e > pmap_memlimit)
2815 e = pmap_memlimit;
2816
2817 /*
2818 * Is this region empty or strange? skip it.
2819 */
2820 if (e <= s) {
2821 mp->start = 0;
2822 mp->size = 0;
2823 continue;
2824 }
2825
2826 /*
2827 * Does this overlap the beginning of kernel?
2828 * Does extend past the end of the kernel?
2829 */
2830 else if (s < kernelstart && e > kernelstart) {
2831 if (e > kernelend) {
2832 avail[avail_cnt].start = kernelend;
2833 avail[avail_cnt].size = e - kernelend;
2834 avail_cnt++;
2835 }
2836 mp->size = kernelstart - s;
2837 }
2838 /*
2839 * Check whether this region overlaps the end of the kernel.
2840 */
2841 else if (s < kernelend && e > kernelend) {
2842 mp->start = kernelend;
2843 mp->size = e - kernelend;
2844 }
2845 /*
2846 * Look whether this regions is completely inside the kernel.
2847 * Nuke it if it does.
2848 */
2849 else if (s >= kernelstart && e <= kernelend) {
2850 mp->start = 0;
2851 mp->size = 0;
2852 }
2853 /*
2854 * If the user imposed a memory limit, enforce it.
2855 */
2856 else if (s >= pmap_memlimit) {
2857 mp->start = -PAGE_SIZE; /* let's know why */
2858 mp->size = 0;
2859 }
2860 else {
2861 mp->start = s;
2862 mp->size = e - s;
2863 }
2864 DPRINTFN(BOOT,
2865 ("pmap_bootstrap: a-avail[%d] start 0x%lx size 0x%lx\n",
2866 i, mp->start, mp->size));
2867 }
2868
2869 /*
2870 * Move (and uncount) all the null return to the end.
2871 */
2872 for (mp = avail, i = 0; i < avail_cnt; i++, mp++) {
2873 if (mp->size == 0) {
2874 tmp = avail[i];
2875 avail[i] = avail[--avail_cnt];
2876 avail[avail_cnt] = avail[i];
2877 }
2878 }
2879
2880 /*
2881 * (Bubble)sort them into asecnding order.
2882 */
2883 for (i = 0; i < avail_cnt; i++) {
2884 for (j = i + 1; j < avail_cnt; j++) {
2885 if (avail[i].start > avail[j].start) {
2886 tmp = avail[i];
2887 avail[i] = avail[j];
2888 avail[j] = tmp;
2889 }
2890 }
2891 }
2892
2893 /*
2894 * Make sure they don't overlap.
2895 */
2896 for (mp = avail, i = 0; i < avail_cnt - 1; i++, mp++) {
2897 if (mp[0].start + mp[0].size > mp[1].start) {
2898 mp[0].size = mp[1].start - mp[0].start;
2899 }
2900 DPRINTFN(BOOT,
2901 ("pmap_bootstrap: avail[%d] start 0x%lx size 0x%lx\n",
2902 i, mp->start, mp->size));
2903 }
2904 DPRINTFN(BOOT,
2905 ("pmap_bootstrap: avail[%d] start 0x%lx size 0x%lx\n",
2906 i, mp->start, mp->size));
2907
2908 #ifdef PTEGCOUNT
2909 pmap_pteg_cnt = PTEGCOUNT;
2910 #else /* PTEGCOUNT */
2911 pmap_pteg_cnt = 0x1000;
2912
2913 while (pmap_pteg_cnt < physmem)
2914 pmap_pteg_cnt <<= 1;
2915
2916 pmap_pteg_cnt >>= 1;
2917 #endif /* PTEGCOUNT */
2918
2919 /*
2920 * Find suitably aligned memory for PTEG hash table.
2921 */
2922 size = pmap_pteg_cnt * sizeof(struct pteg);
2923 pmap_pteg_table = pmap_boot_find_memory(size, size, 0);
2924 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
2925 if ( (uintptr_t) pmap_pteg_table + size > SEGMENT_LENGTH)
2926 panic("pmap_bootstrap: pmap_pteg_table end (%p + %lx) > 256MB",
2927 pmap_pteg_table, size);
2928 #endif
2929
2930 memset((void *)pmap_pteg_table, 0, pmap_pteg_cnt * sizeof(struct pteg));
2931 pmap_pteg_mask = pmap_pteg_cnt - 1;
2932
2933 /*
2934 * We cannot do pmap_steal_memory here since UVM hasn't been loaded
2935 * with pages. So we just steal them before giving them to UVM.
2936 */
2937 size = sizeof(pmap_pvo_table[0]) * pmap_pteg_cnt;
2938 pmap_pvo_table = pmap_boot_find_memory(size, PAGE_SIZE, 0);
2939 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
2940 if ( (uintptr_t) pmap_pvo_table + size > SEGMENT_LENGTH)
2941 panic("pmap_bootstrap: pmap_pvo_table end (%p + %lx) > 256MB",
2942 pmap_pvo_table, size);
2943 #endif
2944
2945 for (i = 0; i < pmap_pteg_cnt; i++)
2946 TAILQ_INIT(&pmap_pvo_table[i]);
2947
2948 #ifndef MSGBUFADDR
2949 /*
2950 * Allocate msgbuf in high memory.
2951 */
2952 msgbuf_paddr =
2953 (paddr_t) pmap_boot_find_memory(MSGBUFSIZE, PAGE_SIZE, 1);
2954 #endif
2955
2956 #ifdef __HAVE_PMAP_PHYSSEG
2957 {
2958 u_int npgs = 0;
2959 for (i = 0, mp = avail; i < avail_cnt; i++, mp++)
2960 npgs += btoc(mp->size);
2961 size = (sizeof(struct pvo_head) + 1) * npgs;
2962 pmap_physseg.pvoh = pmap_boot_find_memory(size, PAGE_SIZE, 0);
2963 pmap_physseg.attrs = (char *) &pmap_physseg.pvoh[npgs];
2964 #if defined(DIAGNOSTIC) || defined(DEBUG) || defined(PMAPCHECK)
2965 if ((uintptr_t)pmap_physseg.pvoh + size > SEGMENT_LENGTH)
2966 panic("pmap_bootstrap: PVO list end (%p + %lx) > 256MB",
2967 pmap_physseg.pvoh, size);
2968 #endif
2969 }
2970 #endif
2971
2972 for (mp = avail, i = 0; i < avail_cnt; mp++, i++) {
2973 paddr_t pfstart = atop(mp->start);
2974 paddr_t pfend = atop(mp->start + mp->size);
2975 if (mp->size == 0)
2976 continue;
2977 if (mp->start + mp->size <= SEGMENT_LENGTH) {
2978 uvm_page_physload(pfstart, pfend, pfstart, pfend,
2979 VM_FREELIST_FIRST256);
2980 } else if (mp->start >= SEGMENT_LENGTH) {
2981 uvm_page_physload(pfstart, pfend, pfstart, pfend,
2982 VM_FREELIST_DEFAULT);
2983 } else {
2984 pfend = atop(SEGMENT_LENGTH);
2985 uvm_page_physload(pfstart, pfend, pfstart, pfend,
2986 VM_FREELIST_FIRST256);
2987 pfstart = atop(SEGMENT_LENGTH);
2988 pfend = atop(mp->start + mp->size);
2989 uvm_page_physload(pfstart, pfend, pfstart, pfend,
2990 VM_FREELIST_DEFAULT);
2991 }
2992 }
2993
2994 /*
2995 * Make sure kernel vsid is allocated as well as VSID 0.
2996 */
2997 pmap_vsid_bitmap[(KERNEL_VSIDBITS & (NPMAPS-1)) / VSID_NBPW]
2998 |= 1 << (KERNEL_VSIDBITS % VSID_NBPW);
2999 pmap_vsid_bitmap[0] |= 1;
3000
3001 /*
3002 * Initialize kernel pmap and hardware.
3003 */
3004 for (i = 0; i < 16; i++) {
3005 pmap_kernel()->pm_sr[i] = EMPTY_SEGMENT;
3006 __asm __volatile ("mtsrin %0,%1"
3007 :: "r"(EMPTY_SEGMENT), "r"(i << ADDR_SR_SHFT));
3008 }
3009
3010 pmap_kernel()->pm_sr[KERNEL_SR] = KERNEL_SEGMENT|SR_SUKEY|SR_PRKEY;
3011 __asm __volatile ("mtsr %0,%1"
3012 :: "n"(KERNEL_SR), "r"(KERNEL_SEGMENT));
3013 #ifdef KERNEL2_SR
3014 pmap_kernel()->pm_sr[KERNEL2_SR] = KERNEL2_SEGMENT|SR_SUKEY|SR_PRKEY;
3015 __asm __volatile ("mtsr %0,%1"
3016 :: "n"(KERNEL2_SR), "r"(KERNEL2_SEGMENT));
3017 #endif
3018 for (i = 0; i < 16; i++) {
3019 if (iosrtable[i] & SR601_T) {
3020 pmap_kernel()->pm_sr[i] = iosrtable[i];
3021 __asm __volatile ("mtsrin %0,%1"
3022 :: "r"(iosrtable[i]), "r"(i << ADDR_SR_SHFT));
3023 }
3024 }
3025
3026 __asm __volatile ("sync; mtsdr1 %0; isync"
3027 :: "r"((uintptr_t)pmap_pteg_table | (pmap_pteg_mask >> 10)));
3028 tlbia();
3029
3030 #ifdef ALTIVEC
3031 pmap_use_altivec = cpu_altivec;
3032 #endif
3033
3034 #ifdef DEBUG
3035 if (pmapdebug & PMAPDEBUG_BOOT) {
3036 u_int cnt;
3037 int bank;
3038 char pbuf[9];
3039 for (cnt = 0, bank = 0; bank < vm_nphysseg; bank++) {
3040 cnt += vm_physmem[bank].avail_end - vm_physmem[bank].avail_start;
3041 printf("pmap_bootstrap: vm_physmem[%d]=%#lx-%#lx/%#lx\n",
3042 bank,
3043 ptoa(vm_physmem[bank].avail_start),
3044 ptoa(vm_physmem[bank].avail_end),
3045 ptoa(vm_physmem[bank].avail_end - vm_physmem[bank].avail_start));
3046 }
3047 format_bytes(pbuf, sizeof(pbuf), ptoa((u_int64_t) cnt));
3048 printf("pmap_bootstrap: UVM memory = %s (%u pages)\n",
3049 pbuf, cnt);
3050 }
3051 #endif
3052
3053 pool_init(&pmap_upvo_pool, sizeof(struct pvo_entry),
3054 sizeof(struct pvo_entry), 0, 0, "pmap_upvopl",
3055 &pmap_pool_uallocator);
3056
3057 pool_setlowat(&pmap_upvo_pool, 252);
3058
3059 pool_init(&pmap_pool, sizeof(struct pmap),
3060 sizeof(void *), 0, 0, "pmap_pl", &pmap_pool_uallocator);
3061 }
3062