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