pmap.c revision 1.37 1 /* $NetBSD: pmap.c,v 1.37 1998/06/09 20:31:28 gwr Exp $ */
2
3 /*-
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jeremy Cooper.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38
39 /*
40 * XXX These comments aren't quite accurate. Need to change.
41 * The sun3x uses the MC68851 Memory Management Unit, which is built
42 * into the CPU. The 68851 maps virtual to physical addresses using
43 * a multi-level table lookup, which is stored in the very memory that
44 * it maps. The number of levels of lookup is configurable from one
45 * to four. In this implementation, we use three, named 'A' through 'C'.
46 *
47 * The MMU translates virtual addresses into physical addresses by
48 * traversing these tables in a proccess called a 'table walk'. The most
49 * significant 7 bits of the Virtual Address ('VA') being translated are
50 * used as an index into the level A table, whose base in physical memory
51 * is stored in a special MMU register, the 'CPU Root Pointer' or CRP. The
52 * address found at that index in the A table is used as the base
53 * address for the next table, the B table. The next six bits of the VA are
54 * used as an index into the B table, which in turn gives the base address
55 * of the third and final C table.
56 *
57 * The next six bits of the VA are used as an index into the C table to
58 * locate a Page Table Entry (PTE). The PTE is a physical address in memory
59 * to which the remaining 13 bits of the VA are added, producing the
60 * mapped physical address.
61 *
62 * To map the entire memory space in this manner would require 2114296 bytes
63 * of page tables per process - quite expensive. Instead we will
64 * allocate a fixed but considerably smaller space for the page tables at
65 * the time the VM system is initialized. When the pmap code is asked by
66 * the kernel to map a VA to a PA, it allocates tables as needed from this
67 * pool. When there are no more tables in the pool, tables are stolen
68 * from the oldest mapped entries in the tree. This is only possible
69 * because all memory mappings are stored in the kernel memory map
70 * structures, independent of the pmap structures. A VA which references
71 * one of these invalidated maps will cause a page fault. The kernel
72 * will determine that the page fault was caused by a task using a valid
73 * VA, but for some reason (which does not concern it), that address was
74 * not mapped. It will ask the pmap code to re-map the entry and then
75 * it will resume executing the faulting task.
76 *
77 * In this manner the most efficient use of the page table space is
78 * achieved. Tasks which do not execute often will have their tables
79 * stolen and reused by tasks which execute more frequently. The best
80 * size for the page table pool will probably be determined by
81 * experimentation.
82 *
83 * You read all of the comments so far. Good for you.
84 * Now go play!
85 */
86
87 /*** A Note About the 68851 Address Translation Cache
88 * The MC68851 has a 64 entry cache, called the Address Translation Cache
89 * or 'ATC'. This cache stores the most recently used page descriptors
90 * accessed by the MMU when it does translations. Using a marker called a
91 * 'task alias' the MMU can store the descriptors from 8 different table
92 * spaces concurrently. The task alias is associated with the base
93 * address of the level A table of that address space. When an address
94 * space is currently active (the CRP currently points to its A table)
95 * the only cached descriptors that will be obeyed are ones which have a
96 * matching task alias of the current space associated with them.
97 *
98 * Since the cache is always consulted before any table lookups are done,
99 * it is important that it accurately reflect the state of the MMU tables.
100 * Whenever a change has been made to a table that has been loaded into
101 * the MMU, the code must be sure to flush any cached entries that are
102 * affected by the change. These instances are documented in the code at
103 * various points.
104 */
105 /*** A Note About the Note About the 68851 Address Translation Cache
106 * 4 months into this code I discovered that the sun3x does not have
107 * a MC68851 chip. Instead, it has a version of this MMU that is part of the
108 * the 68030 CPU.
109 * All though it behaves very similarly to the 68851, it only has 1 task
110 * alias and a 22 entry cache. So sadly (or happily), the first paragraph
111 * of the previous note does not apply to the sun3x pmap.
112 */
113
114 #include <sys/param.h>
115 #include <sys/systm.h>
116 #include <sys/proc.h>
117 #include <sys/malloc.h>
118 #include <sys/user.h>
119 #include <sys/queue.h>
120 #include <sys/kcore.h>
121
122 #include <vm/vm.h>
123 #include <vm/vm_kern.h>
124 #include <vm/vm_page.h>
125
126 #include <machine/cpu.h>
127 #include <machine/kcore.h>
128 #include <machine/mon.h>
129 #include <machine/pmap.h>
130 #include <machine/pte.h>
131 #include <machine/vmparam.h>
132
133 #include <sun3/sun3/cache.h>
134 #include <sun3/sun3/machdep.h>
135
136 #include "pmap_pvt.h"
137
138 /* XXX - What headers declare these? */
139 extern struct pcb *curpcb;
140 extern int physmem;
141
142 extern void copypage __P((const void*, void*));
143 extern void zeropage __P((void*));
144
145 /* Defined in locore.s */
146 extern char kernel_text[];
147
148 /* Defined by the linker */
149 extern char etext[], edata[], end[];
150 extern char *esym; /* DDB */
151
152 /*************************** DEBUGGING DEFINITIONS ***********************
153 * Macros, preprocessor defines and variables used in debugging can make *
154 * code hard to read. Anything used exclusively for debugging purposes *
155 * is defined here to avoid having such mess scattered around the file. *
156 *************************************************************************/
157 #ifdef PMAP_DEBUG
158 /*
159 * To aid the debugging process, macros should be expanded into smaller steps
160 * that accomplish the same goal, yet provide convenient places for placing
161 * breakpoints. When this code is compiled with PMAP_DEBUG mode defined, the
162 * 'INLINE' keyword is defined to an empty string. This way, any function
163 * defined to be a 'static INLINE' will become 'outlined' and compiled as
164 * a separate function, which is much easier to debug.
165 */
166 #define INLINE /* nothing */
167
168 /*
169 * It is sometimes convenient to watch the activity of a particular table
170 * in the system. The following variables are used for that purpose.
171 */
172 a_tmgr_t *pmap_watch_atbl = 0;
173 b_tmgr_t *pmap_watch_btbl = 0;
174 c_tmgr_t *pmap_watch_ctbl = 0;
175
176 int pmap_debug = 0;
177 #define DPRINT(args) if (pmap_debug) printf args
178
179 #else /********** Stuff below is defined if NOT debugging **************/
180
181 #define INLINE inline
182 #define DPRINT(args) /* nada */
183
184 #endif /* PMAP_DEBUG */
185 /*********************** END OF DEBUGGING DEFINITIONS ********************/
186
187 /*** Management Structure - Memory Layout
188 * For every MMU table in the sun3x pmap system there must be a way to
189 * manage it; we must know which process is using it, what other tables
190 * depend on it, and whether or not it contains any locked pages. This
191 * is solved by the creation of 'table management' or 'tmgr'
192 * structures. One for each MMU table in the system.
193 *
194 * MAP OF MEMORY USED BY THE PMAP SYSTEM
195 *
196 * towards lower memory
197 * kernAbase -> +-------------------------------------------------------+
198 * | Kernel MMU A level table |
199 * kernBbase -> +-------------------------------------------------------+
200 * | Kernel MMU B level tables |
201 * kernCbase -> +-------------------------------------------------------+
202 * | |
203 * | Kernel MMU C level tables |
204 * | |
205 * mmuCbase -> +-------------------------------------------------------+
206 * | User MMU C level tables |
207 * mmuAbase -> +-------------------------------------------------------+
208 * | |
209 * | User MMU A level tables |
210 * | |
211 * mmuBbase -> +-------------------------------------------------------+
212 * | User MMU B level tables |
213 * tmgrAbase -> +-------------------------------------------------------+
214 * | TMGR A level table structures |
215 * tmgrBbase -> +-------------------------------------------------------+
216 * | TMGR B level table structures |
217 * tmgrCbase -> +-------------------------------------------------------+
218 * | TMGR C level table structures |
219 * pvbase -> +-------------------------------------------------------+
220 * | Physical to Virtual mapping table (list heads) |
221 * pvebase -> +-------------------------------------------------------+
222 * | Physical to Virtual mapping table (list elements) |
223 * | |
224 * +-------------------------------------------------------+
225 * towards higher memory
226 *
227 * For every A table in the MMU A area, there will be a corresponding
228 * a_tmgr structure in the TMGR A area. The same will be true for
229 * the B and C tables. This arrangement will make it easy to find the
230 * controling tmgr structure for any table in the system by use of
231 * (relatively) simple macros.
232 */
233
234 /*
235 * Global variables for storing the base addresses for the areas
236 * labeled above.
237 */
238 static vm_offset_t kernAphys;
239 static mmu_long_dte_t *kernAbase;
240 static mmu_short_dte_t *kernBbase;
241 static mmu_short_pte_t *kernCbase;
242 static mmu_short_pte_t *mmuCbase;
243 static mmu_short_dte_t *mmuBbase;
244 static mmu_long_dte_t *mmuAbase;
245 static a_tmgr_t *Atmgrbase;
246 static b_tmgr_t *Btmgrbase;
247 static c_tmgr_t *Ctmgrbase;
248 static pv_t *pvbase;
249 static pv_elem_t *pvebase;
250 struct pmap kernel_pmap;
251
252 /*
253 * This holds the CRP currently loaded into the MMU.
254 */
255 struct mmu_rootptr kernel_crp;
256
257 /*
258 * Just all around global variables.
259 */
260 static TAILQ_HEAD(a_pool_head_struct, a_tmgr_struct) a_pool;
261 static TAILQ_HEAD(b_pool_head_struct, b_tmgr_struct) b_pool;
262 static TAILQ_HEAD(c_pool_head_struct, c_tmgr_struct) c_pool;
263
264
265 /*
266 * Flags used to mark the safety/availability of certain operations or
267 * resources.
268 */
269 static boolean_t pv_initialized = FALSE, /* PV system has been initialized. */
270 bootstrap_alloc_enabled = FALSE; /*Safe to use pmap_bootstrap_alloc().*/
271 int tmp_vpages_inuse; /* Temporary virtual pages are in use */
272
273 /*
274 * XXX: For now, retain the traditional variables that were
275 * used in the old pmap/vm interface (without NONCONTIG).
276 */
277 /* Kernel virtual address space available: */
278 vm_offset_t virtual_avail, virtual_end;
279 /* Physical address space available: */
280 vm_offset_t avail_start, avail_end;
281
282 /* This keep track of the end of the contiguously mapped range. */
283 vm_offset_t virtual_contig_end;
284
285 /* Physical address used by pmap_next_page() */
286 vm_offset_t avail_next;
287
288 /* These are used by pmap_copy_page(), etc. */
289 vm_offset_t tmp_vpages[2];
290
291 /*
292 * The 3/80 is the only member of the sun3x family that has non-contiguous
293 * physical memory. Memory is divided into 4 banks which are physically
294 * locatable on the system board. Although the size of these banks varies
295 * with the size of memory they contain, their base addresses are
296 * permenently fixed. The following structure, which describes these
297 * banks, is initialized by pmap_bootstrap() after it reads from a similar
298 * structure provided by the ROM Monitor.
299 *
300 * For the other machines in the sun3x architecture which do have contiguous
301 * RAM, this list will have only one entry, which will describe the entire
302 * range of available memory.
303 */
304 struct pmap_physmem_struct avail_mem[SUN3X_NPHYS_RAM_SEGS];
305 u_int total_phys_mem;
306
307 /*************************************************************************/
308
309 /*
310 * XXX - Should "tune" these based on statistics.
311 *
312 * My first guess about the relative numbers of these needed is
313 * based on the fact that a "typical" process will have several
314 * pages mapped at low virtual addresses (text, data, bss), then
315 * some mapped shared libraries, and then some stack pages mapped
316 * near the high end of the VA space. Each process can use only
317 * one A table, and most will use only two B tables (maybe three)
318 * and probably about four C tables. Therefore, the first guess
319 * at the relative numbers of these needed is 1:2:4 -gwr
320 *
321 * The number of C tables needed is closely related to the amount
322 * of physical memory available plus a certain amount attributable
323 * to the use of double mappings. With a few simulation statistics
324 * we can find a reasonably good estimation of this unknown value.
325 * Armed with that and the above ratios, we have a good idea of what
326 * is needed at each level. -j
327 *
328 * Note: It is not physical memory memory size, but the total mapped
329 * virtual space required by the combined working sets of all the
330 * currently _runnable_ processes. (Sleeping ones don't count.)
331 * The amount of physical memory should be irrelevant. -gwr
332 */
333 #ifdef FIXED_NTABLES
334 #define NUM_A_TABLES 16
335 #define NUM_B_TABLES 32
336 #define NUM_C_TABLES 64
337 #else
338 unsigned int NUM_A_TABLES, NUM_B_TABLES, NUM_C_TABLES;
339 #endif /* FIXED_NTABLES */
340
341 /*
342 * This determines our total virtual mapping capacity.
343 * Yes, it is a FIXED value so we can pre-allocate.
344 */
345 #define NUM_USER_PTES (NUM_C_TABLES * MMU_C_TBL_SIZE)
346
347 /*
348 * The size of the Kernel Virtual Address Space (KVAS)
349 * for purposes of MMU table allocation is -KERNBASE
350 * (length from KERNBASE to 0xFFFFffff)
351 */
352 #define KVAS_SIZE (-KERNBASE)
353
354 /* Numbers of kernel MMU tables to support KVAS_SIZE. */
355 #define KERN_B_TABLES (KVAS_SIZE >> MMU_TIA_SHIFT)
356 #define KERN_C_TABLES (KVAS_SIZE >> MMU_TIB_SHIFT)
357 #define NUM_KERN_PTES (KVAS_SIZE >> MMU_TIC_SHIFT)
358
359 /*************************** MISCELANEOUS MACROS *************************/
360 #define PMAP_LOCK() ; /* Nothing, for now */
361 #define PMAP_UNLOCK() ; /* same. */
362 #define NULL 0
363
364 static INLINE void * mmu_ptov __P((vm_offset_t pa));
365 static INLINE vm_offset_t mmu_vtop __P((void * va));
366
367 #if 0
368 static INLINE a_tmgr_t * mmuA2tmgr __P((mmu_long_dte_t *));
369 #endif /* 0 */
370 static INLINE b_tmgr_t * mmuB2tmgr __P((mmu_short_dte_t *));
371 static INLINE c_tmgr_t * mmuC2tmgr __P((mmu_short_pte_t *));
372
373 static INLINE pv_t *pa2pv __P((vm_offset_t pa));
374 static INLINE int pteidx __P((mmu_short_pte_t *));
375 static INLINE pmap_t current_pmap __P((void));
376
377 /*
378 * We can always convert between virtual and physical addresses
379 * for anything in the range [KERNBASE ... avail_start] because
380 * that range is GUARANTEED to be mapped linearly.
381 * We rely heavily upon this feature!
382 */
383 static INLINE void *
384 mmu_ptov(pa)
385 vm_offset_t pa;
386 {
387 register vm_offset_t va;
388
389 va = (pa + KERNBASE);
390 #ifdef PMAP_DEBUG
391 if ((va < KERNBASE) || (va >= virtual_contig_end))
392 panic("mmu_ptov");
393 #endif
394 return ((void*)va);
395 }
396 static INLINE vm_offset_t
397 mmu_vtop(vva)
398 void *vva;
399 {
400 register vm_offset_t va;
401
402 va = (vm_offset_t)vva;
403 #ifdef PMAP_DEBUG
404 if ((va < KERNBASE) || (va >= virtual_contig_end))
405 panic("mmu_ptov");
406 #endif
407 return (va - KERNBASE);
408 }
409
410 /*
411 * These macros map MMU tables to their corresponding manager structures.
412 * They are needed quite often because many of the pointers in the pmap
413 * system reference MMU tables and not the structures that control them.
414 * There needs to be a way to find one when given the other and these
415 * macros do so by taking advantage of the memory layout described above.
416 * Here's a quick step through the first macro, mmuA2tmgr():
417 *
418 * 1) find the offset of the given MMU A table from the base of its table
419 * pool (table - mmuAbase).
420 * 2) convert this offset into a table index by dividing it by the
421 * size of one MMU 'A' table. (sizeof(mmu_long_dte_t) * MMU_A_TBL_SIZE)
422 * 3) use this index to select the corresponding 'A' table manager
423 * structure from the 'A' table manager pool (Atmgrbase[index]).
424 */
425 /* This function is not currently used. */
426 #if 0
427 static INLINE a_tmgr_t *
428 mmuA2tmgr(mmuAtbl)
429 mmu_long_dte_t *mmuAtbl;
430 {
431 register int idx;
432
433 /* Which table is this in? */
434 idx = (mmuAtbl - mmuAbase) / MMU_A_TBL_SIZE;
435 #ifdef PMAP_DEBUG
436 if ((idx < 0) || (idx >= NUM_A_TABLES))
437 panic("mmuA2tmgr");
438 #endif
439 return (&Atmgrbase[idx]);
440 }
441 #endif /* 0 */
442
443 static INLINE b_tmgr_t *
444 mmuB2tmgr(mmuBtbl)
445 mmu_short_dte_t *mmuBtbl;
446 {
447 register int idx;
448
449 /* Which table is this in? */
450 idx = (mmuBtbl - mmuBbase) / MMU_B_TBL_SIZE;
451 #ifdef PMAP_DEBUG
452 if ((idx < 0) || (idx >= NUM_B_TABLES))
453 panic("mmuB2tmgr");
454 #endif
455 return (&Btmgrbase[idx]);
456 }
457
458 /* mmuC2tmgr INTERNAL
459 **
460 * Given a pte known to belong to a C table, return the address of
461 * that table's management structure.
462 */
463 static INLINE c_tmgr_t *
464 mmuC2tmgr(mmuCtbl)
465 mmu_short_pte_t *mmuCtbl;
466 {
467 register int idx;
468
469 /* Which table is this in? */
470 idx = (mmuCtbl - mmuCbase) / MMU_C_TBL_SIZE;
471 #ifdef PMAP_DEBUG
472 if ((idx < 0) || (idx >= NUM_C_TABLES))
473 panic("mmuC2tmgr");
474 #endif
475 return (&Ctmgrbase[idx]);
476 }
477
478 /* This is now a function call below.
479 * #define pa2pv(pa) \
480 * (&pvbase[(unsigned long)\
481 * m68k_btop(pa)\
482 * ])
483 */
484
485 /* pa2pv INTERNAL
486 **
487 * Return the pv_list_head element which manages the given physical
488 * address.
489 */
490 static INLINE pv_t *
491 pa2pv(pa)
492 vm_offset_t pa;
493 {
494 register struct pmap_physmem_struct *bank;
495 register int idx;
496
497 bank = &avail_mem[0];
498 while (pa >= bank->pmem_end)
499 bank = bank->pmem_next;
500
501 pa -= bank->pmem_start;
502 idx = bank->pmem_pvbase + m68k_btop(pa);
503 #ifdef PMAP_DEBUG
504 if ((idx < 0) || (idx >= physmem))
505 panic("pa2pv");
506 #endif
507 return &pvbase[idx];
508 }
509
510 /* pteidx INTERNAL
511 **
512 * Return the index of the given PTE within the entire fixed table of
513 * PTEs.
514 */
515 static INLINE int
516 pteidx(pte)
517 mmu_short_pte_t *pte;
518 {
519 return (pte - kernCbase);
520 }
521
522 /*
523 * This just offers a place to put some debugging checks,
524 * and reduces the number of places "curproc" appears...
525 */
526 static INLINE pmap_t
527 current_pmap()
528 {
529 struct proc *p;
530 struct vmspace *vm;
531 vm_map_t map;
532 pmap_t pmap;
533
534 p = curproc; /* XXX */
535 if (p == NULL)
536 pmap = &kernel_pmap;
537 else {
538 vm = p->p_vmspace;
539 map = &vm->vm_map;
540 pmap = vm_map_pmap(map);
541 }
542
543 return (pmap);
544 }
545
546
547 /*************************** FUNCTION DEFINITIONS ************************
548 * These appear here merely for the compiler to enforce type checking on *
549 * all function calls. *
550 *************************************************************************/
551
552 /** External functions
553 ** - functions used within this module but written elsewhere.
554 ** both of these functions are in locore.s
555 ** XXX - These functions were later replaced with their more cryptic
556 ** hp300 counterparts. They may be removed now.
557 **/
558 #if 0 /* deprecated mmu */
559 void mmu_seturp __P((vm_offset_t));
560 void mmu_flush __P((int, vm_offset_t));
561 void mmu_flusha __P((void));
562 #endif /* 0 */
563
564 /** Internal functions
565 ** Most functions used only within this module are defined in
566 ** pmap_pvt.h (why not here if used only here?)
567 **/
568 #ifdef MACHINE_NEW_NONCONTIG
569 static void pmap_page_upload __P((void));
570 #endif
571
572 /** Interface functions
573 ** - functions required by the Mach VM Pmap interface, with MACHINE_CONTIG
574 ** defined.
575 **/
576 #ifdef INCLUDED_IN_PMAP_H
577 void pmap_bootstrap __P((void));
578 void *pmap_bootstrap_alloc __P((int));
579 void pmap_enter __P((pmap_t, vm_offset_t, vm_offset_t, vm_prot_t, boolean_t));
580 pmap_t pmap_create __P((vm_size_t));
581 void pmap_destroy __P((pmap_t));
582 void pmap_reference __P((pmap_t));
583 boolean_t pmap_is_referenced __P((vm_offset_t));
584 boolean_t pmap_is_modified __P((vm_offset_t));
585 void pmap_clear_modify __P((vm_offset_t));
586 vm_offset_t pmap_extract __P((pmap_t, vm_offset_t));
587 int pmap_page_index __P((vm_offset_t));
588 u_int pmap_free_pages __P((void));
589 #endif /* INCLUDED_IN_PMAP_H */
590 void pmap_pinit __P((pmap_t));
591 void pmap_release __P((pmap_t));
592
593 /********************************** CODE ********************************
594 * Functions that are called from other parts of the kernel are labeled *
595 * as 'INTERFACE' functions. Functions that are only called from *
596 * within the pmap module are labeled as 'INTERNAL' functions. *
597 * Functions that are internal, but are not (currently) used at all are *
598 * labeled 'INTERNAL_X'. *
599 ************************************************************************/
600
601 /* pmap_bootstrap INTERNAL
602 **
603 * Initializes the pmap system. Called at boot time from
604 * locore2.c:_vm_init()
605 *
606 * Reminder: having a pmap_bootstrap_alloc() and also having the VM
607 * system implement pmap_steal_memory() is redundant.
608 * Don't release this code without removing one or the other!
609 */
610 void
611 pmap_bootstrap(nextva)
612 vm_offset_t nextva;
613 {
614 struct physmemory *membank;
615 struct pmap_physmem_struct *pmap_membank;
616 vm_offset_t va, pa, eva;
617 int b, c, i, j; /* running table counts */
618 int size;
619
620 /*
621 * This function is called by __bootstrap after it has
622 * determined the type of machine and made the appropriate
623 * patches to the ROM vectors (XXX- I don't quite know what I meant
624 * by that.) It allocates and sets up enough of the pmap system
625 * to manage the kernel's address space.
626 */
627
628 /*
629 * Determine the range of kernel virtual and physical
630 * space available. Note that we ABSOLUTELY DEPEND on
631 * the fact that the first bank of memory (4MB) is
632 * mapped linearly to KERNBASE (which we guaranteed in
633 * the first instructions of locore.s).
634 * That is plenty for our bootstrap work.
635 */
636 virtual_avail = m68k_round_page(nextva);
637 virtual_contig_end = KERNBASE + 0x400000; /* +4MB */
638 virtual_end = VM_MAX_KERNEL_ADDRESS;
639 /* Don't need avail_start til later. */
640
641 /* We may now call pmap_bootstrap_alloc(). */
642 bootstrap_alloc_enabled = TRUE;
643
644 /*
645 * This is a somewhat unwrapped loop to deal with
646 * copying the PROM's 'phsymem' banks into the pmap's
647 * banks. The following is always assumed:
648 * 1. There is always at least one bank of memory.
649 * 2. There is always a last bank of memory, and its
650 * pmem_next member must be set to NULL.
651 * XXX - Use: do { ... } while (membank->next) instead?
652 * XXX - Why copy this stuff at all? -gwr
653 * - It is needed in pa2pv().
654 */
655 membank = romVectorPtr->v_physmemory;
656 pmap_membank = avail_mem;
657 total_phys_mem = 0;
658
659 while (membank->next) {
660 pmap_membank->pmem_start = membank->address;
661 pmap_membank->pmem_end = membank->address + membank->size;
662 total_phys_mem += membank->size;
663 /* This silly syntax arises because pmap_membank
664 * is really a pre-allocated array, but it is put into
665 * use as a linked list.
666 */
667 pmap_membank->pmem_next = pmap_membank + 1;
668 pmap_membank = pmap_membank->pmem_next;
669 membank = membank->next;
670 }
671
672 /*
673 * XXX The last bank of memory should be reduced to exclude the
674 * physical pages needed by the PROM monitor from being used
675 * in the VM system. XXX - See below - Fix!
676 */
677 pmap_membank->pmem_start = membank->address;
678 pmap_membank->pmem_end = membank->address + membank->size;
679 pmap_membank->pmem_next = NULL;
680
681 #if 0 /* XXX - Need to integrate this! */
682 /*
683 * The last few pages of physical memory are "owned" by
684 * the PROM. The total amount of memory we are allowed
685 * to use is given by the romvec pointer. -gwr
686 *
687 * We should dedicate different variables for 'useable'
688 * and 'physically available'. Most users are used to the
689 * kernel reporting the amount of memory 'physically available'
690 * as opposed to 'useable by the kernel' at boot time. -j
691 */
692 total_phys_mem = *romVectorPtr->memoryAvail;
693 #endif /* XXX */
694
695 total_phys_mem += membank->size; /* XXX see above */
696 physmem = btoc(total_phys_mem);
697
698 /*
699 * Avail_end is set to the first byte of physical memory
700 * after the end of the last bank. We use this only to
701 * determine if a physical address is "managed" memory.
702 *
703 * XXX - The setting of avail_end is a temporary ROM saving hack.
704 */
705 avail_end = pmap_membank->pmem_end -
706 (total_phys_mem - *romVectorPtr->memoryAvail);
707 avail_end = m68k_trunc_page(avail_end);
708
709 /*
710 * First allocate enough kernel MMU tables to map all
711 * of kernel virtual space from KERNBASE to 0xFFFFFFFF.
712 * Note: All must be aligned on 256 byte boundaries.
713 * Start with the level-A table (one of those).
714 */
715 size = sizeof(mmu_long_dte_t) * MMU_A_TBL_SIZE;
716 kernAbase = pmap_bootstrap_alloc(size);
717 bzero(kernAbase, size);
718
719 /* Now the level-B kernel tables... */
720 size = sizeof(mmu_short_dte_t) * MMU_B_TBL_SIZE * KERN_B_TABLES;
721 kernBbase = pmap_bootstrap_alloc(size);
722 bzero(kernBbase, size);
723
724 /* Now the level-C kernel tables... */
725 size = sizeof(mmu_short_pte_t) * MMU_C_TBL_SIZE * KERN_C_TABLES;
726 kernCbase = pmap_bootstrap_alloc(size);
727 bzero(kernCbase, size);
728 /*
729 * Note: In order for the PV system to work correctly, the kernel
730 * and user-level C tables must be allocated contiguously.
731 * Nothing should be allocated between here and the allocation of
732 * mmuCbase below. XXX: Should do this as one allocation, and
733 * then compute a pointer for mmuCbase instead of this...
734 *
735 * Allocate user MMU tables.
736 * These must be contiguous with the preceeding.
737 */
738
739 #ifndef FIXED_NTABLES
740 /*
741 * The number of user-level C tables that should be allocated is
742 * related to the size of physical memory. In general, there should
743 * be enough tables to map four times the amount of available RAM.
744 * The extra amount is needed because some table space is wasted by
745 * fragmentation.
746 */
747 NUM_C_TABLES = (total_phys_mem * 4) / (MMU_C_TBL_SIZE * MMU_PAGE_SIZE);
748 NUM_B_TABLES = NUM_C_TABLES / 2;
749 NUM_A_TABLES = NUM_B_TABLES / 2;
750 #endif /* !FIXED_NTABLES */
751
752 size = sizeof(mmu_short_pte_t) * MMU_C_TBL_SIZE * NUM_C_TABLES;
753 mmuCbase = pmap_bootstrap_alloc(size);
754
755 size = sizeof(mmu_short_dte_t) * MMU_B_TBL_SIZE * NUM_B_TABLES;
756 mmuBbase = pmap_bootstrap_alloc(size);
757
758 size = sizeof(mmu_long_dte_t) * MMU_A_TBL_SIZE * NUM_A_TABLES;
759 mmuAbase = pmap_bootstrap_alloc(size);
760
761 /*
762 * Fill in the never-changing part of the kernel tables.
763 * For simplicity, the kernel's mappings will be editable as a
764 * flat array of page table entries at kernCbase. The
765 * higher level 'A' and 'B' tables must be initialized to point
766 * to this lower one.
767 */
768 b = c = 0;
769
770 /*
771 * Invalidate all mappings below KERNBASE in the A table.
772 * This area has already been zeroed out, but it is good
773 * practice to explicitly show that we are interpreting
774 * it as a list of A table descriptors.
775 */
776 for (i = 0; i < MMU_TIA(KERNBASE); i++) {
777 kernAbase[i].addr.raw = 0;
778 }
779
780 /*
781 * Set up the kernel A and B tables so that they will reference the
782 * correct spots in the contiguous table of PTEs allocated for the
783 * kernel's virtual memory space.
784 */
785 for (i = MMU_TIA(KERNBASE); i < MMU_A_TBL_SIZE; i++) {
786 kernAbase[i].attr.raw =
787 MMU_LONG_DTE_LU | MMU_LONG_DTE_SUPV | MMU_DT_SHORT;
788 kernAbase[i].addr.raw = mmu_vtop(&kernBbase[b]);
789
790 for (j=0; j < MMU_B_TBL_SIZE; j++) {
791 kernBbase[b + j].attr.raw = mmu_vtop(&kernCbase[c])
792 | MMU_DT_SHORT;
793 c += MMU_C_TBL_SIZE;
794 }
795 b += MMU_B_TBL_SIZE;
796 }
797
798 /* XXX - Doing kernel_pmap a little further down. */
799
800 pmap_alloc_usermmu(); /* Allocate user MMU tables. */
801 pmap_alloc_usertmgr(); /* Allocate user MMU table managers.*/
802 pmap_alloc_pv(); /* Allocate physical->virtual map. */
803
804 /*
805 * We are now done with pmap_bootstrap_alloc(). Round up
806 * `virtual_avail' to the nearest page, and set the flag
807 * to prevent use of pmap_bootstrap_alloc() hereafter.
808 */
809 pmap_bootstrap_aalign(NBPG);
810 bootstrap_alloc_enabled = FALSE;
811
812 /*
813 * Now that we are done with pmap_bootstrap_alloc(), we
814 * must save the virtual and physical addresses of the
815 * end of the linearly mapped range, which are stored in
816 * virtual_contig_end and avail_start, respectively.
817 * These variables will never change after this point.
818 */
819 virtual_contig_end = virtual_avail;
820 avail_start = virtual_avail - KERNBASE;
821
822 /*
823 * `avail_next' is a running pointer used by pmap_next_page() to
824 * keep track of the next available physical page to be handed
825 * to the VM system during its initialization, in which it
826 * asks for physical pages, one at a time.
827 */
828 avail_next = avail_start;
829
830 /*
831 * Now allocate some virtual addresses, but not the physical pages
832 * behind them. Note that virtual_avail is already page-aligned.
833 *
834 * tmp_vpages[] is an array of two virtual pages used for temporary
835 * kernel mappings in the pmap module to facilitate various physical
836 * address-oritented operations.
837 */
838 tmp_vpages[0] = virtual_avail;
839 virtual_avail += NBPG;
840 tmp_vpages[1] = virtual_avail;
841 virtual_avail += NBPG;
842
843 /** Initialize the PV system **/
844 pmap_init_pv();
845
846 /*
847 * Fill in the kernel_pmap structure and kernel_crp.
848 */
849 kernAphys = mmu_vtop(kernAbase);
850 kernel_pmap.pm_a_tmgr = NULL;
851 kernel_pmap.pm_a_phys = kernAphys;
852 kernel_pmap.pm_refcount = 1; /* always in use */
853
854 kernel_crp.rp_attr = MMU_LONG_DTE_LU | MMU_DT_LONG;
855 kernel_crp.rp_addr = kernAphys;
856
857 /*
858 * Now pmap_enter_kernel() may be used safely and will be
859 * the main interface used hereafter to modify the kernel's
860 * virtual address space. Note that since we are still running
861 * under the PROM's address table, none of these table modifications
862 * actually take effect until pmap_takeover_mmu() is called.
863 *
864 * Note: Our tables do NOT have the PROM linear mappings!
865 * Only the mappings created here exist in our tables, so
866 * remember to map anything we expect to use.
867 */
868 va = (vm_offset_t) KERNBASE;
869 pa = 0;
870
871 /*
872 * The first page of the kernel virtual address space is the msgbuf
873 * page. The page attributes (data, non-cached) are set here, while
874 * the address is assigned to this global pointer in cpu_startup().
875 * It is non-cached, mostly due to paranoia.
876 */
877 pmap_enter_kernel(va, pa|PMAP_NC, VM_PROT_ALL);
878 va += NBPG; pa += NBPG;
879
880 /* Next page is used as the temporary stack. */
881 pmap_enter_kernel(va, pa, VM_PROT_ALL);
882 va += NBPG; pa += NBPG;
883
884 /*
885 * Map all of the kernel's text segment as read-only and cacheable.
886 * (Cacheable is implied by default). Unfortunately, the last bytes
887 * of kernel text and the first bytes of kernel data will often be
888 * sharing the same page. Therefore, the last page of kernel text
889 * has to be mapped as read/write, to accomodate the data.
890 */
891 eva = m68k_trunc_page((vm_offset_t)etext);
892 for (; va < eva; va += NBPG, pa += NBPG)
893 pmap_enter_kernel(va, pa, VM_PROT_READ|VM_PROT_EXECUTE);
894
895 /*
896 * Map all of the kernel's data as read/write and cacheable.
897 * This includes: data, BSS, symbols, and everything in the
898 * contiguous memory used by pmap_bootstrap_alloc()
899 */
900 for (; pa < avail_start; va += NBPG, pa += NBPG)
901 pmap_enter_kernel(va, pa, VM_PROT_READ|VM_PROT_WRITE);
902
903 /*
904 * At this point we are almost ready to take over the MMU. But first
905 * we must save the PROM's address space in our map, as we call its
906 * routines and make references to its data later in the kernel.
907 */
908 pmap_bootstrap_copyprom();
909 pmap_takeover_mmu();
910 pmap_bootstrap_setprom();
911
912 /* Notify the VM system of our page size. */
913 PAGE_SIZE = NBPG;
914 vm_set_page_size();
915
916 #if defined(MACHINE_NEW_NONCONTIG)
917 pmap_page_upload();
918 #endif
919 }
920
921
922 /* pmap_alloc_usermmu INTERNAL
923 **
924 * Called from pmap_bootstrap() to allocate MMU tables that will
925 * eventually be used for user mappings.
926 */
927 void
928 pmap_alloc_usermmu()
929 {
930 /* XXX: Moved into caller. */
931 }
932
933 /* pmap_alloc_pv INTERNAL
934 **
935 * Called from pmap_bootstrap() to allocate the physical
936 * to virtual mapping list. Each physical page of memory
937 * in the system has a corresponding element in this list.
938 */
939 void
940 pmap_alloc_pv()
941 {
942 int i;
943 unsigned int total_mem;
944
945 /*
946 * Allocate a pv_head structure for every page of physical
947 * memory that will be managed by the system. Since memory on
948 * the 3/80 is non-contiguous, we cannot arrive at a total page
949 * count by subtraction of the lowest available address from the
950 * highest, but rather we have to step through each memory
951 * bank and add the number of pages in each to the total.
952 *
953 * At this time we also initialize the offset of each bank's
954 * starting pv_head within the pv_head list so that the physical
955 * memory state routines (pmap_is_referenced(),
956 * pmap_is_modified(), et al.) can quickly find coresponding
957 * pv_heads in spite of the non-contiguity.
958 */
959 total_mem = 0;
960 for (i = 0; i < SUN3X_NPHYS_RAM_SEGS; i++) {
961 avail_mem[i].pmem_pvbase = m68k_btop(total_mem);
962 total_mem += avail_mem[i].pmem_end -
963 avail_mem[i].pmem_start;
964 if (avail_mem[i].pmem_next == NULL)
965 break;
966 }
967 #ifdef PMAP_DEBUG
968 if (total_mem != total_phys_mem)
969 panic("pmap_alloc_pv did not arrive at correct page count");
970 #endif
971
972 pvbase = (pv_t *) pmap_bootstrap_alloc(sizeof(pv_t) *
973 m68k_btop(total_phys_mem));
974 }
975
976 /* pmap_alloc_usertmgr INTERNAL
977 **
978 * Called from pmap_bootstrap() to allocate the structures which
979 * facilitate management of user MMU tables. Each user MMU table
980 * in the system has one such structure associated with it.
981 */
982 void
983 pmap_alloc_usertmgr()
984 {
985 /* Allocate user MMU table managers */
986 /* It would be a lot simpler to just make these BSS, but */
987 /* we may want to change their size at boot time... -j */
988 Atmgrbase = (a_tmgr_t *) pmap_bootstrap_alloc(sizeof(a_tmgr_t)
989 * NUM_A_TABLES);
990 Btmgrbase = (b_tmgr_t *) pmap_bootstrap_alloc(sizeof(b_tmgr_t)
991 * NUM_B_TABLES);
992 Ctmgrbase = (c_tmgr_t *) pmap_bootstrap_alloc(sizeof(c_tmgr_t)
993 * NUM_C_TABLES);
994
995 /*
996 * Allocate PV list elements for the physical to virtual
997 * mapping system.
998 */
999 pvebase = (pv_elem_t *) pmap_bootstrap_alloc(
1000 sizeof(pv_elem_t) * (NUM_USER_PTES + NUM_KERN_PTES));
1001 }
1002
1003 /* pmap_bootstrap_copyprom() INTERNAL
1004 **
1005 * Copy the PROM mappings into our own tables. Note, we
1006 * can use physical addresses until __bootstrap returns.
1007 */
1008 void
1009 pmap_bootstrap_copyprom()
1010 {
1011 struct sunromvec *romp;
1012 int *mon_ctbl;
1013 mmu_short_pte_t *kpte;
1014 int i, len;
1015
1016 romp = romVectorPtr;
1017
1018 /*
1019 * Copy the mappings in SUN3X_MON_KDB_BASE...SUN3X_MONEND
1020 * Note: mon_ctbl[0] maps SUN3X_MON_KDB_BASE
1021 */
1022 mon_ctbl = *romp->monptaddr;
1023 i = m68k_btop(SUN3X_MON_KDB_BASE - KERNBASE);
1024 kpte = &kernCbase[i];
1025 len = m68k_btop(SUN3X_MONEND - SUN3X_MON_KDB_BASE);
1026
1027 for (i = 0; i < len; i++) {
1028 kpte[i].attr.raw = mon_ctbl[i];
1029 }
1030
1031 /*
1032 * Copy the mappings at MON_DVMA_BASE (to the end).
1033 * Note, in here, mon_ctbl[0] maps MON_DVMA_BASE.
1034 * Actually, we only want the last page, which the
1035 * PROM has set up for use by the "ie" driver.
1036 * (The i82686 needs its SCP there.)
1037 * If we copy all the mappings, pmap_enter_kernel
1038 * may complain about finding valid PTEs that are
1039 * not recorded in our PV lists...
1040 */
1041 mon_ctbl = *romp->shadowpteaddr;
1042 i = m68k_btop(SUN3X_MON_DVMA_BASE - KERNBASE);
1043 kpte = &kernCbase[i];
1044 len = m68k_btop(SUN3X_MON_DVMA_SIZE);
1045 for (i = (len-1); i < len; i++) {
1046 kpte[i].attr.raw = mon_ctbl[i];
1047 }
1048 }
1049
1050 /* pmap_takeover_mmu INTERNAL
1051 **
1052 * Called from pmap_bootstrap() after it has copied enough of the
1053 * PROM mappings into the kernel map so that we can use our own
1054 * MMU table.
1055 */
1056 void
1057 pmap_takeover_mmu()
1058 {
1059
1060 loadcrp(&kernel_crp);
1061 }
1062
1063 /* pmap_bootstrap_setprom() INTERNAL
1064 **
1065 * Set the PROM mappings so it can see kernel space.
1066 * Note that physical addresses are used here, which
1067 * we can get away with because this runs with the
1068 * low 1GB set for transparent translation.
1069 */
1070 void
1071 pmap_bootstrap_setprom()
1072 {
1073 mmu_long_dte_t *mon_dte;
1074 extern struct mmu_rootptr mon_crp;
1075 int i;
1076
1077 mon_dte = (mmu_long_dte_t *) mon_crp.rp_addr;
1078 for (i = MMU_TIA(KERNBASE); i < MMU_TIA(KERN_END); i++) {
1079 mon_dte[i].attr.raw = kernAbase[i].attr.raw;
1080 mon_dte[i].addr.raw = kernAbase[i].addr.raw;
1081 }
1082 }
1083
1084
1085 /* pmap_init INTERFACE
1086 **
1087 * Called at the end of vm_init() to set up the pmap system to go
1088 * into full time operation. All initialization of kernel_pmap
1089 * should be already done by now, so this should just do things
1090 * needed for user-level pmaps to work.
1091 */
1092 void
1093 pmap_init()
1094 {
1095 /** Initialize the manager pools **/
1096 TAILQ_INIT(&a_pool);
1097 TAILQ_INIT(&b_pool);
1098 TAILQ_INIT(&c_pool);
1099
1100 /**************************************************************
1101 * Initialize all tmgr structures and MMU tables they manage. *
1102 **************************************************************/
1103 /** Initialize A tables **/
1104 pmap_init_a_tables();
1105 /** Initialize B tables **/
1106 pmap_init_b_tables();
1107 /** Initialize C tables **/
1108 pmap_init_c_tables();
1109 }
1110
1111 /* pmap_init_a_tables() INTERNAL
1112 **
1113 * Initializes all A managers, their MMU A tables, and inserts
1114 * them into the A manager pool for use by the system.
1115 */
1116 void
1117 pmap_init_a_tables()
1118 {
1119 int i;
1120 a_tmgr_t *a_tbl;
1121
1122 for (i=0; i < NUM_A_TABLES; i++) {
1123 /* Select the next available A manager from the pool */
1124 a_tbl = &Atmgrbase[i];
1125
1126 /*
1127 * Clear its parent entry. Set its wired and valid
1128 * entry count to zero.
1129 */
1130 a_tbl->at_parent = NULL;
1131 a_tbl->at_wcnt = a_tbl->at_ecnt = 0;
1132
1133 /* Assign it the next available MMU A table from the pool */
1134 a_tbl->at_dtbl = &mmuAbase[i * MMU_A_TBL_SIZE];
1135
1136 /*
1137 * Initialize the MMU A table with the table in the `proc0',
1138 * or kernel, mapping. This ensures that every process has
1139 * the kernel mapped in the top part of its address space.
1140 */
1141 bcopy(kernAbase, a_tbl->at_dtbl, MMU_A_TBL_SIZE *
1142 sizeof(mmu_long_dte_t));
1143
1144 /*
1145 * Finally, insert the manager into the A pool,
1146 * making it ready to be used by the system.
1147 */
1148 TAILQ_INSERT_TAIL(&a_pool, a_tbl, at_link);
1149 }
1150 }
1151
1152 /* pmap_init_b_tables() INTERNAL
1153 **
1154 * Initializes all B table managers, their MMU B tables, and
1155 * inserts them into the B manager pool for use by the system.
1156 */
1157 void
1158 pmap_init_b_tables()
1159 {
1160 int i,j;
1161 b_tmgr_t *b_tbl;
1162
1163 for (i=0; i < NUM_B_TABLES; i++) {
1164 /* Select the next available B manager from the pool */
1165 b_tbl = &Btmgrbase[i];
1166
1167 b_tbl->bt_parent = NULL; /* clear its parent, */
1168 b_tbl->bt_pidx = 0; /* parent index, */
1169 b_tbl->bt_wcnt = 0; /* wired entry count, */
1170 b_tbl->bt_ecnt = 0; /* valid entry count. */
1171
1172 /* Assign it the next available MMU B table from the pool */
1173 b_tbl->bt_dtbl = &mmuBbase[i * MMU_B_TBL_SIZE];
1174
1175 /* Invalidate every descriptor in the table */
1176 for (j=0; j < MMU_B_TBL_SIZE; j++)
1177 b_tbl->bt_dtbl[j].attr.raw = MMU_DT_INVALID;
1178
1179 /* Insert the manager into the B pool */
1180 TAILQ_INSERT_TAIL(&b_pool, b_tbl, bt_link);
1181 }
1182 }
1183
1184 /* pmap_init_c_tables() INTERNAL
1185 **
1186 * Initializes all C table managers, their MMU C tables, and
1187 * inserts them into the C manager pool for use by the system.
1188 */
1189 void
1190 pmap_init_c_tables()
1191 {
1192 int i,j;
1193 c_tmgr_t *c_tbl;
1194
1195 for (i=0; i < NUM_C_TABLES; i++) {
1196 /* Select the next available C manager from the pool */
1197 c_tbl = &Ctmgrbase[i];
1198
1199 c_tbl->ct_parent = NULL; /* clear its parent, */
1200 c_tbl->ct_pidx = 0; /* parent index, */
1201 c_tbl->ct_wcnt = 0; /* wired entry count, */
1202 c_tbl->ct_ecnt = 0; /* valid entry count, */
1203 c_tbl->ct_pmap = NULL; /* parent pmap, */
1204 c_tbl->ct_va = 0; /* base of managed range */
1205
1206 /* Assign it the next available MMU C table from the pool */
1207 c_tbl->ct_dtbl = &mmuCbase[i * MMU_C_TBL_SIZE];
1208
1209 for (j=0; j < MMU_C_TBL_SIZE; j++)
1210 c_tbl->ct_dtbl[j].attr.raw = MMU_DT_INVALID;
1211
1212 TAILQ_INSERT_TAIL(&c_pool, c_tbl, ct_link);
1213 }
1214 }
1215
1216 /* pmap_init_pv() INTERNAL
1217 **
1218 * Initializes the Physical to Virtual mapping system.
1219 */
1220 void
1221 pmap_init_pv()
1222 {
1223 int i;
1224
1225 /* Initialize every PV head. */
1226 for (i = 0; i < m68k_btop(total_phys_mem); i++) {
1227 pvbase[i].pv_idx = PVE_EOL; /* Indicate no mappings */
1228 pvbase[i].pv_flags = 0; /* Zero out page flags */
1229 }
1230
1231 pv_initialized = TRUE;
1232 }
1233
1234 /* get_a_table INTERNAL
1235 **
1236 * Retrieve and return a level A table for use in a user map.
1237 */
1238 a_tmgr_t *
1239 get_a_table()
1240 {
1241 a_tmgr_t *tbl;
1242 pmap_t pmap;
1243
1244 /* Get the top A table in the pool */
1245 tbl = a_pool.tqh_first;
1246 if (tbl == NULL) {
1247 /*
1248 * XXX - Instead of panicing here and in other get_x_table
1249 * functions, we do have the option of sleeping on the head of
1250 * the table pool. Any function which updates the table pool
1251 * would then issue a wakeup() on the head, thus waking up any
1252 * processes waiting for a table.
1253 *
1254 * Actually, the place to sleep would be when some process
1255 * asks for a "wired" mapping that would run us short of
1256 * mapping resources. This design DEPENDS on always having
1257 * some mapping resources in the pool for stealing, so we
1258 * must make sure we NEVER let the pool become empty. -gwr
1259 */
1260 panic("get_a_table: out of A tables.");
1261 }
1262
1263 TAILQ_REMOVE(&a_pool, tbl, at_link);
1264 /*
1265 * If the table has a non-null parent pointer then it is in use.
1266 * Forcibly abduct it from its parent and clear its entries.
1267 * No re-entrancy worries here. This table would not be in the
1268 * table pool unless it was available for use.
1269 *
1270 * Note that the second argument to free_a_table() is FALSE. This
1271 * indicates that the table should not be relinked into the A table
1272 * pool. That is a job for the function that called us.
1273 */
1274 if (tbl->at_parent) {
1275 pmap = tbl->at_parent;
1276 free_a_table(tbl, FALSE);
1277 pmap->pm_a_tmgr = NULL;
1278 pmap->pm_a_phys = kernAphys;
1279 }
1280 #ifdef NON_REENTRANT
1281 /*
1282 * If the table isn't to be wired down, re-insert it at the
1283 * end of the pool.
1284 */
1285 if (!wired)
1286 /*
1287 * Quandary - XXX
1288 * Would it be better to let the calling function insert this
1289 * table into the queue? By inserting it here, we are allowing
1290 * it to be stolen immediately. The calling function is
1291 * probably not expecting to use a table that it is not
1292 * assured full control of.
1293 * Answer - In the intrest of re-entrancy, it is best to let
1294 * the calling function determine when a table is available
1295 * for use. Therefore this code block is not used.
1296 */
1297 TAILQ_INSERT_TAIL(&a_pool, tbl, at_link);
1298 #endif /* NON_REENTRANT */
1299 return tbl;
1300 }
1301
1302 /* get_b_table INTERNAL
1303 **
1304 * Return a level B table for use.
1305 */
1306 b_tmgr_t *
1307 get_b_table()
1308 {
1309 b_tmgr_t *tbl;
1310
1311 /* See 'get_a_table' for comments. */
1312 tbl = b_pool.tqh_first;
1313 if (tbl == NULL)
1314 panic("get_b_table: out of B tables.");
1315 TAILQ_REMOVE(&b_pool, tbl, bt_link);
1316 if (tbl->bt_parent) {
1317 tbl->bt_parent->at_dtbl[tbl->bt_pidx].attr.raw = MMU_DT_INVALID;
1318 tbl->bt_parent->at_ecnt--;
1319 free_b_table(tbl, FALSE);
1320 }
1321 #ifdef NON_REENTRANT
1322 if (!wired)
1323 /* XXX see quandary in get_b_table */
1324 /* XXX start lock */
1325 TAILQ_INSERT_TAIL(&b_pool, tbl, bt_link);
1326 /* XXX end lock */
1327 #endif /* NON_REENTRANT */
1328 return tbl;
1329 }
1330
1331 /* get_c_table INTERNAL
1332 **
1333 * Return a level C table for use.
1334 */
1335 c_tmgr_t *
1336 get_c_table()
1337 {
1338 c_tmgr_t *tbl;
1339
1340 /* See 'get_a_table' for comments */
1341 tbl = c_pool.tqh_first;
1342 if (tbl == NULL)
1343 panic("get_c_table: out of C tables.");
1344 TAILQ_REMOVE(&c_pool, tbl, ct_link);
1345 if (tbl->ct_parent) {
1346 tbl->ct_parent->bt_dtbl[tbl->ct_pidx].attr.raw = MMU_DT_INVALID;
1347 tbl->ct_parent->bt_ecnt--;
1348 free_c_table(tbl, FALSE);
1349 }
1350 #ifdef NON_REENTRANT
1351 if (!wired)
1352 /* XXX See quandary in get_a_table */
1353 /* XXX start lock */
1354 TAILQ_INSERT_TAIL(&c_pool, tbl, c_link);
1355 /* XXX end lock */
1356 #endif /* NON_REENTRANT */
1357
1358 return tbl;
1359 }
1360
1361 /*
1362 * The following 'free_table' and 'steal_table' functions are called to
1363 * detach tables from their current obligations (parents and children) and
1364 * prepare them for reuse in another mapping.
1365 *
1366 * Free_table is used when the calling function will handle the fate
1367 * of the parent table, such as returning it to the free pool when it has
1368 * no valid entries. Functions that do not want to handle this should
1369 * call steal_table, in which the parent table's descriptors and entry
1370 * count are automatically modified when this table is removed.
1371 */
1372
1373 /* free_a_table INTERNAL
1374 **
1375 * Unmaps the given A table and all child tables from their current
1376 * mappings. Returns the number of pages that were invalidated.
1377 * If 'relink' is true, the function will return the table to the head
1378 * of the available table pool.
1379 *
1380 * Cache note: The MC68851 will automatically flush all
1381 * descriptors derived from a given A table from its
1382 * Automatic Translation Cache (ATC) if we issue a
1383 * 'PFLUSHR' instruction with the base address of the
1384 * table. This function should do, and does so.
1385 * Note note: We are using an MC68030 - there is no
1386 * PFLUSHR.
1387 */
1388 int
1389 free_a_table(a_tbl, relink)
1390 a_tmgr_t *a_tbl;
1391 boolean_t relink;
1392 {
1393 int i, removed_cnt;
1394 mmu_long_dte_t *dte;
1395 mmu_short_dte_t *dtbl;
1396 b_tmgr_t *tmgr;
1397
1398 /*
1399 * Flush the ATC cache of all cached descriptors derived
1400 * from this table.
1401 * Sun3x does not use 68851's cached table feature
1402 * flush_atc_crp(mmu_vtop(a_tbl->dte));
1403 */
1404
1405 /*
1406 * Remove any pending cache flushes that were designated
1407 * for the pmap this A table belongs to.
1408 * a_tbl->parent->atc_flushq[0] = 0;
1409 * Not implemented in sun3x.
1410 */
1411
1412 /*
1413 * All A tables in the system should retain a map for the
1414 * kernel. If the table contains any valid descriptors
1415 * (other than those for the kernel area), invalidate them all,
1416 * stopping short of the kernel's entries.
1417 */
1418 removed_cnt = 0;
1419 if (a_tbl->at_ecnt) {
1420 dte = a_tbl->at_dtbl;
1421 for (i=0; i < MMU_TIA(KERNBASE); i++) {
1422 /*
1423 * If a table entry points to a valid B table, free
1424 * it and its children.
1425 */
1426 if (MMU_VALID_DT(dte[i])) {
1427 /*
1428 * The following block does several things,
1429 * from innermost expression to the
1430 * outermost:
1431 * 1) It extracts the base (cc 1996)
1432 * address of the B table pointed
1433 * to in the A table entry dte[i].
1434 * 2) It converts this base address into
1435 * the virtual address it can be
1436 * accessed with. (all MMU tables point
1437 * to physical addresses.)
1438 * 3) It finds the corresponding manager
1439 * structure which manages this MMU table.
1440 * 4) It frees the manager structure.
1441 * (This frees the MMU table and all
1442 * child tables. See 'free_b_table' for
1443 * details.)
1444 */
1445 dtbl = mmu_ptov(dte[i].addr.raw);
1446 tmgr = mmuB2tmgr(dtbl);
1447 removed_cnt += free_b_table(tmgr, TRUE);
1448 dte[i].attr.raw = MMU_DT_INVALID;
1449 }
1450 }
1451 a_tbl->at_ecnt = 0;
1452 }
1453 if (relink) {
1454 a_tbl->at_parent = NULL;
1455 TAILQ_REMOVE(&a_pool, a_tbl, at_link);
1456 TAILQ_INSERT_HEAD(&a_pool, a_tbl, at_link);
1457 }
1458 return removed_cnt;
1459 }
1460
1461 /* free_b_table INTERNAL
1462 **
1463 * Unmaps the given B table and all its children from their current
1464 * mappings. Returns the number of pages that were invalidated.
1465 * (For comments, see 'free_a_table()').
1466 */
1467 int
1468 free_b_table(b_tbl, relink)
1469 b_tmgr_t *b_tbl;
1470 boolean_t relink;
1471 {
1472 int i, removed_cnt;
1473 mmu_short_dte_t *dte;
1474 mmu_short_pte_t *dtbl;
1475 c_tmgr_t *tmgr;
1476
1477 removed_cnt = 0;
1478 if (b_tbl->bt_ecnt) {
1479 dte = b_tbl->bt_dtbl;
1480 for (i=0; i < MMU_B_TBL_SIZE; i++) {
1481 if (MMU_VALID_DT(dte[i])) {
1482 dtbl = mmu_ptov(MMU_DTE_PA(dte[i]));
1483 tmgr = mmuC2tmgr(dtbl);
1484 removed_cnt += free_c_table(tmgr, TRUE);
1485 dte[i].attr.raw = MMU_DT_INVALID;
1486 }
1487 }
1488 b_tbl->bt_ecnt = 0;
1489 }
1490
1491 if (relink) {
1492 b_tbl->bt_parent = NULL;
1493 TAILQ_REMOVE(&b_pool, b_tbl, bt_link);
1494 TAILQ_INSERT_HEAD(&b_pool, b_tbl, bt_link);
1495 }
1496 return removed_cnt;
1497 }
1498
1499 /* free_c_table INTERNAL
1500 **
1501 * Unmaps the given C table from use and returns it to the pool for
1502 * re-use. Returns the number of pages that were invalidated.
1503 *
1504 * This function preserves any physical page modification information
1505 * contained in the page descriptors within the C table by calling
1506 * 'pmap_remove_pte().'
1507 */
1508 int
1509 free_c_table(c_tbl, relink)
1510 c_tmgr_t *c_tbl;
1511 boolean_t relink;
1512 {
1513 int i, removed_cnt;
1514
1515 removed_cnt = 0;
1516 if (c_tbl->ct_ecnt) {
1517 for (i=0; i < MMU_C_TBL_SIZE; i++) {
1518 if (MMU_VALID_DT(c_tbl->ct_dtbl[i])) {
1519 pmap_remove_pte(&c_tbl->ct_dtbl[i]);
1520 removed_cnt++;
1521 }
1522 }
1523 c_tbl->ct_ecnt = 0;
1524 }
1525
1526 if (relink) {
1527 c_tbl->ct_parent = NULL;
1528 TAILQ_REMOVE(&c_pool, c_tbl, ct_link);
1529 TAILQ_INSERT_HEAD(&c_pool, c_tbl, ct_link);
1530 }
1531 return removed_cnt;
1532 }
1533
1534 #if 0
1535 /* free_c_table_novalid INTERNAL
1536 **
1537 * Frees the given C table manager without checking to see whether
1538 * or not it contains any valid page descriptors as it is assumed
1539 * that it does not.
1540 */
1541 void
1542 free_c_table_novalid(c_tbl)
1543 c_tmgr_t *c_tbl;
1544 {
1545 TAILQ_REMOVE(&c_pool, c_tbl, ct_link);
1546 TAILQ_INSERT_HEAD(&c_pool, c_tbl, ct_link);
1547 c_tbl->ct_parent->bt_dtbl[c_tbl->ct_pidx].attr.raw = MMU_DT_INVALID;
1548 c_tbl->ct_parent->bt_ecnt--;
1549 /*
1550 * XXX - Should call equiv. of 'free_b_table_novalid' here if
1551 * we just removed the last entry of the parent B table.
1552 * But I want to insure that this will not endanger pmap_enter()
1553 * with sudden removal of tables it is working with.
1554 *
1555 * We should probably add another field to each table, indicating
1556 * whether or not it is 'locked', ie. in the process of being
1557 * modified.
1558 */
1559 c_tbl->ct_parent = NULL;
1560 }
1561 #endif
1562
1563 /* pmap_remove_pte INTERNAL
1564 **
1565 * Unmap the given pte and preserve any page modification
1566 * information by transfering it to the pv head of the
1567 * physical page it maps to. This function does not update
1568 * any reference counts because it is assumed that the calling
1569 * function will do so.
1570 */
1571 void
1572 pmap_remove_pte(pte)
1573 mmu_short_pte_t *pte;
1574 {
1575 u_short pv_idx, targ_idx;
1576 int s;
1577 vm_offset_t pa;
1578 pv_t *pv;
1579
1580 pa = MMU_PTE_PA(*pte);
1581 if (is_managed(pa)) {
1582 pv = pa2pv(pa);
1583 targ_idx = pteidx(pte); /* Index of PTE being removed */
1584
1585 /*
1586 * If the PTE being removed is the first (or only) PTE in
1587 * the list of PTEs currently mapped to this page, remove the
1588 * PTE by changing the index found on the PV head. Otherwise
1589 * a linear search through the list will have to be executed
1590 * in order to find the PVE which points to the PTE being
1591 * removed, so that it may be modified to point to its new
1592 * neighbor.
1593 */
1594 s = splimp();
1595 pv_idx = pv->pv_idx; /* Index of first PTE in PV list */
1596 if (pv_idx == targ_idx) {
1597 pv->pv_idx = pvebase[targ_idx].pve_next;
1598 } else {
1599 /*
1600 * Find the PV element pointing to the target
1601 * element. Note: may have pv_idx==PVE_EOL
1602 */
1603 for (;;) {
1604 if (pv_idx == PVE_EOL) {
1605 #ifdef PMAP_DEBUG
1606 printf("pmap_remove_pte: PVE_EOL\n");
1607 Debugger();
1608 #endif
1609 goto pv_not_found;
1610 }
1611 if (pvebase[pv_idx].pve_next == targ_idx)
1612 break;
1613 pv_idx = pvebase[pv_idx].pve_next;
1614 }
1615 /*
1616 * At this point, pv_idx is the index of the PV
1617 * element just before the target element in the list.
1618 * Unlink the target.
1619 */
1620 pvebase[pv_idx].pve_next = pvebase[targ_idx].pve_next;
1621 pv_not_found:
1622 }
1623 /*
1624 * Save the mod/ref bits of the pte by simply
1625 * ORing the entire pte onto the pv_flags member
1626 * of the pv structure.
1627 * There is no need to use a separate bit pattern
1628 * for usage information on the pv head than that
1629 * which is used on the MMU ptes.
1630 */
1631 pv->pv_flags |= (u_short) pte->attr.raw;
1632 splx(s);
1633 }
1634
1635 pte->attr.raw = MMU_DT_INVALID;
1636 }
1637
1638 /* pmap_stroll INTERNAL
1639 **
1640 * Retrieve the addresses of all table managers involved in the mapping of
1641 * the given virtual address. If the table walk completed sucessfully,
1642 * return TRUE. If it was only partially sucessful, return FALSE.
1643 * The table walk performed by this function is important to many other
1644 * functions in this module.
1645 *
1646 * Note: This function ought to be easier to read.
1647 */
1648 boolean_t
1649 pmap_stroll(pmap, va, a_tbl, b_tbl, c_tbl, pte, a_idx, b_idx, pte_idx)
1650 pmap_t pmap;
1651 vm_offset_t va;
1652 a_tmgr_t **a_tbl;
1653 b_tmgr_t **b_tbl;
1654 c_tmgr_t **c_tbl;
1655 mmu_short_pte_t **pte;
1656 int *a_idx, *b_idx, *pte_idx;
1657 {
1658 mmu_long_dte_t *a_dte; /* A: long descriptor table */
1659 mmu_short_dte_t *b_dte; /* B: short descriptor table */
1660
1661 if (pmap == pmap_kernel())
1662 return FALSE;
1663
1664 /* Does the given pmap have its own A table? */
1665 *a_tbl = pmap->pm_a_tmgr;
1666 if (*a_tbl == NULL)
1667 return FALSE; /* No. Return unknown. */
1668 /* Does the A table have a valid B table
1669 * under the corresponding table entry?
1670 */
1671 *a_idx = MMU_TIA(va);
1672 a_dte = &((*a_tbl)->at_dtbl[*a_idx]);
1673 if (!MMU_VALID_DT(*a_dte))
1674 return FALSE; /* No. Return unknown. */
1675 /* Yes. Extract B table from the A table. */
1676 *b_tbl = mmuB2tmgr(mmu_ptov(a_dte->addr.raw));
1677 /* Does the B table have a valid C table
1678 * under the corresponding table entry?
1679 */
1680 *b_idx = MMU_TIB(va);
1681 b_dte = &((*b_tbl)->bt_dtbl[*b_idx]);
1682 if (!MMU_VALID_DT(*b_dte))
1683 return FALSE; /* No. Return unknown. */
1684 /* Yes. Extract C table from the B table. */
1685 *c_tbl = mmuC2tmgr(mmu_ptov(MMU_DTE_PA(*b_dte)));
1686 *pte_idx = MMU_TIC(va);
1687 *pte = &((*c_tbl)->ct_dtbl[*pte_idx]);
1688
1689 return TRUE;
1690 }
1691
1692 /* pmap_enter INTERFACE
1693 **
1694 * Called by the kernel to map a virtual address
1695 * to a physical address in the given process map.
1696 *
1697 * Note: this function should apply an exclusive lock
1698 * on the pmap system for its duration. (it certainly
1699 * would save my hair!!)
1700 * This function ought to be easier to read.
1701 */
1702 void
1703 pmap_enter(pmap, va, pa, prot, wired)
1704 pmap_t pmap;
1705 vm_offset_t va;
1706 vm_offset_t pa;
1707 vm_prot_t prot;
1708 boolean_t wired;
1709 {
1710 boolean_t insert, managed; /* Marks the need for PV insertion.*/
1711 u_short nidx; /* PV list index */
1712 int s; /* Used for splimp()/splx() */
1713 int flags; /* Mapping flags. eg. Cache inhibit */
1714 u_int a_idx, b_idx, pte_idx; /* table indices */
1715 a_tmgr_t *a_tbl; /* A: long descriptor table manager */
1716 b_tmgr_t *b_tbl; /* B: short descriptor table manager */
1717 c_tmgr_t *c_tbl; /* C: short page table manager */
1718 mmu_long_dte_t *a_dte; /* A: long descriptor table */
1719 mmu_short_dte_t *b_dte; /* B: short descriptor table */
1720 mmu_short_pte_t *c_pte; /* C: short page descriptor table */
1721 pv_t *pv; /* pv list head */
1722 enum {NONE, NEWA, NEWB, NEWC} llevel; /* used at end */
1723
1724 if (pmap == NULL)
1725 return;
1726 if (pmap == pmap_kernel()) {
1727 pmap_enter_kernel(va, pa, prot);
1728 return;
1729 }
1730
1731 flags = (pa & ~MMU_PAGE_MASK);
1732 pa &= MMU_PAGE_MASK;
1733
1734 /*
1735 * Determine if the physical address being mapped is on-board RAM.
1736 * Any other area of the address space is likely to belong to a
1737 * device and hence it would be disasterous to cache its contents.
1738 */
1739 if ((managed = is_managed(pa)) == FALSE)
1740 flags |= PMAP_NC;
1741
1742 /*
1743 * For user mappings we walk along the MMU tables of the given
1744 * pmap, reaching a PTE which describes the virtual page being
1745 * mapped or changed. If any level of the walk ends in an invalid
1746 * entry, a table must be allocated and the entry must be updated
1747 * to point to it.
1748 * There is a bit of confusion as to whether this code must be
1749 * re-entrant. For now we will assume it is. To support
1750 * re-entrancy we must unlink tables from the table pool before
1751 * we assume we may use them. Tables are re-linked into the pool
1752 * when we are finished with them at the end of the function.
1753 * But I don't feel like doing that until we have proof that this
1754 * needs to be re-entrant.
1755 * 'llevel' records which tables need to be relinked.
1756 */
1757 llevel = NONE;
1758
1759 /*
1760 * Step 1 - Retrieve the A table from the pmap. If it has no
1761 * A table, allocate a new one from the available pool.
1762 */
1763
1764 a_tbl = pmap->pm_a_tmgr;
1765 if (a_tbl == NULL) {
1766 /*
1767 * This pmap does not currently have an A table. Allocate
1768 * a new one.
1769 */
1770 a_tbl = get_a_table();
1771 a_tbl->at_parent = pmap;
1772
1773 /*
1774 * Assign this new A table to the pmap, and calculate its
1775 * physical address so that loadcrp() can be used to make
1776 * the table active.
1777 */
1778 pmap->pm_a_tmgr = a_tbl;
1779 pmap->pm_a_phys = mmu_vtop(a_tbl->at_dtbl);
1780
1781 /*
1782 * If the process receiving a new A table is the current
1783 * process, we are responsible for setting the MMU so that
1784 * it becomes the current address space. This only adds
1785 * new mappings, so no need to flush anything.
1786 */
1787 if (pmap == current_pmap()) {
1788 kernel_crp.rp_addr = pmap->pm_a_phys;
1789 loadcrp(&kernel_crp);
1790 }
1791
1792 if (!wired)
1793 llevel = NEWA;
1794 } else {
1795 /*
1796 * Use the A table already allocated for this pmap.
1797 * Unlink it from the A table pool if necessary.
1798 */
1799 if (wired && !a_tbl->at_wcnt)
1800 TAILQ_REMOVE(&a_pool, a_tbl, at_link);
1801 }
1802
1803 /*
1804 * Step 2 - Walk into the B table. If there is no valid B table,
1805 * allocate one.
1806 */
1807
1808 a_idx = MMU_TIA(va); /* Calculate the TIA of the VA. */
1809 a_dte = &a_tbl->at_dtbl[a_idx]; /* Retrieve descriptor from table */
1810 if (MMU_VALID_DT(*a_dte)) { /* Is the descriptor valid? */
1811 /* The descriptor is valid. Use the B table it points to. */
1812 /*************************************
1813 * a_idx *
1814 * v *
1815 * a_tbl -> +-+-+-+-+-+-+-+-+-+-+-+- *
1816 * | | | | | | | | | | | | *
1817 * +-+-+-+-+-+-+-+-+-+-+-+- *
1818 * | *
1819 * \- b_tbl -> +-+- *
1820 * | | *
1821 * +-+- *
1822 *************************************/
1823 b_dte = mmu_ptov(a_dte->addr.raw);
1824 b_tbl = mmuB2tmgr(b_dte);
1825
1826 /*
1827 * If the requested mapping must be wired, but this table
1828 * being used to map it is not, the table must be removed
1829 * from the available pool and its wired entry count
1830 * incremented.
1831 */
1832 if (wired && !b_tbl->bt_wcnt) {
1833 TAILQ_REMOVE(&b_pool, b_tbl, bt_link);
1834 a_tbl->at_wcnt++;
1835 }
1836 } else {
1837 /* The descriptor is invalid. Allocate a new B table. */
1838 b_tbl = get_b_table();
1839
1840 /* Point the parent A table descriptor to this new B table. */
1841 a_dte->addr.raw = mmu_vtop(b_tbl->bt_dtbl);
1842 a_dte->attr.raw = MMU_LONG_DTE_LU | MMU_DT_SHORT;
1843 a_tbl->at_ecnt++; /* Update parent's valid entry count */
1844
1845 /* Create the necessary back references to the parent table */
1846 b_tbl->bt_parent = a_tbl;
1847 b_tbl->bt_pidx = a_idx;
1848
1849 /*
1850 * If this table is to be wired, make sure the parent A table
1851 * wired count is updated to reflect that it has another wired
1852 * entry.
1853 */
1854 if (wired)
1855 a_tbl->at_wcnt++;
1856 else if (llevel == NONE)
1857 llevel = NEWB;
1858 }
1859
1860 /*
1861 * Step 3 - Walk into the C table, if there is no valid C table,
1862 * allocate one.
1863 */
1864
1865 b_idx = MMU_TIB(va); /* Calculate the TIB of the VA */
1866 b_dte = &b_tbl->bt_dtbl[b_idx]; /* Retrieve descriptor from table */
1867 if (MMU_VALID_DT(*b_dte)) { /* Is the descriptor valid? */
1868 /* The descriptor is valid. Use the C table it points to. */
1869 /**************************************
1870 * c_idx *
1871 * | v *
1872 * \- b_tbl -> +-+-+-+-+-+-+-+-+-+-+- *
1873 * | | | | | | | | | | | *
1874 * +-+-+-+-+-+-+-+-+-+-+- *
1875 * | *
1876 * \- c_tbl -> +-+-- *
1877 * | | | *
1878 * +-+-- *
1879 **************************************/
1880 c_pte = mmu_ptov(MMU_PTE_PA(*b_dte));
1881 c_tbl = mmuC2tmgr(c_pte);
1882
1883 /* If mapping is wired and table is not */
1884 if (wired && !c_tbl->ct_wcnt) {
1885 TAILQ_REMOVE(&c_pool, c_tbl, ct_link);
1886 b_tbl->bt_wcnt++;
1887 }
1888 } else {
1889 /* The descriptor is invalid. Allocate a new C table. */
1890 c_tbl = get_c_table();
1891
1892 /* Point the parent B table descriptor to this new C table. */
1893 b_dte->attr.raw = mmu_vtop(c_tbl->ct_dtbl);
1894 b_dte->attr.raw |= MMU_DT_SHORT;
1895 b_tbl->bt_ecnt++; /* Update parent's valid entry count */
1896
1897 /* Create the necessary back references to the parent table */
1898 c_tbl->ct_parent = b_tbl;
1899 c_tbl->ct_pidx = b_idx;
1900 /*
1901 * Store the pmap and base virtual managed address for faster
1902 * retrieval in the PV functions.
1903 */
1904 c_tbl->ct_pmap = pmap;
1905 c_tbl->ct_va = (va & (MMU_TIA_MASK|MMU_TIB_MASK));
1906
1907 /*
1908 * If this table is to be wired, make sure the parent B table
1909 * wired count is updated to reflect that it has another wired
1910 * entry.
1911 */
1912 if (wired)
1913 b_tbl->bt_wcnt++;
1914 else if (llevel == NONE)
1915 llevel = NEWC;
1916 }
1917
1918 /*
1919 * Step 4 - Deposit a page descriptor (PTE) into the appropriate
1920 * slot of the C table, describing the PA to which the VA is mapped.
1921 */
1922
1923 pte_idx = MMU_TIC(va);
1924 c_pte = &c_tbl->ct_dtbl[pte_idx];
1925 if (MMU_VALID_DT(*c_pte)) { /* Is the entry currently valid? */
1926 /*
1927 * The PTE is currently valid. This particular call
1928 * is just a synonym for one (or more) of the following
1929 * operations:
1930 * change protection of a page
1931 * change wiring status of a page
1932 * remove the mapping of a page
1933 *
1934 * XXX - Semi critical: This code should unwire the PTE
1935 * and, possibly, associated parent tables if this is a
1936 * change wiring operation. Currently it does not.
1937 *
1938 * This may be ok if pmap_change_wiring() is the only
1939 * interface used to UNWIRE a page.
1940 */
1941
1942 /* First check if this is a wiring operation. */
1943 if (wired && (c_pte->attr.raw & MMU_SHORT_PTE_WIRED)) {
1944 /*
1945 * The PTE is already wired. To prevent it from being
1946 * counted as a new wiring operation, reset the 'wired'
1947 * variable.
1948 */
1949 wired = FALSE;
1950 }
1951
1952 /* Is the new address the same as the old? */
1953 if (MMU_PTE_PA(*c_pte) == pa) {
1954 /*
1955 * Yes, mark that it does not need to be reinserted
1956 * into the PV list.
1957 */
1958 insert = FALSE;
1959
1960 /*
1961 * Clear all but the modified, referenced and wired
1962 * bits on the PTE.
1963 */
1964 c_pte->attr.raw &= (MMU_SHORT_PTE_M
1965 | MMU_SHORT_PTE_USED | MMU_SHORT_PTE_WIRED);
1966 } else {
1967 /* No, remove the old entry */
1968 pmap_remove_pte(c_pte);
1969 insert = TRUE;
1970 }
1971
1972 /*
1973 * TLB flush is only necessary if modifying current map.
1974 * However, in pmap_enter(), the pmap almost always IS
1975 * the current pmap, so don't even bother to check.
1976 */
1977 TBIS(va);
1978 } else {
1979 /*
1980 * The PTE is invalid. Increment the valid entry count in
1981 * the C table manager to reflect the addition of a new entry.
1982 */
1983 c_tbl->ct_ecnt++;
1984
1985 /* XXX - temporarily make sure the PTE is cleared. */
1986 c_pte->attr.raw = 0;
1987
1988 /* It will also need to be inserted into the PV list. */
1989 insert = TRUE;
1990 }
1991
1992 /*
1993 * If page is changing from unwired to wired status, set an unused bit
1994 * within the PTE to indicate that it is wired. Also increment the
1995 * wired entry count in the C table manager.
1996 */
1997 if (wired) {
1998 c_pte->attr.raw |= MMU_SHORT_PTE_WIRED;
1999 c_tbl->ct_wcnt++;
2000 }
2001
2002 /*
2003 * Map the page, being careful to preserve modify/reference/wired
2004 * bits. At this point it is assumed that the PTE either has no bits
2005 * set, or if there are set bits, they are only modified, reference or
2006 * wired bits. If not, the following statement will cause erratic
2007 * behavior.
2008 */
2009 #ifdef PMAP_DEBUG
2010 if (c_pte->attr.raw & ~(MMU_SHORT_PTE_M |
2011 MMU_SHORT_PTE_USED | MMU_SHORT_PTE_WIRED)) {
2012 printf("pmap_enter: junk left in PTE at %p\n", c_pte);
2013 Debugger();
2014 }
2015 #endif
2016 c_pte->attr.raw |= ((u_long) pa | MMU_DT_PAGE);
2017
2018 /*
2019 * If the mapping should be read-only, set the write protect
2020 * bit in the PTE.
2021 */
2022 if (!(prot & VM_PROT_WRITE))
2023 c_pte->attr.raw |= MMU_SHORT_PTE_WP;
2024
2025 /*
2026 * If the mapping should be cache inhibited (indicated by the flag
2027 * bits found on the lower order of the physical address.)
2028 * mark the PTE as a cache inhibited page.
2029 */
2030 if (flags & PMAP_NC)
2031 c_pte->attr.raw |= MMU_SHORT_PTE_CI;
2032
2033 /*
2034 * If the physical address being mapped is managed by the PV
2035 * system then link the pte into the list of pages mapped to that
2036 * address.
2037 */
2038 if (insert && managed) {
2039 pv = pa2pv(pa);
2040 nidx = pteidx(c_pte);
2041
2042 s = splimp();
2043 pvebase[nidx].pve_next = pv->pv_idx;
2044 pv->pv_idx = nidx;
2045 splx(s);
2046 }
2047
2048 /* Move any allocated tables back into the active pool. */
2049
2050 switch (llevel) {
2051 case NEWA:
2052 TAILQ_INSERT_TAIL(&a_pool, a_tbl, at_link);
2053 /* FALLTHROUGH */
2054 case NEWB:
2055 TAILQ_INSERT_TAIL(&b_pool, b_tbl, bt_link);
2056 /* FALLTHROUGH */
2057 case NEWC:
2058 TAILQ_INSERT_TAIL(&c_pool, c_tbl, ct_link);
2059 /* FALLTHROUGH */
2060 default:
2061 break;
2062 }
2063 }
2064
2065 /* pmap_enter_kernel INTERNAL
2066 **
2067 * Map the given virtual address to the given physical address within the
2068 * kernel address space. This function exists because the kernel map does
2069 * not do dynamic table allocation. It consists of a contiguous array of ptes
2070 * and can be edited directly without the need to walk through any tables.
2071 *
2072 * XXX: "Danger, Will Robinson!"
2073 * Note that the kernel should never take a fault on any page
2074 * between [ KERNBASE .. virtual_avail ] and this is checked in
2075 * trap.c for kernel-mode MMU faults. This means that mappings
2076 * created in that range must be implicily wired. -gwr
2077 */
2078 void
2079 pmap_enter_kernel(va, pa, prot)
2080 vm_offset_t va;
2081 vm_offset_t pa;
2082 vm_prot_t prot;
2083 {
2084 boolean_t was_valid, insert;
2085 u_short pte_idx;
2086 int s, flags;
2087 mmu_short_pte_t *pte;
2088 pv_t *pv;
2089 vm_offset_t old_pa;
2090
2091 flags = (pa & ~MMU_PAGE_MASK);
2092 pa &= MMU_PAGE_MASK;
2093
2094 if (is_managed(pa))
2095 insert = TRUE;
2096 else
2097 insert = FALSE;
2098
2099 /*
2100 * Calculate the index of the PTE being modified.
2101 */
2102 pte_idx = (u_long) m68k_btop(va - KERNBASE);
2103
2104 /* This array is traditionally named "Sysmap" */
2105 pte = &kernCbase[pte_idx];
2106
2107 s = splimp();
2108 if (MMU_VALID_DT(*pte)) {
2109 was_valid = TRUE;
2110 /*
2111 * If the PTE already maps a different
2112 * physical address, umap and pv_unlink.
2113 */
2114 old_pa = MMU_PTE_PA(*pte);
2115 if (pa != old_pa)
2116 pmap_remove_pte(pte);
2117 else {
2118 /*
2119 * Old PA and new PA are the same. No need to
2120 * relink the mapping within the PV list.
2121 */
2122 insert = FALSE;
2123
2124 /*
2125 * Save any mod/ref bits on the PTE.
2126 */
2127 pte->attr.raw &= (MMU_SHORT_PTE_USED|MMU_SHORT_PTE_M);
2128 }
2129 } else {
2130 pte->attr.raw = MMU_DT_INVALID;
2131 was_valid = FALSE;
2132 }
2133
2134 /*
2135 * Map the page. Being careful to preserve modified/referenced bits
2136 * on the PTE.
2137 */
2138 pte->attr.raw |= (pa | MMU_DT_PAGE);
2139
2140 if (!(prot & VM_PROT_WRITE)) /* If access should be read-only */
2141 pte->attr.raw |= MMU_SHORT_PTE_WP;
2142 if (flags & PMAP_NC)
2143 pte->attr.raw |= MMU_SHORT_PTE_CI;
2144 if (was_valid)
2145 TBIS(va);
2146
2147 /*
2148 * Insert the PTE into the PV system, if need be.
2149 */
2150 if (insert) {
2151 pv = pa2pv(pa);
2152 pvebase[pte_idx].pve_next = pv->pv_idx;
2153 pv->pv_idx = pte_idx;
2154 }
2155 splx(s);
2156
2157 }
2158
2159 /* pmap_map INTERNAL
2160 **
2161 * Map a contiguous range of physical memory into a contiguous range of
2162 * the kernel virtual address space.
2163 *
2164 * Used for device mappings and early mapping of the kernel text/data/bss.
2165 * Returns the first virtual address beyond the end of the range.
2166 */
2167 vm_offset_t
2168 pmap_map(va, pa, endpa, prot)
2169 vm_offset_t va;
2170 vm_offset_t pa;
2171 vm_offset_t endpa;
2172 int prot;
2173 {
2174 int sz;
2175
2176 sz = endpa - pa;
2177 do {
2178 pmap_enter_kernel(va, pa, prot);
2179 va += NBPG;
2180 pa += NBPG;
2181 sz -= NBPG;
2182 } while (sz > 0);
2183 return(va);
2184 }
2185
2186 /* pmap_protect INTERFACE
2187 **
2188 * Apply the given protection to the given virtual address range within
2189 * the given map.
2190 *
2191 * It is ok for the protection applied to be stronger than what is
2192 * specified. We use this to our advantage when the given map has no
2193 * mapping for the virtual address. By skipping a page when this
2194 * is discovered, we are effectively applying a protection of VM_PROT_NONE,
2195 * and therefore do not need to map the page just to apply a protection
2196 * code. Only pmap_enter() needs to create new mappings if they do not exist.
2197 *
2198 * XXX - This function could be speeded up by using pmap_stroll() for inital
2199 * setup, and then manual scrolling in the for() loop.
2200 */
2201 void
2202 pmap_protect(pmap, startva, endva, prot)
2203 pmap_t pmap;
2204 vm_offset_t startva, endva;
2205 vm_prot_t prot;
2206 {
2207 boolean_t iscurpmap;
2208 int a_idx, b_idx, c_idx;
2209 a_tmgr_t *a_tbl;
2210 b_tmgr_t *b_tbl;
2211 c_tmgr_t *c_tbl;
2212 mmu_short_pte_t *pte;
2213
2214 if (pmap == NULL)
2215 return;
2216 if (pmap == pmap_kernel()) {
2217 pmap_protect_kernel(startva, endva, prot);
2218 return;
2219 }
2220
2221 /*
2222 * In this particular pmap implementation, there are only three
2223 * types of memory protection: 'all' (read/write/execute),
2224 * 'read-only' (read/execute) and 'none' (no mapping.)
2225 * It is not possible for us to treat 'executable' as a separate
2226 * protection type. Therefore, protection requests that seek to
2227 * remove execute permission while retaining read or write, and those
2228 * that make little sense (write-only for example) are ignored.
2229 */
2230 switch (prot) {
2231 case VM_PROT_NONE:
2232 /*
2233 * A request to apply the protection code of
2234 * 'VM_PROT_NONE' is a synonym for pmap_remove().
2235 */
2236 pmap_remove(pmap, startva, endva);
2237 return;
2238 case VM_PROT_EXECUTE:
2239 case VM_PROT_READ:
2240 case VM_PROT_READ|VM_PROT_EXECUTE:
2241 /* continue */
2242 break;
2243 case VM_PROT_WRITE:
2244 case VM_PROT_WRITE|VM_PROT_READ:
2245 case VM_PROT_WRITE|VM_PROT_EXECUTE:
2246 case VM_PROT_ALL:
2247 /* None of these should happen in a sane system. */
2248 return;
2249 }
2250
2251 /*
2252 * If the pmap has no A table, it has no mappings and therefore
2253 * there is nothing to protect.
2254 */
2255 if ((a_tbl = pmap->pm_a_tmgr) == NULL)
2256 return;
2257
2258 a_idx = MMU_TIA(startva);
2259 b_idx = MMU_TIB(startva);
2260 c_idx = MMU_TIC(startva);
2261 b_tbl = (b_tmgr_t *) c_tbl = NULL;
2262
2263 iscurpmap = (pmap == current_pmap());
2264 while (startva < endva) {
2265 if (b_tbl || MMU_VALID_DT(a_tbl->at_dtbl[a_idx])) {
2266 if (b_tbl == NULL) {
2267 b_tbl = (b_tmgr_t *) a_tbl->at_dtbl[a_idx].addr.raw;
2268 b_tbl = mmu_ptov((vm_offset_t) b_tbl);
2269 b_tbl = mmuB2tmgr((mmu_short_dte_t *) b_tbl);
2270 }
2271 if (c_tbl || MMU_VALID_DT(b_tbl->bt_dtbl[b_idx])) {
2272 if (c_tbl == NULL) {
2273 c_tbl = (c_tmgr_t *) MMU_DTE_PA(b_tbl->bt_dtbl[b_idx]);
2274 c_tbl = mmu_ptov((vm_offset_t) c_tbl);
2275 c_tbl = mmuC2tmgr((mmu_short_pte_t *) c_tbl);
2276 }
2277 if (MMU_VALID_DT(c_tbl->ct_dtbl[c_idx])) {
2278 pte = &c_tbl->ct_dtbl[c_idx];
2279 /* make the mapping read-only */
2280 pte->attr.raw |= MMU_SHORT_PTE_WP;
2281 /*
2282 * If we just modified the current address space,
2283 * flush any translations for the modified page from
2284 * the translation cache and any data from it in the
2285 * data cache.
2286 */
2287 if (iscurpmap)
2288 TBIS(startva);
2289 }
2290 startva += NBPG;
2291
2292 if (++c_idx >= MMU_C_TBL_SIZE) { /* exceeded C table? */
2293 c_tbl = NULL;
2294 c_idx = 0;
2295 if (++b_idx >= MMU_B_TBL_SIZE) { /* exceeded B table? */
2296 b_tbl = NULL;
2297 b_idx = 0;
2298 }
2299 }
2300 } else { /* C table wasn't valid */
2301 c_tbl = NULL;
2302 c_idx = 0;
2303 startva += MMU_TIB_RANGE;
2304 if (++b_idx >= MMU_B_TBL_SIZE) { /* exceeded B table? */
2305 b_tbl = NULL;
2306 b_idx = 0;
2307 }
2308 } /* C table */
2309 } else { /* B table wasn't valid */
2310 b_tbl = NULL;
2311 b_idx = 0;
2312 startva += MMU_TIA_RANGE;
2313 a_idx++;
2314 } /* B table */
2315 }
2316 }
2317
2318 /* pmap_protect_kernel INTERNAL
2319 **
2320 * Apply the given protection code to a kernel address range.
2321 */
2322 void
2323 pmap_protect_kernel(startva, endva, prot)
2324 vm_offset_t startva, endva;
2325 vm_prot_t prot;
2326 {
2327 vm_offset_t va;
2328 mmu_short_pte_t *pte;
2329
2330 pte = &kernCbase[(unsigned long) m68k_btop(startva - KERNBASE)];
2331 for (va = startva; va < endva; va += NBPG, pte++) {
2332 if (MMU_VALID_DT(*pte)) {
2333 switch (prot) {
2334 case VM_PROT_ALL:
2335 break;
2336 case VM_PROT_EXECUTE:
2337 case VM_PROT_READ:
2338 case VM_PROT_READ|VM_PROT_EXECUTE:
2339 pte->attr.raw |= MMU_SHORT_PTE_WP;
2340 break;
2341 case VM_PROT_NONE:
2342 /* this is an alias for 'pmap_remove_kernel' */
2343 pmap_remove_pte(pte);
2344 break;
2345 default:
2346 break;
2347 }
2348 /*
2349 * since this is the kernel, immediately flush any cached
2350 * descriptors for this address.
2351 */
2352 TBIS(va);
2353 }
2354 }
2355 }
2356
2357 /* pmap_change_wiring INTERFACE
2358 **
2359 * Changes the wiring of the specified page.
2360 *
2361 * This function is called from vm_fault.c to unwire
2362 * a mapping. It really should be called 'pmap_unwire'
2363 * because it is never asked to do anything but remove
2364 * wirings.
2365 */
2366 void
2367 pmap_change_wiring(pmap, va, wire)
2368 pmap_t pmap;
2369 vm_offset_t va;
2370 boolean_t wire;
2371 {
2372 int a_idx, b_idx, c_idx;
2373 a_tmgr_t *a_tbl;
2374 b_tmgr_t *b_tbl;
2375 c_tmgr_t *c_tbl;
2376 mmu_short_pte_t *pte;
2377
2378 /* Kernel mappings always remain wired. */
2379 if (pmap == pmap_kernel())
2380 return;
2381
2382 #ifdef PMAP_DEBUG
2383 if (wire == TRUE)
2384 panic("pmap_change_wiring: wire requested.");
2385 #endif
2386
2387 /*
2388 * Walk through the tables. If the walk terminates without
2389 * a valid PTE then the address wasn't wired in the first place.
2390 * Return immediately.
2391 */
2392 if (pmap_stroll(pmap, va, &a_tbl, &b_tbl, &c_tbl, &pte, &a_idx,
2393 &b_idx, &c_idx) == FALSE)
2394 return;
2395
2396
2397 /* Is the PTE wired? If not, return. */
2398 if (!(pte->attr.raw & MMU_SHORT_PTE_WIRED))
2399 return;
2400
2401 /* Remove the wiring bit. */
2402 pte->attr.raw &= ~(MMU_SHORT_PTE_WIRED);
2403
2404 /*
2405 * Decrement the wired entry count in the C table.
2406 * If it reaches zero the following things happen:
2407 * 1. The table no longer has any wired entries and is considered
2408 * unwired.
2409 * 2. It is placed on the available queue.
2410 * 3. The parent table's wired entry count is decremented.
2411 * 4. If it reaches zero, this process repeats at step 1 and
2412 * stops at after reaching the A table.
2413 */
2414 if (--c_tbl->ct_wcnt == 0) {
2415 TAILQ_INSERT_TAIL(&c_pool, c_tbl, ct_link);
2416 if (--b_tbl->bt_wcnt == 0) {
2417 TAILQ_INSERT_TAIL(&b_pool, b_tbl, bt_link);
2418 if (--a_tbl->at_wcnt == 0) {
2419 TAILQ_INSERT_TAIL(&a_pool, a_tbl, at_link);
2420 }
2421 }
2422 }
2423 }
2424
2425 /* pmap_pageable INTERFACE
2426 **
2427 * Make the specified range of addresses within the given pmap,
2428 * 'pageable' or 'not-pageable'. A pageable page must not cause
2429 * any faults when referenced. A non-pageable page may.
2430 *
2431 * This routine is only advisory. The VM system will call pmap_enter()
2432 * to wire or unwire pages that are going to be made pageable before calling
2433 * this function. By the time this routine is called, everything that needs
2434 * to be done has already been done.
2435 */
2436 void
2437 pmap_pageable(pmap, start, end, pageable)
2438 pmap_t pmap;
2439 vm_offset_t start, end;
2440 boolean_t pageable;
2441 {
2442 /* not implemented. */
2443 }
2444
2445 /* pmap_copy INTERFACE
2446 **
2447 * Copy the mappings of a range of addresses in one pmap, into
2448 * the destination address of another.
2449 *
2450 * This routine is advisory. Should we one day decide that MMU tables
2451 * may be shared by more than one pmap, this function should be used to
2452 * link them together. Until that day however, we do nothing.
2453 */
2454 void
2455 pmap_copy(pmap_a, pmap_b, dst, len, src)
2456 pmap_t pmap_a, pmap_b;
2457 vm_offset_t dst;
2458 vm_size_t len;
2459 vm_offset_t src;
2460 {
2461 /* not implemented. */
2462 }
2463
2464 /* pmap_copy_page INTERFACE
2465 **
2466 * Copy the contents of one physical page into another.
2467 *
2468 * This function makes use of two virtual pages allocated in pmap_bootstrap()
2469 * to map the two specified physical pages into the kernel address space.
2470 *
2471 * Note: We could use the transparent translation registers to make the
2472 * mappings. If we do so, be sure to disable interrupts before using them.
2473 */
2474 void
2475 pmap_copy_page(srcpa, dstpa)
2476 vm_offset_t srcpa, dstpa;
2477 {
2478 vm_offset_t srcva, dstva;
2479 int s;
2480
2481 srcva = tmp_vpages[0];
2482 dstva = tmp_vpages[1];
2483
2484 s = splimp();
2485 if (tmp_vpages_inuse++)
2486 panic("pmap_copy_page: temporary vpages are in use.");
2487
2488 /* Map pages as non-cacheable to avoid cache polution? */
2489 pmap_enter_kernel(srcva, srcpa, VM_PROT_READ);
2490 pmap_enter_kernel(dstva, dstpa, VM_PROT_READ|VM_PROT_WRITE);
2491
2492 /* Hand-optimized version of bcopy(src, dst, NBPG) */
2493 copypage((char *) srcva, (char *) dstva);
2494
2495 pmap_remove_kernel(srcva, srcva + NBPG);
2496 pmap_remove_kernel(dstva, dstva + NBPG);
2497
2498 --tmp_vpages_inuse;
2499 splx(s);
2500 }
2501
2502 /* pmap_zero_page INTERFACE
2503 **
2504 * Zero the contents of the specified physical page.
2505 *
2506 * Uses one of the virtual pages allocated in pmap_boostrap()
2507 * to map the specified page into the kernel address space.
2508 */
2509 void
2510 pmap_zero_page(dstpa)
2511 vm_offset_t dstpa;
2512 {
2513 vm_offset_t dstva;
2514 int s;
2515
2516 dstva = tmp_vpages[1];
2517 s = splimp();
2518 if (tmp_vpages_inuse++)
2519 panic("pmap_zero_page: temporary vpages are in use.");
2520
2521 /* The comments in pmap_copy_page() above apply here also. */
2522 pmap_enter_kernel(dstva, dstpa, VM_PROT_READ|VM_PROT_WRITE);
2523
2524 /* Hand-optimized version of bzero(ptr, NBPG) */
2525 zeropage((char *) dstva);
2526
2527 pmap_remove_kernel(dstva, dstva + NBPG);
2528
2529 --tmp_vpages_inuse;
2530 splx(s);
2531 }
2532
2533 /* pmap_collect INTERFACE
2534 **
2535 * Called from the VM system when we are about to swap out
2536 * the process using this pmap. This should give up any
2537 * resources held here, including all its MMU tables.
2538 */
2539 void
2540 pmap_collect(pmap)
2541 pmap_t pmap;
2542 {
2543 /* XXX - todo... */
2544 }
2545
2546 /* pmap_create INTERFACE
2547 **
2548 * Create and return a pmap structure.
2549 */
2550 pmap_t
2551 pmap_create(size)
2552 vm_size_t size;
2553 {
2554 pmap_t pmap;
2555
2556 if (size)
2557 return NULL;
2558
2559 pmap = (pmap_t) malloc(sizeof(struct pmap), M_VMPMAP, M_WAITOK);
2560 pmap_pinit(pmap);
2561
2562 return pmap;
2563 }
2564
2565 /* pmap_pinit INTERNAL
2566 **
2567 * Initialize a pmap structure.
2568 */
2569 void
2570 pmap_pinit(pmap)
2571 pmap_t pmap;
2572 {
2573 bzero(pmap, sizeof(struct pmap));
2574 pmap->pm_a_tmgr = NULL;
2575 pmap->pm_a_phys = kernAphys;
2576 }
2577
2578 /* pmap_release INTERFACE
2579 **
2580 * Release any resources held by the given pmap.
2581 *
2582 * This is the reverse analog to pmap_pinit. It does not
2583 * necessarily mean for the pmap structure to be deallocated,
2584 * as in pmap_destroy.
2585 */
2586 void
2587 pmap_release(pmap)
2588 pmap_t pmap;
2589 {
2590 /*
2591 * As long as the pmap contains no mappings,
2592 * which always should be the case whenever
2593 * this function is called, there really should
2594 * be nothing to do.
2595 */
2596 #ifdef PMAP_DEBUG
2597 if (pmap == NULL)
2598 return;
2599 if (pmap == pmap_kernel())
2600 panic("pmap_release: kernel pmap");
2601 #endif
2602 /*
2603 * XXX - If this pmap has an A table, give it back.
2604 * The pmap SHOULD be empty by now, and pmap_remove
2605 * should have already given back the A table...
2606 * However, I see: pmap->pm_a_tmgr->at_ecnt == 1
2607 * at this point, which means some mapping was not
2608 * removed when it should have been. -gwr
2609 */
2610 if (pmap->pm_a_tmgr != NULL) {
2611 /* First make sure we are not using it! */
2612 if (kernel_crp.rp_addr == pmap->pm_a_phys) {
2613 kernel_crp.rp_addr = kernAphys;
2614 loadcrp(&kernel_crp);
2615 }
2616 #ifdef PMAP_DEBUG /* XXX - todo! */
2617 /* XXX - Now complain... */
2618 printf("pmap_release: still have table\n");
2619 Debugger();
2620 #endif
2621 free_a_table(pmap->pm_a_tmgr, TRUE);
2622 pmap->pm_a_tmgr = NULL;
2623 pmap->pm_a_phys = kernAphys;
2624 }
2625 }
2626
2627 /* pmap_reference INTERFACE
2628 **
2629 * Increment the reference count of a pmap.
2630 */
2631 void
2632 pmap_reference(pmap)
2633 pmap_t pmap;
2634 {
2635 if (pmap == NULL)
2636 return;
2637
2638 /* pmap_lock(pmap); */
2639 pmap->pm_refcount++;
2640 /* pmap_unlock(pmap); */
2641 }
2642
2643 /* pmap_dereference INTERNAL
2644 **
2645 * Decrease the reference count on the given pmap
2646 * by one and return the current count.
2647 */
2648 int
2649 pmap_dereference(pmap)
2650 pmap_t pmap;
2651 {
2652 int rtn;
2653
2654 if (pmap == NULL)
2655 return 0;
2656
2657 /* pmap_lock(pmap); */
2658 rtn = --pmap->pm_refcount;
2659 /* pmap_unlock(pmap); */
2660
2661 return rtn;
2662 }
2663
2664 /* pmap_destroy INTERFACE
2665 **
2666 * Decrement a pmap's reference count and delete
2667 * the pmap if it becomes zero. Will be called
2668 * only after all mappings have been removed.
2669 */
2670 void
2671 pmap_destroy(pmap)
2672 pmap_t pmap;
2673 {
2674 if (pmap == NULL)
2675 return;
2676 if (pmap == &kernel_pmap)
2677 panic("pmap_destroy: kernel_pmap!");
2678 if (pmap_dereference(pmap) == 0) {
2679 pmap_release(pmap);
2680 free(pmap, M_VMPMAP);
2681 }
2682 }
2683
2684 /* pmap_is_referenced INTERFACE
2685 **
2686 * Determine if the given physical page has been
2687 * referenced (read from [or written to.])
2688 */
2689 boolean_t
2690 pmap_is_referenced(pa)
2691 vm_offset_t pa;
2692 {
2693 pv_t *pv;
2694 int idx, s;
2695
2696 if (!pv_initialized)
2697 return FALSE;
2698 /* XXX - this may be unecessary. */
2699 if (!is_managed(pa))
2700 return FALSE;
2701
2702 pv = pa2pv(pa);
2703 /*
2704 * Check the flags on the pv head. If they are set,
2705 * return immediately. Otherwise a search must be done.
2706 */
2707 if (pv->pv_flags & PV_FLAGS_USED)
2708 return TRUE;
2709
2710 s = splimp();
2711 /*
2712 * Search through all pv elements pointing
2713 * to this page and query their reference bits
2714 */
2715 for (idx = pv->pv_idx;
2716 idx != PVE_EOL;
2717 idx = pvebase[idx].pve_next) {
2718
2719 if (MMU_PTE_USED(kernCbase[idx])) {
2720 splx(s);
2721 return TRUE;
2722 }
2723 }
2724 splx(s);
2725
2726 return FALSE;
2727 }
2728
2729 /* pmap_is_modified INTERFACE
2730 **
2731 * Determine if the given physical page has been
2732 * modified (written to.)
2733 */
2734 boolean_t
2735 pmap_is_modified(pa)
2736 vm_offset_t pa;
2737 {
2738 pv_t *pv;
2739 int idx, s;
2740
2741 if (!pv_initialized)
2742 return FALSE;
2743 /* XXX - this may be unecessary. */
2744 if (!is_managed(pa))
2745 return FALSE;
2746
2747 /* see comments in pmap_is_referenced() */
2748 pv = pa2pv(pa);
2749 if (pv->pv_flags & PV_FLAGS_MDFY)
2750 return TRUE;
2751
2752 s = splimp();
2753 for (idx = pv->pv_idx;
2754 idx != PVE_EOL;
2755 idx = pvebase[idx].pve_next) {
2756
2757 if (MMU_PTE_MODIFIED(kernCbase[idx])) {
2758 splx(s);
2759 return TRUE;
2760 }
2761 }
2762 splx(s);
2763
2764 return FALSE;
2765 }
2766
2767 /* pmap_page_protect INTERFACE
2768 **
2769 * Applies the given protection to all mappings to the given
2770 * physical page.
2771 */
2772 void
2773 pmap_page_protect(pa, prot)
2774 vm_offset_t pa;
2775 vm_prot_t prot;
2776 {
2777 pv_t *pv;
2778 int idx, s;
2779 vm_offset_t va;
2780 struct mmu_short_pte_struct *pte;
2781 c_tmgr_t *c_tbl;
2782 pmap_t pmap, curpmap;
2783
2784 if (!is_managed(pa))
2785 return;
2786
2787 curpmap = current_pmap();
2788 pv = pa2pv(pa);
2789 s = splimp();
2790
2791 for (idx = pv->pv_idx;
2792 idx != PVE_EOL;
2793 idx = pvebase[idx].pve_next) {
2794
2795 pte = &kernCbase[idx];
2796 switch (prot) {
2797 case VM_PROT_ALL:
2798 /* do nothing */
2799 break;
2800 case VM_PROT_EXECUTE:
2801 case VM_PROT_READ:
2802 case VM_PROT_READ|VM_PROT_EXECUTE:
2803 pte->attr.raw |= MMU_SHORT_PTE_WP;
2804
2805 /*
2806 * Determine the virtual address mapped by
2807 * the PTE and flush ATC entries if necessary.
2808 */
2809 va = pmap_get_pteinfo(idx, &pmap, &c_tbl);
2810 if (pmap == curpmap || pmap == pmap_kernel())
2811 TBIS(va);
2812 break;
2813 case VM_PROT_NONE:
2814 /* Save the mod/ref bits. */
2815 pv->pv_flags |= pte->attr.raw;
2816 /* Invalidate the PTE. */
2817 pte->attr.raw = MMU_DT_INVALID;
2818
2819 /*
2820 * Update table counts. And flush ATC entries
2821 * if necessary.
2822 */
2823 va = pmap_get_pteinfo(idx, &pmap, &c_tbl);
2824
2825 /*
2826 * If the PTE belongs to the kernel map,
2827 * be sure to flush the page it maps.
2828 */
2829 if (pmap == pmap_kernel()) {
2830 TBIS(va);
2831 } else {
2832 /*
2833 * The PTE belongs to a user map.
2834 * update the entry count in the C
2835 * table to which it belongs and flush
2836 * the ATC if the mapping belongs to
2837 * the current pmap.
2838 */
2839 c_tbl->ct_ecnt--;
2840 if (pmap == curpmap)
2841 TBIS(va);
2842 }
2843 break;
2844 default:
2845 break;
2846 }
2847 }
2848
2849 /*
2850 * If the protection code indicates that all mappings to the page
2851 * be removed, truncate the PV list to zero entries.
2852 */
2853 if (prot == VM_PROT_NONE)
2854 pv->pv_idx = PVE_EOL;
2855 splx(s);
2856 }
2857
2858 /* pmap_get_pteinfo INTERNAL
2859 **
2860 * Called internally to find the pmap and virtual address within that
2861 * map to which the pte at the given index maps. Also includes the PTE's C
2862 * table manager.
2863 *
2864 * Returns the pmap in the argument provided, and the virtual address
2865 * by return value.
2866 */
2867 vm_offset_t
2868 pmap_get_pteinfo(idx, pmap, tbl)
2869 u_int idx;
2870 pmap_t *pmap;
2871 c_tmgr_t **tbl;
2872 {
2873 vm_offset_t va = 0;
2874
2875 /*
2876 * Determine if the PTE is a kernel PTE or a user PTE.
2877 */
2878 if (idx >= NUM_KERN_PTES) {
2879 /*
2880 * The PTE belongs to a user mapping.
2881 */
2882 /* XXX: Would like an inline for this to validate idx... */
2883 *tbl = &Ctmgrbase[(idx - NUM_KERN_PTES) / MMU_C_TBL_SIZE];
2884
2885 *pmap = (*tbl)->ct_pmap;
2886 /*
2887 * To find the va to which the PTE maps, we first take
2888 * the table's base virtual address mapping which is stored
2889 * in ct_va. We then increment this address by a page for
2890 * every slot skipped until we reach the PTE.
2891 */
2892 va = (*tbl)->ct_va;
2893 va += m68k_ptob(idx % MMU_C_TBL_SIZE);
2894 } else {
2895 /*
2896 * The PTE belongs to the kernel map.
2897 */
2898 *pmap = pmap_kernel();
2899
2900 va = m68k_ptob(idx);
2901 va += KERNBASE;
2902 }
2903
2904 return va;
2905 }
2906
2907 /* pmap_clear_modify INTERFACE
2908 **
2909 * Clear the modification bit on the page at the specified
2910 * physical address.
2911 *
2912 */
2913 void
2914 pmap_clear_modify(pa)
2915 vm_offset_t pa;
2916 {
2917 if (!is_managed(pa))
2918 return;
2919 pmap_clear_pv(pa, PV_FLAGS_MDFY);
2920 }
2921
2922 /* pmap_clear_reference INTERFACE
2923 **
2924 * Clear the referenced bit on the page at the specified
2925 * physical address.
2926 */
2927 void
2928 pmap_clear_reference(pa)
2929 vm_offset_t pa;
2930 {
2931 if (!is_managed(pa))
2932 return;
2933 pmap_clear_pv(pa, PV_FLAGS_USED);
2934 }
2935
2936 /* pmap_clear_pv INTERNAL
2937 **
2938 * Clears the specified flag from the specified physical address.
2939 * (Used by pmap_clear_modify() and pmap_clear_reference().)
2940 *
2941 * Flag is one of:
2942 * PV_FLAGS_MDFY - Page modified bit.
2943 * PV_FLAGS_USED - Page used (referenced) bit.
2944 *
2945 * This routine must not only clear the flag on the pv list
2946 * head. It must also clear the bit on every pte in the pv
2947 * list associated with the address.
2948 */
2949 void
2950 pmap_clear_pv(pa, flag)
2951 vm_offset_t pa;
2952 int flag;
2953 {
2954 pv_t *pv;
2955 int idx, s;
2956 vm_offset_t va;
2957 pmap_t pmap;
2958 mmu_short_pte_t *pte;
2959 c_tmgr_t *c_tbl;
2960
2961 pv = pa2pv(pa);
2962
2963 s = splimp();
2964 pv->pv_flags &= ~(flag);
2965
2966 for (idx = pv->pv_idx;
2967 idx != PVE_EOL;
2968 idx = pvebase[idx].pve_next) {
2969
2970 pte = &kernCbase[idx];
2971 pte->attr.raw &= ~(flag);
2972 /*
2973 * The MC68030 MMU will not set the modified or
2974 * referenced bits on any MMU tables for which it has
2975 * a cached descriptor with its modify bit set. To insure
2976 * that it will modify these bits on the PTE during the next
2977 * time it is written to or read from, we must flush it from
2978 * the ATC.
2979 *
2980 * Ordinarily it is only necessary to flush the descriptor
2981 * if it is used in the current address space. But since I
2982 * am not sure that there will always be a notion of
2983 * 'the current address space' when this function is called,
2984 * I will skip the test and always flush the address. It
2985 * does no harm.
2986 */
2987 va = pmap_get_pteinfo(idx, &pmap, &c_tbl);
2988 TBIS(va);
2989 }
2990 splx(s);
2991 }
2992
2993 /* pmap_extract INTERFACE
2994 **
2995 * Return the physical address mapped by the virtual address
2996 * in the specified pmap or 0 if it is not known.
2997 *
2998 * Note: this function should also apply an exclusive lock
2999 * on the pmap system during its duration.
3000 */
3001 vm_offset_t
3002 pmap_extract(pmap, va)
3003 pmap_t pmap;
3004 vm_offset_t va;
3005 {
3006 int a_idx, b_idx, pte_idx;
3007 a_tmgr_t *a_tbl;
3008 b_tmgr_t *b_tbl;
3009 c_tmgr_t *c_tbl;
3010 mmu_short_pte_t *c_pte;
3011
3012 if (pmap == pmap_kernel())
3013 return pmap_extract_kernel(va);
3014 if (pmap == NULL)
3015 return 0;
3016
3017 if (pmap_stroll(pmap, va, &a_tbl, &b_tbl, &c_tbl,
3018 &c_pte, &a_idx, &b_idx, &pte_idx) == FALSE)
3019 return 0;
3020
3021 if (!MMU_VALID_DT(*c_pte))
3022 return 0;
3023
3024 return (MMU_PTE_PA(*c_pte));
3025 }
3026
3027 /* pmap_extract_kernel INTERNAL
3028 **
3029 * Extract a translation from the kernel address space.
3030 */
3031 vm_offset_t
3032 pmap_extract_kernel(va)
3033 vm_offset_t va;
3034 {
3035 mmu_short_pte_t *pte;
3036
3037 pte = &kernCbase[(u_int) m68k_btop(va - KERNBASE)];
3038 return MMU_PTE_PA(*pte);
3039 }
3040
3041 /* pmap_remove_kernel INTERNAL
3042 **
3043 * Remove the mapping of a range of virtual addresses from the kernel map.
3044 * The arguments are already page-aligned.
3045 */
3046 void
3047 pmap_remove_kernel(sva, eva)
3048 vm_offset_t sva;
3049 vm_offset_t eva;
3050 {
3051 int idx, eidx;
3052
3053 #ifdef PMAP_DEBUG
3054 if ((sva & PGOFSET) || (eva & PGOFSET))
3055 panic("pmap_remove_kernel: alignment");
3056 #endif
3057
3058 idx = m68k_btop(sva - KERNBASE);
3059 eidx = m68k_btop(eva - KERNBASE);
3060
3061 while (idx < eidx) {
3062 pmap_remove_pte(&kernCbase[idx++]);
3063 TBIS(sva);
3064 sva += NBPG;
3065 }
3066 }
3067
3068 /* pmap_remove INTERFACE
3069 **
3070 * Remove the mapping of a range of virtual addresses from the given pmap.
3071 *
3072 * If the range contains any wired entries, this function will probably create
3073 * disaster.
3074 */
3075 void
3076 pmap_remove(pmap, start, end)
3077 pmap_t pmap;
3078 vm_offset_t start;
3079 vm_offset_t end;
3080 {
3081
3082 if (pmap == pmap_kernel()) {
3083 pmap_remove_kernel(start, end);
3084 return;
3085 }
3086
3087 /*
3088 * XXX - Temporary(?) statement to prevent panic caused
3089 * by vm_alloc_with_pager() handing us a software map (ie NULL)
3090 * to remove because it couldn't get backing store.
3091 * (I guess.)
3092 */
3093 if (pmap == NULL)
3094 return;
3095
3096 /*
3097 * If the pmap doesn't have an A table of its own, it has no mappings
3098 * that can be removed.
3099 */
3100 if (pmap->pm_a_tmgr == NULL)
3101 return;
3102
3103 /*
3104 * Remove the specified range from the pmap. If the function
3105 * returns true, the operation removed all the valid mappings
3106 * in the pmap and freed its A table. If this happened to the
3107 * currently loaded pmap, the MMU root pointer must be reloaded
3108 * with the default 'kernel' map.
3109 */
3110 if (pmap_remove_a(pmap->pm_a_tmgr, start, end)) {
3111 if (kernel_crp.rp_addr == pmap->pm_a_phys) {
3112 kernel_crp.rp_addr = kernAphys;
3113 loadcrp(&kernel_crp);
3114 /* will do TLB flush below */
3115 }
3116 pmap->pm_a_tmgr = NULL;
3117 pmap->pm_a_phys = kernAphys;
3118 }
3119
3120 /*
3121 * If we just modified the current address space,
3122 * make sure to flush the MMU cache.
3123 *
3124 * XXX - this could be an unecessarily large flush.
3125 * XXX - Could decide, based on the size of the VA range
3126 * to be removed, whether to flush "by pages" or "all".
3127 */
3128 if (pmap == current_pmap())
3129 TBIAU();
3130 }
3131
3132 /* pmap_remove_a INTERNAL
3133 **
3134 * This is function number one in a set of three that removes a range
3135 * of memory in the most efficient manner by removing the highest possible
3136 * tables from the memory space. This particular function attempts to remove
3137 * as many B tables as it can, delegating the remaining fragmented ranges to
3138 * pmap_remove_b().
3139 *
3140 * If the removal operation results in an empty A table, the function returns
3141 * TRUE.
3142 *
3143 * It's ugly but will do for now.
3144 */
3145 boolean_t
3146 pmap_remove_a(a_tbl, start, end)
3147 a_tmgr_t *a_tbl;
3148 vm_offset_t start;
3149 vm_offset_t end;
3150 {
3151 boolean_t empty;
3152 int idx;
3153 vm_offset_t nstart, nend;
3154 b_tmgr_t *b_tbl;
3155 mmu_long_dte_t *a_dte;
3156 mmu_short_dte_t *b_dte;
3157
3158 /*
3159 * The following code works with what I call a 'granularity
3160 * reduction algorithim'. A range of addresses will always have
3161 * the following properties, which are classified according to
3162 * how the range relates to the size of the current granularity
3163 * - an A table entry:
3164 *
3165 * 1 2 3 4
3166 * -+---+---+---+---+---+---+---+-
3167 * -+---+---+---+---+---+---+---+-
3168 *
3169 * A range will always start on a granularity boundary, illustrated
3170 * by '+' signs in the table above, or it will start at some point
3171 * inbetween a granularity boundary, as illustrated by point 1.
3172 * The first step in removing a range of addresses is to remove the
3173 * range between 1 and 2, the nearest granularity boundary. This
3174 * job is handled by the section of code governed by the
3175 * 'if (start < nstart)' statement.
3176 *
3177 * A range will always encompass zero or more intergral granules,
3178 * illustrated by points 2 and 3. Integral granules are easy to
3179 * remove. The removal of these granules is the second step, and
3180 * is handled by the code block 'if (nstart < nend)'.
3181 *
3182 * Lastly, a range will always end on a granularity boundary,
3183 * ill. by point 3, or it will fall just beyond one, ill. by point
3184 * 4. The last step involves removing this range and is handled by
3185 * the code block 'if (nend < end)'.
3186 */
3187 nstart = MMU_ROUND_UP_A(start);
3188 nend = MMU_ROUND_A(end);
3189
3190 if (start < nstart) {
3191 /*
3192 * This block is executed if the range starts between
3193 * a granularity boundary.
3194 *
3195 * First find the DTE which is responsible for mapping
3196 * the start of the range.
3197 */
3198 idx = MMU_TIA(start);
3199 a_dte = &a_tbl->at_dtbl[idx];
3200
3201 /*
3202 * If the DTE is valid then delegate the removal of the sub
3203 * range to pmap_remove_b(), which can remove addresses at
3204 * a finer granularity.
3205 */
3206 if (MMU_VALID_DT(*a_dte)) {
3207 b_dte = mmu_ptov(a_dte->addr.raw);
3208 b_tbl = mmuB2tmgr(b_dte);
3209
3210 /*
3211 * The sub range to be removed starts at the start
3212 * of the full range we were asked to remove, and ends
3213 * at the greater of:
3214 * 1. The end of the full range, -or-
3215 * 2. The end of the full range, rounded down to the
3216 * nearest granularity boundary.
3217 */
3218 if (end < nstart)
3219 empty = pmap_remove_b(b_tbl, start, end);
3220 else
3221 empty = pmap_remove_b(b_tbl, start, nstart);
3222
3223 /*
3224 * If the removal resulted in an empty B table,
3225 * invalidate the DTE that points to it and decrement
3226 * the valid entry count of the A table.
3227 */
3228 if (empty) {
3229 a_dte->attr.raw = MMU_DT_INVALID;
3230 a_tbl->at_ecnt--;
3231 }
3232 }
3233 /*
3234 * If the DTE is invalid, the address range is already non-
3235 * existant and can simply be skipped.
3236 */
3237 }
3238 if (nstart < nend) {
3239 /*
3240 * This block is executed if the range spans a whole number
3241 * multiple of granules (A table entries.)
3242 *
3243 * First find the DTE which is responsible for mapping
3244 * the start of the first granule involved.
3245 */
3246 idx = MMU_TIA(nstart);
3247 a_dte = &a_tbl->at_dtbl[idx];
3248
3249 /*
3250 * Remove entire sub-granules (B tables) one at a time,
3251 * until reaching the end of the range.
3252 */
3253 for (; nstart < nend; a_dte++, nstart += MMU_TIA_RANGE)
3254 if (MMU_VALID_DT(*a_dte)) {
3255 /*
3256 * Find the B table manager for the
3257 * entry and free it.
3258 */
3259 b_dte = mmu_ptov(a_dte->addr.raw);
3260 b_tbl = mmuB2tmgr(b_dte);
3261 free_b_table(b_tbl, TRUE);
3262
3263 /*
3264 * Invalidate the DTE that points to the
3265 * B table and decrement the valid entry
3266 * count of the A table.
3267 */
3268 a_dte->attr.raw = MMU_DT_INVALID;
3269 a_tbl->at_ecnt--;
3270 }
3271 }
3272 if (nend < end) {
3273 /*
3274 * This block is executed if the range ends beyond a
3275 * granularity boundary.
3276 *
3277 * First find the DTE which is responsible for mapping
3278 * the start of the nearest (rounded down) granularity
3279 * boundary.
3280 */
3281 idx = MMU_TIA(nend);
3282 a_dte = &a_tbl->at_dtbl[idx];
3283
3284 /*
3285 * If the DTE is valid then delegate the removal of the sub
3286 * range to pmap_remove_b(), which can remove addresses at
3287 * a finer granularity.
3288 */
3289 if (MMU_VALID_DT(*a_dte)) {
3290 /*
3291 * Find the B table manager for the entry
3292 * and hand it to pmap_remove_b() along with
3293 * the sub range.
3294 */
3295 b_dte = mmu_ptov(a_dte->addr.raw);
3296 b_tbl = mmuB2tmgr(b_dte);
3297
3298 empty = pmap_remove_b(b_tbl, nend, end);
3299
3300 /*
3301 * If the removal resulted in an empty B table,
3302 * invalidate the DTE that points to it and decrement
3303 * the valid entry count of the A table.
3304 */
3305 if (empty) {
3306 a_dte->attr.raw = MMU_DT_INVALID;
3307 a_tbl->at_ecnt--;
3308 }
3309 }
3310 }
3311
3312 /*
3313 * If there are no more entries in the A table, release it
3314 * back to the available pool and return TRUE.
3315 */
3316 if (a_tbl->at_ecnt == 0) {
3317 a_tbl->at_parent = NULL;
3318 TAILQ_REMOVE(&a_pool, a_tbl, at_link);
3319 TAILQ_INSERT_HEAD(&a_pool, a_tbl, at_link);
3320 empty = TRUE;
3321 } else {
3322 empty = FALSE;
3323 }
3324
3325 return empty;
3326 }
3327
3328 /* pmap_remove_b INTERNAL
3329 **
3330 * Remove a range of addresses from an address space, trying to remove entire
3331 * C tables if possible.
3332 *
3333 * If the operation results in an empty B table, the function returns TRUE.
3334 */
3335 boolean_t
3336 pmap_remove_b(b_tbl, start, end)
3337 b_tmgr_t *b_tbl;
3338 vm_offset_t start;
3339 vm_offset_t end;
3340 {
3341 boolean_t empty;
3342 int idx;
3343 vm_offset_t nstart, nend, rstart;
3344 c_tmgr_t *c_tbl;
3345 mmu_short_dte_t *b_dte;
3346 mmu_short_pte_t *c_dte;
3347
3348
3349 nstart = MMU_ROUND_UP_B(start);
3350 nend = MMU_ROUND_B(end);
3351
3352 if (start < nstart) {
3353 idx = MMU_TIB(start);
3354 b_dte = &b_tbl->bt_dtbl[idx];
3355 if (MMU_VALID_DT(*b_dte)) {
3356 c_dte = mmu_ptov(MMU_DTE_PA(*b_dte));
3357 c_tbl = mmuC2tmgr(c_dte);
3358 if (end < nstart)
3359 empty = pmap_remove_c(c_tbl, start, end);
3360 else
3361 empty = pmap_remove_c(c_tbl, start, nstart);
3362 if (empty) {
3363 b_dte->attr.raw = MMU_DT_INVALID;
3364 b_tbl->bt_ecnt--;
3365 }
3366 }
3367 }
3368 if (nstart < nend) {
3369 idx = MMU_TIB(nstart);
3370 b_dte = &b_tbl->bt_dtbl[idx];
3371 rstart = nstart;
3372 while (rstart < nend) {
3373 if (MMU_VALID_DT(*b_dte)) {
3374 c_dte = mmu_ptov(MMU_DTE_PA(*b_dte));
3375 c_tbl = mmuC2tmgr(c_dte);
3376 free_c_table(c_tbl, TRUE);
3377 b_dte->attr.raw = MMU_DT_INVALID;
3378 b_tbl->bt_ecnt--;
3379 }
3380 b_dte++;
3381 rstart += MMU_TIB_RANGE;
3382 }
3383 }
3384 if (nend < end) {
3385 idx = MMU_TIB(nend);
3386 b_dte = &b_tbl->bt_dtbl[idx];
3387 if (MMU_VALID_DT(*b_dte)) {
3388 c_dte = mmu_ptov(MMU_DTE_PA(*b_dte));
3389 c_tbl = mmuC2tmgr(c_dte);
3390 empty = pmap_remove_c(c_tbl, nend, end);
3391 if (empty) {
3392 b_dte->attr.raw = MMU_DT_INVALID;
3393 b_tbl->bt_ecnt--;
3394 }
3395 }
3396 }
3397
3398 if (b_tbl->bt_ecnt == 0) {
3399 b_tbl->bt_parent = NULL;
3400 TAILQ_REMOVE(&b_pool, b_tbl, bt_link);
3401 TAILQ_INSERT_HEAD(&b_pool, b_tbl, bt_link);
3402 empty = TRUE;
3403 } else {
3404 empty = FALSE;
3405 }
3406
3407 return empty;
3408 }
3409
3410 /* pmap_remove_c INTERNAL
3411 **
3412 * Remove a range of addresses from the given C table.
3413 */
3414 boolean_t
3415 pmap_remove_c(c_tbl, start, end)
3416 c_tmgr_t *c_tbl;
3417 vm_offset_t start;
3418 vm_offset_t end;
3419 {
3420 boolean_t empty;
3421 int idx;
3422 mmu_short_pte_t *c_pte;
3423
3424 idx = MMU_TIC(start);
3425 c_pte = &c_tbl->ct_dtbl[idx];
3426 for (;start < end; start += MMU_PAGE_SIZE, c_pte++) {
3427 if (MMU_VALID_DT(*c_pte)) {
3428 pmap_remove_pte(c_pte);
3429 c_tbl->ct_ecnt--;
3430 }
3431 }
3432
3433 if (c_tbl->ct_ecnt == 0) {
3434 c_tbl->ct_parent = NULL;
3435 TAILQ_REMOVE(&c_pool, c_tbl, ct_link);
3436 TAILQ_INSERT_HEAD(&c_pool, c_tbl, ct_link);
3437 empty = TRUE;
3438 } else {
3439 empty = FALSE;
3440 }
3441
3442 return empty;
3443 }
3444
3445 /* is_managed INTERNAL
3446 **
3447 * Determine if the given physical address is managed by the PV system.
3448 * Note that this logic assumes that no one will ask for the status of
3449 * addresses which lie in-between the memory banks on the 3/80. If they
3450 * do so, it will falsely report that it is managed.
3451 *
3452 * Note: A "managed" address is one that was reported to the VM system as
3453 * a "usable page" during system startup. As such, the VM system expects the
3454 * pmap module to keep an accurate track of the useage of those pages.
3455 * Any page not given to the VM system at startup does not exist (as far as
3456 * the VM system is concerned) and is therefore "unmanaged." Examples are
3457 * those pages which belong to the ROM monitor and the memory allocated before
3458 * the VM system was started.
3459 */
3460 boolean_t
3461 is_managed(pa)
3462 vm_offset_t pa;
3463 {
3464 if (pa >= avail_start && pa < avail_end)
3465 return TRUE;
3466 else
3467 return FALSE;
3468 }
3469
3470 /* pmap_bootstrap_alloc INTERNAL
3471 **
3472 * Used internally for memory allocation at startup when malloc is not
3473 * available. This code will fail once it crosses the first memory
3474 * bank boundary on the 3/80. Hopefully by then however, the VM system
3475 * will be in charge of allocation.
3476 */
3477 void *
3478 pmap_bootstrap_alloc(size)
3479 int size;
3480 {
3481 void *rtn;
3482
3483 #ifdef PMAP_DEBUG
3484 if (bootstrap_alloc_enabled == FALSE) {
3485 mon_printf("pmap_bootstrap_alloc: disabled\n");
3486 sunmon_abort();
3487 }
3488 #endif
3489
3490 rtn = (void *) virtual_avail;
3491 virtual_avail += size;
3492
3493 #ifdef PMAP_DEBUG
3494 if (virtual_avail > virtual_contig_end) {
3495 mon_printf("pmap_bootstrap_alloc: out of mem\n");
3496 sunmon_abort();
3497 }
3498 #endif
3499
3500 return rtn;
3501 }
3502
3503 /* pmap_bootstap_aalign INTERNAL
3504 **
3505 * Used to insure that the next call to pmap_bootstrap_alloc() will
3506 * return a chunk of memory aligned to the specified size.
3507 *
3508 * Note: This function will only support alignment sizes that are powers
3509 * of two.
3510 */
3511 void
3512 pmap_bootstrap_aalign(size)
3513 int size;
3514 {
3515 int off;
3516
3517 off = virtual_avail & (size - 1);
3518 if (off) {
3519 (void) pmap_bootstrap_alloc(size - off);
3520 }
3521 }
3522
3523 /* pmap_pa_exists
3524 **
3525 * Used by the /dev/mem driver to see if a given PA is memory
3526 * that can be mapped. (The PA is not in a hole.)
3527 */
3528 int
3529 pmap_pa_exists(pa)
3530 vm_offset_t pa;
3531 {
3532 register int i;
3533
3534 for (i = 0; i < SUN3X_NPHYS_RAM_SEGS; i++) {
3535 if ((pa >= avail_mem[i].pmem_start) &&
3536 (pa < avail_mem[i].pmem_end))
3537 return (1);
3538 if (avail_mem[i].pmem_next == NULL)
3539 break;
3540 }
3541 return (0);
3542 }
3543
3544 /* Called only from locore.s and pmap.c */
3545 void _pmap_switch __P((pmap_t pmap));
3546
3547 /*
3548 * _pmap_switch INTERNAL
3549 *
3550 * This is called by locore.s:cpu_switch() when it is
3551 * switching to a new process. Load new translations.
3552 * Note: done in-line by locore.s unless PMAP_DEBUG
3553 *
3554 * Note that we do NOT allocate a context here, but
3555 * share the "kernel only" context until we really
3556 * need our own context for user-space mappings in
3557 * pmap_enter_user(). [ s/context/mmu A table/ ]
3558 */
3559 void
3560 _pmap_switch(pmap)
3561 pmap_t pmap;
3562 {
3563 u_long rootpa;
3564
3565 /*
3566 * Only do reload/flush if we have to.
3567 * Note that if the old and new process
3568 * were BOTH using the "null" context,
3569 * then this will NOT flush the TLB.
3570 */
3571 rootpa = pmap->pm_a_phys;
3572 if (kernel_crp.rp_addr != rootpa) {
3573 DPRINT(("pmap_activate(%p)\n", pmap));
3574 kernel_crp.rp_addr = rootpa;
3575 loadcrp(&kernel_crp);
3576 TBIAU();
3577 }
3578 }
3579
3580 /*
3581 * Exported version of pmap_activate(). This is called from the
3582 * machine-independent VM code when a process is given a new pmap.
3583 * If (p == curproc) do like cpu_switch would do; otherwise just
3584 * take this as notification that the process has a new pmap.
3585 */
3586 void
3587 pmap_activate(p)
3588 struct proc *p;
3589 {
3590 pmap_t pmap = p->p_vmspace->vm_map.pmap;
3591 int s;
3592
3593 if (p == curproc) {
3594 s = splimp();
3595 _pmap_switch(pmap);
3596 splx(s);
3597 }
3598 }
3599
3600 /*
3601 * pmap_deactivate INTERFACE
3602 **
3603 * This is called to deactivate the specified process's address space.
3604 * XXX The semantics of this function are currently not well-defined.
3605 */
3606 void
3607 pmap_deactivate(p)
3608 struct proc *p;
3609 {
3610 /* not implemented. */
3611 }
3612
3613 /* pmap_update
3614 **
3615 * Apply any delayed changes scheduled for all pmaps immediately.
3616 *
3617 * No delayed operations are currently done in this pmap.
3618 */
3619 void
3620 pmap_update()
3621 {
3622 /* not implemented. */
3623 }
3624
3625 /*
3626 * Fill in the sun3x-specific part of the kernel core header
3627 * for dumpsys(). (See machdep.c for the rest.)
3628 */
3629 void
3630 pmap_kcore_hdr(sh)
3631 struct sun3x_kcore_hdr *sh;
3632 {
3633 u_long spa, len;
3634 int i;
3635
3636 sh->pg_frame = MMU_SHORT_PTE_BASEADDR;
3637 sh->pg_valid = MMU_DT_PAGE;
3638 sh->contig_end = virtual_contig_end;
3639 sh->kernCbase = (u_long) kernCbase;
3640 for (i = 0; i < SUN3X_NPHYS_RAM_SEGS; i++) {
3641 spa = avail_mem[i].pmem_start;
3642 spa = m68k_trunc_page(spa);
3643 len = avail_mem[i].pmem_end - spa;
3644 len = m68k_round_page(len);
3645 sh->ram_segs[i].start = spa;
3646 sh->ram_segs[i].size = len;
3647 }
3648 }
3649
3650
3651 /* pmap_virtual_space INTERFACE
3652 **
3653 * Return the current available range of virtual addresses in the
3654 * arguuments provided. Only really called once.
3655 */
3656 void
3657 pmap_virtual_space(vstart, vend)
3658 vm_offset_t *vstart, *vend;
3659 {
3660 *vstart = virtual_avail;
3661 *vend = virtual_end;
3662 }
3663
3664 #if defined(MACHINE_NEW_NONCONTIG)
3665
3666 /*
3667 * Provide memory to the VM system.
3668 *
3669 * Assume avail_start is always in the
3670 * first segment as pmap_bootstrap does.
3671 */
3672 static void
3673 pmap_page_upload()
3674 {
3675 vm_offset_t a, b; /* memory range */
3676 int i;
3677
3678 /* Supply the memory in segments. */
3679 for (i = 0; i < SUN3X_NPHYS_RAM_SEGS; i++) {
3680 a = atop(avail_mem[i].pmem_start);
3681 b = atop(avail_mem[i].pmem_end);
3682 if (i == 0)
3683 a = atop(avail_start);
3684
3685 vm_page_physload(a, b, a, b);
3686
3687 if (avail_mem[i].pmem_next == NULL)
3688 break;
3689 }
3690 }
3691
3692 #else /* MACHINE_NEW_NONCONTIG */
3693
3694 /* pmap_free_pages INTERFACE
3695 **
3696 * Return the number of physical pages still available.
3697 *
3698 * This is probably going to be a mess, but it's only called
3699 * once and it's the only function left that I have to implement!
3700 */
3701 u_int
3702 pmap_free_pages()
3703 {
3704 int i;
3705 u_int left;
3706 vm_offset_t avail;
3707
3708 avail = avail_next;
3709 left = 0;
3710 i = 0;
3711 while (avail >= avail_mem[i].pmem_end) {
3712 if (avail_mem[i].pmem_next == NULL)
3713 return 0;
3714 i++;
3715 }
3716 while (i < SUN3X_NPHYS_RAM_SEGS) {
3717 if (avail < avail_mem[i].pmem_start) {
3718 /* Avail is inside a hole, march it
3719 * up to the next bank.
3720 */
3721 avail = avail_mem[i].pmem_start;
3722 }
3723 left += m68k_btop(avail_mem[i].pmem_end - avail);
3724 if (avail_mem[i].pmem_next == NULL)
3725 break;
3726 i++;
3727 }
3728
3729 return left;
3730 }
3731
3732 /* pmap_next_page INTERFACE
3733 **
3734 * Place the physical address of the next available page in the
3735 * argument given. Returns FALSE if there are no more pages left.
3736 *
3737 * This function must jump over any holes in physical memory.
3738 * Once this function is used, any use of pmap_bootstrap_alloc()
3739 * is a sin. Sinners will be punished with erratic behavior.
3740 */
3741 boolean_t
3742 pmap_next_page(pa)
3743 vm_offset_t *pa;
3744 {
3745 static struct pmap_physmem_struct *curbank = avail_mem;
3746
3747 /* XXX - temporary ROM saving hack. */
3748 if (avail_next >= avail_end)
3749 return FALSE;
3750
3751 if (avail_next >= curbank->pmem_end)
3752 if (curbank->pmem_next == NULL)
3753 return FALSE;
3754 else {
3755 curbank = curbank->pmem_next;
3756 avail_next = curbank->pmem_start;
3757 }
3758
3759 *pa = avail_next;
3760 avail_next += NBPG;
3761 return TRUE;
3762 }
3763
3764 #endif /* ! MACHINE_NEW_NONCONTIG */
3765
3766 /* pmap_page_index INTERFACE
3767 **
3768 * Return the index of the given physical page in a list of useable
3769 * physical pages in the system. Holes in physical memory may be counted
3770 * if so desired. As long as pmap_free_pages() and pmap_page_index()
3771 * agree as to whether holes in memory do or do not count as valid pages,
3772 * it really doesn't matter. However, if you like to save a little
3773 * memory, don't count holes as valid pages. This is even more true when
3774 * the holes are large.
3775 *
3776 * We will not count holes as valid pages. We can generate page indices
3777 * that conform to this by using the memory bank structures initialized
3778 * in pmap_alloc_pv().
3779 */
3780 int
3781 pmap_page_index(pa)
3782 vm_offset_t pa;
3783 {
3784 struct pmap_physmem_struct *bank = avail_mem;
3785 vm_offset_t off;
3786
3787 /* Search for the memory bank with this page. */
3788 /* XXX - What if it is not physical memory? */
3789 while (pa > bank->pmem_end)
3790 bank = bank->pmem_next;
3791 off = pa - bank->pmem_start;
3792
3793 return (bank->pmem_pvbase + m68k_btop(off));
3794 }
3795
3796 /* pmap_count INTERFACE
3797 **
3798 * Return the number of resident (valid) pages in the given pmap.
3799 *
3800 * Note: If this function is handed the kernel map, it will report
3801 * that it has no mappings. Hopefully the VM system won't ask for kernel
3802 * map statistics.
3803 */
3804 segsz_t
3805 pmap_count(pmap, type)
3806 pmap_t pmap;
3807 int type;
3808 {
3809 u_int count;
3810 int a_idx, b_idx;
3811 a_tmgr_t *a_tbl;
3812 b_tmgr_t *b_tbl;
3813 c_tmgr_t *c_tbl;
3814
3815 /*
3816 * If the pmap does not have its own A table manager, it has no
3817 * valid entires.
3818 */
3819 if (pmap->pm_a_tmgr == NULL)
3820 return 0;
3821
3822 a_tbl = pmap->pm_a_tmgr;
3823
3824 count = 0;
3825 for (a_idx = 0; a_idx < MMU_TIA(KERNBASE); a_idx++) {
3826 if (MMU_VALID_DT(a_tbl->at_dtbl[a_idx])) {
3827 b_tbl = mmuB2tmgr(mmu_ptov(a_tbl->at_dtbl[a_idx].addr.raw));
3828 for (b_idx = 0; b_idx < MMU_B_TBL_SIZE; b_idx++) {
3829 if (MMU_VALID_DT(b_tbl->bt_dtbl[b_idx])) {
3830 c_tbl = mmuC2tmgr(
3831 mmu_ptov(MMU_DTE_PA(b_tbl->bt_dtbl[b_idx])));
3832 if (type == 0)
3833 /*
3834 * A resident entry count has been requested.
3835 */
3836 count += c_tbl->ct_ecnt;
3837 else
3838 /*
3839 * A wired entry count has been requested.
3840 */
3841 count += c_tbl->ct_wcnt;
3842 }
3843 }
3844 }
3845 }
3846
3847 return count;
3848 }
3849
3850 /************************ SUN3 COMPATIBILITY ROUTINES ********************
3851 * The following routines are only used by DDB for tricky kernel text *
3852 * text operations in db_memrw.c. They are provided for sun3 *
3853 * compatibility. *
3854 *************************************************************************/
3855 /* get_pte INTERNAL
3856 **
3857 * Return the page descriptor the describes the kernel mapping
3858 * of the given virtual address.
3859 */
3860 extern u_long ptest_addr __P((u_long)); /* XXX: locore.s */
3861 u_int
3862 get_pte(va)
3863 vm_offset_t va;
3864 {
3865 u_long pte_pa;
3866 mmu_short_pte_t *pte;
3867
3868 /* Get the physical address of the PTE */
3869 pte_pa = ptest_addr(va & ~PGOFSET);
3870
3871 /* Convert to a virtual address... */
3872 pte = (mmu_short_pte_t *) (KERNBASE + pte_pa);
3873
3874 /* Make sure it is in our level-C tables... */
3875 if ((pte < kernCbase) ||
3876 (pte >= &mmuCbase[NUM_USER_PTES]))
3877 return 0;
3878
3879 /* ... and just return its contents. */
3880 return (pte->attr.raw);
3881 }
3882
3883
3884 /* set_pte INTERNAL
3885 **
3886 * Set the page descriptor that describes the kernel mapping
3887 * of the given virtual address.
3888 */
3889 void
3890 set_pte(va, pte)
3891 vm_offset_t va;
3892 u_int pte;
3893 {
3894 u_long idx;
3895
3896 if (va < KERNBASE)
3897 return;
3898
3899 idx = (unsigned long) m68k_btop(va - KERNBASE);
3900 kernCbase[idx].attr.raw = pte;
3901 TBIS(va);
3902 }
3903
3904 #ifdef PMAP_DEBUG
3905 /************************** DEBUGGING ROUTINES **************************
3906 * The following routines are meant to be an aid to debugging the pmap *
3907 * system. They are callable from the DDB command line and should be *
3908 * prepared to be handed unstable or incomplete states of the system. *
3909 ************************************************************************/
3910
3911 /* pv_list
3912 **
3913 * List all pages found on the pv list for the given physical page.
3914 * To avoid endless loops, the listing will stop at the end of the list
3915 * or after 'n' entries - whichever comes first.
3916 */
3917 void
3918 pv_list(pa, n)
3919 vm_offset_t pa;
3920 int n;
3921 {
3922 int idx;
3923 vm_offset_t va;
3924 pv_t *pv;
3925 c_tmgr_t *c_tbl;
3926 pmap_t pmap;
3927
3928 pv = pa2pv(pa);
3929 idx = pv->pv_idx;
3930
3931 for (;idx != PVE_EOL && n > 0;
3932 idx=pvebase[idx].pve_next, n--) {
3933
3934 va = pmap_get_pteinfo(idx, &pmap, &c_tbl);
3935 printf("idx %d, pmap 0x%x, va 0x%x, c_tbl %x\n",
3936 idx, (u_int) pmap, (u_int) va, (u_int) c_tbl);
3937 }
3938 }
3939 #endif /* PMAP_DEBUG */
3940
3941 #ifdef NOT_YET
3942 /* and maybe not ever */
3943 /************************** LOW-LEVEL ROUTINES **************************
3944 * These routines will eventualy be re-written into assembly and placed *
3945 * in locore.s. They are here now as stubs so that the pmap module can *
3946 * be linked as a standalone user program for testing. *
3947 ************************************************************************/
3948 /* flush_atc_crp INTERNAL
3949 **
3950 * Flush all page descriptors derived from the given CPU Root Pointer
3951 * (CRP), or 'A' table as it is known here, from the 68851's automatic
3952 * cache.
3953 */
3954 void
3955 flush_atc_crp(a_tbl)
3956 {
3957 mmu_long_rp_t rp;
3958
3959 /* Create a temporary root table pointer that points to the
3960 * given A table.
3961 */
3962 rp.attr.raw = ~MMU_LONG_RP_LU;
3963 rp.addr.raw = (unsigned int) a_tbl;
3964
3965 mmu_pflushr(&rp);
3966 /* mmu_pflushr:
3967 * movel sp(4)@,a0
3968 * pflushr a0@
3969 * rts
3970 */
3971 }
3972 #endif /* NOT_YET */
3973