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