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