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