BSD 4_4_Lite1 release
[unix-history] / usr / src / sys / luna68k / luna68k / pmap.c
CommitLineData
79cc4320
AF
1/*
2 * Copyright (c) 1992 OMRON Corporation.
ad787160
C
3 * Copyright (c) 1991, 1993
4 * The Regents of the University of California. All rights reserved.
79cc4320
AF
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the Systems Programming Group of the University of Utah Computer
8 * Science Department.
9 *
ad787160
C
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
79cc4320 37 *
d5b132a4 38 * from: hp300/hp300/pmap.c 8.2 (Berkeley) 11/14/93
79cc4320 39 *
ed554bc5 40 * @(#)pmap.c 8.2 (Berkeley) 12/6/93
79cc4320
AF
41 */
42
43/*
98213947
AF
44 * LUNA physical map management code taken from:
45 * HP9000/300 series physical map management code.
46 *
47 * Supports:
48 * 68030 with on-chip MMU (LUNA-I)
49 * 68040 with on-chip MMU (LUNA-II)
50 *
51 * Notes:
52 * Don't even pay lip service to multiprocessor support.
53 *
54 * We assume TLB entries don't have process tags (except for the
55 * supervisor/user distinction) so we only invalidate TLB entries
56 * when changing mappings for the current (or kernel) pmap. This is
57 * technically not true for the 68551 but we flush the TLB on every
58 * context switch, so it effectively winds up that way.
79cc4320 59 *
98213947
AF
60 * Bitwise and/or operations are significantly faster than bitfield
61 * references so we use them when accessing STE/PTEs in the pmap_pte_*
62 * macros. Note also that the two are not always equivalent; e.g.:
63 * (*(int *)pte & PG_PROT) [4] != pte->pg_prot [1]
64 * and a couple of routines that deal with protection and wiring take
65 * some shortcuts that assume the and/or definitions.
66 *
67 * This implementation will only work for PAGE_SIZE == NBPG
68 * (i.e. 4096 bytes).
79cc4320
AF
69 */
70
71/*
72 * Manages physical address maps.
73 *
74 * In addition to hardware address maps, this
75 * module is called upon to provide software-use-only
76 * maps which may or may not be stored in the same
77 * form as hardware maps. These pseudo-maps are
78 * used to store intermediate results from copy
79 * operations to and from address spaces.
80 *
81 * Since the information managed by this module is
82 * also stored by the logical address mapping module,
83 * this module may throw away valid virtual-to-physical
84 * mappings at almost any time. However, invalidations
85 * of virtual-to-physical mappings must be done as
86 * requested.
87 *
88 * In order to cope with hardware architectures which
89 * make virtual-to-physical map invalidates expensive,
90 * this module may delay invalidate or reduced protection
91 * operations until such time as they are actually
92 * necessary. This module is given full information as
93 * to which processors are currently using which maps,
94 * and to when physical maps must be made correct.
95 */
96
38a01dbe
KB
97#include <sys/param.h>
98#include <sys/systm.h>
99#include <sys/proc.h>
100#include <sys/malloc.h>
101#include <sys/user.h>
79cc4320 102
38a01dbe 103#include <luna68k/luna68k/pte.h>
79cc4320 104
38a01dbe
KB
105#include <vm/vm.h>
106#include <vm/vm_kern.h>
107#include <vm/vm_page.h>
79cc4320 108
38a01dbe 109#include <machine/cpu.h>
79cc4320 110
98213947 111#ifdef PMAPSTATS
79cc4320
AF
112struct {
113 int collectscans;
114 int collectpages;
115 int kpttotal;
116 int kptinuse;
117 int kptmaxuse;
118} kpt_stats;
119struct {
120 int kernel; /* entering kernel mapping */
121 int user; /* entering user mapping */
122 int ptpneeded; /* needed to allocate a PT page */
98213947 123 int nochange; /* no change at all */
79cc4320
AF
124 int pwchange; /* no mapping change, just wiring or protection */
125 int wchange; /* no mapping change, just wiring */
98213947 126 int pchange; /* no mapping change, just protection */
79cc4320
AF
127 int mchange; /* was mapped but mapping to different page */
128 int managed; /* a managed page */
129 int firstpv; /* first mapping for this PA */
130 int secondpv; /* second mapping for this PA */
131 int ci; /* cache inhibited */
132 int unmanaged; /* not a managed page */
133 int flushes; /* cache flushes */
134} enter_stats;
135struct {
136 int calls;
137 int removes;
138 int pvfirst;
139 int pvsearch;
140 int ptinvalid;
141 int uflushes;
142 int sflushes;
143} remove_stats;
144struct {
145 int calls;
98213947 146 int changed;
79cc4320
AF
147 int alreadyro;
148 int alreadyrw;
149} protect_stats;
98213947
AF
150struct chgstats {
151 int setcalls;
152 int sethits;
153 int setmiss;
154 int clrcalls;
155 int clrhits;
156 int clrmiss;
157} changebit_stats[16];
158#endif
79cc4320 159
98213947 160#ifdef DEBUG
79cc4320
AF
161int debugmap = 0;
162int pmapdebug = 0x2000;
163#define PDB_FOLLOW 0x0001
164#define PDB_INIT 0x0002
165#define PDB_ENTER 0x0004
166#define PDB_REMOVE 0x0008
167#define PDB_CREATE 0x0010
168#define PDB_PTPAGE 0x0020
169#define PDB_CACHE 0x0040
170#define PDB_BITS 0x0080
171#define PDB_COLLECT 0x0100
172#define PDB_PROTECT 0x0200
173#define PDB_SEGTAB 0x0400
98213947 174#define PDB_MULTIMAP 0x0800
79cc4320
AF
175#define PDB_PARANOIA 0x2000
176#define PDB_WIRING 0x4000
177#define PDB_PVDUMP 0x8000
178
98213947
AF
179#ifdef HAVEVAC
180int pmapvacflush = 0;
181#define PVF_ENTER 0x01
182#define PVF_REMOVE 0x02
183#define PVF_PROTECT 0x04
184#define PVF_TOTAL 0x80
185#endif
186
187#if defined(LUNA2)
188int dowriteback = 1; /* 68040: enable writeback caching */
189int dokwriteback = 1; /* 68040: enable writeback caching of kernel AS */
190#endif
191
79cc4320
AF
192extern vm_offset_t pager_sva, pager_eva;
193#endif
194
195/*
196 * Get STEs and PTEs for user/kernel address space
197 */
98213947
AF
198#if defined(LUNA2)
199#define pmap_ste1(m, v) \
200 (&((m)->pm_stab[(vm_offset_t)(v) >> SG4_SHIFT1]))
201/* XXX assumes physically contiguous ST pages (if more than one) */
202#define pmap_ste2(m, v) \
203 (&((m)->pm_stab[(st_entry_t *)(*(u_int *)pmap_ste1(m, v) & SG4_ADDR1) \
204 - (m)->pm_stpa + (((v) & SG4_MASK2) >> SG4_SHIFT2)]))
205#define pmap_ste(m, v) \
206 (&((m)->pm_stab[(vm_offset_t)(v) \
207 >> (mmutype == MMU_68040 ? SG4_SHIFT1 : SG_ISHIFT)]))
208#define pmap_ste_v(m, v) \
209 (mmutype == MMU_68040 \
210 ? ((*(int *)pmap_ste1(m, v) & SG_V) && \
211 (*(int *)pmap_ste2(m, v) & SG_V)) \
212 : (*(int *)pmap_ste(m, v) & SG_V))
213#else
214#define pmap_ste(m, v) (&((m)->pm_stab[(vm_offset_t)(v) >> SG_ISHIFT]))
215#define pmap_ste_v(m, v) (*(int *)pmap_ste(m, v) & SG_V)
216#endif
79cc4320 217
98213947 218#define pmap_pte(m, v) (&((m)->pm_ptab[(vm_offset_t)(v) >> PG_SHIFT]))
79cc4320 219#define pmap_pte_pa(pte) (*(int *)(pte) & PG_FRAME)
98213947
AF
220#define pmap_pte_w(pte) (*(int *)(pte) & PG_W)
221#define pmap_pte_ci(pte) (*(int *)(pte) & PG_CI)
222#define pmap_pte_m(pte) (*(int *)(pte) & PG_M)
223#define pmap_pte_u(pte) (*(int *)(pte) & PG_U)
224#define pmap_pte_prot(pte) (*(int *)(pte) & PG_PROT)
225#define pmap_pte_v(pte) (*(int *)(pte) & PG_V)
226
227#define pmap_pte_set_w(pte, v) \
228 if (v) *(int *)(pte) |= PG_W; else *(int *)(pte) &= ~PG_W
229#define pmap_pte_set_prot(pte, v) \
230 if (v) *(int *)(pte) |= PG_PROT; else *(int *)(pte) &= ~PG_PROT
231#define pmap_pte_w_chg(pte, nw) ((nw) ^ pmap_pte_w(pte))
232#define pmap_pte_prot_chg(pte, np) ((np) ^ pmap_pte_prot(pte))
79cc4320
AF
233
234/*
235 * Given a map and a machine independent protection code,
98213947 236 * convert to an luna protection code.
79cc4320
AF
237 */
238#define pte_prot(m, p) (protection_codes[p])
239int protection_codes[8];
240
241/*
242 * Kernel page table page management.
243 */
244struct kpt_page {
245 struct kpt_page *kpt_next; /* link on either used or free list */
246 vm_offset_t kpt_va; /* always valid kernel VA */
247 vm_offset_t kpt_pa; /* PA of this page (for speed) */
248};
249struct kpt_page *kpt_free_list, *kpt_used_list;
250struct kpt_page *kpt_pages;
251
252/*
253 * Kernel segment/page table and page table map.
254 * The page table map gives us a level of indirection we need to dynamically
255 * expand the page table. It is essentially a copy of the segment table
256 * with PTEs instead of STEs. All are initialized in locore at boot time.
257 * Sysmap will initially contain VM_KERNEL_PT_PAGES pages of PTEs.
258 * Segtabzero is an empty segment table which all processes share til they
259 * reference something.
260 */
261st_entry_t *Sysseg;
262pt_entry_t *Sysmap, *Sysptmap;
263st_entry_t *Segtabzero, *Segtabzeropa;
264vm_size_t Sysptsize = VM_KERNEL_PT_PAGES;
265
266struct pmap kernel_pmap_store;
267vm_map_t pt_map;
268
269vm_offset_t avail_start; /* PA of first available physical page */
270vm_offset_t avail_end; /* PA of last available physical page */
271vm_size_t mem_size; /* memory size in bytes */
272vm_offset_t virtual_avail; /* VA of first avail page (after kernel bss)*/
273vm_offset_t virtual_end; /* VA of last avail page (end of kernel AS) */
274vm_offset_t vm_first_phys; /* PA of first managed page */
275vm_offset_t vm_last_phys; /* PA just past last managed page */
79cc4320
AF
276boolean_t pmap_initialized = FALSE; /* Has pmap_init completed? */
277char *pmap_attributes; /* reference and modify bits */
98213947
AF
278#ifdef HAVEVAC
279int pmap_aliasmask; /* seperation at which VA aliasing ok */
280#endif
281#if defined(LUNA2)
282int protostfree; /* prototype (default) free ST map */
283#endif
79cc4320 284
98213947
AF
285/*
286 * Internal routines
287 */
288void pmap_remove_mapping __P((pmap_t, vm_offset_t, pt_entry_t *, int));
289boolean_t pmap_testbit __P((vm_offset_t, int));
290void pmap_changebit __P((vm_offset_t, int, boolean_t));
291void pmap_enter_ptpage __P((pmap_t, vm_offset_t));
292#ifdef DEBUG
293void pmap_pvdump __P((vm_offset_t));
294void pmap_check_wiring __P((char *, vm_offset_t));
295#endif
79cc4320 296
98213947
AF
297/* pmap_remove_mapping flags */
298#define PRM_TFLUSH 1
299#define PRM_CFLUSH 2
79cc4320
AF
300
301/*
302 * Bootstrap memory allocator. This function allows for early dynamic
303 * memory allocation until the virtual memory system has been bootstrapped.
304 * After that point, either kmem_alloc or malloc should be used. This
305 * function works by stealing pages from the (to be) managed page pool,
306 * stealing virtual address space, then mapping the pages and zeroing them.
307 *
308 * It should be used from pmap_bootstrap till vm_page_startup, afterwards
309 * it cannot be used, and will generate a panic if tried. Note that this
310 * memory will never be freed, and in essence it is wired down.
311 */
312void *
313pmap_bootstrap_alloc(size) {
314 vm_offset_t val;
315 int i;
316 extern boolean_t vm_page_startup_initialized;
317
318 if (vm_page_startup_initialized)
319 panic("pmap_bootstrap_alloc: called after startup initialized");
320 size = round_page(size);
321 val = virtual_avail;
322
323 virtual_avail = pmap_map(virtual_avail, avail_start,
324 avail_start + size, VM_PROT_READ|VM_PROT_WRITE);
325 avail_start += size;
326
327 blkclr ((caddr_t) val, size);
328 return ((void *) val);
329}
330
331/*
332 * Initialize the pmap module.
333 * Called by vm_init, to initialize any structures that the pmap
334 * system needs to map virtual memory.
335 */
336void
337pmap_init(phys_start, phys_end)
338 vm_offset_t phys_start, phys_end;
339{
340 vm_offset_t addr, addr2;
341 vm_size_t npg, s;
98213947 342 int rv;
79cc4320
AF
343 extern char kstack[];
344
345#ifdef DEBUG
346 if (pmapdebug & PDB_FOLLOW)
347 printf("pmap_init(%x, %x)\n", phys_start, phys_end);
348#endif
349 /*
350 * Now that kernel map has been allocated, we can mark as
351 * unavailable regions which we have mapped in locore.
352 */
79cc4320
AF
353 addr = (vm_offset_t) Sysmap;
354 vm_object_reference(kernel_object);
355 (void) vm_map_find(kernel_map, kernel_object, addr,
356 &addr, LUNA_MAX_PTSIZE, FALSE);
357 /*
358 * If this fails it is probably because the static portion of
359 * the kernel page table isn't big enough and we overran the
360 * page table map. Need to adjust pmap_size() in luna_init.c.
361 */
362 if (addr != (vm_offset_t)Sysmap)
363 goto bogons;
364
365 addr = (vm_offset_t) kstack;
366 vm_object_reference(kernel_object);
367 (void) vm_map_find(kernel_map, kernel_object, addr,
368 &addr, luna_ptob(UPAGES), FALSE);
369 if (addr != (vm_offset_t)kstack)
370bogons:
371 panic("pmap_init: bogons in the VM system!\n");
372
373#ifdef DEBUG
374 if (pmapdebug & PDB_INIT) {
375 printf("pmap_init: Sysseg %x, Sysmap %x, Sysptmap %x\n",
376 Sysseg, Sysmap, Sysptmap);
377 printf(" pstart %x, pend %x, vstart %x, vend %x\n",
378 avail_start, avail_end, virtual_avail, virtual_end);
379 }
380#endif
381
382 /*
383 * Allocate memory for random pmap data structures. Includes the
384 * initial segment table, pv_head_table and pmap_attributes.
385 */
386 npg = atop(phys_end - phys_start);
387 s = (vm_size_t) (LUNA_STSIZE + sizeof(struct pv_entry) * npg + npg);
388 s = round_page(s);
389 addr = (vm_offset_t) kmem_alloc(kernel_map, s);
390 Segtabzero = (st_entry_t *) addr;
391 Segtabzeropa = (st_entry_t *) pmap_extract(kernel_pmap, addr);
392 addr += LUNA_STSIZE;
393 pv_table = (pv_entry_t) addr;
394 addr += sizeof(struct pv_entry) * npg;
395 pmap_attributes = (char *) addr;
396#ifdef DEBUG
397 if (pmapdebug & PDB_INIT)
398 printf("pmap_init: %x bytes: npg %x s0 %x(%x) tbl %x atr %x\n",
399 s, npg, Segtabzero, Segtabzeropa,
400 pv_table, pmap_attributes);
401#endif
402
403 /*
404 * Allocate physical memory for kernel PT pages and their management.
405 * We need 1 PT page per possible task plus some slop.
406 */
407 npg = min(atop(LUNA_MAX_KPTSIZE), maxproc+16);
408 s = ptoa(npg) + round_page(npg * sizeof(struct kpt_page));
409
410 /*
411 * Verify that space will be allocated in region for which
412 * we already have kernel PT pages.
413 */
414 addr = 0;
415 rv = vm_map_find(kernel_map, NULL, 0, &addr, s, TRUE);
416 if (rv != KERN_SUCCESS || addr + s >= (vm_offset_t)Sysmap)
417 panic("pmap_init: kernel PT too small");
418 vm_map_remove(kernel_map, addr, addr + s);
419
420 /*
421 * Now allocate the space and link the pages together to
422 * form the KPT free list.
423 */
424 addr = (vm_offset_t) kmem_alloc(kernel_map, s);
425 s = ptoa(npg);
426 addr2 = addr + s;
427 kpt_pages = &((struct kpt_page *)addr2)[npg];
428 kpt_free_list = (struct kpt_page *) 0;
429 do {
430 addr2 -= LUNA_PAGE_SIZE;
431 (--kpt_pages)->kpt_next = kpt_free_list;
432 kpt_free_list = kpt_pages;
433 kpt_pages->kpt_va = addr2;
434 kpt_pages->kpt_pa = pmap_extract(kernel_pmap, addr2);
435 } while (addr != addr2);
98213947 436#ifdef PMAPSTATS
79cc4320 437 kpt_stats.kpttotal = atop(s);
98213947
AF
438#endif
439#ifdef DEBUG
79cc4320
AF
440 if (pmapdebug & PDB_INIT)
441 printf("pmap_init: KPT: %d pages from %x to %x\n",
442 atop(s), addr, addr + s);
443#endif
444
445 /*
446 * Slightly modified version of kmem_suballoc() to get page table
447 * map where we want it.
448 */
449 addr = LUNA_PTBASE;
450 s = min(LUNA_PTMAXSIZE, maxproc*LUNA_MAX_PTSIZE);
451 addr2 = addr + s;
452 rv = vm_map_find(kernel_map, NULL, 0, &addr, s, TRUE);
453 if (rv != KERN_SUCCESS)
454 panic("pmap_init: cannot allocate space for PT map");
455 pmap_reference(vm_map_pmap(kernel_map));
456 pt_map = vm_map_create(vm_map_pmap(kernel_map), addr, addr2, TRUE);
457 if (pt_map == NULL)
458 panic("pmap_init: cannot create pt_map");
459 rv = vm_map_submap(kernel_map, addr, addr2, pt_map);
460 if (rv != KERN_SUCCESS)
461 panic("pmap_init: cannot map range to pt_map");
462#ifdef DEBUG
463 if (pmapdebug & PDB_INIT)
464 printf("pmap_init: pt_map [%x - %x)\n", addr, addr2);
465#endif
466
98213947
AF
467#if defined(LUNA2)
468 if (mmutype == MMU_68040) {
469 protostfree = ~l2tobm(0);
470 for (rv = MAXUL2SIZE; rv < sizeof(protostfree)*NBBY; rv++)
471 protostfree &= ~l2tobm(rv);
472 }
473#endif
474
79cc4320
AF
475 /*
476 * Now it is safe to enable pv_table recording.
477 */
478 vm_first_phys = phys_start;
479 vm_last_phys = phys_end;
480 pmap_initialized = TRUE;
481}
482
483/*
484 * Used to map a range of physical addresses into kernel
485 * virtual address space.
486 *
487 * For now, VM is already on, we only need to map the
488 * specified memory.
489 */
490vm_offset_t
491pmap_map(virt, start, end, prot)
492 vm_offset_t virt;
493 vm_offset_t start;
494 vm_offset_t end;
495 int prot;
496{
497#ifdef DEBUG
498 if (pmapdebug & PDB_FOLLOW)
499 printf("pmap_map(%x, %x, %x, %x)\n", virt, start, end, prot);
500#endif
501 while (start < end) {
502 pmap_enter(kernel_pmap, virt, start, prot, FALSE);
503 virt += PAGE_SIZE;
504 start += PAGE_SIZE;
505 }
506 return(virt);
507}
508
509/*
510 * Create and return a physical map.
511 *
512 * If the size specified for the map
513 * is zero, the map is an actual physical
514 * map, and may be referenced by the
515 * hardware.
516 *
517 * If the size specified is non-zero,
518 * the map will be used in software only, and
519 * is bounded by that size.
520 */
521pmap_t
522pmap_create(size)
523 vm_size_t size;
524{
525 register pmap_t pmap;
526
527#ifdef DEBUG
528 if (pmapdebug & (PDB_FOLLOW|PDB_CREATE))
529 printf("pmap_create(%x)\n", size);
530#endif
531 /*
532 * Software use map does not need a pmap
533 */
534 if (size)
535 return(NULL);
536
537 /* XXX: is it ok to wait here? */
538 pmap = (pmap_t) malloc(sizeof *pmap, M_VMPMAP, M_WAITOK);
539#ifdef notifwewait
540 if (pmap == NULL)
541 panic("pmap_create: cannot allocate a pmap");
542#endif
543 bzero(pmap, sizeof(*pmap));
544 pmap_pinit(pmap);
545 return (pmap);
546}
547
548/*
549 * Initialize a preallocated and zeroed pmap structure,
550 * such as one in a vmspace structure.
551 */
552void
553pmap_pinit(pmap)
554 register struct pmap *pmap;
555{
556
557#ifdef DEBUG
558 if (pmapdebug & (PDB_FOLLOW|PDB_CREATE))
559 printf("pmap_pinit(%x)\n", pmap);
560#endif
561 /*
562 * No need to allocate page table space yet but we do need a
563 * valid segment table. Initially, we point everyone at the
564 * "null" segment table. On the first pmap_enter, a real
565 * segment table will be allocated.
566 */
567 pmap->pm_stab = Segtabzero;
568 pmap->pm_stpa = Segtabzeropa;
98213947
AF
569#if defined(LUNA2)
570 if (mmutype == MMU_68040)
571 pmap->pm_stfree = protostfree;
572#endif
79cc4320
AF
573 pmap->pm_stchanged = TRUE;
574 pmap->pm_count = 1;
575 simple_lock_init(&pmap->pm_lock);
576}
577
578/*
579 * Retire the given physical map from service.
580 * Should only be called if the map contains
581 * no valid mappings.
582 */
583void
584pmap_destroy(pmap)
585 register pmap_t pmap;
586{
587 int count;
588
589#ifdef DEBUG
590 if (pmapdebug & PDB_FOLLOW)
591 printf("pmap_destroy(%x)\n", pmap);
592#endif
593 if (pmap == NULL)
594 return;
595
596 simple_lock(&pmap->pm_lock);
597 count = --pmap->pm_count;
598 simple_unlock(&pmap->pm_lock);
599 if (count == 0) {
600 pmap_release(pmap);
601 free((caddr_t)pmap, M_VMPMAP);
602 }
603}
604
605/*
606 * Release any resources held by the given physical map.
607 * Called when a pmap initialized by pmap_pinit is being released.
608 * Should only be called if the map contains no valid mappings.
609 */
610void
611pmap_release(pmap)
612 register struct pmap *pmap;
613{
614
615#ifdef DEBUG
616 if (pmapdebug & PDB_FOLLOW)
617 printf("pmap_release(%x)\n", pmap);
618#endif
619#ifdef notdef /* DIAGNOSTIC */
620 /* count would be 0 from pmap_destroy... */
621 simple_lock(&pmap->pm_lock);
622 if (pmap->pm_count != 1)
623 panic("pmap_release count");
624#endif
625 if (pmap->pm_ptab)
626 kmem_free_wakeup(pt_map, (vm_offset_t)pmap->pm_ptab,
627 LUNA_MAX_PTSIZE);
628 if (pmap->pm_stab != Segtabzero)
629 kmem_free(kernel_map, (vm_offset_t)pmap->pm_stab, LUNA_STSIZE);
630}
631
632/*
633 * Add a reference to the specified pmap.
634 */
635void
636pmap_reference(pmap)
637 pmap_t pmap;
638{
639#ifdef DEBUG
640 if (pmapdebug & PDB_FOLLOW)
641 printf("pmap_reference(%x)\n", pmap);
642#endif
643 if (pmap != NULL) {
644 simple_lock(&pmap->pm_lock);
645 pmap->pm_count++;
646 simple_unlock(&pmap->pm_lock);
647 }
648}
649
650/*
651 * Remove the given range of addresses from the specified map.
652 *
653 * It is assumed that the start and end are properly
654 * rounded to the page size.
655 */
656void
657pmap_remove(pmap, sva, eva)
658 register pmap_t pmap;
98213947 659 register vm_offset_t sva, eva;
79cc4320 660{
98213947 661 register vm_offset_t nssva;
79cc4320 662 register pt_entry_t *pte;
98213947
AF
663 boolean_t firstpage, needcflush;
664 int flags;
79cc4320 665
98213947 666#ifdef DEBUG
79cc4320
AF
667 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
668 printf("pmap_remove(%x, %x, %x)\n", pmap, sva, eva);
669#endif
670
671 if (pmap == NULL)
672 return;
673
98213947 674#ifdef PMAPSTATS
79cc4320
AF
675 remove_stats.calls++;
676#endif
98213947
AF
677 firstpage = TRUE;
678 needcflush = FALSE;
679 flags = active_pmap(pmap) ? PRM_TFLUSH : 0;
680 while (sva < eva) {
681 nssva = luna_trunc_seg(sva) + LUNA_SEG_SIZE;
682 if (nssva == 0 || nssva > eva)
683 nssva = eva;
79cc4320 684 /*
98213947
AF
685 * If VA belongs to an unallocated segment,
686 * skip to the next segment boundary.
79cc4320 687 */
98213947
AF
688 if (!pmap_ste_v(pmap, sva)) {
689 sva = nssva;
79cc4320
AF
690 continue;
691 }
79cc4320 692 /*
98213947 693 * Invalidate every valid mapping within this segment.
79cc4320 694 */
98213947
AF
695 pte = pmap_pte(pmap, sva);
696 while (sva < nssva) {
697 if (pmap_pte_v(pte)) {
698#ifdef HAVEVAC
699 if (pmap_aliasmask) {
700 /*
701 * Purge kernel side of VAC to ensure
702 * we get the correct state of any
703 * hardware maintained bits.
704 */
705 if (firstpage) {
706 DCIS();
707#ifdef PMAPSTATS
708 remove_stats.sflushes++;
79cc4320 709#endif
98213947
AF
710 }
711 /*
712 * Remember if we may need to
713 * flush the VAC due to a non-CI
714 * mapping.
715 */
716 if (!needcflush && !pmap_pte_ci(pte))
717 needcflush = TRUE;
79cc4320 718
98213947 719 }
79cc4320 720#endif
98213947
AF
721 pmap_remove_mapping(pmap, sva, pte, flags);
722 firstpage = FALSE;
79cc4320 723 }
98213947
AF
724 pte++;
725 sva += PAGE_SIZE;
79cc4320 726 }
98213947
AF
727 }
728 /*
729 * Didn't do anything, no need for cache flushes
730 */
731 if (firstpage)
732 return;
733#ifdef HAVEVAC
734 /*
735 * In a couple of cases, we don't need to worry about flushing
736 * the VAC:
737 * 1. if this is a kernel mapping,
738 * we have already done it
739 * 2. if it is a user mapping not for the current process,
740 * it won't be there
741 */
742 if (pmap_aliasmask &&
743 (pmap == kernel_pmap || pmap != curproc->p_vmspace->vm_map.pmap))
744 needcflush = FALSE;
745#ifdef DEBUG
746 if (pmap_aliasmask && (pmapvacflush & PVF_REMOVE)) {
747 if (pmapvacflush & PVF_TOTAL)
748 DCIA();
749 else if (pmap == kernel_pmap)
750 DCIS();
751 else
752 DCIU();
753 } else
79cc4320 754#endif
98213947
AF
755 if (needcflush) {
756 if (pmap == kernel_pmap) {
757 DCIS();
758#ifdef PMAPSTATS
759 remove_stats.sflushes++;
79cc4320 760#endif
98213947
AF
761 } else {
762 DCIU();
763#ifdef PMAPSTATS
764 remove_stats.uflushes++;
79cc4320 765#endif
79cc4320 766 }
79cc4320 767 }
98213947 768#endif
79cc4320
AF
769}
770
771/*
772 * pmap_page_protect:
773 *
774 * Lower the permission for all mappings to a given page.
775 */
776void
777pmap_page_protect(pa, prot)
778 vm_offset_t pa;
779 vm_prot_t prot;
780{
781 register pv_entry_t pv;
782 int s;
783
784#ifdef DEBUG
785 if ((pmapdebug & (PDB_FOLLOW|PDB_PROTECT)) ||
786 prot == VM_PROT_NONE && (pmapdebug & PDB_REMOVE))
787 printf("pmap_page_protect(%x, %x)\n", pa, prot);
788#endif
789 if (pa < vm_first_phys || pa >= vm_last_phys)
790 return;
791
792 switch (prot) {
98213947 793 case VM_PROT_READ|VM_PROT_WRITE:
79cc4320
AF
794 case VM_PROT_ALL:
795 break;
796 /* copy_on_write */
797 case VM_PROT_READ:
798 case VM_PROT_READ|VM_PROT_EXECUTE:
799 pmap_changebit(pa, PG_RO, TRUE);
800 break;
801 /* remove_all */
802 default:
803 pv = pa_to_pvh(pa);
804 s = splimp();
805 while (pv->pv_pmap != NULL) {
806#ifdef DEBUG
807 if (!pmap_ste_v(pv->pv_pmap, pv->pv_va) ||
808 pmap_pte_pa(pmap_pte(pv->pv_pmap,pv->pv_va)) != pa)
809 panic("pmap_page_protect: bad mapping");
810#endif
98213947
AF
811 pmap_remove_mapping(pv->pv_pmap, pv->pv_va,
812 PT_ENTRY_NULL,
813 PRM_TFLUSH|PRM_CFLUSH);
79cc4320
AF
814 }
815 splx(s);
816 break;
817 }
818}
819
820/*
821 * Set the physical protection on the
822 * specified range of this map as requested.
823 */
824void
825pmap_protect(pmap, sva, eva, prot)
826 register pmap_t pmap;
98213947
AF
827 register vm_offset_t sva, eva;
828 vm_prot_t prot;
79cc4320 829{
98213947 830 register vm_offset_t nssva;
79cc4320 831 register pt_entry_t *pte;
98213947
AF
832 boolean_t firstpage, needtflush;
833 int isro;
79cc4320
AF
834
835#ifdef DEBUG
836 if (pmapdebug & (PDB_FOLLOW|PDB_PROTECT))
837 printf("pmap_protect(%x, %x, %x, %x)\n", pmap, sva, eva, prot);
79cc4320 838#endif
98213947 839
79cc4320
AF
840 if (pmap == NULL)
841 return;
842
98213947
AF
843#ifdef PMAPSTATS
844 protect_stats.calls++;
845#endif
79cc4320
AF
846 if ((prot & VM_PROT_READ) == VM_PROT_NONE) {
847 pmap_remove(pmap, sva, eva);
848 return;
849 }
850 if (prot & VM_PROT_WRITE)
851 return;
852
98213947
AF
853 isro = pte_prot(pmap, prot);
854 needtflush = active_pmap(pmap);
855 firstpage = TRUE;
856 while (sva < eva) {
857 nssva = luna_trunc_seg(sva) + LUNA_SEG_SIZE;
858 if (nssva == 0 || nssva > eva)
859 nssva = eva;
79cc4320 860 /*
98213947
AF
861 * If VA belongs to an unallocated segment,
862 * skip to the next segment boundary.
79cc4320 863 */
98213947
AF
864 if (!pmap_ste_v(pmap, sva)) {
865 sva = nssva;
79cc4320
AF
866 continue;
867 }
868 /*
98213947
AF
869 * Change protection on mapping if it is valid and doesn't
870 * already have the correct protection.
79cc4320 871 */
98213947
AF
872 pte = pmap_pte(pmap, sva);
873 while (sva < nssva) {
874 if (pmap_pte_v(pte) && pmap_pte_prot_chg(pte, isro)) {
875#ifdef HAVEVAC
876 /*
877 * Purge kernel side of VAC to ensure we
878 * get the correct state of any hardware
879 * maintained bits.
880 *
881 * XXX do we need to clear the VAC in
882 * general to reflect the new protection?
883 */
884 if (firstpage && pmap_aliasmask)
885 DCIS();
79cc4320 886#endif
98213947 887#if defined(LUNA2)
79cc4320 888 /*
98213947
AF
889 * Clear caches if making RO (see section
890 * "7.3 Cache Coherency" in the manual).
79cc4320 891 */
98213947
AF
892 if (isro && mmutype == MMU_68040) {
893 vm_offset_t pa = pmap_pte_pa(pte);
894
895 DCFP(pa);
896 ICPP(pa);
897 }
898#endif
899 pmap_pte_set_prot(pte, isro);
900 if (needtflush)
901 TBIS(sva);
902#ifdef PMAPSTATS
903 protect_stats.changed++;
904#endif
905 firstpage = FALSE;
906 }
907#ifdef PMAPSTATS
908 else if (pmap_pte_v(pte)) {
909 if (isro)
79cc4320 910 protect_stats.alreadyro++;
98213947 911 else
79cc4320 912 protect_stats.alreadyrw++;
98213947 913 }
79cc4320 914#endif
98213947
AF
915 pte++;
916 sva += PAGE_SIZE;
79cc4320 917 }
79cc4320 918 }
98213947
AF
919#if defined(HAVEVAC) && defined(DEBUG)
920 if (pmap_aliasmask && (pmapvacflush & PVF_PROTECT)) {
921 if (pmapvacflush & PVF_TOTAL)
922 DCIA();
923 else if (pmap == kernel_pmap)
924 DCIS();
925 else
926 DCIU();
927 }
928#endif
79cc4320
AF
929}
930
931/*
932 * Insert the given physical page (p) at
933 * the specified virtual address (v) in the
934 * target physical map with the protection requested.
935 *
936 * If specified, the page will be wired down, meaning
937 * that the related pte can not be reclaimed.
938 *
939 * NB: This is the only routine which MAY NOT lazy-evaluate
940 * or lose information. That is, this routine must actually
941 * insert this page into the given map NOW.
942 */
943void
944pmap_enter(pmap, va, pa, prot, wired)
945 register pmap_t pmap;
946 vm_offset_t va;
947 register vm_offset_t pa;
948 vm_prot_t prot;
949 boolean_t wired;
950{
951 register pt_entry_t *pte;
952 register int npte;
953 vm_offset_t opa;
954 boolean_t cacheable = TRUE;
955 boolean_t checkpv = TRUE;
956
957#ifdef DEBUG
958 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER))
959 printf("pmap_enter(%x, %x, %x, %x, %x)\n",
960 pmap, va, pa, prot, wired);
961#endif
962 if (pmap == NULL)
963 return;
964
98213947 965#ifdef PMAPSTATS
79cc4320
AF
966 if (pmap == kernel_pmap)
967 enter_stats.kernel++;
968 else
969 enter_stats.user++;
970#endif
971 /*
972 * For user mapping, allocate kernel VM resources if necessary.
973 */
974 if (pmap->pm_ptab == NULL)
975 pmap->pm_ptab = (pt_entry_t *)
976 kmem_alloc_wait(pt_map, LUNA_MAX_PTSIZE);
977
978 /*
979 * Segment table entry not valid, we need a new PT page
980 */
981 if (!pmap_ste_v(pmap, va))
982 pmap_enter_ptpage(pmap, va);
983
98213947 984 pa = luna_trunc_page(pa);
79cc4320
AF
985 pte = pmap_pte(pmap, va);
986 opa = pmap_pte_pa(pte);
987#ifdef DEBUG
988 if (pmapdebug & PDB_ENTER)
989 printf("enter: pte %x, *pte %x\n", pte, *(int *)pte);
990#endif
991
992 /*
993 * Mapping has not changed, must be protection or wiring change.
994 */
995 if (opa == pa) {
98213947 996#ifdef PMAPSTATS
79cc4320
AF
997 enter_stats.pwchange++;
998#endif
999 /*
1000 * Wiring change, just update stats.
1001 * We don't worry about wiring PT pages as they remain
1002 * resident as long as there are valid mappings in them.
1003 * Hence, if a user page is wired, the PT page will be also.
1004 */
98213947 1005 if (pmap_pte_w_chg(pte, wired ? PG_W : 0)) {
79cc4320
AF
1006#ifdef DEBUG
1007 if (pmapdebug & PDB_ENTER)
1008 printf("enter: wiring change -> %x\n", wired);
1009#endif
1010 if (wired)
1011 pmap->pm_stats.wired_count++;
1012 else
1013 pmap->pm_stats.wired_count--;
98213947
AF
1014#ifdef PMAPSTATS
1015 if (pmap_pte_prot(pte) == pte_prot(pmap, prot))
1016 enter_stats.wchange++;
79cc4320
AF
1017#endif
1018 }
98213947
AF
1019#ifdef PMAPSTATS
1020 else if (pmap_pte_prot(pte) != pte_prot(pmap, prot))
1021 enter_stats.pchange++;
1022 else
1023 enter_stats.nochange++;
1024#endif
79cc4320
AF
1025 /*
1026 * Retain cache inhibition status
1027 */
1028 checkpv = FALSE;
1029 if (pmap_pte_ci(pte))
1030 cacheable = FALSE;
1031 goto validate;
1032 }
1033
1034 /*
1035 * Mapping has changed, invalidate old range and fall through to
1036 * handle validating new mapping.
1037 */
1038 if (opa) {
1039#ifdef DEBUG
1040 if (pmapdebug & PDB_ENTER)
1041 printf("enter: removing old mapping %x\n", va);
1042#endif
98213947
AF
1043 pmap_remove_mapping(pmap, va, pte, PRM_TFLUSH|PRM_CFLUSH);
1044#ifdef PMAPSTATS
79cc4320
AF
1045 enter_stats.mchange++;
1046#endif
1047 }
1048
1049 /*
1050 * If this is a new user mapping, increment the wiring count
1051 * on this PT page. PT pages are wired down as long as there
1052 * is a valid mapping in the page.
1053 */
1054 if (pmap != kernel_pmap)
962e5545
AF
1055 (void) vm_map_pageable(pt_map, trunc_page(pte),
1056 round_page(pte+1), FALSE);
79cc4320
AF
1057
1058 /*
1059 * Enter on the PV list if part of our managed memory
1060 * Note that we raise IPL while manipulating pv_table
1061 * since pmap_enter can be called at interrupt time.
1062 */
1063 if (pa >= vm_first_phys && pa < vm_last_phys) {
1064 register pv_entry_t pv, npv;
1065 int s;
1066
98213947 1067#ifdef PMAPSTATS
79cc4320
AF
1068 enter_stats.managed++;
1069#endif
1070 pv = pa_to_pvh(pa);
1071 s = splimp();
1072#ifdef DEBUG
1073 if (pmapdebug & PDB_ENTER)
1074 printf("enter: pv at %x: %x/%x/%x\n",
1075 pv, pv->pv_va, pv->pv_pmap, pv->pv_next);
1076#endif
1077 /*
1078 * No entries yet, use header as the first entry
1079 */
1080 if (pv->pv_pmap == NULL) {
98213947 1081#ifdef PMAPSTATS
79cc4320
AF
1082 enter_stats.firstpv++;
1083#endif
1084 pv->pv_va = va;
1085 pv->pv_pmap = pmap;
1086 pv->pv_next = NULL;
1087 pv->pv_ptste = NULL;
1088 pv->pv_ptpmap = NULL;
1089 pv->pv_flags = 0;
1090 }
1091 /*
1092 * There is at least one other VA mapping this page.
1093 * Place this entry after the header.
1094 */
1095 else {
1096#ifdef DEBUG
1097 for (npv = pv; npv; npv = npv->pv_next)
1098 if (pmap == npv->pv_pmap && va == npv->pv_va)
1099 panic("pmap_enter: already in pv_tab");
1100#endif
1101 npv = (pv_entry_t)
1102 malloc(sizeof *npv, M_VMPVENT, M_NOWAIT);
1103 npv->pv_va = va;
1104 npv->pv_pmap = pmap;
1105 npv->pv_next = pv->pv_next;
1106 npv->pv_ptste = NULL;
1107 npv->pv_ptpmap = NULL;
98213947 1108 npv->pv_flags = 0;
79cc4320 1109 pv->pv_next = npv;
98213947 1110#ifdef PMAPSTATS
79cc4320
AF
1111 if (!npv->pv_next)
1112 enter_stats.secondpv++;
98213947
AF
1113#endif
1114#ifdef HAVEVAC
1115 /*
1116 * Since there is another logical mapping for the
1117 * same page we may need to cache-inhibit the
1118 * descriptors on those CPUs with external VACs.
1119 * We don't need to CI if:
1120 *
1121 * - No two mappings belong to the same user pmaps.
1122 * Since the cache is flushed on context switches
1123 * there is no problem between user processes.
1124 *
1125 * - Mappings within a single pmap are a certain
1126 * magic distance apart. VAs at these appropriate
1127 * boundaries map to the same cache entries or
1128 * otherwise don't conflict.
1129 *
1130 * To keep it simple, we only check for these special
1131 * cases if there are only two mappings, otherwise we
1132 * punt and always CI.
1133 *
1134 * Note that there are no aliasing problems with the
1135 * on-chip data-cache when the WA bit is set.
1136 */
1137 if (pmap_aliasmask) {
1138 if (pv->pv_flags & PV_CI) {
1139#ifdef DEBUG
1140 if (pmapdebug & PDB_CACHE)
1141 printf("enter: pa %x already CI'ed\n",
1142 pa);
1143#endif
1144 checkpv = cacheable = FALSE;
1145 } else if (npv->pv_next ||
1146 ((pmap == pv->pv_pmap ||
1147 pmap == kernel_pmap ||
1148 pv->pv_pmap == kernel_pmap) &&
1149 ((pv->pv_va & pmap_aliasmask) !=
1150 (va & pmap_aliasmask)))) {
1151#ifdef DEBUG
1152 if (pmapdebug & PDB_CACHE)
1153 printf("enter: pa %x CI'ing all\n",
1154 pa);
1155#endif
1156 cacheable = FALSE;
1157 pv->pv_flags |= PV_CI;
1158#ifdef PMAPSTATS
1159 enter_stats.ci++;
1160#endif
1161 }
1162 }
79cc4320
AF
1163#endif
1164 }
1165 splx(s);
1166 }
1167 /*
1168 * Assumption: if it is not part of our managed memory
1169 * then it must be device memory which may be volitile.
1170 */
1171 else if (pmap_initialized) {
1172 checkpv = cacheable = FALSE;
98213947 1173#ifdef PMAPSTATS
79cc4320
AF
1174 enter_stats.unmanaged++;
1175#endif
1176 }
1177
1178 /*
1179 * Increment counters
1180 */
1181 pmap->pm_stats.resident_count++;
1182 if (wired)
1183 pmap->pm_stats.wired_count++;
1184
1185validate:
98213947
AF
1186#ifdef HAVEVAC
1187 /*
1188 * Purge kernel side of VAC to ensure we get correct state
1189 * of HW bits so we don't clobber them.
1190 */
1191 if (pmap_aliasmask)
1192 DCIS();
1193#endif
79cc4320 1194 /*
98213947 1195 * Build the new PTE.
79cc4320 1196 */
98213947 1197 npte = pa | pte_prot(pmap, prot) | (*(int *)pte & (PG_M|PG_U)) | PG_V;
79cc4320
AF
1198 if (wired)
1199 npte |= PG_W;
1200 if (!checkpv && !cacheable)
1201 npte |= PG_CI;
98213947
AF
1202#if defined(LUNA2)
1203 if (mmutype == MMU_68040 && (npte & (PG_PROT|PG_CI)) == PG_RW)
1204#ifdef DEBUG
1205 if (dowriteback && (dokwriteback || pmap != kernel_pmap))
1206#endif
1207 npte |= PG_CCB;
1208#endif
79cc4320
AF
1209#ifdef DEBUG
1210 if (pmapdebug & PDB_ENTER)
1211 printf("enter: new pte value %x\n", npte);
1212#endif
98213947
AF
1213 /*
1214 * Remember if this was a wiring-only change.
1215 * If so, we need not flush the TLB and caches.
1216 */
1217 wired = ((*(int *)pte ^ npte) == PG_W);
1218#if defined(LUNA2)
1219 if (mmutype == MMU_68040 && !wired) {
1220 DCFP(pa);
1221 ICPP(pa);
79cc4320 1222 }
79cc4320 1223#endif
98213947
AF
1224 *(int *)pte = npte;
1225 if (!wired && active_pmap(pmap))
1226 TBIS(va);
1227#ifdef HAVEVAC
79cc4320
AF
1228 /*
1229 * The following is executed if we are entering a second
1230 * (or greater) mapping for a physical page and the mappings
1231 * may create an aliasing problem. In this case we must
1232 * cache inhibit the descriptors involved and flush any
1233 * external VAC.
1234 */
1235 if (checkpv && !cacheable) {
1236 pmap_changebit(pa, PG_CI, TRUE);
98213947
AF
1237 DCIA();
1238#ifdef PMAPSTATS
79cc4320
AF
1239 enter_stats.flushes++;
1240#endif
1241#ifdef DEBUG
1242 if ((pmapdebug & (PDB_CACHE|PDB_PVDUMP)) ==
1243 (PDB_CACHE|PDB_PVDUMP))
1244 pmap_pvdump(pa);
1245#endif
1246 }
98213947
AF
1247#ifdef DEBUG
1248 else if (pmapvacflush & PVF_ENTER) {
1249 if (pmapvacflush & PVF_TOTAL)
1250 DCIA();
1251 else if (pmap == kernel_pmap)
1252 DCIS();
1253 else
1254 DCIU();
1255 }
1256#endif
79cc4320 1257#endif
98213947
AF
1258#ifdef DEBUG
1259 if ((pmapdebug & PDB_WIRING) && pmap != kernel_pmap)
79cc4320 1260 pmap_check_wiring("enter", trunc_page(pmap_pte(pmap, va)));
79cc4320
AF
1261#endif
1262}
1263
1264/*
1265 * Routine: pmap_change_wiring
1266 * Function: Change the wiring attribute for a map/virtual-address
1267 * pair.
1268 * In/out conditions:
1269 * The mapping must already exist in the pmap.
1270 */
1271void
1272pmap_change_wiring(pmap, va, wired)
1273 register pmap_t pmap;
1274 vm_offset_t va;
1275 boolean_t wired;
1276{
1277 register pt_entry_t *pte;
1278
1279#ifdef DEBUG
1280 if (pmapdebug & PDB_FOLLOW)
1281 printf("pmap_change_wiring(%x, %x, %x)\n", pmap, va, wired);
1282#endif
1283 if (pmap == NULL)
1284 return;
1285
1286 pte = pmap_pte(pmap, va);
1287#ifdef DEBUG
1288 /*
1289 * Page table page is not allocated.
1290 * Should this ever happen? Ignore it for now,
1291 * we don't want to force allocation of unnecessary PTE pages.
1292 */
1293 if (!pmap_ste_v(pmap, va)) {
1294 if (pmapdebug & PDB_PARANOIA)
1295 printf("pmap_change_wiring: invalid STE for %x\n", va);
1296 return;
1297 }
1298 /*
1299 * Page not valid. Should this ever happen?
1300 * Just continue and change wiring anyway.
1301 */
1302 if (!pmap_pte_v(pte)) {
1303 if (pmapdebug & PDB_PARANOIA)
1304 printf("pmap_change_wiring: invalid PTE for %x\n", va);
1305 }
1306#endif
98213947
AF
1307 /*
1308 * If wiring actually changed (always?) set the wire bit and
1309 * update the wire count. Note that wiring is not a hardware
1310 * characteristic so there is no need to invalidate the TLB.
1311 */
1312 if (pmap_pte_w_chg(pte, wired ? PG_W : 0)) {
1313 pmap_pte_set_w(pte, wired);
79cc4320
AF
1314 if (wired)
1315 pmap->pm_stats.wired_count++;
1316 else
1317 pmap->pm_stats.wired_count--;
1318 }
79cc4320
AF
1319}
1320
1321/*
1322 * Routine: pmap_extract
1323 * Function:
1324 * Extract the physical page address associated
1325 * with the given map/virtual_address pair.
1326 */
1327
1328vm_offset_t
1329pmap_extract(pmap, va)
1330 register pmap_t pmap;
1331 vm_offset_t va;
1332{
1333 register vm_offset_t pa;
1334
1335#ifdef DEBUG
1336 if (pmapdebug & PDB_FOLLOW)
1337 printf("pmap_extract(%x, %x) -> ", pmap, va);
1338#endif
1339 pa = 0;
1340 if (pmap && pmap_ste_v(pmap, va))
1341 pa = *(int *)pmap_pte(pmap, va);
1342 if (pa)
1343 pa = (pa & PG_FRAME) | (va & ~PG_FRAME);
1344#ifdef DEBUG
1345 if (pmapdebug & PDB_FOLLOW)
1346 printf("%x\n", pa);
1347#endif
1348 return(pa);
1349}
1350
1351/*
1352 * Copy the range specified by src_addr/len
1353 * from the source map to the range dst_addr/len
1354 * in the destination map.
1355 *
1356 * This routine is only advisory and need not do anything.
1357 */
1358void pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
1359 pmap_t dst_pmap;
1360 pmap_t src_pmap;
1361 vm_offset_t dst_addr;
1362 vm_size_t len;
1363 vm_offset_t src_addr;
1364{
1365#ifdef DEBUG
1366 if (pmapdebug & PDB_FOLLOW)
1367 printf("pmap_copy(%x, %x, %x, %x, %x)\n",
1368 dst_pmap, src_pmap, dst_addr, len, src_addr);
1369#endif
1370}
1371
1372/*
1373 * Require that all active physical maps contain no
1374 * incorrect entries NOW. [This update includes
1375 * forcing updates of any address map caching.]
1376 *
1377 * Generally used to insure that a thread about
1378 * to run will see a semantically correct world.
1379 */
1380void pmap_update()
1381{
1382#ifdef DEBUG
1383 if (pmapdebug & PDB_FOLLOW)
1384 printf("pmap_update()\n");
1385#endif
1386 TBIA();
1387}
1388
1389/*
1390 * Routine: pmap_collect
1391 * Function:
1392 * Garbage collects the physical map system for
1393 * pages which are no longer used.
1394 * Success need not be guaranteed -- that is, there
1395 * may well be pages which are not referenced, but
1396 * others may be collected.
1397 * Usage:
1398 * Called by the pageout daemon when pages are scarce.
1399 */
1400void
1401pmap_collect(pmap)
1402 pmap_t pmap;
1403{
1404 register vm_offset_t pa;
1405 register pv_entry_t pv;
1406 register int *pte;
1407 vm_offset_t kpa;
1408 int s;
1409
1410#ifdef DEBUG
1411 int *ste;
1412 int opmapdebug;
1413#endif
1414 if (pmap != kernel_pmap)
1415 return;
1416
1417#ifdef DEBUG
1418 if (pmapdebug & PDB_FOLLOW)
1419 printf("pmap_collect(%x)\n", pmap);
98213947
AF
1420#endif
1421#ifdef PMAPSTATS
79cc4320
AF
1422 kpt_stats.collectscans++;
1423#endif
1424 s = splimp();
1425 for (pa = vm_first_phys; pa < vm_last_phys; pa += PAGE_SIZE) {
1426 register struct kpt_page *kpt, **pkpt;
1427
1428 /*
1429 * Locate physical pages which are being used as kernel
1430 * page table pages.
1431 */
1432 pv = pa_to_pvh(pa);
1433 if (pv->pv_pmap != kernel_pmap || !(pv->pv_flags & PV_PTPAGE))
1434 continue;
1435 do {
1436 if (pv->pv_ptste && pv->pv_ptpmap == kernel_pmap)
1437 break;
1438 } while (pv = pv->pv_next);
1439 if (pv == NULL)
1440 continue;
1441#ifdef DEBUG
1442 if (pv->pv_va < (vm_offset_t)Sysmap ||
1443 pv->pv_va >= (vm_offset_t)Sysmap + LUNA_MAX_PTSIZE)
1444 printf("collect: kernel PT VA out of range\n");
1445 else
1446 goto ok;
1447 pmap_pvdump(pa);
1448 continue;
1449ok:
1450#endif
1451 pte = (int *)(pv->pv_va + LUNA_PAGE_SIZE);
1452 while (--pte >= (int *)pv->pv_va && *pte == PG_NV)
1453 ;
1454 if (pte >= (int *)pv->pv_va)
1455 continue;
1456
1457#ifdef DEBUG
1458 if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT)) {
1459 printf("collect: freeing KPT page at %x (ste %x@%x)\n",
1460 pv->pv_va, *(int *)pv->pv_ptste, pv->pv_ptste);
1461 opmapdebug = pmapdebug;
1462 pmapdebug |= PDB_PTPAGE;
1463 }
1464
1465 ste = (int *)pv->pv_ptste;
1466#endif
1467 /*
1468 * If all entries were invalid we can remove the page.
98213947
AF
1469 * We call pmap_remove_entry to take care of invalidating
1470 * ST and Sysptmap entries.
79cc4320
AF
1471 */
1472 kpa = pmap_extract(pmap, pv->pv_va);
98213947
AF
1473 pmap_remove_mapping(pmap, pv->pv_va, PT_ENTRY_NULL,
1474 PRM_TFLUSH|PRM_CFLUSH);
79cc4320
AF
1475 /*
1476 * Use the physical address to locate the original
1477 * (kmem_alloc assigned) address for the page and put
1478 * that page back on the free list.
1479 */
1480 for (pkpt = &kpt_used_list, kpt = *pkpt;
1481 kpt != (struct kpt_page *)0;
1482 pkpt = &kpt->kpt_next, kpt = *pkpt)
1483 if (kpt->kpt_pa == kpa)
1484 break;
1485#ifdef DEBUG
1486 if (kpt == (struct kpt_page *)0)
1487 panic("pmap_collect: lost a KPT page");
1488 if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT))
1489 printf("collect: %x (%x) to free list\n",
1490 kpt->kpt_va, kpa);
1491#endif
1492 *pkpt = kpt->kpt_next;
1493 kpt->kpt_next = kpt_free_list;
1494 kpt_free_list = kpt;
98213947 1495#ifdef PMAPSTATS
79cc4320
AF
1496 kpt_stats.kptinuse--;
1497 kpt_stats.collectpages++;
98213947
AF
1498#endif
1499#ifdef DEBUG
79cc4320
AF
1500 if (pmapdebug & (PDB_PTPAGE|PDB_COLLECT))
1501 pmapdebug = opmapdebug;
1502
1503 if (*ste)
1504 printf("collect: kernel STE at %x still valid (%x)\n",
1505 ste, *ste);
1506 ste = (int *)&Sysptmap[(st_entry_t *)ste-pmap_ste(kernel_pmap, 0)];
1507 if (*ste)
1508 printf("collect: kernel PTmap at %x still valid (%x)\n",
1509 ste, *ste);
1510#endif
1511 }
1512 splx(s);
1513}
1514
1515void
1516pmap_activate(pmap, pcbp)
1517 register pmap_t pmap;
1518 struct pcb *pcbp;
1519{
1520#ifdef DEBUG
1521 if (pmapdebug & (PDB_FOLLOW|PDB_SEGTAB))
1522 printf("pmap_activate(%x, %x)\n", pmap, pcbp);
1523#endif
1524 PMAP_ACTIVATE(pmap, pcbp, pmap == curproc->p_vmspace->vm_map.pmap);
1525}
1526
1527/*
1528 * pmap_zero_page zeros the specified (machine independent)
1529 * page by mapping the page into virtual memory and using
1530 * bzero to clear its contents, one machine dependent page
1531 * at a time.
1532 *
1533 * XXX this is a bad implementation for virtual cache machines
1534 * (320/350) because pmap_enter doesn't cache-inhibit the temporary
1535 * kernel mapping and we wind up with data cached for that KVA.
1536 * It is probably a win for physical cache machines (370/380)
1537 * as the cache loading is not wasted.
1538 */
1539void
1540pmap_zero_page(phys)
1541 vm_offset_t phys;
1542{
1543 register vm_offset_t kva;
1544 extern caddr_t CADDR1;
1545
1546#ifdef DEBUG
1547 if (pmapdebug & PDB_FOLLOW)
1548 printf("pmap_zero_page(%x)\n", phys);
1549#endif
1550 kva = (vm_offset_t) CADDR1;
79cc4320
AF
1551 pmap_enter(kernel_pmap, kva, phys, VM_PROT_READ|VM_PROT_WRITE, TRUE);
1552 bzero((caddr_t)kva, LUNA_PAGE_SIZE);
98213947
AF
1553 pmap_remove_mapping(kernel_pmap, kva, PT_ENTRY_NULL,
1554 PRM_TFLUSH|PRM_CFLUSH);
79cc4320
AF
1555}
1556
1557/*
1558 * pmap_copy_page copies the specified (machine independent)
1559 * page by mapping the page into virtual memory and using
1560 * bcopy to copy the page, one machine dependent page at a
1561 * time.
1562 *
1563 *
1564 * XXX this is a bad implementation for virtual cache machines
1565 * (320/350) because pmap_enter doesn't cache-inhibit the temporary
1566 * kernel mapping and we wind up with data cached for that KVA.
1567 * It is probably a win for physical cache machines (370/380)
1568 * as the cache loading is not wasted.
1569 */
1570void
1571pmap_copy_page(src, dst)
1572 vm_offset_t src, dst;
1573{
1574 register vm_offset_t skva, dkva;
1575 extern caddr_t CADDR1, CADDR2;
1576
1577#ifdef DEBUG
1578 if (pmapdebug & PDB_FOLLOW)
1579 printf("pmap_copy_page(%x, %x)\n", src, dst);
1580#endif
1581 skva = (vm_offset_t) CADDR1;
1582 dkva = (vm_offset_t) CADDR2;
79cc4320
AF
1583 pmap_enter(kernel_pmap, skva, src, VM_PROT_READ, TRUE);
1584 pmap_enter(kernel_pmap, dkva, dst, VM_PROT_READ|VM_PROT_WRITE, TRUE);
d5b132a4 1585 copypage((caddr_t)skva, (caddr_t)dkva);
79cc4320
AF
1586 /* CADDR1 and CADDR2 are virtually contiguous */
1587 pmap_remove(kernel_pmap, skva, skva+2*PAGE_SIZE);
79cc4320
AF
1588}
1589
1590/*
1591 * Routine: pmap_pageable
1592 * Function:
1593 * Make the specified pages (by pmap, offset)
1594 * pageable (or not) as requested.
1595 *
1596 * A page which is not pageable may not take
1597 * a fault; therefore, its page table entry
1598 * must remain valid for the duration.
1599 *
1600 * This routine is merely advisory; pmap_enter
1601 * will specify that these pages are to be wired
1602 * down (or not) as appropriate.
1603 */
1604void
1605pmap_pageable(pmap, sva, eva, pageable)
1606 pmap_t pmap;
1607 vm_offset_t sva, eva;
1608 boolean_t pageable;
1609{
1610#ifdef DEBUG
1611 if (pmapdebug & PDB_FOLLOW)
1612 printf("pmap_pageable(%x, %x, %x, %x)\n",
1613 pmap, sva, eva, pageable);
1614#endif
1615 /*
1616 * If we are making a PT page pageable then all valid
1617 * mappings must be gone from that page. Hence it should
1618 * be all zeros and there is no need to clean it.
1619 * Assumptions:
1620 * - we are called with only one page at a time
1621 * - PT pages have only one pv_table entry
1622 */
1623 if (pmap == kernel_pmap && pageable && sva + PAGE_SIZE == eva) {
1624 register pv_entry_t pv;
1625 register vm_offset_t pa;
1626
1627#ifdef DEBUG
1628 if ((pmapdebug & (PDB_FOLLOW|PDB_PTPAGE)) == PDB_PTPAGE)
1629 printf("pmap_pageable(%x, %x, %x, %x)\n",
1630 pmap, sva, eva, pageable);
1631#endif
1632 if (!pmap_ste_v(pmap, sva))
1633 return;
1634 pa = pmap_pte_pa(pmap_pte(pmap, sva));
1635 if (pa < vm_first_phys || pa >= vm_last_phys)
1636 return;
1637 pv = pa_to_pvh(pa);
1638 if (pv->pv_ptste == NULL)
1639 return;
1640#ifdef DEBUG
1641 if (pv->pv_va != sva || pv->pv_next) {
1642 printf("pmap_pageable: bad PT page va %x next %x\n",
1643 pv->pv_va, pv->pv_next);
1644 return;
1645 }
1646#endif
1647 /*
1648 * Mark it unmodified to avoid pageout
1649 */
1650 pmap_changebit(pa, PG_M, FALSE);
1651#ifdef DEBUG
1652 if (pmapdebug & PDB_PTPAGE)
1653 printf("pmap_pageable: PT page %x(%x) unmodified\n",
1654 sva, *(int *)pmap_pte(pmap, sva));
1655 if (pmapdebug & PDB_WIRING)
1656 pmap_check_wiring("pageable", sva);
1657#endif
1658 }
1659}
1660
1661/*
1662 * Clear the modify bits on the specified physical page.
1663 */
1664
1665void
1666pmap_clear_modify(pa)
1667 vm_offset_t pa;
1668{
1669#ifdef DEBUG
1670 if (pmapdebug & PDB_FOLLOW)
1671 printf("pmap_clear_modify(%x)\n", pa);
1672#endif
1673 pmap_changebit(pa, PG_M, FALSE);
1674}
1675
1676/*
1677 * pmap_clear_reference:
1678 *
1679 * Clear the reference bit on the specified physical page.
1680 */
1681
1682void pmap_clear_reference(pa)
1683 vm_offset_t pa;
1684{
1685#ifdef DEBUG
1686 if (pmapdebug & PDB_FOLLOW)
1687 printf("pmap_clear_reference(%x)\n", pa);
1688#endif
1689 pmap_changebit(pa, PG_U, FALSE);
1690}
1691
1692/*
1693 * pmap_is_referenced:
1694 *
1695 * Return whether or not the specified physical page is referenced
1696 * by any physical maps.
1697 */
1698
1699boolean_t
1700pmap_is_referenced(pa)
1701 vm_offset_t pa;
1702{
1703#ifdef DEBUG
1704 if (pmapdebug & PDB_FOLLOW) {
1705 boolean_t rv = pmap_testbit(pa, PG_U);
1706 printf("pmap_is_referenced(%x) -> %c\n", pa, "FT"[rv]);
1707 return(rv);
1708 }
1709#endif
1710 return(pmap_testbit(pa, PG_U));
1711}
1712
1713/*
1714 * pmap_is_modified:
1715 *
1716 * Return whether or not the specified physical page is modified
1717 * by any physical maps.
1718 */
1719
1720boolean_t
1721pmap_is_modified(pa)
1722 vm_offset_t pa;
1723{
1724#ifdef DEBUG
1725 if (pmapdebug & PDB_FOLLOW) {
1726 boolean_t rv = pmap_testbit(pa, PG_M);
1727 printf("pmap_is_modified(%x) -> %c\n", pa, "FT"[rv]);
1728 return(rv);
1729 }
1730#endif
1731 return(pmap_testbit(pa, PG_M));
1732}
1733
1734vm_offset_t
1735pmap_phys_address(ppn)
1736 int ppn;
1737{
1738 return(luna_ptob(ppn));
1739}
1740
1741/*
1742 * Miscellaneous support routines follow
1743 */
1744
98213947
AF
1745/*
1746 * Invalidate a single page denoted by pmap/va.
1747 * If (pte != NULL), it is the already computed PTE for the page.
1748 * If (flags & PRM_TFLUSH), we must invalidate any TLB information.
1749 * If (flags & PRM_CFLUSH), we must flush/invalidate any cache information.
1750 */
1751/* static */
1752void
1753pmap_remove_mapping(pmap, va, pte, flags)
1754 register pmap_t pmap;
1755 register vm_offset_t va;
1756 register pt_entry_t *pte;
1757 int flags;
1758{
1759 register vm_offset_t pa;
1760 register pv_entry_t pv, npv;
1761 pmap_t ptpmap;
1762 int *ste, s, bits;
1763#ifdef DEBUG
1764 pt_entry_t opte;
1765
1766 if (pmapdebug & (PDB_FOLLOW|PDB_REMOVE|PDB_PROTECT))
1767 printf("pmap_remove_mapping(%x, %x, %x, %x)\n",
1768 pmap, va, pte, flags);
1769#endif
1770
1771 /*
1772 * PTE not provided, compute it from pmap and va.
1773 */
1774 if (pte == PT_ENTRY_NULL) {
1775 pte = pmap_pte(pmap, va);
1776 if (*(int *)pte == PG_NV)
1777 return;
1778 }
1779#ifdef HAVEVAC
1780 if (pmap_aliasmask && (flags & PRM_CFLUSH)) {
1781 /*
1782 * Purge kernel side of VAC to ensure we get the correct
1783 * state of any hardware maintained bits.
1784 */
1785 DCIS();
1786#ifdef PMAPSTATS
1787 remove_stats.sflushes++;
1788#endif
1789 /*
1790 * If this is a non-CI user mapping for the current process,
1791 * flush the VAC. Note that the kernel side was flushed
1792 * above so we don't worry about non-CI kernel mappings.
1793 */
1794 if (pmap == curproc->p_vmspace->vm_map.pmap &&
1795 !pmap_pte_ci(pte)) {
1796 DCIU();
1797#ifdef PMAPSTATS
1798 remove_stats.uflushes++;
1799#endif
1800 }
1801 }
1802#endif
1803 pa = pmap_pte_pa(pte);
1804#ifdef DEBUG
1805 opte = *pte;
1806#endif
1807#ifdef PMAPSTATS
1808 remove_stats.removes++;
1809#endif
1810 /*
1811 * Update statistics
1812 */
1813 if (pmap_pte_w(pte))
1814 pmap->pm_stats.wired_count--;
1815 pmap->pm_stats.resident_count--;
1816
1817 /*
1818 * Invalidate the PTE after saving the reference modify info.
1819 */
1820#ifdef DEBUG
1821 if (pmapdebug & PDB_REMOVE)
1822 printf("remove: invalidating pte at %x\n", pte);
1823#endif
1824 bits = *(int *)pte & (PG_U|PG_M);
1825 *(int *)pte = PG_NV;
1826 if ((flags & PRM_TFLUSH) && active_pmap(pmap))
1827 TBIS(va);
1828 /*
1829 * For user mappings decrement the wiring count on
1830 * the PT page. We do this after the PTE has been
1831 * invalidated because vm_map_pageable winds up in
1832 * pmap_pageable which clears the modify bit for the
1833 * PT page.
1834 */
1835 if (pmap != kernel_pmap) {
962e5545
AF
1836 (void) vm_map_pageable(pt_map, trunc_page(pte),
1837 round_page(pte+1), TRUE);
98213947
AF
1838#ifdef DEBUG
1839 if (pmapdebug & PDB_WIRING)
1840 pmap_check_wiring("remove", trunc_page(pte));
1841#endif
1842 }
1843 /*
1844 * If this isn't a managed page, we are all done.
1845 */
1846 if (pa < vm_first_phys || pa >= vm_last_phys)
1847 return;
1848 /*
1849 * Otherwise remove it from the PV table
1850 * (raise IPL since we may be called at interrupt time).
1851 */
1852 pv = pa_to_pvh(pa);
1853 ste = (int *)0;
1854 s = splimp();
1855 /*
1856 * If it is the first entry on the list, it is actually
1857 * in the header and we must copy the following entry up
1858 * to the header. Otherwise we must search the list for
1859 * the entry. In either case we free the now unused entry.
1860 */
1861 if (pmap == pv->pv_pmap && va == pv->pv_va) {
1862 ste = (int *)pv->pv_ptste;
1863 ptpmap = pv->pv_ptpmap;
1864 npv = pv->pv_next;
1865 if (npv) {
1866 npv->pv_flags = pv->pv_flags;
1867 *pv = *npv;
1868 free((caddr_t)npv, M_VMPVENT);
1869 } else
1870 pv->pv_pmap = NULL;
1871#ifdef PMAPSTATS
1872 remove_stats.pvfirst++;
1873#endif
1874 } else {
1875 for (npv = pv->pv_next; npv; npv = npv->pv_next) {
1876#ifdef PMAPSTATS
1877 remove_stats.pvsearch++;
1878#endif
1879 if (pmap == npv->pv_pmap && va == npv->pv_va)
1880 break;
1881 pv = npv;
1882 }
1883#ifdef DEBUG
1884 if (npv == NULL)
1885 panic("pmap_remove: PA not in pv_tab");
1886#endif
1887 ste = (int *)npv->pv_ptste;
1888 ptpmap = npv->pv_ptpmap;
1889 pv->pv_next = npv->pv_next;
1890 free((caddr_t)npv, M_VMPVENT);
1891 pv = pa_to_pvh(pa);
1892 }
1893#ifdef HAVEVAC
1894 /*
1895 * If only one mapping left we no longer need to cache inhibit
1896 */
1897 if (pmap_aliasmask &&
1898 pv->pv_pmap && pv->pv_next == NULL && (pv->pv_flags & PV_CI)) {
1899#ifdef DEBUG
1900 if (pmapdebug & PDB_CACHE)
1901 printf("remove: clearing CI for pa %x\n", pa);
1902#endif
1903 pv->pv_flags &= ~PV_CI;
1904 pmap_changebit(pa, PG_CI, FALSE);
1905#ifdef DEBUG
1906 if ((pmapdebug & (PDB_CACHE|PDB_PVDUMP)) ==
1907 (PDB_CACHE|PDB_PVDUMP))
1908 pmap_pvdump(pa);
1909#endif
1910 }
1911#endif
1912 /*
1913 * If this was a PT page we must also remove the
1914 * mapping from the associated segment table.
1915 */
1916 if (ste) {
1917#ifdef PMAPSTATS
1918 remove_stats.ptinvalid++;
1919#endif
1920#ifdef DEBUG
1921 if (pmapdebug & (PDB_REMOVE|PDB_PTPAGE))
1922 printf("remove: ste was %x@%x pte was %x@%x\n",
1923 *ste, ste, *(int *)&opte, pmap_pte(pmap, va));
1924#endif
1925#if defined(LUNA2)
1926 if (mmutype == MMU_68040) {
1927 int *este = &ste[NPTEPG/SG4_LEV3SIZE];
1928
1929 while (ste < este)
1930 *ste++ = SG_NV;
1931#ifdef DEBUG
1932 ste -= NPTEPG/SG4_LEV3SIZE;
1933#endif
1934 } else
1935#endif
1936 *ste = SG_NV;
1937 /*
1938 * If it was a user PT page, we decrement the
1939 * reference count on the segment table as well,
1940 * freeing it if it is now empty.
1941 */
1942 if (ptpmap != kernel_pmap) {
1943#ifdef DEBUG
1944 if (pmapdebug & (PDB_REMOVE|PDB_SEGTAB))
1945 printf("remove: stab %x, refcnt %d\n",
1946 ptpmap->pm_stab, ptpmap->pm_sref - 1);
1947 if ((pmapdebug & PDB_PARANOIA) &&
1948 ptpmap->pm_stab != (st_entry_t *)trunc_page(ste))
1949 panic("remove: bogus ste");
1950#endif
1951 if (--(ptpmap->pm_sref) == 0) {
1952#ifdef DEBUG
1953 if (pmapdebug&(PDB_REMOVE|PDB_SEGTAB))
1954 printf("remove: free stab %x\n",
1955 ptpmap->pm_stab);
1956#endif
1957 kmem_free(kernel_map,
1958 (vm_offset_t)ptpmap->pm_stab,
1959 LUNA_STSIZE);
1960 ptpmap->pm_stab = Segtabzero;
1961 ptpmap->pm_stpa = Segtabzeropa;
1962#if defined(LUNA2)
1963 if (mmutype == MMU_68040)
1964 ptpmap->pm_stfree = protostfree;
1965#endif
1966 ptpmap->pm_stchanged = TRUE;
1967 /*
1968 * XXX may have changed segment table
1969 * pointer for current process so
1970 * update now to reload hardware.
1971 */
1972 if (ptpmap == curproc->p_vmspace->vm_map.pmap)
1973 PMAP_ACTIVATE(ptpmap,
1974 (struct pcb *)curproc->p_addr, 1);
1975 }
1976 }
1977#if 0
1978 /*
1979 * XXX this should be unnecessary as we have been
1980 * flushing individual mappings as we go.
1981 */
1982 if (ptpmap == kernel_pmap)
1983 TBIAS();
1984 else
1985 TBIAU();
1986#endif
1987 pv->pv_flags &= ~PV_PTPAGE;
1988 ptpmap->pm_ptpages--;
1989 }
1990 /*
1991 * Update saved attributes for managed page
1992 */
1993 pmap_attributes[pa_index(pa)] |= bits;
1994 splx(s);
1995}
1996
79cc4320
AF
1997/* static */
1998boolean_t
1999pmap_testbit(pa, bit)
2000 register vm_offset_t pa;
2001 int bit;
2002{
2003 register pv_entry_t pv;
2004 register int *pte;
2005 int s;
2006
2007 if (pa < vm_first_phys || pa >= vm_last_phys)
2008 return(FALSE);
2009
2010 pv = pa_to_pvh(pa);
2011 s = splimp();
2012 /*
2013 * Check saved info first
2014 */
2015 if (pmap_attributes[pa_index(pa)] & bit) {
2016 splx(s);
2017 return(TRUE);
2018 }
98213947
AF
2019#ifdef HAVEVAC
2020 /*
2021 * Flush VAC to get correct state of any hardware maintained bits.
2022 */
2023 if (pmap_aliasmask && (bit & (PG_U|PG_M)))
2024 DCIS();
2025#endif
79cc4320
AF
2026 /*
2027 * Not found, check current mappings returning
2028 * immediately if found.
2029 */
2030 if (pv->pv_pmap != NULL) {
2031 for (; pv; pv = pv->pv_next) {
2032 pte = (int *) pmap_pte(pv->pv_pmap, pv->pv_va);
79cc4320
AF
2033 if (*pte & bit) {
2034 splx(s);
2035 return(TRUE);
2036 }
79cc4320
AF
2037 }
2038 }
2039 splx(s);
2040 return(FALSE);
2041}
2042
2043/* static */
98213947 2044void
79cc4320
AF
2045pmap_changebit(pa, bit, setem)
2046 register vm_offset_t pa;
2047 int bit;
2048 boolean_t setem;
2049{
2050 register pv_entry_t pv;
2051 register int *pte, npte;
2052 vm_offset_t va;
2053 int s;
2054 boolean_t firstpage = TRUE;
98213947
AF
2055#ifdef PMAPSTATS
2056 struct chgstats *chgp;
2057#endif
79cc4320
AF
2058
2059#ifdef DEBUG
2060 if (pmapdebug & PDB_BITS)
2061 printf("pmap_changebit(%x, %x, %s)\n",
2062 pa, bit, setem ? "set" : "clear");
2063#endif
2064 if (pa < vm_first_phys || pa >= vm_last_phys)
2065 return;
2066
98213947
AF
2067#ifdef PMAPSTATS
2068 chgp = &changebit_stats[(bit>>2)-1];
2069 if (setem)
2070 chgp->setcalls++;
2071 else
2072 chgp->clrcalls++;
2073#endif
79cc4320
AF
2074 pv = pa_to_pvh(pa);
2075 s = splimp();
2076 /*
2077 * Clear saved attributes (modify, reference)
2078 */
2079 if (!setem)
2080 pmap_attributes[pa_index(pa)] &= ~bit;
2081 /*
2082 * Loop over all current mappings setting/clearing as appropos
2083 * If setting RO do we need to clear the VAC?
2084 */
2085 if (pv->pv_pmap != NULL) {
2086#ifdef DEBUG
2087 int toflush = 0;
2088#endif
2089 for (; pv; pv = pv->pv_next) {
2090#ifdef DEBUG
2091 toflush |= (pv->pv_pmap == kernel_pmap) ? 2 : 1;
2092#endif
2093 va = pv->pv_va;
2094
2095 /*
2096 * XXX don't write protect pager mappings
2097 */
2098 if (bit == PG_RO) {
2099 extern vm_offset_t pager_sva, pager_eva;
2100
2101 if (va >= pager_sva && va < pager_eva)
2102 continue;
2103 }
2104
2105 pte = (int *) pmap_pte(pv->pv_pmap, va);
98213947
AF
2106#ifdef HAVEVAC
2107 /*
2108 * Flush VAC to ensure we get correct state of HW bits
2109 * so we don't clobber them.
2110 */
2111 if (firstpage && pmap_aliasmask) {
2112 firstpage = FALSE;
2113 DCIS();
79cc4320 2114 }
98213947 2115#endif
79cc4320
AF
2116 if (setem)
2117 npte = *pte | bit;
2118 else
2119 npte = *pte & ~bit;
2120 if (*pte != npte) {
98213947
AF
2121#if defined(LUNA2)
2122 /*
2123 * If we are changing caching status or
2124 * protection make sure the caches are
2125 * flushed (but only once).
2126 */
2127 if (firstpage && mmutype == MMU_68040 &&
2128 (bit == PG_RO && setem ||
2129 (bit & PG_CMASK))) {
2130 firstpage = FALSE;
2131 DCFP(pa);
2132 ICPP(pa);
2133 }
2134#endif
79cc4320 2135 *pte = npte;
98213947
AF
2136 if (active_pmap(pv->pv_pmap))
2137 TBIS(va);
2138#ifdef PMAPSTATS
2139 if (setem)
2140 chgp->sethits++;
2141 else
2142 chgp->clrhits++;
2143#endif
2144 }
2145#ifdef PMAPSTATS
2146 else {
2147 if (setem)
2148 chgp->setmiss++;
2149 else
2150 chgp->clrmiss++;
79cc4320
AF
2151 }
2152#endif
2153 }
98213947
AF
2154#if defined(HAVEVAC) && defined(DEBUG)
2155 if (setem && bit == PG_RO && (pmapvacflush & PVF_PROTECT)) {
2156 if ((pmapvacflush & PVF_TOTAL) || toflush == 3)
2157 DCIA();
2158 else if (toflush == 2)
2159 DCIS();
2160 else
2161 DCIU();
2162 }
2163#endif
79cc4320
AF
2164 }
2165 splx(s);
2166}
2167
2168/* static */
2169void
2170pmap_enter_ptpage(pmap, va)
2171 register pmap_t pmap;
2172 register vm_offset_t va;
2173{
2174 register vm_offset_t ptpa;
2175 register pv_entry_t pv;
2176 st_entry_t *ste;
2177 int s;
2178
2179#ifdef DEBUG
2180 if (pmapdebug & (PDB_FOLLOW|PDB_ENTER|PDB_PTPAGE))
2181 printf("pmap_enter_ptpage: pmap %x, va %x\n", pmap, va);
98213947
AF
2182#endif
2183#ifdef PMAPSTATS
79cc4320
AF
2184 enter_stats.ptpneeded++;
2185#endif
2186 /*
2187 * Allocate a segment table if necessary. Note that it is allocated
2188 * from kernel_map and not pt_map. This keeps user page tables
2189 * aligned on segment boundaries in the kernel address space.
2190 * The segment table is wired down. It will be freed whenever the
2191 * reference count drops to zero.
2192 */
2193 if (pmap->pm_stab == Segtabzero) {
2194 pmap->pm_stab = (st_entry_t *)
2195 kmem_alloc(kernel_map, LUNA_STSIZE);
2196 pmap->pm_stpa = (st_entry_t *)
2197 pmap_extract(kernel_pmap, (vm_offset_t)pmap->pm_stab);
98213947
AF
2198#if defined(LUNA2)
2199 if (mmutype == MMU_68040) {
2200#ifdef DEBUG
2201 if (dowriteback && dokwriteback)
2202#endif
2203 pmap_changebit((vm_offset_t)pmap->pm_stab, PG_CCB, 0);
2204 pmap->pm_stfree = protostfree;
2205 }
2206#endif
79cc4320
AF
2207 pmap->pm_stchanged = TRUE;
2208 /*
2209 * XXX may have changed segment table pointer for current
2210 * process so update now to reload hardware.
2211 */
2212 if (pmap == curproc->p_vmspace->vm_map.pmap)
2213 PMAP_ACTIVATE(pmap, (struct pcb *)curproc->p_addr, 1);
2214#ifdef DEBUG
2215 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB))
2216 printf("enter: pmap %x stab %x(%x)\n",
2217 pmap, pmap->pm_stab, pmap->pm_stpa);
2218#endif
2219 }
2220
2221 ste = pmap_ste(pmap, va);
98213947
AF
2222#if defined(LUNA2)
2223 /*
2224 * Allocate level 2 descriptor block if necessary
2225 */
2226 if (mmutype == MMU_68040) {
2227 if (!ste->sg_v) {
2228 int ix;
2229 caddr_t addr;
2230
2231 ix = bmtol2(pmap->pm_stfree);
2232 if (ix == -1)
2233 panic("enter: out of address space"); /* XXX */
2234 pmap->pm_stfree &= ~l2tobm(ix);
2235 addr = (caddr_t)&pmap->pm_stab[ix*SG4_LEV2SIZE];
2236 bzero(addr, SG4_LEV2SIZE*sizeof(st_entry_t));
2237 addr = (caddr_t)&pmap->pm_stpa[ix*SG4_LEV2SIZE];
2238 *(int *)ste = (u_int)addr | SG_RW | SG_U | SG_V;
2239#ifdef DEBUG
2240 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB))
2241 printf("enter: alloc ste2 %d(%x)\n", ix, addr);
2242#endif
2243 }
2244 ste = pmap_ste2(pmap, va);
2245 /*
2246 * Since a level 2 descriptor maps a block of SG4_LEV3SIZE
2247 * level 3 descriptors, we need a chunk of NPTEPG/SG4_LEV3SIZE
2248 * (16) such descriptors (NBPG/SG4_LEV3SIZE bytes) to map a
2249 * PT page--the unit of allocation. We set `ste' to point
2250 * to the first entry of that chunk which is validated in its
2251 * entirety below.
2252 */
2253 ste = (st_entry_t *)((int)ste & ~(NBPG/SG4_LEV3SIZE-1));
2254#ifdef DEBUG
2255 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB))
2256 printf("enter: ste2 %x (%x)\n",
2257 pmap_ste2(pmap, va), ste);
2258#endif
2259 }
2260#endif
79cc4320
AF
2261 va = trunc_page((vm_offset_t)pmap_pte(pmap, va));
2262
2263 /*
2264 * In the kernel we allocate a page from the kernel PT page
2265 * free list and map it into the kernel page table map (via
2266 * pmap_enter).
2267 */
2268 if (pmap == kernel_pmap) {
2269 register struct kpt_page *kpt;
2270
2271 s = splimp();
2272 if ((kpt = kpt_free_list) == (struct kpt_page *)0) {
2273 /*
2274 * No PT pages available.
2275 * Try once to free up unused ones.
2276 */
2277#ifdef DEBUG
2278 if (pmapdebug & PDB_COLLECT)
2279 printf("enter: no KPT pages, collecting...\n");
2280#endif
2281 pmap_collect(kernel_pmap);
2282 if ((kpt = kpt_free_list) == (struct kpt_page *)0)
2283 panic("pmap_enter_ptpage: can't get KPT page");
2284 }
98213947 2285#ifdef PMAPSTATS
79cc4320
AF
2286 if (++kpt_stats.kptinuse > kpt_stats.kptmaxuse)
2287 kpt_stats.kptmaxuse = kpt_stats.kptinuse;
2288#endif
2289 kpt_free_list = kpt->kpt_next;
2290 kpt->kpt_next = kpt_used_list;
2291 kpt_used_list = kpt;
2292 ptpa = kpt->kpt_pa;
8994dc5f 2293 bzero((caddr_t)kpt->kpt_va, LUNA_PAGE_SIZE);
79cc4320
AF
2294 pmap_enter(pmap, va, ptpa, VM_PROT_DEFAULT, TRUE);
2295#ifdef DEBUG
2296 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE)) {
2297 int ix = pmap_ste(pmap, va) - pmap_ste(pmap, 0);
2298
2299 printf("enter: add &Sysptmap[%d]: %x (KPT page %x)\n",
2300 ix, *(int *)&Sysptmap[ix], kpt->kpt_va);
2301 }
2302#endif
2303 splx(s);
2304 }
2305 /*
2306 * For user processes we just simulate a fault on that location
2307 * letting the VM system allocate a zero-filled page.
2308 */
2309 else {
2310#ifdef DEBUG
2311 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE))
2312 printf("enter: about to fault UPT pg at %x\n", va);
962e5545 2313#endif
79cc4320
AF
2314 s = vm_fault(pt_map, va, VM_PROT_READ|VM_PROT_WRITE, FALSE);
2315 if (s != KERN_SUCCESS) {
2316 printf("vm_fault(pt_map, %x, RW, 0) -> %d\n", va, s);
2317 panic("pmap_enter: vm_fault failed");
2318 }
79cc4320 2319 ptpa = pmap_extract(kernel_pmap, va);
962e5545
AF
2320 /*
2321 * Mark the page clean now to avoid its pageout (and
2322 * hence creation of a pager) between now and when it
2323 * is wired; i.e. while it is on a paging queue.
2324 */
2325 PHYS_TO_VM_PAGE(ptpa)->flags |= PG_CLEAN;
98213947
AF
2326#ifdef DEBUG
2327 PHYS_TO_VM_PAGE(ptpa)->flags |= PG_PTPAGE;
2328#endif
2329 }
2330#if defined(LUNA2)
2331 /*
2332 * Turn off copyback caching of page table pages,
2333 * could get ugly otherwise.
2334 */
2335#ifdef DEBUG
2336 if (dowriteback && dokwriteback)
2337#endif
2338 if (mmutype == MMU_68040) {
2339 int *pte = (int *)pmap_pte(kernel_pmap, va);
2340#ifdef DEBUG
2341 if ((pmapdebug & PDB_PARANOIA) && (*pte & PG_CCB) == 0)
2342 printf("%s PT no CCB: kva=%x ptpa=%x pte@%x=%x\n",
2343 pmap == kernel_pmap ? "Kernel" : "User",
2344 va, ptpa, pte, *pte);
79cc4320 2345#endif
98213947 2346 pmap_changebit(ptpa, PG_CCB, 0);
79cc4320 2347 }
98213947 2348#endif
79cc4320
AF
2349 /*
2350 * Locate the PV entry in the kernel for this PT page and
2351 * record the STE address. This is so that we can invalidate
2352 * the STE when we remove the mapping for the page.
2353 */
2354 pv = pa_to_pvh(ptpa);
2355 s = splimp();
2356 if (pv) {
2357 pv->pv_flags |= PV_PTPAGE;
2358 do {
2359 if (pv->pv_pmap == kernel_pmap && pv->pv_va == va)
2360 break;
2361 } while (pv = pv->pv_next);
2362 }
2363#ifdef DEBUG
2364 if (pv == NULL)
2365 panic("pmap_enter_ptpage: PT page not entered");
2366#endif
2367 pv->pv_ptste = ste;
2368 pv->pv_ptpmap = pmap;
2369#ifdef DEBUG
2370 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE))
2371 printf("enter: new PT page at PA %x, ste at %x\n", ptpa, ste);
2372#endif
2373
2374 /*
2375 * Map the new PT page into the segment table.
2376 * Also increment the reference count on the segment table if this
2377 * was a user page table page. Note that we don't use vm_map_pageable
2378 * to keep the count like we do for PT pages, this is mostly because
2379 * it would be difficult to identify ST pages in pmap_pageable to
2380 * release them. We also avoid the overhead of vm_map_pageable.
2381 */
98213947
AF
2382#if defined(LUNA2)
2383 if (mmutype == MMU_68040) {
2384 st_entry_t *este;
2385
2386 for (este = &ste[NPTEPG/SG4_LEV3SIZE]; ste < este; ste++) {
2387 *(int *)ste = ptpa | SG_U | SG_RW | SG_V;
2388 ptpa += SG4_LEV3SIZE * sizeof(st_entry_t);
2389 }
2390 } else
2391#endif
79cc4320
AF
2392 *(int *)ste = (ptpa & SG_FRAME) | SG_RW | SG_V;
2393 if (pmap != kernel_pmap) {
2394 pmap->pm_sref++;
2395#ifdef DEBUG
2396 if (pmapdebug & (PDB_ENTER|PDB_PTPAGE|PDB_SEGTAB))
2397 printf("enter: stab %x refcnt %d\n",
2398 pmap->pm_stab, pmap->pm_sref);
2399#endif
2400 }
98213947 2401#if 0
79cc4320
AF
2402 /*
2403 * Flush stale TLB info.
2404 */
2405 if (pmap == kernel_pmap)
2406 TBIAS();
2407 else
2408 TBIAU();
98213947 2409#endif
79cc4320
AF
2410 pmap->pm_ptpages++;
2411 splx(s);
2412}
2413
2414#ifdef DEBUG
98213947
AF
2415/* static */
2416void
79cc4320
AF
2417pmap_pvdump(pa)
2418 vm_offset_t pa;
2419{
2420 register pv_entry_t pv;
2421
2422 printf("pa %x", pa);
2423 for (pv = pa_to_pvh(pa); pv; pv = pv->pv_next)
2424 printf(" -> pmap %x, va %x, ptste %x, ptpmap %x, flags %x",
2425 pv->pv_pmap, pv->pv_va, pv->pv_ptste, pv->pv_ptpmap,
2426 pv->pv_flags);
2427 printf("\n");
2428}
2429
98213947
AF
2430/* static */
2431void
79cc4320
AF
2432pmap_check_wiring(str, va)
2433 char *str;
2434 vm_offset_t va;
2435{
2436 vm_map_entry_t entry;
2437 register int count, *pte;
2438
2439 va = trunc_page(va);
2440 if (!pmap_ste_v(kernel_pmap, va) ||
2441 !pmap_pte_v(pmap_pte(kernel_pmap, va)))
2442 return;
2443
2444 if (!vm_map_lookup_entry(pt_map, va, &entry)) {
2445 printf("wired_check: entry for %x not found\n", va);
2446 return;
2447 }
2448 count = 0;
2449 for (pte = (int *)va; pte < (int *)(va+PAGE_SIZE); pte++)
2450 if (*pte)
2451 count++;
2452 if (entry->wired_count != count)
2453 printf("*%s*: %x: w%d/a%d\n",
2454 str, va, entry->wired_count, count);
2455}
2456#endif