]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/powerpc/powerpc/mmu_if.m
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / powerpc / powerpc / mmu_if.m
1 #-
2 # Copyright (c) 2005 Peter Grehan
3 # All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
8 # 1. Redistributions of source code must retain the above copyright
9 #    notice, this list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright
11 #    notice, this list of conditions and the following disclaimer in the
12 #    documentation and/or other materials provided with the distribution.
13 #
14 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 # ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 # SUCH DAMAGE.
25 #
26 # $FreeBSD$
27 #
28
29 #include <sys/param.h>
30 #include <sys/lock.h>
31 #include <sys/mutex.h>
32 #include <sys/systm.h>
33
34 #include <vm/vm.h>
35 #include <vm/vm_page.h>
36
37 #include <machine/mmuvar.h>
38
39 /**
40  * @defgroup MMU mmu - KObj methods for PowerPC MMU implementations
41  * @brief A set of methods required by all MMU implementations. These
42  * are basically direct call-thru's from the pmap machine-dependent
43  * code.
44  * Thanks to Bruce M Simpson's pmap man pages for routine descriptions.
45  *@{
46  */
47
48 INTERFACE mmu;
49
50 #
51 # Default implementations of some methods
52 #
53 CODE {
54         static void mmu_null_copy(mmu_t mmu, pmap_t dst_pmap, pmap_t src_pmap,
55             vm_offset_t dst_addr, vm_size_t len, vm_offset_t src_addr)
56         {
57                 return;
58         }
59
60         static void mmu_null_growkernel(mmu_t mmu, vm_offset_t addr)
61         {
62                 return;
63         }
64
65         static void mmu_null_init(mmu_t mmu)
66         {
67                 return;
68         }
69
70         static boolean_t mmu_null_is_prefaultable(mmu_t mmu, pmap_t pmap,
71             vm_offset_t va)
72         {
73                 return (FALSE);
74         }
75
76         static void mmu_null_object_init_pt(mmu_t mmu, pmap_t pmap,
77             vm_offset_t addr, vm_object_t object, vm_pindex_t index,
78             vm_size_t size)
79         {
80                 return;
81         }
82
83         static void mmu_null_page_init(mmu_t mmu, vm_page_t m)
84         {
85                 return;
86         }
87
88         static void mmu_null_remove_pages(mmu_t mmu, pmap_t pmap)
89         {
90                 return;
91         }
92
93         static int mmu_null_mincore(mmu_t mmu, pmap_t pmap, vm_offset_t addr,
94             vm_paddr_t *locked_pa)
95         {
96                 return (0);
97         }
98
99         static void mmu_null_deactivate(struct thread *td)
100         {
101                 return;
102         }
103
104         static void mmu_null_align_superpage(mmu_t mmu, vm_object_t object,
105             vm_ooffset_t offset, vm_offset_t *addr, vm_size_t size)
106         {
107                 return;
108         }
109
110         static struct pmap_md *mmu_null_scan_md(mmu_t mmu, struct pmap_md *p)
111         {
112                 return (NULL);
113         }
114
115         static void *mmu_null_mapdev_attr(mmu_t mmu, vm_offset_t pa,
116             vm_size_t size, vm_memattr_t ma)
117         {
118                 return MMU_MAPDEV(mmu, pa, size);
119         }
120
121         static void mmu_null_kenter_attr(mmu_t mmu, vm_offset_t va,
122             vm_offset_t pa, vm_memattr_t ma)
123         {
124                 MMU_KENTER(mmu, va, pa);
125         }
126
127         static void mmu_null_page_set_memattr(mmu_t mmu, vm_page_t m,
128             vm_memattr_t ma)
129         {
130                 return;
131         }
132 };
133
134
135 /**
136  * @brief Change the wiring attribute for the page in the given physical
137  * map and virtual address.
138  *
139  * @param _pmap         physical map of page
140  * @param _va           page virtual address
141  * @param _wired        TRUE to increment wired count, FALSE to decrement
142  */
143 METHOD void change_wiring {
144         mmu_t           _mmu;
145         pmap_t          _pmap;
146         vm_offset_t     _va;
147         boolean_t       _wired;
148 };
149
150
151 /**
152  * @brief Clear the 'modified' bit on the given physical page
153  *
154  * @param _pg           physical page
155  */
156 METHOD void clear_modify {
157         mmu_t           _mmu;
158         vm_page_t       _pg;
159 };
160
161
162 /**
163  * @brief Clear the 'referenced' bit on the given physical page
164  *
165  * @param _pg           physical page
166  */
167 METHOD void clear_reference {
168         mmu_t           _mmu;
169         vm_page_t       _pg;
170 };
171
172
173 /**
174  * @brief Clear the write and modified bits in each of the given
175  * physical page's mappings
176  *
177  * @param _pg           physical page
178  */
179 METHOD void remove_write {
180         mmu_t           _mmu;
181         vm_page_t       _pg;
182 };
183
184
185 /**
186  * @brief Copy the address range given by the source physical map, virtual
187  * address and length to the destination physical map and virtual address.
188  * This routine is optional (xxx default null implementation ?)
189  *
190  * @param _dst_pmap     destination physical map
191  * @param _src_pmap     source physical map
192  * @param _dst_addr     destination virtual address
193  * @param _len          size of range
194  * @param _src_addr     source virtual address
195  */
196 METHOD void copy {
197         mmu_t           _mmu;
198         pmap_t          _dst_pmap;
199         pmap_t          _src_pmap;
200         vm_offset_t     _dst_addr;
201         vm_size_t       _len;
202         vm_offset_t     _src_addr;
203 } DEFAULT mmu_null_copy;
204
205
206 /**
207  * @brief Copy the source physical page to the destination physical page
208  *
209  * @param _src          source physical page
210  * @param _dst          destination physical page
211  */
212 METHOD void copy_page {
213         mmu_t           _mmu;
214         vm_page_t       _src;
215         vm_page_t       _dst;
216 };
217
218 METHOD void copy_pages {
219         mmu_t           _mmu;
220         vm_page_t       *_ma;
221         vm_offset_t     _a_offset;
222         vm_page_t       *_mb;
223         vm_offset_t     _b_offset;
224         int             _xfersize;
225 };
226
227 /**
228  * @brief Create a mapping between a virtual/physical address pair in the
229  * passed physical map with the specified protection and wiring
230  *
231  * @param _pmap         physical map
232  * @param _va           mapping virtual address
233  * @param _p            mapping physical page
234  * @param _prot         mapping page protection
235  * @param _wired        TRUE if page will be wired
236  */
237 METHOD void enter {
238         mmu_t           _mmu;
239         pmap_t          _pmap;
240         vm_offset_t     _va;
241         vm_page_t       _p;
242         vm_prot_t       _prot;
243         boolean_t       _wired;
244 };
245
246
247 /**
248  * @brief Maps a sequence of resident pages belonging to the same object.
249  *
250  * @param _pmap         physical map
251  * @param _start        virtual range start
252  * @param _end          virtual range end
253  * @param _m_start      physical page mapped at start
254  * @param _prot         mapping page protection
255  */
256 METHOD void enter_object {
257         mmu_t           _mmu;
258         pmap_t          _pmap;
259         vm_offset_t     _start;
260         vm_offset_t     _end;
261         vm_page_t       _m_start;
262         vm_prot_t       _prot;
263 };
264
265
266 /**
267  * @brief A faster entry point for page mapping where it is possible
268  * to short-circuit some of the tests in pmap_enter.
269  *
270  * @param _pmap         physical map (and also currently active pmap)
271  * @param _va           mapping virtual address
272  * @param _pg           mapping physical page
273  * @param _prot         new page protection - used to see if page is exec.
274  */
275 METHOD void enter_quick {
276         mmu_t           _mmu;
277         pmap_t          _pmap;
278         vm_offset_t     _va;
279         vm_page_t       _pg;
280         vm_prot_t       _prot;
281 };
282
283
284 /**
285  * @brief Reverse map the given virtual address, returning the physical
286  * page associated with the address if a mapping exists.
287  *
288  * @param _pmap         physical map
289  * @param _va           mapping virtual address
290  *
291  * @retval 0            No mapping found
292  * @retval addr         The mapping physical address
293  */
294 METHOD vm_paddr_t extract {
295         mmu_t           _mmu;
296         pmap_t          _pmap;
297         vm_offset_t     _va;
298 };
299
300
301 /**
302  * @brief Reverse map the given virtual address, returning the
303  * physical page if found. The page must be held (by calling
304  * vm_page_hold) if the page protection matches the given protection
305  *
306  * @param _pmap         physical map
307  * @param _va           mapping virtual address
308  * @param _prot         protection used to determine if physical page
309  *                      should be locked
310  *
311  * @retval NULL         No mapping found
312  * @retval page         Pointer to physical page. Held if protections match
313  */
314 METHOD vm_page_t extract_and_hold {
315         mmu_t           _mmu;
316         pmap_t          _pmap;
317         vm_offset_t     _va;
318         vm_prot_t       _prot;
319 };
320
321
322 /**
323  * @brief Increase kernel virtual address space to the given virtual address.
324  * Not really required for PowerPC, so optional unless the MMU implementation
325  * can use it.
326  *
327  * @param _va           new upper limit for kernel virtual address space
328  */
329 METHOD void growkernel {
330         mmu_t           _mmu;
331         vm_offset_t     _va;
332 } DEFAULT mmu_null_growkernel;
333
334
335 /**
336  * @brief Called from vm_mem_init. Zone allocation is available at
337  * this stage so a convenient time to create zones. This routine is
338  * for MMU-implementation convenience and is optional.
339  */
340 METHOD void init {
341         mmu_t           _mmu;
342 } DEFAULT mmu_null_init;
343
344
345 /**
346  * @brief Return if the page has been marked by MMU hardware to have been
347  * modified
348  *
349  * @param _pg           physical page to test
350  *
351  * @retval boolean      TRUE if page has been modified
352  */
353 METHOD boolean_t is_modified {
354         mmu_t           _mmu;
355         vm_page_t       _pg;
356 };
357
358
359 /**
360  * @brief Return whether the specified virtual address is a candidate to be
361  * prefaulted in. This routine is optional.
362  *
363  * @param _pmap         physical map
364  * @param _va           virtual address to test
365  *
366  * @retval boolean      TRUE if the address is a candidate.
367  */
368 METHOD boolean_t is_prefaultable {
369         mmu_t           _mmu;
370         pmap_t          _pmap;
371         vm_offset_t     _va;
372 } DEFAULT mmu_null_is_prefaultable;
373
374
375 /**
376  * @brief Return whether or not the specified physical page was referenced
377  * in any physical maps.
378  *
379  * @params _pg          physical page
380  *
381  * @retval boolean      TRUE if page has been referenced
382  */
383 METHOD boolean_t is_referenced {
384         mmu_t           _mmu;
385         vm_page_t       _pg;
386 };
387
388
389 /**
390  * @brief Return a count of referenced bits for a page, clearing those bits.
391  * Not all referenced bits need to be cleared, but it is necessary that 0
392  * only be returned when there are none set.
393  *
394  * @params _m           physical page
395  *
396  * @retval int          count of referenced bits
397  */
398 METHOD boolean_t ts_referenced {
399         mmu_t           _mmu;
400         vm_page_t       _pg;
401 };
402
403
404 /**
405  * @brief Map the requested physical address range into kernel virtual
406  * address space. The value in _virt is taken as a hint. The virtual
407  * address of the range is returned, or NULL if the mapping could not
408  * be created. The range can be direct-mapped if that is supported.
409  *
410  * @param *_virt        Hint for start virtual address, and also return
411  *                      value
412  * @param _start        physical address range start
413  * @param _end          physical address range end
414  * @param _prot         protection of range (currently ignored)
415  *
416  * @retval NULL         could not map the area
417  * @retval addr, *_virt mapping start virtual address
418  */
419 METHOD vm_offset_t map {
420         mmu_t           _mmu;
421         vm_offset_t     *_virt;
422         vm_paddr_t      _start;
423         vm_paddr_t      _end;
424         int             _prot;
425 };
426
427
428 /**
429  * @brief Used to create a contiguous set of read-only mappings for a
430  * given object to try and eliminate a cascade of on-demand faults as
431  * the object is accessed sequentially. This routine is optional.
432  *
433  * @param _pmap         physical map
434  * @param _addr         mapping start virtual address
435  * @param _object       device-backed V.M. object to be mapped
436  * @param _pindex       page-index within object of mapping start
437  * @param _size         size in bytes of mapping
438  */
439 METHOD void object_init_pt {
440         mmu_t           _mmu;
441         pmap_t          _pmap;
442         vm_offset_t     _addr;
443         vm_object_t     _object;
444         vm_pindex_t     _pindex;
445         vm_size_t       _size;
446 } DEFAULT mmu_null_object_init_pt;
447
448
449 /**
450  * @brief Used to determine if the specified page has a mapping for the
451  * given physical map, by scanning the list of reverse-mappings from the
452  * page. The list is scanned to a maximum of 16 entries.
453  *
454  * @param _pmap         physical map
455  * @param _pg           physical page
456  *
457  * @retval bool         TRUE if the physical map was found in the first 16
458  *                      reverse-map list entries off the physical page.
459  */
460 METHOD boolean_t page_exists_quick {
461         mmu_t           _mmu;
462         pmap_t          _pmap;
463         vm_page_t       _pg;
464 };
465
466
467 /**
468  * @brief Initialise the machine-dependent section of the physical page
469  * data structure. This routine is optional.
470  *
471  * @param _pg           physical page
472  */
473 METHOD void page_init {
474         mmu_t           _mmu;
475         vm_page_t       _pg;
476 } DEFAULT mmu_null_page_init;
477
478
479 /**
480  * @brief Count the number of managed mappings to the given physical
481  * page that are wired.
482  *
483  * @param _pg           physical page
484  *
485  * @retval int          the number of wired, managed mappings to the
486  *                      given physical page
487  */
488 METHOD int page_wired_mappings {
489         mmu_t           _mmu;
490         vm_page_t       _pg;
491 };
492
493
494 /**
495  * @brief Initialise a physical map data structure
496  *
497  * @param _pmap         physical map
498  */
499 METHOD void pinit {
500         mmu_t           _mmu;
501         pmap_t          _pmap;
502 };
503
504
505 /**
506  * @brief Initialise the physical map for process 0, the initial process
507  * in the system.
508  * XXX default to pinit ?
509  *
510  * @param _pmap         physical map
511  */
512 METHOD void pinit0 {
513         mmu_t           _mmu;
514         pmap_t          _pmap;
515 };
516
517
518 /**
519  * @brief Set the protection for physical pages in the given virtual address
520  * range to the given value.
521  *
522  * @param _pmap         physical map
523  * @param _start        virtual range start
524  * @param _end          virtual range end
525  * @param _prot         new page protection
526  */
527 METHOD void protect {
528         mmu_t           _mmu;
529         pmap_t          _pmap;
530         vm_offset_t     _start;
531         vm_offset_t     _end;
532         vm_prot_t       _prot;
533 };
534
535
536 /**
537  * @brief Create a mapping in kernel virtual address space for the given array
538  * of wired physical pages.
539  *
540  * @param _start        mapping virtual address start
541  * @param *_m           array of physical page pointers
542  * @param _count        array elements
543  */
544 METHOD void qenter {
545         mmu_t           _mmu;
546         vm_offset_t     _start;
547         vm_page_t       *_pg;
548         int             _count;
549 };
550
551
552 /**
553  * @brief Remove the temporary mappings created by qenter.
554  *
555  * @param _start        mapping virtual address start
556  * @param _count        number of pages in mapping
557  */
558 METHOD void qremove {
559         mmu_t           _mmu;
560         vm_offset_t     _start;
561         int             _count;
562 };
563
564
565 /**
566  * @brief Release per-pmap resources, e.g. mutexes, allocated memory etc. There
567  * should be no existing mappings for the physical map at this point
568  *
569  * @param _pmap         physical map
570  */
571 METHOD void release {
572         mmu_t           _mmu;
573         pmap_t          _pmap;
574 };
575
576
577 /**
578  * @brief Remove all mappings in the given physical map for the start/end
579  * virtual address range. The range will be page-aligned.
580  *
581  * @param _pmap         physical map
582  * @param _start        mapping virtual address start
583  * @param _end          mapping virtual address end
584  */
585 METHOD void remove {
586         mmu_t           _mmu;
587         pmap_t          _pmap;
588         vm_offset_t     _start;
589         vm_offset_t     _end;
590 };
591
592
593 /**
594  * @brief Traverse the reverse-map list off the given physical page and
595  * remove all mappings. Clear the PGA_WRITEABLE attribute from the page.
596  *
597  * @param _pg           physical page
598  */
599 METHOD void remove_all {
600         mmu_t           _mmu;
601         vm_page_t       _pg;
602 };
603
604
605 /**
606  * @brief Remove all mappings in the given start/end virtual address range
607  * for the given physical map. Similar to the remove method, but it used
608  * when tearing down all mappings in an address space. This method is
609  * optional, since pmap_remove will be called for each valid vm_map in
610  * the address space later.
611  *
612  * @param _pmap         physical map
613  * @param _start        mapping virtual address start
614  * @param _end          mapping virtual address end
615  */
616 METHOD void remove_pages {
617         mmu_t           _mmu;
618         pmap_t          _pmap;
619 } DEFAULT mmu_null_remove_pages;
620
621
622 /**
623  * @brief Zero a physical page. It is not assumed that the page is mapped,
624  * so a temporary (or direct) mapping may need to be used.
625  *
626  * @param _pg           physical page
627  */
628 METHOD void zero_page {
629         mmu_t           _mmu;
630         vm_page_t       _pg;
631 };
632
633
634 /**
635  * @brief Zero a portion of a physical page, starting at a given offset and
636  * for a given size (multiples of 512 bytes for 4k pages).
637  *
638  * @param _pg           physical page
639  * @param _off          byte offset from start of page
640  * @param _size         size of area to zero
641  */
642 METHOD void zero_page_area {
643         mmu_t           _mmu;
644         vm_page_t       _pg;
645         int             _off;
646         int             _size;
647 };
648
649
650 /**
651  * @brief Called from the idle loop to zero pages. XXX I think locking
652  * constraints might be different here compared to zero_page.
653  *
654  * @param _pg           physical page
655  */
656 METHOD void zero_page_idle {
657         mmu_t           _mmu;
658         vm_page_t       _pg;
659 };
660
661
662 /**
663  * @brief Extract mincore(2) information from a mapping.
664  *
665  * @param _pmap         physical map
666  * @param _addr         page virtual address
667  * @param _locked_pa    page physical address
668  *
669  * @retval 0            no result
670  * @retval non-zero     mincore(2) flag values
671  */
672 METHOD int mincore {
673         mmu_t           _mmu;
674         pmap_t          _pmap;
675         vm_offset_t     _addr;
676         vm_paddr_t      *_locked_pa;
677 } DEFAULT mmu_null_mincore;
678
679
680 /**
681  * @brief Perform any operations required to allow a physical map to be used
682  * before it's address space is accessed.
683  *
684  * @param _td           thread associated with physical map
685  */
686 METHOD void activate {
687         mmu_t           _mmu;
688         struct thread   *_td;
689 };
690
691 /**
692  * @brief Perform any operations required to deactivate a physical map,
693  * for instance as it is context-switched out.
694  *
695  * @param _td           thread associated with physical map
696  */
697 METHOD void deactivate {
698         mmu_t           _mmu;
699         struct thread   *_td;
700 } DEFAULT mmu_null_deactivate;
701
702 /**
703  * @brief Return a hint for the best virtual address to map a tentative
704  * virtual address range in a given VM object. The default is to just
705  * return the given tentative start address.
706  *
707  * @param _obj          VM backing object
708  * @param _offset       starting offset with the VM object
709  * @param _addr         initial guess at virtual address
710  * @param _size         size of virtual address range
711  */
712 METHOD void align_superpage {
713         mmu_t           _mmu;
714         vm_object_t     _obj;
715         vm_ooffset_t    _offset;
716         vm_offset_t     *_addr;
717         vm_size_t       _size;
718 } DEFAULT mmu_null_align_superpage;
719
720
721
722
723 /**
724  * INTERNAL INTERFACES
725  */
726
727 /**
728  * @brief Bootstrap the VM system. At the completion of this routine, the
729  * kernel will be running in it's own address space with full control over
730  * paging.
731  *
732  * @param _start        start of reserved memory (obsolete ???)
733  * @param _end          end of reserved memory (obsolete ???)
734  *                      XXX I think the intent of these was to allow
735  *                      the memory used by kernel text+data+bss and
736  *                      loader variables/load-time kld's to be carved out
737  *                      of available physical mem.
738  *
739  */
740 METHOD void bootstrap {
741         mmu_t           _mmu;
742         vm_offset_t     _start;
743         vm_offset_t     _end;
744 };
745
746 /**
747  * @brief Set up the MMU on the current CPU. Only called by the PMAP layer
748  * for alternate CPUs on SMP systems.
749  *
750  * @param _ap           Set to 1 if the CPU being set up is an AP
751  *
752  */
753 METHOD void cpu_bootstrap {
754         mmu_t           _mmu;
755         int             _ap;
756 };
757
758
759 /**
760  * @brief Create a kernel mapping for a given physical address range.
761  * Called by bus code on behalf of device drivers. The mapping does not
762  * have to be a virtual address: it can be a direct-mapped physical address
763  * if that is supported by the MMU.
764  *
765  * @param _pa           start physical address
766  * @param _size         size in bytes of mapping
767  *
768  * @retval addr         address of mapping.
769  */
770 METHOD void * mapdev {
771         mmu_t           _mmu;
772         vm_offset_t     _pa;
773         vm_size_t       _size;
774 };
775
776 /**
777  * @brief Create a kernel mapping for a given physical address range.
778  * Called by bus code on behalf of device drivers. The mapping does not
779  * have to be a virtual address: it can be a direct-mapped physical address
780  * if that is supported by the MMU.
781  *
782  * @param _pa           start physical address
783  * @param _size         size in bytes of mapping
784  * @param _attr         cache attributes
785  *
786  * @retval addr         address of mapping.
787  */
788 METHOD void * mapdev_attr {
789         mmu_t           _mmu;
790         vm_offset_t     _pa;
791         vm_size_t       _size;
792         vm_memattr_t    _attr;
793 } DEFAULT mmu_null_mapdev_attr;
794
795 /**
796  * @brief Change cache control attributes for a page. Should modify all
797  * mappings for that page.
798  *
799  * @param _m            page to modify
800  * @param _ma           new cache control attributes
801  */
802 METHOD void page_set_memattr {
803         mmu_t           _mmu;
804         vm_page_t       _pg;
805         vm_memattr_t    _ma;
806 } DEFAULT mmu_null_page_set_memattr;
807
808 /**
809  * @brief Remove the mapping created by mapdev. Called when a driver
810  * is unloaded.
811  *
812  * @param _va           Mapping address returned from mapdev
813  * @param _size         size in bytes of mapping
814  */
815 METHOD void unmapdev {
816         mmu_t           _mmu;
817         vm_offset_t     _va;
818         vm_size_t       _size;
819 };
820
821
822 /**
823  * @brief Reverse-map a kernel virtual address
824  *
825  * @param _va           kernel virtual address to reverse-map
826  *
827  * @retval pa           physical address corresponding to mapping
828  */
829 METHOD vm_offset_t kextract {
830         mmu_t           _mmu;
831         vm_offset_t     _va;
832 };
833
834
835 /**
836  * @brief Map a wired page into kernel virtual address space
837  *
838  * @param _va           mapping virtual address
839  * @param _pa           mapping physical address
840  */
841 METHOD void kenter {
842         mmu_t           _mmu;
843         vm_offset_t     _va;
844         vm_offset_t     _pa;
845 };
846
847 /**
848  * @brief Map a wired page into kernel virtual address space
849  *
850  * @param _va           mapping virtual address
851  * @param _pa           mapping physical address
852  * @param _ma           mapping cache control attributes
853  */
854 METHOD void kenter_attr {
855         mmu_t           _mmu;
856         vm_offset_t     _va;
857         vm_offset_t     _pa;
858         vm_memattr_t    _ma;
859 } DEFAULT mmu_null_kenter_attr;
860
861 /**
862  * @brief Determine if the given physical address range has been direct-mapped.
863  *
864  * @param _pa           physical address start
865  * @param _size         physical address range size
866  *
867  * @retval bool         TRUE if the range is direct-mapped.
868  */
869 METHOD boolean_t dev_direct_mapped {
870         mmu_t           _mmu;
871         vm_offset_t     _pa;
872         vm_size_t       _size;
873 };
874
875
876 /**
877  * @brief Enforce instruction cache coherency. Typically called after a
878  * region of memory has been modified and before execution of or within
879  * that region is attempted. Setting breakpoints in a process through
880  * ptrace(2) is one example of when the instruction cache needs to be
881  * made coherent.
882  *
883  * @param _pm           the physical map of the virtual address
884  * @param _va           the virtual address of the modified region
885  * @param _sz           the size of the modified region
886  */
887 METHOD void sync_icache {
888         mmu_t           _mmu;
889         pmap_t          _pm;
890         vm_offset_t     _va;
891         vm_size_t       _sz;
892 };
893
894
895 /**
896  * @brief Create temporary memory mapping for use by dumpsys().
897  *
898  * @param _md           The memory chunk in which the mapping lies.
899  * @param _ofs          The offset within the chunk of the mapping.
900  * @param _sz           The requested size of the mapping.
901  *
902  * @retval vm_offset_t  The virtual address of the mapping.
903  *                      
904  * The sz argument is modified to reflect the actual size of the
905  * mapping.
906  */
907 METHOD vm_offset_t dumpsys_map {
908         mmu_t           _mmu;
909         struct pmap_md  *_md;
910         vm_size_t       _ofs;
911         vm_size_t       *_sz;
912 };
913
914
915 /**
916  * @brief Remove temporary dumpsys() mapping.
917  *
918  * @param _md           The memory chunk in which the mapping lies.
919  * @param _ofs          The offset within the chunk of the mapping.
920  * @param _va           The virtual address of the mapping.
921  */
922 METHOD void dumpsys_unmap {
923         mmu_t           _mmu;
924         struct pmap_md  *_md;
925         vm_size_t       _ofs;
926         vm_offset_t     _va;
927 };
928
929
930 /**
931  * @brief Scan/iterate memory chunks.
932  *
933  * @param _prev         The previously returned chunk or NULL.
934  *
935  * @retval              The next (or first when _prev is NULL) chunk.
936  */
937 METHOD struct pmap_md * scan_md {
938         mmu_t           _mmu;
939         struct pmap_md  *_prev;
940 } DEFAULT mmu_null_scan_md;