1/*	$NetBSD: pmap.c,v 1.178 2024/01/13 00:43:31 thorpej Exp $	*/
2
3/*-
4 * Copyright (c) 1996 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Adam Glass and Gordon W. Ross.
9 *
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 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31
32/*
33 * Some notes:
34 *
35 * sun3s have contexts (8).  In this pmap design, the kernel is mapped
36 * into all contexts.  Processes take up a known portion of the context,
37 * and compete for the available contexts on a LRU basis.
38 *
39 * sun3s also have this evil "PMEG" crapola.  Essentially each "context"'s
40 * address space is defined by the 2048 one-byte entries in the segment map.
41 * Each of these 1-byte entries points to a "Page Map Entry Group" (PMEG)
42 * which contains the mappings for that virtual segment.  (This strange
43 * terminology invented by Sun and preserved here for consistency.)
44 * Each PMEG maps a segment of 128Kb length, with 16 pages of 8Kb each.
45 *
46 * As you might guess, these PMEGs are in short supply and heavy demand.
47 * PMEGs allocated to the kernel are "static" in the sense that they can't
48 * be stolen from it.  PMEGs allocated to a particular segment of a
49 * pmap's virtual space will be fought over by the other pmaps.
50 */
51
52/*
53 * Cache management:
54 * All sun3 cache implementations are write-back.
55 * Flushes must be done before removing translations
56 * from the MMU because the cache uses the MMU.
57 */
58
59/*
60 * wanted attributes:
61 *       pmegs that aren't needed by a pmap remain in the MMU.
62 *       quick context switches between pmaps
63 *       kernel is in all contexts
64 */
65
66/*
67 * Project1:  Use a "null" context for processes that have not
68 * touched any user-space address recently.  This is efficient
69 * for things that stay in the kernel for a while, waking up
70 * to handle some I/O then going back to sleep (i.e. nfsd).
71 * If and when such a process returns to user-mode, it will
72 * fault and be given a real context at that time.
73 *
74 * This also lets context switch be fast, because all we need
75 * to do there for the MMU is slam the context register.
76 *
77 * Project2:  Use a private pool of PV elements.  This pool can be
78 * fixed size because the total mapped virtual space supported by
79 * the MMU H/W (and this pmap) is fixed for all time.
80 */
81
82#include <sys/cdefs.h>
83__KERNEL_RCSID(0, "$NetBSD: pmap.c,v 1.178 2024/01/13 00:43:31 thorpej Exp $");
84
85#include "opt_ddb.h"
86#include "opt_pmap_debug.h"
87
88#include <sys/param.h>
89#include <sys/systm.h>
90#include <sys/proc.h>
91#include <sys/kmem.h>
92#include <sys/pool.h>
93#include <sys/queue.h>
94#include <sys/kcore.h>
95#include <sys/atomic.h>
96
97#include <uvm/uvm.h>
98
99#include <machine/cpu.h>
100#include <machine/dvma.h>
101#include <machine/fcode.h>
102#include <machine/idprom.h>
103#include <machine/kcore.h>
104#include <machine/mon.h>
105#include <machine/pmap.h>
106#include <machine/pte.h>
107#include <machine/vmparam.h>
108#include <m68k/cacheops.h>
109
110#include <sun3/sun3/cache.h>
111#include <sun3/sun3/control.h>
112#include <sun3/sun3/machdep.h>
113#include <sun3/sun3/obmem.h>
114
115#ifdef DDB
116#include <ddb/db_output.h>
117#else
118#define db_printf printf
119#endif
120
121/* Verify this correspondence between definitions. */
122#if	(PMAP_OBIO << PG_MOD_SHIFT) != PGT_OBIO
123#error	"PMAP_XXX definitions don't match pte.h!"
124#endif
125
126/* Type bits in a "pseudo" physical address. (XXX: pmap.h?) */
127#define PMAP_TYPE	PMAP_VME32
128
129/*
130 * Local convenience macros
131 */
132
133#define DVMA_MAP_END	(DVMA_MAP_BASE + DVMA_MAP_AVAIL)
134
135/* User segments from 0 to KERNBASE */
136#define	NUSEG	(KERNBASE3 / NBSG)
137/* The remainder are kernel segments. */
138#define	NKSEG	(NSEGMAP - NUSEG)
139
140#define VA_SEGNUM(x)	((u_int)(x) >> SEGSHIFT)
141
142/*
143 * Only "main memory" pages are registered in the pv_lists.
144 * This macro is used to determine if a given pte refers to
145 * "main memory" or not.  One slight hack here deserves more
146 * explanation:  The Sun frame buffers all appear as PG_OBMEM
147 * devices but way up near the end of the address space.
148 * We do not want to consider these as "main memory" so the
149 * macro below treats the high bits of the PFN as type bits.
150 *
151 * Note that on the 3/60 only 16 bits of PFN are stored in the
152 * MMU and the top 3 bits read back as zero.  This means a
153 * translation entered into the mmu for physical address
154 * 0xFF000000 will look like 0x1F000000 after one reads back
155 * the pte and converts the PFN to a physical address.
156 */
157#define MEM_BITS	(PG_TYPE | PA_PGNUM(0xF8000000))
158#define	IS_MAIN_MEM(pte) (((pte) & MEM_BITS) == 0)
159
160/* Does this (pseudo) PA represent device space? */
161#define PA_DEV_MASK   (0xF8000000 | PMAP_TYPE)
162#define PA_IS_DEV(pa) ((pa) & PA_DEV_MASK)
163
164/*
165 * Is there a Virtually Addressed Cache (VAC) alias problem
166 * if one page is mapped at both a1 and a2?
167 */
168#define	BADALIAS(a1, a2)	(((int)(a1) ^ (int)(a2)) & SEGOFSET)
169
170
171/*
172 * Debugging support.
173 */
174#define	PMD_ENTER	1
175#define	PMD_LINK	2
176#define	PMD_PROTECT	4
177#define	PMD_SWITCH	8
178#define PMD_COW		0x10
179#define PMD_MODBIT	0x20
180#define PMD_REFBIT	0x40
181#define PMD_WIRING	0x80
182#define PMD_CONTEXT	0x100
183#define PMD_CREATE	0x200
184#define PMD_SEGMAP	0x400
185#define PMD_SETPTE	0x800
186#define PMD_FAULT	0x1000
187#define PMD_KMAP	0x2000
188
189#define	PMD_REMOVE	PMD_ENTER
190#define	PMD_UNLINK	PMD_LINK
191
192#ifdef	PMAP_DEBUG
193int pmap_debug = 0;
194int pmap_db_watchva = -1;
195int pmap_db_watchpmeg = -1;
196#endif	/* PMAP_DEBUG */
197
198/*
199 * Miscellaneous variables.
200 *
201 * For simplicity, this interface retains the variables
202 * that were used in the old interface (without NONCONTIG).
203 * These are set in pmap_bootstrap() and used in
204 * pmap_next_page().
205 */
206vaddr_t virtual_avail, virtual_end;
207paddr_t avail_start, avail_end;
208#define	managed(pa)	(((pa) >= avail_start) && ((pa) < avail_end))
209
210/* used to skip the Sun3/50 video RAM */
211static vaddr_t hole_start, hole_size;
212
213/* This is for pmap_next_page() */
214static paddr_t avail_next;
215
216/* This is where we map a PMEG without a context. */
217static vaddr_t temp_seg_va;
218
219/*
220 * Location to store virtual addresses
221 * to be used in copy/zero operations.
222 */
223vaddr_t tmp_vpages[2] = {
224	SUN3_MONSHORTSEG,
225	SUN3_MONSHORTSEG + PAGE_SIZE };
226int tmp_vpages_inuse;
227
228static int pmap_version = 1;
229static struct pmap kernel_pmap_store;
230struct pmap *const kernel_pmap_ptr  = &kernel_pmap_store;
231#define kernel_pmap (kernel_pmap_ptr)
232static u_char kernel_segmap[NSEGMAP];
233
234/* memory pool for pmap structures */
235struct pool	pmap_pmap_pool;
236
237/* statistics... */
238struct pmap_stats {
239	int	ps_enter_firstpv;	/* pv heads entered */
240	int	ps_enter_secondpv;	/* pv nonheads entered */
241	int	ps_unlink_pvfirst;	/* of pv_unlinks on head */
242	int	ps_unlink_pvsearch;	/* of pv_unlink searches */
243	int	ps_pmeg_faultin;	/* pmegs reloaded */
244	int	ps_changeprots;		/* of calls to changeprot */
245	int	ps_changewire;		/* useless wiring changes */
246	int	ps_npg_prot_all;	/* of active pages protected */
247	int	ps_npg_prot_actual;	/* pages actually affected */
248	int	ps_vac_uncached;	/* non-cached due to bad alias */
249	int	ps_vac_recached;	/* re-cached when bad alias gone */
250} pmap_stats;
251
252#ifdef	PMAP_DEBUG
253#define	CHECK_SPL() do { \
254	if ((getsr() & PSL_IPL) < PSL_IPL4) \
255		panic("pmap: bad spl, line %d", __LINE__); \
256} while (0)
257#else	/* PMAP_DEBUG */
258#define	CHECK_SPL() (void)0
259#endif	/* PMAP_DEBUG */
260
261
262/*
263 * PV support.
264 * (i.e. Find all virtual mappings of a physical page.)
265 */
266
267int pv_initialized = 0;
268
269/* One of these for each mapped virtual page. */
270struct pv_entry {
271	struct pv_entry *pv_next;
272	pmap_t	       pv_pmap;
273	vaddr_t        pv_va;
274};
275typedef struct pv_entry *pv_entry_t;
276
277/* Table of PV list heads (per physical page). */
278static struct pv_entry **pv_head_tbl;
279
280/* Free list of PV entries. */
281static struct pv_entry *pv_free_list;
282
283/* Table of flags (per physical page). */
284static u_char *pv_flags_tbl;
285
286/* These are as in the MMU but shifted by PV_SHIFT. */
287#define PV_SHIFT	24
288#define PV_VALID  0x80
289#define PV_WRITE  0x40
290#define PV_SYSTEM 0x20
291#define PV_NC     0x10
292#define PV_PERM   0xF0
293#define PV_TYPE   0x0C
294#define PV_REF    0x02
295#define PV_MOD    0x01
296
297
298/*
299 * context structures, and queues
300 */
301
302struct context_state {
303	TAILQ_ENTRY(context_state) context_link;
304	int            context_num;
305	struct pmap   *context_upmap;
306};
307typedef struct context_state *context_t;
308
309#define INVALID_CONTEXT -1	/* impossible value */
310#define EMPTY_CONTEXT 0
311#define FIRST_CONTEXT 1
312#define	has_context(pmap)	((pmap)->pm_ctxnum != EMPTY_CONTEXT)
313
314TAILQ_HEAD(context_tailq, context_state)
315	context_free_queue, context_active_queue;
316
317static struct context_state context_array[NCONTEXT];
318
319
320/*
321 * PMEG structures, queues, and macros
322 */
323#define PMEGQ_FREE     0
324#define PMEGQ_INACTIVE 1
325#define PMEGQ_ACTIVE   2
326#define PMEGQ_KERNEL   3
327#define PMEGQ_NONE     4
328
329struct pmeg_state {
330	TAILQ_ENTRY(pmeg_state) pmeg_link;
331	int            pmeg_index;
332	pmap_t         pmeg_owner;
333	int            pmeg_version;
334	vaddr_t        pmeg_va;
335	int            pmeg_wired;
336	int            pmeg_reserved;
337	int            pmeg_vpages;
338	int            pmeg_qstate;
339};
340
341typedef struct pmeg_state *pmeg_t;
342
343#define PMEG_INVAL (NPMEG-1)
344#define PMEG_NULL (pmeg_t) NULL
345
346/* XXX - Replace pmeg_kernel_queue with pmeg_wired_queue ? */
347TAILQ_HEAD(pmeg_tailq, pmeg_state)
348	pmeg_free_queue, pmeg_inactive_queue,
349	pmeg_active_queue, pmeg_kernel_queue;
350
351static struct pmeg_state pmeg_array[NPMEG];
352
353
354/*
355 * prototypes
356 */
357static int get_pte_pmeg(int, int);
358static void set_pte_pmeg(int, int, int);
359
360static void context_allocate(pmap_t);
361static void context_free(pmap_t);
362static void context_init(void);
363
364static void pmeg_init(void);
365static void pmeg_reserve(int);
366
367static pmeg_t pmeg_allocate(pmap_t, vaddr_t);
368static void pmeg_mon_init(vaddr_t, vaddr_t, int);
369static void pmeg_release(pmeg_t);
370static void pmeg_free(pmeg_t);
371static pmeg_t pmeg_cache(pmap_t, vaddr_t);
372static void pmeg_set_wiring(pmeg_t, vaddr_t, int);
373
374static int  pv_link  (pmap_t, int, vaddr_t);
375static void pv_unlink(pmap_t, int, vaddr_t);
376static void pv_remove_all(paddr_t);
377static void pv_changepte(paddr_t, int, int);
378static u_int pv_syncflags(pv_entry_t);
379static void pv_init(void);
380
381static void pmeg_clean(pmeg_t);
382static void pmeg_clean_free(void);
383
384static void pmap_common_init(pmap_t);
385static void pmap_kernel_init(pmap_t);
386static void pmap_user_init(pmap_t);
387static void pmap_page_upload(void);
388
389static void pmap_enter_kernel(vaddr_t, int, bool);
390static void pmap_enter_user(pmap_t, vaddr_t, int, bool);
391
392static void pmap_protect1(pmap_t, vaddr_t, vaddr_t);
393static void pmap_protect_mmu(pmap_t, vaddr_t, vaddr_t);
394static void pmap_protect_noctx(pmap_t, vaddr_t, vaddr_t);
395
396static void pmap_remove1(pmap_t, vaddr_t, vaddr_t);
397static void pmap_remove_mmu(pmap_t, vaddr_t, vaddr_t);
398static void pmap_remove_noctx(pmap_t, vaddr_t, vaddr_t);
399
400static int  pmap_fault_reload(struct pmap *, vaddr_t, int);
401
402/* Called only from locore.s and pmap.c */
403void	_pmap_switch(pmap_t);
404
405#ifdef	PMAP_DEBUG
406void pmap_print(pmap_t);
407void pv_print(paddr_t);
408void pmeg_print(pmeg_t);
409static void pmeg_verify_empty(vaddr_t);
410#endif	/* PMAP_DEBUG */
411void pmap_pinit(pmap_t);
412void pmap_release(pmap_t);
413
414/*
415 * Various in-line helper functions.
416 */
417
418static inline pmap_t
419current_pmap(void)
420{
421	struct vmspace *vm;
422	struct vm_map *map;
423	pmap_t	pmap;
424
425	vm = curproc->p_vmspace;
426	map = &vm->vm_map;
427	pmap = vm_map_pmap(map);
428
429	return (pmap);
430}
431
432static inline struct pv_entry **
433pa_to_pvhead(paddr_t pa)
434{
435	int idx;
436
437	idx = PA_PGNUM(pa);
438#ifdef	DIAGNOSTIC
439	if (PA_IS_DEV(pa) || (idx >= physmem))
440		panic("pmap:pa_to_pvhead: bad pa=0x%lx", pa);
441#endif
442	return (&pv_head_tbl[idx]);
443}
444
445static inline u_char *
446pa_to_pvflags(paddr_t pa)
447{
448	int idx;
449
450	idx = PA_PGNUM(pa);
451#ifdef	DIAGNOSTIC
452	if (PA_IS_DEV(pa) || (idx >= physmem))
453		panic("pmap:pa_to_pvflags: bad pa=0x%lx", pa);
454#endif
455	return (&pv_flags_tbl[idx]);
456}
457
458/*
459 * Save the MOD bit from the given PTE using its PA
460 */
461static inline void
462save_modref_bits(int pte)
463{
464	u_char *pv_flags;
465
466	pv_flags = pa_to_pvflags(PG_PA(pte));
467	*pv_flags |= ((pte & PG_MODREF) >> PV_SHIFT);
468}
469
470static inline pmeg_t
471pmeg_p(int sme)
472{
473#ifdef	DIAGNOSTIC
474	if (sme < 0 || sme >= SEGINV)
475		panic("pmeg_p: bad sme");
476#endif
477	return &pmeg_array[sme];
478}
479
480#define is_pmeg_wired(pmegp) (pmegp->pmeg_wired != 0)
481
482static void
483pmeg_set_wiring(pmeg_t pmegp, vaddr_t va, int flag)
484{
485	int idx, mask;
486
487	idx = VA_PTE_NUM(va);
488	mask = 1 << idx;
489
490	if (flag)
491		pmegp->pmeg_wired |= mask;
492	else
493		pmegp->pmeg_wired &= ~mask;
494}
495
496/****************************************************************
497 * Context management functions.
498 */
499
500/* part of pmap_bootstrap */
501static void
502context_init(void)
503{
504	int i;
505
506	TAILQ_INIT(&context_free_queue);
507	TAILQ_INIT(&context_active_queue);
508
509	/* Leave EMPTY_CONTEXT out of the free list. */
510	context_array[0].context_upmap = kernel_pmap;
511
512	for (i = 1; i < NCONTEXT; i++) {
513		context_array[i].context_num = i;
514		context_array[i].context_upmap = NULL;
515		TAILQ_INSERT_TAIL(&context_free_queue, &context_array[i],
516				  context_link);
517#ifdef	PMAP_DEBUG
518		if (pmap_debug & PMD_CONTEXT)
519			printf("context_init: sizeof(context_array[0])=%d\n",
520			       sizeof(context_array[0]));
521#endif
522	}
523}
524
525/* Get us a context (steal one if necessary). */
526static void
527context_allocate(pmap_t pmap)
528{
529	context_t context;
530
531	CHECK_SPL();
532
533#ifdef	DIAGNOSTIC
534	if (pmap == kernel_pmap)
535		panic("context_allocate: kernel_pmap");
536	if (has_context(pmap))
537		panic("pmap: pmap already has context allocated to it");
538#endif
539
540	context = TAILQ_FIRST(&context_free_queue);
541	if (context == NULL) {
542		/* Steal the head of the active queue. */
543		context = TAILQ_FIRST(&context_active_queue);
544		if (context == NULL)
545			panic("pmap: no contexts left?");
546#ifdef	PMAP_DEBUG
547		if (pmap_debug & PMD_CONTEXT)
548			printf("context_allocate: steal ctx %d from pmap %p\n",
549			       context->context_num, context->context_upmap);
550#endif
551		context_free(context->context_upmap);
552		context = TAILQ_FIRST(&context_free_queue);
553	}
554	TAILQ_REMOVE(&context_free_queue, context, context_link);
555
556#ifdef DIAGNOSTIC
557	if (context->context_upmap != NULL)
558		panic("pmap: context in use???");
559#endif
560
561	context->context_upmap = pmap;
562	pmap->pm_ctxnum = context->context_num;
563
564	TAILQ_INSERT_TAIL(&context_active_queue, context, context_link);
565
566	/*
567	 * We could reload the MMU here, but that would
568	 * artificially move PMEGs from the inactive queue
569	 * to the active queue, so do lazy reloading.
570	 * XXX - Need to reload wired pmegs though...
571	 * XXX: Verify the context it is empty?
572	 */
573}
574
575/*
576 * Unload the context and put it on the free queue.
577 */
578static void
579context_free(pmap_t pmap)
580{
581	int saved_ctxnum, ctxnum;
582	int i, sme;
583	context_t contextp;
584	vaddr_t va;
585
586	CHECK_SPL();
587
588	ctxnum = pmap->pm_ctxnum;
589	if (ctxnum < FIRST_CONTEXT || ctxnum >= NCONTEXT)
590		panic("pmap: context_free ctxnum");
591	contextp = &context_array[ctxnum];
592
593	/* Temporary context change. */
594	saved_ctxnum = get_context();
595	set_context(ctxnum);
596
597	/* Before unloading translations, flush cache. */
598#ifdef	HAVECACHE
599	if (cache_size)
600		cache_flush_context();
601#endif
602
603	/* Unload MMU (but keep in SW segmap). */
604	for (i = 0, va = 0; i < NUSEG; i++, va += NBSG) {
605
606#if !defined(PMAP_DEBUG)
607		/* Short-cut using the S/W segmap (if !debug). */
608		if (pmap->pm_segmap[i] == SEGINV)
609			continue;
610#endif
611
612		/* Check the H/W segmap. */
613		sme = get_segmap(va);
614		if (sme == SEGINV)
615			continue;
616
617		/* Found valid PMEG in the segmap. */
618#ifdef	PMAP_DEBUG
619		if (pmap_debug & PMD_SEGMAP)
620			printf("pmap: set_segmap ctx=%d v=0x%lx old=0x%x "
621			       "new=ff (cf)\n", ctxnum, va, sme);
622#endif
623#ifdef	DIAGNOSTIC
624		if (sme != pmap->pm_segmap[i])
625			panic("context_free: unknown sme at va=0x%lx", va);
626#endif
627		/* Did cache flush above (whole context). */
628		set_segmap(va, SEGINV);
629		/* In this case, do not clear pm_segmap. */
630		/* XXX: Maybe inline this call? */
631		pmeg_release(pmeg_p(sme));
632	}
633
634	/* Restore previous context. */
635	set_context(saved_ctxnum);
636
637	/* Dequeue, update, requeue. */
638	TAILQ_REMOVE(&context_active_queue, contextp, context_link);
639	pmap->pm_ctxnum = EMPTY_CONTEXT;
640	contextp->context_upmap = NULL;
641	TAILQ_INSERT_TAIL(&context_free_queue, contextp, context_link);
642}
643
644
645/****************************************************************
646 * PMEG management functions.
647 */
648
649static void
650pmeg_init(void)
651{
652	int x;
653
654	/* clear pmeg array, put it all on the free pmeq queue */
655
656	TAILQ_INIT(&pmeg_free_queue);
657	TAILQ_INIT(&pmeg_inactive_queue);
658	TAILQ_INIT(&pmeg_active_queue);
659	TAILQ_INIT(&pmeg_kernel_queue);
660
661	memset(pmeg_array, 0, NPMEG*sizeof(struct pmeg_state));
662	for (x = 0; x < NPMEG; x++) {
663		TAILQ_INSERT_TAIL(&pmeg_free_queue, &pmeg_array[x], pmeg_link);
664		pmeg_array[x].pmeg_qstate = PMEGQ_FREE;
665		pmeg_array[x].pmeg_index = x;
666	}
667
668	/* The last pmeg is not usable. */
669	pmeg_reserve(SEGINV);
670}
671
672/*
673 * Reserve a pmeg (forever) for use by PROM, etc.
674 * Contents are left as-is.  Called very early...
675 */
676void
677pmeg_reserve(int sme)
678{
679	pmeg_t pmegp;
680
681	/* Can not use pmeg_p() because it fails on SEGINV. */
682	pmegp = &pmeg_array[sme];
683
684	if (pmegp->pmeg_reserved) {
685		mon_printf("pmeg_reserve: already reserved\n");
686		sunmon_abort();
687	}
688	if (pmegp->pmeg_owner) {
689		mon_printf("pmeg_reserve: already owned\n");
690		sunmon_abort();
691	}
692
693	/* Owned by kernel, but not really usable... */
694	pmegp->pmeg_owner = kernel_pmap;
695	pmegp->pmeg_reserved++;	/* keep count, just in case */
696	TAILQ_REMOVE(&pmeg_free_queue, pmegp, pmeg_link);
697	pmegp->pmeg_qstate = PMEGQ_NONE;
698}
699
700/*
701 * Examine PMEGs used by the monitor, and either
702 * reserve them (keep=1) or clear them (keep=0)
703 */
704static void
705pmeg_mon_init(vaddr_t sva, vaddr_t eva, int keep)
706{
707	vaddr_t pgva, endseg;
708	int pte, valid;
709	unsigned char sme;
710
711#ifdef	PMAP_DEBUG
712	if (pmap_debug & PMD_SEGMAP)
713		mon_printf("pmeg_mon_init(0x%x, 0x%x, %d)\n",
714			   sva, eva, keep);
715#endif
716
717	sva &= ~(NBSG - 1);
718
719	while (sva < eva) {
720		sme = get_segmap(sva);
721		if (sme != SEGINV) {
722			valid = 0;
723			endseg = sva + NBSG;
724			for (pgva = sva; pgva < endseg; pgva += PAGE_SIZE) {
725				pte = get_pte(pgva);
726				if (pte & PG_VALID) {
727					valid++;
728				}
729			}
730#ifdef	PMAP_DEBUG
731			if (pmap_debug & PMD_SEGMAP)
732				mon_printf(" sva=0x%x seg=0x%x valid=%d\n",
733					   sva, sme, valid);
734#endif
735			if (keep && valid)
736				pmeg_reserve(sme);
737			else
738				set_segmap(sva, SEGINV);
739		}
740		sva += NBSG;
741	}
742}
743
744/*
745 * This is used only during pmap_bootstrap, so we can
746 * get away with borrowing a slot in the segmap.
747 */
748static void
749pmeg_clean(pmeg_t pmegp)
750{
751	int sme;
752	vaddr_t va;
753
754	sme = get_segmap(0);
755	if (sme != SEGINV)
756		panic("pmeg_clean");
757
758	sme = pmegp->pmeg_index;
759	set_segmap(0, sme);
760
761	for (va = 0; va < NBSG; va += PAGE_SIZE)
762		set_pte(va, PG_INVAL);
763
764	set_segmap(0, SEGINV);
765}
766
767/*
768 * This routine makes sure that pmegs on the pmeg_free_queue contain
769 * no valid ptes.  It pulls things off the queue, cleans them, and
770 * puts them at the end.  The ending condition is finding the first
771 * queue element at the head of the queue again.
772 */
773static void
774pmeg_clean_free(void)
775{
776	pmeg_t pmegp, pmegp_first;
777
778	pmegp = TAILQ_FIRST(&pmeg_free_queue);
779	if (pmegp == NULL)
780		panic("pmap: no free pmegs available to clean");
781
782	pmegp_first = NULL;
783
784	for (;;) {
785		pmegp = TAILQ_FIRST(&pmeg_free_queue);
786		TAILQ_REMOVE(&pmeg_free_queue, pmegp, pmeg_link);
787
788		pmegp->pmeg_qstate = PMEGQ_NONE;
789		pmeg_clean(pmegp);
790		pmegp->pmeg_qstate = PMEGQ_FREE;
791
792		TAILQ_INSERT_TAIL(&pmeg_free_queue, pmegp, pmeg_link);
793
794		if (pmegp == pmegp_first)
795			break;
796		if (pmegp_first == NULL)
797			pmegp_first = pmegp;
798	}
799}
800
801/*
802 * Allocate a PMEG by whatever means necessary.
803 * (May invalidate some mappings!)
804 */
805static pmeg_t
806pmeg_allocate(pmap_t pmap, vaddr_t va)
807{
808	pmeg_t pmegp;
809
810	CHECK_SPL();
811
812#ifdef	DIAGNOSTIC
813	if (va & SEGOFSET) {
814		panic("pmap:pmeg_allocate: va=0x%lx", va);
815	}
816#endif
817
818	/* Get one onto the free list if necessary. */
819	pmegp = TAILQ_FIRST(&pmeg_free_queue);
820	if (!pmegp) {
821		/* Try inactive queue... */
822		pmegp = TAILQ_FIRST(&pmeg_inactive_queue);
823		if (!pmegp) {
824			/* Try active queue... */
825			pmegp = TAILQ_FIRST(&pmeg_active_queue);
826		}
827		if (!pmegp) {
828			panic("pmeg_allocate: failed");
829		}
830
831		/*
832		 * Remove mappings to free-up a pmeg
833		 * (so it will go onto the free list).
834		 * XXX - Skip this one if it is wired?
835		 */
836		pmap_remove1(pmegp->pmeg_owner,
837			     pmegp->pmeg_va,
838			     pmegp->pmeg_va + NBSG);
839	}
840
841	/* OK, free list has something for us to take. */
842	pmegp = TAILQ_FIRST(&pmeg_free_queue);
843#ifdef	DIAGNOSTIC
844	if (pmegp == NULL)
845		panic("pmeg_allocagte: still none free?");
846	if ((pmegp->pmeg_qstate != PMEGQ_FREE) ||
847	    (pmegp->pmeg_index == SEGINV) ||
848	    (pmegp->pmeg_vpages))
849		panic("pmeg_allocate: bad pmegp=%p", pmegp);
850#endif
851#ifdef	PMAP_DEBUG
852	if (pmegp->pmeg_index == pmap_db_watchpmeg) {
853		db_printf("pmeg_allocate: watch pmegp=%p\n", pmegp);
854		Debugger();
855	}
856#endif
857
858	TAILQ_REMOVE(&pmeg_free_queue, pmegp, pmeg_link);
859
860	/* Reassign this PMEG for the caller. */
861	pmegp->pmeg_owner = pmap;
862	pmegp->pmeg_version = pmap->pm_version;
863	pmegp->pmeg_va = va;
864	pmegp->pmeg_wired = 0;
865	pmegp->pmeg_reserved  = 0;
866	pmegp->pmeg_vpages  = 0;
867	if (pmap == kernel_pmap) {
868		TAILQ_INSERT_TAIL(&pmeg_kernel_queue, pmegp, pmeg_link);
869		pmegp->pmeg_qstate = PMEGQ_KERNEL;
870	} else {
871		TAILQ_INSERT_TAIL(&pmeg_active_queue, pmegp, pmeg_link);
872		pmegp->pmeg_qstate = PMEGQ_ACTIVE;
873	}
874	/* Caller will verify that it's empty (if debugging). */
875	return pmegp;
876}
877
878/*
879 * Put pmeg on the inactive queue, leaving its contents intact.
880 * This happens when we lose our context.  We may reclaim
881 * this pmeg later if it is still in the inactive queue.
882 */
883static void
884pmeg_release(pmeg_t pmegp)
885{
886
887	CHECK_SPL();
888
889#ifdef	DIAGNOSTIC
890	if ((pmegp->pmeg_owner == kernel_pmap) ||
891	    (pmegp->pmeg_qstate != PMEGQ_ACTIVE))
892		panic("pmeg_release: bad pmeg=%p", pmegp);
893#endif
894
895	TAILQ_REMOVE(&pmeg_active_queue, pmegp, pmeg_link);
896	pmegp->pmeg_qstate = PMEGQ_INACTIVE;
897	TAILQ_INSERT_TAIL(&pmeg_inactive_queue, pmegp, pmeg_link);
898}
899
900/*
901 * Move the pmeg to the free queue from wherever it is.
902 * The pmeg will be clean.  It might be in kernel_pmap.
903 */
904static void
905pmeg_free(pmeg_t pmegp)
906{
907
908	CHECK_SPL();
909
910#ifdef	DIAGNOSTIC
911	/* Caller should verify that it's empty. */
912	if (pmegp->pmeg_vpages != 0)
913		panic("pmeg_free: vpages");
914#endif
915
916	switch (pmegp->pmeg_qstate) {
917	case PMEGQ_ACTIVE:
918		TAILQ_REMOVE(&pmeg_active_queue, pmegp, pmeg_link);
919		break;
920	case PMEGQ_INACTIVE:
921		TAILQ_REMOVE(&pmeg_inactive_queue, pmegp, pmeg_link);
922		break;
923	case PMEGQ_KERNEL:
924		TAILQ_REMOVE(&pmeg_kernel_queue, pmegp, pmeg_link);
925		break;
926	default:
927		panic("pmeg_free: releasing bad pmeg");
928		break;
929	}
930
931#ifdef	PMAP_DEBUG
932	if (pmegp->pmeg_index == pmap_db_watchpmeg) {
933		db_printf("pmeg_free: watch pmeg 0x%x\n",
934			  pmegp->pmeg_index);
935		Debugger();
936	}
937#endif
938
939	pmegp->pmeg_owner = NULL;
940	pmegp->pmeg_qstate = PMEGQ_FREE;
941	TAILQ_INSERT_TAIL(&pmeg_free_queue, pmegp, pmeg_link);
942}
943
944/*
945 * Find a PMEG that was put on the inactive queue when we
946 * had our context stolen.  If found, move to active queue.
947 */
948static pmeg_t
949pmeg_cache(pmap_t pmap, vaddr_t va)
950{
951	int sme, segnum;
952	pmeg_t pmegp;
953
954	CHECK_SPL();
955
956#ifdef	DIAGNOSTIC
957	if (pmap == kernel_pmap)
958		panic("pmeg_cache: kernel_pmap");
959	if (va & SEGOFSET) {
960		panic("pmap:pmeg_cache: va=0x%lx", va);
961	}
962#endif
963
964	if (pmap->pm_segmap == NULL)
965		return PMEG_NULL;
966
967	segnum = VA_SEGNUM(va);
968	if (segnum > NUSEG)		/* out of range */
969		return PMEG_NULL;
970
971	sme = pmap->pm_segmap[segnum];
972	if (sme == SEGINV)	/* nothing cached */
973		return PMEG_NULL;
974
975	pmegp = pmeg_p(sme);
976
977#ifdef	PMAP_DEBUG
978	if (pmegp->pmeg_index == pmap_db_watchpmeg) {
979		db_printf("pmeg_cache: watch pmeg 0x%x\n", pmegp->pmeg_index);
980		Debugger();
981	}
982#endif
983
984	/*
985	 * Our segmap named a PMEG.  If it is no longer ours,
986	 * invalidate that entry in our segmap and return NULL.
987	 */
988	if ((pmegp->pmeg_owner != pmap) ||
989	    (pmegp->pmeg_version != pmap->pm_version) ||
990	    (pmegp->pmeg_va != va))
991	{
992#ifdef	PMAP_DEBUG
993		db_printf("pmap:pmeg_cache: invalid pmeg: sme=0x%x\n", sme);
994		pmeg_print(pmegp);
995		Debugger();
996#endif
997		pmap->pm_segmap[segnum] = SEGINV;
998		return PMEG_NULL; /* cache lookup failed */
999	}
1000
1001#ifdef	DIAGNOSTIC
1002	/* Make sure it is on the inactive queue. */
1003	if (pmegp->pmeg_qstate != PMEGQ_INACTIVE)
1004		panic("pmeg_cache: pmeg was taken: %p", pmegp);
1005#endif
1006
1007	TAILQ_REMOVE(&pmeg_inactive_queue, pmegp, pmeg_link);
1008	pmegp->pmeg_qstate = PMEGQ_ACTIVE;
1009	TAILQ_INSERT_TAIL(&pmeg_active_queue, pmegp, pmeg_link);
1010
1011	return pmegp;
1012}
1013
1014#ifdef	PMAP_DEBUG
1015static void
1016pmeg_verify_empty(vaddr_t va)
1017{
1018	vaddr_t eva;
1019	int pte;
1020
1021	for (eva = va + NBSG;  va < eva; va += PAGE_SIZE) {
1022		pte = get_pte(va);
1023		if (pte & PG_VALID)
1024			panic("pmeg_verify_empty");
1025	}
1026}
1027#endif	/* PMAP_DEBUG */
1028
1029
1030/****************************************************************
1031 * Physical-to-virutal lookup support
1032 *
1033 * Need memory for the pv_alloc/pv_free list heads
1034 * and elements.  We know how many to allocate since
1035 * there is one list head for each physical page, and
1036 * at most one element for each PMEG slot.
1037 */
1038static void
1039pv_init(void)
1040{
1041	int npp, nvp, sz;
1042	pv_entry_t pv;
1043	char *p;
1044
1045	/* total allocation size */
1046	sz = 0;
1047
1048	/*
1049	 * Data for each physical page.
1050	 * Each "mod/ref" flag is a char.
1051	 * Each PV head is a pointer.
1052	 * Note physmem is in pages.
1053	 */
1054	npp = ALIGN(physmem);
1055	sz += (npp * sizeof(*pv_flags_tbl));
1056	sz += (npp * sizeof(*pv_head_tbl));
1057
1058	/*
1059	 * Data for each virtual page (all PMEGs).
1060	 * One pv_entry for each page frame.
1061	 */
1062	nvp = NPMEG * NPAGSEG;
1063	sz += (nvp * sizeof(*pv_free_list));
1064
1065	/* Now allocate the whole thing. */
1066	sz = m68k_round_page(sz);
1067	p = (char *)uvm_km_alloc(kernel_map, sz, 0, UVM_KMF_WIRED);
1068	if (p == NULL)
1069		panic("pmap:pv_init: alloc failed");
1070	memset(p, 0, sz);
1071
1072	/* Now divide up the space. */
1073	pv_flags_tbl = (void *) p;
1074	p += (npp * sizeof(*pv_flags_tbl));
1075	pv_head_tbl = (void*) p;
1076	p += (npp * sizeof(*pv_head_tbl));
1077	pv_free_list = (void *)p;
1078	p += (nvp * sizeof(*pv_free_list));
1079
1080	/* Finally, make pv_free_list into a list. */
1081	for (pv = pv_free_list; (char *)pv < p; pv++)
1082		pv->pv_next = &pv[1];
1083	pv[-1].pv_next = 0;
1084
1085	pv_initialized++;
1086}
1087
1088/*
1089 * Set or clear bits in all PTEs mapping a page.
1090 * Also does syncflags work while we are there...
1091 */
1092static void
1093pv_changepte(paddr_t pa, int set_bits, int clear_bits)
1094{
1095	pv_entry_t *head, pv;
1096	u_char *pv_flags;
1097	pmap_t pmap;
1098	vaddr_t va;
1099	int pte, sme;
1100	int saved_ctx;
1101	bool in_ctx;
1102	u_int flags;
1103
1104	pv_flags = pa_to_pvflags(pa);
1105	head     = pa_to_pvhead(pa);
1106
1107	/* If no mappings, no work to do. */
1108	if (*head == NULL)
1109		return;
1110
1111#ifdef	DIAGNOSTIC
1112	/* This function should only clear these bits: */
1113	if (clear_bits & ~(PG_WRITE | PG_NC | PG_REF | PG_MOD))
1114		panic("pv_changepte: clear=0x%x", clear_bits);
1115#endif
1116
1117	flags = 0;
1118	saved_ctx = get_context();
1119	for (pv = *head; pv != NULL; pv = pv->pv_next) {
1120		pmap = pv->pv_pmap;
1121		va = pv->pv_va;
1122
1123#ifdef	DIAGNOSTIC
1124		if (pmap->pm_segmap == NULL)
1125			panic("pv_changepte: null segmap");
1126#endif
1127
1128		/* Is the PTE currently accessible in some context? */
1129		in_ctx = false;
1130		sme = SEGINV;	/* kill warning */
1131		if (pmap == kernel_pmap)
1132			in_ctx = true;
1133		else if (has_context(pmap)) {
1134			/* PMEG may be inactive. */
1135			set_context(pmap->pm_ctxnum);
1136			sme = get_segmap(va);
1137			if (sme != SEGINV)
1138				in_ctx = true;
1139		}
1140
1141		if (in_ctx == true) {
1142			/*
1143			 * The PTE is in the current context.
1144			 * Make sure PTE is up-to-date with VAC.
1145			 */
1146#ifdef	HAVECACHE
1147			if (cache_size)
1148				cache_flush_page(va);
1149#endif
1150			pte = get_pte(va);
1151		} else {
1152
1153			/*
1154			 * The PTE is not in any context.
1155			 */
1156
1157			sme = pmap->pm_segmap[VA_SEGNUM(va)];
1158#ifdef	DIAGNOSTIC
1159			if (sme == SEGINV)
1160				panic("pv_changepte: SEGINV");
1161#endif
1162			pte = get_pte_pmeg(sme, VA_PTE_NUM(va));
1163		}
1164
1165#ifdef	DIAGNOSTIC
1166		/* PV entries point only to valid mappings. */
1167		if ((pte & PG_VALID) == 0)
1168			panic("pv_changepte: not PG_VALID at va=0x%lx", va);
1169#endif
1170		/* Get these while it's easy. */
1171		if (pte & PG_MODREF) {
1172			flags |= (pte & PG_MODREF);
1173			pte &= ~PG_MODREF;
1174		}
1175
1176		/* Finally, set and clear some bits. */
1177		pte |= set_bits;
1178		pte &= ~clear_bits;
1179
1180		if (in_ctx == true) {
1181			/* Did cache flush above. */
1182			set_pte(va, pte);
1183		} else {
1184			set_pte_pmeg(sme, VA_PTE_NUM(va), pte);
1185		}
1186	}
1187	set_context(saved_ctx);
1188
1189	*pv_flags |= (flags >> PV_SHIFT);
1190}
1191
1192/*
1193 * Return ref and mod bits from pvlist,
1194 * and turns off same in hardware PTEs.
1195 */
1196static u_int
1197pv_syncflags(pv_entry_t pv)
1198{
1199	pmap_t pmap;
1200	vaddr_t va;
1201	int pte, sme;
1202	int saved_ctx;
1203	bool in_ctx;
1204	u_int flags;
1205
1206	/* If no mappings, no work to do. */
1207	if (pv == NULL)
1208		return (0);
1209
1210	flags = 0;
1211	saved_ctx = get_context();
1212	for (; pv != NULL; pv = pv->pv_next) {
1213		pmap = pv->pv_pmap;
1214		va = pv->pv_va;
1215		sme = SEGINV;
1216
1217#ifdef	DIAGNOSTIC
1218		/*
1219		 * Only the head may have a null pmap, and
1220		 * we checked for that above.
1221		 */
1222		if (pmap->pm_segmap == NULL)
1223			panic("pv_syncflags: null segmap");
1224#endif
1225
1226		/* Is the PTE currently accessible in some context? */
1227		in_ctx = false;
1228		if (pmap == kernel_pmap)
1229			in_ctx = true;
1230		else if (has_context(pmap)) {
1231			/* PMEG may be inactive. */
1232			set_context(pmap->pm_ctxnum);
1233			sme = get_segmap(va);
1234			if (sme != SEGINV)
1235				in_ctx = true;
1236		}
1237
1238		if (in_ctx == true) {
1239
1240			/*
1241			 * The PTE is in the current context.
1242			 * Make sure PTE is up-to-date with VAC.
1243			 */
1244
1245#ifdef	HAVECACHE
1246			if (cache_size)
1247				cache_flush_page(va);
1248#endif
1249			pte = get_pte(va);
1250		} else {
1251
1252			/*
1253			 * The PTE is not in any context.
1254			 */
1255
1256			sme = pmap->pm_segmap[VA_SEGNUM(va)];
1257#ifdef	DIAGNOSTIC
1258			if (sme == SEGINV)
1259				panic("pv_syncflags: SEGINV");
1260#endif
1261			pte = get_pte_pmeg(sme, VA_PTE_NUM(va));
1262		}
1263
1264#ifdef	DIAGNOSTIC
1265		/* PV entries point only to valid mappings. */
1266		if ((pte & PG_VALID) == 0)
1267			panic("pv_syncflags: not PG_VALID at va=0x%lx", va);
1268#endif
1269		/* OK, do what we came here for... */
1270		if (pte & PG_MODREF) {
1271			flags |= (pte & PG_MODREF);
1272			pte &= ~PG_MODREF;
1273		}
1274
1275		if (in_ctx == true) {
1276			/* Did cache flush above. */
1277			set_pte(va, pte);
1278		} else {
1279			set_pte_pmeg(sme, VA_PTE_NUM(va), pte);
1280		}
1281	}
1282	set_context(saved_ctx);
1283
1284	return (flags >> PV_SHIFT);
1285}
1286
1287/* Remove all mappings for the physical page. */
1288static void
1289pv_remove_all(paddr_t pa)
1290{
1291	pv_entry_t *head, pv;
1292	pmap_t pmap;
1293	vaddr_t va;
1294
1295	CHECK_SPL();
1296
1297#ifdef PMAP_DEBUG
1298	if (pmap_debug & PMD_REMOVE)
1299		printf("pv_remove_all(0x%lx)\n", pa);
1300#endif
1301
1302	head = pa_to_pvhead(pa);
1303	while ((pv = *head) != NULL) {
1304		pmap = pv->pv_pmap;
1305		va   = pv->pv_va;
1306		pmap_remove1(pmap, va, va + PAGE_SIZE);
1307#ifdef PMAP_DEBUG
1308		/* Make sure it went away. */
1309		if (pv == *head) {
1310			db_printf("pv_remove_all: "
1311				  "head unchanged for pa=0x%lx\n", pa);
1312			Debugger();
1313		}
1314#endif
1315	}
1316}
1317
1318/*
1319 * The pmap system is asked to lookup all mappings that point to a
1320 * given physical memory address.  This function adds a new element
1321 * to the list of mappings maintained for the given physical address.
1322 * Returns PV_NC if the (new) pvlist says that the address cannot
1323 * be cached.
1324 */
1325static int
1326pv_link(pmap_t pmap, int pte, vaddr_t va)
1327{
1328	paddr_t pa;
1329	pv_entry_t *head, pv;
1330	u_char *pv_flags;
1331#ifdef HAVECACHE
1332	int flags;
1333#endif
1334
1335	if (!pv_initialized)
1336		return 0;
1337
1338	CHECK_SPL();
1339
1340	pa = PG_PA(pte);
1341
1342#ifdef PMAP_DEBUG
1343	if ((pmap_debug & PMD_LINK) || (va == pmap_db_watchva)) {
1344		printf("pv_link(%p, 0x%x, 0x%lx)\n", pmap, pte, va);
1345		/* pv_print(pa); */
1346	}
1347#endif
1348
1349	pv_flags = pa_to_pvflags(pa);
1350	head     = pa_to_pvhead(pa);
1351
1352#ifdef	DIAGNOSTIC
1353	/* See if this mapping is already in the list. */
1354	for (pv = *head; pv != NULL; pv = pv->pv_next) {
1355		if ((pv->pv_pmap == pmap) && (pv->pv_va == va))
1356			panic("pv_link: duplicate entry for PA=0x%lx", pa);
1357	}
1358#endif
1359
1360	flags = (pte & (PG_NC | PG_MODREF)) >> PV_SHIFT;
1361	*pv_flags |= flags;
1362
1363#ifdef HAVECACHE
1364	/*
1365	 * Does this new mapping cause VAC alias problems?
1366	 */
1367	if ((*pv_flags & PV_NC) == 0) {
1368		for (pv = *head; pv != NULL; pv = pv->pv_next) {
1369			if (BADALIAS(va, pv->pv_va)) {
1370				*pv_flags |= PV_NC;
1371				pv_changepte(pa, PG_NC, 0);
1372				pmap_stats.ps_vac_uncached++;
1373				break;
1374			}
1375		}
1376	}
1377#endif
1378
1379	/* Allocate a PV element (pv_alloc()). */
1380	pv = pv_free_list;
1381	if (pv == NULL)
1382		panic("pv_link: pv_alloc");
1383	pv_free_list = pv->pv_next;
1384	pv->pv_next = 0;
1385
1386	/* Insert new entry at the head. */
1387	pv->pv_pmap = pmap;
1388	pv->pv_va   = va;
1389	pv->pv_next = *head;
1390	*head = pv;
1391
1392	return (*pv_flags & PV_NC);
1393}
1394
1395/*
1396 * pv_unlink is a helper function for pmap_remove.
1397 * It removes the appropriate (pmap, pa, va) entry.
1398 *
1399 * Once the entry is removed, if the pv_table head has the cache
1400 * inhibit bit set, see if we can turn that off; if so, walk the
1401 * pvlist and turn off PG_NC in each PTE.  (The pvlist is by
1402 * definition nonempty, since it must have at least two elements
1403 * in it to have PV_NC set, and we only remove one here.)
1404 */
1405static void
1406pv_unlink(pmap_t pmap, int pte, vaddr_t va)
1407{
1408	paddr_t pa;
1409	pv_entry_t *head, *ppv, pv;
1410	u_char *pv_flags;
1411
1412	CHECK_SPL();
1413
1414	pa = PG_PA(pte);
1415#ifdef PMAP_DEBUG
1416	if ((pmap_debug & PMD_LINK) || (va == pmap_db_watchva)) {
1417		printf("pv_unlink(%p, 0x%x, 0x%lx)\n", pmap, pte, va);
1418		/* pv_print(pa); */
1419	}
1420#endif
1421
1422	pv_flags = pa_to_pvflags(pa);
1423	head     = pa_to_pvhead(pa);
1424
1425	/*
1426	 * Find the entry.
1427	 */
1428	ppv = head;
1429	pv = *ppv;
1430	while (pv) {
1431		if ((pv->pv_pmap == pmap) && (pv->pv_va == va))
1432			goto found;
1433		ppv = &pv->pv_next;
1434		pv  =  pv->pv_next;
1435	}
1436#ifdef PMAP_DEBUG
1437	db_printf("pv_unlink: not found (pa=0x%lx,va=0x%lx)\n", pa, va);
1438	Debugger();
1439#endif
1440	return;
1441
1442  found:
1443	/* Unlink this entry from the list and clear it. */
1444	*ppv = pv->pv_next;
1445	pv->pv_pmap = NULL;
1446	pv->pv_va   = 0;
1447
1448	/* Insert it on the head of the free list. (pv_free()) */
1449	pv->pv_next = pv_free_list;
1450	pv_free_list = pv;
1451	pv = NULL;
1452
1453	/* Do any non-cached mappings remain? */
1454	if ((*pv_flags & PV_NC) == 0)
1455		return;
1456	if ((pv = *head) == NULL)
1457		return;
1458
1459	/*
1460	 * Have non-cached mappings.  See if we can fix that now.
1461	 */
1462	va = pv->pv_va;
1463	for (pv = pv->pv_next; pv != NULL; pv = pv->pv_next) {
1464		/* If there is a DVMA mapping, leave it NC. */
1465		if (va >= DVMA_MAP_BASE)
1466			return;
1467		/* If there are VAC alias problems, leave NC. */
1468		if (BADALIAS(va, pv->pv_va))
1469			return;
1470	}
1471	/* OK, there are no "problem" mappings. */
1472	*pv_flags &= ~PV_NC;
1473	pv_changepte(pa, 0, PG_NC);
1474	pmap_stats.ps_vac_recached++;
1475}
1476
1477
1478/****************************************************************
1479 * Bootstrap and Initialization, etc.
1480 */
1481
1482void
1483pmap_common_init(pmap_t pmap)
1484{
1485	memset(pmap, 0, sizeof(struct pmap));
1486	pmap->pm_refcount = 1;
1487	pmap->pm_version = pmap_version++;
1488	pmap->pm_ctxnum = EMPTY_CONTEXT;
1489}
1490
1491/*
1492 * Prepare the kernel for VM operations.
1493 * This is called by locore2.c:_vm_init()
1494 * after the "start/end" globals are set.
1495 * This function must NOT leave context zero.
1496 */
1497void
1498pmap_bootstrap(vaddr_t nextva)
1499{
1500	struct sunromvec *rvec;
1501	vaddr_t va, eva;
1502	int i, pte, sme;
1503	extern char etext[];
1504
1505	nextva = m68k_round_page(nextva);
1506	rvec = romVectorPtr;
1507
1508	/* Steal some special-purpose, already mapped pages? */
1509
1510	/*
1511	 * Determine the range of kernel virtual space available.
1512	 * It is segment-aligned to simplify PMEG management.
1513	 */
1514	virtual_avail = sun3_round_seg(nextva);
1515	virtual_end = VM_MAX_KERNEL_ADDRESS;
1516
1517	/*
1518	 * Determine the range of physical memory available.
1519	 * Physical memory at zero was remapped to KERNBASE.
1520	 */
1521	avail_start = nextva - KERNBASE3;
1522	if (rvec->romvecVersion < 1) {
1523		mon_printf("Warning: ancient PROM version=%d\n",
1524			   rvec->romvecVersion);
1525		/* Guess that PROM version 0.X used two pages. */
1526		avail_end = *rvec->memorySize - (2*PAGE_SIZE);
1527	} else {
1528		/* PROM version 1 or later. */
1529		avail_end = *rvec->memoryAvail;
1530	}
1531	avail_end = m68k_trunc_page(avail_end);
1532
1533	/*
1534	 * Report the actual amount of physical memory,
1535	 * even though the PROM takes a few pages.
1536	 */
1537	physmem = (btoc(avail_end) + 0xF) & ~0xF;
1538
1539	/*
1540	 * On the Sun3/50, the video frame buffer is located at
1541	 * physical address 1MB so we must step over it.
1542	 */
1543	if (cpu_machine_id == ID_SUN3_50) {
1544		hole_start = m68k_trunc_page(OBMEM_BW50_ADDR);
1545		hole_size  = m68k_round_page(OBMEM_BW2_SIZE);
1546		if (avail_start > hole_start) {
1547			mon_printf("kernel too large for Sun3/50\n");
1548			sunmon_abort();
1549		}
1550	}
1551
1552	/*
1553	 * Done allocating PAGES of virtual space, so
1554	 * clean out the rest of the last used segment.
1555	 */
1556	for (va = nextva; va < virtual_avail; va += PAGE_SIZE)
1557		set_pte(va, PG_INVAL);
1558
1559	/*
1560	 * Now that we are done stealing physical pages, etc.
1561	 * figure out which PMEGs are used by those mappings
1562	 * and either reserve them or clear them out.
1563	 * -- but first, init PMEG management.
1564	 * This puts all PMEGs in the free list.
1565	 * We will allocte the in-use ones.
1566	 */
1567	pmeg_init();
1568
1569	/*
1570	 * Unmap user virtual segments.
1571	 * VA range: [0 .. KERNBASE]
1572	 */
1573	for (va = 0; va < KERNBASE3; va += NBSG)
1574		set_segmap(va, SEGINV);
1575
1576	/*
1577	 * Reserve PMEGS for kernel text/data/bss
1578	 * and the misc pages taken above.
1579	 * VA range: [KERNBASE .. virtual_avail]
1580	 */
1581	for ( ; va < virtual_avail; va += NBSG) {
1582		sme = get_segmap(va);
1583		if (sme == SEGINV) {
1584			mon_printf("kernel text/data/bss not mapped\n");
1585			sunmon_abort();
1586		}
1587		pmeg_reserve(sme);
1588	}
1589
1590	/*
1591	 * Unmap kernel virtual space.  Make sure to leave no valid
1592	 * segmap entries in the MMU unless pmeg_array records them.
1593	 * VA range: [vseg_avail .. virtual_end]
1594	 */
1595	for ( ; va < virtual_end; va += NBSG)
1596		set_segmap(va, SEGINV);
1597
1598	/*
1599	 * Reserve PMEGs used by the PROM monitor (device mappings).
1600	 * Free up any pmegs in this range which have no mappings.
1601	 * VA range: [0x0FE00000 .. 0x0FF00000]
1602	 */
1603	pmeg_mon_init(SUN3_MONSTART, SUN3_MONEND, true);
1604
1605	/*
1606	 * Unmap any pmegs left in DVMA space by the PROM.
1607	 * DO NOT kill the last one! (owned by the PROM!)
1608	 * VA range: [0x0FF00000 .. 0x0FFE0000]
1609	 */
1610	pmeg_mon_init(SUN3_MONEND, SUN3_MONSHORTSEG, false);
1611
1612	/*
1613	 * MONSHORTSEG contains MONSHORTPAGE which is a data page
1614	 * allocated by the PROM monitor.  Reserve the segment,
1615	 * but clear out all but the last PTE inside it.
1616	 * Note we use this for tmp_vpages.
1617	 */
1618	va  = SUN3_MONSHORTSEG;
1619	eva = SUN3_MONSHORTPAGE;
1620	sme = get_segmap(va);
1621	pmeg_reserve(sme);
1622	for ( ; va < eva; va += PAGE_SIZE)
1623		set_pte(va, PG_INVAL);
1624
1625	/*
1626	 * Done reserving PMEGs and/or clearing out mappings.
1627	 *
1628	 * Now verify the mapping protections and such for the
1629	 * important parts of the address space (in VA order).
1630	 * Note that the Sun PROM usually leaves the memory
1631	 * mapped with everything non-cached...
1632	 */
1633
1634	/*
1635	 * Map the message buffer page at a constant location
1636	 * (physical address zero) so its contents will be
1637	 * preserved through a reboot.
1638	 */
1639	va = KERNBASE3;
1640	pte = get_pte(va);
1641	pte |= (PG_SYSTEM | PG_WRITE | PG_NC);
1642	set_pte(va, pte);
1643	va += PAGE_SIZE;
1644	/* Initialize msgbufaddr later, in machdep.c */
1645
1646	/* Next is the tmpstack page. */
1647	pte = get_pte(va);
1648	pte &= ~(PG_NC);
1649	pte |= (PG_SYSTEM | PG_WRITE);
1650	set_pte(va, pte);
1651	va += PAGE_SIZE;
1652
1653	/*
1654	 * Next is the kernel text.
1655	 *
1656	 * Verify protection bits on kernel text/data/bss
1657	 * All of kernel text, data, and bss are cached.
1658	 * Text is read-only (except in db_write_ktext).
1659	 */
1660	eva = m68k_trunc_page(etext);
1661	while (va < eva) {
1662		pte = get_pte(va);
1663		if ((pte & (PG_VALID|PG_TYPE)) != PG_VALID) {
1664			mon_printf("invalid page at 0x%x\n", va);
1665		}
1666		pte &= ~(PG_WRITE|PG_NC);
1667		/* Kernel text is read-only */
1668		pte |= (PG_SYSTEM);
1669		set_pte(va, pte);
1670		va += PAGE_SIZE;
1671	}
1672	/* data, bss, etc. */
1673	while (va < nextva) {
1674		pte = get_pte(va);
1675		if ((pte & (PG_VALID|PG_TYPE)) != PG_VALID) {
1676			mon_printf("invalid page at 0x%x\n", va);
1677		}
1678		pte &= ~(PG_NC);
1679		pte |= (PG_SYSTEM | PG_WRITE);
1680		set_pte(va, pte);
1681		va += PAGE_SIZE;
1682	}
1683
1684	/*
1685	 * Duplicate all mappings in the current context into
1686	 * every other context.  We have to let the PROM do the
1687	 * actual segmap manipulation because we can only switch
1688	 * the MMU context after we are sure that the kernel is
1689	 * identically mapped in all contexts.  The PROM can do
1690	 * the job using hardware-dependent tricks...
1691	 */
1692#ifdef	DIAGNOSTIC
1693	/* Note: PROM setcxsegmap function needs sfc=dfc=FC_CONTROL */
1694	if ((getsfc() != FC_CONTROL) || (getdfc() != FC_CONTROL)) {
1695		mon_printf("pmap_bootstrap: bad dfc or sfc\n");
1696		sunmon_abort();
1697	}
1698	/* Near the beginning of locore.s we set context zero. */
1699	if (get_context() != 0) {
1700		mon_printf("pmap_bootstrap: not in context zero?\n");
1701		sunmon_abort();
1702	}
1703#endif	/* DIAGNOSTIC */
1704	for (va = 0; va < (vaddr_t) (NBSG * NSEGMAP); va += NBSG) {
1705		/* Read the segmap entry from context zero... */
1706		sme = get_segmap(va);
1707		/* ... then copy it into all other contexts. */
1708		for (i = 1; i < NCONTEXT; i++) {
1709			(*rvec->setcxsegmap)(i, va, sme);
1710		}
1711	}
1712
1713	/*
1714	 * Reserve a segment for the kernel to use to access a pmeg
1715	 * that is not currently mapped into any context/segmap.
1716	 * The kernel temporarily maps such a pmeg into this segment.
1717	 *
1718	 * XXX: Now that context zero is reserved as kernel-only,
1719	 * we could borrow context zero for these temporary uses.
1720	 */
1721	temp_seg_va = virtual_avail;
1722	virtual_avail += NBSG;
1723#ifdef	DIAGNOSTIC
1724	if (temp_seg_va & SEGOFSET) {
1725		mon_printf("pmap_bootstrap: temp_seg_va\n");
1726		sunmon_abort();
1727	}
1728#endif
1729
1730	/* Initialization for pmap_next_page() */
1731	avail_next = avail_start;
1732
1733	uvmexp.pagesize = PAGE_SIZE;
1734	uvm_md_init();
1735
1736	/* after setting up some structures */
1737
1738	pmap_common_init(kernel_pmap);
1739	pmap_kernel_init(kernel_pmap);
1740
1741	context_init();
1742
1743	pmeg_clean_free();
1744
1745	pmap_page_upload();
1746}
1747
1748/*
1749 * Give the kernel pmap a segmap, just so there are not
1750 * so many special cases required.  Maybe faster too,
1751 * because this lets pmap_remove() and pmap_protect()
1752 * use a S/W copy of the segmap to avoid function calls.
1753 */
1754void
1755pmap_kernel_init(pmap_t pmap)
1756{
1757	vaddr_t va;
1758	int i, sme;
1759
1760	for (i=0, va=0; i < NSEGMAP; i++, va+=NBSG) {
1761		sme = get_segmap(va);
1762		kernel_segmap[i] = sme;
1763	}
1764	pmap->pm_segmap = kernel_segmap;
1765}
1766
1767
1768/****************************************************************
1769 * PMAP interface functions.
1770 */
1771
1772/*
1773 * Support functions for vm_page_bootstrap().
1774 */
1775
1776/*
1777 * How much virtual space does this kernel have?
1778 * (After mapping kernel text, data, etc.)
1779 */
1780void
1781pmap_virtual_space(vaddr_t *v_start, vaddr_t *v_end)
1782{
1783	*v_start = virtual_avail;
1784	*v_end   = virtual_end;
1785}
1786
1787/* Provide memory to the VM system. */
1788static void
1789pmap_page_upload(void)
1790{
1791	int a, b, c, d;
1792
1793	if (hole_size) {
1794		/*
1795		 * Supply the memory in two segments so the
1796		 * reserved memory (3/50 video ram at 1MB)
1797		 * can be carved from the front of the 2nd.
1798		 */
1799		a = atop(avail_start);
1800		b = atop(hole_start);
1801		uvm_page_physload(a, b, a, b, VM_FREELIST_DEFAULT);
1802		c = atop(hole_start + hole_size);
1803		d = atop(avail_end);
1804		uvm_page_physload(b, d, c, d, VM_FREELIST_DEFAULT);
1805	} else {
1806		a = atop(avail_start);
1807		d = atop(avail_end);
1808		uvm_page_physload(a, d, a, d, VM_FREELIST_DEFAULT);
1809	}
1810}
1811
1812/*
1813 *	Initialize the pmap module.
1814 *	Called by vm_init, to initialize any structures that the pmap
1815 *	system needs to map virtual memory.
1816 */
1817void
1818pmap_init(void)
1819{
1820	pv_init();
1821
1822	/* Initialize the pmap pool. */
1823	pool_init(&pmap_pmap_pool, sizeof(struct pmap), 0, 0, 0, "pmappl",
1824		  &pool_allocator_nointr, IPL_NONE);
1825}
1826
1827/*
1828 * Map a range of kernel virtual address space.
1829 * This might be used for device mappings, or to
1830 * record the mapping for kernel text/data/bss.
1831 * Return VA following the mapped range.
1832 */
1833vaddr_t
1834pmap_map(vaddr_t va, paddr_t pa, paddr_t endpa, int prot)
1835{
1836	int sz;
1837
1838	sz = endpa - pa;
1839	do {
1840		pmap_enter(kernel_pmap, va, pa, prot, 0);
1841		va += PAGE_SIZE;
1842		pa += PAGE_SIZE;
1843		sz -= PAGE_SIZE;
1844	} while (sz > 0);
1845	pmap_update(kernel_pmap);
1846	return(va);
1847}
1848
1849void
1850pmap_user_init(pmap_t pmap)
1851{
1852	int i;
1853	pmap->pm_segmap = kmem_alloc(sizeof(char)*NUSEG, KM_SLEEP);
1854	for (i = 0; i < NUSEG; i++) {
1855		pmap->pm_segmap[i] = SEGINV;
1856	}
1857}
1858
1859/*
1860 *	Create and return a physical map.
1861 *
1862 *	If the size specified for the map
1863 *	is zero, the map is an actual physical
1864 *	map, and may be referenced by the
1865 *	hardware.
1866 *
1867 *	If the size specified is non-zero,
1868 *	the map will be used in software only, and
1869 *	is bounded by that size.
1870 */
1871pmap_t
1872pmap_create(void)
1873{
1874	pmap_t pmap;
1875
1876	pmap = pool_get(&pmap_pmap_pool, PR_WAITOK);
1877	pmap_pinit(pmap);
1878	return pmap;
1879}
1880
1881/*
1882 * Release any resources held by the given physical map.
1883 * Called when a pmap initialized by pmap_pinit is being released.
1884 * Should only be called if the map contains no valid mappings.
1885 */
1886void
1887pmap_release(struct pmap *pmap)
1888{
1889	int s;
1890
1891	s = splvm();
1892
1893	if (pmap == kernel_pmap)
1894		panic("pmap_release: kernel_pmap!");
1895
1896	if (has_context(pmap)) {
1897#ifdef	PMAP_DEBUG
1898		if (pmap_debug & PMD_CONTEXT)
1899			printf("pmap_release(%p): free ctx %d\n",
1900			       pmap, pmap->pm_ctxnum);
1901#endif
1902		context_free(pmap);
1903	}
1904	kmem_free(pmap->pm_segmap, sizeof(char)*NUSEG);
1905	pmap->pm_segmap = NULL;
1906
1907	splx(s);
1908}
1909
1910
1911/*
1912 *	Retire the given physical map from service.
1913 *	Should only be called if the map contains
1914 *	no valid mappings.
1915 */
1916void
1917pmap_destroy(pmap_t pmap)
1918{
1919	int count;
1920
1921#ifdef PMAP_DEBUG
1922	if (pmap_debug & PMD_CREATE)
1923		printf("pmap_destroy(%p)\n", pmap);
1924#endif
1925	if (pmap == kernel_pmap)
1926		panic("pmap_destroy: kernel_pmap!");
1927	count = atomic_dec_uint_nv(&pmap->pm_refcount);
1928	if (count == 0) {
1929		pmap_release(pmap);
1930		pool_put(&pmap_pmap_pool, pmap);
1931	}
1932}
1933
1934/*
1935 *	Add a reference to the specified pmap.
1936 */
1937void
1938pmap_reference(pmap_t pmap)
1939{
1940
1941	atomic_inc_uint(&pmap->pm_refcount);
1942}
1943
1944
1945/*
1946 *	Insert the given physical page (p) at
1947 *	the specified virtual address (v) in the
1948 *	target physical map with the protection requested.
1949 *
1950 *	The physical address is page aligned, but may have some
1951 *	low bits set indicating an OBIO or VME bus page, or just
1952 *	that the non-cache bit should be set (i.e PMAP_NC).
1953 *
1954 *	If specified, the page will be wired down, meaning
1955 *	that the related pte can not be reclaimed.
1956 *
1957 *	NB:  This is the only routine which MAY NOT lazy-evaluate
1958 *	or lose information.  That is, this routine must actually
1959 *	insert this page into the given map NOW.
1960 */
1961int
1962pmap_enter(pmap_t pmap, vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
1963{
1964	int new_pte, s;
1965	bool wired = (flags & PMAP_WIRED) != 0;
1966
1967#ifdef	PMAP_DEBUG
1968	if ((pmap_debug & PMD_ENTER) ||
1969	    (va == pmap_db_watchva))
1970		printf("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)\n",
1971		       pmap, va, pa, prot, wired);
1972#endif
1973
1974	/* Get page-type bits from low part of the PA... */
1975	new_pte = (pa & PMAP_SPEC) << PG_MOD_SHIFT;
1976
1977	/* ...now the valid and writable bits... */
1978	new_pte |= PG_VALID;
1979	if (prot & VM_PROT_WRITE)
1980		new_pte |= PG_WRITE;
1981	if (flags & VM_PROT_ALL) {
1982		new_pte |= PG_REF;
1983		if (flags & VM_PROT_WRITE) {
1984			new_pte |= PG_MOD;
1985		}
1986	}
1987
1988	/* ...and finally the page-frame number. */
1989	new_pte |= PA_PGNUM(pa);
1990
1991	/*
1992	 * treatment varies significantly:
1993	 *  kernel ptes are in all contexts, and are always in the mmu
1994	 *  user ptes may not necessarily? be in the mmu.  pmap may not
1995	 *   be in the mmu either.
1996	 *
1997	 */
1998	s = splvm();
1999	if (pmap == kernel_pmap) {
2000		new_pte |= PG_SYSTEM;
2001		pmap_enter_kernel(va, new_pte, wired);
2002	} else {
2003		pmap_enter_user(pmap, va, new_pte, wired);
2004	}
2005	splx(s);
2006	return 0;
2007}
2008
2009static void
2010pmap_enter_kernel(vaddr_t pgva, int new_pte, bool wired)
2011{
2012	pmap_t pmap = kernel_pmap;
2013	pmeg_t pmegp;
2014	int do_pv, old_pte, sme;
2015	vaddr_t segva;
2016
2017	/*
2018	  keep in hardware only, since its mapped into all contexts anyway;
2019	  need to handle possibly allocating additional pmegs
2020	  need to make sure they cant be stolen from the kernel;
2021	  map any new pmegs into all contexts, make sure rest of pmeg is null;
2022	  deal with pv_stuff; possibly caching problems;
2023	  must also deal with changes too.
2024	*/
2025
2026	/*
2027	 * In detail:
2028	 *
2029	 * (a) lock pmap
2030	 * (b) Is the VA in a already mapped segment, if so
2031	 *	 look to see if that VA address is "valid".  If it is, then
2032	 *	 action is a change to an existing pte
2033	 * (c) if not mapped segment, need to allocate pmeg
2034	 * (d) if adding pte entry or changing physaddr of existing one,
2035	 *		use pv_stuff, for change, pmap_remove() possibly.
2036	 * (e) change/add pte
2037	 */
2038
2039#ifdef	DIAGNOSTIC
2040	if ((pgva < virtual_avail) || (pgva >= DVMA_MAP_END))
2041		panic("pmap_enter_kernel: bad va=0x%lx", pgva);
2042	if ((new_pte & (PG_VALID | PG_SYSTEM)) != (PG_VALID | PG_SYSTEM))
2043		panic("pmap_enter_kernel: bad pte");
2044#endif
2045
2046	if (pgva >= DVMA_MAP_BASE) {
2047		/* This is DVMA space.  Always want it non-cached. */
2048		new_pte |= PG_NC;
2049	}
2050
2051	segva = sun3_trunc_seg(pgva);
2052	do_pv = true;
2053
2054	/* Do we have a PMEG? */
2055	sme = get_segmap(segva);
2056	if (sme != SEGINV) {
2057		/* Found a PMEG in the segmap.  Cool. */
2058		pmegp = pmeg_p(sme);
2059#ifdef	DIAGNOSTIC
2060		/* Make sure it is the right PMEG. */
2061		if (sme != pmap->pm_segmap[VA_SEGNUM(segva)])
2062			panic("pmap_enter_kernel: wrong sme at VA=0x%lx",
2063			      segva);
2064		/* Make sure it is ours. */
2065		if (pmegp->pmeg_owner != pmap)
2066			panic("pmap_enter_kernel: MMU has bad pmeg 0x%x", sme);
2067#endif
2068	} else {
2069		/* No PMEG in the segmap.  Have to allocate one. */
2070		pmegp = pmeg_allocate(pmap, segva);
2071		sme = pmegp->pmeg_index;
2072		pmap->pm_segmap[VA_SEGNUM(segva)] = sme;
2073		set_segmap_allctx(segva, sme);
2074#ifdef	PMAP_DEBUG
2075		pmeg_verify_empty(segva);
2076		if (pmap_debug & PMD_SEGMAP) {
2077			printf("pmap: set_segmap pmap=%p va=0x%lx sme=0x%x "
2078			       "(ek)\n", pmap, segva, sme);
2079		}
2080#endif
2081		/* There are no existing mappings to deal with. */
2082		old_pte = 0;
2083		goto add_pte;
2084	}
2085
2086	/*
2087	 * We have a PMEG.  Is the VA already mapped to somewhere?
2088	 *	(a) if so, is it same pa? (really a protection change)
2089	 *	(b) if not same pa, then we have to unlink from old pa
2090	 */
2091	old_pte = get_pte(pgva);
2092	if ((old_pte & PG_VALID) == 0)
2093		goto add_pte;
2094
2095	/* Have valid translation.  Flush cache before changing it. */
2096#ifdef	HAVECACHE
2097	if (cache_size) {
2098		cache_flush_page(pgva);
2099		/* Get fresh mod/ref bits from write-back. */
2100		old_pte = get_pte(pgva);
2101	}
2102#endif
2103
2104	/* XXX - removing valid page here, way lame... -glass */
2105	pmegp->pmeg_vpages--;
2106
2107	if (!IS_MAIN_MEM(old_pte)) {
2108		/* Was not main memory, so no pv_entry for it. */
2109		goto add_pte;
2110	}
2111
2112	/* Old mapping was main memory.  Save mod/ref bits. */
2113	save_modref_bits(old_pte);
2114
2115	/*
2116	 * If not changing the type or pfnum then re-use pv_entry.
2117	 * Note we get here only with old_pte having PGT_OBMEM.
2118	 */
2119	if ((old_pte & (PG_TYPE|PG_FRAME)) == (new_pte & (PG_TYPE|PG_FRAME))) {
2120		do_pv = false;		/* re-use pv_entry */
2121		new_pte |= (old_pte & PG_NC);
2122		goto add_pte;
2123	}
2124
2125	/* OK, different type or PA, have to kill old pv_entry. */
2126	pv_unlink(pmap, old_pte, pgva);
2127
2128add_pte:	/* can be destructive */
2129	pmeg_set_wiring(pmegp, pgva, wired);
2130
2131	/* Anything but MAIN_MEM is mapped non-cached. */
2132	if (!IS_MAIN_MEM(new_pte)) {
2133		new_pte |= PG_NC;
2134		do_pv = false;
2135	}
2136	if (do_pv == true) {
2137		if (pv_link(pmap, new_pte, pgva) & PV_NC)
2138			new_pte |= PG_NC;
2139	}
2140#ifdef	PMAP_DEBUG
2141	if ((pmap_debug & PMD_SETPTE) || (pgva == pmap_db_watchva)) {
2142		printf("pmap: set_pte pmap=%p va=0x%lx old=0x%x new=0x%x "
2143		       "(ek)\n", pmap, pgva, old_pte, new_pte);
2144	}
2145#endif
2146	/* cache flush done above */
2147	set_pte(pgva, new_pte);
2148	pmegp->pmeg_vpages++;
2149}
2150
2151
2152static void
2153pmap_enter_user(pmap_t pmap, vaddr_t pgva, int new_pte, bool wired)
2154{
2155	int do_pv, old_pte, sme;
2156	vaddr_t segva;
2157	pmeg_t pmegp;
2158
2159#ifdef	DIAGNOSTIC
2160	if (pgva >= VM_MAXUSER_ADDRESS)
2161		panic("pmap_enter_user: bad va=0x%lx", pgva);
2162	if ((new_pte & (PG_VALID | PG_SYSTEM)) != PG_VALID)
2163		panic("pmap_enter_user: bad pte");
2164#endif
2165#ifdef	PMAP_DEBUG
2166	/*
2167	 * Some user pages are wired here, and a later
2168	 * call to pmap_unwire() will unwire them.
2169	 * XXX - Need a separate list for wired user pmegs
2170	 * so they can not be stolen from the active list.
2171	 * XXX - Note: vm_fault.c assumes pmap_extract will
2172	 * work on wired mappings, so must preserve them...
2173	 * XXX: Maybe keep a list of wired PMEGs?
2174	 */
2175	if (wired && (pmap_debug & PMD_WIRING)) {
2176		db_printf("pmap_enter_user: attempt to wire user page, "
2177			  "ignored\n");
2178		Debugger();
2179	}
2180#endif
2181
2182	/* Validate this assumption. */
2183	if (pmap != current_pmap()) {
2184#ifdef	PMAP_DEBUG
2185		/* Apparently, this never happens. */
2186		db_printf("pmap_enter_user: not curlwp\n");
2187		Debugger();
2188#endif
2189		/* Just throw it out (fault it in later). */
2190		/* XXX: But must remember it if wired... */
2191		return;
2192	}
2193
2194	segva = sun3_trunc_seg(pgva);
2195	do_pv = true;
2196
2197	/*
2198	 * If this pmap was sharing the "empty" context,
2199	 * allocate a real context for its exclusive use.
2200	 */
2201	if (!has_context(pmap)) {
2202		context_allocate(pmap);
2203#ifdef PMAP_DEBUG
2204		if (pmap_debug & PMD_CONTEXT)
2205			printf("pmap_enter(%p) got context %d\n",
2206			       pmap, pmap->pm_ctxnum);
2207#endif
2208		set_context(pmap->pm_ctxnum);
2209	} else {
2210#ifdef	PMAP_DEBUG
2211		/* Make sure context is correct. */
2212		if (pmap->pm_ctxnum != get_context()) {
2213			db_printf("pmap_enter_user: wrong context\n");
2214			Debugger();
2215			/* XXX: OK to proceed? */
2216			set_context(pmap->pm_ctxnum);
2217		}
2218#endif
2219	}
2220
2221	/*
2222	 * We have a context.  Do we have a PMEG?
2223	 */
2224	sme = get_segmap(segva);
2225	if (sme != SEGINV) {
2226		/* Found a PMEG in the segmap.  Cool. */
2227		pmegp = pmeg_p(sme);
2228#ifdef	DIAGNOSTIC
2229		/* Make sure it is the right PMEG. */
2230		if (sme != pmap->pm_segmap[VA_SEGNUM(segva)])
2231			panic("pmap_enter_user: wrong sme at VA=0x%lx", segva);
2232		/* Make sure it is ours. */
2233		if (pmegp->pmeg_owner != pmap)
2234			panic("pmap_enter_user: MMU has bad pmeg 0x%x", sme);
2235#endif
2236	} else {
2237		/* Not in the segmap.  Try the S/W cache. */
2238		pmegp = pmeg_cache(pmap, segva);
2239		if (pmegp) {
2240			/* Found PMEG in cache.  Just reload it. */
2241			sme = pmegp->pmeg_index;
2242			set_segmap(segva, sme);
2243		} else {
2244			/* PMEG not in cache, so allocate one. */
2245			pmegp = pmeg_allocate(pmap, segva);
2246			sme = pmegp->pmeg_index;
2247			pmap->pm_segmap[VA_SEGNUM(segva)] = sme;
2248			set_segmap(segva, sme);
2249#ifdef	PMAP_DEBUG
2250			pmeg_verify_empty(segva);
2251#endif
2252		}
2253#ifdef	PMAP_DEBUG
2254		if (pmap_debug & PMD_SEGMAP) {
2255			printf("pmap: set_segmap pmap=%p va=0x%lx sme=0x%x "
2256			       "(eu)\n", pmap, segva, sme);
2257		}
2258#endif
2259	}
2260
2261	/*
2262	 * We have a PMEG.  Is the VA already mapped to somewhere?
2263	 *	(a) if so, is it same pa? (really a protection change)
2264	 *	(b) if not same pa, then we have to unlink from old pa
2265	 */
2266	old_pte = get_pte(pgva);
2267	if ((old_pte & PG_VALID) == 0)
2268		goto add_pte;
2269
2270	/* Have valid translation.  Flush cache before changing it. */
2271#ifdef	HAVECACHE
2272	if (cache_size) {
2273		cache_flush_page(pgva);
2274		/* Get fresh mod/ref bits from write-back. */
2275		old_pte = get_pte(pgva);
2276	}
2277#endif
2278
2279	/* XXX - removing valid page here, way lame... -glass */
2280	pmegp->pmeg_vpages--;
2281
2282	if (!IS_MAIN_MEM(old_pte)) {
2283		/* Was not main memory, so no pv_entry for it. */
2284		goto add_pte;
2285	}
2286
2287	/* Old mapping was main memory.  Save mod/ref bits. */
2288	save_modref_bits(old_pte);
2289
2290	/*
2291	 * If not changing the type or pfnum then re-use pv_entry.
2292	 * Note we get here only with old_pte having PGT_OBMEM.
2293	 */
2294	if ((old_pte & (PG_TYPE|PG_FRAME)) == (new_pte & (PG_TYPE|PG_FRAME))) {
2295		do_pv = false;		/* re-use pv_entry */
2296		new_pte |= (old_pte & PG_NC);
2297		goto add_pte;
2298	}
2299
2300	/* OK, different type or PA, have to kill old pv_entry. */
2301	pv_unlink(pmap, old_pte, pgva);
2302
2303  add_pte:
2304	/* XXX - Wiring changes on user pmaps? */
2305	/* pmeg_set_wiring(pmegp, pgva, wired); */
2306
2307	/* Anything but MAIN_MEM is mapped non-cached. */
2308	if (!IS_MAIN_MEM(new_pte)) {
2309		new_pte |= PG_NC;
2310		do_pv = false;
2311	}
2312	if (do_pv == true) {
2313		if (pv_link(pmap, new_pte, pgva) & PV_NC)
2314			new_pte |= PG_NC;
2315	}
2316#ifdef	PMAP_DEBUG
2317	if ((pmap_debug & PMD_SETPTE) || (pgva == pmap_db_watchva)) {
2318		printf("pmap: set_pte pmap=%p va=0x%lx old=0x%x new=0x%x "
2319		       "(eu)\n", pmap, pgva, old_pte, new_pte);
2320	}
2321#endif
2322	/* cache flush done above */
2323	set_pte(pgva, new_pte);
2324	pmegp->pmeg_vpages++;
2325}
2326
2327void
2328pmap_kenter_pa(vaddr_t va, paddr_t pa, vm_prot_t prot, u_int flags)
2329{
2330	int new_pte, s;
2331	pmap_t pmap = kernel_pmap;
2332	pmeg_t pmegp;
2333	int sme;
2334	vaddr_t segva;
2335
2336#ifdef	PMAP_DEBUG
2337	if ((pmap_debug & PMD_ENTER) ||
2338	    (va == pmap_db_watchva))
2339		printf("pmap_kenter_pa(0x%lx, 0x%lx, 0x%x)\n",
2340		       va, pa, prot);
2341#endif
2342
2343	/* Get page-type bits from low part of the PA... */
2344	new_pte = (pa & PMAP_SPEC) << PG_MOD_SHIFT;
2345
2346	/* ...now the valid and writable bits... */
2347	new_pte |= PG_SYSTEM|PG_VALID;
2348	if (prot & VM_PROT_WRITE)
2349		new_pte |= PG_WRITE;
2350
2351	/* ...and finally the page-frame number. */
2352	new_pte |= PA_PGNUM(pa);
2353
2354	/*
2355	 * keep in hardware only, since its mapped into all contexts anyway;
2356	 * need to handle possibly allocating additional pmegs
2357	 * need to make sure they cant be stolen from the kernel;
2358	 * map any new pmegs into all contexts, make sure rest of pmeg is null;
2359	 * must also deal with changes too.
2360	 */
2361
2362	/*
2363	 * In detail:
2364	 *
2365	 * (a) lock pmap
2366	 * (b) Is the VA in a already mapped segment, if so
2367	 *	 look to see if that VA address is "valid".  If it is, then
2368	 *	 action is a change to an existing pte
2369	 * (c) if not mapped segment, need to allocate pmeg
2370	 * (d) change/add pte
2371	 */
2372
2373#ifdef	DIAGNOSTIC
2374	if ((va < virtual_avail) || (va >= DVMA_MAP_END))
2375		panic("pmap_kenter_pa: bad va=0x%lx", va);
2376#endif
2377
2378	if (va >= DVMA_MAP_BASE) {
2379		/* This is DVMA space.  Always want it non-cached. */
2380		new_pte |= PG_NC;
2381	}
2382
2383	segva = sun3_trunc_seg(va);
2384
2385	s = splvm();
2386
2387	/* Do we have a PMEG? */
2388	sme = get_segmap(segva);
2389	if (sme != SEGINV) {
2390		KASSERT((get_pte(va) & PG_VALID) == 0);
2391
2392		/* Found a PMEG in the segmap.  Cool. */
2393		pmegp = pmeg_p(sme);
2394#ifdef	DIAGNOSTIC
2395		/* Make sure it is the right PMEG. */
2396		if (sme != pmap->pm_segmap[VA_SEGNUM(segva)])
2397			panic("pmap_kenter_pa: wrong sme at VA=0x%lx", segva);
2398		/* Make sure it is ours. */
2399		if (pmegp->pmeg_owner != pmap)
2400			panic("pmap_kenter_pa: MMU has bad pmeg 0x%x", sme);
2401#endif
2402	} else {
2403
2404		/* No PMEG in the segmap.  Have to allocate one. */
2405		pmegp = pmeg_allocate(pmap, segva);
2406		sme = pmegp->pmeg_index;
2407		pmap->pm_segmap[VA_SEGNUM(segva)] = sme;
2408		set_segmap_allctx(segva, sme);
2409#ifdef	PMAP_DEBUG
2410		pmeg_verify_empty(segva);
2411		if (pmap_debug & PMD_SEGMAP) {
2412			printf("pmap: set_segmap pmap=%p va=0x%lx sme=0x%x "
2413			       "(ek)\n", pmap, segva, sme);
2414		}
2415#endif
2416	}
2417
2418	pmeg_set_wiring(pmegp, va, true);
2419
2420	/* Anything but MAIN_MEM is mapped non-cached. */
2421	if (!IS_MAIN_MEM(new_pte)) {
2422		new_pte |= PG_NC;
2423	}
2424#ifdef	PMAP_DEBUG
2425	if ((pmap_debug & PMD_SETPTE) || (va == pmap_db_watchva)) {
2426		printf("pmap: set_pte pmap=%p va=0x%lx new=0x%x "
2427		       "(ek)\n", pmap, va, new_pte);
2428	}
2429#endif
2430	/* cache flush done above */
2431	set_pte(va, new_pte);
2432	pmegp->pmeg_vpages++;
2433	splx(s);
2434}
2435
2436void
2437pmap_kremove(vaddr_t va, vsize_t len)
2438{
2439	pmap_t pmap = kernel_pmap;
2440	vaddr_t eva, neva, pgva, segva, segnum;
2441	int pte, sme;
2442	pmeg_t pmegp;
2443	int flush_by_page = 0;
2444	int s;
2445
2446	s = splvm();
2447	segnum = VA_SEGNUM(va);
2448	for (eva = va + len; va < eva; va = neva, segnum++) {
2449		neva = sun3_trunc_seg(va) + NBSG;
2450		if (neva > eva) {
2451			neva = eva;
2452		}
2453		if (pmap->pm_segmap[segnum] == SEGINV) {
2454			continue;
2455		}
2456
2457		segva = sun3_trunc_seg(va);
2458		sme = get_segmap(segva);
2459		pmegp = pmeg_p(sme);
2460
2461#ifdef	HAVECACHE
2462		if (cache_size) {
2463
2464			/*
2465			 * If the range to be removed is larger than the cache,
2466			 * it will be cheaper to flush this segment entirely.
2467			 */
2468
2469			if (cache_size < (eva - va)) {
2470				/* cheaper to flush whole segment */
2471				cache_flush_segment(segva);
2472			} else {
2473				flush_by_page = 1;
2474			}
2475		}
2476#endif
2477
2478		/* Invalidate the PTEs in the given range. */
2479		for (pgva = va; pgva < neva; pgva += PAGE_SIZE) {
2480			pte = get_pte(pgva);
2481			if (pte & PG_VALID) {
2482				if (flush_by_page) {
2483#ifdef	HAVECACHE
2484					cache_flush_page(pgva);
2485					/* Get fresh mod/ref bits
2486					   from write-back. */
2487					pte = get_pte(pgva);
2488#endif
2489				}
2490#ifdef	PMAP_DEBUG
2491				if ((pmap_debug & PMD_SETPTE) ||
2492				    (pgva == pmap_db_watchva)) {
2493					printf("pmap: set_pte pmap=%p va=0x%lx"
2494					       " old=0x%x new=0x%x (rrmmu)\n",
2495					       pmap, pgva, pte, PG_INVAL);
2496				}
2497#endif
2498				set_pte(pgva, PG_INVAL);
2499				KASSERT(pmegp->pmeg_vpages > 0);
2500				pmegp->pmeg_vpages--;
2501			}
2502		}
2503		KASSERT(pmegp->pmeg_vpages >= 0);
2504		if (pmegp->pmeg_vpages == 0) {
2505			/* We are done with this pmeg. */
2506#ifdef	PMAP_DEBUG
2507			if (is_pmeg_wired(pmegp)) {
2508				if (pmap_debug & PMD_WIRING) {
2509					db_printf("pmap: removing wired "
2510						  "pmeg: %p\n", pmegp);
2511					Debugger();
2512				}
2513			}
2514			if (pmap_debug & PMD_SEGMAP) {
2515				printf("pmap: set_segmap ctx=%d v=0x%lx "
2516				       "old=0x%x new=ff (rm)\n",
2517				       pmap->pm_ctxnum, segva,
2518				       pmegp->pmeg_index);
2519			}
2520			pmeg_verify_empty(segva);
2521#endif
2522
2523			/* Remove it from the MMU. */
2524			set_segmap_allctx(segva, SEGINV);
2525			pmap->pm_segmap[VA_SEGNUM(segva)] = SEGINV;
2526
2527			/* Now, put it on the free list. */
2528			pmeg_free(pmegp);
2529		}
2530	}
2531	splx(s);
2532}
2533
2534
2535/*
2536 * The trap handler calls this so we can try to resolve
2537 * user-level faults by reloading a PMEG.
2538 * If that does not prodce a valid mapping,
2539 * call vm_fault as usual.
2540 *
2541 * XXX: Merge this with the next function?
2542 */
2543int
2544_pmap_fault(struct vm_map *map, vaddr_t va, vm_prot_t ftype)
2545{
2546	pmap_t pmap;
2547	int rv;
2548
2549	pmap = vm_map_pmap(map);
2550	if (map == kernel_map) {
2551		/* Do not allow faults below the "managed" space. */
2552		if (va < virtual_avail) {
2553			/*
2554			 * Most pages below virtual_avail are read-only,
2555			 * so I will assume it is a protection failure.
2556			 */
2557			return EACCES;
2558		}
2559	} else {
2560		/* User map.  Try reload shortcut. */
2561		if (pmap_fault_reload(pmap, va, ftype))
2562			return 0;
2563	}
2564	rv = uvm_fault(map, va, ftype);
2565
2566#ifdef	PMAP_DEBUG
2567	if (pmap_debug & PMD_FAULT) {
2568		printf("pmap_fault(%p, 0x%lx, 0x%x) -> 0x%x\n",
2569		       map, va, ftype, rv);
2570	}
2571#endif
2572
2573	return (rv);
2574}
2575
2576/*
2577 * This is a shortcut used by the trap handler to
2578 * reload PMEGs into a user segmap without calling
2579 * the actual VM fault handler.  Returns true if:
2580 *	the PMEG was reloaded, and
2581 *	it has a valid PTE at va.
2582 * Otherwise return zero and let VM code handle it.
2583 */
2584int
2585pmap_fault_reload(pmap_t pmap, vaddr_t pgva, vm_prot_t ftype)
2586{
2587	int rv, s, pte, chkpte, sme;
2588	vaddr_t segva;
2589	pmeg_t pmegp;
2590
2591	if (pgva >= VM_MAXUSER_ADDRESS)
2592		return (0);
2593	if (pmap->pm_segmap == NULL) {
2594#ifdef	PMAP_DEBUG
2595		db_printf("pmap_fault_reload: null segmap\n");
2596		Debugger();
2597#endif
2598		return (0);
2599	}
2600
2601	/* Short-cut using the S/W segmap. */
2602	if (pmap->pm_segmap[VA_SEGNUM(pgva)] == SEGINV)
2603		return (0);
2604
2605	segva = sun3_trunc_seg(pgva);
2606	chkpte = PG_VALID;
2607	if (ftype & VM_PROT_WRITE)
2608		chkpte |= PG_WRITE;
2609	rv = 0;
2610
2611	s = splvm();
2612
2613	/*
2614	 * Given that we faulted on a user-space address, we will
2615	 * probably need a context.  Get a context now so we can
2616	 * try to resolve the fault with a segmap reload.
2617	 */
2618	if (!has_context(pmap)) {
2619		context_allocate(pmap);
2620#ifdef PMAP_DEBUG
2621		if (pmap_debug & PMD_CONTEXT)
2622			printf("pmap_fault(%p) got context %d\n",
2623			       pmap, pmap->pm_ctxnum);
2624#endif
2625		set_context(pmap->pm_ctxnum);
2626	} else {
2627#ifdef	PMAP_DEBUG
2628		/* Make sure context is correct. */
2629		if (pmap->pm_ctxnum != get_context()) {
2630			db_printf("pmap_fault_reload: wrong context\n");
2631			Debugger();
2632			/* XXX: OK to proceed? */
2633			set_context(pmap->pm_ctxnum);
2634		}
2635#endif
2636	}
2637
2638	sme = get_segmap(segva);
2639	if (sme == SEGINV) {
2640		/* See if there is something to reload. */
2641		pmegp = pmeg_cache(pmap, segva);
2642		if (pmegp) {
2643			/* Found one!  OK, reload it. */
2644			pmap_stats.ps_pmeg_faultin++;
2645			sme = pmegp->pmeg_index;
2646			set_segmap(segva, sme);
2647			pte = get_pte(pgva);
2648			if (pte & chkpte)
2649				rv = 1;
2650		}
2651	}
2652
2653	splx(s);
2654	return (rv);
2655}
2656
2657
2658/*
2659 * Clear the modify bit for the given physical page.
2660 */
2661bool
2662pmap_clear_modify(struct vm_page *pg)
2663{
2664	paddr_t pa = VM_PAGE_TO_PHYS(pg);
2665	pv_entry_t *head;
2666	u_char *pv_flags;
2667	int s;
2668	bool rv;
2669
2670	pv_flags = pa_to_pvflags(pa);
2671	head     = pa_to_pvhead(pa);
2672
2673	s = splvm();
2674	*pv_flags |= pv_syncflags(*head);
2675	rv = *pv_flags & PV_MOD;
2676	*pv_flags &= ~PV_MOD;
2677	splx(s);
2678	return rv;
2679}
2680
2681/*
2682 * Tell whether the given physical page has been modified.
2683 */
2684bool
2685pmap_is_modified(struct vm_page *pg)
2686{
2687	paddr_t pa = VM_PAGE_TO_PHYS(pg);
2688	pv_entry_t *head;
2689	u_char *pv_flags;
2690	int s;
2691	bool rv;
2692
2693	pv_flags = pa_to_pvflags(pa);
2694	head     = pa_to_pvhead(pa);
2695
2696	s = splvm();
2697	if ((*pv_flags & PV_MOD) == 0)
2698		*pv_flags |= pv_syncflags(*head);
2699	rv = (*pv_flags & PV_MOD);
2700	splx(s);
2701	return (rv);
2702}
2703
2704/*
2705 * Clear the reference bit for the given physical page.
2706 * It's OK to just remove mappings if that's easier.
2707 */
2708bool
2709pmap_clear_reference(struct vm_page *pg)
2710{
2711	paddr_t pa = VM_PAGE_TO_PHYS(pg);
2712	pv_entry_t *head;
2713	u_char *pv_flags;
2714	int s;
2715	bool rv;
2716
2717	pv_flags = pa_to_pvflags(pa);
2718	head     = pa_to_pvhead(pa);
2719
2720	s = splvm();
2721	*pv_flags |= pv_syncflags(*head);
2722	rv = *pv_flags & PV_REF;
2723	*pv_flags &= ~PV_REF;
2724	splx(s);
2725	return rv;
2726}
2727
2728/*
2729 * Tell whether the given physical page has been referenced.
2730 * It's OK to just return false if page is not mapped.
2731 */
2732bool
2733pmap_is_referenced(struct vm_page *pg)
2734{
2735	paddr_t pa = VM_PAGE_TO_PHYS(pg);
2736	pv_entry_t *head;
2737	u_char *pv_flags;
2738	int s;
2739	bool rv;
2740
2741	pv_flags = pa_to_pvflags(pa);
2742	head     = pa_to_pvhead(pa);
2743
2744	s = splvm();
2745	if ((*pv_flags & PV_REF) == 0)
2746		*pv_flags |= pv_syncflags(*head);
2747	rv = (*pv_flags & PV_REF);
2748	splx(s);
2749	return (rv);
2750}
2751
2752
2753/*
2754 * This is called by locore.s:cpu_switch() when it is
2755 * switching to a new process.  Load new translations.
2756 * Note: done in-line by locore.s unless PMAP_DEBUG
2757 *
2758 * Note that we do NOT allocate a context here, but
2759 * share the "kernel only" context until we really
2760 * need our own context for user-space mappings in
2761 * pmap_enter_user().
2762 */
2763void
2764_pmap_switch(pmap_t pmap)
2765{
2766	set_context(pmap->pm_ctxnum);
2767	ICIA();
2768}
2769
2770/*
2771 * Exported version of pmap_activate().  This is called from the
2772 * machine-independent VM code when a process is given a new pmap.
2773 * If (p == curlwp) do like cpu_switch would do; otherwise just
2774 * take this as notification that the process has a new pmap.
2775 */
2776void
2777pmap_activate(struct lwp *l)
2778{
2779	pmap_t pmap = l->l_proc->p_vmspace->vm_map.pmap;
2780
2781	if (l->l_proc == curproc) {
2782		_pmap_switch(pmap);
2783	}
2784}
2785
2786/*
2787 * Deactivate the address space of the specified process.
2788 */
2789void
2790pmap_deactivate(struct lwp *l)
2791{
2792	/* Nothing to do. */
2793}
2794
2795/*
2796 *	Routine:	pmap_unwire
2797 *	Function:	Clear the wired attribute for a map/virtual-address
2798 *			pair.
2799 *	In/out conditions:
2800 *			The mapping must already exist in the pmap.
2801 */
2802void
2803pmap_unwire(pmap_t pmap, vaddr_t va)
2804{
2805	int s, sme;
2806	int wiremask, ptenum;
2807	pmeg_t pmegp;
2808
2809#ifdef PMAP_DEBUG
2810	if (pmap_debug & PMD_WIRING)
2811		printf("pmap_unwire(pmap=%p, va=0x%lx)\n",
2812		       pmap, va);
2813#endif
2814	/*
2815	 * We are asked to unwire pages that were wired when
2816	 * pmap_enter() was called and we ignored wiring.
2817	 * (VM code appears to wire a stack page during fork.)
2818	 */
2819	if (pmap != kernel_pmap) {
2820#ifdef PMAP_DEBUG
2821		if (pmap_debug & PMD_WIRING) {
2822			db_printf("  (user pmap -- ignored)\n");
2823			Debugger();
2824		}
2825#endif
2826		return;
2827	}
2828
2829	ptenum = VA_PTE_NUM(va);
2830	wiremask = 1 << ptenum;
2831
2832	s = splvm();
2833	sme = get_segmap(va);
2834	pmegp = pmeg_p(sme);
2835	pmegp->pmeg_wired &= ~wiremask;
2836	splx(s);
2837}
2838
2839/*
2840 *	Copy the range specified by src_addr/len
2841 *	from the source map to the range dst_addr/len
2842 *	in the destination map.
2843 *
2844 *	This routine is only advisory and need not do anything.
2845 */
2846void
2847pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vaddr_t dst_addr, vsize_t len,
2848	  vaddr_t src_addr)
2849{
2850}
2851
2852/*
2853 *	Routine:	pmap_extract
2854 *	Function:
2855 *		Extract the physical page address associated
2856 *		with the given map/virtual_address pair.
2857 *	Returns zero if VA not valid.
2858 */
2859bool
2860pmap_extract(pmap_t pmap, vaddr_t va, paddr_t *pap)
2861{
2862	int s, sme, segnum, ptenum, pte;
2863	paddr_t pa;
2864
2865	pte = 0;
2866	s = splvm();
2867	if (pmap == kernel_pmap) {
2868		sme = get_segmap(va);
2869		if (sme != SEGINV)
2870			pte = get_pte(va);
2871	} else {
2872		/* This is rare, so do it the easy way. */
2873		segnum = VA_SEGNUM(va);
2874		sme = pmap->pm_segmap[segnum];
2875		if (sme != SEGINV) {
2876			ptenum = VA_PTE_NUM(va);
2877			pte = get_pte_pmeg(sme, ptenum);
2878		}
2879	}
2880	splx(s);
2881
2882	if ((pte & PG_VALID) == 0) {
2883#ifdef PMAP_DEBUG
2884		db_printf("pmap_extract: invalid va=0x%lx\n", va);
2885		Debugger();
2886#endif
2887		return (false);
2888	}
2889	pa = PG_PA(pte);
2890#ifdef	DIAGNOSTIC
2891	if (pte & PG_TYPE) {
2892		panic("pmap_extract: not main mem, va=0x%lx", va);
2893	}
2894#endif
2895	if (pap != NULL)
2896		*pap = pa;
2897	return (true);
2898}
2899
2900
2901/*
2902 *	  pmap_page_protect:
2903 *
2904 *	  Lower the permission for all mappings to a given page.
2905 */
2906void
2907pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
2908{
2909	paddr_t pa = VM_PAGE_TO_PHYS(pg);
2910	int s;
2911
2912	s = splvm();
2913#ifdef PMAP_DEBUG
2914	if (pmap_debug & PMD_PROTECT)
2915		printf("pmap_page_protect(0x%lx, 0x%x)\n", pa, prot);
2916#endif
2917	switch (prot) {
2918	case VM_PROT_ALL:
2919		break;
2920	case VM_PROT_READ:
2921	case VM_PROT_READ|VM_PROT_EXECUTE:
2922		pv_changepte(pa, 0, PG_WRITE);
2923		break;
2924	default:
2925		/* remove mapping for all pmaps that have it */
2926		pv_remove_all(pa);
2927		break;
2928	}
2929	splx(s);
2930}
2931
2932/*
2933 * Initialize a preallocated and zeroed pmap structure,
2934 * such as one in a vmspace structure.
2935 */
2936void
2937pmap_pinit(pmap_t pmap)
2938{
2939	pmap_common_init(pmap);
2940	pmap_user_init(pmap);
2941}
2942
2943/*
2944 *	Reduce the permissions on the specified
2945 *	range of this map as requested.
2946 *	(Make pages read-only.)
2947 */
2948void
2949pmap_protect(pmap_t pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
2950{
2951	vaddr_t va, neva;
2952	int segnum;
2953
2954	/* If leaving writable, nothing to do. */
2955	if (prot & VM_PROT_WRITE)
2956		return;
2957
2958	/* If removing all permissions, just unmap. */
2959	if ((prot & VM_PROT_READ) == 0) {
2960		pmap_remove(pmap, sva, eva);
2961		return;
2962	}
2963
2964#ifdef	PMAP_DEBUG
2965	if ((pmap_debug & PMD_PROTECT) ||
2966	    ((sva <= pmap_db_watchva && eva > pmap_db_watchva)))
2967		printf("pmap_protect(%p, 0x%lx, 0x%lx)\n", pmap, sva, eva);
2968#endif
2969
2970	KASSERT((pmap == kernel_pmap) ?
2971		sva >= virtual_avail && eva < DVMA_MAP_END :
2972		eva <= VM_MAXUSER_ADDRESS);
2973	va = sva;
2974	segnum = VA_SEGNUM(va);
2975	while (va < eva) {
2976		neva = sun3_trunc_seg(va) + NBSG;
2977		if (neva > eva)
2978			neva = eva;
2979		if (pmap->pm_segmap[segnum] != SEGINV)
2980			pmap_protect1(pmap, va, neva);
2981		va = neva;
2982		segnum++;
2983	}
2984}
2985
2986/*
2987 * Remove write permissions in given range.
2988 * (guaranteed to be within one segment)
2989 * similar to pmap_remove1()
2990 */
2991void
2992pmap_protect1(pmap_t pmap, vaddr_t sva, vaddr_t eva)
2993{
2994	int old_ctx, s, sme;
2995	bool in_ctx;
2996
2997	s = splvm();
2998
2999#ifdef	DIAGNOSTIC
3000	if (sun3_trunc_seg(sva) != sun3_trunc_seg(eva-1))
3001		panic("pmap_protect1: bad range!");
3002#endif
3003
3004	if (pmap == kernel_pmap) {
3005		sme = get_segmap(sva);
3006		if (sme != SEGINV)
3007			pmap_protect_mmu(pmap, sva, eva);
3008		goto out;
3009	}
3010	/* It is a user pmap. */
3011
3012	/* There is a PMEG, but maybe not active. */
3013	old_ctx = INVALID_CONTEXT;
3014	in_ctx = false;
3015	if (has_context(pmap)) {
3016		/* Temporary context change. */
3017		old_ctx = get_context();
3018		set_context(pmap->pm_ctxnum);
3019		sme = get_segmap(sva);
3020		if (sme != SEGINV)
3021			in_ctx = true;
3022	}
3023
3024	if (in_ctx == true)
3025		pmap_protect_mmu(pmap, sva, eva);
3026	else
3027		pmap_protect_noctx(pmap, sva, eva);
3028
3029	if (old_ctx != INVALID_CONTEXT) {
3030		/* Restore previous context. */
3031		set_context(old_ctx);
3032	}
3033
3034out:
3035	splx(s);
3036}
3037
3038/*
3039 * Remove write permissions, all in one PMEG,
3040 * where that PMEG is currently in the MMU.
3041 * The current context is already correct.
3042 */
3043void
3044pmap_protect_mmu(pmap_t pmap, vaddr_t sva, vaddr_t eva)
3045{
3046	vaddr_t pgva;
3047	int pte;
3048	int flush_by_page = 0;
3049#if defined(HAVECACHE) || defined(DIAGNOSTIC)
3050	vaddr_t segva = sun3_trunc_seg(sva);
3051#endif
3052
3053	CHECK_SPL();
3054
3055#ifdef	DIAGNOSTIC
3056	if (pmap != kernel_pmap) {
3057		if (pmap->pm_ctxnum != get_context())
3058			panic("pmap_protect_mmu: wrong context");
3059	}
3060
3061	int sme = get_segmap(segva);
3062	/* Make sure it is valid and known. */
3063	if (sme == SEGINV)
3064		panic("pmap_protect_mmu: SEGINV");
3065	if (pmap->pm_segmap && (pmap->pm_segmap[VA_SEGNUM(segva)] != sme))
3066		panic("pmap_protect_mmu: incorrect sme, va=0x%lx", segva);
3067
3068	/* have pmeg, will travel */
3069	pmeg_t pmegp = pmeg_p(sme);
3070	/* Make sure we own the pmeg, right va, etc. */
3071	if ((pmegp->pmeg_va != segva) ||
3072	    (pmegp->pmeg_owner != pmap) ||
3073	    (pmegp->pmeg_version != pmap->pm_version))
3074	{
3075		panic("pmap_protect_mmu: bad pmeg=%p", pmegp);
3076	}
3077	if (pmegp->pmeg_vpages < 0)
3078		panic("pmap_protect_mmu: npages corrupted");
3079	if (pmegp->pmeg_vpages == 0)
3080		panic("pmap_protect_mmu: no valid pages?");
3081#endif /* DIAGNOSTIC */
3082
3083#ifdef	HAVECACHE
3084	if (cache_size) {
3085		/*
3086		 * If the range to be removed is larger than the cache,
3087		 * it will be cheaper to flush this segment entirely.
3088		 */
3089		if (cache_size < (eva - sva)) {
3090			/* cheaper to flush whole segment */
3091			cache_flush_segment(segva);
3092		} else {
3093			flush_by_page = 1;
3094		}
3095	}
3096#endif
3097
3098	/* Remove write permission in the given range. */
3099	for (pgva = sva; pgva < eva; pgva += PAGE_SIZE) {
3100		pte = get_pte(pgva);
3101		if (pte & PG_VALID) {
3102			if (flush_by_page) {
3103#ifdef	HAVECACHE
3104				cache_flush_page(pgva);
3105				/* Get fresh mod/ref bits from write-back. */
3106				pte = get_pte(pgva);
3107#endif
3108			}
3109			if (IS_MAIN_MEM(pte)) {
3110				save_modref_bits(pte);
3111			}
3112			pte &= ~(PG_WRITE | PG_MODREF);
3113			set_pte(pgva, pte);
3114		}
3115	}
3116}
3117
3118/*
3119 * Remove write permissions, all in one PMEG,
3120 * where it is not currently in any context.
3121 */
3122void
3123pmap_protect_noctx(pmap_t pmap, vaddr_t sva, vaddr_t eva)
3124{
3125	int old_ctx, pte, sme, segnum;
3126	vaddr_t pgva, segva;
3127
3128#ifdef	DIAGNOSTIC
3129	/* Kernel always in a context (actually, in all contexts). */
3130	if (pmap == kernel_pmap)
3131		panic("pmap_protect_noctx: kernel_pmap");
3132	if (pmap->pm_segmap == NULL)
3133		panic("pmap_protect_noctx: null segmap");
3134#endif
3135
3136	segva = sun3_trunc_seg(sva);
3137	segnum = VA_SEGNUM(segva);
3138	sme = pmap->pm_segmap[segnum];
3139	if (sme == SEGINV)
3140		return;
3141
3142	/*
3143	 * Borrow the EMPTY_CONTEXT so we can access the PMEG
3144	 * at its normal virtual address.
3145	 */
3146	old_ctx = get_context();
3147	set_context(EMPTY_CONTEXT);
3148	set_segmap(segva, sme);
3149
3150	/* Remove write permission in the given range. */
3151	for (pgva = sva; pgva < eva; pgva += PAGE_SIZE) {
3152		pte = get_pte(pgva);
3153		if (pte & PG_VALID) {
3154			/* No cache flush needed. */
3155			if (IS_MAIN_MEM(pte)) {
3156				save_modref_bits(pte);
3157			}
3158			pte &= ~(PG_WRITE | PG_MODREF);
3159			set_pte(pgva, pte);
3160		}
3161	}
3162
3163	/*
3164	 * Make the EMPTY_CONTEXT really empty again, and
3165	 * restore the previous context.
3166	 */
3167	set_segmap(segva, SEGINV);
3168	set_context(old_ctx);
3169}
3170
3171
3172/*
3173 *	Remove the given range of addresses from the specified map.
3174 *
3175 *	It is assumed that the start and end are properly
3176 *	rounded to the page size.
3177 */
3178void
3179pmap_remove(pmap_t pmap, vaddr_t sva, vaddr_t eva)
3180{
3181	vaddr_t va, neva;
3182	int segnum;
3183
3184#ifdef	PMAP_DEBUG
3185	if ((pmap_debug & PMD_REMOVE) ||
3186	    ((sva <= pmap_db_watchva && eva > pmap_db_watchva)))
3187		printf("pmap_remove(%p, 0x%lx, 0x%lx)\n", pmap, sva, eva);
3188#endif
3189
3190
3191	KASSERT((pmap == kernel_pmap) ?
3192		sva >= virtual_avail && eva < DVMA_MAP_END :
3193		eva <= VM_MAXUSER_ADDRESS);
3194	va = sva;
3195	segnum = VA_SEGNUM(va);
3196	while (va < eva) {
3197		neva = sun3_trunc_seg(va) + NBSG;
3198		if (neva > eva)
3199			neva = eva;
3200		if (pmap->pm_segmap[segnum] != SEGINV)
3201			pmap_remove1(pmap, va, neva);
3202		va = neva;
3203		segnum++;
3204	}
3205}
3206
3207/*
3208 * Remove user mappings, all within one segment
3209 */
3210void
3211pmap_remove1(pmap_t pmap, vaddr_t sva, vaddr_t eva)
3212{
3213	int old_ctx, s, sme;
3214	bool in_ctx;
3215
3216	s = splvm();
3217
3218#ifdef	DIAGNOSTIC
3219	if (sun3_trunc_seg(sva) != sun3_trunc_seg(eva-1))
3220		panic("pmap_remove1: bad range!");
3221#endif
3222
3223	if (pmap == kernel_pmap) {
3224		sme = get_segmap(sva);
3225		if (sme != SEGINV)
3226			pmap_remove_mmu(pmap, sva, eva);
3227		goto out;
3228	}
3229	/* It is a user pmap. */
3230
3231	/* There is a PMEG, but maybe not active. */
3232	old_ctx = INVALID_CONTEXT;
3233	in_ctx = false;
3234	if (has_context(pmap)) {
3235		/* Temporary context change. */
3236		old_ctx = get_context();
3237		set_context(pmap->pm_ctxnum);
3238		sme = get_segmap(sva);
3239		if (sme != SEGINV)
3240			in_ctx = true;
3241	}
3242
3243	if (in_ctx == true)
3244		pmap_remove_mmu(pmap, sva, eva);
3245	else
3246		pmap_remove_noctx(pmap, sva, eva);
3247
3248	if (old_ctx != INVALID_CONTEXT) {
3249		/* Restore previous context. */
3250		set_context(old_ctx);
3251	}
3252
3253out:
3254	splx(s);
3255}
3256
3257/*
3258 * Remove some mappings, all in one PMEG,
3259 * where that PMEG is currently in the MMU.
3260 * The current context is already correct.
3261 * If no PTEs remain valid in the PMEG, free it.
3262 */
3263void
3264pmap_remove_mmu(pmap_t pmap, vaddr_t sva, vaddr_t eva)
3265{
3266	pmeg_t pmegp;
3267	vaddr_t pgva, segva;
3268	int pte, sme;
3269	int flush_by_page = 0;
3270
3271	CHECK_SPL();
3272
3273#ifdef	DIAGNOSTIC
3274	if (pmap != kernel_pmap) {
3275		if (pmap->pm_ctxnum != get_context())
3276			panic("pmap_remove_mmu: wrong context");
3277	}
3278#endif
3279
3280	segva = sun3_trunc_seg(sva);
3281	sme = get_segmap(segva);
3282
3283#ifdef	DIAGNOSTIC
3284	/* Make sure it is valid and known. */
3285	if (sme == SEGINV)
3286		panic("pmap_remove_mmu: SEGINV");
3287	if (pmap->pm_segmap && (pmap->pm_segmap[VA_SEGNUM(segva)] != sme))
3288		panic("pmap_remove_mmu: incorrect sme, va=0x%lx", segva);
3289#endif
3290
3291	pmegp = pmeg_p(sme);
3292	/* have pmeg, will travel */
3293
3294#ifdef	DIAGNOSTIC
3295	/* Make sure we own the pmeg, right va, etc. */
3296	if ((pmegp->pmeg_va != segva) ||
3297	    (pmegp->pmeg_owner != pmap) ||
3298	    (pmegp->pmeg_version != pmap->pm_version))
3299	{
3300		panic("pmap_remove_mmu: bad pmeg=%p", pmegp);
3301	}
3302	if (pmegp->pmeg_vpages < 0)
3303		panic("pmap_remove_mmu: npages corrupted");
3304	if (pmegp->pmeg_vpages == 0)
3305		panic("pmap_remove_mmu: no valid pages?");
3306#endif
3307
3308#ifdef	HAVECACHE
3309	if (cache_size) {
3310		/*
3311		 * If the range to be removed is larger than the cache,
3312		 * it will be cheaper to flush this segment entirely.
3313		 */
3314		if (cache_size < (eva - sva)) {
3315			/* cheaper to flush whole segment */
3316			cache_flush_segment(segva);
3317		} else {
3318			flush_by_page = 1;
3319		}
3320	}
3321#endif
3322
3323	/* Invalidate the PTEs in the given range. */
3324	for (pgva = sva; pgva < eva; pgva += PAGE_SIZE) {
3325		pte = get_pte(pgva);
3326		if (pte & PG_VALID) {
3327			if (flush_by_page) {
3328#ifdef	HAVECACHE
3329				cache_flush_page(pgva);
3330				/* Get fresh mod/ref bits from write-back. */
3331				pte = get_pte(pgva);
3332#endif
3333			}
3334			if (IS_MAIN_MEM(pte)) {
3335				save_modref_bits(pte);
3336				pv_unlink(pmap, pte, pgva);
3337			}
3338#ifdef	PMAP_DEBUG
3339			if ((pmap_debug & PMD_SETPTE) ||
3340			    (pgva == pmap_db_watchva)) {
3341				printf("pmap: set_pte pmap=%p va=0x%lx"
3342				       " old=0x%x new=0x%x (rrmmu)\n",
3343				       pmap, pgva, pte, PG_INVAL);
3344			}
3345#endif
3346			set_pte(pgva, PG_INVAL);
3347			KASSERT(pmegp->pmeg_vpages > 0);
3348			pmegp->pmeg_vpages--;
3349		}
3350	}
3351
3352	KASSERT(pmegp->pmeg_vpages >= 0);
3353	if (pmegp->pmeg_vpages == 0) {
3354		/* We are done with this pmeg. */
3355#ifdef	PMAP_DEBUG
3356		if (is_pmeg_wired(pmegp)) {
3357			if (pmap_debug & PMD_WIRING) {
3358				db_printf("pmap: removing wired pmeg: %p\n",
3359					  pmegp);
3360				Debugger();
3361			}
3362		}
3363
3364		if (pmap_debug & PMD_SEGMAP) {
3365			printf("pmap: set_segmap ctx=%d v=0x%lx old=0x%x "
3366			       "new=ff (rm)\n",
3367			       pmap->pm_ctxnum, segva, pmegp->pmeg_index);
3368		}
3369		pmeg_verify_empty(segva);
3370#endif /* PMAP_DEBUG */
3371
3372		/* Remove it from the MMU. */
3373		if (kernel_pmap == pmap) {
3374			/* Did cache flush above. */
3375			set_segmap_allctx(segva, SEGINV);
3376		} else {
3377			/* Did cache flush above. */
3378			set_segmap(segva, SEGINV);
3379		}
3380		pmap->pm_segmap[VA_SEGNUM(segva)] = SEGINV;
3381		/* Now, put it on the free list. */
3382		pmeg_free(pmegp);
3383	}
3384}
3385
3386/*
3387 * Remove some mappings, all in one PMEG,
3388 * where it is not currently in any context.
3389 */
3390void
3391pmap_remove_noctx(pmap_t pmap, vaddr_t sva, vaddr_t eva)
3392{
3393	pmeg_t pmegp;
3394	int old_ctx, pte, sme, segnum;
3395	vaddr_t pgva, segva;
3396
3397	CHECK_SPL();
3398
3399#ifdef	DIAGNOSTIC
3400	/* Kernel always in a context (actually, in all contexts). */
3401	if (pmap == kernel_pmap)
3402		panic("pmap_remove_noctx: kernel_pmap");
3403	if (pmap->pm_segmap == NULL)
3404		panic("pmap_remove_noctx: null segmap");
3405#endif
3406
3407	segva = sun3_trunc_seg(sva);
3408	segnum = VA_SEGNUM(segva);
3409	sme = pmap->pm_segmap[segnum];
3410	if (sme == SEGINV)
3411		return;
3412	pmegp = pmeg_p(sme);
3413
3414	/*
3415	 * Borrow the EMPTY_CONTEXT so we can access the PMEG
3416	 * at its normal virtual address.
3417	 */
3418	old_ctx = get_context();
3419	set_context(EMPTY_CONTEXT);
3420	set_segmap(segva, sme);
3421
3422	/* Invalidate the PTEs in the given range. */
3423	for (pgva = sva; pgva < eva; pgva += PAGE_SIZE) {
3424		pte = get_pte(pgva);
3425		if (pte & PG_VALID) {
3426			/* No cache flush needed. */
3427			if (IS_MAIN_MEM(pte)) {
3428				save_modref_bits(pte);
3429				pv_unlink(pmap, pte, pgva);
3430			}
3431#ifdef	PMAP_DEBUG
3432			if ((pmap_debug & PMD_SETPTE) ||
3433			    (pgva == pmap_db_watchva)) {
3434				printf("pmap: set_pte pmap=%p va=0x%lx"
3435				       " old=0x%x new=0x%x (rrncx)\n",
3436				       pmap, pgva, pte, PG_INVAL);
3437			}
3438#endif
3439			set_pte(pgva, PG_INVAL);
3440			KASSERT(pmegp->pmeg_vpages > 0);
3441			pmegp->pmeg_vpages--;
3442		}
3443	}
3444
3445	/*
3446	 * Make the EMPTY_CONTEXT really empty again, and
3447	 * restore the previous context.
3448	 */
3449	set_segmap(segva, SEGINV);
3450	set_context(old_ctx);
3451
3452	KASSERT(pmegp->pmeg_vpages >= 0);
3453	if (pmegp->pmeg_vpages == 0) {
3454		/* We are done with this pmeg. */
3455		if (is_pmeg_wired(pmegp)) {
3456#ifdef	PMAP_DEBUG
3457			if (pmap_debug & PMD_WIRING) {
3458				db_printf("pmap: removing wired pmeg: %p\n",
3459					  pmegp);
3460				Debugger();
3461			}
3462#endif	/* PMAP_DEBUG */
3463		}
3464
3465		pmap->pm_segmap[segnum] = SEGINV;
3466		pmeg_free(pmegp);
3467	}
3468}
3469
3470
3471/*
3472 * Count resident pages in this pmap.
3473 * See: kern_sysctl.c:pmap_resident_count
3474 */
3475segsz_t
3476pmap_resident_pages(pmap_t pmap)
3477{
3478	int i, sme, pages;
3479	pmeg_t pmeg;
3480
3481	if (pmap->pm_segmap == 0)
3482		return (0);
3483
3484	pages = 0;
3485	for (i = 0; i < NUSEG; i++) {
3486		sme = pmap->pm_segmap[i];
3487		if (sme != SEGINV) {
3488			pmeg = pmeg_p(sme);
3489			pages += pmeg->pmeg_vpages;
3490		}
3491	}
3492	return (pages);
3493}
3494
3495/*
3496 * Count wired pages in this pmap.
3497 * See vm_mmap.c:pmap_wired_count
3498 */
3499segsz_t
3500pmap_wired_pages(pmap_t pmap)
3501{
3502	int i, mask, sme, pages;
3503	pmeg_t pmeg;
3504
3505	if (pmap->pm_segmap == 0)
3506		return (0);
3507
3508	pages = 0;
3509	for (i = 0; i < NUSEG; i++) {
3510		sme = pmap->pm_segmap[i];
3511		if (sme != SEGINV) {
3512			pmeg = pmeg_p(sme);
3513			mask = 0x8000;
3514			do {
3515				if (pmeg->pmeg_wired & mask)
3516					pages++;
3517				mask = (mask >> 1);
3518			} while (mask);
3519		}
3520	}
3521	return (pages);
3522}
3523
3524
3525/*
3526 *	pmap_copy_page copies the specified (machine independent)
3527 *	page by mapping the page into virtual memory and using
3528 *	bcopy to copy the page, one machine dependent page at a
3529 *	time.
3530 */
3531void
3532pmap_copy_page(paddr_t src, paddr_t dst)
3533{
3534	int pte;
3535	int s;
3536
3537	s = splvm();
3538
3539#ifdef	PMAP_DEBUG
3540	if (pmap_debug & PMD_COW)
3541		printf("pmap_copy_page: 0x%lx -> 0x%lx\n", src, dst);
3542#endif
3543
3544#ifdef DIAGNOSTIC
3545	if (tmp_vpages_inuse)
3546		panic("pmap_copy_page: vpages inuse");
3547	tmp_vpages_inuse++;
3548#endif
3549
3550	/* PG_PERM is short for (PG_VALID|PG_WRITE|PG_SYSTEM|PG_NC) */
3551	/* All mappings to vmp_vpages are non-cached, so no flush. */
3552	pte = PG_PERM | PA_PGNUM(src);
3553	set_pte(tmp_vpages[0], pte);
3554	pte = PG_PERM | PA_PGNUM(dst);
3555	set_pte(tmp_vpages[1], pte);
3556	copypage((char *) tmp_vpages[0], (char *) tmp_vpages[1]);
3557	set_pte(tmp_vpages[0], PG_INVAL);
3558	set_pte(tmp_vpages[0], PG_INVAL);
3559
3560#ifdef DIAGNOSTIC
3561	tmp_vpages_inuse--;
3562#endif
3563
3564	splx(s);
3565}
3566
3567/*
3568 *	pmap_zero_page zeros the specified (machine independent)
3569 *	page by mapping the page into virtual memory and using
3570 *	bzero to clear its contents, one machine dependent page
3571 *	at a time.
3572 */
3573void
3574pmap_zero_page(paddr_t pa)
3575{
3576	int pte;
3577	int s;
3578
3579	s = splvm();
3580
3581#ifdef	PMAP_DEBUG
3582	if (pmap_debug & PMD_COW)
3583		printf("pmap_zero_page: 0x%lx\n", pa);
3584#endif
3585
3586#ifdef DIAGNOSTIC
3587	if (tmp_vpages_inuse)
3588		panic("pmap_zero_page: vpages inuse");
3589	tmp_vpages_inuse++;
3590#endif
3591
3592	/* PG_PERM is short for (PG_VALID|PG_WRITE|PG_SYSTEM|PG_NC) */
3593	/* All mappings to vmp_vpages are non-cached, so no flush. */
3594	pte = PG_PERM | PA_PGNUM(pa);
3595	set_pte(tmp_vpages[0], pte);
3596	zeropage((char *) tmp_vpages[0]);
3597	set_pte(tmp_vpages[0], PG_INVAL);
3598
3599#ifdef DIAGNOSTIC
3600	tmp_vpages_inuse--;
3601#endif
3602
3603	splx(s);
3604}
3605
3606/*
3607 * Find first virtual address >= *va that is
3608 * least likely to cause cache aliases.
3609 * (This will just seg-align mappings.)
3610 */
3611void
3612pmap_prefer(vaddr_t fo, vaddr_t *va, int td)
3613{
3614	long d;
3615
3616	d = fo - *va;
3617	d &= SEGOFSET;
3618	if (d == 0) {
3619		return;
3620	}
3621	if (td) {
3622		*va -= SEGOFSET + 1;
3623	}
3624	*va += d;
3625}
3626
3627/*
3628 * Fill in the sun3x-specific part of the kernel core header
3629 * for dumpsys().  (See machdep.c for the rest.)
3630 */
3631void
3632pmap_kcore_hdr(struct sun3_kcore_hdr *sh)
3633{
3634	vaddr_t va;
3635	u_char *cp, *ep;
3636
3637	sh->segshift = SEGSHIFT;
3638	sh->pg_frame = PG_FRAME;
3639	sh->pg_valid = PG_VALID;
3640
3641	/* Copy the kernel segmap (256 bytes). */
3642	va = KERNBASE3;
3643	cp = sh->ksegmap;
3644	ep = cp + sizeof(sh->ksegmap);
3645	do {
3646		*cp = get_segmap(va);
3647		va += NBSG;
3648		cp++;
3649	} while (cp < ep);
3650}
3651
3652/*
3653 * Copy the pagemap RAM into the passed buffer (one page)
3654 * starting at OFF in the pagemap RAM.
3655 */
3656void
3657pmap_get_pagemap(int *pt, int off)
3658{
3659	vaddr_t va, va_end;
3660	int sme, sme_end;	/* SegMap Entry numbers */
3661
3662	sme = (off >> 6);	/* PMEG to start on */
3663	sme_end = sme + 128; /* where to stop */
3664	va_end = temp_seg_va + NBSG;
3665
3666	do {
3667		set_segmap(temp_seg_va, sme);
3668		va = temp_seg_va;
3669		do {
3670			*pt++ = get_pte(va);
3671			va += PAGE_SIZE;
3672		} while (va < va_end);
3673		sme++;
3674	} while (sme < sme_end);
3675	set_segmap(temp_seg_va, SEGINV);
3676}
3677
3678
3679/*
3680 * Helper functions for changing unloaded PMEGs
3681 * XXX: These should go away.  (Borrow context zero instead.)
3682 */
3683
3684#ifdef DIAGNOSTIC
3685static int temp_seg_inuse;
3686#endif
3687
3688static int
3689get_pte_pmeg(int pmeg_num, int page_num)
3690{
3691	vaddr_t va;
3692	int pte;
3693
3694	CHECK_SPL();
3695#ifdef DIAGNOSTIC
3696	if (temp_seg_inuse)
3697		panic("get_pte_pmeg: temp_seg_inuse");
3698	temp_seg_inuse++;
3699#endif
3700
3701	va = temp_seg_va;
3702	set_segmap(temp_seg_va, pmeg_num);
3703	va += PAGE_SIZE*page_num;
3704	pte = get_pte(va);
3705	set_segmap(temp_seg_va, SEGINV);
3706
3707#ifdef DIAGNOSTIC
3708	temp_seg_inuse--;
3709#endif
3710	return pte;
3711}
3712
3713static void
3714set_pte_pmeg(int pmeg_num, int page_num, int pte)
3715{
3716	vaddr_t va;
3717
3718	CHECK_SPL();
3719#ifdef DIAGNOSTIC
3720	if (temp_seg_inuse)
3721		panic("set_pte_pmeg: temp_seg_inuse");
3722	temp_seg_inuse++;
3723#endif
3724
3725	/* We never access data in temp_seg_va so no need to flush. */
3726	va = temp_seg_va;
3727	set_segmap(temp_seg_va, pmeg_num);
3728	va += PAGE_SIZE*page_num;
3729	set_pte(va, pte);
3730	set_segmap(temp_seg_va, SEGINV);
3731
3732#ifdef DIAGNOSTIC
3733	temp_seg_inuse--;
3734#endif
3735}
3736
3737/*
3738 *	Routine:        pmap_procwr
3739 *
3740 *	Function:
3741 *		Synchronize caches corresponding to [addr, addr+len) in p.
3742 */
3743void
3744pmap_procwr(struct proc *p, vaddr_t va, size_t len)
3745{
3746	(void)cachectl1(0x80000004, va, len, p);
3747}
3748
3749
3750#ifdef	PMAP_DEBUG
3751/* Things to call from the debugger. */
3752
3753void
3754pmap_print(pmap_t pmap)
3755{
3756	db_printf(" pm_ctxnum=%d\n", pmap->pm_ctxnum);
3757	db_printf(" pm_version=0x%x\n", pmap->pm_version);
3758	db_printf(" pm_segmap=%p\n", pmap->pm_segmap);
3759}
3760
3761void
3762pmeg_print(pmeg_t pmegp)
3763{
3764	db_printf("link_next=%p  link_prev=%p\n",
3765		  TAILQ_NEXT(pmegp, pmeg_link),
3766		  TAILQ_PREV(pmegp, pmeg_tailq, pmeg_link));
3767	db_printf("index=0x%x owner=%p own_vers=0x%x\n",
3768		  pmegp->pmeg_index, pmegp->pmeg_owner, pmegp->pmeg_version);
3769	db_printf("va=0x%lx wired=0x%x reserved=0x%x vpgs=0x%x qstate=0x%x\n",
3770		  pmegp->pmeg_va, pmegp->pmeg_wired,
3771		  pmegp->pmeg_reserved, pmegp->pmeg_vpages,
3772		  pmegp->pmeg_qstate);
3773}
3774
3775void
3776pv_print(paddr_t pa)
3777{
3778	pv_entry_t pv;
3779	int idx;
3780
3781	idx = PA_PGNUM(pa);
3782	if (idx >= physmem) {
3783		db_printf("bad address\n");
3784		return;
3785	}
3786	db_printf("pa=0x%lx, flags=0x%x\n",
3787		  pa, pv_flags_tbl[idx]);
3788
3789	pv = pv_head_tbl[idx];
3790	while (pv) {
3791		db_printf(" pv_entry %p pmap %p va 0x%lx next %p\n",
3792			  pv, pv->pv_pmap, pv->pv_va, pv->pv_next);
3793		pv = pv->pv_next;
3794	}
3795}
3796#endif	/* PMAP_DEBUG */
3797