xref: /freebsd/sys/i386/i386/pmap_base.c (revision 1f1b2286fd5ae4cd7f8e6412723201e92d28771a)
19a527560SKonstantin Belousov /*-
29a527560SKonstantin Belousov  * SPDX-License-Identifier: BSD-4-Clause
39a527560SKonstantin Belousov  *
49a527560SKonstantin Belousov  * Copyright (c) 1991 Regents of the University of California.
59a527560SKonstantin Belousov  * All rights reserved.
69a527560SKonstantin Belousov  * Copyright (c) 1994 John S. Dyson
79a527560SKonstantin Belousov  * All rights reserved.
89a527560SKonstantin Belousov  * Copyright (c) 1994 David Greenman
99a527560SKonstantin Belousov  * All rights reserved.
109a527560SKonstantin Belousov  * Copyright (c) 2005-2010 Alan L. Cox <alc@cs.rice.edu>
119a527560SKonstantin Belousov  * All rights reserved.
129a527560SKonstantin Belousov  *
139a527560SKonstantin Belousov  * This code is derived from software contributed to Berkeley by
149a527560SKonstantin Belousov  * the Systems Programming Group of the University of Utah Computer
159a527560SKonstantin Belousov  * Science Department and William Jolitz of UUNET Technologies Inc.
169a527560SKonstantin Belousov  *
179a527560SKonstantin Belousov  * Redistribution and use in source and binary forms, with or without
189a527560SKonstantin Belousov  * modification, are permitted provided that the following conditions
199a527560SKonstantin Belousov  * are met:
209a527560SKonstantin Belousov  * 1. Redistributions of source code must retain the above copyright
219a527560SKonstantin Belousov  *    notice, this list of conditions and the following disclaimer.
229a527560SKonstantin Belousov  * 2. Redistributions in binary form must reproduce the above copyright
239a527560SKonstantin Belousov  *    notice, this list of conditions and the following disclaimer in the
249a527560SKonstantin Belousov  *    documentation and/or other materials provided with the distribution.
259a527560SKonstantin Belousov  * 3. All advertising materials mentioning features or use of this software
269a527560SKonstantin Belousov  *    must display the following acknowledgement:
279a527560SKonstantin Belousov  *	This product includes software developed by the University of
289a527560SKonstantin Belousov  *	California, Berkeley and its contributors.
299a527560SKonstantin Belousov  * 4. Neither the name of the University nor the names of its contributors
309a527560SKonstantin Belousov  *    may be used to endorse or promote products derived from this software
319a527560SKonstantin Belousov  *    without specific prior written permission.
329a527560SKonstantin Belousov  *
339a527560SKonstantin Belousov  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
349a527560SKonstantin Belousov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
359a527560SKonstantin Belousov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
369a527560SKonstantin Belousov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
379a527560SKonstantin Belousov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
389a527560SKonstantin Belousov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
399a527560SKonstantin Belousov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
409a527560SKonstantin Belousov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
419a527560SKonstantin Belousov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
429a527560SKonstantin Belousov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
439a527560SKonstantin Belousov  * SUCH DAMAGE.
449a527560SKonstantin Belousov  */
459a527560SKonstantin Belousov /*-
469a527560SKonstantin Belousov  * Copyright (c) 2003 Networks Associates Technology, Inc.
479a527560SKonstantin Belousov  * All rights reserved.
489a527560SKonstantin Belousov  * Copyright (c) 2018 The FreeBSD Foundation
499a527560SKonstantin Belousov  * All rights reserved.
509a527560SKonstantin Belousov  *
519a527560SKonstantin Belousov  * This software was developed for the FreeBSD Project by Jake Burkholder,
529a527560SKonstantin Belousov  * Safeport Network Services, and Network Associates Laboratories, the
539a527560SKonstantin Belousov  * Security Research Division of Network Associates, Inc. under
549a527560SKonstantin Belousov  * DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"), as part of the DARPA
559a527560SKonstantin Belousov  * CHATS research program.
569a527560SKonstantin Belousov  *
579a527560SKonstantin Belousov  * Portions of this software were developed by
589a527560SKonstantin Belousov  * Konstantin Belousov <kib@FreeBSD.org> under sponsorship from
599a527560SKonstantin Belousov  * the FreeBSD Foundation.
609a527560SKonstantin Belousov  *
619a527560SKonstantin Belousov  * Redistribution and use in source and binary forms, with or without
629a527560SKonstantin Belousov  * modification, are permitted provided that the following conditions
639a527560SKonstantin Belousov  * are met:
649a527560SKonstantin Belousov  * 1. Redistributions of source code must retain the above copyright
659a527560SKonstantin Belousov  *    notice, this list of conditions and the following disclaimer.
669a527560SKonstantin Belousov  * 2. Redistributions in binary form must reproduce the above copyright
679a527560SKonstantin Belousov  *    notice, this list of conditions and the following disclaimer in the
689a527560SKonstantin Belousov  *    documentation and/or other materials provided with the distribution.
699a527560SKonstantin Belousov  *
709a527560SKonstantin Belousov  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
719a527560SKonstantin Belousov  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
729a527560SKonstantin Belousov  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
739a527560SKonstantin Belousov  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
749a527560SKonstantin Belousov  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
759a527560SKonstantin Belousov  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
769a527560SKonstantin Belousov  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
779a527560SKonstantin Belousov  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
789a527560SKonstantin Belousov  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
799a527560SKonstantin Belousov  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
809a527560SKonstantin Belousov  * SUCH DAMAGE.
819a527560SKonstantin Belousov  */
829a527560SKonstantin Belousov 
839a527560SKonstantin Belousov #include <sys/cdefs.h>
849a527560SKonstantin Belousov #include "opt_apic.h"
859a527560SKonstantin Belousov #include "opt_cpu.h"
869a527560SKonstantin Belousov #include "opt_pmap.h"
879a527560SKonstantin Belousov #include "opt_smp.h"
889a527560SKonstantin Belousov #include "opt_vm.h"
899a527560SKonstantin Belousov 
909a527560SKonstantin Belousov #include <sys/param.h>
919a527560SKonstantin Belousov #include <sys/systm.h>
929a527560SKonstantin Belousov #include <sys/kernel.h>
939a527560SKonstantin Belousov #include <sys/vmmeter.h>
949a527560SKonstantin Belousov #include <sys/sysctl.h>
952648ed92SKonstantin Belousov #include <machine/bootinfo.h>
969a527560SKonstantin Belousov #include <machine/cpu.h>
979a527560SKonstantin Belousov #include <machine/cputypes.h>
989a527560SKonstantin Belousov #include <machine/md_var.h>
999a527560SKonstantin Belousov #ifdef DEV_APIC
1009a527560SKonstantin Belousov #include <sys/bus.h>
1019a527560SKonstantin Belousov #include <machine/intr_machdep.h>
1029a527560SKonstantin Belousov #include <x86/apicvar.h>
1039a527560SKonstantin Belousov #endif
1049a527560SKonstantin Belousov #include <x86/ifunc.h>
1059a527560SKonstantin Belousov 
1067029da5cSPawel Biernacki static SYSCTL_NODE(_vm, OID_AUTO, pmap, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
1077029da5cSPawel Biernacki     "VM/pmap parameters");
1089a527560SKonstantin Belousov 
1099a527560SKonstantin Belousov #include <machine/vmparam.h>
1109a527560SKonstantin Belousov #include <vm/vm.h>
1119a527560SKonstantin Belousov #include <vm/vm_page.h>
1129a527560SKonstantin Belousov #include <vm/pmap.h>
1139a527560SKonstantin Belousov #include <machine/pmap_base.h>
1149a527560SKonstantin Belousov 
1159a527560SKonstantin Belousov vm_offset_t virtual_avail;	/* VA of first avail page (after kernel bss) */
1169a527560SKonstantin Belousov vm_offset_t virtual_end;	/* VA of last avail page (end of kernel AS) */
1179a527560SKonstantin Belousov 
1189a527560SKonstantin Belousov int unmapped_buf_allowed = 1;
1199a527560SKonstantin Belousov 
1209a527560SKonstantin Belousov int pti;
1219a527560SKonstantin Belousov 
1229a527560SKonstantin Belousov u_long physfree;	/* phys addr of next free page */
1239a527560SKonstantin Belousov u_long vm86phystk;	/* PA of vm86/bios stack */
1249a527560SKonstantin Belousov u_long vm86paddr;	/* address of vm86 region */
1259a527560SKonstantin Belousov int vm86pa;		/* phys addr of vm86 region */
1269a527560SKonstantin Belousov u_long KERNend;		/* phys addr end of kernel (just after bss) */
1279a527560SKonstantin Belousov u_long KPTphys;		/* phys addr of kernel page tables */
1289a527560SKonstantin Belousov caddr_t ptvmmap = 0;
1299a527560SKonstantin Belousov vm_offset_t kernel_vm_end;
1309a527560SKonstantin Belousov 
1319a527560SKonstantin Belousov int i386_pmap_VM_NFREEORDER;
1329a527560SKonstantin Belousov int i386_pmap_VM_LEVEL_0_ORDER;
1339a527560SKonstantin Belousov int i386_pmap_PDRSHIFT;
1349a527560SKonstantin Belousov 
1359a527560SKonstantin Belousov int pat_works = 1;
1369a527560SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, pat_works, CTLFLAG_RD,
137c7301c6bSKonstantin Belousov     &pat_works, 0,
1389a527560SKonstantin Belousov     "Is page attribute table fully functional?");
1399a527560SKonstantin Belousov 
1409a527560SKonstantin Belousov int pg_ps_enabled = 1;
1419a527560SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_enabled, CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
1429a527560SKonstantin Belousov     &pg_ps_enabled, 0,
1439a527560SKonstantin Belousov     "Are large page mappings enabled?");
1449a527560SKonstantin Belousov 
1459a527560SKonstantin Belousov int pv_entry_max = 0;
1469a527560SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_max, CTLFLAG_RD,
1479a527560SKonstantin Belousov     &pv_entry_max, 0,
1489a527560SKonstantin Belousov     "Max number of PV entries");
1499a527560SKonstantin Belousov 
1509a527560SKonstantin Belousov int pv_entry_count = 0;
1519a527560SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_count, CTLFLAG_RD,
1529a527560SKonstantin Belousov     &pv_entry_count, 0,
1539a527560SKonstantin Belousov     "Current number of pv entries");
1549a527560SKonstantin Belousov 
1559a527560SKonstantin Belousov #ifndef PMAP_SHPGPERPROC
1569a527560SKonstantin Belousov #define PMAP_SHPGPERPROC 200
1579a527560SKonstantin Belousov #endif
1589a527560SKonstantin Belousov 
1599a527560SKonstantin Belousov int shpgperproc = PMAP_SHPGPERPROC;
1609a527560SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, shpgperproc, CTLFLAG_RD,
1619a527560SKonstantin Belousov     &shpgperproc, 0,
1629a527560SKonstantin Belousov     "Page share factor per proc");
1639a527560SKonstantin Belousov 
1647029da5cSPawel Biernacki static SYSCTL_NODE(_vm_pmap, OID_AUTO, pde, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
1659a527560SKonstantin Belousov     "2/4MB page mapping counters");
1669a527560SKonstantin Belousov 
1679a527560SKonstantin Belousov u_long pmap_pde_demotions;
1689a527560SKonstantin Belousov SYSCTL_ULONG(_vm_pmap_pde, OID_AUTO, demotions, CTLFLAG_RD,
1699a527560SKonstantin Belousov     &pmap_pde_demotions, 0,
1709a527560SKonstantin Belousov     "2/4MB page demotions");
1719a527560SKonstantin Belousov 
1729a527560SKonstantin Belousov u_long pmap_pde_mappings;
1739a527560SKonstantin Belousov SYSCTL_ULONG(_vm_pmap_pde, OID_AUTO, mappings, CTLFLAG_RD,
1749a527560SKonstantin Belousov     &pmap_pde_mappings, 0,
1759a527560SKonstantin Belousov     "2/4MB page mappings");
1769a527560SKonstantin Belousov 
1779a527560SKonstantin Belousov u_long pmap_pde_p_failures;
1789a527560SKonstantin Belousov SYSCTL_ULONG(_vm_pmap_pde, OID_AUTO, p_failures, CTLFLAG_RD,
1799a527560SKonstantin Belousov     &pmap_pde_p_failures, 0,
1809a527560SKonstantin Belousov     "2/4MB page promotion failures");
1819a527560SKonstantin Belousov 
1829a527560SKonstantin Belousov u_long pmap_pde_promotions;
1839a527560SKonstantin Belousov SYSCTL_ULONG(_vm_pmap_pde, OID_AUTO, promotions, CTLFLAG_RD,
1849a527560SKonstantin Belousov     &pmap_pde_promotions, 0,
1859a527560SKonstantin Belousov     "2/4MB page promotions");
1869a527560SKonstantin Belousov 
1879a527560SKonstantin Belousov #ifdef SMP
1889a527560SKonstantin Belousov int PMAP1changedcpu;
1899a527560SKonstantin Belousov SYSCTL_INT(_debug, OID_AUTO, PMAP1changedcpu, CTLFLAG_RD,
1909a527560SKonstantin Belousov     &PMAP1changedcpu, 0,
1919a527560SKonstantin Belousov     "Number of times pmap_pte_quick changed CPU with same PMAP1");
1929a527560SKonstantin Belousov #endif
1939a527560SKonstantin Belousov 
1949a527560SKonstantin Belousov int PMAP1changed;
1959a527560SKonstantin Belousov SYSCTL_INT(_debug, OID_AUTO, PMAP1changed, CTLFLAG_RD,
1969a527560SKonstantin Belousov     &PMAP1changed, 0,
1979a527560SKonstantin Belousov     "Number of times pmap_pte_quick changed PMAP1");
1989a527560SKonstantin Belousov int PMAP1unchanged;
1999a527560SKonstantin Belousov SYSCTL_INT(_debug, OID_AUTO, PMAP1unchanged, CTLFLAG_RD,
2009a527560SKonstantin Belousov     &PMAP1unchanged, 0,
2019a527560SKonstantin Belousov     "Number of times pmap_pte_quick didn't change PMAP1");
2029a527560SKonstantin Belousov 
2039a527560SKonstantin Belousov static int
kvm_size(SYSCTL_HANDLER_ARGS)2049a527560SKonstantin Belousov kvm_size(SYSCTL_HANDLER_ARGS)
2059a527560SKonstantin Belousov {
2069a527560SKonstantin Belousov 	unsigned long ksize;
2079a527560SKonstantin Belousov 
2089a527560SKonstantin Belousov 	ksize = VM_MAX_KERNEL_ADDRESS - KERNBASE;
2099a527560SKonstantin Belousov 	return (sysctl_handle_long(oidp, &ksize, 0, req));
2109a527560SKonstantin Belousov }
2119a527560SKonstantin Belousov SYSCTL_PROC(_vm, OID_AUTO, kvm_size, CTLTYPE_LONG | CTLFLAG_RD | CTLFLAG_MPSAFE,
2129a527560SKonstantin Belousov     0, 0, kvm_size, "IU",
2139a527560SKonstantin Belousov     "Size of KVM");
2149a527560SKonstantin Belousov 
2159a527560SKonstantin Belousov static int
kvm_free(SYSCTL_HANDLER_ARGS)2169a527560SKonstantin Belousov kvm_free(SYSCTL_HANDLER_ARGS)
2179a527560SKonstantin Belousov {
2189a527560SKonstantin Belousov 	unsigned long kfree;
2199a527560SKonstantin Belousov 
2209a527560SKonstantin Belousov 	kfree = VM_MAX_KERNEL_ADDRESS - kernel_vm_end;
2219a527560SKonstantin Belousov 	return (sysctl_handle_long(oidp, &kfree, 0, req));
2229a527560SKonstantin Belousov }
2239a527560SKonstantin Belousov SYSCTL_PROC(_vm, OID_AUTO, kvm_free, CTLTYPE_LONG | CTLFLAG_RD | CTLFLAG_MPSAFE,
2249a527560SKonstantin Belousov     0, 0, kvm_free, "IU",
2259a527560SKonstantin Belousov     "Amount of KVM free");
2269a527560SKonstantin Belousov 
2279a527560SKonstantin Belousov #ifdef PV_STATS
2289a527560SKonstantin Belousov int pc_chunk_count, pc_chunk_allocs, pc_chunk_frees, pc_chunk_tryfail;
2299a527560SKonstantin Belousov long pv_entry_frees, pv_entry_allocs;
2309a527560SKonstantin Belousov int pv_entry_spare;
2319a527560SKonstantin Belousov 
2329a527560SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_count, CTLFLAG_RD,
2339a527560SKonstantin Belousov     &pc_chunk_count, 0,
2349a527560SKonstantin Belousov     "Current number of pv entry chunks");
2359a527560SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_allocs, CTLFLAG_RD,
2369a527560SKonstantin Belousov     &pc_chunk_allocs, 0,
2379a527560SKonstantin Belousov     "Current number of pv entry chunks allocated");
2389a527560SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_frees, CTLFLAG_RD,
2399a527560SKonstantin Belousov     &pc_chunk_frees, 0,
2409a527560SKonstantin Belousov     "Current number of pv entry chunks frees");
2419a527560SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, pc_chunk_tryfail, CTLFLAG_RD,
2429a527560SKonstantin Belousov     &pc_chunk_tryfail, 0,
2439a527560SKonstantin Belousov     "Number of times tried to get a chunk page but failed.");
2449a527560SKonstantin Belousov SYSCTL_LONG(_vm_pmap, OID_AUTO, pv_entry_frees, CTLFLAG_RD,
2459a527560SKonstantin Belousov     &pv_entry_frees, 0,
2469a527560SKonstantin Belousov     "Current number of pv entry frees");
2479a527560SKonstantin Belousov SYSCTL_LONG(_vm_pmap, OID_AUTO, pv_entry_allocs, CTLFLAG_RD,
2489a527560SKonstantin Belousov     &pv_entry_allocs, 0,
2499a527560SKonstantin Belousov     "Current number of pv entry allocs");
2509a527560SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, pv_entry_spare, CTLFLAG_RD,
2519a527560SKonstantin Belousov     &pv_entry_spare, 0,
2529a527560SKonstantin Belousov     "Current number of spare pv entries");
2539a527560SKonstantin Belousov #endif
2549a527560SKonstantin Belousov 
2559a527560SKonstantin Belousov struct pmap kernel_pmap_store;
2569a527560SKonstantin Belousov static struct pmap_methods *pmap_methods_ptr;
2579a527560SKonstantin Belousov 
258b223a692SKonstantin Belousov static int
sysctl_kmaps(SYSCTL_HANDLER_ARGS)259b223a692SKonstantin Belousov sysctl_kmaps(SYSCTL_HANDLER_ARGS)
260b223a692SKonstantin Belousov {
261b223a692SKonstantin Belousov 	return (pmap_methods_ptr->pm_sysctl_kmaps(oidp, arg1, arg2, req));
262b223a692SKonstantin Belousov }
263b223a692SKonstantin Belousov SYSCTL_OID(_vm_pmap, OID_AUTO, kernel_maps,
2641dce7d9eSJohn Baldwin     CTLTYPE_STRING | CTLFLAG_RD | CTLFLAG_MPSAFE | CTLFLAG_SKIP,
265b223a692SKonstantin Belousov     NULL, 0, sysctl_kmaps, "A",
266b223a692SKonstantin Belousov     "Dump kernel address layout");
267b223a692SKonstantin Belousov 
2689a527560SKonstantin Belousov /*
2699a527560SKonstantin Belousov  * Initialize a vm_page's machine-dependent fields.
2709a527560SKonstantin Belousov  */
2719a527560SKonstantin Belousov void
pmap_page_init(vm_page_t m)2729a527560SKonstantin Belousov pmap_page_init(vm_page_t m)
2739a527560SKonstantin Belousov {
2749a527560SKonstantin Belousov 
2759a527560SKonstantin Belousov 	TAILQ_INIT(&m->md.pv_list);
2769a527560SKonstantin Belousov 	m->md.pat_mode = PAT_WRITE_BACK;
2779a527560SKonstantin Belousov }
2789a527560SKonstantin Belousov 
2799a527560SKonstantin Belousov void
invltlb_glob(void)2809a527560SKonstantin Belousov invltlb_glob(void)
2819a527560SKonstantin Belousov {
2829a527560SKonstantin Belousov 
2839a527560SKonstantin Belousov 	invltlb();
2849a527560SKonstantin Belousov }
2859a527560SKonstantin Belousov 
2869a527560SKonstantin Belousov static void pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva,
2879a527560SKonstantin Belousov     vm_offset_t eva);
2889a527560SKonstantin Belousov static void pmap_invalidate_cache_range_all(vm_offset_t sva,
2899a527560SKonstantin Belousov     vm_offset_t eva);
2909a527560SKonstantin Belousov 
2919a527560SKonstantin Belousov void
pmap_flush_page(vm_page_t m)2929a527560SKonstantin Belousov pmap_flush_page(vm_page_t m)
2939a527560SKonstantin Belousov {
2949a527560SKonstantin Belousov 
2959a527560SKonstantin Belousov 	pmap_methods_ptr->pm_flush_page(m);
2969a527560SKonstantin Belousov }
2979a527560SKonstantin Belousov 
2987c5a46a1SKonstantin Belousov DEFINE_IFUNC(, void, pmap_invalidate_cache_range, (vm_offset_t, vm_offset_t))
2999a527560SKonstantin Belousov {
3009a527560SKonstantin Belousov 
3019a527560SKonstantin Belousov 	if ((cpu_feature & CPUID_SS) != 0)
3029a527560SKonstantin Belousov 		return (pmap_invalidate_cache_range_selfsnoop);
3039a527560SKonstantin Belousov 	if ((cpu_feature & CPUID_CLFSH) != 0)
3049a527560SKonstantin Belousov 		return (pmap_force_invalidate_cache_range);
3059a527560SKonstantin Belousov 	return (pmap_invalidate_cache_range_all);
3069a527560SKonstantin Belousov }
3079a527560SKonstantin Belousov 
3089a527560SKonstantin Belousov #define	PMAP_CLFLUSH_THRESHOLD	(2 * 1024 * 1024)
3099a527560SKonstantin Belousov 
3109a527560SKonstantin Belousov static void
pmap_invalidate_cache_range_check_align(vm_offset_t sva,vm_offset_t eva)3119a527560SKonstantin Belousov pmap_invalidate_cache_range_check_align(vm_offset_t sva, vm_offset_t eva)
3129a527560SKonstantin Belousov {
3139a527560SKonstantin Belousov 
3149a527560SKonstantin Belousov 	KASSERT((sva & PAGE_MASK) == 0,
3159a527560SKonstantin Belousov 	    ("pmap_invalidate_cache_range: sva not page-aligned"));
3169a527560SKonstantin Belousov 	KASSERT((eva & PAGE_MASK) == 0,
3179a527560SKonstantin Belousov 	    ("pmap_invalidate_cache_range: eva not page-aligned"));
3189a527560SKonstantin Belousov }
3199a527560SKonstantin Belousov 
3209a527560SKonstantin Belousov static void
pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva,vm_offset_t eva)3219a527560SKonstantin Belousov pmap_invalidate_cache_range_selfsnoop(vm_offset_t sva, vm_offset_t eva)
3229a527560SKonstantin Belousov {
3239a527560SKonstantin Belousov 
3249a527560SKonstantin Belousov 	pmap_invalidate_cache_range_check_align(sva, eva);
3259a527560SKonstantin Belousov }
3269a527560SKonstantin Belousov 
3279a527560SKonstantin Belousov void
pmap_force_invalidate_cache_range(vm_offset_t sva,vm_offset_t eva)3289a527560SKonstantin Belousov pmap_force_invalidate_cache_range(vm_offset_t sva, vm_offset_t eva)
3299a527560SKonstantin Belousov {
3309a527560SKonstantin Belousov 
3319a527560SKonstantin Belousov 	sva &= ~(vm_offset_t)(cpu_clflush_line_size - 1);
3329a527560SKonstantin Belousov 	if (eva - sva >= PMAP_CLFLUSH_THRESHOLD) {
3339a527560SKonstantin Belousov 		/*
3349a527560SKonstantin Belousov 		 * The supplied range is bigger than 2MB.
3359a527560SKonstantin Belousov 		 * Globally invalidate cache.
3369a527560SKonstantin Belousov 		 */
3379a527560SKonstantin Belousov 		pmap_invalidate_cache();
3389a527560SKonstantin Belousov 		return;
3399a527560SKonstantin Belousov 	}
3409a527560SKonstantin Belousov 
3419a527560SKonstantin Belousov #ifdef DEV_APIC
3429a527560SKonstantin Belousov 	/*
3439a527560SKonstantin Belousov 	 * XXX: Some CPUs fault, hang, or trash the local APIC
3449a527560SKonstantin Belousov 	 * registers if we use CLFLUSH on the local APIC
3459a527560SKonstantin Belousov 	 * range.  The local APIC is always uncached, so we
3469a527560SKonstantin Belousov 	 * don't need to flush for that range anyway.
3479a527560SKonstantin Belousov 	 */
3489a527560SKonstantin Belousov 	if (pmap_kextract(sva) == lapic_paddr)
3499a527560SKonstantin Belousov 		return;
3509a527560SKonstantin Belousov #endif
3519a527560SKonstantin Belousov 
3529a527560SKonstantin Belousov 	if ((cpu_stdext_feature & CPUID_STDEXT_CLFLUSHOPT) != 0) {
3539a527560SKonstantin Belousov 		/*
3549a527560SKonstantin Belousov 		 * Do per-cache line flush.  Use the sfence
3559a527560SKonstantin Belousov 		 * instruction to insure that previous stores are
3569a527560SKonstantin Belousov 		 * included in the write-back.  The processor
3579a527560SKonstantin Belousov 		 * propagates flush to other processors in the cache
3589a527560SKonstantin Belousov 		 * coherence domain.
3599a527560SKonstantin Belousov 		 */
3609a527560SKonstantin Belousov 		sfence();
3619a527560SKonstantin Belousov 		for (; sva < eva; sva += cpu_clflush_line_size)
3629a527560SKonstantin Belousov 			clflushopt(sva);
3639a527560SKonstantin Belousov 		sfence();
3649a527560SKonstantin Belousov 	} else {
3659a527560SKonstantin Belousov 		/*
3669a527560SKonstantin Belousov 		 * Writes are ordered by CLFLUSH on Intel CPUs.
3679a527560SKonstantin Belousov 		 */
3689a527560SKonstantin Belousov 		if (cpu_vendor_id != CPU_VENDOR_INTEL)
3699a527560SKonstantin Belousov 			mfence();
3709a527560SKonstantin Belousov 		for (; sva < eva; sva += cpu_clflush_line_size)
3719a527560SKonstantin Belousov 			clflush(sva);
3729a527560SKonstantin Belousov 		if (cpu_vendor_id != CPU_VENDOR_INTEL)
3739a527560SKonstantin Belousov 			mfence();
3749a527560SKonstantin Belousov 	}
3759a527560SKonstantin Belousov }
3769a527560SKonstantin Belousov 
3779a527560SKonstantin Belousov static void
pmap_invalidate_cache_range_all(vm_offset_t sva,vm_offset_t eva)3789a527560SKonstantin Belousov pmap_invalidate_cache_range_all(vm_offset_t sva, vm_offset_t eva)
3799a527560SKonstantin Belousov {
3809a527560SKonstantin Belousov 
3819a527560SKonstantin Belousov 	pmap_invalidate_cache_range_check_align(sva, eva);
3829a527560SKonstantin Belousov 	pmap_invalidate_cache();
3839a527560SKonstantin Belousov }
3849a527560SKonstantin Belousov 
3859a527560SKonstantin Belousov void
pmap_invalidate_cache_pages(vm_page_t * pages,int count)3869a527560SKonstantin Belousov pmap_invalidate_cache_pages(vm_page_t *pages, int count)
3879a527560SKonstantin Belousov {
3889a527560SKonstantin Belousov 	int i;
3899a527560SKonstantin Belousov 
3909a527560SKonstantin Belousov 	if (count >= PMAP_CLFLUSH_THRESHOLD / PAGE_SIZE ||
3919a527560SKonstantin Belousov 	    (cpu_feature & CPUID_CLFSH) == 0) {
3929a527560SKonstantin Belousov 		pmap_invalidate_cache();
3939a527560SKonstantin Belousov 	} else {
3949a527560SKonstantin Belousov 		for (i = 0; i < count; i++)
3959a527560SKonstantin Belousov 			pmap_flush_page(pages[i]);
3969a527560SKonstantin Belousov 	}
3979a527560SKonstantin Belousov }
3989a527560SKonstantin Belousov 
3999a527560SKonstantin Belousov void
pmap_ksetrw(vm_offset_t va)4009a527560SKonstantin Belousov pmap_ksetrw(vm_offset_t va)
4019a527560SKonstantin Belousov {
4029a527560SKonstantin Belousov 
4039a527560SKonstantin Belousov 	pmap_methods_ptr->pm_ksetrw(va);
4049a527560SKonstantin Belousov }
4059a527560SKonstantin Belousov 
4069a527560SKonstantin Belousov void
pmap_remap_lower(bool enable)4079a527560SKonstantin Belousov pmap_remap_lower(bool enable)
4089a527560SKonstantin Belousov {
4099a527560SKonstantin Belousov 
4109a527560SKonstantin Belousov 	pmap_methods_ptr->pm_remap_lower(enable);
4119a527560SKonstantin Belousov }
4129a527560SKonstantin Belousov 
4139a527560SKonstantin Belousov void
pmap_remap_lowptdi(bool enable)4149a527560SKonstantin Belousov pmap_remap_lowptdi(bool enable)
4159a527560SKonstantin Belousov {
4169a527560SKonstantin Belousov 
4179a527560SKonstantin Belousov 	pmap_methods_ptr->pm_remap_lowptdi(enable);
4189a527560SKonstantin Belousov }
4199a527560SKonstantin Belousov 
4209a527560SKonstantin Belousov void
pmap_align_superpage(vm_object_t object,vm_ooffset_t offset,vm_offset_t * addr,vm_size_t size)4219a527560SKonstantin Belousov pmap_align_superpage(vm_object_t object, vm_ooffset_t offset,
4229a527560SKonstantin Belousov     vm_offset_t *addr, vm_size_t size)
4239a527560SKonstantin Belousov {
4249a527560SKonstantin Belousov 
4259a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_align_superpage(object, offset,
4269a527560SKonstantin Belousov 	    addr, size));
4279a527560SKonstantin Belousov }
4289a527560SKonstantin Belousov 
4299a527560SKonstantin Belousov vm_offset_t
pmap_quick_enter_page(vm_page_t m)4309a527560SKonstantin Belousov pmap_quick_enter_page(vm_page_t m)
4319a527560SKonstantin Belousov {
4329a527560SKonstantin Belousov 
4339a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_quick_enter_page(m));
4349a527560SKonstantin Belousov }
4359a527560SKonstantin Belousov 
4369a527560SKonstantin Belousov void
pmap_quick_remove_page(vm_offset_t addr)4379a527560SKonstantin Belousov pmap_quick_remove_page(vm_offset_t addr)
4389a527560SKonstantin Belousov {
4399a527560SKonstantin Belousov 
4409a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_quick_remove_page(addr));
4419a527560SKonstantin Belousov }
4429a527560SKonstantin Belousov 
4439a527560SKonstantin Belousov void *
pmap_trm_alloc(size_t size,int flags)4449a527560SKonstantin Belousov pmap_trm_alloc(size_t size, int flags)
4459a527560SKonstantin Belousov {
4469a527560SKonstantin Belousov 
4479a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_trm_alloc(size, flags));
4489a527560SKonstantin Belousov }
4499a527560SKonstantin Belousov 
4509a527560SKonstantin Belousov void
pmap_trm_free(void * addr,size_t size)4519a527560SKonstantin Belousov pmap_trm_free(void *addr, size_t size)
4529a527560SKonstantin Belousov {
4539a527560SKonstantin Belousov 
4549a527560SKonstantin Belousov 	pmap_methods_ptr->pm_trm_free(addr, size);
4559a527560SKonstantin Belousov }
4569a527560SKonstantin Belousov 
4579a527560SKonstantin Belousov void
pmap_sync_icache(pmap_t pm,vm_offset_t va,vm_size_t sz)4589a527560SKonstantin Belousov pmap_sync_icache(pmap_t pm, vm_offset_t va, vm_size_t sz)
4599a527560SKonstantin Belousov {
4609a527560SKonstantin Belousov }
4619a527560SKonstantin Belousov 
4629a527560SKonstantin Belousov vm_offset_t
pmap_get_map_low(void)4639a527560SKonstantin Belousov pmap_get_map_low(void)
4649a527560SKonstantin Belousov {
4659a527560SKonstantin Belousov 
4669a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_get_map_low());
4679a527560SKonstantin Belousov }
4689a527560SKonstantin Belousov 
4699a527560SKonstantin Belousov vm_offset_t
pmap_get_vm_maxuser_address(void)4709a527560SKonstantin Belousov pmap_get_vm_maxuser_address(void)
4719a527560SKonstantin Belousov {
4729a527560SKonstantin Belousov 
4739a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_get_vm_maxuser_address());
4749a527560SKonstantin Belousov }
4759a527560SKonstantin Belousov 
4769a527560SKonstantin Belousov vm_paddr_t
pmap_kextract(vm_offset_t va)4779a527560SKonstantin Belousov pmap_kextract(vm_offset_t va)
4789a527560SKonstantin Belousov {
4799a527560SKonstantin Belousov 
4809a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_kextract(va));
4819a527560SKonstantin Belousov }
4829a527560SKonstantin Belousov 
4839a527560SKonstantin Belousov vm_paddr_t
pmap_pg_frame(vm_paddr_t pa)4849a527560SKonstantin Belousov pmap_pg_frame(vm_paddr_t pa)
4859a527560SKonstantin Belousov {
4869a527560SKonstantin Belousov 
4879a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_pg_frame(pa));
4889a527560SKonstantin Belousov }
4899a527560SKonstantin Belousov 
4909a527560SKonstantin Belousov void
pmap_sf_buf_map(struct sf_buf * sf)4919a527560SKonstantin Belousov pmap_sf_buf_map(struct sf_buf *sf)
4929a527560SKonstantin Belousov {
4939a527560SKonstantin Belousov 
4949a527560SKonstantin Belousov 	pmap_methods_ptr->pm_sf_buf_map(sf);
4959a527560SKonstantin Belousov }
4969a527560SKonstantin Belousov 
4979a527560SKonstantin Belousov void
pmap_cp_slow0_map(vm_offset_t kaddr,int plen,vm_page_t * ma)4989a527560SKonstantin Belousov pmap_cp_slow0_map(vm_offset_t kaddr, int plen, vm_page_t *ma)
4999a527560SKonstantin Belousov {
5009a527560SKonstantin Belousov 
5019a527560SKonstantin Belousov 	pmap_methods_ptr->pm_cp_slow0_map(kaddr, plen, ma);
5029a527560SKonstantin Belousov }
5039a527560SKonstantin Belousov 
5049a527560SKonstantin Belousov u_int
pmap_get_kcr3(void)5059a527560SKonstantin Belousov pmap_get_kcr3(void)
5069a527560SKonstantin Belousov {
5079a527560SKonstantin Belousov 
5089a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_get_kcr3());
5099a527560SKonstantin Belousov }
5109a527560SKonstantin Belousov 
5119a527560SKonstantin Belousov u_int
pmap_get_cr3(pmap_t pmap)5129a527560SKonstantin Belousov pmap_get_cr3(pmap_t pmap)
5139a527560SKonstantin Belousov {
5149a527560SKonstantin Belousov 
5159a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_get_cr3(pmap));
5169a527560SKonstantin Belousov }
5179a527560SKonstantin Belousov 
5189a527560SKonstantin Belousov caddr_t
pmap_cmap3(vm_paddr_t pa,u_int pte_flags)5199a527560SKonstantin Belousov pmap_cmap3(vm_paddr_t pa, u_int pte_flags)
5209a527560SKonstantin Belousov {
5219a527560SKonstantin Belousov 
5229a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_cmap3(pa, pte_flags));
5239a527560SKonstantin Belousov }
5249a527560SKonstantin Belousov 
5259a527560SKonstantin Belousov void
pmap_basemem_setup(u_int basemem)5269a527560SKonstantin Belousov pmap_basemem_setup(u_int basemem)
5279a527560SKonstantin Belousov {
5289a527560SKonstantin Belousov 
5299a527560SKonstantin Belousov 	pmap_methods_ptr->pm_basemem_setup(basemem);
5309a527560SKonstantin Belousov }
5319a527560SKonstantin Belousov 
5329a527560SKonstantin Belousov void
pmap_set_nx(void)5339a527560SKonstantin Belousov pmap_set_nx(void)
5349a527560SKonstantin Belousov {
5359a527560SKonstantin Belousov 
5369a527560SKonstantin Belousov 	pmap_methods_ptr->pm_set_nx();
5379a527560SKonstantin Belousov }
5389a527560SKonstantin Belousov 
5399a527560SKonstantin Belousov void *
pmap_bios16_enter(void)5409a527560SKonstantin Belousov pmap_bios16_enter(void)
5419a527560SKonstantin Belousov {
5429a527560SKonstantin Belousov 
5439a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_bios16_enter());
5449a527560SKonstantin Belousov }
5459a527560SKonstantin Belousov 
5469a527560SKonstantin Belousov void
pmap_bios16_leave(void * handle)5479a527560SKonstantin Belousov pmap_bios16_leave(void *handle)
5489a527560SKonstantin Belousov {
5499a527560SKonstantin Belousov 
5509a527560SKonstantin Belousov 	pmap_methods_ptr->pm_bios16_leave(handle);
5519a527560SKonstantin Belousov }
5529a527560SKonstantin Belousov 
5539a527560SKonstantin Belousov void
pmap_bootstrap(vm_paddr_t firstaddr)5549a527560SKonstantin Belousov pmap_bootstrap(vm_paddr_t firstaddr)
5559a527560SKonstantin Belousov {
5569a527560SKonstantin Belousov 
5579a527560SKonstantin Belousov 	pmap_methods_ptr->pm_bootstrap(firstaddr);
5589a527560SKonstantin Belousov }
5599a527560SKonstantin Belousov 
560*1f1b2286SJohn Baldwin bool
pmap_is_valid_memattr(pmap_t pmap,vm_memattr_t mode)5619a527560SKonstantin Belousov pmap_is_valid_memattr(pmap_t pmap, vm_memattr_t mode)
5629a527560SKonstantin Belousov {
5639a527560SKonstantin Belousov 
5649a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_is_valid_memattr(pmap, mode));
5659a527560SKonstantin Belousov }
5669a527560SKonstantin Belousov 
5679a527560SKonstantin Belousov int
pmap_cache_bits(pmap_t pmap,int mode,bool is_pde)568*1f1b2286SJohn Baldwin pmap_cache_bits(pmap_t pmap, int mode, bool is_pde)
5699a527560SKonstantin Belousov {
5709a527560SKonstantin Belousov 
5719a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_cache_bits(pmap, mode, is_pde));
5729a527560SKonstantin Belousov }
5739a527560SKonstantin Belousov 
5749a527560SKonstantin Belousov bool
pmap_ps_enabled(pmap_t pmap)5759a527560SKonstantin Belousov pmap_ps_enabled(pmap_t pmap)
5769a527560SKonstantin Belousov {
5779a527560SKonstantin Belousov 
5789a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_ps_enabled(pmap));
5799a527560SKonstantin Belousov }
5809a527560SKonstantin Belousov 
5819a527560SKonstantin Belousov void
pmap_pinit0(pmap_t pmap)5829a527560SKonstantin Belousov pmap_pinit0(pmap_t pmap)
5839a527560SKonstantin Belousov {
5849a527560SKonstantin Belousov 
5859a527560SKonstantin Belousov 	pmap_methods_ptr->pm_pinit0(pmap);
5869a527560SKonstantin Belousov }
5879a527560SKonstantin Belousov 
5889a527560SKonstantin Belousov int
pmap_pinit(pmap_t pmap)5899a527560SKonstantin Belousov pmap_pinit(pmap_t pmap)
5909a527560SKonstantin Belousov {
5919a527560SKonstantin Belousov 
5929a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_pinit(pmap));
5939a527560SKonstantin Belousov }
5949a527560SKonstantin Belousov 
5959a527560SKonstantin Belousov void
pmap_activate(struct thread * td)5969a527560SKonstantin Belousov pmap_activate(struct thread *td)
5979a527560SKonstantin Belousov {
5989a527560SKonstantin Belousov 
5999a527560SKonstantin Belousov 	pmap_methods_ptr->pm_activate(td);
6009a527560SKonstantin Belousov }
6019a527560SKonstantin Belousov 
6029a527560SKonstantin Belousov void
pmap_activate_boot(pmap_t pmap)6039a527560SKonstantin Belousov pmap_activate_boot(pmap_t pmap)
6049a527560SKonstantin Belousov {
6059a527560SKonstantin Belousov 
6069a527560SKonstantin Belousov 	pmap_methods_ptr->pm_activate_boot(pmap);
6079a527560SKonstantin Belousov }
6089a527560SKonstantin Belousov 
6099a527560SKonstantin Belousov void
pmap_advise(pmap_t pmap,vm_offset_t sva,vm_offset_t eva,int advice)6109a527560SKonstantin Belousov pmap_advise(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, int advice)
6119a527560SKonstantin Belousov {
6129a527560SKonstantin Belousov 
6139a527560SKonstantin Belousov 	pmap_methods_ptr->pm_advise(pmap, sva, eva, advice);
6149a527560SKonstantin Belousov }
6159a527560SKonstantin Belousov 
6169a527560SKonstantin Belousov void
pmap_clear_modify(vm_page_t m)6179a527560SKonstantin Belousov pmap_clear_modify(vm_page_t m)
6189a527560SKonstantin Belousov {
6199a527560SKonstantin Belousov 
6209a527560SKonstantin Belousov 	pmap_methods_ptr->pm_clear_modify(m);
6219a527560SKonstantin Belousov }
6229a527560SKonstantin Belousov 
6239a527560SKonstantin Belousov int
pmap_change_attr(vm_offset_t va,vm_size_t size,int mode)6249a527560SKonstantin Belousov pmap_change_attr(vm_offset_t va, vm_size_t size, int mode)
6259a527560SKonstantin Belousov {
6269a527560SKonstantin Belousov 
6279a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_change_attr(va, size, mode));
6289a527560SKonstantin Belousov }
6299a527560SKonstantin Belousov 
6309a527560SKonstantin Belousov int
pmap_mincore(pmap_t pmap,vm_offset_t addr,vm_paddr_t * pap)63101cef4caSMark Johnston pmap_mincore(pmap_t pmap, vm_offset_t addr, vm_paddr_t *pap)
6329a527560SKonstantin Belousov {
6339a527560SKonstantin Belousov 
63401cef4caSMark Johnston 	return (pmap_methods_ptr->pm_mincore(pmap, addr, pap));
6359a527560SKonstantin Belousov }
6369a527560SKonstantin Belousov 
6379a527560SKonstantin Belousov void
pmap_copy(pmap_t dst_pmap,pmap_t src_pmap,vm_offset_t dst_addr,vm_size_t len,vm_offset_t src_addr)6389a527560SKonstantin Belousov pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
6399a527560SKonstantin Belousov     vm_offset_t src_addr)
6409a527560SKonstantin Belousov {
6419a527560SKonstantin Belousov 
6429a527560SKonstantin Belousov 	pmap_methods_ptr->pm_copy(dst_pmap, src_pmap, dst_addr, len, src_addr);
6439a527560SKonstantin Belousov }
6449a527560SKonstantin Belousov 
6459a527560SKonstantin Belousov void
pmap_copy_page(vm_page_t src,vm_page_t dst)6469a527560SKonstantin Belousov pmap_copy_page(vm_page_t src, vm_page_t dst)
6479a527560SKonstantin Belousov {
6489a527560SKonstantin Belousov 
6499a527560SKonstantin Belousov 	pmap_methods_ptr->pm_copy_page(src, dst);
6509a527560SKonstantin Belousov }
6519a527560SKonstantin Belousov 
6529a527560SKonstantin Belousov void
pmap_copy_pages(vm_page_t ma[],vm_offset_t a_offset,vm_page_t mb[],vm_offset_t b_offset,int xfersize)6539a527560SKonstantin Belousov pmap_copy_pages(vm_page_t ma[], vm_offset_t a_offset, vm_page_t mb[],
6549a527560SKonstantin Belousov     vm_offset_t b_offset, int xfersize)
6559a527560SKonstantin Belousov {
6569a527560SKonstantin Belousov 
6579a527560SKonstantin Belousov 	pmap_methods_ptr->pm_copy_pages(ma, a_offset, mb, b_offset, xfersize);
6589a527560SKonstantin Belousov }
6599a527560SKonstantin Belousov 
6609a527560SKonstantin Belousov void
pmap_zero_page(vm_page_t m)6619a527560SKonstantin Belousov pmap_zero_page(vm_page_t m)
6629a527560SKonstantin Belousov {
6639a527560SKonstantin Belousov 
6649a527560SKonstantin Belousov 	pmap_methods_ptr->pm_zero_page(m);
6659a527560SKonstantin Belousov }
6669a527560SKonstantin Belousov 
6679a527560SKonstantin Belousov void
pmap_zero_page_area(vm_page_t m,int off,int size)6689a527560SKonstantin Belousov pmap_zero_page_area(vm_page_t m, int off, int size)
6699a527560SKonstantin Belousov {
6709a527560SKonstantin Belousov 
6719a527560SKonstantin Belousov 	pmap_methods_ptr->pm_zero_page_area(m, off, size);
6729a527560SKonstantin Belousov }
6739a527560SKonstantin Belousov 
6749a527560SKonstantin Belousov int
pmap_enter(pmap_t pmap,vm_offset_t va,vm_page_t m,vm_prot_t prot,u_int flags,int8_t psind)6759a527560SKonstantin Belousov pmap_enter(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot,
6769a527560SKonstantin Belousov     u_int flags, int8_t psind)
6779a527560SKonstantin Belousov {
6789a527560SKonstantin Belousov 
6799a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_enter(pmap, va, m, prot, flags, psind));
6809a527560SKonstantin Belousov }
6819a527560SKonstantin Belousov 
6829a527560SKonstantin Belousov void
pmap_enter_object(pmap_t pmap,vm_offset_t start,vm_offset_t end,vm_page_t m_start,vm_prot_t prot)6839a527560SKonstantin Belousov pmap_enter_object(pmap_t pmap, vm_offset_t start, vm_offset_t end,
6849a527560SKonstantin Belousov     vm_page_t m_start, vm_prot_t prot)
6859a527560SKonstantin Belousov {
6869a527560SKonstantin Belousov 
6879a527560SKonstantin Belousov 	pmap_methods_ptr->pm_enter_object(pmap, start, end, m_start, prot);
6889a527560SKonstantin Belousov }
6899a527560SKonstantin Belousov 
6909a527560SKonstantin Belousov void
pmap_enter_quick(pmap_t pmap,vm_offset_t va,vm_page_t m,vm_prot_t prot)6919a527560SKonstantin Belousov pmap_enter_quick(pmap_t pmap, vm_offset_t va, vm_page_t m, vm_prot_t prot)
6929a527560SKonstantin Belousov {
6939a527560SKonstantin Belousov 
6949a527560SKonstantin Belousov 	pmap_methods_ptr->pm_enter_quick(pmap, va, m, prot);
6959a527560SKonstantin Belousov }
6969a527560SKonstantin Belousov 
6979a527560SKonstantin Belousov void *
pmap_kenter_temporary(vm_paddr_t pa,int i)6989a527560SKonstantin Belousov pmap_kenter_temporary(vm_paddr_t pa, int i)
6999a527560SKonstantin Belousov {
7009a527560SKonstantin Belousov 
7019a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_kenter_temporary(pa, i));
7029a527560SKonstantin Belousov }
7039a527560SKonstantin Belousov 
7049a527560SKonstantin Belousov void
pmap_object_init_pt(pmap_t pmap,vm_offset_t addr,vm_object_t object,vm_pindex_t pindex,vm_size_t size)7059a527560SKonstantin Belousov pmap_object_init_pt(pmap_t pmap, vm_offset_t addr, vm_object_t object,
7069a527560SKonstantin Belousov     vm_pindex_t pindex, vm_size_t size)
7079a527560SKonstantin Belousov {
7089a527560SKonstantin Belousov 
7099a527560SKonstantin Belousov 	pmap_methods_ptr->pm_object_init_pt(pmap, addr, object, pindex, size);
7109a527560SKonstantin Belousov }
7119a527560SKonstantin Belousov 
7129a527560SKonstantin Belousov void
pmap_unwire(pmap_t pmap,vm_offset_t sva,vm_offset_t eva)7139a527560SKonstantin Belousov pmap_unwire(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
7149a527560SKonstantin Belousov {
7159a527560SKonstantin Belousov 
7169a527560SKonstantin Belousov 	pmap_methods_ptr->pm_unwire(pmap, sva, eva);
7179a527560SKonstantin Belousov }
7189a527560SKonstantin Belousov 
719*1f1b2286SJohn Baldwin bool
pmap_page_exists_quick(pmap_t pmap,vm_page_t m)7209a527560SKonstantin Belousov pmap_page_exists_quick(pmap_t pmap, vm_page_t m)
7219a527560SKonstantin Belousov {
7229a527560SKonstantin Belousov 
7239a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_page_exists_quick(pmap, m));
7249a527560SKonstantin Belousov }
7259a527560SKonstantin Belousov 
7269a527560SKonstantin Belousov int
pmap_page_wired_mappings(vm_page_t m)7279a527560SKonstantin Belousov pmap_page_wired_mappings(vm_page_t m)
7289a527560SKonstantin Belousov {
7299a527560SKonstantin Belousov 
7309a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_page_wired_mappings(m));
7319a527560SKonstantin Belousov }
7329a527560SKonstantin Belousov 
733*1f1b2286SJohn Baldwin bool
pmap_page_is_mapped(vm_page_t m)7349a527560SKonstantin Belousov pmap_page_is_mapped(vm_page_t m)
7359a527560SKonstantin Belousov {
7369a527560SKonstantin Belousov 
7379a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_page_is_mapped(m));
7389a527560SKonstantin Belousov }
7399a527560SKonstantin Belousov 
7409a527560SKonstantin Belousov void
pmap_remove_pages(pmap_t pmap)7419a527560SKonstantin Belousov pmap_remove_pages(pmap_t pmap)
7429a527560SKonstantin Belousov {
7439a527560SKonstantin Belousov 
7449a527560SKonstantin Belousov 	pmap_methods_ptr->pm_remove_pages(pmap);
7459a527560SKonstantin Belousov }
7469a527560SKonstantin Belousov 
747*1f1b2286SJohn Baldwin bool
pmap_is_modified(vm_page_t m)7489a527560SKonstantin Belousov pmap_is_modified(vm_page_t m)
7499a527560SKonstantin Belousov {
7509a527560SKonstantin Belousov 
7519a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_is_modified(m));
7529a527560SKonstantin Belousov }
7539a527560SKonstantin Belousov 
754*1f1b2286SJohn Baldwin bool
pmap_is_prefaultable(pmap_t pmap,vm_offset_t addr)7559a527560SKonstantin Belousov pmap_is_prefaultable(pmap_t pmap, vm_offset_t addr)
7569a527560SKonstantin Belousov {
7579a527560SKonstantin Belousov 
7589a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_is_prefaultable(pmap, addr));
7599a527560SKonstantin Belousov }
7609a527560SKonstantin Belousov 
761*1f1b2286SJohn Baldwin bool
pmap_is_referenced(vm_page_t m)7629a527560SKonstantin Belousov pmap_is_referenced(vm_page_t m)
7639a527560SKonstantin Belousov {
7649a527560SKonstantin Belousov 
7659a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_is_referenced(m));
7669a527560SKonstantin Belousov }
7679a527560SKonstantin Belousov 
7689a527560SKonstantin Belousov void
pmap_remove_write(vm_page_t m)7699a527560SKonstantin Belousov pmap_remove_write(vm_page_t m)
7709a527560SKonstantin Belousov {
7719a527560SKonstantin Belousov 
7729a527560SKonstantin Belousov 	pmap_methods_ptr->pm_remove_write(m);
7739a527560SKonstantin Belousov }
7749a527560SKonstantin Belousov 
7759a527560SKonstantin Belousov int
pmap_ts_referenced(vm_page_t m)7769a527560SKonstantin Belousov pmap_ts_referenced(vm_page_t m)
7779a527560SKonstantin Belousov {
7789a527560SKonstantin Belousov 
7799a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_ts_referenced(m));
7809a527560SKonstantin Belousov }
7819a527560SKonstantin Belousov 
7829a527560SKonstantin Belousov void *
pmap_mapdev_attr(vm_paddr_t pa,vm_size_t size,int mode)7839a527560SKonstantin Belousov pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode)
7849a527560SKonstantin Belousov {
7859a527560SKonstantin Belousov 
786c45cbc7aSJohn Baldwin 	return (pmap_methods_ptr->pm_mapdev_attr(pa, size, mode,
787c45cbc7aSJohn Baldwin 	    MAPDEV_SETATTR));
7889a527560SKonstantin Belousov }
7899a527560SKonstantin Belousov 
7909a527560SKonstantin Belousov void *
pmap_mapdev(vm_paddr_t pa,vm_size_t size)7919a527560SKonstantin Belousov pmap_mapdev(vm_paddr_t pa, vm_size_t size)
7929a527560SKonstantin Belousov {
7939a527560SKonstantin Belousov 
794c45cbc7aSJohn Baldwin 	return (pmap_methods_ptr->pm_mapdev_attr(pa, size, PAT_UNCACHEABLE,
795c45cbc7aSJohn Baldwin 	    MAPDEV_SETATTR));
7969a527560SKonstantin Belousov }
7979a527560SKonstantin Belousov 
7989a527560SKonstantin Belousov void *
pmap_mapbios(vm_paddr_t pa,vm_size_t size)7999a527560SKonstantin Belousov pmap_mapbios(vm_paddr_t pa, vm_size_t size)
8009a527560SKonstantin Belousov {
8019a527560SKonstantin Belousov 
802c45cbc7aSJohn Baldwin 	return (pmap_methods_ptr->pm_mapdev_attr(pa, size, PAT_WRITE_BACK, 0));
8039a527560SKonstantin Belousov }
8049a527560SKonstantin Belousov 
8059a527560SKonstantin Belousov void
pmap_unmapdev(void * p,vm_size_t size)8067ae99f80SJohn Baldwin pmap_unmapdev(void *p, vm_size_t size)
8079a527560SKonstantin Belousov {
8089a527560SKonstantin Belousov 
8097ae99f80SJohn Baldwin 	pmap_methods_ptr->pm_unmapdev(p, size);
8109a527560SKonstantin Belousov }
8119a527560SKonstantin Belousov 
8129a527560SKonstantin Belousov void
pmap_page_set_memattr(vm_page_t m,vm_memattr_t ma)8139a527560SKonstantin Belousov pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma)
8149a527560SKonstantin Belousov {
8159a527560SKonstantin Belousov 
8169a527560SKonstantin Belousov 	pmap_methods_ptr->pm_page_set_memattr(m, ma);
8179a527560SKonstantin Belousov }
8189a527560SKonstantin Belousov 
8199a527560SKonstantin Belousov vm_paddr_t
pmap_extract(pmap_t pmap,vm_offset_t va)8209a527560SKonstantin Belousov pmap_extract(pmap_t pmap, vm_offset_t va)
8219a527560SKonstantin Belousov {
8229a527560SKonstantin Belousov 
8239a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_extract(pmap, va));
8249a527560SKonstantin Belousov }
8259a527560SKonstantin Belousov 
8269a527560SKonstantin Belousov vm_page_t
pmap_extract_and_hold(pmap_t pmap,vm_offset_t va,vm_prot_t prot)8279a527560SKonstantin Belousov pmap_extract_and_hold(pmap_t pmap, vm_offset_t va, vm_prot_t prot)
8289a527560SKonstantin Belousov {
8299a527560SKonstantin Belousov 
8309a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_extract_and_hold(pmap, va, prot));
8319a527560SKonstantin Belousov }
8329a527560SKonstantin Belousov 
8339a527560SKonstantin Belousov vm_offset_t
pmap_map(vm_offset_t * virt,vm_paddr_t start,vm_paddr_t end,int prot)8349a527560SKonstantin Belousov pmap_map(vm_offset_t *virt, vm_paddr_t start, vm_paddr_t end, int prot)
8359a527560SKonstantin Belousov {
8369a527560SKonstantin Belousov 
8379a527560SKonstantin Belousov 	return (pmap_methods_ptr->pm_map(virt, start, end, prot));
8389a527560SKonstantin Belousov }
8399a527560SKonstantin Belousov 
8409a527560SKonstantin Belousov void
pmap_qenter(vm_offset_t sva,vm_page_t * ma,int count)8419a527560SKonstantin Belousov pmap_qenter(vm_offset_t sva, vm_page_t *ma, int count)
8429a527560SKonstantin Belousov {
8439a527560SKonstantin Belousov 
8449a527560SKonstantin Belousov 	pmap_methods_ptr->pm_qenter(sva, ma, count);
8459a527560SKonstantin Belousov }
8469a527560SKonstantin Belousov 
8479a527560SKonstantin Belousov void
pmap_qremove(vm_offset_t sva,int count)8489a527560SKonstantin Belousov pmap_qremove(vm_offset_t sva, int count)
8499a527560SKonstantin Belousov {
8509a527560SKonstantin Belousov 
8519a527560SKonstantin Belousov 	pmap_methods_ptr->pm_qremove(sva, count);
8529a527560SKonstantin Belousov }
8539a527560SKonstantin Belousov 
8549a527560SKonstantin Belousov void
pmap_release(pmap_t pmap)8559a527560SKonstantin Belousov pmap_release(pmap_t pmap)
8569a527560SKonstantin Belousov {
8579a527560SKonstantin Belousov 
8589a527560SKonstantin Belousov 	pmap_methods_ptr->pm_release(pmap);
8599a527560SKonstantin Belousov }
8609a527560SKonstantin Belousov 
8619a527560SKonstantin Belousov void
pmap_remove(pmap_t pmap,vm_offset_t sva,vm_offset_t eva)8629a527560SKonstantin Belousov pmap_remove(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
8639a527560SKonstantin Belousov {
8649a527560SKonstantin Belousov 
8659a527560SKonstantin Belousov 	pmap_methods_ptr->pm_remove(pmap, sva, eva);
8669a527560SKonstantin Belousov }
8679a527560SKonstantin Belousov 
8689a527560SKonstantin Belousov void
pmap_protect(pmap_t pmap,vm_offset_t sva,vm_offset_t eva,vm_prot_t prot)8699a527560SKonstantin Belousov pmap_protect(pmap_t pmap, vm_offset_t sva, vm_offset_t eva, vm_prot_t prot)
8709a527560SKonstantin Belousov {
8719a527560SKonstantin Belousov 
8729a527560SKonstantin Belousov 	pmap_methods_ptr->pm_protect(pmap, sva, eva, prot);
8739a527560SKonstantin Belousov }
8749a527560SKonstantin Belousov 
8759a527560SKonstantin Belousov void
pmap_remove_all(vm_page_t m)8769a527560SKonstantin Belousov pmap_remove_all(vm_page_t m)
8779a527560SKonstantin Belousov {
8789a527560SKonstantin Belousov 
8799a527560SKonstantin Belousov 	pmap_methods_ptr->pm_remove_all(m);
8809a527560SKonstantin Belousov }
8819a527560SKonstantin Belousov 
8829a527560SKonstantin Belousov void
pmap_init(void)8839a527560SKonstantin Belousov pmap_init(void)
8849a527560SKonstantin Belousov {
8859a527560SKonstantin Belousov 
8869a527560SKonstantin Belousov 	pmap_methods_ptr->pm_init();
8879a527560SKonstantin Belousov }
8889a527560SKonstantin Belousov 
8899a527560SKonstantin Belousov void
pmap_init_pat(void)8909a527560SKonstantin Belousov pmap_init_pat(void)
8919a527560SKonstantin Belousov {
8929a527560SKonstantin Belousov 
8939a527560SKonstantin Belousov 	pmap_methods_ptr->pm_init_pat();
8949a527560SKonstantin Belousov }
8959a527560SKonstantin Belousov 
8969a527560SKonstantin Belousov void
pmap_growkernel(vm_offset_t addr)8979a527560SKonstantin Belousov pmap_growkernel(vm_offset_t addr)
8989a527560SKonstantin Belousov {
8999a527560SKonstantin Belousov 
9009a527560SKonstantin Belousov 	pmap_methods_ptr->pm_growkernel(addr);
9019a527560SKonstantin Belousov }
9029a527560SKonstantin Belousov 
9039a527560SKonstantin Belousov void
pmap_invalidate_page(pmap_t pmap,vm_offset_t va)9049a527560SKonstantin Belousov pmap_invalidate_page(pmap_t pmap, vm_offset_t va)
9059a527560SKonstantin Belousov {
9069a527560SKonstantin Belousov 
9079a527560SKonstantin Belousov 	pmap_methods_ptr->pm_invalidate_page(pmap, va);
9089a527560SKonstantin Belousov }
9099a527560SKonstantin Belousov 
9109a527560SKonstantin Belousov void
pmap_invalidate_range(pmap_t pmap,vm_offset_t sva,vm_offset_t eva)9119a527560SKonstantin Belousov pmap_invalidate_range(pmap_t pmap, vm_offset_t sva, vm_offset_t eva)
9129a527560SKonstantin Belousov {
9139a527560SKonstantin Belousov 
9149a527560SKonstantin Belousov 	pmap_methods_ptr->pm_invalidate_range(pmap, sva, eva);
9159a527560SKonstantin Belousov }
9169a527560SKonstantin Belousov 
9179a527560SKonstantin Belousov void
pmap_invalidate_all(pmap_t pmap)9189a527560SKonstantin Belousov pmap_invalidate_all(pmap_t pmap)
9199a527560SKonstantin Belousov {
9209a527560SKonstantin Belousov 
9219a527560SKonstantin Belousov 	pmap_methods_ptr->pm_invalidate_all(pmap);
9229a527560SKonstantin Belousov }
9239a527560SKonstantin Belousov 
9249a527560SKonstantin Belousov void
pmap_invalidate_cache(void)9259a527560SKonstantin Belousov pmap_invalidate_cache(void)
9269a527560SKonstantin Belousov {
9279a527560SKonstantin Belousov 
9289a527560SKonstantin Belousov 	pmap_methods_ptr->pm_invalidate_cache();
9299a527560SKonstantin Belousov }
9309a527560SKonstantin Belousov 
9319a527560SKonstantin Belousov void
pmap_kenter(vm_offset_t va,vm_paddr_t pa)9329a527560SKonstantin Belousov pmap_kenter(vm_offset_t va, vm_paddr_t pa)
9339a527560SKonstantin Belousov {
9349a527560SKonstantin Belousov 
9359a527560SKonstantin Belousov 	pmap_methods_ptr->pm_kenter(va, pa);
9369a527560SKonstantin Belousov }
9379a527560SKonstantin Belousov 
9389a527560SKonstantin Belousov void
pmap_kremove(vm_offset_t va)9399a527560SKonstantin Belousov pmap_kremove(vm_offset_t va)
9409a527560SKonstantin Belousov {
9419a527560SKonstantin Belousov 
9429a527560SKonstantin Belousov 	pmap_methods_ptr->pm_kremove(va);
9439a527560SKonstantin Belousov }
9449a527560SKonstantin Belousov 
9458882b785SKonstantin Belousov void
pmap_active_cpus(pmap_t pmap,cpuset_t * res)9468882b785SKonstantin Belousov pmap_active_cpus(pmap_t pmap, cpuset_t *res)
9478882b785SKonstantin Belousov {
9488882b785SKonstantin Belousov 	*res = pmap->pm_active;
9498882b785SKonstantin Belousov }
9508882b785SKonstantin Belousov 
9519a527560SKonstantin Belousov extern struct pmap_methods pmap_pae_methods, pmap_nopae_methods;
9529a527560SKonstantin Belousov int pae_mode;
9532648ed92SKonstantin Belousov SYSCTL_INT(_vm_pmap, OID_AUTO, pae_mode, CTLFLAG_RDTUN | CTLFLAG_NOFETCH,
9542648ed92SKonstantin Belousov     &pae_mode, 0,
9559a527560SKonstantin Belousov     "PAE");
9569a527560SKonstantin Belousov 
9579a527560SKonstantin Belousov void
pmap_cold(void)9589a527560SKonstantin Belousov pmap_cold(void)
9599a527560SKonstantin Belousov {
9609a527560SKonstantin Belousov 
9612648ed92SKonstantin Belousov 	init_static_kenv((char *)bootinfo.bi_envp, 0);
9622648ed92SKonstantin Belousov 	pae_mode = (cpu_feature & CPUID_PAE) != 0;
9632648ed92SKonstantin Belousov 	if (pae_mode)
9642648ed92SKonstantin Belousov 		TUNABLE_INT_FETCH("vm.pmap.pae_mode", &pae_mode);
9652648ed92SKonstantin Belousov 	if (pae_mode) {
9669a527560SKonstantin Belousov 		pmap_methods_ptr = &pmap_pae_methods;
9679a527560SKonstantin Belousov 		pmap_pae_cold();
9689a527560SKonstantin Belousov 	} else {
9699a527560SKonstantin Belousov 		pmap_methods_ptr = &pmap_nopae_methods;
9709a527560SKonstantin Belousov 		pmap_nopae_cold();
9719a527560SKonstantin Belousov 	}
9729a527560SKonstantin Belousov }
973