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