2 * Copyright 2014 Svatopluk Kraus <onwahe@gmail.com>
3 * Copyright 2014 Michal Meloun <meloun@miracle.cz>
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 #ifndef _MACHINE_PMAP_VAR_H_
29 #define _MACHINE_PMAP_VAR_H_
31 #include <machine/pte.h>
34 * Various PMAP defines, exports, and inline functions
35 * definitions also usable in other MD code.
38 /* A number of pages in L1 page table. */
39 #define NPG_IN_PT1 (NB_IN_PT1 / PAGE_SIZE)
41 /* A number of L2 page tables in a page. */
42 #define NPT2_IN_PG (PAGE_SIZE / NB_IN_PT2)
44 /* A number of L2 page table entries in a page. */
45 #define NPTE2_IN_PG (NPT2_IN_PG * NPTE2_IN_PT2)
50 * A L2 page tables page contains NPT2_IN_PG L2 page tables. Masking of
51 * pte1_idx by PT2PG_MASK gives us an index to associated L2 page table
52 * in a page. The PT2PG_SHIFT definition depends on NPT2_IN_PG strictly.
53 * I.e., (1 << PT2PG_SHIFT) == NPT2_IN_PG must be fulfilled.
56 #define PT2PG_MASK ((1 << PT2PG_SHIFT) - 1)
59 * A PT2TAB holds all allocated L2 page table pages in a pmap.
60 * Right shifting of virtual address by PT2TAB_SHIFT gives us an index
61 * to L2 page table page in PT2TAB which holds the address mapping.
63 #define PT2TAB_ENTRIES (NPTE1_IN_PT1 / NPT2_IN_PG)
64 #define PT2TAB_SHIFT (PTE1_SHIFT + PT2PG_SHIFT)
67 * All allocated L2 page table pages in a pmap are mapped into PT2MAP space.
68 * An virtual address right shifting by PT2MAP_SHIFT gives us an index to PTE2
69 * which maps the address.
71 #define PT2MAP_SIZE (NPTE1_IN_PT1 * NB_IN_PT2)
72 #define PT2MAP_SHIFT PTE2_SHIFT
74 extern pt1_entry_t *kern_pt1;
75 extern pt2_entry_t *kern_pt2tab;
76 extern pt2_entry_t *PT2MAP;
79 * Virtual interface for L1 page table management.
83 pte1_index(vm_offset_t va)
86 return (va >> PTE1_SHIFT);
89 static __inline pt1_entry_t *
90 pte1_ptr(pt1_entry_t *pt1, vm_offset_t va)
93 return (pt1 + pte1_index(va));
96 static __inline vm_offset_t
97 pte1_trunc(vm_offset_t va)
100 return (va & PTE1_FRAME);
103 static __inline vm_offset_t
104 pte1_roundup(vm_offset_t va)
107 return ((va + PTE1_OFFSET) & PTE1_FRAME);
111 * Virtual interface for L1 page table entries management.
113 * XXX: Some of the following functions now with a synchronization barrier
114 * are called in a loop, so it could be useful to have two versions of them.
115 * One with the barrier and one without the barrier. In this case, pure
116 * barrier pte1_sync() should be implemented as well.
119 pte1_sync(pt1_entry_t *pte1p)
123 #ifndef PMAP_PTE_NOCACHE
124 if (!cpuinfo.coherent_walk)
125 dcache_wb_pou((vm_offset_t)pte1p, sizeof(*pte1p));
130 pte1_sync_range(pt1_entry_t *pte1p, vm_size_t size)
134 #ifndef PMAP_PTE_NOCACHE
135 if (!cpuinfo.coherent_walk)
136 dcache_wb_pou((vm_offset_t)pte1p, size);
141 pte1_store(pt1_entry_t *pte1p, pt1_entry_t pte1)
150 pte1_clear(pt1_entry_t *pte1p)
153 pte1_store(pte1p, 0);
157 pte1_clear_bit(pt1_entry_t *pte1p, uint32_t bit)
164 static __inline boolean_t
165 pte1_is_link(pt1_entry_t pte1)
168 return ((pte1 & L1_TYPE_MASK) == L1_TYPE_C);
172 pte1_is_section(pt1_entry_t pte1)
175 return ((pte1 & L1_TYPE_MASK) == L1_TYPE_S);
178 static __inline boolean_t
179 pte1_is_dirty(pt1_entry_t pte1)
182 return ((pte1 & (PTE1_NM | PTE1_RO)) == 0);
185 static __inline boolean_t
186 pte1_is_global(pt1_entry_t pte1)
189 return ((pte1 & PTE1_NG) == 0);
192 static __inline boolean_t
193 pte1_is_valid(pt1_entry_t pte1)
197 l1_type = pte1 & L1_TYPE_MASK;
198 return ((l1_type == L1_TYPE_C) || (l1_type == L1_TYPE_S));
201 static __inline boolean_t
202 pte1_is_wired(pt1_entry_t pte1)
205 return (pte1 & PTE1_W);
208 static __inline pt1_entry_t
209 pte1_load(pt1_entry_t *pte1p)
217 static __inline pt1_entry_t
218 pte1_load_clear(pt1_entry_t *pte1p)
229 pte1_set_bit(pt1_entry_t *pte1p, uint32_t bit)
236 static __inline vm_paddr_t
237 pte1_pa(pt1_entry_t pte1)
240 return ((vm_paddr_t)(pte1 & PTE1_FRAME));
243 static __inline vm_paddr_t
244 pte1_link_pa(pt1_entry_t pte1)
247 return ((vm_paddr_t)(pte1 & L1_C_ADDR_MASK));
251 * Virtual interface for L2 page table entries management.
253 * XXX: Some of the following functions now with a synchronization barrier
254 * are called in a loop, so it could be useful to have two versions of them.
255 * One with the barrier and one without the barrier.
259 pte2_sync(pt2_entry_t *pte2p)
263 #ifndef PMAP_PTE_NOCACHE
264 if (!cpuinfo.coherent_walk)
265 dcache_wb_pou((vm_offset_t)pte2p, sizeof(*pte2p));
270 pte2_sync_range(pt2_entry_t *pte2p, vm_size_t size)
274 #ifndef PMAP_PTE_NOCACHE
275 if (!cpuinfo.coherent_walk)
276 dcache_wb_pou((vm_offset_t)pte2p, size);
281 pte2_store(pt2_entry_t *pte2p, pt2_entry_t pte2)
290 pte2_clear(pt2_entry_t *pte2p)
293 pte2_store(pte2p, 0);
297 pte2_clear_bit(pt2_entry_t *pte2p, uint32_t bit)
304 static __inline boolean_t
305 pte2_is_dirty(pt2_entry_t pte2)
308 return ((pte2 & (PTE2_NM | PTE2_RO)) == 0);
311 static __inline boolean_t
312 pte2_is_global(pt2_entry_t pte2)
315 return ((pte2 & PTE2_NG) == 0);
318 static __inline boolean_t
319 pte2_is_valid(pt2_entry_t pte2)
322 return (pte2 & PTE2_V);
325 static __inline boolean_t
326 pte2_is_wired(pt2_entry_t pte2)
329 return (pte2 & PTE2_W);
332 static __inline pt2_entry_t
333 pte2_load(pt2_entry_t *pte2p)
341 static __inline pt2_entry_t
342 pte2_load_clear(pt2_entry_t *pte2p)
353 pte2_set_bit(pt2_entry_t *pte2p, uint32_t bit)
361 pte2_set_wired(pt2_entry_t *pte2p, boolean_t wired)
365 * Wired bit is transparent for page table walk,
366 * so pte2_sync() is not needed.
374 static __inline vm_paddr_t
375 pte2_pa(pt2_entry_t pte2)
378 return ((vm_paddr_t)(pte2 & PTE2_FRAME));
381 static __inline u_int
382 pte2_attr(pt2_entry_t pte2)
385 return ((u_int)(pte2 & PTE2_ATTR_MASK));
389 * Virtual interface for L2 page tables mapping management.
392 static __inline u_int
393 pt2tab_index(vm_offset_t va)
396 return (va >> PT2TAB_SHIFT);
399 static __inline pt2_entry_t *
400 pt2tab_entry(pt2_entry_t *pt2tab, vm_offset_t va)
403 return (pt2tab + pt2tab_index(va));
407 pt2tab_store(pt2_entry_t *pte2p, pt2_entry_t pte2)
410 pte2_store(pte2p,pte2);
413 static __inline pt2_entry_t
414 pt2tab_load(pt2_entry_t *pte2p)
417 return (pte2_load(pte2p));
420 static __inline pt2_entry_t
421 pt2tab_load_clear(pt2_entry_t *pte2p)
424 return (pte2_load_clear(pte2p));
427 static __inline u_int
428 pt2map_index(vm_offset_t va)
431 return (va >> PT2MAP_SHIFT);
434 static __inline pt2_entry_t *
435 pt2map_entry(vm_offset_t va)
438 return (PT2MAP + pt2map_index(va));
442 * Virtual interface for pmap structure & kernel shortcuts.
445 static __inline pt1_entry_t *
446 pmap_pte1(pmap_t pmap, vm_offset_t va)
449 return (pte1_ptr(pmap->pm_pt1, va));
452 static __inline pt1_entry_t *
453 kern_pte1(vm_offset_t va)
456 return (pte1_ptr(kern_pt1, va));
459 static __inline pt2_entry_t *
460 pmap_pt2tab_entry(pmap_t pmap, vm_offset_t va)
463 return (pt2tab_entry(pmap->pm_pt2tab, va));
466 static __inline pt2_entry_t *
467 kern_pt2tab_entry(vm_offset_t va)
470 return (pt2tab_entry(kern_pt2tab, va));
473 static __inline vm_page_t
474 pmap_pt2_page(pmap_t pmap, vm_offset_t va)
478 pte2 = pte2_load(pmap_pt2tab_entry(pmap, va));
479 return (PHYS_TO_VM_PAGE(pte2 & PTE2_FRAME));
482 static __inline vm_page_t
483 kern_pt2_page(vm_offset_t va)
487 pte2 = pte2_load(kern_pt2tab_entry(va));
488 return (PHYS_TO_VM_PAGE(pte2 & PTE2_FRAME));
492 #endif /* !_MACHINE_PMAP_VAR_H_ */