1*0a6a1f1dSLionel Sambuc /* $NetBSD: pmap.h,v 1.56 2015/04/03 01:04:23 riastradh Exp $ */
21cd76c75SBen Gras
31cd76c75SBen Gras /*
41cd76c75SBen Gras * Copyright (c) 1997 Charles D. Cranor and Washington University.
51cd76c75SBen Gras * All rights reserved.
61cd76c75SBen Gras *
71cd76c75SBen Gras * Redistribution and use in source and binary forms, with or without
81cd76c75SBen Gras * modification, are permitted provided that the following conditions
91cd76c75SBen Gras * are met:
101cd76c75SBen Gras * 1. Redistributions of source code must retain the above copyright
111cd76c75SBen Gras * notice, this list of conditions and the following disclaimer.
121cd76c75SBen Gras * 2. Redistributions in binary form must reproduce the above copyright
131cd76c75SBen Gras * notice, this list of conditions and the following disclaimer in the
141cd76c75SBen Gras * documentation and/or other materials provided with the distribution.
151cd76c75SBen Gras *
161cd76c75SBen Gras * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
171cd76c75SBen Gras * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
181cd76c75SBen Gras * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
191cd76c75SBen Gras * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
201cd76c75SBen Gras * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
211cd76c75SBen Gras * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
221cd76c75SBen Gras * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
231cd76c75SBen Gras * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
241cd76c75SBen Gras * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
251cd76c75SBen Gras * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
261cd76c75SBen Gras */
271cd76c75SBen Gras
281cd76c75SBen Gras /*
291cd76c75SBen Gras * Copyright (c) 2001 Wasabi Systems, Inc.
301cd76c75SBen Gras * All rights reserved.
311cd76c75SBen Gras *
321cd76c75SBen Gras * Written by Frank van der Linden for Wasabi Systems, Inc.
331cd76c75SBen Gras *
341cd76c75SBen Gras * Redistribution and use in source and binary forms, with or without
351cd76c75SBen Gras * modification, are permitted provided that the following conditions
361cd76c75SBen Gras * are met:
371cd76c75SBen Gras * 1. Redistributions of source code must retain the above copyright
381cd76c75SBen Gras * notice, this list of conditions and the following disclaimer.
391cd76c75SBen Gras * 2. Redistributions in binary form must reproduce the above copyright
401cd76c75SBen Gras * notice, this list of conditions and the following disclaimer in the
411cd76c75SBen Gras * documentation and/or other materials provided with the distribution.
421cd76c75SBen Gras * 3. All advertising materials mentioning features or use of this software
431cd76c75SBen Gras * must display the following acknowledgement:
441cd76c75SBen Gras * This product includes software developed for the NetBSD Project by
451cd76c75SBen Gras * Wasabi Systems, Inc.
461cd76c75SBen Gras * 4. The name of Wasabi Systems, Inc. may not be used to endorse
471cd76c75SBen Gras * or promote products derived from this software without specific prior
481cd76c75SBen Gras * written permission.
491cd76c75SBen Gras *
501cd76c75SBen Gras * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
511cd76c75SBen Gras * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
521cd76c75SBen Gras * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
531cd76c75SBen Gras * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL WASABI SYSTEMS, INC
541cd76c75SBen Gras * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
551cd76c75SBen Gras * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
561cd76c75SBen Gras * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
571cd76c75SBen Gras * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
581cd76c75SBen Gras * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
591cd76c75SBen Gras * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
601cd76c75SBen Gras * POSSIBILITY OF SUCH DAMAGE.
611cd76c75SBen Gras */
621cd76c75SBen Gras
631cd76c75SBen Gras /*
641cd76c75SBen Gras * pmap.h: see pmap.c for the history of this pmap module.
651cd76c75SBen Gras */
661cd76c75SBen Gras
671cd76c75SBen Gras #ifndef _X86_PMAP_H_
681cd76c75SBen Gras #define _X86_PMAP_H_
691cd76c75SBen Gras
701cd76c75SBen Gras /*
711cd76c75SBen Gras * pl*_pi: index in the ptp page for a pde mapping a VA.
721cd76c75SBen Gras * (pl*_i below is the index in the virtual array of all pdes per level)
731cd76c75SBen Gras */
741cd76c75SBen Gras #define pl1_pi(VA) (((VA_SIGN_POS(VA)) & L1_MASK) >> L1_SHIFT)
751cd76c75SBen Gras #define pl2_pi(VA) (((VA_SIGN_POS(VA)) & L2_MASK) >> L2_SHIFT)
761cd76c75SBen Gras #define pl3_pi(VA) (((VA_SIGN_POS(VA)) & L3_MASK) >> L3_SHIFT)
771cd76c75SBen Gras #define pl4_pi(VA) (((VA_SIGN_POS(VA)) & L4_MASK) >> L4_SHIFT)
781cd76c75SBen Gras
791cd76c75SBen Gras /*
801cd76c75SBen Gras * pl*_i: generate index into pde/pte arrays in virtual space
811cd76c75SBen Gras *
821cd76c75SBen Gras * pl_i(va, X) == plX_i(va) <= pl_i_roundup(va, X)
831cd76c75SBen Gras */
841cd76c75SBen Gras #define pl1_i(VA) (((VA_SIGN_POS(VA)) & L1_FRAME) >> L1_SHIFT)
851cd76c75SBen Gras #define pl2_i(VA) (((VA_SIGN_POS(VA)) & L2_FRAME) >> L2_SHIFT)
861cd76c75SBen Gras #define pl3_i(VA) (((VA_SIGN_POS(VA)) & L3_FRAME) >> L3_SHIFT)
871cd76c75SBen Gras #define pl4_i(VA) (((VA_SIGN_POS(VA)) & L4_FRAME) >> L4_SHIFT)
881cd76c75SBen Gras #define pl_i(va, lvl) \
891cd76c75SBen Gras (((VA_SIGN_POS(va)) & ptp_masks[(lvl)-1]) >> ptp_shifts[(lvl)-1])
901cd76c75SBen Gras
911cd76c75SBen Gras #define pl_i_roundup(va, lvl) pl_i((va)+ ~ptp_masks[(lvl)-1], (lvl))
921cd76c75SBen Gras
931cd76c75SBen Gras /*
941cd76c75SBen Gras * PTP macros:
951cd76c75SBen Gras * a PTP's index is the PD index of the PDE that points to it
961cd76c75SBen Gras * a PTP's offset is the byte-offset in the PTE space that this PTP is at
971cd76c75SBen Gras * a PTP's VA is the first VA mapped by that PTP
981cd76c75SBen Gras */
991cd76c75SBen Gras
1001cd76c75SBen Gras #define ptp_va2o(va, lvl) (pl_i(va, (lvl)+1) * PAGE_SIZE)
1011cd76c75SBen Gras
1021cd76c75SBen Gras /* size of a PDP: usually one page, except for PAE */
1031cd76c75SBen Gras #ifdef PAE
1041cd76c75SBen Gras #define PDP_SIZE 4
1051cd76c75SBen Gras #else
1061cd76c75SBen Gras #define PDP_SIZE 1
1071cd76c75SBen Gras #endif
1081cd76c75SBen Gras
1091cd76c75SBen Gras
1101cd76c75SBen Gras #if defined(_KERNEL)
1111cd76c75SBen Gras #include <sys/kcpuset.h>
1121cd76c75SBen Gras
1131cd76c75SBen Gras /*
1141cd76c75SBen Gras * pmap data structures: see pmap.c for details of locking.
1151cd76c75SBen Gras */
1161cd76c75SBen Gras
1171cd76c75SBen Gras /*
1181cd76c75SBen Gras * we maintain a list of all non-kernel pmaps
1191cd76c75SBen Gras */
1201cd76c75SBen Gras
1211cd76c75SBen Gras LIST_HEAD(pmap_head, pmap); /* struct pmap_head: head of a pmap list */
1221cd76c75SBen Gras
1231cd76c75SBen Gras /*
1241cd76c75SBen Gras * linked list of all non-kernel pmaps
1251cd76c75SBen Gras */
1261cd76c75SBen Gras extern struct pmap_head pmaps;
1271cd76c75SBen Gras extern kmutex_t pmaps_lock; /* protects pmaps */
1281cd76c75SBen Gras
1291cd76c75SBen Gras /*
1301cd76c75SBen Gras * pool_cache(9) that PDPs are allocated from
1311cd76c75SBen Gras */
1321cd76c75SBen Gras extern struct pool_cache pmap_pdp_cache;
1331cd76c75SBen Gras
1341cd76c75SBen Gras /*
1351cd76c75SBen Gras * the pmap structure
1361cd76c75SBen Gras *
1371cd76c75SBen Gras * note that the pm_obj contains the lock pointer, the reference count,
1381cd76c75SBen Gras * page list, and number of PTPs within the pmap.
1391cd76c75SBen Gras *
1401cd76c75SBen Gras * pm_lock is the same as the lock for vm object 0. Changes to
1411cd76c75SBen Gras * the other objects may only be made if that lock has been taken
1421cd76c75SBen Gras * (the other object locks are only used when uvm_pagealloc is called)
1431cd76c75SBen Gras */
1441cd76c75SBen Gras
1451cd76c75SBen Gras struct pmap {
1461cd76c75SBen Gras struct uvm_object pm_obj[PTP_LEVELS-1]; /* objects for lvl >= 1) */
1471cd76c75SBen Gras #define pm_lock pm_obj[0].vmobjlock
1481cd76c75SBen Gras kmutex_t pm_obj_lock[PTP_LEVELS-1]; /* locks for pm_objs */
1491cd76c75SBen Gras LIST_ENTRY(pmap) pm_list; /* list (lck by pm_list lock) */
1501cd76c75SBen Gras pd_entry_t *pm_pdir; /* VA of PD (lck by object lock) */
1511cd76c75SBen Gras paddr_t pm_pdirpa[PDP_SIZE]; /* PA of PDs (read-only after create) */
1521cd76c75SBen Gras struct vm_page *pm_ptphint[PTP_LEVELS-1];
1531cd76c75SBen Gras /* pointer to a PTP in our pmap */
1541cd76c75SBen Gras struct pmap_statistics pm_stats; /* pmap stats (lck by object lock) */
1551cd76c75SBen Gras
1561cd76c75SBen Gras #if !defined(__x86_64__)
1571cd76c75SBen Gras vaddr_t pm_hiexec; /* highest executable mapping */
1581cd76c75SBen Gras #endif /* !defined(__x86_64__) */
1591cd76c75SBen Gras int pm_flags; /* see below */
1601cd76c75SBen Gras
1611cd76c75SBen Gras union descriptor *pm_ldt; /* user-set LDT */
1621cd76c75SBen Gras size_t pm_ldt_len; /* size of LDT in bytes */
1631cd76c75SBen Gras int pm_ldt_sel; /* LDT selector */
1641cd76c75SBen Gras kcpuset_t *pm_cpus; /* mask of CPUs using pmap */
1651cd76c75SBen Gras kcpuset_t *pm_kernel_cpus; /* mask of CPUs using kernel part
1661cd76c75SBen Gras of pmap */
1671cd76c75SBen Gras kcpuset_t *pm_xen_ptp_cpus; /* mask of CPUs which have this pmap's
1681cd76c75SBen Gras ptp mapped */
1691cd76c75SBen Gras uint64_t pm_ncsw; /* for assertions */
1701cd76c75SBen Gras struct vm_page *pm_gc_ptp; /* pages from pmap g/c */
1711cd76c75SBen Gras };
1721cd76c75SBen Gras
1731cd76c75SBen Gras /* macro to access pm_pdirpa slots */
1741cd76c75SBen Gras #ifdef PAE
1751cd76c75SBen Gras #define pmap_pdirpa(pmap, index) \
1761cd76c75SBen Gras ((pmap)->pm_pdirpa[l2tol3(index)] + l2tol2(index) * sizeof(pd_entry_t))
1771cd76c75SBen Gras #else
1781cd76c75SBen Gras #define pmap_pdirpa(pmap, index) \
1791cd76c75SBen Gras ((pmap)->pm_pdirpa[0] + (index) * sizeof(pd_entry_t))
1801cd76c75SBen Gras #endif
1811cd76c75SBen Gras
1821cd76c75SBen Gras /*
1831cd76c75SBen Gras * flag to be used for kernel mappings: PG_u on Xen/amd64,
1841cd76c75SBen Gras * 0 otherwise.
1851cd76c75SBen Gras */
1861cd76c75SBen Gras #if defined(XEN) && defined(__x86_64__)
1871cd76c75SBen Gras #define PG_k PG_u
1881cd76c75SBen Gras #else
1891cd76c75SBen Gras #define PG_k 0
1901cd76c75SBen Gras #endif
1911cd76c75SBen Gras
1921cd76c75SBen Gras /*
1931cd76c75SBen Gras * MD flags that we use for pmap_enter and pmap_kenter_pa:
1941cd76c75SBen Gras */
1951cd76c75SBen Gras
1961cd76c75SBen Gras /*
1971cd76c75SBen Gras * global kernel variables
1981cd76c75SBen Gras */
1991cd76c75SBen Gras
2001cd76c75SBen Gras /*
2011cd76c75SBen Gras * PDPpaddr is the physical address of the kernel's PDP.
2021cd76c75SBen Gras * - i386 non-PAE and amd64: PDPpaddr corresponds directly to the %cr3
2031cd76c75SBen Gras * value associated to the kernel process, proc0.
2041cd76c75SBen Gras * - i386 PAE: it still represents the PA of the kernel's PDP (L2). Due to
2051cd76c75SBen Gras * the L3 PD, it cannot be considered as the equivalent of a %cr3 any more.
2061cd76c75SBen Gras * - Xen: it corresponds to the PFN of the kernel's PDP.
2071cd76c75SBen Gras */
2081cd76c75SBen Gras extern u_long PDPpaddr;
2091cd76c75SBen Gras
2101cd76c75SBen Gras extern int pmap_pg_g; /* do we support PG_G? */
2111cd76c75SBen Gras extern long nkptp[PTP_LEVELS];
2121cd76c75SBen Gras
2131cd76c75SBen Gras /*
2141cd76c75SBen Gras * macros
2151cd76c75SBen Gras */
2161cd76c75SBen Gras
2171cd76c75SBen Gras #define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
2181cd76c75SBen Gras #define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
2191cd76c75SBen Gras
2201cd76c75SBen Gras #define pmap_clear_modify(pg) pmap_clear_attrs(pg, PG_M)
2211cd76c75SBen Gras #define pmap_clear_reference(pg) pmap_clear_attrs(pg, PG_U)
22284d9c625SLionel Sambuc #define pmap_copy(DP,SP,D,L,S) __USE(L)
2231cd76c75SBen Gras #define pmap_is_modified(pg) pmap_test_attrs(pg, PG_M)
2241cd76c75SBen Gras #define pmap_is_referenced(pg) pmap_test_attrs(pg, PG_U)
2251cd76c75SBen Gras #define pmap_move(DP,SP,D,L,S)
2261cd76c75SBen Gras #define pmap_phys_address(ppn) (x86_ptob(ppn) & ~X86_MMAP_FLAG_MASK)
2271cd76c75SBen Gras #define pmap_mmap_flags(ppn) x86_mmap_flags(ppn)
2281cd76c75SBen Gras #define pmap_valid_entry(E) ((E) & PG_V) /* is PDE or PTE valid? */
2291cd76c75SBen Gras
2301cd76c75SBen Gras #if defined(__x86_64__) || defined(PAE)
2311cd76c75SBen Gras #define X86_MMAP_FLAG_SHIFT (64 - PGSHIFT)
2321cd76c75SBen Gras #else
2331cd76c75SBen Gras #define X86_MMAP_FLAG_SHIFT (32 - PGSHIFT)
2341cd76c75SBen Gras #endif
2351cd76c75SBen Gras
2361cd76c75SBen Gras #define X86_MMAP_FLAG_MASK 0xf
2371cd76c75SBen Gras #define X86_MMAP_FLAG_PREFETCH 0x1
2381cd76c75SBen Gras
2391cd76c75SBen Gras /*
2401cd76c75SBen Gras * prototypes
2411cd76c75SBen Gras */
2421cd76c75SBen Gras
2431cd76c75SBen Gras void pmap_activate(struct lwp *);
2441cd76c75SBen Gras void pmap_bootstrap(vaddr_t);
2451cd76c75SBen Gras bool pmap_clear_attrs(struct vm_page *, unsigned);
246*0a6a1f1dSLionel Sambuc bool pmap_pv_clear_attrs(paddr_t, unsigned);
2471cd76c75SBen Gras void pmap_deactivate(struct lwp *);
2481cd76c75SBen Gras void pmap_page_remove(struct vm_page *);
249*0a6a1f1dSLionel Sambuc void pmap_pv_remove(paddr_t);
2501cd76c75SBen Gras void pmap_remove(struct pmap *, vaddr_t, vaddr_t);
2511cd76c75SBen Gras bool pmap_test_attrs(struct vm_page *, unsigned);
2521cd76c75SBen Gras void pmap_write_protect(struct pmap *, vaddr_t, vaddr_t, vm_prot_t);
2531cd76c75SBen Gras void pmap_load(void);
2541cd76c75SBen Gras paddr_t pmap_init_tmp_pgtbl(paddr_t);
2551cd76c75SBen Gras void pmap_remove_all(struct pmap *);
2561cd76c75SBen Gras void pmap_ldt_sync(struct pmap *);
25784d9c625SLionel Sambuc void pmap_kremove_local(vaddr_t, vsize_t);
2581cd76c75SBen Gras
2591cd76c75SBen Gras void pmap_emap_enter(vaddr_t, paddr_t, vm_prot_t);
2601cd76c75SBen Gras void pmap_emap_remove(vaddr_t, vsize_t);
2611cd76c75SBen Gras void pmap_emap_sync(bool);
2621cd76c75SBen Gras
263*0a6a1f1dSLionel Sambuc #define __HAVE_PMAP_PV_TRACK 1
264*0a6a1f1dSLionel Sambuc void pmap_pv_init(void);
265*0a6a1f1dSLionel Sambuc void pmap_pv_track(paddr_t, psize_t);
266*0a6a1f1dSLionel Sambuc void pmap_pv_untrack(paddr_t, psize_t);
267*0a6a1f1dSLionel Sambuc
2681cd76c75SBen Gras void pmap_map_ptes(struct pmap *, struct pmap **, pd_entry_t **,
2691cd76c75SBen Gras pd_entry_t * const **);
2701cd76c75SBen Gras void pmap_unmap_ptes(struct pmap *, struct pmap *);
2711cd76c75SBen Gras
2721cd76c75SBen Gras int pmap_pdes_invalid(vaddr_t, pd_entry_t * const *, pd_entry_t *);
2731cd76c75SBen Gras
2741cd76c75SBen Gras u_int x86_mmap_flags(paddr_t);
2751cd76c75SBen Gras
2761cd76c75SBen Gras bool pmap_is_curpmap(struct pmap *);
2771cd76c75SBen Gras
2781cd76c75SBen Gras vaddr_t reserve_dumppages(vaddr_t); /* XXX: not a pmap fn */
2791cd76c75SBen Gras
2801cd76c75SBen Gras typedef enum tlbwhy {
2811cd76c75SBen Gras TLBSHOOT_APTE,
2821cd76c75SBen Gras TLBSHOOT_KENTER,
2831cd76c75SBen Gras TLBSHOOT_KREMOVE,
2841cd76c75SBen Gras TLBSHOOT_FREE_PTP1,
2851cd76c75SBen Gras TLBSHOOT_FREE_PTP2,
2861cd76c75SBen Gras TLBSHOOT_REMOVE_PTE,
2871cd76c75SBen Gras TLBSHOOT_REMOVE_PTES,
2881cd76c75SBen Gras TLBSHOOT_SYNC_PV1,
2891cd76c75SBen Gras TLBSHOOT_SYNC_PV2,
2901cd76c75SBen Gras TLBSHOOT_WRITE_PROTECT,
2911cd76c75SBen Gras TLBSHOOT_ENTER,
2921cd76c75SBen Gras TLBSHOOT_UPDATE,
2931cd76c75SBen Gras TLBSHOOT_BUS_DMA,
2941cd76c75SBen Gras TLBSHOOT_BUS_SPACE,
2951cd76c75SBen Gras TLBSHOOT__MAX,
2961cd76c75SBen Gras } tlbwhy_t;
2971cd76c75SBen Gras
2981cd76c75SBen Gras void pmap_tlb_init(void);
2991cd76c75SBen Gras void pmap_tlb_cpu_init(struct cpu_info *);
3001cd76c75SBen Gras void pmap_tlb_shootdown(pmap_t, vaddr_t, pt_entry_t, tlbwhy_t);
3011cd76c75SBen Gras void pmap_tlb_shootnow(void);
3021cd76c75SBen Gras void pmap_tlb_intr(void);
3031cd76c75SBen Gras
3041cd76c75SBen Gras #define __HAVE_PMAP_EMAP
3051cd76c75SBen Gras
3061cd76c75SBen Gras #define PMAP_GROWKERNEL /* turn on pmap_growkernel interface */
3071cd76c75SBen Gras #define PMAP_FORK /* turn on pmap_fork interface */
3081cd76c75SBen Gras
3091cd76c75SBen Gras /*
3101cd76c75SBen Gras * Do idle page zero'ing uncached to avoid polluting the cache.
3111cd76c75SBen Gras */
3121cd76c75SBen Gras bool pmap_pageidlezero(paddr_t);
3131cd76c75SBen Gras #define PMAP_PAGEIDLEZERO(pa) pmap_pageidlezero((pa))
3141cd76c75SBen Gras
3151cd76c75SBen Gras /*
3161cd76c75SBen Gras * inline functions
3171cd76c75SBen Gras */
3181cd76c75SBen Gras
3191cd76c75SBen Gras __inline static bool __unused
pmap_pdes_valid(vaddr_t va,pd_entry_t * const * pdes,pd_entry_t * lastpde)3201cd76c75SBen Gras pmap_pdes_valid(vaddr_t va, pd_entry_t * const *pdes, pd_entry_t *lastpde)
3211cd76c75SBen Gras {
3221cd76c75SBen Gras return pmap_pdes_invalid(va, pdes, lastpde) == 0;
3231cd76c75SBen Gras }
3241cd76c75SBen Gras
3251cd76c75SBen Gras /*
3261cd76c75SBen Gras * pmap_update_pg: flush one page from the TLB (or flush the whole thing
3271cd76c75SBen Gras * if hardware doesn't support one-page flushing)
3281cd76c75SBen Gras */
3291cd76c75SBen Gras
3301cd76c75SBen Gras __inline static void __unused
pmap_update_pg(vaddr_t va)3311cd76c75SBen Gras pmap_update_pg(vaddr_t va)
3321cd76c75SBen Gras {
3331cd76c75SBen Gras invlpg(va);
3341cd76c75SBen Gras }
3351cd76c75SBen Gras
3361cd76c75SBen Gras /*
3371cd76c75SBen Gras * pmap_update_2pg: flush two pages from the TLB
3381cd76c75SBen Gras */
3391cd76c75SBen Gras
3401cd76c75SBen Gras __inline static void __unused
pmap_update_2pg(vaddr_t va,vaddr_t vb)3411cd76c75SBen Gras pmap_update_2pg(vaddr_t va, vaddr_t vb)
3421cd76c75SBen Gras {
3431cd76c75SBen Gras invlpg(va);
3441cd76c75SBen Gras invlpg(vb);
3451cd76c75SBen Gras }
3461cd76c75SBen Gras
3471cd76c75SBen Gras /*
3481cd76c75SBen Gras * pmap_page_protect: change the protection of all recorded mappings
3491cd76c75SBen Gras * of a managed page
3501cd76c75SBen Gras *
3511cd76c75SBen Gras * => this function is a frontend for pmap_page_remove/pmap_clear_attrs
3521cd76c75SBen Gras * => we only have to worry about making the page more protected.
3531cd76c75SBen Gras * unprotecting a page is done on-demand at fault time.
3541cd76c75SBen Gras */
3551cd76c75SBen Gras
3561cd76c75SBen Gras __inline static void __unused
pmap_page_protect(struct vm_page * pg,vm_prot_t prot)3571cd76c75SBen Gras pmap_page_protect(struct vm_page *pg, vm_prot_t prot)
3581cd76c75SBen Gras {
3591cd76c75SBen Gras if ((prot & VM_PROT_WRITE) == 0) {
3601cd76c75SBen Gras if (prot & (VM_PROT_READ|VM_PROT_EXECUTE)) {
3611cd76c75SBen Gras (void) pmap_clear_attrs(pg, PG_RW);
3621cd76c75SBen Gras } else {
3631cd76c75SBen Gras pmap_page_remove(pg);
3641cd76c75SBen Gras }
3651cd76c75SBen Gras }
3661cd76c75SBen Gras }
3671cd76c75SBen Gras
3681cd76c75SBen Gras /*
369*0a6a1f1dSLionel Sambuc * pmap_pv_protect: change the protection of all recorded mappings
370*0a6a1f1dSLionel Sambuc * of an unmanaged page
371*0a6a1f1dSLionel Sambuc */
372*0a6a1f1dSLionel Sambuc
373*0a6a1f1dSLionel Sambuc __inline static void __unused
pmap_pv_protect(paddr_t pa,vm_prot_t prot)374*0a6a1f1dSLionel Sambuc pmap_pv_protect(paddr_t pa, vm_prot_t prot)
375*0a6a1f1dSLionel Sambuc {
376*0a6a1f1dSLionel Sambuc if ((prot & VM_PROT_WRITE) == 0) {
377*0a6a1f1dSLionel Sambuc if (prot & (VM_PROT_READ|VM_PROT_EXECUTE)) {
378*0a6a1f1dSLionel Sambuc (void) pmap_pv_clear_attrs(pa, PG_RW);
379*0a6a1f1dSLionel Sambuc } else {
380*0a6a1f1dSLionel Sambuc pmap_pv_remove(pa);
381*0a6a1f1dSLionel Sambuc }
382*0a6a1f1dSLionel Sambuc }
383*0a6a1f1dSLionel Sambuc }
384*0a6a1f1dSLionel Sambuc
385*0a6a1f1dSLionel Sambuc /*
3861cd76c75SBen Gras * pmap_protect: change the protection of pages in a pmap
3871cd76c75SBen Gras *
3881cd76c75SBen Gras * => this function is a frontend for pmap_remove/pmap_write_protect
3891cd76c75SBen Gras * => we only have to worry about making the page more protected.
3901cd76c75SBen Gras * unprotecting a page is done on-demand at fault time.
3911cd76c75SBen Gras */
3921cd76c75SBen Gras
3931cd76c75SBen Gras __inline static void __unused
pmap_protect(struct pmap * pmap,vaddr_t sva,vaddr_t eva,vm_prot_t prot)3941cd76c75SBen Gras pmap_protect(struct pmap *pmap, vaddr_t sva, vaddr_t eva, vm_prot_t prot)
3951cd76c75SBen Gras {
3961cd76c75SBen Gras if ((prot & VM_PROT_WRITE) == 0) {
3971cd76c75SBen Gras if (prot & (VM_PROT_READ|VM_PROT_EXECUTE)) {
3981cd76c75SBen Gras pmap_write_protect(pmap, sva, eva, prot);
3991cd76c75SBen Gras } else {
4001cd76c75SBen Gras pmap_remove(pmap, sva, eva);
4011cd76c75SBen Gras }
4021cd76c75SBen Gras }
4031cd76c75SBen Gras }
4041cd76c75SBen Gras
4051cd76c75SBen Gras /*
4061cd76c75SBen Gras * various address inlines
4071cd76c75SBen Gras *
4081cd76c75SBen Gras * vtopte: return a pointer to the PTE mapping a VA, works only for
4091cd76c75SBen Gras * user and PT addresses
4101cd76c75SBen Gras *
4111cd76c75SBen Gras * kvtopte: return a pointer to the PTE mapping a kernel VA
4121cd76c75SBen Gras */
4131cd76c75SBen Gras
4141cd76c75SBen Gras #include <lib/libkern/libkern.h>
4151cd76c75SBen Gras
4161cd76c75SBen Gras static __inline pt_entry_t * __unused
vtopte(vaddr_t va)4171cd76c75SBen Gras vtopte(vaddr_t va)
4181cd76c75SBen Gras {
4191cd76c75SBen Gras
4201cd76c75SBen Gras KASSERT(va < VM_MIN_KERNEL_ADDRESS);
4211cd76c75SBen Gras
4221cd76c75SBen Gras return (PTE_BASE + pl1_i(va));
4231cd76c75SBen Gras }
4241cd76c75SBen Gras
4251cd76c75SBen Gras static __inline pt_entry_t * __unused
kvtopte(vaddr_t va)4261cd76c75SBen Gras kvtopte(vaddr_t va)
4271cd76c75SBen Gras {
4281cd76c75SBen Gras pd_entry_t *pde;
4291cd76c75SBen Gras
4301cd76c75SBen Gras KASSERT(va >= VM_MIN_KERNEL_ADDRESS);
4311cd76c75SBen Gras
4321cd76c75SBen Gras pde = L2_BASE + pl2_i(va);
4331cd76c75SBen Gras if (*pde & PG_PS)
4341cd76c75SBen Gras return ((pt_entry_t *)pde);
4351cd76c75SBen Gras
4361cd76c75SBen Gras return (PTE_BASE + pl1_i(va));
4371cd76c75SBen Gras }
4381cd76c75SBen Gras
4391cd76c75SBen Gras paddr_t vtophys(vaddr_t);
4401cd76c75SBen Gras vaddr_t pmap_map(vaddr_t, paddr_t, paddr_t, vm_prot_t);
4411cd76c75SBen Gras void pmap_cpu_init_late(struct cpu_info *);
4421cd76c75SBen Gras bool sse2_idlezero_page(void *);
4431cd76c75SBen Gras
4441cd76c75SBen Gras #ifdef XEN
4451cd76c75SBen Gras #include <sys/bitops.h>
4461cd76c75SBen Gras
4471cd76c75SBen Gras #define XPTE_MASK L1_FRAME
4481cd76c75SBen Gras /* Selects the index of a PTE in (A)PTE_BASE */
4491cd76c75SBen Gras #define XPTE_SHIFT (L1_SHIFT - ilog2(sizeof(pt_entry_t)))
4501cd76c75SBen Gras
4511cd76c75SBen Gras /* PTE access inline fuctions */
4521cd76c75SBen Gras
4531cd76c75SBen Gras /*
4541cd76c75SBen Gras * Get the machine address of the pointed pte
4551cd76c75SBen Gras * We use hardware MMU to get value so works only for levels 1-3
4561cd76c75SBen Gras */
4571cd76c75SBen Gras
4581cd76c75SBen Gras static __inline paddr_t
xpmap_ptetomach(pt_entry_t * pte)4591cd76c75SBen Gras xpmap_ptetomach(pt_entry_t *pte)
4601cd76c75SBen Gras {
4611cd76c75SBen Gras pt_entry_t *up_pte;
4621cd76c75SBen Gras vaddr_t va = (vaddr_t) pte;
4631cd76c75SBen Gras
4641cd76c75SBen Gras va = ((va & XPTE_MASK) >> XPTE_SHIFT) | (vaddr_t) PTE_BASE;
4651cd76c75SBen Gras up_pte = (pt_entry_t *) va;
4661cd76c75SBen Gras
4671cd76c75SBen Gras return (paddr_t) (((*up_pte) & PG_FRAME) + (((vaddr_t) pte) & (~PG_FRAME & ~VA_SIGN_MASK)));
4681cd76c75SBen Gras }
4691cd76c75SBen Gras
4701cd76c75SBen Gras /* Xen helpers to change bits of a pte */
4711cd76c75SBen Gras #define XPMAP_UPDATE_DIRECT 1 /* Update direct map entry flags too */
4721cd76c75SBen Gras
4731cd76c75SBen Gras paddr_t vtomach(vaddr_t);
4741cd76c75SBen Gras #define vtomfn(va) (vtomach(va) >> PAGE_SHIFT)
4751cd76c75SBen Gras #endif /* XEN */
4761cd76c75SBen Gras
4771cd76c75SBen Gras /* pmap functions with machine addresses */
4781cd76c75SBen Gras void pmap_kenter_ma(vaddr_t, paddr_t, vm_prot_t, u_int);
4791cd76c75SBen Gras int pmap_enter_ma(struct pmap *, vaddr_t, paddr_t, paddr_t,
4801cd76c75SBen Gras vm_prot_t, u_int, int);
4811cd76c75SBen Gras bool pmap_extract_ma(pmap_t, vaddr_t, paddr_t *);
4821cd76c75SBen Gras
4831cd76c75SBen Gras /*
4841cd76c75SBen Gras * Hooks for the pool allocator.
4851cd76c75SBen Gras */
4861cd76c75SBen Gras #define POOL_VTOPHYS(va) vtophys((vaddr_t) (va))
4871cd76c75SBen Gras
4881cd76c75SBen Gras #ifdef __HAVE_DIRECT_MAP
4891cd76c75SBen Gras
4901cd76c75SBen Gras #define L4_SLOT_DIRECT 509
4911cd76c75SBen Gras #define PDIR_SLOT_DIRECT L4_SLOT_DIRECT
4921cd76c75SBen Gras
4931cd76c75SBen Gras #define PMAP_DIRECT_BASE (VA_SIGN_NEG((L4_SLOT_DIRECT * NBPD_L4)))
4941cd76c75SBen Gras #define PMAP_DIRECT_END (VA_SIGN_NEG(((L4_SLOT_DIRECT + 1) * NBPD_L4)))
4951cd76c75SBen Gras
4961cd76c75SBen Gras #define PMAP_DIRECT_MAP(pa) ((vaddr_t)PMAP_DIRECT_BASE + (pa))
4971cd76c75SBen Gras #define PMAP_DIRECT_UNMAP(va) ((paddr_t)(va) - PMAP_DIRECT_BASE)
4981cd76c75SBen Gras
4991cd76c75SBen Gras /*
5001cd76c75SBen Gras * Alternate mapping hooks for pool pages.
5011cd76c75SBen Gras */
5021cd76c75SBen Gras #define PMAP_MAP_POOLPAGE(pa) PMAP_DIRECT_MAP((pa))
5031cd76c75SBen Gras #define PMAP_UNMAP_POOLPAGE(va) PMAP_DIRECT_UNMAP((va))
5041cd76c75SBen Gras
5051cd76c75SBen Gras void pagezero(vaddr_t);
5061cd76c75SBen Gras
5071cd76c75SBen Gras #endif /* __HAVE_DIRECT_MAP */
5081cd76c75SBen Gras
5091cd76c75SBen Gras #endif /* _KERNEL */
5101cd76c75SBen Gras
5111cd76c75SBen Gras #endif /* _X86_PMAP_H_ */
512