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