pmap.h revision 1.56
11.378Suebayasi/*	$NetBSD: pmap.h,v 1.56 2018/08/29 06:28:50 maxv Exp $	*/
21.277Sad
31.277Sad/*
41.277Sad * Copyright (c) 1997 Charles D. Cranor and Washington University.
51.277Sad * All rights reserved.
61.277Sad *
71.277Sad * Redistribution and use in source and binary forms, with or without
81.277Sad * modification, are permitted provided that the following conditions
91.277Sad * are met:
101.277Sad * 1. Redistributions of source code must retain the above copyright
111.277Sad *    notice, this list of conditions and the following disclaimer.
121.277Sad * 2. Redistributions in binary form must reproduce the above copyright
131.277Sad *    notice, this list of conditions and the following disclaimer in the
141.277Sad *    documentation and/or other materials provided with the distribution.
151.277Sad *
161.277Sad * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
171.277Sad * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
181.277Sad * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
191.277Sad * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
201.277Sad * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
211.277Sad * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
221.277Sad * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
231.277Sad * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
241.277Sad * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
251.277Sad * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
261.277Sad */
271.277Sad
281.55Scgd/*
291.55Scgd * Copyright (c) 2001 Wasabi Systems, Inc.
301.77Scgd * All rights reserved.
311.55Scgd *
321.55Scgd * Written by Frank van der Linden for Wasabi Systems, Inc.
331.55Scgd *
341.55Scgd * Redistribution and use in source and binary forms, with or without
351.55Scgd * modification, are permitted provided that the following conditions
361.55Scgd * are met:
371.55Scgd * 1. Redistributions of source code must retain the above copyright
381.55Scgd *    notice, this list of conditions and the following disclaimer.
391.55Scgd * 2. Redistributions in binary form must reproduce the above copyright
401.55Scgd *    notice, this list of conditions and the following disclaimer in the
411.55Scgd *    documentation and/or other materials provided with the distribution.
421.55Scgd * 3. All advertising materials mentioning features or use of this software
431.55Scgd *    must display the following acknowledgement:
441.55Scgd *      This product includes software developed for the NetBSD Project by
451.55Scgd *      Wasabi Systems, Inc.
461.55Scgd * 4. The name of Wasabi Systems, Inc. may not be used to endorse
471.55Scgd *    or promote products derived from this software without specific prior
481.55Scgd *    written permission.
491.55Scgd *
501.55Scgd * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
511.55Scgd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
521.55Scgd * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
531.55Scgd * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
541.55Scgd * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
551.55Scgd * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
561.55Scgd * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
571.55Scgd * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
581.55Scgd * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
591.55Scgd * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
601.146Slukem * POSSIBILITY OF SUCH DAMAGE.
611.146Slukem */
621.378Suebayasi
631.89Smrg#ifndef	_AMD64_PMAP_H_
641.325Sjmcneill#define	_AMD64_PMAP_H_
651.360Schristos
661.92Sthorpej#ifdef __x86_64__
671.285Sapb
681.124Sjdolecek#if defined(_KERNEL_OPT)
691.226Sdogcow#include "opt_xen.h"
701.232Selad#include "opt_kasan.h"
711.55Scgd#endif
721.55Scgd
731.55Scgd#include <sys/atomic.h>
741.55Scgd
751.55Scgd#include <machine/pte.h>
761.55Scgd#include <machine/segments.h>
771.55Scgd#ifdef _KERNEL
781.55Scgd#include <machine/cpufunc.h>
791.265Syamt#endif
801.55Scgd
811.55Scgd#include <uvm/uvm_object.h>
821.55Scgd#ifdef XEN
831.55Scgd#include <xen/xenfunc.h>
841.337Smartin#include <xen/xenpmap.h>
851.55Scgd#endif
861.55Scgd
871.278Spooka/*
881.55Scgd * Mask to get rid of the sign-extended part of addresses.
891.55Scgd */
901.155Sgmcgarry#define VA_SIGN_MASK		0xffff000000000000
911.55Scgd#define VA_SIGN_NEG(va)		((va) | VA_SIGN_MASK)
921.55Scgd/* XXXfvdl this one's not right. */
931.124Sjdolecek#define VA_SIGN_POS(va)		((va) & ~VA_SIGN_MASK)
941.218Selad
951.253Sad#ifdef KASAN
961.260Schristos#define L4_SLOT_KASAN		256
971.263Sad#define NL4_SLOT_KASAN		32
981.282Sad#endif
991.289Spooka
1001.56Scgd#define NL4_SLOT_DIRECT		32
1011.222Selad
1021.197Sblymn#ifndef XEN
1031.222Selad#define L4_SLOT_PTE		slotspace.area[SLAREA_PTE].sslot
1041.294Sdarran#else
1051.337Smartin#define L4_SLOT_PTE		509
1061.337Smartin#endif
1071.330Stls#define L4_SLOT_KERN		slotspace.area[SLAREA_MAIN].sslot
1081.55Scgd#define L4_SLOT_KERNBASE	511 /* pl4_i(KERNBASE) */
1091.88Smrg
1101.88Smrg#define PDIR_SLOT_USERLIM	255
1111.55Scgd#define PDIR_SLOT_KERN	L4_SLOT_KERN
1121.55Scgd#define PDIR_SLOT_PTE	L4_SLOT_PTE
1131.244Sdsl
1141.244Sdsl/*
1151.364Smartin * The following defines give the virtual addresses of various MMU
1161.370Schristos * data structures:
1171.364Smartin * PTE_BASE: the base VA of the linear PTE mappings
1181.364Smartin * PDP_BASE: the base VA of the recursive mapping of the PTD
1191.364Smartin */
1201.364Smartin
1211.364Smartin#ifndef XEN
1221.364Smartinextern pt_entry_t *pte_base;
1231.391Suebayasi#define PTE_BASE	pte_base
1241.391Suebayasi#else
1251.396Suebayasi#define PTE_BASE	((pt_entry_t *)VA_SIGN_NEG((L4_SLOT_PTE * NBPD_L4)))
1261.396Suebayasi#endif
1271.399Suebayasi
1281.399Suebayasi#define L1_BASE	PTE_BASE
1291.398Suebayasi#define L2_BASE	((pd_entry_t *)((char *)L1_BASE + L4_SLOT_PTE * NBPD_L3))
1301.391Suebayasi#define L3_BASE	((pd_entry_t *)((char *)L2_BASE + L4_SLOT_PTE * NBPD_L2))
1311.391Suebayasi#define L4_BASE	((pd_entry_t *)((char *)L3_BASE + L4_SLOT_PTE * NBPD_L1))
1321.392Suebayasi
1331.392Suebayasi#define PDP_BASE	L4_BASE
1341.171Schs
1351.171Schs#define NKL4_MAX_ENTRIES	(unsigned long)64
1361.143Schristos#define NKL3_MAX_ENTRIES	(unsigned long)(NKL4_MAX_ENTRIES * 512)
1371.305Smatt#define NKL2_MAX_ENTRIES	(unsigned long)(NKL3_MAX_ENTRIES * 512)
1381.312Schristos#define NKL1_MAX_ENTRIES	(unsigned long)(NKL2_MAX_ENTRIES * 512)
1391.312Schristos
1401.388Suebayasi#define NKL4_KIMG_ENTRIES	1
1411.388Suebayasi#define NKL3_KIMG_ENTRIES	1
1421.143Schristos#define NKL2_KIMG_ENTRIES	48
1431.143Schristos
1441.312Schristos/*
1451.388Suebayasi * Since kva space is below the kernel in its entirety, we start off
1461.143Schristos * with zero entries on each level.
1471.165Sthorpej */
1481.130Sjdolecek#define NKL4_START_ENTRIES	0
1491.294Sdarran#define NKL3_START_ENTRIES	0
1501.294Sdarran#define NKL2_START_ENTRIES	0
1511.361Sriz#define NKL1_START_ENTRIES	0
1521.294Sdarran
1531.294Sdarran#define PTP_MASK_INITIALIZER	{ L1_FRAME, L2_FRAME, L3_FRAME, L4_FRAME }
1541.294Sdarran#define PTP_SHIFT_INITIALIZER	{ L1_SHIFT, L2_SHIFT, L3_SHIFT, L4_SHIFT }
1551.361Sriz#define NKPTP_INITIALIZER	{ NKL1_START_ENTRIES, NKL2_START_ENTRIES, \
1561.294Sdarran				  NKL3_START_ENTRIES, NKL4_START_ENTRIES }
1571.294Sdarran#define NKPTPMAX_INITIALIZER	{ NKL1_MAX_ENTRIES, NKL2_MAX_ENTRIES, \
1581.294Sdarran				  NKL3_MAX_ENTRIES, NKL4_MAX_ENTRIES }
1591.361Sriz#define NBPD_INITIALIZER	{ NBPD_L1, NBPD_L2, NBPD_L3, NBPD_L4 }
1601.294Sdarran#define PDES_INITIALIZER	{ L2_BASE, L3_BASE, L4_BASE }
1611.294Sdarran
1621.294Sdarran#define PTP_LEVELS	4
1631.294Sdarran
1641.294Sdarran/*
1651.130Sjdolecek * PG_AVAIL usage: we make use of the ignored bits of the PTE
1661.130Sjdolecek */
1671.130Sjdolecek
1681.130Sjdolecek#define PG_W		PG_AVAIL1	/* "wired" mapping */
1691.130Sjdolecek#define PG_PVLIST	PG_AVAIL2	/* mapping has entry on pvlist */
1701.130Sjdolecek/* PG_AVAIL3 not used */
1711.130Sjdolecek
1721.130Sjdolecek#define	PG_X		0		/* dummy */
1731.130Sjdolecek
1741.138Slukemvoid svs_pmap_sync(struct pmap *, int);
1751.138Slukemvoid svs_lwp_switch(struct lwp *, struct lwp *);
1761.138Slukemvoid svs_pdir_switch(struct pmap *);
1771.282Sadvoid svs_init(void);
1781.130Sjdolecekextern bool svs_enabled;
1791.130Sjdolecek
1801.282Sad#include <x86/pmap.h>
1811.282Sad
1821.130Sjdolecek#ifndef XEN
1831.138Slukem#define pmap_pa2pte(a)			(a)
1841.282Sad#define pmap_pte2pa(a)			((a) & PG_FRAME)
1851.282Sad#define pmap_pte_set(p, n)		do { *(p) = (n); } while (0)
1861.130Sjdolecek#define pmap_pte_cas(p, o, n)		atomic_cas_64((p), (o), (n))
1871.130Sjdolecek#define pmap_pte_testset(p, n)		\
1881.203Schristos    atomic_swap_ulong((volatile unsigned long *)p, n)
1891.203Schristos#define pmap_pte_setbits(p, b)		\
1901.203Schristos    atomic_or_ulong((volatile unsigned long *)p, b)
1911.203Schristos#define pmap_pte_clearbits(p, b)	\
1921.173Schristos    atomic_and_ulong((volatile unsigned long *)p, ~(b))
1931.282Sad#define pmap_pte_flush()		/* nothing */
1941.291Srmind#else
1951.371Smanuextern kmutex_t pte_lock;
1961.371Smanu
1971.371Smanustatic __inline pt_entry_t
1981.371Smanupmap_pa2pte(paddr_t pa)
1991.371Smanu{
2001.133Smycroft	return (pt_entry_t)xpmap_ptom_masked(pa);
2011.291Srmind}
2021.291Srmind
2031.291Srmindstatic __inline paddr_t
2041.291Srmindpmap_pte2pa(pt_entry_t pte)
2051.133Smycroft{
2061.291Srmind	return xpmap_mtop_masked(pte & PG_FRAME);
2071.124Sjdolecek}
2081.291Srmind
2091.124Sjdolecekstatic __inline void
2101.291Srmindpmap_pte_set(pt_entry_t *pte, pt_entry_t npte)
2111.124Sjdolecek{
2121.291Srmind	int s = splvm();
2131.291Srmind	xpq_queue_pte_update(xpmap_ptetomach(pte), npte);
2141.291Srmind	splx(s);
2151.291Srmind}
2161.291Srmind
2171.291Srmindstatic __inline pt_entry_t
2181.291Srmindpmap_pte_cas(volatile pt_entry_t *ptep, pt_entry_t o, pt_entry_t n)
2191.291Srmind{
2201.291Srmind	pt_entry_t opte;
2211.291Srmind
2221.291Srmind	mutex_enter(&pte_lock);
2231.291Srmind	opte = *ptep;
2241.133Smycroft	if (opte == o) {
2251.291Srmind		xpq_queue_pte_update(xpmap_ptetomach(__UNVOLATILE(ptep)), n);
2261.133Smycroft		xpq_flush_queue();
2271.291Srmind	}
2281.133Smycroft
2291.291Srmind	mutex_exit(&pte_lock);
2301.291Srmind	return opte;
2311.291Srmind}
2321.291Srmind
2331.291Srmindstatic __inline pt_entry_t
2341.291Srmindpmap_pte_testset(volatile pt_entry_t *pte, pt_entry_t npte)
2351.124Sjdolecek{
2361.124Sjdolecek	pt_entry_t opte;
2371.55Scgd
2381.130Sjdolecek	mutex_enter(&pte_lock);
2391.130Sjdolecek	opte = *pte;
2401.130Sjdolecek	xpq_queue_pte_update(xpmap_ptetomach(__UNVOLATILE(pte)), npte);
2411.352Srmind	xpq_flush_queue();
2421.352Srmind	mutex_exit(&pte_lock);
2431.352Srmind	return opte;
2441.259Sad}
2451.337Smartin
2461.337Smartinstatic __inline void
2471.337Smartinpmap_pte_setbits(volatile pt_entry_t *pte, pt_entry_t bits)
2481.337Smartin{
2491.337Smartin	mutex_enter(&pte_lock);
2501.337Smartin	xpq_queue_pte_update(xpmap_ptetomach(__UNVOLATILE(pte)), (*pte) | bits);
2511.337Smartin	xpq_flush_queue();
2521.337Smartin	mutex_exit(&pte_lock);
2531.337Smartin}
2541.337Smartin
2551.337Smartinstatic __inline void
2561.337Smartinpmap_pte_clearbits(volatile pt_entry_t *pte, pt_entry_t bits)
2571.337Smartin{
2581.396Suebayasi	mutex_enter(&pte_lock);
2591.337Smartin	xpq_queue_pte_update(xpmap_ptetomach(__UNVOLATILE(pte)),
2601.337Smartin	    (*pte) & ~bits);
2611.337Smartin	xpq_flush_queue();
2621.337Smartin	mutex_exit(&pte_lock);
2631.337Smartin}
2641.337Smartin
2651.337Smartinstatic __inline void
2661.337Smartinpmap_pte_flush(void)
2671.337Smartin{
2681.348Smartin	int s = splvm();
2691.337Smartin	xpq_flush_queue();
2701.337Smartin	splx(s);
2711.337Smartin}
2721.337Smartin#endif
2731.337Smartin
2741.337Smartin#ifdef __HAVE_DIRECT_MAP
2751.348Smartin#define PMAP_DIRECT
2761.337Smartin
2771.337Smartinstatic __inline int
2781.277Sadpmap_direct_process(paddr_t pa, voff_t pgoff, size_t len,
2791.277Sad    int (*process)(void *, size_t, void *), void *arg)
2801.277Sad{
2811.277Sad	vaddr_t va = PMAP_DIRECT_MAP(pa);
2821.277Sad
2831.277Sad	return process((void *)(va + pgoff), len, arg);
2841.277Sad}
2851.277Sad
2861.277Sad#endif /* __HAVE_DIRECT_MAP */
2871.277Sad
2881.277Sadvoid pmap_changeprot_local(vaddr_t, vm_prot_t);
2891.277Sad
2901.277Sad#include <x86/pmap_pv.h>
2911.277Sad
2921.277Sad#define	__HAVE_VM_PAGE_MD
2931.277Sad#define	VM_MDPAGE_INIT(pg) \
2941.277Sad	memset(&(pg)->mdpage, 0, sizeof((pg)->mdpage)); \
2951.277Sad	PMAP_PAGE_INIT(&(pg)->mdpage.mp_pp)
2961.277Sad
2971.277Sadstruct vm_page_md {
2981.277Sad	struct pmap_page mp_pp;
2991.277Sad};
3001.277Sad
3011.130Sjdolecek#else	/*	!__x86_64__	*/
3021.55Scgd
3031.55Scgd#include <i386/pmap.h>
3041.55Scgd
3051.55Scgd#endif	/*	__x86_64__	*/
3061.55Scgd
3071.55Scgd#endif	/* _AMD64_PMAP_H_ */
3081.212Schristos