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