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