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