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(®ion_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(®ion_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(®ion_locked, me, me_list);
1564 } else {
1565 TAILQ_REMOVE(®ion_lru, me, me_list);
1566 }
1567
1568 /* no associated pmap; on free list */
1569 me->me_pmap = NULL;
1570 TAILQ_INSERT_TAIL(®ion_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(®ion_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(®ion_freelist);
2763 TAILQ_INIT(®ion_lru);
2764 TAILQ_INIT(®ion_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(®ion_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(®ion_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(®ion_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