xref: /netbsd/sys/arch/sparc/sparc/pmap.c (revision bf9ec67e)
1 /*	$NetBSD: pmap.c,v 1.207 2002/04/11 11:08:40 pk Exp $ */
2 
3 /*
4  * Copyright (c) 1996
5  * 	The President and Fellows of Harvard College. All rights reserved.
6  * Copyright (c) 1992, 1993
7  *	The Regents of the University of California.  All rights reserved.
8  *
9  * This software was developed by the Computer Systems Engineering group
10  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
11  * contributed to Berkeley.
12  *
13  * All advertising materials mentioning features or use of this software
14  * must display the following acknowledgement:
15  *	This product includes software developed by Harvard University.
16  *	This product includes software developed by the University of
17  *	California, Lawrence Berkeley Laboratory.
18  *
19  * Redistribution and use in source and binary forms, with or without
20  * modification, are permitted provided that the following conditions
21  * are met:
22  *
23  * 1. Redistributions of source code must retain the above copyright
24  *    notice, this list of conditions and the following disclaimer.
25  * 2. Redistributions in binary form must reproduce the above copyright
26  *    notice, this list of conditions and the following disclaimer in the
27  *    documentation and/or other materials provided with the distribution.
28  * 3. All advertising materials mentioning features or use of this software
29  *    must display the following acknowledgement:
30  *	This product includes software developed by Aaron Brown and
31  *	Harvard University.
32  *      This product includes software developed by the University of
33  *      California, Berkeley and its contributors.
34  * 4. Neither the name of the University nor the names of its contributors
35  *    may be used to endorse or promote products derived from this software
36  *    without specific prior written permission.
37  *
38  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
39  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
40  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
41  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
42  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
43  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
44  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
46  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
47  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
48  * SUCH DAMAGE.
49  *
50  *	@(#)pmap.c	8.4 (Berkeley) 2/5/94
51  *
52  */
53 
54 /*
55  * SPARC physical map management code.
56  * Does not function on multiprocessors (yet).
57  */
58 
59 #include "opt_ddb.h"
60 #include "opt_kgdb.h"
61 #include "opt_multiprocessor.h"
62 #include "opt_sparc_arch.h"
63 
64 #include <sys/param.h>
65 #include <sys/systm.h>
66 #include <sys/device.h>
67 #include <sys/proc.h>
68 #include <sys/queue.h>
69 #include <sys/malloc.h>
70 #include <sys/lock.h>
71 #include <sys/pool.h>
72 #include <sys/exec.h>
73 #include <sys/core.h>
74 #include <sys/kcore.h>
75 #include <sys/kernel.h>
76 
77 #include <uvm/uvm.h>
78 
79 #include <machine/autoconf.h>
80 #include <machine/bsd_openprom.h>
81 #include <machine/oldmon.h>
82 #include <machine/cpu.h>
83 #include <machine/ctlreg.h>
84 #include <machine/kcore.h>
85 
86 #include <sparc/sparc/asm.h>
87 #include <sparc/sparc/cache.h>
88 #include <sparc/sparc/vaddrs.h>
89 #include <sparc/sparc/cpuvar.h>
90 
91 /*
92  * The SPARCstation offers us the following challenges:
93  *
94  *   1. A virtual address cache.  This is, strictly speaking, not
95  *	part of the architecture, but the code below assumes one.
96  *	This is a write-through cache on the 4c and a write-back cache
97  *	on others.
98  *
99  *   2. (4/4c only) An MMU that acts like a cache.  There is not enough
100  *	space in the MMU to map everything all the time.  Instead, we need
101  *	to load MMU with the `working set' of translations for each
102  *	process. The sun4m does not act like a cache; tables are maintained
103  *	in physical memory.
104  *
105  *   3.	Segmented virtual and physical spaces.  The upper 12 bits of
106  *	a virtual address (the virtual segment) index a segment table,
107  *	giving a physical segment.  The physical segment selects a
108  *	`Page Map Entry Group' (PMEG) and the virtual page number---the
109  *	next 5 or 6 bits of the virtual address---select the particular
110  *	`Page Map Entry' for the page.  We call the latter a PTE and
111  *	call each Page Map Entry Group a pmeg (for want of a better name).
112  *	Note that the sun4m has an unsegmented 36-bit physical space.
113  *
114  *	Since there are no valid bits in the segment table, the only way
115  *	to have an invalid segment is to make one full pmeg of invalid PTEs.
116  *	We use the last one (since the ROM does as well) (sun4/4c only)
117  *
118  *   4. Discontiguous physical pages.  The Mach VM expects physical pages
119  *	to be in one sequential lump.
120  *
121  *   5. The MMU is always on: it is not possible to disable it.  This is
122  *	mainly a startup hassle.
123  */
124 
125 struct pmap_stats {
126 	int	ps_unlink_pvfirst;	/* # of pv_unlinks on head */
127 	int	ps_unlink_pvsearch;	/* # of pv_unlink searches */
128 	int	ps_changeprots;		/* # of calls to changeprot */
129 	int	ps_useless_changeprots;	/* # of changeprots for wiring */
130 	int	ps_enter_firstpv;	/* pv heads entered */
131 	int	ps_enter_secondpv;	/* pv nonheads entered */
132 	int	ps_useless_changewire;	/* useless wiring changes */
133 	int	ps_npg_prot_all;	/* # of active pages protected */
134 	int	ps_npg_prot_actual;	/* # pages actually affected */
135 	int	ps_npmeg_free;		/* # of free pmegs */
136 	int	ps_npmeg_locked;	/* # of pmegs on locked list */
137 	int	ps_npmeg_lru;		/* # of pmegs on lru list */
138 } pmap_stats;
139 
140 #ifdef DEBUG
141 #define	PDB_CREATE	0x0001
142 #define	PDB_DESTROY	0x0002
143 #define	PDB_REMOVE	0x0004
144 #define	PDB_CHANGEPROT	0x0008
145 #define	PDB_ENTER	0x0010
146 #define	PDB_FOLLOW	0x0020
147 
148 #define	PDB_MMU_ALLOC	0x0100
149 #define	PDB_MMU_STEAL	0x0200
150 #define	PDB_CTX_ALLOC	0x0400
151 #define	PDB_CTX_STEAL	0x0800
152 #define	PDB_MMUREG_ALLOC	0x1000
153 #define	PDB_MMUREG_STEAL	0x2000
154 #define	PDB_CACHESTUFF	0x4000
155 #define	PDB_SWITCHMAP	0x8000
156 #define	PDB_SANITYCHK	0x10000
157 int	pmapdebug = 0;
158 #endif
159 
160 /*
161  * Bounds on managed physical addresses. Used by (MD) users
162  * of uvm_pglistalloc() to provide search hints.
163  */
164 paddr_t	vm_first_phys = (paddr_t)-1;
165 paddr_t	vm_last_phys = 0;
166 psize_t vm_num_phys;
167 
168 /*
169  * For each managed physical page, there is a list of all currently
170  * valid virtual mappings of that page.  Since there is usually one
171  * (or zero) mapping per page, the table begins with an initial entry,
172  * rather than a pointer; this head entry is empty iff its pv_pmap
173  * field is NULL.
174  *
175  * Note that these are per machine independent page (so there may be
176  * only one for every two hardware pages, e.g.).  Since the virtual
177  * address is aligned on a page boundary, the low order bits are free
178  * for storing flags.  Only the head of each list has flags.
179  *
180  * THIS SHOULD BE PART OF THE CORE MAP
181  */
182 struct pvlist {
183 	struct		pvlist *pv_next;	/* next pvlist, if any */
184 	struct		pmap *pv_pmap;		/* pmap of this va */
185 	vaddr_t		pv_va;			/* virtual address */
186 	int		pv_flags;		/* flags (below) */
187 };
188 
189 /*
190  * Flags in pv_flags.  Note that PV_MOD must be 1 and PV_REF must be 2
191  * since they must line up with the bits in the hardware PTEs (see pte.h).
192  * SUN4M bits are at a slightly different location in the PTE.
193  * Note: the REF, MOD and ANC flag bits occur only in the head of a pvlist.
194  * The NC bit is meaningful in each individual pv entry and reflects the
195  * requested non-cacheability at the time the entry was made through
196  * pv_link() or when subsequently altered by kvm_uncache() (but the latter
197  * does not happen in kernels as of the time of this writing (March 2001)).
198  */
199 #define PV_MOD		1	/* page modified */
200 #define PV_REF		2	/* page referenced */
201 #define PV_NC		4	/* page cannot be cached */
202 #define PV_REF4M	1	/* page referenced (SRMMU) */
203 #define PV_MOD4M	2	/* page modified (SRMMU) */
204 #define PV_ANC		0x10	/* page has incongruent aliases */
205 
206 static struct pool pv_pool;
207 
208 static int pmap_initialized;	/* XXX - allow pmap_enter() before the
209 				 *	 pv tables are allocated.
210 				 */
211 
212 static struct pvlist *pvhead(paddr_t pfn)
213 {
214 	int bank, off;
215 
216 #ifdef DIAGNOSTIC
217 	if (pmap_initialized == 0)
218 		panic("pvhead: not initialized");
219 #endif
220 
221 	bank = vm_physseg_find(pfn, &off);
222 	if (bank == -1)
223 		return (NULL);
224 
225 	return (&vm_physmem[bank].pmseg.pvhead[off]);
226 }
227 
228 /*
229  * Each virtual segment within each pmap is either valid or invalid.
230  * It is valid if pm_npte[VA_VSEG(va)] is not 0.  This does not mean
231  * it is in the MMU, however; that is true iff pm_segmap[VA_VSEG(va)]
232  * does not point to the invalid PMEG.
233  *
234  * In the older SPARC architectures (sun4/sun4c), page tables are cached in
235  * the MMU. The following discussion applies to these architectures:
236  *
237  * If a virtual segment is valid and loaded, the correct PTEs appear
238  * in the MMU only.  If it is valid and unloaded, the correct PTEs appear
239  * in the pm_pte[VA_VSEG(va)] only.  However, some effort is made to keep
240  * the software copies consistent enough with the MMU so that libkvm can
241  * do user address translations.  In particular, pv_changepte() and
242  * pmap_enu() maintain consistency, while less critical changes are
243  * not maintained.  pm_pte[VA_VSEG(va)] always points to space for those
244  * PTEs, unless this is the kernel pmap, in which case pm_pte[x] is not
245  * used (sigh).
246  *
247  * Each PMEG in the MMU is either free or contains PTEs corresponding to
248  * some pmap and virtual segment.  If it contains some PTEs, it also contains
249  * reference and modify bits that belong in the pv_table.  If we need
250  * to steal a PMEG from some process (if we need one and none are free)
251  * we must copy the ref and mod bits, and update pm_segmap in the other
252  * pmap to show that its virtual segment is no longer in the MMU.
253  *
254  * There are 128 PMEGs in a small Sun-4, of which only a few dozen are
255  * tied down permanently, leaving `about' 100 to be spread among
256  * running processes.  These are managed as an LRU cache.  Before
257  * calling the VM paging code for a user page fault, the fault handler
258  * calls mmu_load(pmap, va) to try to get a set of PTEs put into the
259  * MMU.  mmu_load will check the validity of the segment and tell whether
260  * it did something.
261  *
262  * Since I hate the name PMEG I call this data structure an `mmu entry'.
263  * Each mmuentry is on exactly one of three `usage' lists: free, LRU,
264  * or locked.  The LRU list is for user processes; the locked list is
265  * for kernel entries; both are doubly linked queues headed by `mmuhd's.
266  * The free list is a simple list, headed by a free list pointer.
267  *
268  *
269  * In the sun4m architecture using the SPARC Reference MMU (SRMMU), three
270  * levels of page tables are maintained in physical memory. We use the same
271  * structures as with the 3-level old-style MMU (pm_regmap, pm_segmap,
272  * rg_segmap, sg_pte, etc) to maintain kernel-edible page tables; we also
273  * build a parallel set of physical tables that can be used by the MMU.
274  * (XXX: This seems redundant, but is it necessary for the unified kernel?)
275  *
276  * If a virtual segment is valid, its entries will be in both parallel lists.
277  * If it is not valid, then its entry in the kernel tables will be zero, and
278  * its entry in the MMU tables will either be nonexistent or zero as well.
279  *
280  * The Reference MMU generally uses a Translation Look-aside Buffer (TLB)
281  * to cache the result of recently executed page table walks. When
282  * manipulating page tables, we need to ensure consistency of the
283  * in-memory and TLB copies of the page table entries. This is handled
284  * by flushing (and invalidating) a TLB entry when appropriate before
285  * altering an in-memory page table entry.
286  */
287 struct mmuentry {
288 	TAILQ_ENTRY(mmuentry)	me_list;	/* usage list link */
289 	TAILQ_ENTRY(mmuentry)	me_pmchain;	/* pmap owner link */
290 	struct	pmap *me_pmap;		/* pmap, if in use */
291 	u_short	me_vreg;		/* associated virtual region/segment */
292 	u_short	me_vseg;		/* associated virtual region/segment */
293 	u_short	me_cookie;		/* hardware SMEG/PMEG number */
294 };
295 struct mmuentry *mmusegments;	/* allocated in pmap_bootstrap */
296 struct mmuentry *mmuregions;	/* allocated in pmap_bootstrap */
297 
298 struct mmuhd segm_freelist, segm_lru, segm_locked;
299 struct mmuhd region_freelist, region_lru, region_locked;
300 
301 int	seginval;		/* [4/4c] the invalid segment number */
302 int	reginval;		/* [4/3mmu] the invalid region number */
303 
304 /*
305  * (sun4/4c)
306  * A context is simply a small number that dictates which set of 4096
307  * segment map entries the MMU uses.  The Sun 4c has eight (SS1,IPC) or
308  * sixteen (SS2,IPX) such sets. These are alloted in an `almost MRU' fashion.
309  * (sun4m)
310  * A context is simply a small number that indexes the context table, the
311  * root-level page table mapping 4G areas. Each entry in this table points
312  * to a 1st-level region table. A SPARC reference MMU will usually use 16
313  * such contexts, but some offer as many as 64k contexts; the theoretical
314  * maximum is 2^32 - 1, but this would create overlarge context tables.
315  *
316  * Each context is either free or attached to a pmap.
317  *
318  * Since the virtual address cache is tagged by context, when we steal
319  * a context we have to flush (that part of) the cache.
320  */
321 union ctxinfo {
322 	union	ctxinfo *c_nextfree;	/* free list (if free) */
323 	struct	pmap *c_pmap;		/* pmap (if busy) */
324 };
325 
326 static struct simplelock ctx_lock;	/* lock for below */
327 union	ctxinfo *ctxinfo;		/* allocated at in pmap_bootstrap */
328 union	ctxinfo *ctx_freelist;		/* context free list */
329 int	ctx_kick;			/* allocation rover when none free */
330 int	ctx_kickdir;			/* ctx_kick roves both directions */
331 int	ncontext;			/* sizeof ctx_freelist */
332 
333 void	ctx_alloc __P((struct pmap *));
334 void	ctx_free __P((struct pmap *));
335 
336 caddr_t	vpage[2];		/* two reserved MD virtual pages */
337 #if defined(SUN4M)
338 int	*vpage_pte[2];		/* pte location of vpage[] */
339 #endif
340 caddr_t	vmmap;			/* one reserved MI vpage for /dev/mem */
341 caddr_t	vdumppages;		/* 32KB worth of reserved dump pages */
342 
343 smeg_t		tregion;	/* [4/3mmu] Region for temporary mappings */
344 
345 struct pmap	kernel_pmap_store;		/* the kernel's pmap */
346 struct regmap	kernel_regmap_store[NKREG];	/* the kernel's regmap */
347 struct segmap	kernel_segmap_store[NKREG*NSEGRG];/* the kernel's segmaps */
348 
349 #if defined(SUN4M)
350 u_int 	*kernel_regtable_store;		/* 1k of storage to map the kernel */
351 u_int	*kernel_segtable_store;		/* 2k of storage to map the kernel */
352 u_int	*kernel_pagtable_store;		/* 128k of storage to map the kernel */
353 
354 /*
355  * Memory pools and back-end supplier for SRMMU page tables.
356  * Share a pool between the level 2 and level 3 page tables,
357  * since these are equal in size.
358  */
359 static struct pool L1_pool;
360 static struct pool L23_pool;
361 
362 static void *pgt_page_alloc __P((struct pool *, int));
363 static void  pgt_page_free __P((struct pool *, void *));
364 
365 static struct pool_allocator pgt_page_allocator = {
366 	pgt_page_alloc, pgt_page_free, 0,
367 };
368 
369 #endif
370 
371 #define	MA_SIZE	32		/* size of memory descriptor arrays */
372 struct	memarr pmemarr[MA_SIZE];/* physical memory regions */
373 int	npmemarr;		/* number of entries in pmemarr */
374 
375 static paddr_t	avail_start;	/* first available physical page, other
376 				   than the `etext gap' defined below */
377 static vaddr_t	etext_gap_start;/* start of gap between text & data */
378 static vaddr_t	etext_gap_end;	/* end of gap between text & data */
379 static vaddr_t	virtual_avail;	/* first free kernel virtual address */
380 static vaddr_t	virtual_end;	/* last free kernel virtual address */
381 
382 static void pmap_page_upload __P((void));
383 
384 int mmu_has_hole;
385 
386 vaddr_t prom_vstart;	/* For /dev/kmem */
387 vaddr_t prom_vend;
388 
389 /*
390  * Memory pool for pmap structures.
391  */
392 static struct pool pmap_pmap_pool;
393 static struct pool_cache pmap_pmap_pool_cache;
394 static int	pmap_pmap_pool_ctor __P((void *, void *, int));
395 static void	pmap_pmap_pool_dtor __P((void *, void *));
396 
397 #if defined(SUN4)
398 /*
399  * [sun4]: segfixmask: on some systems (4/110) "getsegmap()" returns a
400  * partly invalid value. getsegmap returns a 16 bit value on the sun4,
401  * but only the first 8 or so bits are valid (the rest are *supposed* to
402  * be zero. On the 4/110 the bits that are supposed to be zero are
403  * all one instead. e.g. KERNBASE is usually mapped by pmeg number zero.
404  * On a 4/300 getsegmap(KERNBASE) == 0x0000, but
405  * on a 4/100 getsegmap(KERNBASE) == 0xff00
406  *
407  * This confuses mmu_reservemon() and causes it to not reserve the PROM's
408  * pmegs. Then the PROM's pmegs get used during autoconfig and everything
409  * falls apart!  (not very fun to debug, BTW.)
410  *
411  * solution: mask the invalid bits in the getsetmap macro.
412  */
413 
414 static u_long segfixmask = 0xffffffff; /* all bits valid to start */
415 #else
416 #define segfixmask 0xffffffff	/* It's in getsegmap's scope */
417 #endif
418 
419 /*
420  * pseudo-functions for mnemonic value
421  */
422 #define	getsegmap(va)		(CPU_ISSUN4C \
423 					? lduba(va, ASI_SEGMAP) \
424 					: (lduha(va, ASI_SEGMAP) & segfixmask))
425 #define	setsegmap(va, pmeg)	(CPU_ISSUN4C \
426 					? stba(va, ASI_SEGMAP, pmeg) \
427 					: stha(va, ASI_SEGMAP, pmeg))
428 
429 /* 3-level sun4 MMU only: */
430 #define	getregmap(va)		((unsigned)lduha((va)+2, ASI_REGMAP) >> 8)
431 #define	setregmap(va, smeg)	stha((va)+2, ASI_REGMAP, (smeg << 8))
432 
433 #if defined(SUN4M)
434 void		setpgt4m __P((int *ptep, int pte));
435 void		setpte4m __P((vaddr_t va, int pte));
436 
437 #ifdef MULTIPROCESSOR
438 void		setpgt4m_va __P((vaddr_t, int *, int, int));
439 #else
440 #define		setpgt4m_va(va, ptep, pte, pageflush) do { \
441 	if ((pageflush)) \
442 		tlb_flush_page((va)); \
443 	setpgt4m((ptep), (pte)); \
444 } while (0)
445 #endif
446 
447 #endif
448 
449 /* Function pointer messiness for supporting multiple sparc architectures
450  * within a single kernel: notice that there are two versions of many of the
451  * functions within this file/module, one for the sun4/sun4c and the other
452  * for the sun4m. For performance reasons (since things like pte bits don't
453  * map nicely between the two architectures), there are separate functions
454  * rather than unified functions which test the cputyp variable. If only
455  * one architecture is being used, then the non-suffixed function calls
456  * are macro-translated into the appropriate xxx4_4c or xxx4m call. If
457  * multiple architectures are defined, the calls translate to (*xxx_p),
458  * i.e. they indirect through function pointers initialized as appropriate
459  * to the run-time architecture in pmap_bootstrap. See also pmap.h.
460  */
461 
462 #if defined(SUN4M)
463 static void mmu_setup4m_L1 __P((int, struct pmap *));
464 static void mmu_setup4m_L2 __P((int, struct regmap *));
465 static void  mmu_setup4m_L3 __P((int, struct segmap *));
466 /*static*/ void	mmu_reservemon4m __P((struct pmap *));
467 
468 /*static*/ void pmap_rmk4m __P((struct pmap *, vaddr_t, vaddr_t, int, int));
469 /*static*/ void pmap_rmu4m __P((struct pmap *, vaddr_t, vaddr_t, int, int));
470 /*static*/ int  pmap_enk4m __P((struct pmap *, vaddr_t, vm_prot_t,
471 				int, struct pvlist *, int));
472 /*static*/ int  pmap_enu4m __P((struct pmap *, vaddr_t, vm_prot_t,
473 				int, struct pvlist *, int));
474 /*static*/ void pv_changepte4m __P((struct pvlist *, int, int));
475 /*static*/ int  pv_syncflags4m __P((struct pvlist *));
476 /*static*/ int  pv_link4m __P((struct pvlist *, struct pmap *, vaddr_t, int));
477 /*static*/ void pv_unlink4m __P((struct pvlist *, struct pmap *, vaddr_t));
478 #endif
479 
480 #if defined(SUN4) || defined(SUN4C)
481 /*static*/ void	mmu_reservemon4_4c __P((int *, int *));
482 /*static*/ void pmap_rmk4_4c __P((struct pmap *, vaddr_t, vaddr_t, int, int));
483 /*static*/ void pmap_rmu4_4c __P((struct pmap *, vaddr_t, vaddr_t, int, int));
484 /*static*/ int  pmap_enk4_4c __P((struct pmap *, vaddr_t, vm_prot_t,
485 				  int, struct pvlist *, int));
486 /*static*/ int  pmap_enu4_4c __P((struct pmap *, vaddr_t, vm_prot_t,
487 				  int, struct pvlist *, int));
488 /*static*/ void pv_changepte4_4c __P((struct pvlist *, int, int));
489 /*static*/ int  pv_syncflags4_4c __P((struct pvlist *));
490 /*static*/ int  pv_link4_4c __P((struct pvlist *, struct pmap *, vaddr_t, int));
491 /*static*/ void pv_unlink4_4c __P((struct pvlist *, struct pmap *, vaddr_t));
492 #endif
493 
494 #if !defined(SUN4M) && (defined(SUN4) || defined(SUN4C))
495 #define		pmap_rmk	pmap_rmk4_4c
496 #define		pmap_rmu	pmap_rmu4_4c
497 
498 #elif defined(SUN4M) && !(defined(SUN4) || defined(SUN4C))
499 #define		pmap_rmk	pmap_rmk4m
500 #define		pmap_rmu	pmap_rmu4m
501 
502 #else  /* must use function pointers */
503 
504 /* function pointer declarations */
505 /* from pmap.h: */
506 boolean_t	(*pmap_clear_modify_p) __P((struct vm_page *));
507 boolean_t	(*pmap_clear_reference_p) __P((struct vm_page *));
508 int		(*pmap_enter_p) __P((pmap_t, vaddr_t, paddr_t, vm_prot_t, int));
509 boolean_t	(*pmap_extract_p) __P((pmap_t, vaddr_t, paddr_t *));
510 boolean_t	(*pmap_is_modified_p) __P((struct vm_page *));
511 boolean_t	(*pmap_is_referenced_p) __P((struct vm_page *));
512 void		(*pmap_kenter_pa_p) __P((vaddr_t, paddr_t, vm_prot_t));
513 void		(*pmap_kremove_p) __P((vaddr_t, vsize_t));
514 void		(*pmap_page_protect_p) __P((struct vm_page *, vm_prot_t));
515 void		(*pmap_protect_p) __P((pmap_t, vaddr_t, vaddr_t, vm_prot_t));
516 void		(*pmap_changeprot_p) __P((pmap_t, vaddr_t, vm_prot_t, int));
517 /* local: */
518 void 		(*pmap_rmk_p) __P((struct pmap *, vaddr_t, vaddr_t, int, int));
519 void 		(*pmap_rmu_p) __P((struct pmap *, vaddr_t, vaddr_t, int, int));
520 
521 #define		pmap_rmk	(*pmap_rmk_p)
522 #define		pmap_rmu	(*pmap_rmu_p)
523 
524 #endif
525 
526 /* --------------------------------------------------------------*/
527 
528 /*
529  * Next we have some sun4m-specific routines which have no 4/4c
530  * counterparts, or which are 4/4c macros.
531  */
532 
533 #if defined(SUN4M)
534 
535 #if defined(MULTIPROCESSOR)
536 /*
537  * The SMP versions of the tlb flush routines.
538  */
539 static __inline__ void	smp_tlb_flush_context __P((void));
540 static __inline__ void	smp_tlb_flush_region __P((int));
541 static __inline__ void	smp_tlb_flush_segment __P((int, int));
542 static __inline__ void	smp_tlb_flush_page __P((int va));
543 static __inline__ void	smp_tlb_flush_all __P((void));
544 
545 #if 0
546 int smp_tlb_fc_cnt[2];	/* [0] -> calls, [1] -> ipi generating calls */
547 int smp_tlb_fr_cnt[2];
548 int smp_tlb_fs_cnt[2];
549 int smp_tlb_fp_cnt[2];
550 int smp_tlb_fa_cnt[2];
551 #define INCR_COUNT(x) x[0]++
552 #define INCR_CALL(x) x[1]++
553 
554 void db_print_tlb_stats(void);
555 void
556 db_print_tlb_stats()
557 {
558 
559 	printf("SMP TLB shootdown statistics:\n");
560 	printf("\twhat\tcount\tcalls\n");
561 	printf("\tcontext\t%d\t%d\n", smp_tlb_fc_cnt[0], smp_tlb_fc_cnt[1]);
562 	printf("\tregion\t%d\t%d\n", smp_tlb_fr_cnt[0], smp_tlb_fr_cnt[1]);
563 	printf("\tseg\t%d\t%d\n", smp_tlb_fs_cnt[0], smp_tlb_fs_cnt[1]);
564 	printf("\tpage\t%d\t%d\n", smp_tlb_fp_cnt[0], smp_tlb_fp_cnt[1]);
565 	printf("\tall\t%d\t%d\n", smp_tlb_fa_cnt[0], smp_tlb_fa_cnt[1]);
566 }
567 #else
568 #define INCR_COUNT(x) /* nothing */
569 #define INCR_CALL(x) /* nothing */
570 #endif
571 
572 /*
573  * SMP TLB flush routines; these *must* be broadcast on sun4m systems
574  */
575 static __inline__ void
576 smp_tlb_flush_page(va)
577 	int va;
578 {
579 	int n, s;
580 
581 	INCR_COUNT(smp_tlb_fp_cnt);
582 	tlb_flush_page_real(va);
583 	if (cold || (cpuinfo.flags & CPUFLG_READY) == 0)
584 		return;
585 	INCR_CALL(smp_tlb_fc_cnt);
586 	LOCK_XPMSG();
587 	for (n = 0; n < ncpu; n++) {
588 		struct cpu_info *cpi = cpus[n];
589 		struct xpmsg_flush_page *p;
590 
591 		if (CPU_READY(cpi))
592 			continue;
593 		p = &cpi->msg.u.xpmsg_flush_page;
594 		s = splhigh();
595 		simple_lock(&cpi->msg.lock);
596 		cpi->msg.tag = XPMSG_DEMAP_TLB_PAGE;
597 		p->ctx = getcontext4m();
598 		p->va = va;
599 		raise_ipi_wait_and_unlock(cpi);
600 		splx(s);
601 	}
602 	UNLOCK_XPMSG();
603 }
604 
605 static __inline__ void
606 smp_tlb_flush_segment(vr, vs)
607 	int vr, vs;
608 {
609 	int n, s;
610 
611 	INCR_COUNT(smp_tlb_fs_cnt);
612 	tlb_flush_segment_real(vr, vs);
613 	if (cold || (cpuinfo.flags & CPUFLG_READY) == 0)
614 		return;
615 	INCR_CALL(smp_tlb_fs_cnt);
616 	LOCK_XPMSG();
617 	for (n = 0; n < ncpu; n++) {
618 		struct cpu_info *cpi = cpus[n];
619 		struct xpmsg_flush_segment *p;
620 
621 		if (CPU_READY(cpi))
622 			continue;
623 		p = &cpi->msg.u.xpmsg_flush_segment;
624 		s = splhigh();
625 		simple_lock(&cpi->msg.lock);
626 		cpi->msg.tag = XPMSG_DEMAP_TLB_SEGMENT;
627 		p->ctx = getcontext4m();
628 		p->vr = vr;
629 		p->vs = vs;
630 		raise_ipi_wait_and_unlock(cpi);
631 		splx(s);
632 	}
633 	UNLOCK_XPMSG();
634 }
635 
636 static __inline__ void
637 smp_tlb_flush_region(vr)
638 	int vr;
639 {
640 	int n, s;
641 
642 	INCR_COUNT(smp_tlb_fr_cnt);
643 	tlb_flush_region_real(vr);
644 	if (cold || (cpuinfo.flags & CPUFLG_READY) == 0)
645 		return;
646 	INCR_CALL(smp_tlb_fr_cnt);
647 	LOCK_XPMSG();
648 	for (n = 0; n < ncpu; n++) {
649 		struct cpu_info *cpi = cpus[n];
650 		struct xpmsg_flush_region *p;
651 
652 		if (CPU_READY(cpi))
653 			continue;
654 		p = &cpi->msg.u.xpmsg_flush_region;
655 		s = splhigh();
656 		simple_lock(&cpi->msg.lock);
657 		cpi->msg.tag = XPMSG_DEMAP_TLB_REGION;
658 		p->ctx = getcontext4m();
659 		p->vr = vr;
660 		raise_ipi_wait_and_unlock(cpi);
661 		splx(s);
662 	}
663 	UNLOCK_XPMSG();
664 }
665 
666 static __inline__ void
667 smp_tlb_flush_context()
668 {
669 	int n, s;
670 
671 	INCR_COUNT(smp_tlb_fc_cnt);
672 	tlb_flush_context_real();
673 	if (cold || (cpuinfo.flags & CPUFLG_READY) == 0)
674 		return;
675 	INCR_CALL(smp_tlb_fc_cnt);
676 	LOCK_XPMSG();
677 	for (n = 0; n < ncpu; n++) {
678 		struct cpu_info *cpi = cpus[n];
679 		struct xpmsg_flush_context *p;
680 
681 		if (CPU_READY(cpi))
682 			continue;
683 		p = &cpi->msg.u.xpmsg_flush_context;
684 		s = splhigh();
685 		simple_lock(&cpi->msg.lock);
686 		cpi->msg.tag = XPMSG_DEMAP_TLB_CONTEXT;
687 		p->ctx = getcontext4m();
688 		raise_ipi_wait_and_unlock(cpi);
689 		splx(s);
690 	}
691 	UNLOCK_XPMSG();
692 }
693 
694 static __inline__ void
695 smp_tlb_flush_all()
696 {
697 	int n, s;
698 
699 	INCR_COUNT(smp_tlb_fa_cnt);
700 	tlb_flush_all_real();
701 	if (cold || (cpuinfo.flags & CPUFLG_READY) == 0)
702 		return;
703 	INCR_CALL(smp_tlb_fa_cnt);
704 	LOCK_XPMSG();
705 	for (n = 0; n < ncpu; n++) {
706 		struct cpu_info *cpi = cpus[n];
707 
708 		if (CPU_READY(cpi))
709 			continue;
710 		s = splhigh();
711 		simple_lock(&cpi->msg.lock);
712 		cpi->msg.tag = XPMSG_DEMAP_TLB_ALL;
713 		raise_ipi_wait_and_unlock(cpi);
714 		splx(s);
715 	}
716 	UNLOCK_XPMSG();
717 }
718 #endif
719 
720 #if defined(MULTIPROCESSOR) && 0
721 #define tlb_flush_page(va)		smp_tlb_flush_page((int)va)
722 #define tlb_flush_segment(vr, vs)	smp_tlb_flush_segment(vr, vs)
723 #define tlb_flush_region(vr)		smp_tlb_flush_region(vr)
724 #define tlb_flush_context()		smp_tlb_flush_context()
725 #define tlb_flush_all()			smp_tlb_flush_all()
726 #else
727 #define tlb_flush_page(va)		tlb_flush_page_real(va)
728 #define tlb_flush_segment(vr, vs)	tlb_flush_segment_real(vr, vs)
729 #define tlb_flush_region(vr)		tlb_flush_region_real(vr)
730 #define tlb_flush_context()		tlb_flush_context_real()
731 #define tlb_flush_all()			tlb_flush_all_real()
732 #endif
733 
734 /*
735  * Atomically update a PTE entry, coping with hardware updating the
736  * PTE at the same time we are.  This is the procedure that is
737  * recommended in the SuperSPARC user's manual.
738  */
739 int updatepte4m __P((vaddr_t, int *, int, int));
740 static struct simplelock pte4m_lock = SIMPLELOCK_INITIALIZER;
741 
742 int
743 updatepte4m(va, pte, bic, bis)
744 	vaddr_t va;
745 	int *pte;
746 	int bic;
747 	int bis;
748 {
749 	int oldval, swapval;
750 	volatile int *vpte = (volatile int *)pte;
751 
752 	/*
753 	 * Can only be one of these happening in the system
754 	 * at any one time.
755 	 */
756 	simple_lock(&pte4m_lock);
757 
758 	/*
759 	 * The idea is to loop swapping zero into the pte, flushing
760 	 * it, and repeating until it stays zero.  At this point,
761 	 * there should be no more hardware accesses to this PTE
762 	 * so we can modify it without losing any mod/ref info.
763 	 */
764 	oldval = 0;
765 	do {
766 		swapval = 0;
767 		swap(vpte, swapval);
768 		tlb_flush_page(va);
769 		oldval |= swapval;
770 	} while (*vpte != 0);
771 
772 	swapval = (oldval & ~bic) | bis;
773 	swap(vpte, swapval);
774 
775 	simple_unlock(&pte4m_lock);
776 
777 	return (oldval);
778 }
779 
780 static u_int	VA2PA __P((caddr_t));
781 static u_long	srmmu_bypass_read __P((u_long));
782 
783 /*
784  * VA2PA(addr) -- converts a virtual address to a physical address using
785  * the MMU's currently-installed page tables. As a side effect, the address
786  * translation used may cause the associated pte to be encached. The correct
787  * context for VA must be set before this is called.
788  *
789  * This routine should work with any level of mapping, as it is used
790  * during bootup to interact with the ROM's initial L1 mapping of the kernel.
791  */
792 static u_int
793 VA2PA(addr)
794 	caddr_t addr;
795 {
796 	u_int pte;
797 
798 	/* we'll use that handy SRMMU flush/probe! %%%: make consts below! */
799 	/* Try each level in turn until we find a valid pte. Otherwise panic */
800 
801 	pte = lda(((u_int)addr & ~0xfff) | ASI_SRMMUFP_L3, ASI_SRMMUFP);
802 	/* Unlock fault status; required on Hypersparc modules */
803 	(void)lda(SRMMU_SFSR, ASI_SRMMU);
804 	if ((pte & SRMMU_TETYPE) == SRMMU_TEPTE)
805 	    return (((pte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) |
806 		    ((u_int)addr & 0xfff));
807 
808 	/* A `TLB Flush Entire' is required before any L0, L1 or L2 probe */
809 	tlb_flush_all_real();
810 
811 	pte = lda(((u_int)addr & ~0xfff) | ASI_SRMMUFP_L2, ASI_SRMMUFP);
812 	if ((pte & SRMMU_TETYPE) == SRMMU_TEPTE)
813 	    return (((pte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) |
814 		    ((u_int)addr & 0x3ffff));
815 	pte = lda(((u_int)addr & ~0xfff) | ASI_SRMMUFP_L1, ASI_SRMMUFP);
816 	if ((pte & SRMMU_TETYPE) == SRMMU_TEPTE)
817 	    return (((pte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) |
818 		    ((u_int)addr & 0xffffff));
819 	pte = lda(((u_int)addr & ~0xfff) | ASI_SRMMUFP_L0, ASI_SRMMUFP);
820 	if ((pte & SRMMU_TETYPE) == SRMMU_TEPTE)
821 	    return (((pte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) |
822 		    ((u_int)addr & 0xffffffff));
823 
824 #ifdef DIAGNOSTIC
825 	panic("VA2PA: Asked to translate unmapped VA %p", addr);
826 #else
827 	return (0);
828 #endif
829 }
830 
831 __inline void
832 setpgt4m(ptep, pte)
833 	int *ptep;
834 	int pte;
835 {
836 
837 	swap(ptep, pte);
838 }
839 
840 #ifdef MULTIPROCESSOR
841 __inline void
842 setpgt4m_va(va, ptep, pte, pageflush)
843 	vaddr_t va;
844 	int *ptep;
845 	int pte;
846 	int pageflush;	/* ignored */
847 {
848 
849 	updatepte4m(va, ptep, 0xffffffff, pte);
850 }
851 #endif
852 
853 /* Set the page table entry for va to pte. */
854 __inline void
855 setpte4m(va, pte)
856 	vaddr_t va;
857 	int pte;
858 {
859 	struct pmap *pm;
860 	struct regmap *rm;
861 	struct segmap *sm;
862 
863 	if (getcontext4m() != 0)
864 		panic("setpte4m: user context");
865 
866 	pm = pmap_kernel();
867 
868 	/* Note: inline version of setptesw4m() */
869 #ifdef DEBUG
870 	if (pm->pm_regmap == NULL)
871 		panic("setpte4m: no regmap entry");
872 #endif
873 	rm = &pm->pm_regmap[VA_VREG(va)];
874 	sm = &rm->rg_segmap[VA_VSEG(va)];
875 
876 #ifdef DEBUG
877 	if (rm->rg_segmap == NULL)
878 		panic("setpte4m: no segmap for va %p (rp=%p)",
879 			(caddr_t)va, (caddr_t)rm);
880 
881 	if (sm->sg_pte == NULL)
882 		panic("setpte4m: no pte for va %p (rp=%p, sp=%p)",
883 		      (caddr_t)va, rm, sm);
884 #endif
885 	tlb_flush_page(va);
886 	setpgt4m(sm->sg_pte + VA_SUN4M_VPG(va), pte);
887 }
888 
889 /*
890  * Page table pool back-end.
891  */
892 void *
893 pgt_page_alloc(struct pool *pp, int flags)
894 {
895 	int cacheit = (cpuinfo.flags & CPUFLG_CACHEPAGETABLES) != 0;
896 	struct vm_page *pg;
897 	vaddr_t va;
898 	paddr_t pa;
899 
900 	/* Allocate a page of physical memory */
901 	if ((pg = uvm_pagealloc(NULL, 0, NULL, 0)) == NULL)
902 		return (NULL);
903 
904 	/* Allocate virtual memory */
905 	va = uvm_km_valloc(kernel_map, PAGE_SIZE);
906 	if (va == 0) {
907 		uvm_pagefree(pg);
908 		return (NULL);
909 	}
910 
911 	/*
912 	 * On systems with a physical data cache we need to flush this page
913 	 * from the cache if the pagetables cannot be cached.
914 	 * On systems with a virtually indexed data cache, we only need
915 	 * to map it non-cacheable, since the page is not currently mapped.
916 	 */
917 	pa = VM_PAGE_TO_PHYS(pg);
918 	if (cacheit == 0)
919 		pcache_flush_page(pa, 1);
920 
921 	/* Map the page */
922 	pmap_kenter_pa(va, pa | (cacheit ? 0 : PMAP_NC),
923 	    VM_PROT_READ | VM_PROT_WRITE);
924 	pmap_update(pmap_kernel());
925 
926 	return ((void *)va);
927 }
928 
929 void
930 pgt_page_free(struct pool *pp, void *v)
931 {
932 	vaddr_t va;
933 	paddr_t pa;
934 	boolean_t rv;
935 
936 	va = (vaddr_t)v;
937 	rv = pmap_extract(pmap_kernel(), va, &pa);
938 	KASSERT(rv);
939 	uvm_pagefree(PHYS_TO_VM_PAGE(pa));
940 	pmap_kremove(va, PAGE_SIZE);
941 	uvm_km_free(kernel_map, va, PAGE_SIZE);
942 }
943 #endif /* 4m only */
944 
945 /*----------------------------------------------------------------*/
946 
947 /*
948  * The following three macros are to be used in sun4/sun4c code only.
949  */
950 #if defined(SUN4_MMU3L)
951 #define CTX_USABLE(pm,rp) (					\
952 		((pm)->pm_ctx != NULL &&			\
953 		 (!HASSUN4_MMU3L || (rp)->rg_smeg != reginval))	\
954 )
955 #else
956 #define CTX_USABLE(pm,rp)	((pm)->pm_ctx != NULL )
957 #endif
958 
959 #define GAP_WIDEN(pm,vr) do if (CPU_ISSUN4OR4C) {	\
960 	if (vr + 1 == pm->pm_gap_start)			\
961 		pm->pm_gap_start = vr;			\
962 	if (vr == pm->pm_gap_end)			\
963 		pm->pm_gap_end = vr + 1;		\
964 } while (0)
965 
966 #define GAP_SHRINK(pm,vr) do if (CPU_ISSUN4OR4C) {			\
967 	int x;								\
968 	x = pm->pm_gap_start + (pm->pm_gap_end - pm->pm_gap_start) / 2;	\
969 	if (vr > x) {							\
970 		if (vr < pm->pm_gap_end)				\
971 			pm->pm_gap_end = vr;				\
972 	} else {							\
973 		if (vr >= pm->pm_gap_start && x != pm->pm_gap_start)	\
974 			pm->pm_gap_start = vr + 1;			\
975 	}								\
976 } while (0)
977 
978 
979 static void get_phys_mem __P((void));
980 void	pv_flushcache __P((struct pvlist *));
981 void	pv_uncache __P((struct pvlist *));
982 void	kvm_iocache __P((caddr_t, int));
983 
984 #ifdef DEBUG
985 void	pm_check __P((char *, struct pmap *));
986 void	pm_check_k __P((char *, struct pmap *));
987 void	pm_check_u __P((char *, struct pmap *));
988 #endif
989 
990 /*
991  * During the PMAP bootstrap, we can use a simple translation to map a
992  * kernel virtual address to a psysical memory address (this is arranged
993  * in locore).  Usually, KERNBASE maps to physical address 0. This is always
994  * the case on sun4 and sun4c machines. On sun4m machines -- if no memory is
995  * installed in the bank corresponding to physical address 0 -- the PROM may
996  * elect to load us at some other address, presumably at the start of
997  * the first memory bank that is available. We set the up the variable
998  * `va2pa_offset' to hold the physical address corresponding to KERNBASE.
999  */
1000 
1001 static u_long va2pa_offset = KERNBASE;
1002 #define PMAP_BOOTSTRAP_VA2PA(v) ((paddr_t)((u_long)(v) - va2pa_offset))
1003 
1004 /*
1005  * Grab physical memory list.
1006  * While here, compute `physmem'.
1007  */
1008 void
1009 get_phys_mem()
1010 {
1011 	struct memarr *mp;
1012 	int i;
1013 
1014 	npmemarr = makememarr(pmemarr, MA_SIZE, MEMARR_AVAILPHYS);
1015 
1016 	for (physmem = 0, mp = pmemarr, i = npmemarr; --i >= 0; mp++)
1017 		physmem += btoc(mp->len);
1018 }
1019 
1020 
1021 /*
1022  * Support functions for vm_page_bootstrap().
1023  */
1024 
1025 /*
1026  * How much virtual space does this kernel have?
1027  * (After mapping kernel text, data, etc.)
1028  */
1029 void
1030 pmap_virtual_space(v_start, v_end)
1031         vaddr_t *v_start;
1032         vaddr_t *v_end;
1033 {
1034         *v_start = virtual_avail;
1035         *v_end   = virtual_end;
1036 }
1037 
1038 /*
1039  * Helper routine that hands off available physical pages to the VM system.
1040  */
1041 static void
1042 pmap_page_upload()
1043 {
1044 	int	n;
1045 	paddr_t	start, end;
1046 
1047 	/* First, the `etext gap' */
1048 	start = PMAP_BOOTSTRAP_VA2PA(etext_gap_start);
1049 	end = PMAP_BOOTSTRAP_VA2PA(etext_gap_end);
1050 #ifdef DIAGNOSTIC
1051 	if (avail_start <= start)
1052 		panic("pmap_page_upload: etext gap overlap: %lx < %lx",
1053 			(u_long)avail_start, (u_long)start);
1054 #endif
1055 	if (etext_gap_start < etext_gap_end) {
1056 		vm_first_phys = start;
1057 		uvm_page_physload(
1058 			atop(start),
1059 			atop(end),
1060 			atop(start),
1061 			atop(end), VM_FREELIST_DEFAULT);
1062 	}
1063 
1064 	for (n = 0; n < npmemarr; n++) {
1065 
1066 		start = pmemarr[n].addr;
1067 		end = start + pmemarr[n].len;
1068 
1069 		/*
1070 		 * If this segment contains `avail_start', we must exclude
1071 		 * the range of initial kernel memory as computed by
1072 		 * pmap_bootstrap(). Note that this will also exclude
1073 		 * the `etext gap' range already uploaded above.
1074 		 */
1075 		if (start <= avail_start && avail_start < end)
1076 			start = avail_start;
1077 
1078 		if (start == end)
1079 			continue;
1080 
1081 		/* Update vm_{first_last}_phys */
1082 		if (vm_first_phys > start)
1083 			vm_first_phys = start;
1084 
1085 		if (vm_last_phys < end)
1086 			vm_last_phys = end;
1087 
1088 		uvm_page_physload(
1089 			atop(start),
1090 			atop(end),
1091 			atop(start),
1092 			atop(end), VM_FREELIST_DEFAULT);
1093 	}
1094 }
1095 
1096 /*
1097  * This routine is used by mmrw() to validate access to `/dev/mem'.
1098  */
1099 int
1100 pmap_pa_exists(pa)
1101 	paddr_t pa;
1102 {
1103 	int nmem;
1104 	struct memarr *mp;
1105 
1106 	for (mp = pmemarr, nmem = npmemarr; --nmem >= 0; mp++) {
1107 		if (pa >= mp->addr && pa < mp->addr + mp->len)
1108 			return 1;
1109 	}
1110 
1111 	return 0;
1112 }
1113 
1114 /* update pv_flags given a valid pte */
1115 #define	MR4_4C(pte) (((pte) >> PG_M_SHIFT) & (PV_MOD | PV_REF))
1116 #define MR4M(pte) (((pte) >> PG_M_SHIFT4M) & (PV_MOD4M | PV_REF4M))
1117 
1118 /*----------------------------------------------------------------*/
1119 
1120 /*
1121  * Agree with the monitor ROM as to how many MMU entries are
1122  * to be reserved, and map all of its segments into all contexts.
1123  *
1124  * Unfortunately, while the Version 0 PROM had a nice linked list of
1125  * taken virtual memory, the Version 2 PROM provides instead a convoluted
1126  * description of *free* virtual memory.  Rather than invert this, we
1127  * resort to two magic constants from the PROM vector description file.
1128  */
1129 #if defined(SUN4) || defined(SUN4C)
1130 void
1131 mmu_reservemon4_4c(nrp, nsp)
1132 	int *nrp, *nsp;
1133 {
1134 	u_int va = 0, eva = 0;
1135 	int mmuseg, i, nr, ns, vr, lastvr;
1136 #if defined(SUN4_MMU3L)
1137 	int mmureg;
1138 #endif
1139 	struct regmap *rp;
1140 
1141 #if defined(SUN4M)
1142 	if (CPU_ISSUN4M) {
1143 		panic("mmu_reservemon4_4c called on sun4m machine");
1144 		return;
1145 	}
1146 #endif
1147 
1148 #if defined(SUN4)
1149 	if (CPU_ISSUN4) {
1150 		prom_vstart = va = OLDMON_STARTVADDR;
1151 		prom_vend = eva = OLDMON_ENDVADDR;
1152 	}
1153 #endif
1154 #if defined(SUN4C)
1155 	if (CPU_ISSUN4C) {
1156 		prom_vstart = va = OPENPROM_STARTVADDR;
1157 		prom_vend = eva = OPENPROM_ENDVADDR;
1158 	}
1159 #endif
1160 	ns = *nsp;
1161 	nr = *nrp;
1162 	lastvr = 0;
1163 	while (va < eva) {
1164 		vr = VA_VREG(va);
1165 		rp = &pmap_kernel()->pm_regmap[vr];
1166 
1167 #if defined(SUN4_MMU3L)
1168 		if (HASSUN4_MMU3L && vr != lastvr) {
1169 			lastvr = vr;
1170 			mmureg = getregmap(va);
1171 			if (mmureg < nr)
1172 				rp->rg_smeg = nr = mmureg;
1173 			/*
1174 			 * On 3-level MMU machines, we distribute regions,
1175 			 * rather than segments, amongst the contexts.
1176 			 */
1177 			for (i = ncontext; --i > 0;)
1178 				prom_setcontext(i, (caddr_t)va, mmureg);
1179 		}
1180 #endif
1181 		mmuseg = getsegmap(va);
1182 		if (mmuseg < ns)
1183 			ns = mmuseg;
1184 
1185 		if (!HASSUN4_MMU3L)
1186 			for (i = ncontext; --i > 0;)
1187 				prom_setcontext(i, (caddr_t)va, mmuseg);
1188 
1189 		if (mmuseg == seginval) {
1190 			va += NBPSG;
1191 			continue;
1192 		}
1193 		/*
1194 		 * Another PROM segment. Enter into region map.
1195 		 * Assume the entire segment is valid.
1196 		 */
1197 		rp->rg_nsegmap += 1;
1198 		rp->rg_segmap[VA_VSEG(va)].sg_pmeg = mmuseg;
1199 		rp->rg_segmap[VA_VSEG(va)].sg_npte = NPTESG;
1200 
1201 		/* PROM maps its memory user-accessible: fix it. */
1202 		for (i = NPTESG; --i >= 0; va += NBPG)
1203 			setpte4(va, getpte4(va) | PG_S);
1204 	}
1205 	*nsp = ns;
1206 	*nrp = nr;
1207 	return;
1208 }
1209 #endif
1210 
1211 #if defined(SUN4M) /* sun4m versions of above */
1212 
1213 u_long
1214 srmmu_bypass_read(paddr)
1215 	u_long	paddr;
1216 {
1217 	unsigned long v;
1218 
1219 	if (cpuinfo.mxcc) {
1220 		/*
1221 		 * We're going to have to use MMU passthrough. If we're on
1222 		 * a Viking SuperSPARC with a MultiCache Controller, we
1223 		 * need to set the AC (Alternate Cacheable) bit in the MMU's
1224 		 * control register in order to not by-pass the cache.
1225 		 */
1226 
1227 		unsigned long s = lda(SRMMU_PCR, ASI_SRMMU);
1228 
1229 		/* set MMU AC bit */
1230 		sta(SRMMU_PCR, ASI_SRMMU, s | VIKING_PCR_AC);
1231 		v = lda(paddr, ASI_BYPASS);
1232 		sta(SRMMU_PCR, ASI_SRMMU, s);
1233 	} else
1234 		v = lda(paddr, ASI_BYPASS);
1235 
1236 	return (v);
1237 }
1238 
1239 
1240 /*
1241  * Take the monitor's initial page table layout, convert it to 3rd-level pte's
1242  * (it starts out as a L1 mapping), and install it along with a set of kernel
1243  * mapping tables as the kernel's initial page table setup. Also create and
1244  * enable a context table. I suppose we also want to block user-mode access
1245  * to the new kernel/ROM mappings.
1246  */
1247 
1248 /*
1249  * mmu_reservemon4m(): Copies the existing (ROM) page tables to kernel space,
1250  * converting any L1/L2 PTEs to L3 PTEs. Does *not* copy the L1 entry mapping
1251  * the kernel at KERNBASE since we don't want to map 16M of physical
1252  * memory for the kernel. Thus the kernel must be installed later!
1253  * Also installs ROM mappings into the kernel pmap.
1254  * NOTE: This also revokes all user-mode access to the mapped regions.
1255  */
1256 void
1257 mmu_reservemon4m(kpmap)
1258 	struct pmap *kpmap;
1259 {
1260 	unsigned int rom_ctxtbl;
1261 	int te;
1262 
1263 	prom_vstart = OPENPROM_STARTVADDR;
1264 	prom_vend = OPENPROM_ENDVADDR;
1265 
1266 	/*
1267 	 * XXX: although the sun4m can handle 36 bits of physical
1268 	 * address space, we assume that all these page tables, etc
1269 	 * are in the lower 4G (32-bits) of address space, i.e. out of I/O
1270 	 * space. Eventually this should be changed to support the 36 bit
1271 	 * physical addressing, in case some crazed ROM designer decides to
1272 	 * stick the pagetables up there. In that case, we should use MMU
1273 	 * transparent mode, (i.e. ASI 0x20 to 0x2f) to access
1274 	 * physical memory.
1275 	 */
1276 
1277 	rom_ctxtbl = (lda(SRMMU_CXTPTR,ASI_SRMMU) << SRMMU_PPNPASHIFT);
1278 
1279 	te = srmmu_bypass_read(rom_ctxtbl);	/* i.e. context 0 */
1280 
1281 	switch (te & SRMMU_TETYPE) {
1282 	case SRMMU_TEINVALID:
1283 		cpuinfo.ctx_tbl[0] = SRMMU_TEINVALID;
1284 		panic("mmu_reservemon4m: no existing L0 mapping! "
1285 		      "(How are we running?");
1286 		break;
1287 	case SRMMU_TEPTE:
1288 		panic("mmu_reservemon4m: can't handle ROM 4G page size");
1289 		/* XXX: Should make this work, however stupid it is */
1290 		break;
1291 	case SRMMU_TEPTD:
1292 		mmu_setup4m_L1(te, kpmap);
1293 		break;
1294 	default:
1295 		panic("mmu_reservemon4m: unknown pagetable entry type");
1296 	}
1297 }
1298 
1299 void
1300 mmu_setup4m_L1(regtblptd, kpmap)
1301 	int regtblptd;		/* PTD for region table to be remapped */
1302 	struct pmap *kpmap;
1303 {
1304 	unsigned int regtblrover;
1305 	int i;
1306 	unsigned int te;
1307 	struct regmap *rp;
1308 	int j, k;
1309 
1310 	/*
1311 	 * Here we scan the region table to copy any entries which appear.
1312 	 * We are only concerned with regions in kernel space and above
1313 	 * (i.e. regions VA_VREG(KERNBASE)+1 to 0xff). We ignore the first
1314 	 * region (at VA_VREG(KERNBASE)), since that is the 16MB L1 mapping
1315 	 * that the ROM used to map the kernel in initially. Later, we will
1316 	 * rebuild a new L3 mapping for the kernel and install it before
1317 	 * switching to the new pagetables.
1318 	 */
1319 	regtblrover =
1320 		((regtblptd & ~SRMMU_TETYPE) << SRMMU_PPNPASHIFT) +
1321 		(VA_VREG(KERNBASE)+1) * sizeof(long);	/* kernel only */
1322 
1323 	for (i = VA_VREG(KERNBASE) + 1; i < SRMMU_L1SIZE;
1324 	     i++, regtblrover += sizeof(long)) {
1325 
1326 		/* The region we're dealing with */
1327 		rp = &kpmap->pm_regmap[i];
1328 
1329 		te = srmmu_bypass_read(regtblrover);
1330 		switch(te & SRMMU_TETYPE) {
1331 		case SRMMU_TEINVALID:
1332 			break;
1333 
1334 		case SRMMU_TEPTE:
1335 #ifdef DEBUG
1336 			printf("mmu_setup4m_L1: "
1337 			       "converting region 0x%x from L1->L3\n", i);
1338 #endif
1339 			/*
1340 			 * This region entry covers 64MB of memory -- or
1341 			 * (NSEGRG * NPTESG) pages -- which we must convert
1342 			 * into a 3-level description.
1343 			 */
1344 
1345 			for (j = 0; j < SRMMU_L2SIZE; j++) {
1346 				struct segmap *sp = &rp->rg_segmap[j];
1347 
1348 				for (k = 0; k < SRMMU_L3SIZE; k++) {
1349 					sp->sg_npte++;
1350 					setpgt4m(&sp->sg_pte[k],
1351 						(te & SRMMU_L1PPNMASK) |
1352 						(j << SRMMU_L2PPNSHFT) |
1353 						(k << SRMMU_L3PPNSHFT) |
1354 						(te & SRMMU_PGBITSMSK) |
1355 						((te & SRMMU_PROT_MASK) |
1356 						 PPROT_U2S_OMASK) |
1357 						SRMMU_TEPTE);
1358 				}
1359 			}
1360 			break;
1361 
1362 		case SRMMU_TEPTD:
1363 			mmu_setup4m_L2(te, rp);
1364 			break;
1365 
1366 		default:
1367 			panic("mmu_setup4m_L1: unknown pagetable entry type");
1368 		}
1369 	}
1370 }
1371 
1372 void
1373 mmu_setup4m_L2(segtblptd, rp)
1374 	int segtblptd;
1375 	struct regmap *rp;
1376 {
1377 	unsigned int segtblrover;
1378 	int i, k;
1379 	unsigned int te;
1380 	struct segmap *sp;
1381 
1382 	segtblrover = (segtblptd & ~SRMMU_TETYPE) << SRMMU_PPNPASHIFT;
1383 	for (i = 0; i < SRMMU_L2SIZE; i++, segtblrover += sizeof(long)) {
1384 
1385 		sp = &rp->rg_segmap[i];
1386 
1387 		te = srmmu_bypass_read(segtblrover);
1388 		switch(te & SRMMU_TETYPE) {
1389 		case SRMMU_TEINVALID:
1390 			break;
1391 
1392 		case SRMMU_TEPTE:
1393 #ifdef DEBUG
1394 			printf("mmu_setup4m_L2: converting L2 entry at segment 0x%x to L3\n",i);
1395 #endif
1396 			/*
1397 			 * This segment entry covers 256KB of memory -- or
1398 			 * (NPTESG) pages -- which we must convert
1399 			 * into a 3-level description.
1400 			 */
1401 			for (k = 0; k < SRMMU_L3SIZE; k++) {
1402 				sp->sg_npte++;
1403 				setpgt4m(&sp->sg_pte[k],
1404 					(te & SRMMU_L1PPNMASK) |
1405 					(te & SRMMU_L2PPNMASK) |
1406 					(k << SRMMU_L3PPNSHFT) |
1407 					(te & SRMMU_PGBITSMSK) |
1408 					((te & SRMMU_PROT_MASK) |
1409 					 PPROT_U2S_OMASK) |
1410 					SRMMU_TEPTE);
1411 			}
1412 			break;
1413 
1414 		case SRMMU_TEPTD:
1415 			mmu_setup4m_L3(te, sp);
1416 			break;
1417 
1418 		default:
1419 			panic("mmu_setup4m_L2: unknown pagetable entry type");
1420 		}
1421 	}
1422 }
1423 
1424 void
1425 mmu_setup4m_L3(pagtblptd, sp)
1426 	int pagtblptd;
1427 	struct segmap *sp;
1428 {
1429 	unsigned int pagtblrover;
1430 	int i;
1431 	unsigned int te;
1432 
1433 	pagtblrover = (pagtblptd & ~SRMMU_TETYPE) << SRMMU_PPNPASHIFT;
1434 	for (i = 0; i < SRMMU_L3SIZE; i++, pagtblrover += sizeof(long)) {
1435 		te = srmmu_bypass_read(pagtblrover);
1436 		switch(te & SRMMU_TETYPE) {
1437 		case SRMMU_TEINVALID:
1438 			break;
1439 		case SRMMU_TEPTE:
1440 			sp->sg_npte++;
1441 			setpgt4m(&sp->sg_pte[i], te | PPROT_U2S_OMASK);
1442 			break;
1443 		case SRMMU_TEPTD:
1444 			panic("mmu_setup4m_L3: PTD found in L3 page table");
1445 		default:
1446 			panic("mmu_setup4m_L3: unknown pagetable entry type");
1447 		}
1448 	}
1449 }
1450 #endif /* defined SUN4M */
1451 
1452 /*----------------------------------------------------------------*/
1453 
1454 /*
1455  * MMU management.
1456  */
1457 struct mmuentry *me_alloc __P((struct mmuhd *, struct pmap *, int, int));
1458 void		me_free __P((struct pmap *, u_int));
1459 struct mmuentry	*region_alloc __P((struct mmuhd *, struct pmap *, int));
1460 void		region_free __P((struct pmap *, u_int));
1461 
1462 /*
1463  * Change contexts.  We need the old context number as well as the new
1464  * one.  If the context is changing, we must write all user windows
1465  * first, lest an interrupt cause them to be written to the (other)
1466  * user whose context we set here.
1467  */
1468 #define	CHANGE_CONTEXTS(old, new) \
1469 	if ((old) != (new)) { \
1470 		write_user_windows(); \
1471 		setcontext(new); \
1472 	}
1473 
1474 #if defined(SUN4) || defined(SUN4C) /* This is old sun MMU stuff */
1475 /*
1476  * Allocate an MMU entry (i.e., a PMEG).
1477  * If necessary, steal one from someone else.
1478  * Put it on the tail of the given queue
1479  * (which is either the LRU list or the locked list).
1480  * The locked list is not actually ordered, but this is easiest.
1481  * Also put it on the given (new) pmap's chain,
1482  * enter its pmeg number into that pmap's segmap,
1483  * and store the pmeg's new virtual segment number (me->me_vseg).
1484  *
1485  * This routine is large and complicated, but it must be fast
1486  * since it implements the dynamic allocation of MMU entries.
1487  */
1488 struct mmuentry *
1489 me_alloc(mh, newpm, newvreg, newvseg)
1490 	struct mmuhd *mh;
1491 	struct pmap *newpm;
1492 	int newvreg, newvseg;
1493 {
1494 	struct mmuentry *me;
1495 	struct pmap *pm;
1496 	int i, va, *pte, tpte;
1497 	int ctx;
1498 	struct regmap *rp;
1499 	struct segmap *sp;
1500 
1501 	/* try free list first */
1502 	if ((me = segm_freelist.tqh_first) != NULL) {
1503 		TAILQ_REMOVE(&segm_freelist, me, me_list);
1504 #ifdef DEBUG
1505 		if (me->me_pmap != NULL)
1506 			panic("me_alloc: freelist entry has pmap");
1507 		if (pmapdebug & PDB_MMU_ALLOC)
1508 			printf("me_alloc: got pmeg %d\n", me->me_cookie);
1509 #endif
1510 		TAILQ_INSERT_TAIL(mh, me, me_list);
1511 
1512 		/* onto on pmap chain; pmap is already locked, if needed */
1513 		TAILQ_INSERT_TAIL(&newpm->pm_seglist, me, me_pmchain);
1514 #ifdef DIAGNOSTIC
1515 		pmap_stats.ps_npmeg_free--;
1516 		if (mh == &segm_locked)
1517 			pmap_stats.ps_npmeg_locked++;
1518 		else
1519 			pmap_stats.ps_npmeg_lru++;
1520 #endif
1521 
1522 		/* into pmap segment table, with backpointers */
1523 		newpm->pm_regmap[newvreg].rg_segmap[newvseg].sg_pmeg = me->me_cookie;
1524 		me->me_pmap = newpm;
1525 		me->me_vseg = newvseg;
1526 		me->me_vreg = newvreg;
1527 
1528 		return (me);
1529 	}
1530 
1531 	/* no luck, take head of LRU list */
1532 	if ((me = segm_lru.tqh_first) == NULL)
1533 		panic("me_alloc: all pmegs gone");
1534 
1535 	pm = me->me_pmap;
1536 #ifdef DEBUG
1537 	if (pmapdebug & (PDB_MMU_ALLOC | PDB_MMU_STEAL))
1538 		printf("me_alloc: stealing pmeg 0x%x from pmap %p\n",
1539 		    me->me_cookie, pm);
1540 #endif
1541 	/*
1542 	 * Remove from LRU list, and insert at end of new list
1543 	 * (probably the LRU list again, but so what?).
1544 	 */
1545 	TAILQ_REMOVE(&segm_lru, me, me_list);
1546 	TAILQ_INSERT_TAIL(mh, me, me_list);
1547 
1548 #ifdef DIAGNOSTIC
1549 	if (mh == &segm_locked) {
1550 		pmap_stats.ps_npmeg_lru--;
1551 		pmap_stats.ps_npmeg_locked++;
1552 	}
1553 #endif
1554 
1555 	rp = &pm->pm_regmap[me->me_vreg];
1556 	sp = &rp->rg_segmap[me->me_vseg];
1557 	pte = sp->sg_pte;
1558 
1559 	/*
1560 	 * The PMEG must be mapped into some context so that we can
1561 	 * read its PTEs.  Use its current context if it has one;
1562 	 * if not, and since context 0 is reserved for the kernel,
1563 	 * the simplest method is to switch to 0 and map the PMEG
1564 	 * to virtual address 0---which, being a user space address,
1565 	 * is by definition not in use.
1566 	 *
1567 	 * XXX for ncpus>1 must use per-cpu VA?
1568 	 * XXX do not have to flush cache immediately
1569 	 */
1570 	ctx = getcontext4();
1571 	if (CTX_USABLE(pm,rp)) {
1572 		CHANGE_CONTEXTS(ctx, pm->pm_ctxnum);
1573 		cache_flush_segment(me->me_vreg, me->me_vseg);
1574 		va = VSTOVA(me->me_vreg,me->me_vseg);
1575 	} else {
1576 		CHANGE_CONTEXTS(ctx, 0);
1577 		if (HASSUN4_MMU3L)
1578 			setregmap(0, tregion);
1579 		setsegmap(0, me->me_cookie);
1580 		/*
1581 		 * No cache flush needed: it happened earlier when
1582 		 * the old context was taken.
1583 		 */
1584 		va = 0;
1585 	}
1586 
1587 	/*
1588 	 * Record reference and modify bits for each page,
1589 	 * and copy PTEs into kernel memory so that they can
1590 	 * be reloaded later.
1591 	 */
1592 	i = NPTESG;
1593 	do {
1594 		tpte = getpte4(va);
1595 		if ((tpte & (PG_V | PG_TYPE)) == (PG_V | PG_OBMEM)) {
1596 			u_int pfn = tpte & PG_PFNUM;
1597 			struct pvlist *pv;
1598 			if ((pv = pvhead(pfn)) != NULL)
1599 				pv->pv_flags |= MR4_4C(tpte);
1600 		}
1601 		*pte++ = tpte & ~(PG_U|PG_M);
1602 		va += NBPG;
1603 	} while (--i > 0);
1604 
1605 	/* update segment tables */
1606 	simple_lock(&pm->pm_lock); /* what if other cpu takes mmuentry ?? */
1607 	if (CTX_USABLE(pm,rp))
1608 		setsegmap(VSTOVA(me->me_vreg,me->me_vseg), seginval);
1609 	sp->sg_pmeg = seginval;
1610 
1611 	/* off old pmap chain */
1612 	TAILQ_REMOVE(&pm->pm_seglist, me, me_pmchain);
1613 	simple_unlock(&pm->pm_lock);
1614 	setcontext4(ctx);
1615 
1616 	/* onto new pmap chain; new pmap is already locked, if needed */
1617 	TAILQ_INSERT_TAIL(&newpm->pm_seglist, me, me_pmchain);
1618 
1619 	/* into new segment table, with backpointers */
1620 	newpm->pm_regmap[newvreg].rg_segmap[newvseg].sg_pmeg = me->me_cookie;
1621 	me->me_pmap = newpm;
1622 	me->me_vseg = newvseg;
1623 	me->me_vreg = newvreg;
1624 
1625 	return (me);
1626 }
1627 
1628 /*
1629  * Free an MMU entry.
1630  *
1631  * Assumes the corresponding pmap is already locked.
1632  * Does NOT flush cache, but does record ref and mod bits.
1633  * The rest of each PTE is discarded.
1634  * CALLER MUST SET CONTEXT to pm->pm_ctxnum (if pmap has
1635  * a context) or to 0 (if not).  Caller must also update
1636  * pm->pm_segmap and (possibly) the hardware.
1637  */
1638 void
1639 me_free(pm, pmeg)
1640 	struct pmap *pm;
1641 	u_int pmeg;
1642 {
1643 	struct mmuentry *me = &mmusegments[pmeg];
1644 	int i, va, tpte;
1645 	int vr;
1646 	struct regmap *rp;
1647 
1648 	vr = me->me_vreg;
1649 
1650 #ifdef DEBUG
1651 	if (pmapdebug & PDB_MMU_ALLOC)
1652 		printf("me_free: freeing pmeg %d from pmap %p\n",
1653 		    me->me_cookie, pm);
1654 	if (me->me_cookie != pmeg)
1655 		panic("me_free: wrong mmuentry");
1656 	if (pm != me->me_pmap)
1657 		panic("me_free: pm != me_pmap");
1658 #endif
1659 
1660 	rp = &pm->pm_regmap[vr];
1661 
1662 	/* just like me_alloc, but no cache flush, and context already set */
1663 	if (CTX_USABLE(pm,rp)) {
1664 		va = VSTOVA(vr,me->me_vseg);
1665 	} else {
1666 #ifdef DEBUG
1667 if (getcontext4() != 0) panic("me_free: ctx != 0");
1668 #endif
1669 		if (HASSUN4_MMU3L)
1670 			setregmap(0, tregion);
1671 		setsegmap(0, me->me_cookie);
1672 		va = 0;
1673 	}
1674 	i = NPTESG;
1675 	do {
1676 		tpte = getpte4(va);
1677 		if ((tpte & (PG_V | PG_TYPE)) == (PG_V | PG_OBMEM)) {
1678 			u_int pfn = tpte & PG_PFNUM;
1679 			struct pvlist *pv;
1680 			if ((pv = pvhead(pfn)) != NULL)
1681 				pv->pv_flags |= MR4_4C(tpte);
1682 		}
1683 		va += NBPG;
1684 	} while (--i > 0);
1685 
1686 	/* take mmu entry off pmap chain */
1687 	TAILQ_REMOVE(&pm->pm_seglist, me, me_pmchain);
1688 	/* ... and remove from segment map */
1689 	if (rp->rg_segmap == NULL)
1690 		panic("me_free: no segments in pmap");
1691 	rp->rg_segmap[me->me_vseg].sg_pmeg = seginval;
1692 
1693 	/* off LRU or lock chain */
1694 	if (pm == pmap_kernel()) {
1695 		TAILQ_REMOVE(&segm_locked, me, me_list);
1696 #ifdef DIAGNOSTIC
1697 		pmap_stats.ps_npmeg_locked--;
1698 #endif
1699 	} else {
1700 		TAILQ_REMOVE(&segm_lru, me, me_list);
1701 #ifdef DIAGNOSTIC
1702 		pmap_stats.ps_npmeg_lru--;
1703 #endif
1704 	}
1705 
1706 	/* no associated pmap; on free list */
1707 	me->me_pmap = NULL;
1708 	TAILQ_INSERT_TAIL(&segm_freelist, me, me_list);
1709 #ifdef DIAGNOSTIC
1710 	pmap_stats.ps_npmeg_free++;
1711 #endif
1712 }
1713 
1714 #if defined(SUN4_MMU3L)
1715 
1716 /* XXX - Merge with segm_alloc/segm_free ? */
1717 
1718 struct mmuentry *
1719 region_alloc(mh, newpm, newvr)
1720 	struct mmuhd *mh;
1721 	struct pmap *newpm;
1722 	int newvr;
1723 {
1724 	struct mmuentry *me;
1725 	struct pmap *pm;
1726 	int ctx;
1727 	struct regmap *rp;
1728 
1729 	/* try free list first */
1730 	if ((me = region_freelist.tqh_first) != NULL) {
1731 		TAILQ_REMOVE(&region_freelist, me, me_list);
1732 #ifdef DEBUG
1733 		if (me->me_pmap != NULL)
1734 			panic("region_alloc: freelist entry has pmap");
1735 		if (pmapdebug & PDB_MMUREG_ALLOC)
1736 			printf("region_alloc: got smeg 0x%x\n", me->me_cookie);
1737 #endif
1738 		TAILQ_INSERT_TAIL(mh, me, me_list);
1739 
1740 		/* onto on pmap chain; pmap is already locked, if needed */
1741 		TAILQ_INSERT_TAIL(&newpm->pm_reglist, me, me_pmchain);
1742 
1743 		/* into pmap segment table, with backpointers */
1744 		newpm->pm_regmap[newvr].rg_smeg = me->me_cookie;
1745 		me->me_pmap = newpm;
1746 		me->me_vreg = newvr;
1747 
1748 		return (me);
1749 	}
1750 
1751 	/* no luck, take head of LRU list */
1752 	if ((me = region_lru.tqh_first) == NULL)
1753 		panic("region_alloc: all smegs gone");
1754 
1755 	pm = me->me_pmap;
1756 	if (pm == NULL)
1757 		panic("region_alloc: LRU entry has no pmap");
1758 	if (pm == pmap_kernel())
1759 		panic("region_alloc: stealing from kernel");
1760 #ifdef DEBUG
1761 	if (pmapdebug & (PDB_MMUREG_ALLOC | PDB_MMUREG_STEAL))
1762 		printf("region_alloc: stealing smeg 0x%x from pmap %p\n",
1763 		    me->me_cookie, pm);
1764 #endif
1765 	/*
1766 	 * Remove from LRU list, and insert at end of new list
1767 	 * (probably the LRU list again, but so what?).
1768 	 */
1769 	TAILQ_REMOVE(&region_lru, me, me_list);
1770 	TAILQ_INSERT_TAIL(mh, me, me_list);
1771 
1772 	rp = &pm->pm_regmap[me->me_vreg];
1773 	ctx = getcontext4();
1774 	if (pm->pm_ctx) {
1775 		CHANGE_CONTEXTS(ctx, pm->pm_ctxnum);
1776 		cache_flush_region(me->me_vreg);
1777 	}
1778 
1779 	/* update region tables */
1780 	simple_lock(&pm->pm_lock); /* what if other cpu takes mmuentry ?? */
1781 	if (pm->pm_ctx)
1782 		setregmap(VRTOVA(me->me_vreg), reginval);
1783 	rp->rg_smeg = reginval;
1784 
1785 	/* off old pmap chain */
1786 	TAILQ_REMOVE(&pm->pm_reglist, me, me_pmchain);
1787 	simple_unlock(&pm->pm_lock);
1788 	setcontext4(ctx);	/* done with old context */
1789 
1790 	/* onto new pmap chain; new pmap is already locked, if needed */
1791 	TAILQ_INSERT_TAIL(&newpm->pm_reglist, me, me_pmchain);
1792 
1793 	/* into new segment table, with backpointers */
1794 	newpm->pm_regmap[newvr].rg_smeg = me->me_cookie;
1795 	me->me_pmap = newpm;
1796 	me->me_vreg = newvr;
1797 
1798 	return (me);
1799 }
1800 
1801 /*
1802  * Free an MMU entry.
1803  *
1804  * Assumes the corresponding pmap is already locked.
1805  * Does NOT flush cache. ???
1806  * CALLER MUST SET CONTEXT to pm->pm_ctxnum (if pmap has
1807  * a context) or to 0 (if not).  Caller must also update
1808  * pm->pm_regmap and (possibly) the hardware.
1809  */
1810 void
1811 region_free(pm, smeg)
1812 	struct pmap *pm;
1813 	u_int smeg;
1814 {
1815 	struct mmuentry *me = &mmuregions[smeg];
1816 
1817 #ifdef DEBUG
1818 	if (pmapdebug & PDB_MMUREG_ALLOC)
1819 		printf("region_free: freeing smeg 0x%x from pmap %p\n",
1820 		    me->me_cookie, pm);
1821 	if (me->me_cookie != smeg)
1822 		panic("region_free: wrong mmuentry");
1823 	if (pm != me->me_pmap)
1824 		panic("region_free: pm != me_pmap");
1825 #endif
1826 
1827 	if (pm->pm_ctx)
1828 		cache_flush_region(me->me_vreg);
1829 
1830 	/* take mmu entry off pmap chain */
1831 	TAILQ_REMOVE(&pm->pm_reglist, me, me_pmchain);
1832 	/* ... and remove from segment map */
1833 	pm->pm_regmap[me->me_vreg].rg_smeg = reginval;
1834 
1835 	/* off LRU or lock chain */
1836 	if (pm == pmap_kernel()) {
1837 		TAILQ_REMOVE(&region_locked, me, me_list);
1838 	} else {
1839 		TAILQ_REMOVE(&region_lru, me, me_list);
1840 	}
1841 
1842 	/* no associated pmap; on free list */
1843 	me->me_pmap = NULL;
1844 	TAILQ_INSERT_TAIL(&region_freelist, me, me_list);
1845 }
1846 #endif
1847 
1848 /*
1849  * `Page in' (load or inspect) an MMU entry; called on page faults.
1850  * Returns 1 if we reloaded the segment, -1 if the segment was
1851  * already loaded and the page was marked valid (in which case the
1852  * fault must be a bus error or something), or 0 (segment loaded but
1853  * PTE not valid, or segment not loaded at all).
1854  */
1855 int
1856 mmu_pagein(pm, va, prot)
1857 	struct pmap *pm;
1858 	vaddr_t va;
1859 	int prot;
1860 {
1861 	int *pte;
1862 	int vr, vs, pmeg, i, s, bits;
1863 	struct regmap *rp;
1864 	struct segmap *sp;
1865 
1866 	if (va >= (unsigned long)KERNBASE)
1867 		return (0);
1868 
1869 	if (prot != VM_PROT_NONE)
1870 		bits = PG_V | ((prot & VM_PROT_WRITE) ? PG_W : 0);
1871 	else
1872 		bits = 0;
1873 
1874 	vr = VA_VREG(va);
1875 	vs = VA_VSEG(va);
1876 	rp = &pm->pm_regmap[vr];
1877 #ifdef DEBUG
1878 	if (pm == pmap_kernel())
1879 	printf("mmu_pagein: kernel wants map at va 0x%lx, vr %d, vs %d\n",
1880 		(u_long)va, vr, vs);
1881 #endif
1882 
1883 	/* return 0 if we have no PMEGs to load */
1884 	if (rp->rg_segmap == NULL)
1885 		return (0);
1886 
1887 #if defined(SUN4_MMU3L)
1888 	if (HASSUN4_MMU3L && rp->rg_smeg == reginval) {
1889 		smeg_t smeg;
1890 		unsigned int tva = VA_ROUNDDOWNTOREG(va);
1891 		struct segmap *sp = rp->rg_segmap;
1892 
1893 		s = splvm();		/* paranoid */
1894 		smeg = region_alloc(&region_lru, pm, vr)->me_cookie;
1895 		setregmap(tva, smeg);
1896 		i = NSEGRG;
1897 		do {
1898 			setsegmap(tva, sp++->sg_pmeg);
1899 			tva += NBPSG;
1900 		} while (--i > 0);
1901 		splx(s);
1902 	}
1903 #endif
1904 	sp = &rp->rg_segmap[vs];
1905 
1906 	/* return 0 if we have no PTEs to load */
1907 	if ((pte = sp->sg_pte) == NULL)
1908 		return (0);
1909 
1910 	/* return -1 if the fault is `hard', 0 if not */
1911 	if (sp->sg_pmeg != seginval)
1912 		return (bits && (getpte4(va) & bits) == bits ? -1 : 0);
1913 
1914 	/* reload segment: write PTEs into a new LRU entry */
1915 	va = VA_ROUNDDOWNTOSEG(va);
1916 	s = splvm();		/* paranoid */
1917 	pmeg = me_alloc(&segm_lru, pm, vr, vs)->me_cookie;
1918 	setsegmap(va, pmeg);
1919 	i = NPTESG;
1920 	do {
1921 		setpte4(va, *pte++);
1922 		va += NBPG;
1923 	} while (--i > 0);
1924 	splx(s);
1925 	return (1);
1926 }
1927 #endif /* defined SUN4 or SUN4C */
1928 
1929 /*
1930  * Allocate a context.  If necessary, steal one from someone else.
1931  * Changes hardware context number and loads segment map.
1932  *
1933  * This routine is only ever called from locore.s just after it has
1934  * saved away the previous process, so there are no active user windows.
1935  */
1936 void
1937 ctx_alloc(pm)
1938 	struct pmap *pm;
1939 {
1940 	union ctxinfo *c;
1941 	int s, cnum, i, doflush;
1942 	struct regmap *rp;
1943 	int gap_start, gap_end;
1944 	vaddr_t va;
1945 
1946 /*XXX-GCC!*/gap_start=gap_end=0;
1947 #ifdef DEBUG
1948 	if (pm->pm_ctx)
1949 		panic("ctx_alloc pm_ctx");
1950 	if (pmapdebug & PDB_CTX_ALLOC)
1951 		printf("ctx_alloc(%p)\n", pm);
1952 #endif
1953 	if (CPU_ISSUN4OR4C) {
1954 		gap_start = pm->pm_gap_start;
1955 		gap_end = pm->pm_gap_end;
1956 	}
1957 
1958 	s = splvm();
1959 	simple_lock(&ctx_lock);
1960 	if ((c = ctx_freelist) != NULL) {
1961 		ctx_freelist = c->c_nextfree;
1962 		cnum = c - ctxinfo;
1963 		doflush = 0;
1964 	} else {
1965 		if ((ctx_kick += ctx_kickdir) >= ncontext) {
1966 			ctx_kick = ncontext - 1;
1967 			ctx_kickdir = -1;
1968 		} else if (ctx_kick < 1) {
1969 			ctx_kick = 1;
1970 			ctx_kickdir = 1;
1971 		}
1972 		c = &ctxinfo[cnum = ctx_kick];
1973 #ifdef DEBUG
1974 		if (c->c_pmap == NULL)
1975 			panic("ctx_alloc cu_pmap");
1976 		if (pmapdebug & (PDB_CTX_ALLOC | PDB_CTX_STEAL))
1977 			printf("ctx_alloc: steal context %d from %p\n",
1978 			    cnum, c->c_pmap);
1979 #endif
1980 		c->c_pmap->pm_ctx = NULL;
1981 		doflush = (CACHEINFO.c_vactype != VAC_NONE);
1982 		if (CPU_ISSUN4OR4C) {
1983 			if (gap_start < c->c_pmap->pm_gap_start)
1984 				gap_start = c->c_pmap->pm_gap_start;
1985 			if (gap_end > c->c_pmap->pm_gap_end)
1986 				gap_end = c->c_pmap->pm_gap_end;
1987 		}
1988 	}
1989 	simple_unlock(&ctx_lock);
1990 
1991 	c->c_pmap = pm;
1992 	pm->pm_ctx = c;
1993 	pm->pm_ctxnum = cnum;
1994 
1995 	if (CPU_ISSUN4OR4C) {
1996 		/*
1997 		 * Write pmap's region (3-level MMU) or segment table into
1998 		 * the MMU.
1999 		 *
2000 		 * Only write those entries that actually map something in
2001 		 * this context by maintaining a pair of region numbers in
2002 		 * between which the pmap has no valid mappings.
2003 		 *
2004 		 * If a context was just allocated from the free list, trust
2005 		 * that all its pmeg numbers are `seginval'. We make sure this
2006 		 * is the case initially in pmap_bootstrap(). Otherwise, the
2007 		 * context was freed by calling ctx_free() in pmap_release(),
2008 		 * which in turn is supposedly called only when all mappings
2009 		 * have been removed.
2010 		 *
2011 		 * On the other hand, if the context had to be stolen from
2012 		 * another pmap, we possibly shrink the gap to be the
2013 		 * disjuction of the new and the previous map.
2014 		 */
2015 
2016 		setcontext4(cnum);
2017 		splx(s);
2018 		if (doflush)
2019 			cache_flush_context();
2020 
2021 		rp = pm->pm_regmap;
2022 		for (va = 0, i = NUREG; --i >= 0; ) {
2023 			if (VA_VREG(va) >= gap_start) {
2024 				va = VRTOVA(gap_end);
2025 				i -= gap_end - gap_start;
2026 				rp += gap_end - gap_start;
2027 				if (i < 0)
2028 					break;
2029 				/* mustn't re-enter this branch */
2030 				gap_start = NUREG;
2031 			}
2032 			if (HASSUN4_MMU3L) {
2033 				setregmap(va, rp++->rg_smeg);
2034 				va += NBPRG;
2035 			} else {
2036 				int j;
2037 				struct segmap *sp = rp->rg_segmap;
2038 				for (j = NSEGRG; --j >= 0; va += NBPSG)
2039 					setsegmap(va,
2040 						  sp?sp++->sg_pmeg:seginval);
2041 				rp++;
2042 			}
2043 		}
2044 
2045 	} else if (CPU_ISSUN4M) {
2046 
2047 #if defined(SUN4M)
2048 		/*
2049 		 * Reload page and context tables to activate the page tables
2050 		 * for this context.
2051 		 *
2052 		 * The gap stuff isn't really needed in the sun4m architecture,
2053 		 * since we don't have to worry about excessive mappings (all
2054 		 * mappings exist since the page tables must be complete for
2055 		 * the mmu to be happy).
2056 		 *
2057 		 * If a context was just allocated from the free list, trust
2058 		 * that all of its mmu-edible page tables are zeroed out
2059 		 * (except for those associated with the kernel). We make
2060 		 * sure this is the case initially in pmap_bootstrap() and
2061 		 * pmap_init() (?).
2062 		 * Otherwise, the context was freed by calling ctx_free() in
2063 		 * pmap_release(), which in turn is supposedly called only
2064 		 * when all mappings have been removed.
2065 		 *
2066 		 * XXX: Do we have to flush cache after reloading ctx tbl?
2067 		 */
2068 
2069 		/* Do any cache flush needed on context switch */
2070 		(*cpuinfo.pure_vcache_flush)();
2071 
2072 		/*
2073 		 * We need to flush the cache only when stealing a context
2074 		 * from another pmap. In that case it's Ok to switch the
2075 		 * context and leave it set, since it the context table
2076 		 * will have a valid region table entry for this context
2077 		 * number.
2078 		 *
2079 		 * Otherwise, we switch to the new context after loading
2080 		 * the context table entry with the new pmap's region.
2081 		 */
2082 		if (doflush) {
2083 			setcontext4m(cnum);
2084 			cache_flush_context();
2085 		}
2086 
2087 		/*
2088 		 * The context allocated to a process is the same on all CPUs.
2089 		 * Here we install the per-CPU region table in each CPU's
2090 		 * context table slot.
2091 		 *
2092 		 * Note on multi-threaded processes: a context must remain
2093 		 * valid as long as any thread is still running on a cpu.
2094 		 */
2095 		simple_lock(&pm->pm_lock);
2096 #if defined(MULTIPROCESSOR)
2097 		for (i = 0; i < ncpu; i++)
2098 #else
2099 		i = 0;
2100 #endif
2101 		{
2102 			struct cpu_info *cpi = cpus[i];
2103 #if defined(MULTIPROCESSOR)
2104 			if (cpi == NULL)
2105 				continue;
2106 #endif
2107 			setpgt4m(&cpi->ctx_tbl[cnum],
2108 				 (pm->pm_reg_ptps_pa[i] >> SRMMU_PPNPASHIFT) |
2109 					SRMMU_TEPTD);
2110 		}
2111 		simple_unlock(&pm->pm_lock);
2112 
2113 		/* Set context if not yet done above to flush the cache */
2114 		if (!doflush)
2115 			setcontext4m(cnum);
2116 
2117 		tlb_flush_context(); /* remove any remnant garbage from tlb */
2118 #endif
2119 		splx(s);
2120 	}
2121 }
2122 
2123 /*
2124  * Give away a context.  Flushes cache and sets current context to 0.
2125  */
2126 void
2127 ctx_free(pm)
2128 	struct pmap *pm;
2129 {
2130 	union ctxinfo *c;
2131 	int newc, oldc;
2132 
2133 	c = pm->pm_ctx;
2134 	pm->pm_ctx = NULL;
2135 	oldc = getcontext();
2136 	if (CACHEINFO.c_vactype != VAC_NONE) {
2137 		/* Do any cache flush needed on context switch */
2138 		(*cpuinfo.pure_vcache_flush)();
2139 		newc = pm->pm_ctxnum;
2140 		CHANGE_CONTEXTS(oldc, newc);
2141 		cache_flush_context();
2142 #if defined(SUN4M)
2143 		if (CPU_ISSUN4M)
2144 			tlb_flush_context();
2145 #endif
2146 	} else {
2147 #if defined(SUN4M)
2148 		if (CPU_ISSUN4M) {
2149 			/* Do any cache flush needed on context switch */
2150 			(*cpuinfo.pure_vcache_flush)();
2151 			newc = pm->pm_ctxnum;
2152 			CHANGE_CONTEXTS(oldc, newc);
2153 			tlb_flush_context();
2154 		}
2155 #endif
2156 	}
2157 	setcontext(oldc);
2158 
2159 	simple_lock(&ctx_lock);
2160 	c->c_nextfree = ctx_freelist;
2161 	ctx_freelist = c;
2162 	simple_unlock(&ctx_lock);
2163 }
2164 
2165 
2166 /*----------------------------------------------------------------*/
2167 
2168 /*
2169  * pvlist functions.
2170  */
2171 
2172 /*
2173  * Walk the given pv list, and for each PTE, set or clear some bits
2174  * (e.g., PG_W or PG_NC).
2175  *
2176  * This routine flushes the cache for any page whose PTE changes,
2177  * as long as the process has a context; this is overly conservative.
2178  * It also copies ref and mod bits to the pvlist, on the theory that
2179  * this might save work later.  (XXX should test this theory)
2180  */
2181 
2182 #if defined(SUN4) || defined(SUN4C)
2183 
2184 void
2185 pv_changepte4_4c(pv0, bis, bic)
2186 	struct pvlist *pv0;
2187 	int bis, bic;
2188 {
2189 	int *pte;
2190 	struct pvlist *pv;
2191 	struct pmap *pm;
2192 	int va, vr, vs;
2193 	int ctx, s;
2194 	struct regmap *rp;
2195 	struct segmap *sp;
2196 
2197 	write_user_windows();		/* paranoid? */
2198 	s = splvm();			/* paranoid? */
2199 	if (pv0->pv_pmap == NULL) {
2200 		splx(s);
2201 		return;
2202 	}
2203 	ctx = getcontext4();
2204 	for (pv = pv0; pv != NULL; pv = pv->pv_next) {
2205 		pm = pv->pv_pmap;
2206 		va = pv->pv_va;
2207 		vr = VA_VREG(va);
2208 		vs = VA_VSEG(va);
2209 		rp = &pm->pm_regmap[vr];
2210 		sp = &rp->rg_segmap[vs];
2211 		pte = sp->sg_pte;
2212 
2213 		if (sp->sg_pmeg == seginval) {
2214 			/* not in hardware: just fix software copy */
2215 			pte += VA_VPG(va);
2216 			*pte = (*pte | bis) & ~bic;
2217 		} else {
2218 			int tpte;
2219 
2220 			/* in hardware: fix hardware copy */
2221 			if (CTX_USABLE(pm,rp)) {
2222 				setcontext4(pm->pm_ctxnum);
2223 				/* XXX should flush only when necessary */
2224 				tpte = getpte4(va);
2225 				/*
2226 				 * XXX: always flush cache; conservative, but
2227 				 * needed to invalidate cache tag protection
2228 				 * bits and when disabling caching.
2229 				 */
2230 				cache_flush_page(va);
2231 			} else {
2232 				/* XXX per-cpu va? */
2233 				setcontext4(0);
2234 				if (HASSUN4_MMU3L)
2235 					setregmap(0, tregion);
2236 				setsegmap(0, sp->sg_pmeg);
2237 				va = VA_VPG(va) << PGSHIFT;
2238 				tpte = getpte4(va);
2239 			}
2240 			if (tpte & PG_V)
2241 				pv0->pv_flags |= MR4_4C(tpte);
2242 			tpte = (tpte | bis) & ~bic;
2243 			setpte4(va, tpte);
2244 			if (pte != NULL)	/* update software copy */
2245 				pte[VA_VPG(va)] = tpte;
2246 		}
2247 	}
2248 	setcontext4(ctx);
2249 	splx(s);
2250 }
2251 
2252 /*
2253  * Sync ref and mod bits in pvlist (turns off same in hardware PTEs).
2254  * Returns the new flags.
2255  *
2256  * This is just like pv_changepte, but we never add or remove bits,
2257  * hence never need to adjust software copies.
2258  */
2259 int
2260 pv_syncflags4_4c(pv0)
2261 	struct pvlist *pv0;
2262 {
2263 	struct pvlist *pv;
2264 	struct pmap *pm;
2265 	int tpte, va, vr, vs, pmeg, flags;
2266 	int ctx, s;
2267 	struct regmap *rp;
2268 	struct segmap *sp;
2269 
2270 	s = splvm();			/* paranoid? */
2271 	if (pv0->pv_pmap == NULL) {	/* paranoid */
2272 		splx(s);
2273 		return (0);
2274 	}
2275 	ctx = getcontext4();
2276 	flags = pv0->pv_flags;
2277 	for (pv = pv0; pv != NULL; pv = pv->pv_next) {
2278 		pm = pv->pv_pmap;
2279 		va = pv->pv_va;
2280 		vr = VA_VREG(va);
2281 		vs = VA_VSEG(va);
2282 		rp = &pm->pm_regmap[vr];
2283 		sp = &rp->rg_segmap[vs];
2284 		if ((pmeg = sp->sg_pmeg) == seginval)
2285 			continue;
2286 		if (CTX_USABLE(pm,rp)) {
2287 			setcontext4(pm->pm_ctxnum);
2288 			/* XXX should flush only when necessary */
2289 			tpte = getpte4(va);
2290 			if (tpte & PG_M)
2291 				cache_flush_page(va);
2292 		} else {
2293 			/* XXX per-cpu va? */
2294 			setcontext4(0);
2295 			if (HASSUN4_MMU3L)
2296 				setregmap(0, tregion);
2297 			setsegmap(0, pmeg);
2298 			va = VA_VPG(va) << PGSHIFT;
2299 			tpte = getpte4(va);
2300 		}
2301 		if (tpte & (PG_M|PG_U) && tpte & PG_V) {
2302 			flags |= MR4_4C(tpte);
2303 			tpte &= ~(PG_M|PG_U);
2304 			setpte4(va, tpte);
2305 		}
2306 	}
2307 	pv0->pv_flags = flags;
2308 	setcontext4(ctx);
2309 	splx(s);
2310 	return (flags);
2311 }
2312 
2313 /*
2314  * pv_unlink is a helper function for pmap_remove.
2315  * It takes a pointer to the pv_table head for some physical address
2316  * and removes the appropriate (pmap, va) entry.
2317  *
2318  * Once the entry is removed, if the pv_table head has the cache
2319  * inhibit bit set, see if we can turn that off; if so, walk the
2320  * pvlist and turn off PG_NC in each PTE.  (The pvlist is by
2321  * definition nonempty, since it must have at least two elements
2322  * in it to have PV_NC set, and we only remove one here.)
2323  */
2324 /*static*/ void
2325 pv_unlink4_4c(pv, pm, va)
2326 	struct pvlist *pv;
2327 	struct pmap *pm;
2328 	vaddr_t va;
2329 {
2330 	struct pvlist *npv;
2331 
2332 	/*
2333 	 * First entry is special (sigh).
2334 	 */
2335 	npv = pv->pv_next;
2336 	if (pv->pv_pmap == pm && pv->pv_va == va) {
2337 		pmap_stats.ps_unlink_pvfirst++;
2338 		if (npv != NULL) {
2339 			/*
2340 			 * Shift next entry into the head.
2341 			 * Make sure to retain the REF, MOD and ANC flags.
2342 			 */
2343 			pv->pv_next = npv->pv_next;
2344 			pv->pv_pmap = npv->pv_pmap;
2345 			pv->pv_va = npv->pv_va;
2346 			pv->pv_flags &= ~PV_NC;
2347 			pv->pv_flags |= (npv->pv_flags & PV_NC);
2348 			pool_put(&pv_pool, npv);
2349 		} else {
2350 			/*
2351 			 * No mappings left; we still need to maintain
2352 			 * the REF and MOD flags. since pmap_is_modified()
2353 			 * can still be called for this page.
2354 			 */
2355 			pv->pv_pmap = NULL;
2356 			pv->pv_flags &= ~(PV_NC|PV_ANC);
2357 			return;
2358 		}
2359 	} else {
2360 		struct pvlist *prev;
2361 
2362 		for (prev = pv;; prev = npv, npv = npv->pv_next) {
2363 			pmap_stats.ps_unlink_pvsearch++;
2364 			if (npv->pv_pmap == pm && npv->pv_va == va)
2365 				break;
2366 		}
2367 		prev->pv_next = npv->pv_next;
2368 		pool_put(&pv_pool, npv);
2369 	}
2370 	if ((pv->pv_flags & (PV_NC|PV_ANC)) == PV_ANC) {
2371 		/*
2372 		 * Not cached: check to see if we can fix that now.
2373 		 */
2374 		va = pv->pv_va;
2375 		for (npv = pv->pv_next; npv != NULL; npv = npv->pv_next)
2376 			if (BADALIAS(va, npv->pv_va) ||
2377 			    (npv->pv_flags & PV_NC) != 0)
2378 				return;
2379 		pv->pv_flags &= ~PV_ANC;
2380 		pv_changepte4_4c(pv, 0, PG_NC);
2381 	}
2382 }
2383 
2384 /*
2385  * pv_link is the inverse of pv_unlink, and is used in pmap_enter.
2386  * It returns PG_NC if the (new) pvlist says that the address cannot
2387  * be cached.
2388  */
2389 /*static*/ int
2390 pv_link4_4c(pv, pm, va, nc)
2391 	struct pvlist *pv;
2392 	struct pmap *pm;
2393 	vaddr_t va;
2394 	int nc;
2395 {
2396 	struct pvlist *npv;
2397 	int ret;
2398 
2399 	ret = nc ? PG_NC : 0;
2400 
2401 	if (pv->pv_pmap == NULL) {
2402 		/* no pvlist entries yet */
2403 		pmap_stats.ps_enter_firstpv++;
2404 		pv->pv_next = NULL;
2405 		pv->pv_pmap = pm;
2406 		pv->pv_va = va;
2407 		pv->pv_flags |= nc ? PV_NC : 0;
2408 		return (ret);
2409 	}
2410 	/*
2411 	 * Before entering the new mapping, see if
2412 	 * it will cause old mappings to become aliased
2413 	 * and thus need to be `discached'.
2414 	 */
2415 	pmap_stats.ps_enter_secondpv++;
2416 	if (pv->pv_flags & PV_ANC) {
2417 		/* already uncached, just stay that way */
2418 		ret = PG_NC;
2419 	} else {
2420 		for (npv = pv; npv != NULL; npv = npv->pv_next) {
2421 			if (npv->pv_flags & PV_NC) {
2422 				ret = PG_NC;
2423 #ifdef DEBUG
2424 				/* Check currently illegal condition */
2425 				if (nc == 0)
2426 					printf("pv_link: proc %s, va=0x%lx: "
2427 				"unexpected uncached mapping at 0x%lx\n",
2428 					    curproc ? curproc->p_comm : "--",
2429 					    va, npv->pv_va);
2430 #endif
2431 			}
2432 			if (BADALIAS(va, npv->pv_va)) {
2433 #ifdef DEBUG
2434 				if (pmapdebug & PDB_CACHESTUFF)
2435 					printf(
2436 			"pv_link: badalias: proc %s, 0x%lx<=>0x%lx, pv %p\n",
2437 					curproc ? curproc->p_comm : "--",
2438 					va, npv->pv_va, pv);
2439 #endif
2440 				/* Mark list head `uncached due to aliases' */
2441 				pv->pv_flags |= PV_ANC;
2442 				pv_changepte4_4c(pv, ret = PG_NC, 0);
2443 				break;
2444 			}
2445 		}
2446 	}
2447 	npv = pool_get(&pv_pool, PR_NOWAIT);
2448 	if (npv == NULL)
2449 		panic("pv_link: pv_pool exhausted");
2450 	npv->pv_next = pv->pv_next;
2451 	npv->pv_pmap = pm;
2452 	npv->pv_va = va;
2453 	npv->pv_flags = nc ? PV_NC : 0;
2454 	pv->pv_next = npv;
2455 	return (ret);
2456 }
2457 
2458 #endif /* sun4, sun4c code */
2459 
2460 #if defined(SUN4M)		/* sun4m versions of above */
2461 /*
2462  * Walk the given pv list, and for each PTE, set or clear some bits
2463  * (e.g., PG_W or PG_NC).
2464  *
2465  * This routine flushes the cache for any page whose PTE changes,
2466  * as long as the process has a context; this is overly conservative.
2467  * It also copies ref and mod bits to the pvlist, on the theory that
2468  * this might save work later.  (XXX should test this theory)
2469  */
2470 void
2471 pv_changepte4m(pv0, bis, bic)
2472 	struct pvlist *pv0;
2473 	int bis, bic;
2474 {
2475 	struct pvlist *pv;
2476 	struct pmap *pm;
2477 	int va, vr;
2478 	int ctx, s;
2479 	struct regmap *rp;
2480 	struct segmap *sp;
2481 
2482 	write_user_windows();		/* paranoid? */
2483 	s = splvm();			/* paranoid? */
2484 	if (pv0->pv_pmap == NULL) {
2485 		splx(s);
2486 		return;
2487 	}
2488 	ctx = getcontext4m();
2489 	for (pv = pv0; pv != NULL; pv = pv->pv_next) {
2490 		int tpte;
2491 		pm = pv->pv_pmap;
2492 		va = pv->pv_va;
2493 		vr = VA_VREG(va);
2494 		rp = &pm->pm_regmap[vr];
2495 		sp = &rp->rg_segmap[VA_VSEG(va)];
2496 
2497 		if (pm->pm_ctx) {
2498 			setcontext4m(pm->pm_ctxnum);
2499 
2500 			/*
2501 			 * XXX: always flush cache; conservative, but
2502 			 * needed to invalidate cache tag protection
2503 			 * bits and when disabling caching.
2504 			 */
2505 			cache_flush_page(va);
2506 
2507 #if !defined(MULTIPROCESSOR)	/* XXX? done in updatepte4m() */
2508 			/* Flush TLB so memory copy is up-to-date */
2509 			tlb_flush_page(va);
2510 #endif
2511 		}
2512 
2513 		tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
2514 		KASSERT((tpte & SRMMU_TETYPE) == SRMMU_TEPTE);
2515 		pv0->pv_flags |= MR4M(updatepte4m(va,
2516 		    &sp->sg_pte[VA_SUN4M_VPG(va)], bic, bis));
2517 	}
2518 	setcontext4m(ctx);
2519 	splx(s);
2520 }
2521 
2522 /*
2523  * Sync ref and mod bits in pvlist. If page has been ref'd or modified,
2524  * update ref/mod bits in pvlist, and clear the hardware bits.
2525  *
2526  * Return the new flags.
2527  */
2528 int
2529 pv_syncflags4m(pv0)
2530 	struct pvlist *pv0;
2531 {
2532 	struct pvlist *pv;
2533 	struct pmap *pm;
2534 	int tpte, va, vr, vs, flags;
2535 	int ctx, s;
2536 	struct regmap *rp;
2537 	struct segmap *sp;
2538 	boolean_t doflush;
2539 
2540 	write_user_windows();		/* paranoid? */
2541 	s = splvm();			/* paranoid? */
2542 	if (pv0->pv_pmap == NULL) {	/* paranoid */
2543 		splx(s);
2544 		return (0);
2545 	}
2546 	ctx = getcontext4m();
2547 	flags = pv0->pv_flags;
2548 	for (pv = pv0; pv != NULL; pv = pv->pv_next) {
2549 		pm = pv->pv_pmap;
2550 		va = pv->pv_va;
2551 		vr = VA_VREG(va);
2552 		vs = VA_VSEG(va);
2553 		rp = &pm->pm_regmap[vr];
2554 		sp = &rp->rg_segmap[vs];
2555 		if (sp->sg_pte == NULL) {
2556 			continue;
2557 		}
2558 
2559 		/*
2560 		 * We need the PTE from memory as the TLB version will
2561 		 * always have the SRMMU_PG_R bit on.
2562 		 */
2563 
2564 		if (pm->pm_ctx) {
2565 			setcontext4m(pm->pm_ctxnum);
2566 			tlb_flush_page(va);
2567 		}
2568 		tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
2569 		if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE && /* if valid pte */
2570 		    (tpte & (SRMMU_PG_M|SRMMU_PG_R))) {	  /* and mod/refd */
2571 			flags |= MR4M(tpte);
2572 
2573 			/*
2574 			 * Clear mod/ref bits from PTE and write it back.
2575 			 * We must do this before flushing the cache to
2576 			 * avoid races with another cpu setting the M bit
2577 			 * and creating dirty cache lines again.
2578 			 */
2579 
2580 			doflush = pm->pm_ctx && (tpte & SRMMU_PG_M);
2581 			updatepte4m(va, &sp->sg_pte[VA_SUN4M_VPG(va)], SRMMU_PG_M | SRMMU_PG_R, 0);
2582 			if (doflush) {
2583 
2584 				/* Only do this for write-back caches? */
2585 				cache_flush_page(va);
2586 
2587 				/*
2588 				 * VIPT caches might use the TLB when
2589 				 * flushing, so we flush the TLB again.
2590 				 */
2591 				tlb_flush_page(va);
2592 			}
2593 		}
2594 	}
2595 	pv0->pv_flags = flags;
2596 	setcontext4m(ctx);
2597 	splx(s);
2598 	return (flags);
2599 }
2600 
2601 /*
2602  * Should be called with pmap already locked.
2603  */
2604 void
2605 pv_unlink4m(pv, pm, va)
2606 	struct pvlist *pv;
2607 	struct pmap *pm;
2608 	vaddr_t va;
2609 {
2610 	struct pvlist *npv;
2611 
2612 	/*
2613 	 * First entry is special (sigh).
2614 	 */
2615 
2616 	npv = pv->pv_next;
2617 	if (pv->pv_pmap == pm && pv->pv_va == va) {
2618 		pmap_stats.ps_unlink_pvfirst++;
2619 		if (npv != NULL) {
2620 			/*
2621 			 * Shift next entry into the head.
2622 			 * Make sure to retain the REF, MOD and ANC flags
2623 			 * on the list head.
2624 			 */
2625 			pv->pv_next = npv->pv_next;
2626 			pv->pv_pmap = npv->pv_pmap;
2627 			pv->pv_va = npv->pv_va;
2628 			pv->pv_flags &= ~PV_NC;
2629 			pv->pv_flags |= (npv->pv_flags & PV_NC);
2630 			pool_put(&pv_pool, npv);
2631 		} else {
2632 			/*
2633 			 * No mappings left; we need to maintain
2634 			 * the REF and MOD flags, since pmap_is_modified()
2635 			 * can still be called for this page.
2636 			 */
2637 			pv->pv_pmap = NULL;
2638 			pv->pv_flags &= ~(PV_NC|PV_ANC);
2639 			return;
2640 		}
2641 	} else {
2642 		struct pvlist *prev;
2643 
2644 		for (prev = pv;; prev = npv, npv = npv->pv_next) {
2645 			pmap_stats.ps_unlink_pvsearch++;
2646 			if (npv->pv_pmap == pm && npv->pv_va == va)
2647 				break;
2648 		}
2649 		prev->pv_next = npv->pv_next;
2650 		pool_put(&pv_pool, npv);
2651 	}
2652 	if ((pv->pv_flags & (PV_NC|PV_ANC)) == PV_ANC) {
2653 
2654 		/*
2655 		 * Not cached: check to see if we can fix that now.
2656 		 */
2657 
2658 		va = pv->pv_va;
2659 		for (npv = pv->pv_next; npv != NULL; npv = npv->pv_next)
2660 			if (BADALIAS(va, npv->pv_va) ||
2661 			    (npv->pv_flags & PV_NC) != 0)
2662 				return;
2663 #ifdef DEBUG
2664 		if (pmapdebug & PDB_CACHESTUFF)
2665 			printf(
2666 			"pv_unlink: alias ok: proc %s, va 0x%lx, pv %p\n",
2667 				curproc ? curproc->p_comm : "--",
2668 				va, pv);
2669 #endif
2670 		pv->pv_flags &= ~PV_ANC;
2671 		pv_changepte4m(pv, SRMMU_PG_C, 0);
2672 	}
2673 }
2674 
2675 /*
2676  * pv_link is the inverse of pv_unlink, and is used in pmap_enter.
2677  * It returns SRMMU_PG_C if the (new) pvlist says that the address cannot
2678  * be cached (i.e. its results must be (& ~)'d in.
2679  */
2680 /*static*/ int
2681 pv_link4m(pv, pm, va, nc)
2682 	struct pvlist *pv;
2683 	struct pmap *pm;
2684 	vaddr_t va;
2685 	int nc;
2686 {
2687 	struct pvlist *npv;
2688 	int ret;
2689 
2690 	ret = nc ? SRMMU_PG_C : 0;
2691 
2692 	if (pv->pv_pmap == NULL) {
2693 		/* no pvlist entries yet */
2694 		pmap_stats.ps_enter_firstpv++;
2695 		pv->pv_next = NULL;
2696 		pv->pv_pmap = pm;
2697 		pv->pv_va = va;
2698 		pv->pv_flags |= nc ? PV_NC : 0;
2699 		return (ret);
2700 	}
2701 
2702 	/*
2703 	 * Before entering the new mapping, see if
2704 	 * it will cause old mappings to become aliased
2705 	 * and thus need to be `discached'.
2706 	 */
2707 
2708 	pmap_stats.ps_enter_secondpv++;
2709 	if ((pv->pv_flags & PV_ANC) != 0) {
2710 		/* already uncached, just stay that way */
2711 		ret = SRMMU_PG_C;
2712 	} else {
2713 		for (npv = pv; npv != NULL; npv = npv->pv_next) {
2714 			if ((npv->pv_flags & PV_NC) != 0) {
2715 				ret = SRMMU_PG_C;
2716 #ifdef DEBUG
2717 				/* Check currently illegal condition */
2718 				if (nc == 0)
2719 					printf("pv_link: proc %s, va=0x%lx: "
2720 				"unexpected uncached mapping at 0x%lx\n",
2721 					    curproc ? curproc->p_comm : "--",
2722 					    va, npv->pv_va);
2723 #endif
2724 			}
2725 			if (BADALIAS(va, npv->pv_va)) {
2726 #ifdef DEBUG
2727 				if (pmapdebug & PDB_CACHESTUFF)
2728 					printf(
2729 			"pv_link: badalias: proc %s, 0x%lx<=>0x%lx, pv %p\n",
2730 					curproc ? curproc->p_comm : "--",
2731 					va, npv->pv_va, pv);
2732 #endif
2733 				/* Mark list head `uncached due to aliases' */
2734 				pv->pv_flags |= PV_ANC;
2735 				pv_changepte4m(pv, 0, ret = SRMMU_PG_C);
2736 				break;
2737 			}
2738 		}
2739 	}
2740 	npv = pool_get(&pv_pool, PR_NOWAIT);
2741 	if (npv == NULL)
2742 		panic("pv_link: pv_pool exhausted");
2743 	npv->pv_next = pv->pv_next;
2744 	npv->pv_pmap = pm;
2745 	npv->pv_va = va;
2746 	npv->pv_flags = nc ? PV_NC : 0;
2747 	pv->pv_next = npv;
2748 	return (ret);
2749 }
2750 #endif
2751 
2752 /*
2753  * Uncache all entries on behalf of kvm_uncache(). In addition to
2754  * removing the cache bit from the PTE, we are also setting PV_NC
2755  * in each entry to stop pv_unlink() from re-caching (i.e. when a
2756  * a bad alias is going away).
2757  */
2758 void
2759 pv_uncache(pv0)
2760 	struct pvlist *pv0;
2761 {
2762 	struct pvlist *pv;
2763 
2764 	for (pv = pv0; pv != NULL; pv = pv->pv_next)
2765 		pv->pv_flags |= PV_NC;
2766 
2767 #if defined(SUN4M)
2768 	if (CPU_ISSUN4M)
2769 		pv_changepte4m(pv, 0, SRMMU_PG_C);
2770 #endif
2771 #if defined(SUN4) || defined(SUN4C)
2772 	if (CPU_ISSUN4OR4C)
2773 		pv_changepte4_4c(pv, PG_NC, 0);
2774 #endif
2775 }
2776 
2777 /*
2778  * Walk the given list and flush the cache for each (MI) page that is
2779  * potentially in the cache. Called only if vactype != VAC_NONE.
2780  */
2781 void
2782 pv_flushcache(pv)
2783 	struct pvlist *pv;
2784 {
2785 	struct pmap *pm;
2786 	int s, ctx;
2787 
2788 	write_user_windows();	/* paranoia? */
2789 	s = splvm();		/* XXX extreme paranoia */
2790 	if ((pm = pv->pv_pmap) != NULL) {
2791 		ctx = getcontext();
2792 		for (;;) {
2793 			if (pm->pm_ctx) {
2794 				setcontext(pm->pm_ctxnum);
2795 				cache_flush_page(pv->pv_va);
2796 #if defined(SUN4M)
2797 				if (CPU_ISSUN4M)
2798 					tlb_flush_page(pv->pv_va);
2799 #endif
2800 			}
2801 			pv = pv->pv_next;
2802 			if (pv == NULL)
2803 				break;
2804 			pm = pv->pv_pmap;
2805 		}
2806 		setcontext(ctx);
2807 	}
2808 	splx(s);
2809 }
2810 
2811 /*----------------------------------------------------------------*/
2812 
2813 /*
2814  * At last, pmap code.
2815  */
2816 
2817 #if defined(SUN4) && (defined(SUN4C) || defined(SUN4M))
2818 int nptesg;
2819 #endif
2820 
2821 #if defined(SUN4M)
2822 static void pmap_bootstrap4m __P((void));
2823 #endif
2824 #if defined(SUN4) || defined(SUN4C)
2825 static void pmap_bootstrap4_4c __P((int, int, int));
2826 #endif
2827 
2828 /*
2829  * Bootstrap the system enough to run with VM enabled.
2830  *
2831  * nsegment is the number of mmu segment entries (``PMEGs'');
2832  * nregion is the number of mmu region entries (``SMEGs'');
2833  * nctx is the number of contexts.
2834  */
2835 void
2836 pmap_bootstrap(nctx, nregion, nsegment)
2837 	int nsegment, nctx, nregion;
2838 {
2839 	extern char etext[], kernel_data_start[];
2840 
2841 #if defined(SUN4M)
2842 	if (CPU_ISSUN4M) {
2843 		/*
2844 		 * Compute `va2pa_offset'.
2845 		 * Since the kernel is loaded at address 0x4000 within
2846 		 * the memory bank, we'll use the corresponding VA
2847 		 * (i.e. `kernel_text') to fetch the physical load
2848 		 * address, just in case those first 4 pages aren't mapped.
2849 		 */
2850 		extern char kernel_text[];
2851 		int offset = (vaddr_t)kernel_text - (vaddr_t)KERNBASE;
2852 		va2pa_offset -= (VA2PA(kernel_text) - offset);
2853 	}
2854 #endif
2855 
2856 	uvmexp.pagesize = NBPG;
2857 	uvm_setpagesize();
2858 
2859 #if defined(SUN4) && (defined(SUN4C) || defined(SUN4M))
2860 	/* In this case NPTESG is a variable */
2861 	nptesg = (NBPSG >> pgshift);
2862 #endif
2863 
2864 	/*
2865 	 * Grab physical memory list.
2866 	 */
2867 	get_phys_mem();
2868 
2869 	/*
2870 	 * The data segment in sparc ELF images is aligned to a 64KB
2871 	 * (the maximum page size defined by the ELF/sparc ABI) boundary.
2872 	 * This results in a unused portion of physical memory in between
2873 	 * the text/rodata and the data segment. We pick up that gap
2874 	 * here to remove it from the kernel map and give it to the
2875 	 * VM manager later.
2876 	 */
2877 	etext_gap_start = (vaddr_t)(etext + NBPG - 1) & ~PGOFSET;
2878 	etext_gap_end = (vaddr_t)kernel_data_start & ~PGOFSET;
2879 
2880 	if (CPU_ISSUN4M) {
2881 #if defined(SUN4M)
2882 		pmap_bootstrap4m();
2883 #endif
2884 	} else if (CPU_ISSUN4OR4C) {
2885 #if defined(SUN4) || defined(SUN4C)
2886 		pmap_bootstrap4_4c(nctx, nregion, nsegment);
2887 #endif
2888 	}
2889 
2890 	pmap_page_upload();
2891 }
2892 
2893 #if defined(SUN4) || defined(SUN4C)
2894 void
2895 pmap_bootstrap4_4c(nctx, nregion, nsegment)
2896 	int nsegment, nctx, nregion;
2897 {
2898 	union ctxinfo *ci;
2899 	struct mmuentry *mmuseg;
2900 #if defined(SUN4_MMU3L)
2901 	struct mmuentry *mmureg;
2902 #endif
2903 	struct   regmap *rp;
2904 	int i, j;
2905 	int npte, zseg, vr, vs;
2906 	int rcookie, scookie;
2907 	caddr_t p;
2908 	int lastpage;
2909 	vaddr_t va;
2910 	extern char *kernel_top;
2911 
2912 	ncontext = nctx;
2913 
2914 	switch (cputyp) {
2915 	case CPU_SUN4C:
2916 		mmu_has_hole = 1;
2917 		break;
2918 	case CPU_SUN4:
2919 		if (cpuinfo.cpu_type != CPUTYP_4_400) {
2920 			mmu_has_hole = 1;
2921 			break;
2922 		}
2923 	}
2924 
2925 #if defined(SUN4)
2926 	/*
2927 	 * set up the segfixmask to mask off invalid bits
2928 	 */
2929 	segfixmask =  nsegment - 1; /* assume nsegment is a power of 2 */
2930 #ifdef DIAGNOSTIC
2931 	if (((nsegment & segfixmask) | (nsegment & ~segfixmask)) != nsegment) {
2932 		printf("pmap_bootstrap: unsuitable number of segments (%d)\n",
2933 			nsegment);
2934 		callrom();
2935 	}
2936 #endif
2937 #endif
2938 
2939 #if defined(SUN4M) /* We're in a dual-arch kernel. Setup 4/4c fn. ptrs */
2940 	pmap_clear_modify_p 	=	pmap_clear_modify4_4c;
2941 	pmap_clear_reference_p 	= 	pmap_clear_reference4_4c;
2942 	pmap_enter_p 		=	pmap_enter4_4c;
2943 	pmap_extract_p 		=	pmap_extract4_4c;
2944 	pmap_is_modified_p 	=	pmap_is_modified4_4c;
2945 	pmap_is_referenced_p	=	pmap_is_referenced4_4c;
2946 	pmap_kenter_pa_p 	=	pmap_kenter_pa4_4c;
2947 	pmap_kremove_p	 	=	pmap_kremove4_4c;
2948 	pmap_page_protect_p	=	pmap_page_protect4_4c;
2949 	pmap_protect_p		=	pmap_protect4_4c;
2950 	pmap_changeprot_p	=	pmap_changeprot4_4c;
2951 	pmap_rmk_p		=	pmap_rmk4_4c;
2952 	pmap_rmu_p		=	pmap_rmu4_4c;
2953 #endif /* defined SUN4M */
2954 
2955 	/*
2956 	 * Last segment is the `invalid' one (one PMEG of pte's with !pg_v).
2957 	 * It will never be used for anything else.
2958 	 */
2959 	seginval = --nsegment;
2960 
2961 #if defined(SUN4_MMU3L)
2962 	if (HASSUN4_MMU3L)
2963 		reginval = --nregion;
2964 #endif
2965 
2966 	/*
2967 	 * Intialize the kernel pmap.
2968 	 */
2969 	/* kernel_pmap_store.pm_ctxnum = 0; */
2970 	simple_lock_init(&kernel_pmap_store.pm_lock);
2971 	kernel_pmap_store.pm_refcount = 1;
2972 #if defined(SUN4_MMU3L)
2973 	TAILQ_INIT(&kernel_pmap_store.pm_reglist);
2974 #endif
2975 	TAILQ_INIT(&kernel_pmap_store.pm_seglist);
2976 
2977 	/*
2978 	 * Set up pm_regmap for kernel to point NUREG *below* the beginning
2979 	 * of kernel regmap storage. Since the kernel only uses regions
2980 	 * above NUREG, we save storage space and can index kernel and
2981 	 * user regions in the same way.
2982 	 */
2983 	kernel_pmap_store.pm_regmap = &kernel_regmap_store[-NUREG];
2984 	for (i = NKREG; --i >= 0;) {
2985 #if defined(SUN4_MMU3L)
2986 		kernel_regmap_store[i].rg_smeg = reginval;
2987 #endif
2988 		kernel_regmap_store[i].rg_segmap =
2989 			&kernel_segmap_store[i * NSEGRG];
2990 		for (j = NSEGRG; --j >= 0;)
2991 			kernel_segmap_store[i * NSEGRG + j].sg_pmeg = seginval;
2992 	}
2993 
2994 	/*
2995 	 * Preserve the monitor ROM's reserved VM region, so that
2996 	 * we can use L1-A or the monitor's debugger.  As a side
2997 	 * effect we map the ROM's reserved VM into all contexts
2998 	 * (otherwise L1-A crashes the machine!).
2999 	 */
3000 
3001 	mmu_reservemon4_4c(&nregion, &nsegment);
3002 
3003 #if defined(SUN4_MMU3L)
3004 	/* Reserve one region for temporary mappings */
3005 	if (HASSUN4_MMU3L)
3006 		tregion = --nregion;
3007 #endif
3008 
3009 	/*
3010 	 * Allocate and clear mmu entries and context structures.
3011 	 */
3012 	p = kernel_top;
3013 
3014 #if defined(SUN4_MMU3L)
3015 	mmuregions = mmureg = (struct mmuentry *)p;
3016 	p += nregion * sizeof(struct mmuentry);
3017 	bzero(mmuregions, nregion * sizeof(struct mmuentry));
3018 #endif
3019 	mmusegments = mmuseg = (struct mmuentry *)p;
3020 	p += nsegment * sizeof(struct mmuentry);
3021 	bzero(mmusegments, nsegment * sizeof(struct mmuentry));
3022 
3023 	pmap_kernel()->pm_ctx = ctxinfo = ci = (union ctxinfo *)p;
3024 	p += nctx * sizeof *ci;
3025 
3026 	/* Initialize MMU resource queues */
3027 #if defined(SUN4_MMU3L)
3028 	TAILQ_INIT(&region_freelist);
3029 	TAILQ_INIT(&region_lru);
3030 	TAILQ_INIT(&region_locked);
3031 #endif
3032 	TAILQ_INIT(&segm_freelist);
3033 	TAILQ_INIT(&segm_lru);
3034 	TAILQ_INIT(&segm_locked);
3035 
3036 	/*
3037 	 * Set up the `constants' for the call to vm_init()
3038 	 * in main().  All pages beginning at p (rounded up to
3039 	 * the next whole page) and continuing through the number
3040 	 * of available pages are free, but they start at a higher
3041 	 * virtual address.  This gives us two mappable MD pages
3042 	 * for pmap_zero_page and pmap_copy_page, and one MI page
3043 	 * for /dev/mem, all with no associated physical memory.
3044 	 */
3045 	p = (caddr_t)(((u_int)p + NBPG - 1) & ~PGOFSET);
3046 
3047 	avail_start = PMAP_BOOTSTRAP_VA2PA(p);
3048 
3049 	i = (int)p;
3050 	vpage[0] = p, p += NBPG;
3051 	vpage[1] = p, p += NBPG;
3052 	vmmap = p, p += NBPG;
3053 	p = reserve_dumppages(p);
3054 
3055 	virtual_avail = (vaddr_t)p;
3056 	virtual_end = VM_MAX_KERNEL_ADDRESS;
3057 
3058 	p = (caddr_t)i;			/* retract to first free phys */
3059 
3060 	/*
3061 	 * All contexts are free except the kernel's.
3062 	 *
3063 	 * XXX sun4c could use context 0 for users?
3064 	 */
3065 	simple_lock_init(&ctx_lock);
3066 	ci->c_pmap = pmap_kernel();
3067 	ctx_freelist = ci + 1;
3068 	for (i = 1; i < ncontext; i++) {
3069 		ci++;
3070 		ci->c_nextfree = ci + 1;
3071 	}
3072 	ci->c_nextfree = NULL;
3073 	ctx_kick = 0;
3074 	ctx_kickdir = -1;
3075 
3076 	/*
3077 	 * Init mmu entries that map the kernel physical addresses.
3078 	 *
3079 	 * All the other MMU entries are free.
3080 	 *
3081 	 * THIS ASSUMES SEGMENT i IS MAPPED BY MMU ENTRY i DURING THE
3082 	 * BOOT PROCESS
3083 	 */
3084 
3085 	/* Compute the number of segments used by the kernel */
3086 	zseg = ((((u_int)p + NBPSG - 1) & ~SGOFSET) - KERNBASE) >> SGSHIFT;
3087 	lastpage = VA_VPG(p);
3088 	if (lastpage == 0)
3089 		/*
3090 		 * If the page bits in p are 0, we filled the last segment
3091 		 * exactly (now how did that happen?); if not, it is
3092 		 * the last page filled in the last segment.
3093 		 */
3094 		lastpage = NPTESG;
3095 
3096 	p = (caddr_t)KERNBASE;		/* first va */
3097 	vs = VA_VSEG(KERNBASE);		/* first virtual segment */
3098 	vr = VA_VREG(KERNBASE);		/* first virtual region */
3099 	rp = &pmap_kernel()->pm_regmap[vr];
3100 
3101 	for (rcookie = 0, scookie = 0;;) {
3102 
3103 		/*
3104 		 * Distribute each kernel region/segment into all contexts.
3105 		 * This is done through the monitor ROM, rather than
3106 		 * directly here: if we do a setcontext we will fault,
3107 		 * as we are not (yet) mapped in any other context.
3108 		 */
3109 
3110 		if ((vs % NSEGRG) == 0) {
3111 			/* Entering a new region */
3112 			if (VA_VREG(p) > vr) {
3113 #ifdef DEBUG
3114 				printf("note: giant kernel!\n");
3115 #endif
3116 				vr++, rp++;
3117 			}
3118 #if defined(SUN4_MMU3L)
3119 			if (HASSUN4_MMU3L) {
3120 				for (i = 1; i < nctx; i++)
3121 					prom_setcontext(i, p, rcookie);
3122 
3123 				TAILQ_INSERT_TAIL(&region_locked,
3124 						  mmureg, me_list);
3125 				TAILQ_INSERT_TAIL(&pmap_kernel()->pm_reglist,
3126 						  mmureg, me_pmchain);
3127 				mmureg->me_cookie = rcookie;
3128 				mmureg->me_pmap = pmap_kernel();
3129 				mmureg->me_vreg = vr;
3130 				rp->rg_smeg = rcookie;
3131 				mmureg++;
3132 				rcookie++;
3133 			}
3134 #endif
3135 		}
3136 
3137 #if defined(SUN4_MMU3L)
3138 		if (!HASSUN4_MMU3L)
3139 #endif
3140 			for (i = 1; i < nctx; i++)
3141 				prom_setcontext(i, p, scookie);
3142 
3143 		/* set up the mmu entry */
3144 		TAILQ_INSERT_TAIL(&segm_locked, mmuseg, me_list);
3145 		TAILQ_INSERT_TAIL(&pmap_kernel()->pm_seglist, mmuseg, me_pmchain);
3146 		pmap_stats.ps_npmeg_locked++;
3147 		mmuseg->me_cookie = scookie;
3148 		mmuseg->me_pmap = pmap_kernel();
3149 		mmuseg->me_vreg = vr;
3150 		mmuseg->me_vseg = vs % NSEGRG;
3151 		rp->rg_segmap[vs % NSEGRG].sg_pmeg = scookie;
3152 		npte = ++scookie < zseg ? NPTESG : lastpage;
3153 		rp->rg_segmap[vs % NSEGRG].sg_npte = npte;
3154 		rp->rg_nsegmap += 1;
3155 		mmuseg++;
3156 		vs++;
3157 		if (scookie < zseg) {
3158 			p += NBPSG;
3159 			continue;
3160 		}
3161 
3162 		/*
3163 		 * Unmap the pages, if any, that are not part of
3164 		 * the final segment.
3165 		 */
3166 		for (p += npte << PGSHIFT; npte < NPTESG; npte++, p += NBPG)
3167 			setpte4(p, 0);
3168 
3169 #if defined(SUN4_MMU3L)
3170 		if (HASSUN4_MMU3L) {
3171 			/*
3172 			 * Unmap the segments, if any, that are not part of
3173 			 * the final region.
3174 			 */
3175 			for (i = rp->rg_nsegmap; i < NSEGRG; i++, p += NBPSG)
3176 				setsegmap(p, seginval);
3177 
3178 			/*
3179 			 * Unmap any kernel regions that we aren't using.
3180 			 */
3181 			for (i = 0; i < nctx; i++) {
3182 				setcontext4(i);
3183 				for (va = (vaddr_t)p;
3184 				     va < (OPENPROM_STARTVADDR & ~(NBPRG - 1));
3185 				     va += NBPRG)
3186 					setregmap(va, reginval);
3187 			}
3188 
3189 		} else
3190 #endif
3191 		{
3192 			/*
3193 			 * Unmap any kernel segments that we aren't using.
3194 			 */
3195 			for (i = 0; i < nctx; i++) {
3196 				setcontext4(i);
3197 				for (va = (vaddr_t)p;
3198 				     va < (OPENPROM_STARTVADDR & ~(NBPSG - 1));
3199 				     va += NBPSG)
3200 					setsegmap(va, seginval);
3201 			}
3202 		}
3203 		break;
3204 	}
3205 
3206 #if defined(SUN4_MMU3L)
3207 	if (HASSUN4_MMU3L)
3208 		for (; rcookie < nregion; rcookie++, mmureg++) {
3209 			mmureg->me_cookie = rcookie;
3210 			TAILQ_INSERT_TAIL(&region_freelist, mmureg, me_list);
3211 		}
3212 #endif
3213 
3214 	for (; scookie < nsegment; scookie++, mmuseg++) {
3215 		mmuseg->me_cookie = scookie;
3216 		TAILQ_INSERT_TAIL(&segm_freelist, mmuseg, me_list);
3217 		pmap_stats.ps_npmeg_free++;
3218 	}
3219 
3220 	/* Erase all spurious user-space segmaps */
3221 	for (i = 1; i < ncontext; i++) {
3222 		setcontext4(i);
3223 		if (HASSUN4_MMU3L)
3224 			for (p = 0, j = NUREG; --j >= 0; p += NBPRG)
3225 				setregmap(p, reginval);
3226 		else
3227 			for (p = 0, vr = 0; vr < NUREG; vr++) {
3228 				if (VA_INHOLE(p)) {
3229 					p = (caddr_t)MMU_HOLE_END;
3230 					vr = VA_VREG(p);
3231 				}
3232 				for (j = NSEGRG; --j >= 0; p += NBPSG)
3233 					setsegmap(p, seginval);
3234 			}
3235 	}
3236 	setcontext4(0);
3237 
3238 	/*
3239 	 * write protect & encache kernel text;
3240 	 * set red zone at kernel base; enable cache on message buffer.
3241 	 */
3242 	{
3243 		extern char etext[];
3244 #ifdef KGDB
3245 		int mask = ~PG_NC;	/* XXX chgkprot is busted */
3246 #else
3247 		int mask = ~(PG_W | PG_NC);
3248 #endif
3249 
3250 		for (p = (caddr_t)trapbase; p < etext; p += NBPG)
3251 			setpte4(p, getpte4(p) & mask);
3252 
3253 		/*
3254 		 * Unmap the `etext gap'; it'll be made available
3255 		 * to the VM manager.
3256 		 */
3257 		for (p = (caddr_t)etext_gap_start;
3258 		     p < (caddr_t)etext_gap_end;
3259 		     p += NBPG)
3260 			setpte4(p, 0);
3261 	}
3262 }
3263 #endif
3264 
3265 #if defined(SUN4M)		/* sun4m version of pmap_bootstrap */
3266 /*
3267  * Bootstrap the system enough to run with VM enabled on a sun4m machine.
3268  *
3269  * Switches from ROM to kernel page tables, and sets up initial mappings.
3270  */
3271 static void
3272 pmap_bootstrap4m(void)
3273 {
3274 	int i, j;
3275 	caddr_t p, q;
3276 	union ctxinfo *ci;
3277 	int reg, seg;
3278 	unsigned int ctxtblsize;
3279 	caddr_t pagetables_start, pagetables_end;
3280 	paddr_t pagetables_start_pa;
3281 	extern char *kernel_top;
3282 	extern char etext[];
3283 	extern caddr_t reserve_dumppages(caddr_t);
3284 
3285 	ncontext = cpuinfo.mmu_ncontext;
3286 
3287 #if defined(SUN4) || defined(SUN4C) /* setup 4M fn. ptrs for dual-arch kernel */
3288 	pmap_clear_modify_p 	=	pmap_clear_modify4m;
3289 	pmap_clear_reference_p 	= 	pmap_clear_reference4m;
3290 	pmap_enter_p 		=	pmap_enter4m;
3291 	pmap_extract_p 		=	pmap_extract4m;
3292 	pmap_is_modified_p 	=	pmap_is_modified4m;
3293 	pmap_is_referenced_p	=	pmap_is_referenced4m;
3294 	pmap_kenter_pa_p 	=	pmap_kenter_pa4m;
3295 	pmap_kremove_p	 	=	pmap_kremove4m;
3296 	pmap_page_protect_p	=	pmap_page_protect4m;
3297 	pmap_protect_p		=	pmap_protect4m;
3298 	pmap_changeprot_p	=	pmap_changeprot4m;
3299 	pmap_rmk_p		=	pmap_rmk4m;
3300 	pmap_rmu_p		=	pmap_rmu4m;
3301 #endif /* defined SUN4/SUN4C */
3302 
3303 	/*
3304 	 * p points to top of kernel mem
3305 	 */
3306 	p = kernel_top;
3307 
3308 	/*
3309 	 * Intialize the kernel pmap.
3310 	 */
3311 	/* kernel_pmap_store.pm_ctxnum = 0; */
3312 	simple_lock_init(&kernel_pmap_store.pm_lock);
3313 	kernel_pmap_store.pm_refcount = 1;
3314 
3315 	/*
3316 	 * Set up pm_regmap for kernel to point NUREG *below* the beginning
3317 	 * of kernel regmap storage. Since the kernel only uses regions
3318 	 * above NUREG, we save storage space and can index kernel and
3319 	 * user regions in the same way.
3320 	 */
3321 	kernel_pmap_store.pm_regmap = &kernel_regmap_store[-NUREG];
3322 	bzero(kernel_regmap_store, NKREG * sizeof(struct regmap));
3323 	bzero(kernel_segmap_store, NKREG * NSEGRG * sizeof(struct segmap));
3324 	for (i = NKREG; --i >= 0;) {
3325 		kernel_regmap_store[i].rg_segmap =
3326 			&kernel_segmap_store[i * NSEGRG];
3327 		kernel_regmap_store[i].rg_seg_ptps = NULL;
3328 		for (j = NSEGRG; --j >= 0;)
3329 			kernel_segmap_store[i * NSEGRG + j].sg_pte = NULL;
3330 	}
3331 
3332 	/* Allocate kernel region pointer tables */
3333 	pmap_kernel()->pm_reg_ptps = (int **)(q = p);
3334 	p += ncpu * sizeof(int **);
3335 	bzero(q, (u_int)p - (u_int)q);
3336 
3337 	pmap_kernel()->pm_reg_ptps_pa = (int *)(q = p);
3338 	p += ncpu * sizeof(int *);
3339 	bzero(q, (u_int)p - (u_int)q);
3340 
3341 	/* Allocate context administration */
3342 	pmap_kernel()->pm_ctx = ctxinfo = ci = (union ctxinfo *)p;
3343 	p += ncontext * sizeof *ci;
3344 	bzero((caddr_t)ci, (u_int)p - (u_int)ci);
3345 
3346 
3347 	/*
3348 	 * Set up the `constants' for the call to vm_init()
3349 	 * in main().  All pages beginning at p (rounded up to
3350 	 * the next whole page) and continuing through the number
3351 	 * of available pages are free.
3352 	 */
3353 	p = (caddr_t)(((u_int)p + NBPG - 1) & ~PGOFSET);
3354 
3355 	/*
3356 	 * Reserve memory for MMU pagetables. Some of these have severe
3357 	 * alignment restrictions. We allocate in a sequence that
3358 	 * minimizes alignment gaps.
3359 	 */
3360 
3361 	pagetables_start = p;
3362 	pagetables_start_pa = PMAP_BOOTSTRAP_VA2PA(p);
3363 
3364 	/*
3365 	 * Allocate context table.
3366 	 * To keep supersparc happy, minimum aligment is on a 4K boundary.
3367 	 */
3368 	ctxtblsize = max(ncontext,1024) * sizeof(int);
3369 	cpuinfo.ctx_tbl = (int *)roundup((u_int)p, ctxtblsize);
3370 	cpuinfo.ctx_tbl_pa = PMAP_BOOTSTRAP_VA2PA(cpuinfo.ctx_tbl);
3371 	p = (caddr_t)((u_int)cpuinfo.ctx_tbl + ctxtblsize);
3372 
3373 	/*
3374 	 * Reserve memory for segment and page tables needed to map the entire
3375 	 * kernel. This takes (2K + NKREG * 16K) of space, but unfortunately
3376 	 * is necessary since pmap_enter() *must* be able to enter a kernel
3377 	 * mapping without delay.
3378 	 */
3379 	p = (caddr_t) roundup((u_int)p, SRMMU_L1SIZE * sizeof(u_int));
3380 	qzero(p, SRMMU_L1SIZE * sizeof(u_int));
3381 	kernel_regtable_store = (u_int *)p;
3382 	p += SRMMU_L1SIZE * sizeof(u_int);
3383 
3384 	p = (caddr_t) roundup((u_int)p, SRMMU_L2SIZE * sizeof(u_int));
3385 	qzero(p, (SRMMU_L2SIZE * sizeof(u_int)) * NKREG);
3386 	kernel_segtable_store = (u_int *)p;
3387 	p += (SRMMU_L2SIZE * sizeof(u_int)) * NKREG;
3388 
3389 	p = (caddr_t) roundup((u_int)p, SRMMU_L3SIZE * sizeof(u_int));
3390 	/* zero it: all will be SRMMU_TEINVALID */
3391 	qzero(p, ((SRMMU_L3SIZE * sizeof(u_int)) * NKREG) * NSEGRG);
3392 	kernel_pagtable_store = (u_int *)p;
3393 	p += ((SRMMU_L3SIZE * sizeof(u_int)) * NKREG) * NSEGRG;
3394 
3395 	/* Round to next page and mark end of pre-wired kernel space */
3396 	p = (caddr_t)(((u_int)p + NBPG - 1) & ~PGOFSET);
3397 	pagetables_end = p;
3398 
3399 	avail_start = PMAP_BOOTSTRAP_VA2PA(p);
3400 
3401 	/*
3402 	 * Now wire the region and segment tables of the kernel map.
3403 	 */
3404 	pmap_kernel()->pm_reg_ptps[0] = (int *) kernel_regtable_store;
3405 	pmap_kernel()->pm_reg_ptps_pa[0] =
3406 		VA2PA((caddr_t)pmap_kernel()->pm_reg_ptps[0]);
3407 
3408 	/* Install L1 table in context 0 */
3409 	setpgt4m(&cpuinfo.ctx_tbl[0],
3410 	    (pmap_kernel()->pm_reg_ptps_pa[0] >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
3411 
3412 	for (reg = 0; reg < NKREG; reg++) {
3413 		struct regmap *rp;
3414 		caddr_t kphyssegtbl;
3415 
3416 		/*
3417 		 * Entering new region; install & build segtbl
3418 		 */
3419 
3420 		rp = &pmap_kernel()->pm_regmap[reg + VA_VREG(KERNBASE)];
3421 
3422 		kphyssegtbl = (caddr_t)
3423 		    &kernel_segtable_store[reg * SRMMU_L2SIZE];
3424 
3425 		setpgt4m(&pmap_kernel()->pm_reg_ptps[0][reg + VA_VREG(KERNBASE)],
3426 			 (VA2PA(kphyssegtbl) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
3427 
3428 		rp->rg_seg_ptps = (int *)kphyssegtbl;
3429 
3430 		for (seg = 0; seg < NSEGRG; seg++) {
3431 			struct segmap *sp;
3432 			caddr_t kphyspagtbl;
3433 
3434 			rp->rg_nsegmap++;
3435 
3436 			sp = &rp->rg_segmap[seg];
3437 			kphyspagtbl = (caddr_t)
3438 			    &kernel_pagtable_store
3439 				[((reg * NSEGRG) + seg) * SRMMU_L3SIZE];
3440 
3441 			setpgt4m(&rp->rg_seg_ptps[seg],
3442 				 (VA2PA(kphyspagtbl) >> SRMMU_PPNPASHIFT) |
3443 				 SRMMU_TEPTD);
3444 			sp->sg_pte = (int *) kphyspagtbl;
3445 		}
3446 	}
3447 
3448 	/*
3449 	 * Preserve the monitor ROM's reserved VM region, so that
3450 	 * we can use L1-A or the monitor's debugger.
3451 	 */
3452 	mmu_reservemon4m(&kernel_pmap_store);
3453 
3454 	/*
3455 	 * Reserve virtual address space for two mappable MD pages
3456 	 * for pmap_zero_page and pmap_copy_page, one MI page
3457 	 * for /dev/mem, and some more for dumpsys().
3458 	 */
3459 	q = p;
3460 	vpage[0] = p, p += NBPG;
3461 	vpage[1] = p, p += NBPG;
3462 	vmmap = p, p += NBPG;
3463 	p = reserve_dumppages(p);
3464 
3465 	/* Find PTE locations of vpage[] to optimize zero_fill() et.al. */
3466 	for (i = 0; i < 2; i++) {
3467 		struct regmap *rp;
3468 		struct segmap *sp;
3469 		rp = &pmap_kernel()->pm_regmap[VA_VREG(vpage[i])];
3470 		sp = &rp->rg_segmap[VA_VSEG(vpage[i])];
3471 		vpage_pte[i] = &sp->sg_pte[VA_SUN4M_VPG(vpage[i])];
3472 	}
3473 
3474 	virtual_avail = (vaddr_t)p;
3475 	virtual_end = VM_MAX_KERNEL_ADDRESS;
3476 
3477 	p = q;			/* retract to first free phys */
3478 
3479 	/*
3480 	 * Set up the ctxinfo structures (freelist of contexts)
3481 	 */
3482 	simple_lock_init(&ctx_lock);
3483 	ci->c_pmap = pmap_kernel();
3484 	ctx_freelist = ci + 1;
3485 	for (i = 1; i < ncontext; i++) {
3486 		ci++;
3487 		ci->c_nextfree = ci + 1;
3488 	}
3489 	ci->c_nextfree = NULL;
3490 	ctx_kick = 0;
3491 	ctx_kickdir = -1;
3492 
3493 	/*
3494 	 * Now map the kernel into our new set of page tables, then
3495 	 * (finally) switch over to our running page tables.
3496 	 * We map from KERNBASE to p into context 0's page tables (and
3497 	 * the kernel pmap).
3498 	 */
3499 #ifdef DEBUG			/* Sanity checks */
3500 	if ((u_int)p % NBPG != 0)
3501 		panic("pmap_bootstrap4m: p misaligned?!?");
3502 	if (KERNBASE % NBPRG != 0)
3503 		panic("pmap_bootstrap4m: KERNBASE not region-aligned");
3504 #endif
3505 
3506 	for (q = (caddr_t) KERNBASE; q < p; q += NBPG) {
3507 		struct regmap *rp;
3508 		struct segmap *sp;
3509 		int pte, *ptep;
3510 
3511 		/*
3512 		 * Now install entry for current page.
3513 		 */
3514 		rp = &pmap_kernel()->pm_regmap[VA_VREG(q)];
3515 		sp = &rp->rg_segmap[VA_VSEG(q)];
3516 		ptep = &sp->sg_pte[VA_VPG(q)];
3517 
3518 		/*
3519 		 * Unmap the `etext gap'; it'll be made available
3520 		 * to the VM manager.
3521 		 */
3522 		if (q >= (caddr_t)etext_gap_start &&
3523 		    q < (caddr_t)etext_gap_end) {
3524 			setpgt4m(ptep, 0);
3525 			continue;
3526 		}
3527 
3528 		sp->sg_npte++;
3529 
3530 		pte = PMAP_BOOTSTRAP_VA2PA(q) >> SRMMU_PPNPASHIFT;
3531 		pte |= PPROT_N_RX | SRMMU_TEPTE;
3532 
3533 		/* Deal with the cacheable bit for pagetable memory */
3534 		if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) != 0 ||
3535 		    q < pagetables_start || q >= pagetables_end)
3536 			pte |= SRMMU_PG_C;
3537 
3538 		/* write-protect kernel text */
3539 		if (q < (caddr_t) trapbase || q >= etext)
3540 			pte |= PPROT_WRITE;
3541 
3542 		setpgt4m(ptep, pte);
3543 	}
3544 
3545 	if ((cpuinfo.flags & CPUFLG_CACHEPAGETABLES) == 0) {
3546 		/*
3547 		 * The page tables have been setup. Since we're still
3548 		 * running on the PROM's memory map, the memory we
3549 		 * allocated for our page tables might still be cached.
3550 		 * Flush it now, and don't touch it again until we
3551 		 * switch to our own tables (will be done immediately below).
3552 		 */
3553 		int size = pagetables_end - pagetables_start;
3554 		if (CACHEINFO.c_vactype != VAC_NONE) {
3555 			int va = (vaddr_t)pagetables_start;
3556 			while (size != 0) {
3557 				cache_flush_page(va);
3558 				va += NBPG;
3559 				size -= NBPG;
3560 			}
3561 		} else if (cpuinfo.pcache_flush_page != NULL) {
3562 			int pa = pagetables_start_pa;
3563 			while (size != 0) {
3564 				pcache_flush_page(pa, 0);
3565 				pa += NBPG;
3566 				size -= NBPG;
3567 			}
3568 		}
3569 	}
3570 
3571 	/*
3572 	 * Now switch to kernel pagetables (finally!)
3573 	 */
3574 	mmu_install_tables(&cpuinfo);
3575 }
3576 
3577 static u_long prom_ctxreg;
3578 
3579 void
3580 mmu_install_tables(sc)
3581 	struct cpu_info *sc;
3582 {
3583 
3584 #ifdef DEBUG
3585 	printf("pmap_bootstrap: installing kernel page tables...");
3586 #endif
3587 	setcontext4m(0);	/* paranoia? %%%: Make 0x3 a define! below */
3588 
3589 	/* Enable MMU tablewalk caching, flush TLB */
3590 	if (sc->mmu_enable != 0)
3591 		sc->mmu_enable();
3592 
3593 	tlb_flush_all_real();
3594 	prom_ctxreg = lda(SRMMU_CXTPTR, ASI_SRMMU);
3595 
3596 	sta(SRMMU_CXTPTR, ASI_SRMMU,
3597 		(sc->ctx_tbl_pa >> SRMMU_PPNPASHIFT) & ~0x3);
3598 
3599 	tlb_flush_all_real();
3600 
3601 #ifdef DEBUG
3602 	printf("done.\n");
3603 #endif
3604 }
3605 
3606 void srmmu_restore_prom_ctx __P((void));
3607 
3608 void
3609 srmmu_restore_prom_ctx()
3610 {
3611 	tlb_flush_all();
3612 	sta(SRMMU_CXTPTR, ASI_SRMMU, prom_ctxreg);
3613 	tlb_flush_all();
3614 }
3615 
3616 /*
3617  * Globalize the boot cpu's cpu_info structure.
3618  */
3619 void
3620 pmap_globalize_boot_cpuinfo(cpi)
3621 	struct cpu_info *cpi;
3622 {
3623 	vaddr_t va;
3624 	vsize_t off;
3625 
3626 	off = 0;
3627 	for (va = (vaddr_t)cpi; off < sizeof(*cpi); va += NBPG, off += NBPG) {
3628 		paddr_t pa = VA2PA((caddr_t)CPUINFO_VA + off);
3629 		pmap_kenter_pa(va, pa, VM_PROT_READ | VM_PROT_WRITE);
3630 	}
3631 	pmap_update(pmap_kernel());
3632 }
3633 
3634 /*
3635  * Allocate per-CPU page tables. One region, segment and page table
3636  * is needed to map CPUINFO_VA to different physical addresses on
3637  * each CPU. Since the kernel region and segment tables are all
3638  * pre-wired (in bootstrap() above) and we also assume that the
3639  * first segment (256K) of kernel space is fully populated with
3640  * pages from the start, these per-CPU tables will never need
3641  * to be updated when mapping kernel virtual memory.
3642  *
3643  * Note: this routine is called in the context of the boot CPU
3644  * during autoconfig.
3645  */
3646 void
3647 pmap_alloc_cpu(sc)
3648 	struct cpu_info *sc;
3649 {
3650 	vaddr_t va;
3651 	paddr_t pa;
3652 	paddr_t alignment;
3653 	u_int *ctxtable, *regtable, *segtable, *pagtable;
3654 	u_int *ctxtable_pa, *regtable_pa, *segtable_pa, *pagtable_pa;
3655 	psize_t ctxsize, size;
3656 	int vr, vs, vpg;
3657 	struct regmap *rp;
3658 	struct segmap *sp;
3659 	struct pglist mlist;
3660 	int cachebit;
3661 	int pagesz = NBPG;
3662 
3663 	cachebit = (sc->flags & CPUFLG_CACHEPAGETABLES) != 0;
3664 
3665 	/*
3666 	 * Allocate properly aligned and contiguous physically memory
3667 	 * for the PTE tables.
3668 	 */
3669 	ctxsize = (sc->mmu_ncontext * sizeof(int) + pagesz - 1) & -pagesz;
3670 	alignment = ctxsize;
3671 
3672 	/* The region, segment and page table we need fit in one page */
3673 	size = ctxsize + pagesz;
3674 
3675 	TAILQ_INIT(&mlist);
3676 	if (uvm_pglistalloc(size, vm_first_phys, vm_first_phys+vm_num_phys,
3677 			    alignment, 0, &mlist, 1, 0) != 0)
3678 		panic("pmap_alloc_cpu: no memory");
3679 
3680 	pa = VM_PAGE_TO_PHYS(TAILQ_FIRST(&mlist));
3681 
3682 	/* Allocate virtual memory */
3683 	va = uvm_km_valloc(kernel_map, size);
3684 	if (va == 0)
3685 		panic("pmap_alloc_cpu: no memory");
3686 
3687 	/*
3688 	 * Layout the page tables in our chunk of memory
3689 	 */
3690 	ctxtable = (u_int *)va;
3691 	regtable = (u_int *)(va + ctxsize);
3692 	segtable = regtable + SRMMU_L1SIZE;
3693 	pagtable = segtable + SRMMU_L2SIZE;
3694 
3695 	ctxtable_pa = (u_int *)pa;
3696 	regtable_pa = (u_int *)(pa + ctxsize);
3697 	segtable_pa = regtable_pa + SRMMU_L1SIZE;
3698 	pagtable_pa = segtable_pa + SRMMU_L2SIZE;
3699 
3700 	/* Map the pages */
3701 	while (size != 0) {
3702 		pmap_kenter_pa(va, pa | (cachebit ? 0 : PMAP_NC),
3703 		    VM_PROT_READ | VM_PROT_WRITE);
3704 		va += pagesz;
3705 		pa += pagesz;
3706 		size -= pagesz;
3707 	}
3708 	pmap_update(pmap_kernel());
3709 
3710 	/*
3711 	 * Store the region table pointer (and its corresponding physical
3712 	 * address) in the CPU's slot in the kernel pmap region table
3713 	 * pointer table.
3714 	 */
3715 	pmap_kernel()->pm_reg_ptps[sc->ci_cpuid] = regtable;
3716 	pmap_kernel()->pm_reg_ptps_pa[sc->ci_cpuid] = (paddr_t)regtable_pa;
3717 
3718 	vr = VA_VREG(CPUINFO_VA);
3719 	vs = VA_VSEG(CPUINFO_VA);
3720 	vpg = VA_VPG(CPUINFO_VA);
3721 	rp = &pmap_kernel()->pm_regmap[vr];
3722 	sp = &rp->rg_segmap[vs];
3723 
3724 	/*
3725 	 * Copy page tables from CPU #0, then modify entry for CPUINFO_VA
3726 	 * so that it points at the per-CPU pages.
3727 	 */
3728 	qcopy(pmap_kernel()->pm_reg_ptps[0], regtable,
3729 		SRMMU_L1SIZE * sizeof(int));
3730 	qcopy(rp->rg_seg_ptps, segtable, SRMMU_L2SIZE * sizeof(int));
3731 	qcopy(sp->sg_pte, pagtable, SRMMU_L3SIZE * sizeof(int));
3732 
3733 	setpgt4m(&ctxtable[0],
3734 		 ((u_long)regtable_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
3735 	setpgt4m(&regtable[vr],
3736 		 ((u_long)segtable_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
3737 	setpgt4m(&segtable[vs],
3738 		 ((u_long)pagtable_pa >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
3739 	setpgt4m(&pagtable[vpg],
3740 		(VA2PA((caddr_t)sc) >> SRMMU_PPNPASHIFT) |
3741 		(SRMMU_TEPTE | PPROT_N_RWX | SRMMU_PG_C));
3742 
3743 	/* Install this CPU's context table */
3744 	sc->ctx_tbl = ctxtable;
3745 	sc->ctx_tbl_pa = (paddr_t)ctxtable_pa;
3746 }
3747 #endif /* SUN4M */
3748 
3749 
3750 void
3751 pmap_init()
3752 {
3753 	u_int sizeof_pmap;
3754 	int n, npages;
3755 	vsize_t s;
3756 	vaddr_t va;
3757 
3758 	if (PAGE_SIZE != NBPG)
3759 		panic("pmap_init: PAGE_SIZE!=NBPG");
3760 
3761 	npages = 0;
3762 	for (n = 0; n < vm_nphysseg; n++)
3763 		npages += (vm_physmem[n].end - vm_physmem[n].start);
3764 
3765 	s = (vsize_t)round_page(npages * sizeof(struct pvlist));
3766 	va = (vaddr_t)uvm_km_zalloc(kernel_map, s);
3767 	if (va == 0)
3768 		panic("pmap_init: pv_table");
3769 
3770 	for (n = 0; n < vm_nphysseg; n++) {
3771 		vm_physmem[n].pmseg.pvhead = (struct pvlist *)va;
3772 		va += (vm_physmem[n].end - vm_physmem[n].start) *
3773 			sizeof(struct pvlist);
3774 	}
3775 
3776 	vm_num_phys = vm_last_phys - vm_first_phys;
3777 
3778 	/* Setup a pool for additional pvlist structures */
3779 	pool_init(&pv_pool, sizeof(struct pvlist), 0, 0, 0, "pvtable", NULL);
3780 
3781 	/*
3782 	 * Setup a pool for pmap structures.
3783 	 * The pool size includes space for an array of per-cpu
3784 	 * region table pointers & physical addresses
3785 	 */
3786 	sizeof_pmap = ALIGN(sizeof(struct pmap)) +
3787 		      ALIGN(NUREG * sizeof(struct regmap)) +
3788 		      ncpu * sizeof(int *) +		/* pm_reg_ptps */
3789 		      ncpu * sizeof(int);		/* pm_reg_ptps_pa */
3790 	pool_init(&pmap_pmap_pool, sizeof_pmap, 0, 0, 0, "pmappl",
3791 		  &pool_allocator_nointr);
3792 	pool_cache_init(&pmap_pmap_pool_cache, &pmap_pmap_pool,
3793 			pmap_pmap_pool_ctor, pmap_pmap_pool_dtor, NULL);
3794 
3795 #if defined(SUN4M)
3796 	if (CPU_ISSUN4M) {
3797 		/*
3798 		 * The SRMMU only ever needs chunks in one of two sizes:
3799 		 * 1024 (for region level tables) and 256 (for segment
3800 		 * and page level tables).
3801 		 */
3802 		int n;
3803 
3804 		n = SRMMU_L1SIZE * sizeof(int);
3805 		pool_init(&L1_pool, n, n, 0, 0, "L1 pagetable",
3806 			  &pgt_page_allocator);
3807 
3808 		n = SRMMU_L2SIZE * sizeof(int);
3809 		pool_init(&L23_pool, n, n, 0, 0, "L2/L3 pagetable",
3810 			  &pgt_page_allocator);
3811 	}
3812 #endif
3813 
3814 	pmap_initialized = 1;
3815 }
3816 
3817 
3818 /*
3819  * Map physical addresses into kernel VM.
3820  */
3821 vaddr_t
3822 pmap_map(va, pa, endpa, prot)
3823 	vaddr_t va;
3824 	paddr_t pa, endpa;
3825 	int prot;
3826 {
3827 	int pgsize = PAGE_SIZE;
3828 
3829 	while (pa < endpa) {
3830 		pmap_kenter_pa(va, pa, prot);
3831 		va += pgsize;
3832 		pa += pgsize;
3833 	}
3834 	pmap_update(pmap_kernel());
3835 	return (va);
3836 }
3837 
3838 #ifdef DEBUG
3839 /*
3840  * Check a pmap for spuriously lingering mappings
3841  */
3842 static __inline__ void
3843 pmap_quiet_check(struct pmap *pm)
3844 {
3845 	int vs, vr;
3846 
3847 	if (CPU_ISSUN4OR4C) {
3848 #if defined(SUN4_MMU3L)
3849 		if (pm->pm_reglist.tqh_first)
3850 			panic("pmap_destroy: region list not empty");
3851 #endif
3852 		if (pm->pm_seglist.tqh_first)
3853 			panic("pmap_destroy: segment list not empty");
3854 	}
3855 
3856 	for (vr = 0; vr < NUREG; vr++) {
3857 		struct regmap *rp = &pm->pm_regmap[vr];
3858 
3859 		if (CPU_ISSUN4OR4C) {
3860 #if defined(SUN4_MMU3L)
3861 			if (HASSUN4_MMU3L) {
3862 				if (rp->rg_smeg != reginval)
3863 					printf("pmap_chk: spurious smeg in "
3864 						"user region %d\n", vr);
3865 			}
3866 #endif
3867 		}
3868 		if (CPU_ISSUN4M) {
3869 			int n;
3870 #if defined(MULTIPROCESSOR)
3871 			for (n = 0; n < ncpu; n++)
3872 #else
3873 			n = 0;
3874 #endif
3875 			{
3876 				if (pm->pm_reg_ptps[n][vr] != SRMMU_TEINVALID)
3877 					printf("pmap_chk: spurious PTP in user "
3878 						"region %d on cpu %d\n", vr, n);
3879 			}
3880 		}
3881 		if (rp->rg_nsegmap != 0)
3882 			printf("pmap_chk: %d segments remain in "
3883 				"region %d\n", rp->rg_nsegmap, vr);
3884 		if (rp->rg_segmap != NULL) {
3885 			printf("pmap_chk: segments still "
3886 				"allocated in region %d\n", vr);
3887 			for (vs = 0; vs < NSEGRG; vs++) {
3888 				struct segmap *sp = &rp->rg_segmap[vs];
3889 				if (sp->sg_npte != 0)
3890 					printf("pmap_chk: %d ptes "
3891 					     "remain in segment %d\n",
3892 						sp->sg_npte, vs);
3893 				if (sp->sg_pte != NULL) {
3894 					printf("pmap_chk: ptes still "
3895 					     "allocated in segment %d\n", vs);
3896 				}
3897 			}
3898 		}
3899 	}
3900 }
3901 #endif /* DEBUG */
3902 
3903 int
3904 pmap_pmap_pool_ctor(void *arg, void *object, int flags)
3905 {
3906 	struct pmap *pm = object;
3907 	u_long addr;
3908 
3909 	bzero(pm, sizeof *pm);
3910 
3911 	/*
3912 	 * `pmap_pool' entries include space for the per-CPU
3913 	 * region table pointer arrays.
3914 	 */
3915 	addr = (u_long)pm + ALIGN(sizeof(struct pmap));
3916 	pm->pm_regmap = (void *)addr;
3917 	addr += ALIGN(NUREG * sizeof(struct regmap));
3918 	pm->pm_reg_ptps = (int **)addr;
3919 	addr += ncpu * sizeof(int *);
3920 	pm->pm_reg_ptps_pa = (int *)addr;
3921 
3922 	qzero((caddr_t)pm->pm_regmap, NUREG * sizeof(struct regmap));
3923 
3924 	/* pm->pm_ctx = NULL; */
3925 	simple_lock_init(&pm->pm_lock);
3926 
3927 	if (CPU_ISSUN4OR4C) {
3928 		TAILQ_INIT(&pm->pm_seglist);
3929 #if defined(SUN4_MMU3L)
3930 		TAILQ_INIT(&pm->pm_reglist);
3931 		if (HASSUN4_MMU3L) {
3932 			int i;
3933 			for (i = NUREG; --i >= 0;)
3934 				pm->pm_regmap[i].rg_smeg = reginval;
3935 		}
3936 #endif
3937 		pm->pm_gap_end = VA_VREG(VM_MAXUSER_ADDRESS);
3938 	}
3939 #if defined(SUN4M)
3940 	else {
3941 		int i, n;
3942 
3943 		/*
3944 		 * We must allocate and initialize hardware-readable (MMU)
3945 		 * pagetables. We must also map the kernel regions into this
3946 		 * pmap's pagetables, so that we can access the kernel from
3947 		 * this user context.
3948 		 *
3949 		 */
3950 #if defined(MULTIPROCESSOR)
3951 		for (n = 0; n < ncpu; n++)
3952 #else
3953 		n = 0;
3954 #endif
3955 		{
3956 			int *upt, *kpt;
3957 
3958 			upt = pool_get(&L1_pool, flags);
3959 			pm->pm_reg_ptps[n] = upt;
3960 			pm->pm_reg_ptps_pa[n] = VA2PA((char *)upt);
3961 
3962 			/* Invalidate user space regions */
3963 			for (i = 0; i < NUREG; i++)
3964 				setpgt4m(upt++, SRMMU_TEINVALID);
3965 
3966 			/* Copy kernel regions */
3967 			kpt = &pmap_kernel()->pm_reg_ptps[n][VA_VREG(KERNBASE)];
3968 			for (i = 0; i < NKREG; i++) {
3969 				int j = kpt[i];
3970 
3971 				setpgt4m(upt++, j);
3972 			}
3973 		}
3974 	}
3975 #endif
3976 
3977 	return (0);
3978 }
3979 
3980 void
3981 pmap_pmap_pool_dtor(void *arg, void *object)
3982 {
3983 	struct pmap *pm = object;
3984 	union ctxinfo *c;
3985 	int s = splvm();	/* paranoia */
3986 
3987 #ifdef DEBUG
3988 	if (pmapdebug & PDB_DESTROY)
3989 		printf("pmap_pmap_pool_dtor(%p)\n", pm);
3990 #endif
3991 
3992 	if ((c = pm->pm_ctx) != NULL) {
3993 		ctx_free(pm);
3994 	}
3995 
3996 #if defined(SUN4M)
3997 	if (CPU_ISSUN4M) {
3998 		int n;
3999 
4000 #if defined(MULTIPROCESSOR)
4001 		for (n = 0; n < ncpu; n++)
4002 #else
4003 		n = 0;
4004 #endif
4005 		{
4006 			int *pt = pm->pm_reg_ptps[n];
4007 			pm->pm_reg_ptps[n] = NULL;
4008 			pm->pm_reg_ptps_pa[n] = 0;
4009 			pool_put(&L1_pool, pt);
4010 		}
4011 	}
4012 #endif
4013 	splx(s);
4014 }
4015 
4016 /*
4017  * Create and return a physical map.
4018  */
4019 struct pmap *
4020 pmap_create()
4021 {
4022 	struct pmap *pm;
4023 
4024 	pm = pool_cache_get(&pmap_pmap_pool_cache, PR_WAITOK);
4025 	pm->pm_refcount = 1;
4026 #ifdef DEBUG
4027 	if (pmapdebug & PDB_CREATE)
4028 		printf("pmap_create: created %p\n", pm);
4029 	pmap_quiet_check(pm);
4030 #endif
4031 	return (pm);
4032 }
4033 
4034 /*
4035  * Retire the given pmap from service.
4036  * Should only be called if the map contains no valid mappings.
4037  */
4038 void
4039 pmap_destroy(pm)
4040 	struct pmap *pm;
4041 {
4042 	int count;
4043 
4044 #ifdef DEBUG
4045 	if (pmapdebug & PDB_DESTROY)
4046 		printf("pmap_destroy(%p)\n", pm);
4047 #endif
4048 	simple_lock(&pm->pm_lock);
4049 	count = --pm->pm_refcount;
4050 	simple_unlock(&pm->pm_lock);
4051 	if (count == 0) {
4052 #ifdef DEBUG
4053 		pmap_quiet_check(pm);
4054 #endif
4055 		pool_cache_put(&pmap_pmap_pool_cache, pm);
4056 	}
4057 }
4058 
4059 /*
4060  * Add a reference to the given pmap.
4061  */
4062 void
4063 pmap_reference(pm)
4064 	struct pmap *pm;
4065 {
4066 	simple_lock(&pm->pm_lock);
4067 	pm->pm_refcount++;
4068 	simple_unlock(&pm->pm_lock);
4069 }
4070 
4071 /*
4072  * Remove the given range of mapping entries.
4073  * The starting and ending addresses are already rounded to pages.
4074  * Sheer lunacy: pmap_remove is often asked to remove nonexistent
4075  * mappings.
4076  */
4077 void
4078 pmap_remove(pm, va, endva)
4079 	struct pmap *pm;
4080 	vaddr_t va, endva;
4081 {
4082 	vaddr_t nva;
4083 	int vr, vs, s, ctx;
4084 	void (*rm)(struct pmap *, vaddr_t, vaddr_t, int, int);
4085 
4086 #ifdef DEBUG
4087 	if (pmapdebug & PDB_REMOVE)
4088 		printf("pmap_remove(%p, 0x%lx, 0x%lx)\n", pm, va, endva);
4089 #endif
4090 
4091 	if (pm == pmap_kernel()) {
4092 		/*
4093 		 * Removing from kernel address space.
4094 		 */
4095 		rm = pmap_rmk;
4096 	} else {
4097 		/*
4098 		 * Removing from user address space.
4099 		 */
4100 		write_user_windows();
4101 		rm = pmap_rmu;
4102 	}
4103 
4104 	ctx = getcontext();
4105 	s = splvm();		/* XXX conservative */
4106 	simple_lock(&pm->pm_lock);
4107 	for (; va < endva; va = nva) {
4108 		/* do one virtual segment at a time */
4109 		vr = VA_VREG(va);
4110 		vs = VA_VSEG(va);
4111 		nva = VSTOVA(vr, vs + 1);
4112 		if (nva == 0 || nva > endva)
4113 			nva = endva;
4114 		if (pm->pm_regmap[vr].rg_nsegmap != 0)
4115 			(*rm)(pm, va, nva, vr, vs);
4116 	}
4117 	simple_unlock(&pm->pm_lock);
4118 	splx(s);
4119 	setcontext(ctx);
4120 }
4121 
4122 /*
4123  * The following magic number was chosen because:
4124  *	1. It is the same amount of work to cache_flush_page 4 pages
4125  *	   as to cache_flush_segment 1 segment (so at 4 the cost of
4126  *	   flush is the same).
4127  *	2. Flushing extra pages is bad (causes cache not to work).
4128  *	3. The current code, which malloc()s 5 pages for each process
4129  *	   for a user vmspace/pmap, almost never touches all 5 of those
4130  *	   pages.
4131  */
4132 #if 0
4133 #define	PMAP_RMK_MAGIC	(cacheinfo.c_hwflush?5:64)	/* if > magic, use cache_flush_segment */
4134 #else
4135 #define	PMAP_RMK_MAGIC	5	/* if > magic, use cache_flush_segment */
4136 #endif
4137 
4138 /*
4139  * Remove a range contained within a single segment.
4140  * These are egregiously complicated routines.
4141  */
4142 
4143 #if defined(SUN4) || defined(SUN4C)
4144 
4145 /* remove from kernel */
4146 /*static*/ void
4147 pmap_rmk4_4c(pm, va, endva, vr, vs)
4148 	struct pmap *pm;
4149 	vaddr_t va, endva;
4150 	int vr, vs;
4151 {
4152 	int i, tpte, perpage, npg;
4153 	struct pvlist *pv;
4154 	int nleft, pmeg;
4155 	struct regmap *rp;
4156 	struct segmap *sp;
4157 
4158 	rp = &pm->pm_regmap[vr];
4159 	sp = &rp->rg_segmap[vs];
4160 
4161 	if (rp->rg_nsegmap == 0)
4162 		return;
4163 	if ((nleft = sp->sg_npte) == 0)
4164 		return;
4165 	pmeg = sp->sg_pmeg;
4166 	setcontext4(0);
4167 	/* decide how to flush cache */
4168 	npg = (endva - va) >> PGSHIFT;
4169 	if (npg > PMAP_RMK_MAGIC) {
4170 		/* flush the whole segment */
4171 		perpage = 0;
4172 		cache_flush_segment(vr, vs);
4173 	} else {
4174 		/* flush each page individually; some never need flushing */
4175 		perpage = (CACHEINFO.c_vactype != VAC_NONE);
4176 	}
4177 	while (va < endva) {
4178 		tpte = getpte4(va);
4179 		if ((tpte & PG_V) == 0) {
4180 			va += NBPG;
4181 			continue;
4182 		}
4183 		if ((tpte & PG_TYPE) == PG_OBMEM) {
4184 			u_int pfn = tpte & PG_PFNUM;
4185 			/* if cacheable, flush page as needed */
4186 			if (perpage && (tpte & PG_NC) == 0)
4187 				cache_flush_page(va);
4188 			if ((pv = pvhead(pfn)) != NULL) {
4189 				pv->pv_flags |= MR4_4C(tpte);
4190 				pv_unlink4_4c(pv, pm, va);
4191 			}
4192 		}
4193 		nleft--;
4194 #ifdef DIAGNOSTIC
4195 		if (nleft < 0)
4196 			panic("pmap_rmk: too many PTEs in segment; "
4197 			      "va 0x%lx; endva 0x%lx", va, endva);
4198 #endif
4199 		setpte4(va, 0);
4200 		va += NBPG;
4201 	}
4202 
4203 	/*
4204 	 * If the segment is all gone, remove it from everyone and
4205 	 * free the MMU entry.
4206 	 */
4207 	if ((sp->sg_npte = nleft) == 0) {
4208 		va = VSTOVA(vr,vs);		/* retract */
4209 #if defined(SUN4_MMU3L)
4210 		if (HASSUN4_MMU3L)
4211 			setsegmap(va, seginval);
4212 		else
4213 #endif
4214 			for (i = ncontext; --i >= 0;) {
4215 				setcontext4(i);
4216 				setsegmap(va, seginval);
4217 			}
4218 		me_free(pm, pmeg);
4219 		if (--rp->rg_nsegmap == 0) {
4220 #if defined(SUN4_MMU3L)
4221 			if (HASSUN4_MMU3L) {
4222 				for (i = ncontext; --i >= 0;) {
4223 					setcontext4(i);
4224 					setregmap(va, reginval);
4225 				}
4226 				/* note: context is 0 */
4227 				region_free(pm, rp->rg_smeg);
4228 			}
4229 #endif
4230 		}
4231 	}
4232 }
4233 
4234 #endif /* sun4, sun4c */
4235 
4236 #if defined(SUN4M)		/* 4M version of pmap_rmk */
4237 /* remove from kernel (4m)*/
4238 /*static*/ void
4239 /* pm is already locked */
4240 pmap_rmk4m(pm, va, endva, vr, vs)
4241 	struct pmap *pm;
4242 	vaddr_t va, endva;
4243 	int vr, vs;
4244 {
4245 	int tpte, perpage, npg;
4246 	struct pvlist *pv;
4247 	int nleft;
4248 	struct regmap *rp;
4249 	struct segmap *sp;
4250 
4251 	rp = &pm->pm_regmap[vr];
4252 	sp = &rp->rg_segmap[vs];
4253 	if (rp->rg_nsegmap == 0)
4254 		return;
4255 	if ((nleft = sp->sg_npte) == 0)
4256 		return;
4257 	setcontext4m(0);
4258 	/* decide how to flush cache */
4259 	npg = (endva - va) >> PGSHIFT;
4260 	if (npg > PMAP_RMK_MAGIC) {
4261 		/* flush the whole segment */
4262 		perpage = 0;
4263 		if (CACHEINFO.c_vactype != VAC_NONE)
4264 			cache_flush_segment(vr, vs);
4265 	} else {
4266 		/* flush each page individually; some never need flushing */
4267 		perpage = (CACHEINFO.c_vactype != VAC_NONE);
4268 	}
4269 	while (va < endva) {
4270 		tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
4271 		if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) {
4272 #ifdef DEBUG
4273 			if ((pmapdebug & PDB_SANITYCHK) &&
4274 			    (getpte4m(va) & SRMMU_TETYPE) == SRMMU_TEPTE)
4275 				panic("pmap_rmk: Spurious kTLB entry for 0x%lx",
4276 				      va);
4277 #endif
4278 			va += NBPG;
4279 			continue;
4280 		}
4281 		if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) {
4282 			u_int pfn = (tpte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT;
4283 			/* if cacheable, flush page as needed */
4284 			if (perpage && (tpte & SRMMU_PG_C))
4285 				cache_flush_page(va);
4286 			if ((pv = pvhead(pfn)) != NULL) {
4287 				pv->pv_flags |= MR4M(tpte);
4288 				pv_unlink4m(pv, pm, va);
4289 			}
4290 		}
4291 		setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)],
4292 		    SRMMU_TEINVALID, 1);
4293 		nleft--;
4294 #ifdef DIAGNOSTIC
4295 		if (nleft < 0)
4296 			panic("pmap_rmk: too many PTEs in segment; "
4297 			      "va 0x%lx; endva 0x%lx", va, endva);
4298 #endif
4299 		va += NBPG;
4300 	}
4301 
4302 	sp->sg_npte = nleft;
4303 }
4304 #endif /* SUN4M */
4305 
4306 /*
4307  * Just like pmap_rmk_magic, but we have a different threshold.
4308  * Note that this may well deserve further tuning work.
4309  */
4310 #if 0
4311 #define	PMAP_RMU_MAGIC	(cacheinfo.c_hwflush?4:64)	/* if > magic, use cache_flush_segment */
4312 #else
4313 #define	PMAP_RMU_MAGIC	4	/* if > magic, use cache_flush_segment */
4314 #endif
4315 
4316 #if defined(SUN4) || defined(SUN4C)
4317 
4318 /* remove from user */
4319 /*static*/ void
4320 pmap_rmu4_4c(pm, va, endva, vr, vs)
4321 	struct pmap *pm;
4322 	vaddr_t va, endva;
4323 	int vr, vs;
4324 {
4325 	int *pte0, pteva, tpte, perpage, npg;
4326 	struct pvlist *pv;
4327 	int nleft, pmeg;
4328 	struct regmap *rp;
4329 	struct segmap *sp;
4330 
4331 	rp = &pm->pm_regmap[vr];
4332 	if (rp->rg_nsegmap == 0)
4333 		return;
4334 	sp = &rp->rg_segmap[vs];
4335 	if ((nleft = sp->sg_npte) == 0)
4336 		return;
4337 	pmeg = sp->sg_pmeg;
4338 	pte0 = sp->sg_pte;
4339 	if (pmeg == seginval) {
4340 		int *pte = pte0 + VA_VPG(va);
4341 
4342 		/*
4343 		 * PTEs are not in MMU.  Just invalidate software copies.
4344 		 */
4345 		for (; va < endva; pte++, va += NBPG) {
4346 			tpte = *pte;
4347 			if ((tpte & PG_V) == 0) {
4348 				/* nothing to remove (braindead VM layer) */
4349 				continue;
4350 			}
4351 			if ((tpte & PG_TYPE) == PG_OBMEM) {
4352 				u_int pfn = tpte & PG_PFNUM;
4353 				if ((pv = pvhead(pfn)) != NULL)
4354 					pv_unlink4_4c(pv, pm, va);
4355 			}
4356 			nleft--;
4357 #ifdef DIAGNOSTIC
4358 			if (nleft < 0)
4359 				panic("pmap_rmu: too many PTEs in segment; "
4360 				      "va 0x%lx; endva 0x%lx", va, endva);
4361 #endif
4362 			*pte = 0;
4363 		}
4364 		if ((sp->sg_npte = nleft) == 0) {
4365 			free(pte0, M_VMPMAP);
4366 			sp->sg_pte = NULL;
4367 			if (--rp->rg_nsegmap == 0) {
4368 				free(rp->rg_segmap, M_VMPMAP);
4369 				rp->rg_segmap = NULL;
4370 #if defined(SUN4_MMU3L)
4371 				if (HASSUN4_MMU3L && rp->rg_smeg != reginval) {
4372 					if (pm->pm_ctx) {
4373 						setcontext4(pm->pm_ctxnum);
4374 						setregmap(va, reginval);
4375 					} else
4376 						setcontext4(0);
4377 					region_free(pm, rp->rg_smeg);
4378 				}
4379 #endif
4380 			}
4381 		}
4382 		return;
4383 	}
4384 
4385 	/*
4386 	 * PTEs are in MMU.  Invalidate in hardware, update ref &
4387 	 * mod bits, and flush cache if required.
4388 	 */
4389 	if (CTX_USABLE(pm,rp)) {
4390 		/* process has a context, must flush cache */
4391 		npg = (endva - va) >> PGSHIFT;
4392 		setcontext4(pm->pm_ctxnum);
4393 		if (npg > PMAP_RMU_MAGIC) {
4394 			perpage = 0; /* flush the whole segment */
4395 			cache_flush_segment(vr, vs);
4396 		} else
4397 			perpage = (CACHEINFO.c_vactype != VAC_NONE);
4398 		pteva = va;
4399 	} else {
4400 		/* no context, use context 0; cache flush unnecessary */
4401 		setcontext4(0);
4402 		if (HASSUN4_MMU3L)
4403 			setregmap(0, tregion);
4404 		/* XXX use per-cpu pteva? */
4405 		setsegmap(0, pmeg);
4406 		pteva = VA_VPG(va) << PGSHIFT;
4407 		perpage = 0;
4408 	}
4409 	for (; va < endva; pteva += NBPG, va += NBPG) {
4410 		tpte = getpte4(pteva);
4411 		if ((tpte & PG_V) == 0)
4412 			continue;
4413 		if ((tpte & PG_TYPE) == PG_OBMEM) {
4414 			u_int pfn = tpte & PG_PFNUM;
4415 			/* if cacheable, flush page as needed */
4416 			if (perpage && (tpte & PG_NC) == 0)
4417 				cache_flush_page(va);
4418 			if ((pv = pvhead(pfn)) != NULL) {
4419 				pv->pv_flags |= MR4_4C(tpte);
4420 				pv_unlink4_4c(pv, pm, va);
4421 			}
4422 		}
4423 		nleft--;
4424 #ifdef DIAGNOSTIC
4425 		if (nleft < 0)
4426 			panic("pmap_rmu: too many PTEs in segment; "
4427 			     "va 0x%lx; endva 0x%lx; pmeg %d", va, endva, pmeg);
4428 #endif
4429 		setpte4(pteva, 0);
4430 		pte0[VA_VPG(pteva)] = 0;
4431 	}
4432 
4433 	/*
4434 	 * If the segment is all gone, and the context is loaded, give
4435 	 * the segment back.
4436 	 */
4437 
4438 	sp->sg_npte = nleft;
4439 	if (nleft == 0) {
4440 		va = VSTOVA(vr,vs);
4441 		if (CTX_USABLE(pm,rp))
4442 			setsegmap(va, seginval);
4443 		else if (HASSUN4_MMU3L && rp->rg_smeg != reginval) {
4444 			/* note: context already set earlier */
4445 			setregmap(0, rp->rg_smeg);
4446 			setsegmap(vs << SGSHIFT, seginval);
4447 		}
4448 		free(pte0, M_VMPMAP);
4449 		sp->sg_pte = NULL;
4450 		me_free(pm, pmeg);
4451 
4452 		if (--rp->rg_nsegmap == 0) {
4453 			free(rp->rg_segmap, M_VMPMAP);
4454 			rp->rg_segmap = NULL;
4455 			GAP_WIDEN(pm,vr);
4456 
4457 #if defined(SUN4_MMU3L)
4458 			if (HASSUN4_MMU3L && rp->rg_smeg != reginval) {
4459 				/* note: context already set */
4460 				if (pm->pm_ctx)
4461 					setregmap(va, reginval);
4462 				region_free(pm, rp->rg_smeg);
4463 			}
4464 #endif
4465 		}
4466 	}
4467 }
4468 
4469 #endif /* sun4,4c */
4470 
4471 #if defined(SUN4M)		/* 4M version of pmap_rmu */
4472 /* remove from user */
4473 /* Note: pm is already locked */
4474 /*static*/ void
4475 pmap_rmu4m(pm, va, endva, vr, vs)
4476 	struct pmap *pm;
4477 	vaddr_t va, endva;
4478 	int vr, vs;
4479 {
4480 	int *pte0, perpage, npg;
4481 	struct pvlist *pv;
4482 	int nleft;
4483 	struct regmap *rp;
4484 	struct segmap *sp;
4485 
4486 	rp = &pm->pm_regmap[vr];
4487 	if (rp->rg_nsegmap == 0)
4488 		return;
4489 	sp = &rp->rg_segmap[vs];
4490 	if ((nleft = sp->sg_npte) == 0)
4491 		return;
4492 	pte0 = sp->sg_pte;
4493 
4494 	/*
4495 	 * Invalidate PTE in MMU pagetables. Flush cache if necessary.
4496 	 */
4497 	if (pm->pm_ctx) {
4498 		/* process has a context, must flush cache */
4499 		setcontext4m(pm->pm_ctxnum);
4500 		if (CACHEINFO.c_vactype != VAC_NONE) {
4501 			npg = (endva - va) >> PGSHIFT;
4502 			if (npg > PMAP_RMU_MAGIC) {
4503 				perpage = 0; /* flush the whole segment */
4504 				cache_flush_segment(vr, vs);
4505 			} else
4506 				perpage = 1;
4507 		} else
4508 			perpage = 0;
4509 	} else {
4510 		/* no context; cache flush unnecessary */
4511 		perpage = 0;
4512 	}
4513 	for (; va < endva; va += NBPG) {
4514 		int tpte;
4515 
4516 		tpte = pte0[VA_SUN4M_VPG(va)];
4517 
4518 		if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) {
4519 #ifdef DEBUG
4520 			if ((pmapdebug & PDB_SANITYCHK) &&
4521 			    pm->pm_ctx &&
4522 			    (getpte4m(va) & SRMMU_TEPTE) == SRMMU_TEPTE)
4523 				panic("pmap_rmu: Spurious uTLB entry for 0x%lx",
4524 				      va);
4525 #endif
4526 			continue;
4527 		}
4528 
4529 		if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) {
4530 			u_int pfn = (tpte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT;
4531 			/* if cacheable, flush page as needed */
4532 			if (perpage && (tpte & SRMMU_PG_C))
4533 				cache_flush_page(va);
4534 			if ((pv = pvhead(pfn)) != NULL) {
4535 				pv->pv_flags |= MR4M(tpte);
4536 				pv_unlink4m(pv, pm, va);
4537 			}
4538 		}
4539 		nleft--;
4540 #ifdef DIAGNOSTIC
4541 		if (nleft < 0)
4542 			panic("pmap_rmu: too many PTEs in segment; "
4543 			      "va 0x%lx; endva 0x%lx", va, endva);
4544 #endif
4545 		setpgt4m_va(va, &pte0[VA_SUN4M_VPG(va)], SRMMU_TEINVALID,
4546 		    pm->pm_ctx != NULL);
4547 	}
4548 
4549 	/*
4550 	 * If the segment is all gone, and the context is loaded, give
4551 	 * the segment back.
4552 	 */
4553 	if ((sp->sg_npte = nleft) == 0) {
4554 		va = VSTOVA(vr,vs);
4555 
4556 		if (pm->pm_ctx)
4557 			tlb_flush_segment(vr, vs); 	/* Paranoia? */
4558 		setpgt4m_va(va, &rp->rg_seg_ptps[vs], SRMMU_TEINVALID, 0);
4559 		sp->sg_pte = NULL;
4560 		pool_put(&L23_pool, pte0);
4561 
4562 		if (--rp->rg_nsegmap == 0) {
4563 			int n;
4564 
4565 			if (pm->pm_ctx)
4566 				tlb_flush_region(vr); 	/* Paranoia? */
4567 #ifdef MULTIPROCESSOR
4568 			for (n = 0; n < ncpu; n++)
4569 #else
4570 			n = 0;
4571 #endif
4572 			{
4573 				setpgt4m(&pm->pm_reg_ptps[n][vr],
4574 					 SRMMU_TEINVALID);
4575 			}
4576 			free(rp->rg_segmap, M_VMPMAP);
4577 			rp->rg_segmap = NULL;
4578 			pool_put(&L23_pool, rp->rg_seg_ptps);
4579 		}
4580 	}
4581 }
4582 #endif /* SUN4M */
4583 
4584 /*
4585  * Lower (make more strict) the protection on the specified
4586  * physical page.
4587  *
4588  * There are only two cases: either the protection is going to 0
4589  * (in which case we do the dirty work here), or it is going from
4590  * to read-only (in which case pv_changepte does the trick).
4591  */
4592 
4593 #if defined(SUN4) || defined(SUN4C)
4594 void
4595 pmap_page_protect4_4c(pg, prot)
4596 	struct vm_page *pg;
4597 	vm_prot_t prot;
4598 {
4599 	struct pvlist *pv, *pv0, *npv;
4600 	struct pmap *pm;
4601 	int va, vr, vs, pteva, tpte;
4602 	int flags, nleft, i, s, ctx;
4603 	struct regmap *rp;
4604 	struct segmap *sp;
4605 	paddr_t pa = VM_PAGE_TO_PHYS(pg);
4606 
4607 #ifdef DEBUG
4608 	if ((pmapdebug & PDB_CHANGEPROT) ||
4609 	    (pmapdebug & PDB_REMOVE && prot == VM_PROT_NONE))
4610 		printf("pmap_page_protect(0x%lx, 0x%x)\n", pa, prot);
4611 #endif
4612 	/*
4613 	 * Skip unmanaged pages.
4614 	 */
4615 	if ((pv = pvhead(atop(pa))) == NULL)
4616 		return;
4617 
4618 	write_user_windows();	/* paranoia */
4619 	if (prot & VM_PROT_READ) {
4620 		pv_changepte4_4c(pv, 0, PG_W);
4621 		return;
4622 	}
4623 
4624 	/*
4625 	 * Remove all access to all people talking to this page.
4626 	 * Walk down PV list, removing all mappings.
4627 	 * The logic is much like that for pmap_remove,
4628 	 * but we know we are removing exactly one page.
4629 	 */
4630 	s = splvm();
4631 	if (pv->pv_pmap == NULL) {
4632 		splx(s);
4633 		return;
4634 	}
4635 	ctx = getcontext4();
4636 	pv0 = pv;
4637 
4638 	/* This pv head will become empty, so clear caching state flags */
4639 	flags = pv->pv_flags & ~(PV_NC|PV_ANC);
4640 
4641 	while (pv != NULL) {
4642 		pm = pv->pv_pmap;
4643 		va = pv->pv_va;
4644 		vr = VA_VREG(va);
4645 		vs = VA_VSEG(va);
4646 		rp = &pm->pm_regmap[vr];
4647 		sp = &rp->rg_segmap[vs];
4648 		nleft = sp->sg_npte;
4649 		sp->sg_npte = --nleft;
4650 
4651 		if (sp->sg_pmeg == seginval) {
4652 			/* Definitely not a kernel map */
4653 			if (nleft) {
4654 				sp->sg_pte[VA_VPG(va)] = 0;
4655 			} else {
4656 				free(sp->sg_pte, M_VMPMAP);
4657 				sp->sg_pte = NULL;
4658 				if (--rp->rg_nsegmap == 0) {
4659 					free(rp->rg_segmap, M_VMPMAP);
4660 					rp->rg_segmap = NULL;
4661 					GAP_WIDEN(pm,vr);
4662 #if defined(SUN4_MMU3L)
4663 					if (HASSUN4_MMU3L && rp->rg_smeg != reginval) {
4664 						if (pm->pm_ctx) {
4665 							setcontext4(pm->pm_ctxnum);
4666 							setregmap(va, reginval);
4667 						} else
4668 							setcontext4(0);
4669 						region_free(pm, rp->rg_smeg);
4670 					}
4671 #endif
4672 				}
4673 			}
4674 			goto nextpv;
4675 		}
4676 
4677 		if (CTX_USABLE(pm,rp)) {
4678 			setcontext4(pm->pm_ctxnum);
4679 			pteva = va;
4680 			cache_flush_page(va);
4681 		} else {
4682 			setcontext4(0);
4683 			/* XXX use per-cpu pteva? */
4684 			if (HASSUN4_MMU3L)
4685 				setregmap(0, tregion);
4686 			setsegmap(0, sp->sg_pmeg);
4687 			pteva = VA_VPG(va) << PGSHIFT;
4688 		}
4689 
4690 		tpte = getpte4(pteva);
4691 #ifdef	DIAGNOSTIC
4692 		if ((tpte & PG_V) == 0)
4693 			panic("pmap_page_protect !PG_V: "
4694 			      "ctx %d, va 0x%x, pte 0x%x",
4695 			      pm->pm_ctxnum, va, tpte);
4696 #endif
4697 		flags |= MR4_4C(tpte);
4698 
4699 		if (nleft) {
4700 			setpte4(pteva, 0);
4701 			if (sp->sg_pte != NULL)
4702 				sp->sg_pte[VA_VPG(pteva)] = 0;
4703 			goto nextpv;
4704 		}
4705 
4706 		/* Entire segment is gone */
4707 		if (pm == pmap_kernel()) {
4708 #if defined(SUN4_MMU3L)
4709 			if (!HASSUN4_MMU3L)
4710 #endif
4711 				for (i = ncontext; --i >= 0;) {
4712 					setcontext4(i);
4713 					setsegmap(va, seginval);
4714 				}
4715 			me_free(pm, sp->sg_pmeg);
4716 			if (--rp->rg_nsegmap == 0) {
4717 #if defined(SUN4_MMU3L)
4718 				if (HASSUN4_MMU3L) {
4719 					for (i = ncontext; --i >= 0;) {
4720 						setcontext4(i);
4721 						setregmap(va, reginval);
4722 					}
4723 					region_free(pm, rp->rg_smeg);
4724 				}
4725 #endif
4726 			}
4727 		} else {
4728 			if (CTX_USABLE(pm,rp))
4729 				/* `pteva'; we might be using tregion */
4730 				setsegmap(pteva, seginval);
4731 #if defined(SUN4_MMU3L)
4732 			else if (HASSUN4_MMU3L &&
4733 				 rp->rg_smeg != reginval) {
4734 				/* note: context already set earlier */
4735 				setregmap(0, rp->rg_smeg);
4736 				setsegmap(vs << SGSHIFT, seginval);
4737 			}
4738 #endif
4739 			free(sp->sg_pte, M_VMPMAP);
4740 			sp->sg_pte = NULL;
4741 			me_free(pm, sp->sg_pmeg);
4742 
4743 			if (--rp->rg_nsegmap == 0) {
4744 #if defined(SUN4_MMU3L)
4745 				if (HASSUN4_MMU3L &&
4746 				    rp->rg_smeg != reginval) {
4747 					if (pm->pm_ctx)
4748 						setregmap(va, reginval);
4749 					region_free(pm, rp->rg_smeg);
4750 				}
4751 #endif
4752 				free(rp->rg_segmap, M_VMPMAP);
4753 				rp->rg_segmap = NULL;
4754 				GAP_WIDEN(pm,vr);
4755 			}
4756 		}
4757 
4758 	nextpv:
4759 		npv = pv->pv_next;
4760 		if (pv != pv0)
4761 			pool_put(&pv_pool, pv);
4762 		pv = npv;
4763 	}
4764 
4765 	/* Finally, update pv head */
4766 	pv0->pv_pmap = NULL;
4767 	pv0->pv_next = NULL;
4768 	pv0->pv_flags = flags;
4769 	setcontext4(ctx);
4770 	splx(s);
4771 }
4772 
4773 /*
4774  * Lower (make more strict) the protection on the specified
4775  * range of this pmap.
4776  *
4777  * There are only two cases: either the protection is going to 0
4778  * (in which case we call pmap_remove to do the dirty work), or
4779  * it is going from read/write to read-only.  The latter is
4780  * fairly easy.
4781  */
4782 void
4783 pmap_protect4_4c(pm, sva, eva, prot)
4784 	struct pmap *pm;
4785 	vaddr_t sva, eva;
4786 	vm_prot_t prot;
4787 {
4788 	int va, nva, vr, vs;
4789 	int s, ctx;
4790 	struct regmap *rp;
4791 	struct segmap *sp;
4792 
4793 	if ((prot & VM_PROT_READ) == 0) {
4794 		pmap_remove(pm, sva, eva);
4795 		return;
4796 	}
4797 
4798 	write_user_windows();
4799 	ctx = getcontext4();
4800 	s = splvm();
4801 	simple_lock(&pm->pm_lock);
4802 	for (va = sva; va < eva;) {
4803 		vr = VA_VREG(va);
4804 		vs = VA_VSEG(va);
4805 		rp = &pm->pm_regmap[vr];
4806 		nva = VSTOVA(vr,vs + 1);
4807 		if (nva > eva)
4808 			nva = eva;
4809 		if (rp->rg_nsegmap == 0) {
4810 			va = nva;
4811 			continue;
4812 		}
4813 #ifdef DEBUG
4814 		if (rp->rg_segmap == NULL)
4815 			panic("pmap_protect: no segments");
4816 #endif
4817 		sp = &rp->rg_segmap[vs];
4818 		if (sp->sg_npte == 0) {
4819 			va = nva;
4820 			continue;
4821 		}
4822 #ifdef DEBUG
4823 		if (pm != pmap_kernel() && sp->sg_pte == NULL)
4824 			panic("pmap_protect: no pages");
4825 #endif
4826 		if (sp->sg_pmeg == seginval) {
4827 			int *pte = &sp->sg_pte[VA_VPG(va)];
4828 
4829 			/* not in MMU; just clear PG_W from core copies */
4830 			for (; va < nva; va += NBPG)
4831 				*pte++ &= ~PG_W;
4832 		} else {
4833 			/* in MMU: take away write bits from MMU PTEs */
4834 			if (CTX_USABLE(pm,rp)) {
4835 				int tpte;
4836 
4837 				/*
4838 				 * Flush cache so that any existing cache
4839 				 * tags are updated.  This is really only
4840 				 * needed for PTEs that lose PG_W.
4841 				 */
4842 				setcontext4(pm->pm_ctxnum);
4843 				for (; va < nva; va += NBPG) {
4844 					tpte = getpte4(va);
4845 					pmap_stats.ps_npg_prot_all++;
4846 					if ((tpte & (PG_W|PG_TYPE)) ==
4847 					    (PG_W|PG_OBMEM)) {
4848 						pmap_stats.ps_npg_prot_actual++;
4849 						cache_flush_page(va);
4850 						setpte4(va, tpte & ~PG_W);
4851 					}
4852 				}
4853 			} else {
4854 				int pteva;
4855 
4856 				/*
4857 				 * No context, hence not cached;
4858 				 * just update PTEs.
4859 				 */
4860 				setcontext4(0);
4861 				/* XXX use per-cpu pteva? */
4862 				if (HASSUN4_MMU3L)
4863 					setregmap(0, tregion);
4864 				setsegmap(0, sp->sg_pmeg);
4865 				pteva = VA_VPG(va) << PGSHIFT;
4866 				for (; va < nva; pteva += NBPG, va += NBPG)
4867 					setpte4(pteva, getpte4(pteva) & ~PG_W);
4868 			}
4869 		}
4870 	}
4871 	simple_unlock(&pm->pm_lock);
4872 	splx(s);
4873 	setcontext4(ctx);
4874 }
4875 
4876 /*
4877  * Change the protection and/or wired status of the given (MI) virtual page.
4878  * XXX: should have separate function (or flag) telling whether only wiring
4879  * is changing.
4880  */
4881 void
4882 pmap_changeprot4_4c(pm, va, prot, wired)
4883 	struct pmap *pm;
4884 	vaddr_t va;
4885 	vm_prot_t prot;
4886 	int wired;
4887 {
4888 	int vr, vs, tpte, newprot, ctx, s;
4889 	struct regmap *rp;
4890 	struct segmap *sp;
4891 
4892 #ifdef DEBUG
4893 	if (pmapdebug & PDB_CHANGEPROT)
4894 		printf("pmap_changeprot(%p, 0x%lx, 0x%x, 0x%x)\n",
4895 		    pm, va, prot, wired);
4896 #endif
4897 
4898 	write_user_windows();	/* paranoia */
4899 
4900 	va &= ~(NBPG-1);
4901 	if (pm == pmap_kernel())
4902 		newprot = prot & VM_PROT_WRITE ? PG_S|PG_W : PG_S;
4903 	else
4904 		newprot = prot & VM_PROT_WRITE ? PG_W : 0;
4905 	vr = VA_VREG(va);
4906 	vs = VA_VSEG(va);
4907 	s = splvm();		/* conservative */
4908 	rp = &pm->pm_regmap[vr];
4909 	sp = &rp->rg_segmap[vs];
4910 	pmap_stats.ps_changeprots++;
4911 
4912 	/* update PTEs in software or hardware */
4913 	if (sp->sg_pmeg == seginval) {
4914 		int *pte = &sp->sg_pte[VA_VPG(va)];
4915 
4916 		/* update in software */
4917 		*pte = (*pte & ~PG_PROT) | newprot;
4918 	} else {
4919 		/* update in hardware */
4920 		ctx = getcontext4();
4921 		if (CTX_USABLE(pm,rp)) {
4922 			/*
4923 			 * Use current context.
4924 			 * Flush cache if page has been referenced to
4925 			 * avoid stale protection bits in the cache tags.
4926 			 */
4927 			setcontext4(pm->pm_ctxnum);
4928 			tpte = getpte4(va);
4929 			if ((tpte & (PG_U|PG_NC|PG_TYPE)) == (PG_U|PG_OBMEM))
4930 				cache_flush_page((int)va);
4931 		} else {
4932 			setcontext4(0);
4933 			/* XXX use per-cpu va? */
4934 			if (HASSUN4_MMU3L)
4935 				setregmap(0, tregion);
4936 			setsegmap(0, sp->sg_pmeg);
4937 			va = VA_VPG(va) << PGSHIFT;
4938 			tpte = getpte4(va);
4939 		}
4940 		tpte = (tpte & ~PG_PROT) | newprot;
4941 		setpte4(va, tpte);
4942 		setcontext4(ctx);
4943 	}
4944 	splx(s);
4945 }
4946 
4947 #endif /* sun4, 4c */
4948 
4949 #if defined(SUN4M)		/* 4M version of protection routines above */
4950 /*
4951  * Lower (make more strict) the protection on the specified
4952  * physical page.
4953  *
4954  * There are only two cases: either the protection is going to 0
4955  * (in which case we do the dirty work here), or it is going
4956  * to read-only (in which case pv_changepte does the trick).
4957  */
4958 void
4959 pmap_page_protect4m(pg, prot)
4960 	struct vm_page *pg;
4961 	vm_prot_t prot;
4962 {
4963 	struct pvlist *pv, *pv0, *npv;
4964 	struct pmap *pm;
4965 	int va, vr, vs, tpte;
4966 	int flags, nleft, s, ctx;
4967 	struct regmap *rp;
4968 	struct segmap *sp;
4969 	paddr_t pa = VM_PAGE_TO_PHYS(pg);
4970 
4971 #ifdef DEBUG
4972 	if ((pmapdebug & PDB_CHANGEPROT) ||
4973 	    (pmapdebug & PDB_REMOVE && prot == VM_PROT_NONE))
4974 		printf("pmap_page_protect(0x%lx, 0x%x)\n", pa, prot);
4975 #endif
4976 	/*
4977 	 * Skip unmanaged pages, or operations that do not take
4978 	 * away write permission.
4979 	 */
4980 	if ((pv = pvhead(atop(pa))) == NULL || prot & VM_PROT_WRITE)
4981 		return;
4982 
4983 	write_user_windows();	/* paranoia */
4984 	if (prot & VM_PROT_READ) {
4985 		pv_changepte4m(pv, 0, PPROT_WRITE);
4986 		return;
4987 	}
4988 
4989 	/*
4990 	 * Remove all access to all people talking to this page.
4991 	 * Walk down PV list, removing all mappings.
4992 	 * The logic is much like that for pmap_remove,
4993 	 * but we know we are removing exactly one page.
4994 	 */
4995 	s = splvm();
4996 	if (pv->pv_pmap == NULL) {
4997 		splx(s);
4998 		return;
4999 	}
5000 	ctx = getcontext4m();
5001 	pv0 = pv;
5002 
5003 	/* This pv head will become empty, so clear caching state flags */
5004 	flags = pv->pv_flags & ~(PV_NC|PV_ANC);
5005 
5006 	while (pv != NULL) {
5007 
5008 		pm = pv->pv_pmap;
5009 		simple_lock(&pm->pm_lock);
5010 		va = pv->pv_va;
5011 		vr = VA_VREG(va);
5012 		vs = VA_VSEG(va);
5013 		rp = &pm->pm_regmap[vr];
5014 		if (rp->rg_nsegmap == 0)
5015 			panic("pmap_remove_all: empty vreg");
5016 		sp = &rp->rg_segmap[vs];
5017 		if ((nleft = sp->sg_npte) == 0)
5018 			panic("pmap_remove_all: empty vseg");
5019 		sp->sg_npte = --nleft;
5020 
5021 		/* Invalidate PTE in MMU pagetables. Flush cache if necessary */
5022 		if (pm->pm_ctx) {
5023 			setcontext4m(pm->pm_ctxnum);
5024 			cache_flush_page(va);
5025 		}
5026 
5027 		tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
5028 		setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], SRMMU_TEINVALID,
5029 		    pm->pm_ctx != NULL);
5030 
5031 		if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE)
5032 			panic("pmap_page_protect !PG_V");
5033 
5034 		flags |= MR4M(tpte);
5035 
5036 		if (nleft == 0 && pm != pmap_kernel()) {
5037 			/*
5038 			 * Entire user mode segment is gone
5039 			 */
5040 			if (pm->pm_ctx)
5041 				tlb_flush_segment(vr, vs);
5042 			setpgt4m_va(va, &rp->rg_seg_ptps[vs], SRMMU_TEINVALID, 0);
5043 			pool_put(&L23_pool, sp->sg_pte);
5044 			sp->sg_pte = NULL;
5045 
5046 			if (--rp->rg_nsegmap == 0) {
5047 				int n;
5048 				if (pm->pm_ctx)
5049 					tlb_flush_region(vr);
5050 
5051 				/*
5052 				 * Replicate segment de-allocation in each
5053 				 * CPU's region table.
5054 				 */
5055 #ifdef MULTIPROCESSOR
5056 				for (n = 0; n < ncpu; n++)
5057 #else
5058 				n = 0;
5059 #endif
5060 				{
5061 					setpgt4m(&pm->pm_reg_ptps[n][vr],
5062 						 SRMMU_TEINVALID);
5063 				}
5064 				free(rp->rg_segmap, M_VMPMAP);
5065 				rp->rg_segmap = NULL;
5066 				pool_put(&L23_pool, rp->rg_seg_ptps);
5067 			}
5068 		}
5069 
5070 		npv = pv->pv_next;
5071 		if (pv != pv0)
5072 			pool_put(&pv_pool, pv);
5073 		simple_unlock(&pm->pm_lock);
5074 		pv = npv;
5075 	}
5076 
5077 	/* Finally, update pv head */
5078 	pv0->pv_pmap = NULL;
5079 	pv0->pv_next = NULL;
5080 	pv0->pv_flags = flags;
5081 	setcontext4m(ctx);
5082 	splx(s);
5083 }
5084 
5085 /*
5086  * Lower (make more strict) the protection on the specified
5087  * range of this pmap.
5088  *
5089  * There are only two cases: either the protection is going to 0
5090  * (in which case we call pmap_remove to do the dirty work), or
5091  * it is going from read/write to read-only.  The latter is
5092  * fairly easy.
5093  */
5094 void
5095 pmap_protect4m(pm, sva, eva, prot)
5096 	struct pmap *pm;
5097 	vaddr_t sva, eva;
5098 	vm_prot_t prot;
5099 {
5100 	vaddr_t va, nva;
5101 	int s, ctx, vr, vs;
5102 	struct regmap *rp;
5103 	struct segmap *sp;
5104 
5105 	if ((prot & VM_PROT_READ) == 0) {
5106 		pmap_remove(pm, sva, eva);
5107 		return;
5108 	}
5109 
5110 #ifdef DEBUG
5111 	if (pmapdebug & PDB_CHANGEPROT)
5112 		printf("pmap_protect[curpid %d, ctx %d](%lx, %lx, %x)\n",
5113 			curproc==NULL ? -1 : curproc->p_pid,
5114 			pm->pm_ctx ? pm->pm_ctxnum : -1, sva, eva, prot);
5115 #endif
5116 
5117 	write_user_windows();
5118 	ctx = getcontext4m();
5119 	s = splvm();
5120 	simple_lock(&pm->pm_lock);
5121 
5122 	for (va = sva; va < eva;) {
5123 		vr = VA_VREG(va);
5124 		vs = VA_VSEG(va);
5125 		rp = &pm->pm_regmap[vr];
5126 		nva = VSTOVA(vr,vs + 1);
5127 		if (nva == 0)	/* XXX */
5128 			panic("pmap_protect: last segment"); /* cannot happen(why?)*/
5129 		if (nva > eva)
5130 			nva = eva;
5131 		if (rp->rg_nsegmap == 0) {
5132 			va = nva;
5133 			continue;
5134 		}
5135 #ifdef DEBUG
5136 		if (rp->rg_segmap == NULL)
5137 			panic("pmap_protect: no segments");
5138 #endif
5139 		sp = &rp->rg_segmap[vs];
5140 		if (sp->sg_npte == 0) {
5141 			va = nva;
5142 			continue;
5143 		}
5144 #ifdef DEBUG
5145 		if (sp->sg_pte == NULL)
5146 			panic("pmap_protect: no pages");
5147 #endif
5148 		/*
5149 		 * pages loaded: take away write bits from MMU PTEs
5150 		 */
5151 		if (pm->pm_ctx)
5152 			setcontext4m(pm->pm_ctxnum);
5153 
5154 		pmap_stats.ps_npg_prot_all = (nva - va) >> PGSHIFT;
5155 		for (; va < nva; va += NBPG) {
5156 			int tpte;
5157 
5158 			tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
5159 			/*
5160 			 * Flush cache so that any existing cache
5161 			 * tags are updated.  This is really only
5162 			 * needed for PTEs that lose PG_W.
5163 			 */
5164 			if ((tpte & (PPROT_WRITE|SRMMU_PGTYPE)) ==
5165 			    (PPROT_WRITE|PG_SUN4M_OBMEM)) {
5166 				pmap_stats.ps_npg_prot_actual++;
5167 				if (pm->pm_ctx) {
5168 					cache_flush_page(va);
5169 #if !defined(MULTIPROCESSOR)
5170 					/* Flush TLB entry */
5171 					tlb_flush_page(va);
5172 #endif
5173 				}
5174 				updatepte4m(va, &sp->sg_pte[VA_SUN4M_VPG(va)], PPROT_WRITE, 0);
5175 			}
5176 		}
5177 	}
5178 	simple_unlock(&pm->pm_lock);
5179 	splx(s);
5180 	setcontext4m(ctx);
5181 }
5182 
5183 /*
5184  * Change the protection and/or wired status of the given (MI) virtual page.
5185  * XXX: should have separate function (or flag) telling whether only wiring
5186  * is changing.
5187  */
5188 void
5189 pmap_changeprot4m(pm, va, prot, wired)
5190 	struct pmap *pm;
5191 	vaddr_t va;
5192 	vm_prot_t prot;
5193 	int wired;
5194 {
5195 	int pte, newprot, ctx, s;
5196 	struct regmap *rp;
5197 	struct segmap *sp;
5198 
5199 #ifdef DEBUG
5200 	if (pmapdebug & PDB_CHANGEPROT)
5201 		printf("pmap_changeprot(%p, 0x%lx, 0x%x, 0x%x)\n",
5202 		    pm, va, prot, wired);
5203 #endif
5204 
5205 	write_user_windows();	/* paranoia */
5206 
5207 	va &= ~(NBPG-1);
5208 	if (pm == pmap_kernel())
5209 		newprot = prot & VM_PROT_WRITE ? PPROT_N_RWX : PPROT_N_RX;
5210 	else
5211 		newprot = prot & VM_PROT_WRITE ? PPROT_RWX_RWX : PPROT_RX_RX;
5212 
5213 	pmap_stats.ps_changeprots++;
5214 
5215 	s = splvm();		/* conservative */
5216 	simple_lock(&pm->pm_lock);
5217 
5218 	rp = &pm->pm_regmap[VA_VREG(va)];
5219 	sp = &rp->rg_segmap[VA_VSEG(va)];
5220 
5221 	pte = sp->sg_pte[VA_SUN4M_VPG(va)];
5222 	if ((pte & SRMMU_PROT_MASK) == newprot) {
5223 		/* only wiring changed, and we ignore wiring */
5224 		pmap_stats.ps_useless_changeprots++;
5225 		goto out;
5226 	}
5227 
5228 	if (pm->pm_ctx) {
5229 		/*
5230 		 * Use current context.
5231 		 * Flush cache if page has been referenced to
5232 		 * avoid stale protection bits in the cache tags.
5233 		 */
5234 
5235 		ctx = getcontext4m();
5236 		setcontext4m(pm->pm_ctxnum);
5237 		if ((pte & (SRMMU_PG_C|SRMMU_PGTYPE)) ==
5238 		    (SRMMU_PG_C|PG_SUN4M_OBMEM))
5239 			cache_flush_page(va);
5240 	}
5241 
5242 	setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)],
5243 		 (pte & ~SRMMU_PROT_MASK) | newprot,
5244 		 pm->pm_ctx != NULL);
5245 
5246 	if (pm->pm_ctx)
5247 		setcontext4m(ctx);
5248 
5249 out:
5250 	simple_unlock(&pm->pm_lock);
5251 	splx(s);
5252 }
5253 #endif /* SUN4M */
5254 
5255 /*
5256  * Insert (MI) physical page pa at virtual address va in the given pmap.
5257  * NB: the pa parameter includes type bits PMAP_OBIO, PMAP_NC as necessary.
5258  *
5259  * If pa is not in the `managed' range it will not be `bank mapped'.
5260  * This works during bootstrap only because the first 4MB happens to
5261  * map one-to-one.
5262  *
5263  * There may already be something else there, or we might just be
5264  * changing protections and/or wiring on an existing mapping.
5265  *	XXX	should have different entry points for changing!
5266  */
5267 
5268 #if defined(SUN4) || defined(SUN4C)
5269 
5270 int
5271 pmap_enter4_4c(pm, va, pa, prot, flags)
5272 	struct pmap *pm;
5273 	vaddr_t va;
5274 	paddr_t pa;
5275 	vm_prot_t prot;
5276 	int flags;
5277 {
5278 	struct pvlist *pv;
5279 	int pteproto, ctx;
5280 	u_int pfn;
5281 	int error;
5282 
5283 	if (VA_INHOLE(va)) {
5284 #ifdef DEBUG
5285 		printf("pmap_enter: pm %p, va 0x%lx, pa 0x%lx: in MMU hole\n",
5286 			pm, va, pa);
5287 #endif
5288 		return 0;
5289 	}
5290 
5291 #ifdef DEBUG
5292 	if (pmapdebug & PDB_ENTER)
5293 		printf("pmap_enter(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)\n",
5294 		    pm, va, pa, prot, flags);
5295 #endif
5296 
5297 	pteproto = PG_V | PMAP_T2PTE_4(pa);
5298 	pa &= ~PMAP_TNC_4;
5299 	pfn = atop(pa);
5300 	/*
5301 	 * Set up prototype for new PTE.  Cannot set PG_NC from PV_NC yet
5302 	 * since the pvlist no-cache bit might change as a result of the
5303 	 * new mapping.
5304 	 */
5305 	if ((pteproto & PG_TYPE) == PG_OBMEM && pmap_initialized) {
5306 		pv = pvhead(pfn);
5307 	} else {
5308 		pv = NULL;
5309 	}
5310 	pteproto |= pfn & PG_PFNUM;
5311 	if (prot & VM_PROT_WRITE)
5312 		pteproto |= PG_W;
5313 
5314 	ctx = getcontext4();
5315 	if (pm == pmap_kernel())
5316 		error = pmap_enk4_4c(pm, va, prot, flags, pv, pteproto | PG_S);
5317 	else
5318 		error = pmap_enu4_4c(pm, va, prot, flags, pv, pteproto);
5319 	setcontext4(ctx);
5320 	return (error);
5321 }
5322 
5323 /* enter new (or change existing) kernel mapping */
5324 int
5325 pmap_enk4_4c(pm, va, prot, flags, pv, pteproto)
5326 	struct pmap *pm;
5327 	vaddr_t va;
5328 	vm_prot_t prot;
5329 	int flags;
5330 	struct pvlist *pv;
5331 	int pteproto;
5332 {
5333 	int vr, vs, tpte, i, s;
5334 	struct regmap *rp;
5335 	struct segmap *sp;
5336 
5337 	vr = VA_VREG(va);
5338 	vs = VA_VSEG(va);
5339 	rp = &pm->pm_regmap[vr];
5340 	sp = &rp->rg_segmap[vs];
5341 	s = splvm();		/* XXX way too conservative */
5342 
5343 #if defined(SUN4_MMU3L)
5344 	if (HASSUN4_MMU3L && rp->rg_smeg == reginval) {
5345 		vaddr_t tva;
5346 		rp->rg_smeg = region_alloc(&region_locked, pm, vr)->me_cookie;
5347 		i = ncontext - 1;
5348 		do {
5349 			setcontext4(i);
5350 			setregmap(va, rp->rg_smeg);
5351 		} while (--i >= 0);
5352 
5353 		/* set all PTEs to invalid, then overwrite one PTE below */
5354 		tva = VA_ROUNDDOWNTOREG(va);
5355 		for (i = 0; i < NSEGRG; i++) {
5356 			setsegmap(tva, rp->rg_segmap[i].sg_pmeg);
5357 			tva += NBPSG;
5358 		}
5359 	}
5360 #endif
5361 	if (sp->sg_pmeg != seginval && (tpte = getpte4(va)) & PG_V) {
5362 
5363 		/* old mapping exists, and is of the same pa type */
5364 		if ((tpte & (PG_PFNUM|PG_TYPE)) ==
5365 		    (pteproto & (PG_PFNUM|PG_TYPE))) {
5366 			/* just changing protection and/or wiring */
5367 			splx(s);
5368 			pmap_changeprot4_4c(pm, va, prot,
5369 					    (flags & PMAP_WIRED) != 0);
5370 			return (0);
5371 		}
5372 
5373 		if ((tpte & PG_TYPE) == PG_OBMEM) {
5374 			struct pvlist *pv;
5375 			u_int pfn;
5376 
5377 			/*
5378 			 * Switcheroo: changing pa for this va.
5379 			 * If old pa was managed, remove from pvlist.
5380 			 * If old page was cached, flush cache.
5381 			 */
5382 
5383 			pfn = tpte & PG_PFNUM;
5384 			if ((pv = pvhead(pfn)) != NULL)
5385 				pv_unlink4_4c(pv, pm, va);
5386 			if ((tpte & PG_NC) == 0) {
5387 				setcontext4(0);	/* ??? */
5388 				cache_flush_page((int)va);
5389 			}
5390 		}
5391 	} else {
5392 		/* adding new entry */
5393 		sp->sg_npte++;
5394 	}
5395 
5396 	/*
5397 	 * If the new mapping is for a managed PA, enter into pvlist.
5398 	 * Note that the mapping for a malloc page will always be
5399 	 * unique (hence will never cause a second call to malloc).
5400 	 */
5401 	if (pv != NULL)
5402 		pteproto |= pv_link4_4c(pv, pm, va, pteproto & PG_NC);
5403 
5404 	if (sp->sg_pmeg == seginval) {
5405 		int tva;
5406 
5407 		/*
5408 		 * Allocate an MMU entry now (on locked list),
5409 		 * and map it into every context.  Set all its
5410 		 * PTEs invalid (we will then overwrite one, but
5411 		 * this is more efficient than looping twice).
5412 		 */
5413 #ifdef DEBUG
5414 		if (pm->pm_ctx == NULL || pm->pm_ctxnum != 0)
5415 			panic("pmap_enk: kern seg but no kern ctx");
5416 #endif
5417 		sp->sg_pmeg = me_alloc(&segm_locked, pm, vr, vs)->me_cookie;
5418 		rp->rg_nsegmap++;
5419 
5420 #if defined(SUN4_MMU3L)
5421 		if (HASSUN4_MMU3L)
5422 			setsegmap(va, sp->sg_pmeg);
5423 		else
5424 #endif
5425 		{
5426 			i = ncontext - 1;
5427 			do {
5428 				setcontext4(i);
5429 				setsegmap(va, sp->sg_pmeg);
5430 			} while (--i >= 0);
5431 		}
5432 
5433 		/* set all PTEs to invalid, then overwrite one PTE below */
5434 		tva = VA_ROUNDDOWNTOSEG(va);
5435 		i = NPTESG;
5436 		do {
5437 			setpte4(tva, 0);
5438 			tva += NBPG;
5439 		} while (--i > 0);
5440 	}
5441 
5442 	/* ptes kept in hardware only */
5443 	setpte4(va, pteproto);
5444 	splx(s);
5445 	return (0);
5446 }
5447 
5448 /* enter new (or change existing) user mapping */
5449 int
5450 pmap_enu4_4c(pm, va, prot, flags, pv, pteproto)
5451 	struct pmap *pm;
5452 	vaddr_t va;
5453 	vm_prot_t prot;
5454 	int flags;
5455 	struct pvlist *pv;
5456 	int pteproto;
5457 {
5458 	int vr, vs, *pte, tpte, pmeg, s, doflush;
5459 	int error = 0;
5460 	struct regmap *rp;
5461 	struct segmap *sp;
5462 
5463 	write_user_windows();		/* XXX conservative */
5464 	vr = VA_VREG(va);
5465 	vs = VA_VSEG(va);
5466 	rp = &pm->pm_regmap[vr];
5467 	s = splvm();			/* XXX conservative */
5468 
5469 	/*
5470 	 * If there is no space in which the PTEs can be written
5471 	 * while they are not in the hardware, this must be a new
5472 	 * virtual segment.  Get PTE space and count the segment.
5473 	 *
5474 	 * TO SPEED UP CTX ALLOC, PUT SEGMENT BOUNDS STUFF HERE
5475 	 * AND IN pmap_rmu()
5476 	 */
5477 
5478 	GAP_SHRINK(pm,vr);
5479 
5480 #ifdef DEBUG
5481 	if (pm->pm_gap_end < pm->pm_gap_start) {
5482 		printf("pmap_enu: gap_start 0x%x, gap_end 0x%x",
5483 			pm->pm_gap_start, pm->pm_gap_end);
5484 		panic("pmap_enu: gap botch");
5485 	}
5486 #endif
5487 
5488 	if (rp->rg_segmap == NULL) {
5489 		/* definitely a new mapping */
5490 		int i;
5491 		int size = NSEGRG * sizeof (struct segmap);
5492 		int mflag = M_NOWAIT;
5493 
5494 	rretry:
5495 		sp = (struct segmap *)malloc((u_long)size, M_VMPMAP, mflag);
5496 		if (sp == NULL) {
5497 			if ((flags & PMAP_CANFAIL) != 0) {
5498 				error = ENOMEM;
5499 				goto out;
5500 			}
5501 			mflag = M_WAITOK;
5502 			goto rretry;
5503 		}
5504 #ifdef DEBUG
5505 		if (rp->rg_segmap != NULL)
5506 			panic("pmap_enter: segment filled during sleep");
5507 #endif
5508 		qzero((caddr_t)sp, size);
5509 		rp->rg_segmap = sp;
5510 		rp->rg_nsegmap = 0;
5511 		for (i = NSEGRG; --i >= 0;)
5512 			sp++->sg_pmeg = seginval;
5513 	}
5514 
5515 	sp = &rp->rg_segmap[vs];
5516 
5517 	if ((pte = sp->sg_pte) == NULL) {
5518 		/* definitely a new mapping */
5519 		int size = NPTESG * sizeof *pte;
5520 		int mflag = M_NOWAIT;
5521 
5522 	sretry:
5523 		pte = (int *)malloc((u_long)size, M_VMPMAP, mflag);
5524 		if (pte == NULL) {
5525 			if ((flags & PMAP_CANFAIL) != 0) {
5526 				error = ENOMEM;
5527 				goto out;
5528 			}
5529 			mflag = M_WAITOK;
5530 			goto sretry;
5531 		}
5532 #ifdef DEBUG
5533 		if (sp->sg_pte != NULL)
5534 			panic("pmap_enter: pte filled during sleep");
5535 		if (sp->sg_pmeg != seginval)
5536 			panic("pmap_enter: new ptes, but not seginval");
5537 #endif
5538 		qzero((caddr_t)pte, size);
5539 		sp->sg_pte = pte;
5540 		sp->sg_npte = 1;
5541 		rp->rg_nsegmap++;
5542 	} else {
5543 		/* might be a change: fetch old pte */
5544 		doflush = 0;
5545 		if ((pmeg = sp->sg_pmeg) == seginval) {
5546 			/* software pte */
5547 			tpte = pte[VA_VPG(va)];
5548 		} else {
5549 			/* hardware pte */
5550 			if (CTX_USABLE(pm,rp)) {
5551 				setcontext4(pm->pm_ctxnum);
5552 				tpte = getpte4(va);
5553 				doflush = CACHEINFO.c_vactype != VAC_NONE;
5554 			} else {
5555 				setcontext4(0);
5556 				/* XXX use per-cpu pteva? */
5557 				if (HASSUN4_MMU3L)
5558 					setregmap(0, tregion);
5559 				setsegmap(0, pmeg);
5560 				tpte = getpte4(VA_VPG(va) << PGSHIFT);
5561 			}
5562 		}
5563 
5564 		if (tpte & PG_V) {
5565 			/* old mapping exists, and is of the same pa type */
5566 			if ((tpte & (PG_PFNUM|PG_TYPE)) ==
5567 			    (pteproto & (PG_PFNUM|PG_TYPE))) {
5568 				/* just changing prot and/or wiring */
5569 				splx(s);
5570 				/* caller should call this directly: */
5571 				pmap_changeprot4_4c(pm, va, prot,
5572 						    (flags & PMAP_WIRED) != 0);
5573 				if ((flags & PMAP_WIRED) != 0)
5574 					pm->pm_stats.wired_count++;
5575 				else
5576 					pm->pm_stats.wired_count--;
5577 				return (0);
5578 			}
5579 			/*
5580 			 * Switcheroo: changing pa for this va.
5581 			 * If old pa was managed, remove from pvlist.
5582 			 * If old page was cached, flush cache.
5583 			 */
5584 #if 0
5585 			printf("%s[%d]: pmap_enu: changing existing "
5586 				"va(0x%x)=>pa entry\n",
5587 				curproc->p_comm, curproc->p_pid, va);
5588 #endif
5589 			if ((tpte & PG_TYPE) == PG_OBMEM) {
5590 				struct pvlist *pv;
5591 				u_int pfn = tpte & PG_PFNUM;
5592 				if ((pv = pvhead(pfn)) != NULL)
5593 					pv_unlink4_4c(pv, pm, va);
5594 				if (doflush && (tpte & PG_NC) == 0)
5595 					cache_flush_page((int)va);
5596 			}
5597 		} else {
5598 			/* adding new entry */
5599 			sp->sg_npte++;
5600 
5601 			/*
5602 			 * Increment counters
5603 			 */
5604 			if ((flags & PMAP_WIRED) != 0)
5605 				pm->pm_stats.wired_count++;
5606 		}
5607 	}
5608 
5609 	if (pv != NULL)
5610 		pteproto |= pv_link4_4c(pv, pm, va, pteproto & PG_NC);
5611 
5612 	/*
5613 	 * Update hardware & software PTEs.
5614 	 */
5615 	if ((pmeg = sp->sg_pmeg) != seginval) {
5616 		/* ptes are in hardware */
5617 		if (CTX_USABLE(pm,rp))
5618 			setcontext4(pm->pm_ctxnum);
5619 		else {
5620 			setcontext4(0);
5621 			/* XXX use per-cpu pteva? */
5622 			if (HASSUN4_MMU3L)
5623 				setregmap(0, tregion);
5624 			setsegmap(0, pmeg);
5625 			va = VA_VPG(va) << PGSHIFT;
5626 		}
5627 		setpte4(va, pteproto);
5628 	}
5629 	/* update software copy */
5630 	pte += VA_VPG(va);
5631 	*pte = pteproto;
5632 
5633 out:
5634 	splx(s);
5635 	return (error);
5636 }
5637 
5638 void
5639 pmap_kenter_pa4_4c(va, pa, prot)
5640 	vaddr_t va;
5641 	paddr_t pa;
5642 	vm_prot_t prot;
5643 {
5644 	struct pmap *pm = pmap_kernel();
5645 	struct regmap *rp;
5646 	struct segmap *sp;
5647 	int vr, vs, i, s;
5648 	int pteproto, ctx;
5649 
5650 	pteproto = PG_S | PG_V | PMAP_T2PTE_4(pa);
5651 	pa &= ~PMAP_TNC_4;
5652 	pteproto |= atop(pa) & PG_PFNUM;
5653 	if (prot & VM_PROT_WRITE)
5654 		pteproto |= PG_W;
5655 
5656 	vr = VA_VREG(va);
5657 	vs = VA_VSEG(va);
5658 	rp = &pm->pm_regmap[vr];
5659 	sp = &rp->rg_segmap[vs];
5660 
5661 	ctx = getcontext4();
5662 	s = splvm();
5663 #if defined(SUN4_MMU3L)
5664 	if (HASSUN4_MMU3L && rp->rg_smeg == reginval) {
5665 		vaddr_t tva;
5666 		rp->rg_smeg = region_alloc(&region_locked, pm, vr)->me_cookie;
5667 		i = ncontext - 1;
5668 		do {
5669 			setcontext4(i);
5670 			setregmap(va, rp->rg_smeg);
5671 		} while (--i >= 0);
5672 
5673 		/* set all PTEs to invalid, then overwrite one PTE below */
5674 		tva = VA_ROUNDDOWNTOREG(va);
5675 		for (i = 0; i < NSEGRG; i++) {
5676 			setsegmap(tva, rp->rg_segmap[i].sg_pmeg);
5677 			tva += NBPSG;
5678 		}
5679 	}
5680 #endif
5681 	KASSERT(sp->sg_pmeg == seginval || (getpte4(va) & PG_V) == 0);
5682 	if (sp->sg_pmeg == seginval) {
5683 		int tva;
5684 
5685 		/*
5686 		 * Allocate an MMU entry now (on locked list),
5687 		 * and map it into every context.  Set all its
5688 		 * PTEs invalid (we will then overwrite one, but
5689 		 * this is more efficient than looping twice).
5690 		 */
5691 
5692 		sp->sg_pmeg = me_alloc(&segm_locked, pm, vr, vs)->me_cookie;
5693 		rp->rg_nsegmap++;
5694 
5695 #if defined(SUN4_MMU3L)
5696 		if (HASSUN4_MMU3L)
5697 			setsegmap(va, sp->sg_pmeg);
5698 		else
5699 #endif
5700 		{
5701 			i = ncontext - 1;
5702 			do {
5703 				setcontext4(i);
5704 				setsegmap(va, sp->sg_pmeg);
5705 			} while (--i >= 0);
5706 		}
5707 
5708 		/* set all PTEs to invalid, then overwrite one PTE below */
5709 		tva = VA_ROUNDDOWNTOSEG(va);
5710 		i = NPTESG;
5711 		do {
5712 			setpte4(tva, 0);
5713 			tva += NBPG;
5714 		} while (--i > 0);
5715 	}
5716 
5717 	/* ptes kept in hardware only */
5718 	setpte4(va, pteproto);
5719 	sp->sg_npte++;
5720 	splx(s);
5721 	setcontext4(ctx);
5722 }
5723 
5724 void
5725 pmap_kremove4_4c(va, len)
5726 	vaddr_t va;
5727 	vsize_t len;
5728 {
5729 	struct pmap *pm = pmap_kernel();
5730 	struct regmap *rp;
5731 	struct segmap *sp;
5732 	vaddr_t nva, endva;
5733 	int i, tpte, perpage, npg;
5734 	int nleft, pmeg;
5735 	int vr, vs, s, ctx;
5736 
5737 	endva = va + len;
5738 #ifdef DEBUG
5739 	if (pmapdebug & PDB_REMOVE)
5740 		printf("pmap_kremove(0x%lx, 0x%lx)\n", va, endva);
5741 #endif
5742 
5743 	s = splvm();
5744 	ctx = getcontext();
5745 	simple_lock(&pm->pm_lock);
5746 	for (; va < endva; va = nva) {
5747 		/* do one virtual segment at a time */
5748 		vr = VA_VREG(va);
5749 		vs = VA_VSEG(va);
5750 		nva = VSTOVA(vr, vs + 1);
5751 		if (nva == 0 || nva > endva)
5752 			nva = endva;
5753 
5754 		rp = &pm->pm_regmap[vr];
5755 		sp = &rp->rg_segmap[vs];
5756 
5757 		if (rp->rg_nsegmap == 0)
5758 			continue;
5759 		nleft = sp->sg_npte;
5760 		if (nleft == 0)
5761 			continue;
5762 		pmeg = sp->sg_pmeg;
5763 		KASSERT(pmeg != seginval);
5764 		setcontext4(0);
5765 		/* decide how to flush cache */
5766 		npg = (nva - va) >> PGSHIFT;
5767 		if (npg > PMAP_RMK_MAGIC) {
5768 			/* flush the whole segment */
5769 			perpage = 0;
5770 			cache_flush_segment(vr, vs);
5771 		} else {
5772 			/*
5773 			 * flush each page individually;
5774 			 * some never need flushing
5775 			 */
5776 			perpage = (CACHEINFO.c_vactype != VAC_NONE);
5777 		}
5778 		while (va < nva) {
5779 			tpte = getpte4(va);
5780 			if ((tpte & PG_V) == 0) {
5781 				va += NBPG;
5782 				continue;
5783 			}
5784 			if ((tpte & PG_TYPE) == PG_OBMEM) {
5785 				/* if cacheable, flush page as needed */
5786 				if (perpage && (tpte & PG_NC) == 0)
5787 					cache_flush_page(va);
5788 			}
5789 			nleft--;
5790 #ifdef DIAGNOSTIC
5791 			if (nleft < 0)
5792 				panic("pmap_kremove: too many PTEs in segment; "
5793 				      "va 0x%lx; endva 0x%lx", va, endva);
5794 #endif
5795 			setpte4(va, 0);
5796 			va += NBPG;
5797 		}
5798 
5799 		/*
5800 		 * If the segment is all gone, remove it from everyone and
5801 		 * free the MMU entry.
5802 		 */
5803 
5804 		sp->sg_npte = nleft;
5805 		if (nleft == 0) {
5806 			va = VSTOVA(vr, vs);
5807 #if defined(SUN4_MMU3L)
5808 			if (HASSUN4_MMU3L)
5809 				setsegmap(va, seginval);
5810 			else
5811 #endif
5812 				for (i = ncontext; --i >= 0;) {
5813 					setcontext4(i);
5814 					setsegmap(va, seginval);
5815 				}
5816 			me_free(pm, pmeg);
5817 			if (--rp->rg_nsegmap == 0) {
5818 #if defined(SUN4_MMU3L)
5819 				if (HASSUN4_MMU3L) {
5820 					for (i = ncontext; --i >= 0;) {
5821 						setcontext4(i);
5822 						setregmap(va, reginval);
5823 					}
5824 					/* note: context is 0 */
5825 					region_free(pm, rp->rg_smeg);
5826 				}
5827 #endif
5828 			}
5829 		}
5830 	}
5831 	simple_unlock(&pm->pm_lock);
5832 	setcontext(ctx);
5833 	splx(s);
5834 }
5835 
5836 #endif /*sun4,4c*/
5837 
5838 #if defined(SUN4M)		/* sun4m versions of enter routines */
5839 /*
5840  * Insert (MI) physical page pa at virtual address va in the given pmap.
5841  * NB: the pa parameter includes type bits PMAP_OBIO, PMAP_NC as necessary.
5842  *
5843  * If pa is not in the `managed' range it will not be `bank mapped'.
5844  * This works during bootstrap only because the first 4MB happens to
5845  * map one-to-one.
5846  *
5847  * There may already be something else there, or we might just be
5848  * changing protections and/or wiring on an existing mapping.
5849  *	XXX	should have different entry points for changing!
5850  */
5851 
5852 int
5853 pmap_enter4m(pm, va, pa, prot, flags)
5854 	struct pmap *pm;
5855 	vaddr_t va;
5856 	paddr_t pa;
5857 	vm_prot_t prot;
5858 	int flags;
5859 {
5860 	struct pvlist *pv;
5861 	int pteproto, ctx;
5862 	u_int pfn;
5863 	int error;
5864 
5865 #ifdef DEBUG
5866 	if (pmapdebug & PDB_ENTER)
5867 		printf("pmap_enter[curpid %d, ctx %d]"
5868 			"(%p, 0x%lx, 0x%lx, 0x%x, 0x%x)\n",
5869 			curproc==NULL ? -1 : curproc->p_pid,
5870 			pm->pm_ctx==NULL ? -1 : pm->pm_ctxnum,
5871 			pm, va, pa, prot, flags);
5872 #endif
5873 
5874 	/* Initialise pteproto with cache bit */
5875 	pteproto = (pa & PMAP_NC) == 0 ? SRMMU_PG_C : 0;
5876 
5877 #ifdef DEBUG
5878 	if (pa & PMAP_TYPE_SRMMU) {	/* this page goes in an iospace */
5879 		if (cpuinfo.cpu_type == CPUTYP_MS1)
5880 			panic("pmap_enter4m: attempt to use 36-bit iospace on"
5881 			      " MicroSPARC");
5882 	}
5883 #endif
5884 	pteproto |= PMAP_T2PTE_SRMMU(pa);
5885 
5886 	/* Make sure we get a pte with appropriate perms! */
5887 	pteproto |= SRMMU_TEPTE | PPROT_RX_RX;
5888 
5889 	pa &= ~PMAP_TNC_SRMMU;
5890 	/*
5891 	 * Set up prototype for new PTE.  Cannot set PG_NC from PV_NC yet
5892 	 * since the pvlist no-cache bit might change as a result of the
5893 	 * new mapping.
5894 	 */
5895 	pfn = atop(pa);
5896 	if ((pteproto & SRMMU_PGTYPE) == PG_SUN4M_OBMEM && pmap_initialized) {
5897 		pv = pvhead(pfn);
5898 	} else {
5899 		pv = NULL;
5900 	}
5901 	pteproto |= (pfn << SRMMU_PPNSHIFT);
5902 
5903 	if (prot & VM_PROT_WRITE)
5904 		pteproto |= PPROT_WRITE;
5905 
5906 	ctx = getcontext4m();
5907 
5908 	if (pm == pmap_kernel())
5909 		error = pmap_enk4m(pm, va, prot, flags, pv, pteproto | PPROT_S);
5910 	else
5911 		error = pmap_enu4m(pm, va, prot, flags, pv, pteproto);
5912 
5913 	setcontext4m(ctx);
5914 	return (error);
5915 }
5916 
5917 /* enter new (or change existing) kernel mapping */
5918 int
5919 pmap_enk4m(pm, va, prot, flags, pv, pteproto)
5920 	struct pmap *pm;
5921 	vaddr_t va;
5922 	vm_prot_t prot;
5923 	int flags;
5924 	struct pvlist *pv;
5925 	int pteproto;
5926 {
5927 	int vr, vs, tpte, s;
5928 	struct regmap *rp;
5929 	struct segmap *sp;
5930 
5931 #ifdef DEBUG
5932 	if (va < KERNBASE)
5933 		panic("pmap_enk4m: can't enter va 0x%lx below KERNBASE", va);
5934 #endif
5935 	vr = VA_VREG(va);
5936 	vs = VA_VSEG(va);
5937 	rp = &pm->pm_regmap[vr];
5938 	sp = &rp->rg_segmap[vs];
5939 
5940 	s = splvm();		/* XXX way too conservative */
5941 
5942 	if (rp->rg_seg_ptps == NULL) /* enter new region */
5943 		panic("pmap_enk4m: missing kernel region table for va 0x%lx",va);
5944 
5945 	tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
5946 	if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE) {
5947 
5948 		/* old mapping exists, and is of the same pa type */
5949 
5950 		if ((tpte & SRMMU_PPNMASK) == (pteproto & SRMMU_PPNMASK)) {
5951 			/* just changing protection and/or wiring */
5952 			splx(s);
5953 			pmap_changeprot4m(pm, va, prot,
5954 					  (flags & PMAP_WIRED) != 0);
5955 			return (0);
5956 		}
5957 
5958 		if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) {
5959 			struct pvlist *pv;
5960 			u_int pfn = (tpte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT;
5961 #ifdef DEBUG
5962 printf("pmap_enk4m: changing existing va=>pa entry: va 0x%lx, pteproto 0x%x, "
5963        "oldpte 0x%x\n", va, pteproto, tpte);
5964 #endif
5965 			/*
5966 			 * Switcheroo: changing pa for this va.
5967 			 * If old pa was managed, remove from pvlist.
5968 			 * If old page was cached, flush cache.
5969 			 */
5970 			if ((pv = pvhead(pfn)) != NULL)
5971 				pv_unlink4m(pv, pm, va);
5972 			if (tpte & SRMMU_PG_C) {
5973 				setcontext4m(0);	/* ??? */
5974 				cache_flush_page((int)va);
5975 			}
5976 		}
5977 	} else {
5978 		/* adding new entry */
5979 		sp->sg_npte++;
5980 	}
5981 
5982 	/*
5983 	 * If the new mapping is for a managed PA, enter into pvlist.
5984 	 * Note that the mapping for a malloc page will always be
5985 	 * unique (hence will never cause a second call to malloc).
5986 	 */
5987 	if (pv != NULL)
5988 	        pteproto &= ~(pv_link4m(pv, pm, va, (pteproto & SRMMU_PG_C) == 0));
5989 
5990 #ifdef DEBUG
5991 	if (sp->sg_pte == NULL) /* If no existing pagetable */
5992 		panic("pmap_enk4m: missing segment table for va 0x%lx",va);
5993 #endif
5994 
5995 	setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], pteproto, 1);
5996 
5997 	splx(s);
5998 	return (0);
5999 }
6000 
6001 /* enter new (or change existing) user mapping */
6002 int
6003 pmap_enu4m(pm, va, prot, flags, pv, pteproto)
6004 	struct pmap *pm;
6005 	vaddr_t va;
6006 	vm_prot_t prot;
6007 	int flags;
6008 	struct pvlist *pv;
6009 	int pteproto;
6010 {
6011 	int vr, vs, *pte, tpte, s;
6012 	int error = 0;
6013 	struct regmap *rp;
6014 	struct segmap *sp;
6015 
6016 #ifdef DEBUG
6017 	if (KERNBASE < va)
6018 		panic("pmap_enu4m: can't enter va 0x%lx above KERNBASE", va);
6019 #endif
6020 
6021 	write_user_windows();		/* XXX conservative */
6022 	vr = VA_VREG(va);
6023 	vs = VA_VSEG(va);
6024 	rp = &pm->pm_regmap[vr];
6025 	s = splvm();			/* XXX conservative */
6026 
6027 	if (rp->rg_segmap == NULL) {
6028 		/* definitely a new mapping */
6029 		int size = NSEGRG * sizeof (struct segmap);
6030 		int mflag = M_NOWAIT;
6031 
6032 	rretry:
6033 		sp = (struct segmap *)malloc((u_long)size, M_VMPMAP, mflag);
6034 		if (sp == NULL) {
6035 			if ((flags & PMAP_CANFAIL) != 0) {
6036 				error = ENOMEM;
6037 				goto out;
6038 			}
6039 			mflag = M_WAITOK;
6040 			goto rretry;
6041 		}
6042 #ifdef DEBUG
6043 		if (rp->rg_segmap != NULL)
6044 			panic("pmap_enu4m: segment filled during sleep");
6045 #endif
6046 		qzero((caddr_t)sp, size);
6047 		rp->rg_segmap = sp;
6048 		rp->rg_nsegmap = 0;
6049 		rp->rg_seg_ptps = NULL;
6050 	}
6051 	if (rp->rg_seg_ptps == NULL) {
6052 		/* Need a segment table */
6053 		int i, *ptd;
6054 		int mflag = PR_NOWAIT;
6055 
6056 	rgretry:
6057 		ptd = pool_get(&L23_pool, mflag);
6058 		if (ptd == NULL) {
6059 			if ((flags & PMAP_CANFAIL) != 0) {
6060 				error = ENOMEM;
6061 				goto out;
6062 			}
6063 			mflag = PR_WAITOK;
6064 			goto rgretry;
6065 		}
6066 #ifdef DEBUG
6067 		if (rp->rg_seg_ptps != NULL)
6068 			panic("pmap_enu4m: segment table fill during sleep");
6069 #endif
6070 
6071 		rp->rg_seg_ptps = ptd;
6072 		for (i = 0; i < SRMMU_L2SIZE; i++)
6073 			setpgt4m(&ptd[i], SRMMU_TEINVALID);
6074 
6075 		/* Replicate segment allocation in each CPU's region table */
6076 #ifdef MULTIPROCESSOR
6077 		for (i = 0; i < ncpu; i++)
6078 #else
6079 		i = 0;
6080 #endif
6081 		{
6082 			setpgt4m(&pm->pm_reg_ptps[i][vr],
6083 				 (VA2PA((caddr_t)ptd) >> SRMMU_PPNPASHIFT) |
6084 					SRMMU_TEPTD);
6085 		}
6086 	}
6087 
6088 	sp = &rp->rg_segmap[vs];
6089 
6090 	if ((pte = sp->sg_pte) == NULL) {
6091 		/* definitely a new mapping */
6092 		int i;
6093 		int mflag = PR_NOWAIT;
6094 
6095 	sretry:
6096 		pte = pool_get(&L23_pool, mflag);
6097 		if (pte == NULL) {
6098 			if ((flags & PMAP_CANFAIL) != 0) {
6099 				error = ENOMEM;
6100 				goto out;
6101 			}
6102 			mflag = PR_WAITOK;
6103 			goto sretry;
6104 		}
6105 #ifdef DEBUG
6106 		if (sp->sg_pte != NULL)
6107 			panic("pmap_enter: pte filled during sleep");
6108 #endif
6109 
6110 		sp->sg_pte = pte;
6111 		sp->sg_npte = 1;
6112 		rp->rg_nsegmap++;
6113 		for (i = 0; i < SRMMU_L3SIZE; i++)
6114 			setpgt4m(&pte[i], SRMMU_TEINVALID);
6115 		setpgt4m(&rp->rg_seg_ptps[vs],
6116 			(VA2PA((caddr_t)pte) >> SRMMU_PPNPASHIFT) | SRMMU_TEPTD);
6117 	} else {
6118 		/*
6119 		 * Might be a change: fetch old pte
6120 		 */
6121 		if (pm->pm_ctx) {
6122 			setcontext4m(pm->pm_ctxnum);
6123 			tlb_flush_page(va);
6124 		}
6125 		tpte = pte[VA_SUN4M_VPG(va)];
6126 
6127 		if ((tpte & SRMMU_TETYPE) == SRMMU_TEPTE) {
6128 
6129 			/* old mapping exists, and is of the same pa type */
6130 			if ((tpte & SRMMU_PPNMASK) ==
6131 			    (pteproto & SRMMU_PPNMASK)) {
6132 				/* just changing prot and/or wiring */
6133 				splx(s);
6134 				/* caller should call this directly: */
6135 				pmap_changeprot4m(pm, va, prot,
6136 						  (flags & PMAP_WIRED) != 0);
6137 				if ((flags & PMAP_WIRED) != 0)
6138 					pm->pm_stats.wired_count++;
6139 				else
6140 					pm->pm_stats.wired_count--;
6141 				return (0);
6142 			}
6143 			/*
6144 			 * Switcheroo: changing pa for this va.
6145 			 * If old pa was managed, remove from pvlist.
6146 			 * If old page was cached, flush cache.
6147 			 */
6148 #ifdef DEBUG
6149 			if (pmapdebug & PDB_SWITCHMAP)
6150 				printf("%s[%d]: pmap_enu: changing existing "
6151 					"va 0x%x: pte 0x%x=>0x%x\n",
6152 					curproc->p_comm, curproc->p_pid,
6153 					(int)va, tpte, pteproto);
6154 #endif
6155 			if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) {
6156 				struct pvlist *pv;
6157 				u_int pfn =
6158 				    (tpte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT;
6159 				if ((pv = pvhead(pfn)) != NULL) {
6160 					pv->pv_flags |= MR4M(tpte);
6161 					pv_unlink4m(pv, pm, va);
6162 				}
6163 				if (pm->pm_ctx && (tpte & SRMMU_PG_C))
6164 					cache_flush_page((int)va);
6165 			}
6166 		} else {
6167 			/* adding new entry */
6168 			sp->sg_npte++;
6169 
6170 			/*
6171 			 * Increment counters
6172 			 */
6173 			if ((flags & PMAP_WIRED) != 0)
6174 				pm->pm_stats.wired_count++;
6175 		}
6176 	}
6177 	if (pv != NULL)
6178 	        pteproto &= ~(pv_link4m(pv, pm, va, (pteproto & SRMMU_PG_C) == 0));
6179 
6180 	/*
6181 	 * Update PTEs, flush TLB as necessary.
6182 	 */
6183 	if (pm->pm_ctx)
6184 		setcontext4m(pm->pm_ctxnum);
6185 	setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], pteproto,
6186 	    pm->pm_ctx != NULL);
6187 
6188 out:
6189 	splx(s);
6190 	return (error);
6191 }
6192 
6193 void
6194 pmap_kenter_pa4m(va, pa, prot)
6195 	vaddr_t va;
6196 	paddr_t pa;
6197 	vm_prot_t prot;
6198 {
6199 	struct pmap *pm = pmap_kernel();
6200 	struct regmap *rp;
6201 	struct segmap *sp;
6202 	int pteproto, vr, vs, tpte;
6203 
6204 	/* Initialise pteproto with cache bit */
6205 	pteproto = (pa & PMAP_NC) == 0 ? SRMMU_PG_C : 0;
6206 	pteproto |= PMAP_T2PTE_SRMMU(pa);
6207 	pteproto |= SRMMU_TEPTE | PPROT_RX_RX;
6208 	pteproto |= (atop(pa & ~PMAP_TNC_SRMMU) << SRMMU_PPNSHIFT);
6209 	if (prot & VM_PROT_WRITE)
6210 		pteproto |= PPROT_WRITE;
6211 	pteproto |= PPROT_S;
6212 
6213 	vr = VA_VREG(va);
6214 	vs = VA_VSEG(va);
6215 	rp = &pm->pm_regmap[vr];
6216 	sp = &rp->rg_segmap[vs];
6217 
6218 	tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
6219 	KASSERT((tpte & SRMMU_TETYPE) != SRMMU_TEPTE);
6220 
6221 	sp->sg_npte++;
6222 	setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)], pteproto, 1);
6223 }
6224 
6225 void
6226 pmap_kremove4m(va, len)
6227 	vaddr_t va;
6228 	vsize_t len;
6229 {
6230 	struct pmap *pm = pmap_kernel();
6231 	struct regmap *rp;
6232 	struct segmap *sp;
6233 	vaddr_t endva, nva;
6234 	int vr, vs, ctx;
6235 	int tpte, perpage, npg;
6236 	int nleft;
6237 
6238 	endva = va + len;
6239 	ctx = getcontext();
6240 	simple_lock(&pm->pm_lock);
6241 	for (; va < endva; va = nva) {
6242 		/* do one virtual segment at a time */
6243 		vr = VA_VREG(va);
6244 		vs = VA_VSEG(va);
6245 		nva = VSTOVA(vr, vs + 1);
6246 		if (nva == 0 || nva > endva) {
6247 			nva = endva;
6248 		}
6249 
6250 		rp = &pm->pm_regmap[vr];
6251 		if (rp->rg_nsegmap == 0) {
6252 			continue;
6253 		}
6254 
6255 		sp = &rp->rg_segmap[vs];
6256 		nleft = sp->sg_npte;
6257 		if (nleft == 0) {
6258 			continue;
6259 		}
6260 
6261 		setcontext4m(0);
6262 		/* decide how to flush cache */
6263 		npg = (nva - va) >> PGSHIFT;
6264 		if (npg > PMAP_RMK_MAGIC) {
6265 			/* flush the whole segment */
6266 			perpage = 0;
6267 			if (CACHEINFO.c_vactype != VAC_NONE) {
6268 				cache_flush_segment(vr, vs);
6269 			}
6270 		} else {
6271 
6272 			/*
6273 			 * flush each page individually;
6274 			 * some never need flushing
6275 			 */
6276 
6277 			perpage = (CACHEINFO.c_vactype != VAC_NONE);
6278 		}
6279 		for (; va < nva; va += NBPG) {
6280 			tpte = sp->sg_pte[VA_SUN4M_VPG(va)];
6281 			if ((tpte & SRMMU_TETYPE) != SRMMU_TEPTE) {
6282 				continue;
6283 			}
6284 			if ((tpte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) {
6285 				/* if cacheable, flush page as needed */
6286 				if (perpage && (tpte & SRMMU_PG_C))
6287 					cache_flush_page(va);
6288 			}
6289 			setpgt4m_va(va, &sp->sg_pte[VA_SUN4M_VPG(va)],
6290 				 SRMMU_TEINVALID, 1);
6291 			nleft--;
6292 		}
6293 		sp->sg_npte = nleft;
6294 	}
6295 	simple_unlock(&pm->pm_lock);
6296 	setcontext(ctx);
6297 }
6298 
6299 #endif /* SUN4M */
6300 
6301 /*
6302  * Clear the wiring attribute for a map/virtual-address pair.
6303  */
6304 /* ARGSUSED */
6305 void
6306 pmap_unwire(pm, va)
6307 	struct pmap *pm;
6308 	vaddr_t va;
6309 {
6310 
6311 	pmap_stats.ps_useless_changewire++;
6312 }
6313 
6314 /*
6315  * Extract the physical page address associated
6316  * with the given map/virtual_address pair.
6317  * GRR, the vm code knows; we should not have to do this!
6318  */
6319 
6320 #if defined(SUN4) || defined(SUN4C)
6321 boolean_t
6322 pmap_extract4_4c(pm, va, pap)
6323 	struct pmap *pm;
6324 	vaddr_t va;
6325 	paddr_t *pap;
6326 {
6327 	int tpte;
6328 	int vr, vs;
6329 	struct regmap *rp;
6330 	struct segmap *sp;
6331 
6332 	vr = VA_VREG(va);
6333 	vs = VA_VSEG(va);
6334 	rp = &pm->pm_regmap[vr];
6335 	if (rp->rg_segmap == NULL) {
6336 #ifdef DEBUG
6337 		if (pmapdebug & PDB_FOLLOW)
6338 			printf("pmap_extract: invalid segment (%d)\n", vr);
6339 #endif
6340 		return (FALSE);
6341 	}
6342 	sp = &rp->rg_segmap[vs];
6343 
6344 	if (sp->sg_pmeg != seginval) {
6345 		int ctx = getcontext4();
6346 
6347 		if (CTX_USABLE(pm,rp)) {
6348 			CHANGE_CONTEXTS(ctx, pm->pm_ctxnum);
6349 			tpte = getpte4(va);
6350 		} else {
6351 			CHANGE_CONTEXTS(ctx, 0);
6352 			if (HASSUN4_MMU3L)
6353 				setregmap(0, tregion);
6354 			setsegmap(0, sp->sg_pmeg);
6355 			tpte = getpte4(VA_VPG(va) << PGSHIFT);
6356 		}
6357 		setcontext4(ctx);
6358 	} else {
6359 		int *pte = sp->sg_pte;
6360 
6361 		if (pte == NULL) {
6362 #ifdef DEBUG
6363 			if (pmapdebug & PDB_FOLLOW)
6364 				printf("pmap_extract: invalid segment\n");
6365 #endif
6366 			return (FALSE);
6367 		}
6368 		tpte = pte[VA_VPG(va)];
6369 	}
6370 	if ((tpte & PG_V) == 0) {
6371 #ifdef DEBUG
6372 		if (pmapdebug & PDB_FOLLOW)
6373 			printf("pmap_extract: invalid pte\n");
6374 #endif
6375 		return (FALSE);
6376 	}
6377 	tpte &= PG_PFNUM;
6378 	tpte = tpte;
6379 	if (pap != NULL)
6380 		*pap = (tpte << PGSHIFT) | (va & PGOFSET);
6381 	return (TRUE);
6382 }
6383 #endif /*4,4c*/
6384 
6385 #if defined(SUN4M)		/* 4m version of pmap_extract */
6386 /*
6387  * Extract the physical page address associated
6388  * with the given map/virtual_address pair.
6389  * GRR, the vm code knows; we should not have to do this!
6390  */
6391 boolean_t
6392 pmap_extract4m(pm, va, pap)
6393 	struct pmap *pm;
6394 	vaddr_t va;
6395 	paddr_t *pap;
6396 {
6397 	struct regmap *rm;
6398 	struct segmap *sm;
6399 	int pte;
6400 
6401 	if ((rm = pm->pm_regmap) == NULL) {
6402 #ifdef DEBUG
6403 		if (pmapdebug & PDB_FOLLOW)
6404 			printf("pmap_extract: no regmap entry\n");
6405 #endif
6406 		return (FALSE);
6407 	}
6408 
6409 	rm += VA_VREG(va);
6410 	if ((sm = rm->rg_segmap) == NULL) {
6411 #ifdef DEBUG
6412 		if (pmapdebug & PDB_FOLLOW)
6413 			printf("pmap_extract: no segmap\n");
6414 #endif
6415 		return (FALSE);
6416 	}
6417 
6418 	sm += VA_VSEG(va);
6419 	if (sm->sg_pte == NULL) {
6420 #ifdef DEBUG
6421 		if (pmapdebug & PDB_FOLLOW)
6422 			printf("pmap_extract: no ptes\n");
6423 #endif
6424 		return (FALSE);
6425 	}
6426 
6427 	pte = sm->sg_pte[VA_SUN4M_VPG(va)];
6428 	if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE) {
6429 #ifdef DEBUG
6430 		if (pmapdebug & PDB_FOLLOW)
6431 			printf("pmap_extract: invalid pte of type %d\n",
6432 			       pte & SRMMU_TETYPE);
6433 #endif
6434 		return (FALSE);
6435 	}
6436 
6437 	if (pap != NULL)
6438 		*pap = ptoa((pte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT) |
6439 		    VA_OFF(va);
6440 	return (TRUE);
6441 }
6442 #endif /* sun4m */
6443 
6444 /*
6445  * Copy the range specified by src_addr/len
6446  * from the source map to the range dst_addr/len
6447  * in the destination map.
6448  *
6449  * This routine is only advisory and need not do anything.
6450  */
6451 /* ARGSUSED */
6452 int pmap_copy_disabled=0;
6453 void
6454 pmap_copy(dst_pmap, src_pmap, dst_addr, len, src_addr)
6455 	struct pmap *dst_pmap, *src_pmap;
6456 	vaddr_t dst_addr;
6457 	vsize_t len;
6458 	vaddr_t src_addr;
6459 {
6460 #if notyet
6461 	struct regmap *rm;
6462 	struct segmap *sm;
6463 
6464 	if (pmap_copy_disabled)
6465 		return;
6466 #ifdef DIAGNOSTIC
6467 	if (VA_OFF(src_addr) != 0)
6468 		printf("pmap_copy: addr not page aligned: 0x%lx\n", src_addr);
6469 	if ((len & (NBPG-1)) != 0)
6470 		printf("pmap_copy: length not page aligned: 0x%lx\n", len);
6471 #endif
6472 
6473 	if (src_pmap == NULL)
6474 		return;
6475 
6476 	if (CPU_ISSUN4M) {
6477 		int i, npg, pte;
6478 		paddr_t pa;
6479 
6480 		npg = len >> PGSHIFT;
6481 		for (i = 0; i < npg; i++) {
6482 			tlb_flush_page(src_addr);
6483 			if ((rm = src_pmap->pm_regmap) == NULL)
6484 				continue;
6485 			rm += VA_VREG(src_addr);
6486 
6487 			if ((sm = rm->rg_segmap) == NULL)
6488 				continue;
6489 			sm += VA_VSEG(src_addr);
6490 			if (sm->sg_npte == 0)
6491 				continue;
6492 
6493 			pte = sm->sg_pte[VA_SUN4M_VPG(src_addr)];
6494 			if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE)
6495 				continue;
6496 
6497 			pa = ptoa((pte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT);
6498 			pmap_enter(dst_pmap, dst_addr,
6499 				   pa,
6500 				   (pte & PPROT_WRITE)
6501 					? (VM_PROT_WRITE | VM_PROT_READ)
6502 					: VM_PROT_READ,
6503 				   0);
6504 			src_addr += NBPG;
6505 			dst_addr += NBPG;
6506 		}
6507 		pmap_update(dst_pmap);
6508 	}
6509 #endif
6510 }
6511 
6512 /*
6513  * Garbage collects the physical map system for
6514  * pages which are no longer used.
6515  * Success need not be guaranteed -- that is, there
6516  * may well be pages which are not referenced, but
6517  * others may be collected.
6518  * Called by the pageout daemon when pages are scarce.
6519  */
6520 /* ARGSUSED */
6521 void
6522 pmap_collect(pm)
6523 	struct pmap *pm;
6524 {
6525 }
6526 
6527 #if defined(SUN4) || defined(SUN4C)
6528 
6529 /*
6530  * Clear the modify bit for the given physical page.
6531  */
6532 boolean_t
6533 pmap_clear_modify4_4c(pg)
6534 	struct vm_page *pg;
6535 {
6536 	struct pvlist *pv;
6537 	u_int pfn = atop(VM_PAGE_TO_PHYS(pg));
6538 	boolean_t rv;
6539 
6540 	if ((pv = pvhead(pfn)) == NULL)
6541 		return (0);
6542 
6543 	(void) pv_syncflags4_4c(pv);
6544 	rv = pv->pv_flags & PV_MOD;
6545 	pv->pv_flags &= ~PV_MOD;
6546 	return (rv);
6547 }
6548 
6549 /*
6550  * Tell whether the given physical page has been modified.
6551  */
6552 boolean_t
6553 pmap_is_modified4_4c(pg)
6554 	struct vm_page *pg;
6555 {
6556 	struct pvlist *pv;
6557 	u_int pfn = atop(VM_PAGE_TO_PHYS(pg));
6558 
6559 	if ((pv = pvhead(pfn)) == NULL)
6560 		return (0);
6561 
6562 	return (pv->pv_flags & PV_MOD || pv_syncflags4_4c(pv) & PV_MOD);
6563 }
6564 
6565 /*
6566  * Clear the reference bit for the given physical page.
6567  */
6568 boolean_t
6569 pmap_clear_reference4_4c(pg)
6570 	struct vm_page *pg;
6571 {
6572 	struct pvlist *pv;
6573 	u_int pfn = atop(VM_PAGE_TO_PHYS(pg));
6574 	boolean_t rv;
6575 
6576 	if ((pv = pvhead(pfn)) == NULL)
6577 		return (0);
6578 
6579 	(void) pv_syncflags4_4c(pv);
6580 	rv = pv->pv_flags & PV_REF;
6581 	pv->pv_flags &= ~PV_REF;
6582 	return (rv);
6583 }
6584 
6585 /*
6586  * Tell whether the given physical page has been referenced.
6587  */
6588 boolean_t
6589 pmap_is_referenced4_4c(pg)
6590 	struct vm_page *pg;
6591 {
6592 	struct pvlist *pv;
6593 	u_int pfn = atop(VM_PAGE_TO_PHYS(pg));
6594 
6595 	if ((pv = pvhead(pfn)) == NULL)
6596 		return (0);
6597 
6598 	return (pv->pv_flags & PV_REF || pv_syncflags4_4c(pv) & PV_REF);
6599 }
6600 #endif /*4,4c*/
6601 
6602 #if defined(SUN4M)
6603 
6604 /*
6605  * 4m versions of bit test/set routines
6606  *
6607  * Note that the 4m-specific routines should eventually service these
6608  * requests from their page tables, and the whole pvlist bit mess should
6609  * be dropped for the 4m (unless this causes a performance hit from
6610  * tracing down pagetables/regmap/segmaps).
6611  */
6612 
6613 /*
6614  * Clear the modify bit for the given physical page.
6615  */
6616 boolean_t
6617 pmap_clear_modify4m(pg)	   /* XXX %%%: Should service from swpagetbl for 4m */
6618 	struct vm_page *pg;
6619 {
6620 	struct pvlist *pv;
6621 	u_int pfn = atop(VM_PAGE_TO_PHYS(pg));
6622 	boolean_t rv;
6623 
6624 	if ((pv = pvhead(pfn)) == NULL)
6625 		return (0);
6626 
6627 	(void) pv_syncflags4m(pv);
6628 	rv = pv->pv_flags & PV_MOD4M;
6629 	pv->pv_flags &= ~PV_MOD4M;
6630 	return (rv);
6631 }
6632 
6633 /*
6634  * Tell whether the given physical page has been modified.
6635  */
6636 boolean_t
6637 pmap_is_modified4m(pg) /* Test performance with SUN4M && SUN4/4C. XXX */
6638 	struct vm_page *pg;
6639 {
6640 	struct pvlist *pv;
6641 	u_int pfn = atop(VM_PAGE_TO_PHYS(pg));
6642 
6643 	if ((pv = pvhead(pfn)) == NULL)
6644 		return (0);
6645 
6646 	return (pv->pv_flags & PV_MOD4M || pv_syncflags4m(pv) & PV_MOD4M);
6647 }
6648 
6649 /*
6650  * Clear the reference bit for the given physical page.
6651  */
6652 boolean_t
6653 pmap_clear_reference4m(pg)
6654 	struct vm_page *pg;
6655 {
6656 	struct pvlist *pv;
6657 	u_int pfn = atop(VM_PAGE_TO_PHYS(pg));
6658 	boolean_t rv;
6659 
6660 	if ((pv = pvhead(pfn)) == NULL)
6661 		return (0);
6662 
6663 	(void) pv_syncflags4m(pv);
6664 	rv = pv->pv_flags & PV_REF4M;
6665 	pv->pv_flags &= ~PV_REF4M;
6666 	return (rv);
6667 }
6668 
6669 /*
6670  * Tell whether the given physical page has been referenced.
6671  */
6672 int
6673 pmap_is_referenced4m(pg)
6674 	struct vm_page *pg;
6675 {
6676 	struct pvlist *pv;
6677 	u_int pfn = atop(VM_PAGE_TO_PHYS(pg));
6678 
6679 	if ((pv = pvhead(pfn)) == NULL)
6680 		return (0);
6681 
6682 	return (pv->pv_flags & PV_REF4M || pv_syncflags4m(pv) & PV_REF4M);
6683 }
6684 #endif /* 4m */
6685 
6686 /*
6687  * Fill the given MI physical page with zero bytes.
6688  *
6689  * We avoid stomping on the cache.
6690  * XXX	might be faster to use destination's context and allow cache to fill?
6691  */
6692 
6693 #if defined(SUN4) || defined(SUN4C)
6694 
6695 void
6696 pmap_zero_page4_4c(pa)
6697 	paddr_t pa;
6698 {
6699 	u_int pfn = atop(pa);
6700 	struct pvlist *pv;
6701 	caddr_t va;
6702 	int pte;
6703 
6704 	if ((pv = pvhead(pfn)) != NULL) {
6705 		/*
6706 		 * The following might not be necessary since the page
6707 		 * is being cleared because it is about to be allocated,
6708 		 * i.e., is in use by no one.
6709 		 */
6710 		pv_flushcache(pv);
6711 	}
6712 	pte = PG_V | PG_S | PG_W | PG_NC | (pfn & PG_PFNUM);
6713 
6714 	va = vpage[0];
6715 	setpte4(va, pte);
6716 	qzero(va, NBPG);
6717 	setpte4(va, 0);
6718 }
6719 
6720 /*
6721  * Copy the given MI physical source page to its destination.
6722  *
6723  * We avoid stomping on the cache as above (with same `XXX' note).
6724  * We must first flush any write-back cache for the source page.
6725  * We go ahead and stomp on the kernel's virtual cache for the
6726  * source page, since the cache can read memory MUCH faster than
6727  * the processor.
6728  */
6729 void
6730 pmap_copy_page4_4c(src, dst)
6731 	paddr_t src, dst;
6732 {
6733 	struct pvlist *pv;
6734 	caddr_t sva, dva;
6735 	u_int srcpfn, dstpfn;
6736 	int spte, dpte;
6737 
6738 	srcpfn = atop(src);
6739 	dstpfn = atop(dst);
6740 	if ((pv = pvhead(srcpfn)) != NULL) {
6741 		if (CACHEINFO.c_vactype == VAC_WRITEBACK)
6742 			pv_flushcache(pv);
6743 	}
6744 	spte = PG_V | PG_S | (srcpfn & PG_PFNUM);
6745 
6746 	if ((pv = pvhead(dstpfn)) != NULL) {
6747 		/* similar `might not be necessary' comment applies */
6748 		if (CACHEINFO.c_vactype != VAC_NONE)
6749 			pv_flushcache(pv);
6750 	}
6751 	dpte = PG_V | PG_S | PG_W | PG_NC | (dstpfn & PG_PFNUM);
6752 
6753 	sva = vpage[0];
6754 	dva = vpage[1];
6755 	setpte4(sva, spte);
6756 	setpte4(dva, dpte);
6757 	qcopy(sva, dva, NBPG);	/* loads cache, so we must ... */
6758 	cache_flush_page((vaddr_t)sva);
6759 	setpte4(sva, 0);
6760 	setpte4(dva, 0);
6761 }
6762 #endif /* 4, 4c */
6763 
6764 #if defined(SUN4M)		/* sun4m version of copy/zero routines */
6765 /*
6766  * Fill the given MI physical page with zero bytes.
6767  *
6768  * We avoid stomping on the cache.
6769  * XXX	might be faster to use destination's context and allow cache to fill?
6770  */
6771 void
6772 pmap_zero_page4m(pa)
6773 	paddr_t pa;
6774 {
6775 	u_int pfn = atop(pa);
6776 	struct pvlist *pv;
6777 	caddr_t va;
6778 	int pte;
6779 
6780 	if ((pv = pvhead(pfn)) != NULL) {
6781 		/*
6782 		 * The following VAC flush might not be necessary since the
6783 		 * page is being cleared because it is about to be allocated,
6784 		 * i.e., is in use by no one.
6785 		 * In the case of a physical cache, a flush (or just an
6786 		 * invalidate, if possible) is usually necessary when using
6787 		 * uncached access to clear it.
6788 		 */
6789 		if (CACHEINFO.c_vactype != VAC_NONE)
6790 			pv_flushcache(pv);
6791 		else
6792 			pcache_flush_page(pa, 1);
6793 	}
6794 	pte = SRMMU_TEPTE | PPROT_N_RWX | (pfn << SRMMU_PPNSHIFT);
6795 	if (cpuinfo.flags & CPUFLG_CACHE_MANDATORY)
6796 		pte |= SRMMU_PG_C;
6797 
6798 	va = vpage[0];
6799 	setpgt4m(vpage_pte[0], pte);
6800 	qzero(va, NBPG);
6801 	/* Remove temporary mapping */
6802 	tlb_flush_page(va);
6803 	setpgt4m(vpage_pte[0], SRMMU_TEINVALID);
6804 }
6805 
6806 /*
6807  * Viking/MXCC specific version of pmap_zero_page
6808  */
6809 void
6810 pmap_zero_page_viking_mxcc(pa)
6811 	paddr_t pa;
6812 {
6813 	u_int offset;
6814 	u_int stream_data_addr = MXCC_STREAM_DATA;
6815 	u_int64_t v = (u_int64_t)pa;
6816 
6817 	/* Load MXCC stream data register with 0 (bottom 32 bytes only) */
6818 	stda(stream_data_addr+0, ASI_CONTROL, 0);
6819 	stda(stream_data_addr+8, ASI_CONTROL, 0);
6820 	stda(stream_data_addr+16, ASI_CONTROL, 0);
6821 	stda(stream_data_addr+24, ASI_CONTROL, 0);
6822 
6823 	/* Then write the stream data register to each block in the page */
6824 	v |= MXCC_STREAM_C;
6825 	for (offset = 0; offset < NBPG; offset += MXCC_STREAM_BLKSZ) {
6826 		stda(MXCC_STREAM_DST, ASI_CONTROL, v | offset);
6827 	}
6828 }
6829 
6830 /*
6831  * HyperSPARC/RT625 specific version of pmap_zero_page
6832  */
6833 void
6834 pmap_zero_page_hypersparc(pa)
6835 	paddr_t pa;
6836 {
6837 	u_int pfn = atop(pa);
6838 	struct pvlist *pv;
6839 	caddr_t va;
6840 	int pte;
6841 	int offset;
6842 
6843 	/*
6844 	 * We still have to map the page, since ASI_BLOCKFILL
6845 	 * takes virtual addresses. This also means we have to
6846 	 * consider cache aliasing; therefore we still need
6847 	 * to flush the cache here. All we gain is the speed-up
6848 	 * in zero-fill loop itself..
6849 	 */
6850 	if ((pv = pvhead(pfn)) != NULL) {
6851 		/*
6852 		 * The following might not be necessary since the page
6853 		 * is being cleared because it is about to be allocated,
6854 		 * i.e., is in use by no one.
6855 		 */
6856 		if (CACHEINFO.c_vactype != VAC_NONE)
6857 			pv_flushcache(pv);
6858 	}
6859 	pte = SRMMU_TEPTE | SRMMU_PG_C | PPROT_N_RWX | (pfn << SRMMU_PPNSHIFT);
6860 
6861 	va = vpage[0];
6862 	setpgt4m(vpage_pte[0], pte);
6863 	for (offset = 0; offset < NBPG; offset += 32) {
6864 		sta(va + offset, ASI_BLOCKFILL, 0);
6865 	}
6866 	/* Remove temporary mapping */
6867 	tlb_flush_page(va);
6868 	setpgt4m(vpage_pte[0], SRMMU_TEINVALID);
6869 }
6870 
6871 /*
6872  * Copy the given MI physical source page to its destination.
6873  *
6874  * We avoid stomping on the cache as above (with same `XXX' note).
6875  * We must first flush any write-back cache for the source page.
6876  * We go ahead and stomp on the kernel's virtual cache for the
6877  * source page, since the cache can read memory MUCH faster than
6878  * the processor.
6879  */
6880 void
6881 pmap_copy_page4m(src, dst)
6882 	paddr_t src, dst;
6883 {
6884 	struct pvlist *pv;
6885 	caddr_t sva, dva;
6886 	u_int srcpfn, dstpfn;
6887 	int spte, dpte;
6888 
6889 	srcpfn = atop(src);
6890 	dstpfn = atop(dst);
6891 	if ((pv = pvhead(srcpfn)) != NULL) {
6892 		if (CACHEINFO.c_vactype == VAC_WRITEBACK)
6893 			pv_flushcache(pv);
6894 	}
6895 
6896 	spte = SRMMU_TEPTE | SRMMU_PG_C | PPROT_N_RX |
6897 		(srcpfn << SRMMU_PPNSHIFT);
6898 
6899 	if ((pv = pvhead(dstpfn)) != NULL) {
6900 		/* similar `might not be necessary' comment applies */
6901 		if (CACHEINFO.c_vactype != VAC_NONE)
6902 			pv_flushcache(pv);
6903 		else
6904 			pcache_flush_page(dst, 1);
6905 	}
6906 
6907 	dpte = SRMMU_TEPTE | PPROT_N_RWX | (dstpfn << SRMMU_PPNSHIFT);
6908 	if (cpuinfo.flags & CPUFLG_CACHE_MANDATORY)
6909 		dpte |= SRMMU_PG_C;
6910 
6911 	sva = vpage[0];
6912 	dva = vpage[1];
6913 	setpgt4m(vpage_pte[0], spte);
6914 	setpgt4m(vpage_pte[1], dpte);
6915 	qcopy(sva, dva, NBPG);	/* loads cache, so we must ... */
6916 	cache_flush_page((vaddr_t)sva);
6917 	tlb_flush_page(sva);
6918 	setpgt4m(vpage_pte[0], SRMMU_TEINVALID);
6919 	tlb_flush_page(dva);
6920 	setpgt4m(vpage_pte[1], SRMMU_TEINVALID);
6921 }
6922 
6923 /*
6924  * Viking/MXCC specific version of pmap_copy_page
6925  */
6926 void
6927 pmap_copy_page_viking_mxcc(src, dst)
6928 	paddr_t src, dst;
6929 {
6930 	u_int offset;
6931 	u_int64_t v1 = (u_int64_t)src;
6932 	u_int64_t v2 = (u_int64_t)dst;
6933 
6934 	/* Enable cache-coherency */
6935 	v1 |= MXCC_STREAM_C;
6936 	v2 |= MXCC_STREAM_C;
6937 
6938 	/* Copy through stream data register */
6939 	for (offset = 0; offset < NBPG; offset += MXCC_STREAM_BLKSZ) {
6940 		stda(MXCC_STREAM_SRC, ASI_CONTROL, v1 | offset);
6941 		stda(MXCC_STREAM_DST, ASI_CONTROL, v2 | offset);
6942 	}
6943 }
6944 
6945 /*
6946  * HyperSPARC/RT625 specific version of pmap_copy_page
6947  */
6948 void
6949 pmap_copy_page_hypersparc(src, dst)
6950 	paddr_t src, dst;
6951 {
6952 	struct pvlist *pv;
6953 	caddr_t sva, dva;
6954 	u_int srcpfn, dstpfn;
6955 	int spte, dpte;
6956 	int offset;
6957 
6958 	/*
6959 	 * We still have to map the pages, since ASI_BLOCKCOPY
6960 	 * takes virtual addresses. This also means we have to
6961 	 * consider cache aliasing; therefore we still need
6962 	 * to flush the cache here. All we gain is the speed-up
6963 	 * in copy loop itself..
6964 	 */
6965 
6966 	srcpfn = atop(src);
6967 	dstpfn = atop(dst);
6968 	if ((pv = pvhead(srcpfn)) != NULL) {
6969 		if (CACHEINFO.c_vactype == VAC_WRITEBACK)
6970 			pv_flushcache(pv);
6971 	}
6972 
6973 	spte = SRMMU_TEPTE | SRMMU_PG_C | PPROT_N_RX |
6974 		(srcpfn << SRMMU_PPNSHIFT);
6975 
6976 	if ((pv = pvhead(dstpfn)) != NULL) {
6977 		/* similar `might not be necessary' comment applies */
6978 		if (CACHEINFO.c_vactype != VAC_NONE)
6979 			pv_flushcache(pv);
6980 	}
6981 
6982 	dpte = SRMMU_TEPTE | SRMMU_PG_C | PPROT_N_RWX |
6983 		(dstpfn << SRMMU_PPNSHIFT);
6984 
6985 	sva = vpage[0];
6986 	dva = vpage[1];
6987 	setpgt4m(vpage_pte[0], spte);
6988 	setpgt4m(vpage_pte[1], dpte);
6989 
6990 	for (offset = 0; offset < NBPG; offset += 32) {
6991 		sta(dva + offset, ASI_BLOCKCOPY, sva + offset);
6992 	}
6993 
6994 	tlb_flush_page(sva);
6995 	setpgt4m(vpage_pte[0], SRMMU_TEINVALID);
6996 	tlb_flush_page(dva);
6997 	setpgt4m(vpage_pte[1], SRMMU_TEINVALID);
6998 }
6999 #endif /* SUN4M */
7000 
7001 /*
7002  * Turn a cdevsw d_mmap value into a byte address for pmap_enter.
7003  * XXX	this should almost certainly be done differently, and
7004  *	elsewhere, or even not at all
7005  */
7006 paddr_t
7007 pmap_phys_address(x)
7008 	int x;
7009 {
7010 
7011 	return ((paddr_t)x);
7012 }
7013 
7014 /*
7015  * Turn off cache for a given (va, number of pages).
7016  *
7017  * We just assert PG_NC for each PTE; the addresses must reside
7018  * in locked kernel space.  A cache flush is also done.
7019  */
7020 void
7021 kvm_uncache(va, npages)
7022 	caddr_t va;
7023 	int npages;
7024 {
7025 	struct pvlist *pv;
7026 	int pte;
7027 	u_int pfn;
7028 
7029 	if (CPU_ISSUN4M) {
7030 #if defined(SUN4M)
7031 		int ctx = getcontext4m();
7032 
7033 		setcontext4m(0);
7034 		for (; --npages >= 0; va += NBPG) {
7035 			pte = getpte4m((vaddr_t) va);
7036 			if ((pte & SRMMU_TETYPE) != SRMMU_TEPTE)
7037 				panic("kvm_uncache: table entry not pte");
7038 
7039 			if ((pte & SRMMU_PGTYPE) == PG_SUN4M_OBMEM) {
7040 				pfn = (pte & SRMMU_PPNMASK) >> SRMMU_PPNSHIFT;
7041 				if ((pv = pvhead(pfn)) != NULL) {
7042 					pv_uncache(pv);
7043 					return;
7044 				}
7045 				cache_flush_page((int)va);
7046 			}
7047 
7048 			pte &= ~SRMMU_PG_C;
7049 			setpte4m((vaddr_t)va, pte);
7050 		}
7051 		setcontext4m(ctx);
7052 #endif
7053 	} else {
7054 #if defined(SUN4) || defined(SUN4C)
7055 		for (; --npages >= 0; va += NBPG) {
7056 			pte = getpte4(va);
7057 			if ((pte & PG_V) == 0)
7058 				panic("kvm_uncache !pg_v");
7059 
7060 			if ((pte & PG_TYPE) == PG_OBMEM) {
7061 				pfn = pte & PG_PFNUM;
7062 				if ((pv = pvhead(pfn)) != NULL) {
7063 					pv_uncache(pv);
7064 					return;
7065 				}
7066 				cache_flush_page((int)va);
7067 			}
7068 			pte |= PG_NC;
7069 			setpte4(va, pte);
7070 		}
7071 #endif
7072 	}
7073 }
7074 
7075 /*
7076  * Turn on IO cache for a given (va, number of pages).
7077  *
7078  * We just assert PG_NC for each PTE; the addresses must reside
7079  * in locked kernel space.  A cache flush is also done.
7080  */
7081 void
7082 kvm_iocache(va, npages)
7083 	caddr_t va;
7084 	int npages;
7085 {
7086 
7087 #ifdef SUN4M
7088 	if (CPU_ISSUN4M) /* %%%: Implement! */
7089 		panic("kvm_iocache: 4m iocache not implemented");
7090 #endif
7091 #if defined(SUN4) || defined(SUN4C)
7092 	for (; --npages >= 0; va += NBPG) {
7093 		int pte = getpte4(va);
7094 		if ((pte & PG_V) == 0)
7095 			panic("kvm_iocache !pg_v");
7096 		pte |= PG_IOC;
7097 		setpte4(va, pte);
7098 	}
7099 #endif
7100 }
7101 
7102 int
7103 pmap_count_ptes(pm)
7104 	struct pmap *pm;
7105 {
7106 	int idx, vs, total;
7107 	struct regmap *rp;
7108 	struct segmap *sp;
7109 
7110 	if (pm == pmap_kernel()) {
7111 		rp = &pm->pm_regmap[NUREG];
7112 		idx = NKREG;
7113 	} else {
7114 		rp = pm->pm_regmap;
7115 		idx = NUREG;
7116 	}
7117 	for (total = 0; idx;) {
7118 		if ((sp = rp[--idx].rg_segmap) == NULL) {
7119 			continue;
7120 		}
7121 		for (vs = 0; vs < NSEGRG; vs++) {
7122 			total += sp[vs].sg_npte;
7123 		}
7124 	}
7125 	pm->pm_stats.resident_count = total;
7126 	return (total);
7127 }
7128 
7129 /*
7130  * Find first virtual address >= *va that is
7131  * least likely to cause cache aliases.
7132  * (This will just seg-align mappings.)
7133  */
7134 void
7135 pmap_prefer(foff, vap)
7136 	vaddr_t foff;
7137 	vaddr_t *vap;
7138 {
7139 	vaddr_t va = *vap;
7140 	long d, m;
7141 
7142 	if (VA_INHOLE(va))
7143 		va = MMU_HOLE_END;
7144 
7145 	m = CACHE_ALIAS_DIST;
7146 	if (m == 0)		/* m=0 => no cache aliasing */
7147 		return;
7148 
7149 	d = foff - va;
7150 	d &= (m - 1);
7151 	*vap = va + d;
7152 }
7153 
7154 void
7155 pmap_redzone()
7156 {
7157 	pmap_remove(pmap_kernel(), KERNBASE, KERNBASE+NBPG);
7158 }
7159 
7160 /*
7161  * Activate the address space for the specified process.  If the
7162  * process is the current process, load the new MMU context.
7163  */
7164 void
7165 pmap_activate(p)
7166 	struct proc *p;
7167 {
7168 	pmap_t pmap = p->p_vmspace->vm_map.pmap;
7169 	int s;
7170 
7171 	/*
7172 	 * This is essentially the same thing that happens in cpu_switch()
7173 	 * when the newly selected process is about to run, except that we
7174 	 * have to make sure to clean the register windows before we set
7175 	 * the new context.
7176 	 */
7177 
7178 	s = splvm();
7179 	if (p == curproc) {
7180 		write_user_windows();
7181 		if (pmap->pm_ctx == NULL) {
7182 			ctx_alloc(pmap);	/* performs setcontext() */
7183 		} else {
7184 			/* Do any cache flush needed on context switch */
7185 			(*cpuinfo.pure_vcache_flush)();
7186 			setcontext(pmap->pm_ctxnum);
7187 		}
7188 	}
7189 	splx(s);
7190 }
7191 
7192 /*
7193  * Deactivate the address space of the specified process.
7194  */
7195 void
7196 pmap_deactivate(p)
7197 	struct proc *p;
7198 {
7199 }
7200 
7201 #ifdef DEBUG
7202 /*
7203  * Check consistency of a pmap (time consuming!).
7204  */
7205 void
7206 pm_check(s, pm)
7207 	char *s;
7208 	struct pmap *pm;
7209 {
7210 	if (pm == pmap_kernel())
7211 		pm_check_k(s, pm);
7212 	else
7213 		pm_check_u(s, pm);
7214 }
7215 
7216 void
7217 pm_check_u(s, pm)
7218 	char *s;
7219 	struct pmap *pm;
7220 {
7221 	struct regmap *rp;
7222 	struct segmap *sp;
7223 	int n, vs, vr, j, m, *pte;
7224 
7225 	if (pm->pm_regmap == NULL)
7226 		panic("%s: CHK(pmap %p): no region mapping", s, pm);
7227 
7228 #if defined(SUN4M)
7229 	if (CPU_ISSUN4M &&
7230 	    (pm->pm_reg_ptps[0] == NULL ||
7231 	     pm->pm_reg_ptps_pa[0] != VA2PA((caddr_t)pm->pm_reg_ptps[0])))
7232 		panic("%s: CHK(pmap %p): no SRMMU region table or bad pa: "
7233 		      "tblva=%p, tblpa=0x%x",
7234 			s, pm, pm->pm_reg_ptps[0], pm->pm_reg_ptps_pa[0]);
7235 
7236 	if (CPU_ISSUN4M && pm->pm_ctx != NULL &&
7237 	    (cpuinfo.ctx_tbl[pm->pm_ctxnum] != ((VA2PA((caddr_t)pm->pm_reg_ptps[0])
7238 					      >> SRMMU_PPNPASHIFT) |
7239 					     SRMMU_TEPTD)))
7240 	    panic("%s: CHK(pmap %p): SRMMU region table at 0x%x not installed "
7241 		  "for context %d", s, pm, pm->pm_reg_ptps_pa[0], pm->pm_ctxnum);
7242 #endif
7243 
7244 	for (vr = 0; vr < NUREG; vr++) {
7245 		rp = &pm->pm_regmap[vr];
7246 		if (rp->rg_nsegmap == 0)
7247 			continue;
7248 		if (rp->rg_segmap == NULL)
7249 			panic("%s: CHK(vr %d): nsegmap = %d; sp==NULL",
7250 				s, vr, rp->rg_nsegmap);
7251 #if defined(SUN4M)
7252 		if (CPU_ISSUN4M && rp->rg_seg_ptps == NULL)
7253 		    panic("%s: CHK(vr %d): nsegmap=%d; no SRMMU segment table",
7254 			  s, vr, rp->rg_nsegmap);
7255 		if (CPU_ISSUN4M &&
7256 		    pm->pm_reg_ptps[0][vr] != ((VA2PA((caddr_t)rp->rg_seg_ptps) >>
7257 					    SRMMU_PPNPASHIFT) | SRMMU_TEPTD))
7258 		    panic("%s: CHK(vr %d): SRMMU segtbl not installed",s,vr);
7259 #endif
7260 		if ((unsigned int)rp < KERNBASE)
7261 			panic("%s: rp=%p", s, rp);
7262 		n = 0;
7263 		for (vs = 0; vs < NSEGRG; vs++) {
7264 			sp = &rp->rg_segmap[vs];
7265 			if ((unsigned int)sp < KERNBASE)
7266 				panic("%s: sp=%p", s, sp);
7267 			if (sp->sg_npte != 0) {
7268 				n++;
7269 				if (sp->sg_pte == NULL)
7270 					panic("%s: CHK(vr %d, vs %d): npte=%d, "
7271 					   "pte=NULL", s, vr, vs, sp->sg_npte);
7272 #if defined(SUN4M)
7273 				if (CPU_ISSUN4M &&
7274 				    rp->rg_seg_ptps[vs] !=
7275 				     ((VA2PA((caddr_t)sp->sg_pte)
7276 					>> SRMMU_PPNPASHIFT) |
7277 				       SRMMU_TEPTD))
7278 				    panic("%s: CHK(vr %d, vs %d): SRMMU page "
7279 					  "table not installed correctly",s,vr,
7280 					  vs);
7281 #endif
7282 				pte=sp->sg_pte;
7283 				m = 0;
7284 				for (j=0; j<NPTESG; j++,pte++)
7285 				    if ((CPU_ISSUN4M
7286 					 ?((*pte & SRMMU_TETYPE) == SRMMU_TEPTE)
7287 					 :(*pte & PG_V)))
7288 					m++;
7289 				if (m != sp->sg_npte)
7290 				    /*if (pmapdebug & 0x10000)*/
7291 					printf("%s: user CHK(vr %d, vs %d): "
7292 					    "npte(%d) != # valid(%d)\n",
7293 						s, vr, vs, sp->sg_npte, m);
7294 			}
7295 		}
7296 		if (n != rp->rg_nsegmap)
7297 			panic("%s: CHK(vr %d): inconsistent "
7298 				"# of pte's: %d, should be %d",
7299 				s, vr, rp->rg_nsegmap, n);
7300 	}
7301 	return;
7302 }
7303 
7304 void
7305 pm_check_k(s, pm)		/* Note: not as extensive as pm_check_u. */
7306 	char *s;
7307 	struct pmap *pm;
7308 {
7309 	struct regmap *rp;
7310 	int vr, vs, n;
7311 
7312 	if (pm->pm_regmap == NULL)
7313 		panic("%s: CHK(pmap %p): no region mapping", s, pm);
7314 
7315 #if defined(SUN4M)
7316 	if (CPU_ISSUN4M &&
7317 	    (pm->pm_reg_ptps[0] == NULL ||
7318 	     pm->pm_reg_ptps_pa[0] != VA2PA((caddr_t)pm->pm_reg_ptps[0])))
7319 	    panic("%s: CHK(pmap %p): no SRMMU region table or bad pa: tblva=%p, tblpa=0x%x",
7320 		  s, pm, pm->pm_reg_ptps[0], pm->pm_reg_ptps_pa[0]);
7321 
7322 	if (CPU_ISSUN4M &&
7323 	    (cpuinfo.ctx_tbl[0] != ((VA2PA((caddr_t)pm->pm_reg_ptps[0]) >>
7324 					     SRMMU_PPNPASHIFT) | SRMMU_TEPTD)))
7325 	    panic("%s: CHK(pmap %p): SRMMU region table at 0x%x not installed "
7326 		  "for context %d", s, pm, pm->pm_reg_ptps_pa[0], 0);
7327 #endif
7328 	for (vr = NUREG; vr < NUREG+NKREG; vr++) {
7329 		rp = &pm->pm_regmap[vr];
7330 		if (rp->rg_segmap == NULL)
7331 			panic("%s: CHK(vr %d): nsegmap = %d; sp==NULL",
7332 				s, vr, rp->rg_nsegmap);
7333 		if (rp->rg_nsegmap == 0)
7334 			continue;
7335 #if defined(SUN4M)
7336 		if (CPU_ISSUN4M && rp->rg_seg_ptps == NULL)
7337 		    panic("%s: CHK(vr %d): nsegmap=%d; no SRMMU segment table",
7338 			  s, vr, rp->rg_nsegmap);
7339 		if (CPU_ISSUN4M &&
7340 		    pm->pm_reg_ptps[0][vr] != ((VA2PA((caddr_t)rp->rg_seg_ptps[0]) >>
7341 					    SRMMU_PPNPASHIFT) | SRMMU_TEPTD))
7342 		    panic("%s: CHK(vr %d): SRMMU segtbl not installed",s,vr);
7343 #endif
7344 		if (CPU_ISSUN4M) {
7345 			n = NSEGRG;
7346 		} else {
7347 			for (n = 0, vs = 0; vs < NSEGRG; vs++) {
7348 				if (rp->rg_segmap[vs].sg_npte)
7349 					n++;
7350 			}
7351 		}
7352 		if (n != rp->rg_nsegmap)
7353 			printf("%s: kernel CHK(vr %d): inconsistent "
7354 				"# of pte's: %d, should be %d\n",
7355 				s, vr, rp->rg_nsegmap, n);
7356 	}
7357 	return;
7358 }
7359 #endif
7360 
7361 /*
7362  * Return the number of disk blocks that pmap_dumpmmu() will dump.
7363  */
7364 int
7365 pmap_dumpsize()
7366 {
7367 	int	sz;
7368 
7369 	sz = ALIGN(sizeof(kcore_seg_t)) + ALIGN(sizeof(cpu_kcore_hdr_t));
7370 	sz += npmemarr * sizeof(phys_ram_seg_t);
7371 	sz += sizeof(kernel_segmap_store);
7372 
7373 	if (CPU_ISSUN4OR4C)
7374 		/* For each pmeg in the MMU, we'll write NPTESG PTEs. */
7375 		sz += (seginval + 1) * NPTESG * sizeof(int);
7376 
7377 	return btodb(sz + DEV_BSIZE - 1);
7378 }
7379 
7380 /*
7381  * Write the core dump headers and MD data to the dump device.
7382  * We dump the following items:
7383  *
7384  *	kcore_seg_t		 MI header defined in <sys/kcore.h>)
7385  *	cpu_kcore_hdr_t		 MD header defined in <machine/kcore.h>)
7386  *	phys_ram_seg_t[npmemarr] physical memory segments
7387  *	segmap_t[NKREG*NSEGRG]	 the kernel's segment map
7388  *	the MMU pmegs on sun4/sun4c
7389  */
7390 int
7391 pmap_dumpmmu(dump, blkno)
7392 	daddr_t blkno;
7393 	int (*dump)	__P((dev_t, daddr_t, caddr_t, size_t));
7394 {
7395 	kcore_seg_t	*ksegp;
7396 	cpu_kcore_hdr_t	*kcpup;
7397 	phys_ram_seg_t	memseg;
7398 	int		error = 0;
7399 	int		i, memsegoffset, segmapoffset, pmegoffset;
7400 	int		buffer[dbtob(1) / sizeof(int)];
7401 	int		*bp, *ep;
7402 #if defined(SUN4C) || defined(SUN4)
7403 	int	pmeg;
7404 #endif
7405 
7406 #define EXPEDITE(p,n) do {						\
7407 	int *sp = (int *)(p);						\
7408 	int sz = (n);							\
7409 	while (sz > 0) {						\
7410 		*bp++ = *sp++;						\
7411 		if (bp >= ep) {						\
7412 			error = (*dump)(dumpdev, blkno,			\
7413 					(caddr_t)buffer, dbtob(1));	\
7414 			if (error != 0)					\
7415 				return (error);				\
7416 			++blkno;					\
7417 			bp = buffer;					\
7418 		}							\
7419 		sz -= 4;						\
7420 	}								\
7421 } while (0)
7422 
7423 	setcontext(0);
7424 
7425 	/* Setup bookkeeping pointers */
7426 	bp = buffer;
7427 	ep = &buffer[sizeof(buffer) / sizeof(buffer[0])];
7428 
7429 	/* Fill in MI segment header */
7430 	ksegp = (kcore_seg_t *)bp;
7431 	CORE_SETMAGIC(*ksegp, KCORE_MAGIC, MID_MACHINE, CORE_CPU);
7432 	ksegp->c_size = dbtob(pmap_dumpsize()) - ALIGN(sizeof(kcore_seg_t));
7433 
7434 	/* Fill in MD segment header (interpreted by MD part of libkvm) */
7435 	kcpup = (cpu_kcore_hdr_t *)((int)bp + ALIGN(sizeof(kcore_seg_t)));
7436 	kcpup->cputype = cputyp;
7437 	kcpup->kernbase = KERNBASE;
7438 	kcpup->nmemseg = npmemarr;
7439 	kcpup->memsegoffset = memsegoffset = ALIGN(sizeof(cpu_kcore_hdr_t));
7440 	kcpup->nsegmap = NKREG*NSEGRG;
7441 	kcpup->segmapoffset = segmapoffset =
7442 		memsegoffset + npmemarr * sizeof(phys_ram_seg_t);
7443 
7444 	kcpup->npmeg = (CPU_ISSUN4OR4C) ? seginval + 1 : 0;
7445 	kcpup->pmegoffset = pmegoffset =
7446 		segmapoffset + kcpup->nsegmap * sizeof(struct segmap);
7447 
7448 	/* Note: we have assumed everything fits in buffer[] so far... */
7449 	bp = (int *)((int)kcpup + ALIGN(sizeof(cpu_kcore_hdr_t)));
7450 
7451 #if 0
7452 	/* Align storage for upcoming quad-aligned segment array */
7453 	while (bp != (int *)ALIGN(bp)) {
7454 		int dummy = 0;
7455 		EXPEDITE(&dummy, 4);
7456 	}
7457 #endif
7458 
7459 	for (i = 0; i < npmemarr; i++) {
7460 		memseg.start = pmemarr[i].addr;
7461 		memseg.size = pmemarr[i].len;
7462 		EXPEDITE(&memseg, sizeof(phys_ram_seg_t));
7463 	}
7464 
7465 	EXPEDITE(&kernel_segmap_store, sizeof(kernel_segmap_store));
7466 
7467 	if (CPU_ISSUN4M)
7468 		goto out;
7469 
7470 #if defined(SUN4C) || defined(SUN4)
7471 	/*
7472 	 * dump page table entries
7473 	 *
7474 	 * We dump each pmeg in order (by segment number).  Since the MMU
7475 	 * automatically maps the given virtual segment to a pmeg we must
7476 	 * iterate over the segments by incrementing an unused segment slot
7477 	 * in the MMU.  This fixed segment number is used in the virtual
7478 	 * address argument to getpte().
7479 	 */
7480 
7481 	/*
7482 	 * Go through the pmegs and dump each one.
7483 	 */
7484 	for (pmeg = 0; pmeg <= seginval; ++pmeg) {
7485 		int va = 0;
7486 
7487 		setsegmap(va, pmeg);
7488 		i = NPTESG;
7489 		do {
7490 			int pte = getpte4(va);
7491 			EXPEDITE(&pte, sizeof(pte));
7492 			va += NBPG;
7493 		} while (--i > 0);
7494 	}
7495 	setsegmap(0, seginval);
7496 #endif
7497 
7498 out:
7499 	if (bp != buffer)
7500 		error = (*dump)(dumpdev, blkno++, (caddr_t)buffer, dbtob(1));
7501 
7502 	return (error);
7503 }
7504 
7505 /*
7506  * Helper function for debuggers.
7507  */
7508 void
7509 pmap_writetext(dst, ch)
7510 	unsigned char *dst;
7511 	int ch;
7512 {
7513 	int s, pte0, pte, ctx;
7514 	vaddr_t va;
7515 
7516 	s = splvm();
7517 	va = (unsigned long)dst & (~PGOFSET);
7518 	cpuinfo.cache_flush(dst, 1);
7519 
7520 	ctx = getcontext();
7521 	setcontext(0);
7522 
7523 #if defined(SUN4M)
7524 	if (CPU_ISSUN4M) {
7525 		pte0 = getpte4m(va);
7526 		if ((pte0 & SRMMU_TETYPE) != SRMMU_TEPTE) {
7527 			splx(s);
7528 			return;
7529 		}
7530 		pte = pte0 | PPROT_WRITE;
7531 		setpte4m(va, pte);
7532 		*dst = (unsigned char)ch;
7533 		setpte4m(va, pte0);
7534 
7535 	}
7536 #endif
7537 #if defined(SUN4) || defined(SUN4C)
7538 	if (CPU_ISSUN4C || CPU_ISSUN4) {
7539 		pte0 = getpte4(va);
7540 		if ((pte0 & PG_V) == 0) {
7541 			splx(s);
7542 			return;
7543 		}
7544 		pte = pte0 | PG_W;
7545 		setpte4(va, pte);
7546 		*dst = (unsigned char)ch;
7547 		setpte4(va, pte0);
7548 	}
7549 #endif
7550 	cpuinfo.cache_flush(dst, 1);
7551 	setcontext(ctx);
7552 	splx(s);
7553 }
7554 
7555 #ifdef EXTREME_DEBUG
7556 
7557 static void test_region __P((int, int, int));
7558 
7559 void
7560 debug_pagetables()
7561 {
7562 	int i;
7563 	int *regtbl;
7564 	int te;
7565 
7566 	printf("\nncontext=%d. ",ncontext);
7567 	printf("Context table is at va 0x%x. Level 0 PTP: 0x%x\n",
7568 	       cpuinfo.ctx_tbl, cpuinfo.ctx_tbl[0]);
7569 	printf("Context 0 region table is at va 0x%x, pa 0x%x. Contents:\n",
7570 	       pmap_kernel()->pm_reg_ptps[0], pmap_kernel()->pm_reg_ptps_pa[0]);
7571 
7572 	regtbl = pmap_kernel()->pm_reg_ptps[0];
7573 
7574 	printf("PROM vector is at 0x%x\n",promvec);
7575 	printf("PROM reboot routine is at 0x%x\n",promvec->pv_reboot);
7576 	printf("PROM abort routine is at 0x%x\n",promvec->pv_abort);
7577 	printf("PROM halt routine is at 0x%x\n",promvec->pv_halt);
7578 
7579 	printf("Testing region 0xfe: ");
7580 	test_region(0xfe,0,16*1024*1024);
7581 	printf("Testing region 0xff: ");
7582 	test_region(0xff,0,16*1024*1024);
7583 	printf("Testing kernel region 0x%x: ", VA_VREG(KERNBASE));
7584 	test_region(VA_VREG(KERNBASE), 4096, avail_start);
7585 	cngetc();
7586 
7587 	for (i = 0; i < SRMMU_L1SIZE; i++) {
7588 		te = regtbl[i];
7589 		if ((te & SRMMU_TETYPE) == SRMMU_TEINVALID)
7590 		    continue;
7591 		printf("Region 0x%x: PTE=0x%x <%s> L2PA=0x%x kernL2VA=0x%x\n",
7592 		       i, te, ((te & SRMMU_TETYPE) == SRMMU_TEPTE ? "pte" :
7593 			       ((te & SRMMU_TETYPE) == SRMMU_TEPTD ? "ptd" :
7594 				((te & SRMMU_TETYPE) == SRMMU_TEINVALID ?
7595 				 "invalid" : "reserved"))),
7596 		       (te & ~0x3) << SRMMU_PPNPASHIFT,
7597 		       pmap_kernel()->pm_regmap[i].rg_seg_ptps);
7598 	}
7599 	printf("Press q to halt...\n");
7600 	if (cngetc()=='q')
7601 	    callrom();
7602 }
7603 
7604 static u_int
7605 VA2PAsw(ctx, addr, pte)
7606 	int ctx;
7607 	caddr_t addr;
7608 	int *pte;
7609 {
7610 	int *curtbl;
7611 	int curpte;
7612 
7613 #ifdef EXTREME_EXTREME_DEBUG
7614 	printf("Looking up addr 0x%x in context 0x%x\n",addr,ctx);
7615 #endif
7616 	/* L0 */
7617 	*pte = curpte = cpuinfo.ctx_tbl[ctx];
7618 #ifdef EXTREME_EXTREME_DEBUG
7619 	printf("Got L0 pte 0x%x\n",pte);
7620 #endif
7621 	if ((curpte & SRMMU_TETYPE) == SRMMU_TEPTE) {
7622 		return (((curpte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) |
7623 			((u_int)addr & 0xffffffff));
7624 	}
7625 	if ((curpte & SRMMU_TETYPE) != SRMMU_TEPTD) {
7626 		printf("Bad context table entry 0x%x for context 0x%x\n",
7627 		       curpte, ctx);
7628 		return 0;
7629 	}
7630 	/* L1 */
7631 	curtbl = ((curpte & ~0x3) << 4) | KERNBASE; /* correct for krn*/
7632 	*pte = curpte = curtbl[VA_VREG(addr)];
7633 #ifdef EXTREME_EXTREME_DEBUG
7634 	printf("L1 table at 0x%x.\nGot L1 pte 0x%x\n",curtbl,curpte);
7635 #endif
7636 	if ((curpte & SRMMU_TETYPE) == SRMMU_TEPTE)
7637 	    return (((curpte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) |
7638 		    ((u_int)addr & 0xffffff));
7639 	if ((curpte & SRMMU_TETYPE) != SRMMU_TEPTD) {
7640 		printf("Bad region table entry 0x%x for region 0x%x\n",
7641 		       curpte, VA_VREG(addr));
7642 		return 0;
7643 	}
7644 	/* L2 */
7645 	curtbl = ((curpte & ~0x3) << 4) | KERNBASE; /* correct for krn*/
7646 	*pte = curpte = curtbl[VA_VSEG(addr)];
7647 #ifdef EXTREME_EXTREME_DEBUG
7648 	printf("L2 table at 0x%x.\nGot L2 pte 0x%x\n",curtbl,curpte);
7649 #endif
7650 	if ((curpte & SRMMU_TETYPE) == SRMMU_TEPTE)
7651 	    return (((curpte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) |
7652 		    ((u_int)addr & 0x3ffff));
7653 	if ((curpte & SRMMU_TETYPE) != SRMMU_TEPTD) {
7654 		printf("Bad segment table entry 0x%x for reg 0x%x, seg 0x%x\n",
7655 		       curpte, VA_VREG(addr), VA_VSEG(addr));
7656 		return 0;
7657 	}
7658 	/* L3 */
7659 	curtbl = ((curpte & ~0x3) << 4) | KERNBASE; /* correct for krn*/
7660 	*pte = curpte = curtbl[VA_VPG(addr)];
7661 #ifdef EXTREME_EXTREME_DEBUG
7662 	printf("L3 table at 0x%x.\nGot L3 pte 0x%x\n",curtbl,curpte);
7663 #endif
7664 	if ((curpte & SRMMU_TETYPE) == SRMMU_TEPTE)
7665 	    return (((curpte & SRMMU_PPNMASK) << SRMMU_PPNPASHIFT) |
7666 		    ((u_int)addr & 0xfff));
7667 	else {
7668 		printf("Bad L3 pte 0x%x for reg 0x%x, seg 0x%x, pg 0x%x\n",
7669 		       curpte, VA_VREG(addr), VA_VSEG(addr), VA_VPG(addr));
7670 		return 0;
7671 	}
7672 	printf("Bizarreness with address 0x%x!\n",addr);
7673 }
7674 
7675 void test_region(reg, start, stop)
7676 	int reg;
7677 	int start, stop;
7678 {
7679 	int i;
7680 	int addr;
7681 	int pte;
7682 	int ptesw;
7683 /*	int cnt=0;
7684 */
7685 
7686 	for (i = start; i < stop; i+= NBPG) {
7687 		addr = (reg << RGSHIFT) | i;
7688 		pte=lda(((u_int)(addr)) | ASI_SRMMUFP_LN, ASI_SRMMUFP);
7689 		if (pte) {
7690 /*			printf("Valid address 0x%x\n",addr);
7691 			if (++cnt == 20) {
7692 				cngetc();
7693 				cnt=0;
7694 			}
7695 */
7696 			if (VA2PA(addr) != VA2PAsw(0,addr,&ptesw)) {
7697 				printf("Mismatch at address 0x%x.\n",addr);
7698 				if (cngetc()=='q') break;
7699 			}
7700 			if (reg == VA_VREG(KERNBASE))
7701 				/* kernel permissions are different */
7702 				continue;
7703 			if ((pte&SRMMU_PROT_MASK)!=(ptesw&SRMMU_PROT_MASK)) {
7704 				printf("Mismatched protections at address "
7705 				       "0x%x; pte=0x%x, ptesw=0x%x\n",
7706 				       addr,pte,ptesw);
7707 				if (cngetc()=='q') break;
7708 			}
7709 		}
7710 	}
7711 	printf("done.\n");
7712 }
7713 
7714 
7715 void print_fe_map(void)
7716 {
7717 	u_int i, pte;
7718 
7719 	printf("map of region 0xfe:\n");
7720 	for (i = 0xfe000000; i < 0xff000000; i+=4096) {
7721 		if (((pte = getpte4m(i)) & SRMMU_TETYPE) != SRMMU_TEPTE)
7722 		    continue;
7723 		printf("0x%x -> 0x%x%x (pte 0x%x)\n", i, pte >> 28,
7724 		       (pte & ~0xff) << 4, pte);
7725 	}
7726 	printf("done\n");
7727 }
7728 
7729 #endif
7730