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