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