xref: /minix3/sys/arch/x86/include/pmap.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
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