xref: /minix3/sys/arch/arm/include/arm32/pmap.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: pmap.h,v 1.142 2015/09/09 07:37:36 skrll Exp $	*/
202222606SBen Gras 
302222606SBen Gras /*
402222606SBen Gras  * Copyright (c) 2002, 2003 Wasabi Systems, Inc.
502222606SBen Gras  * All rights reserved.
602222606SBen Gras  *
702222606SBen Gras  * Written by Jason R. Thorpe & Steve C. Woodford for Wasabi Systems, Inc.
802222606SBen Gras  *
902222606SBen Gras  * Redistribution and use in source and binary forms, with or without
1002222606SBen Gras  * modification, are permitted provided that the following conditions
1102222606SBen Gras  * are met:
1202222606SBen Gras  * 1. Redistributions of source code must retain the above copyright
1302222606SBen Gras  *    notice, this list of conditions and the following disclaimer.
1402222606SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
1502222606SBen Gras  *    notice, this list of conditions and the following disclaimer in the
1602222606SBen Gras  *    documentation and/or other materials provided with the distribution.
1702222606SBen Gras  * 3. All advertising materials mentioning features or use of this software
1802222606SBen Gras  *    must display the following acknowledgement:
1902222606SBen Gras  *	This product includes software developed for the NetBSD Project by
2002222606SBen Gras  *	Wasabi Systems, Inc.
2102222606SBen Gras  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
2202222606SBen Gras  *    or promote products derived from this software without specific prior
2302222606SBen Gras  *    written permission.
2402222606SBen Gras  *
2502222606SBen Gras  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
2602222606SBen Gras  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2702222606SBen Gras  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2802222606SBen Gras  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
2902222606SBen Gras  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
3002222606SBen Gras  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
3102222606SBen Gras  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
3202222606SBen Gras  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
3302222606SBen Gras  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
3402222606SBen Gras  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
3502222606SBen Gras  * POSSIBILITY OF SUCH DAMAGE.
3602222606SBen Gras  */
3702222606SBen Gras 
3802222606SBen Gras /*
3902222606SBen Gras  * Copyright (c) 1994,1995 Mark Brinicombe.
4002222606SBen Gras  * All rights reserved.
4102222606SBen Gras  *
4202222606SBen Gras  * Redistribution and use in source and binary forms, with or without
4302222606SBen Gras  * modification, are permitted provided that the following conditions
4402222606SBen Gras  * are met:
4502222606SBen Gras  * 1. Redistributions of source code must retain the above copyright
4602222606SBen Gras  *    notice, this list of conditions and the following disclaimer.
4702222606SBen Gras  * 2. Redistributions in binary form must reproduce the above copyright
4802222606SBen Gras  *    notice, this list of conditions and the following disclaimer in the
4902222606SBen Gras  *    documentation and/or other materials provided with the distribution.
5002222606SBen Gras  * 3. All advertising materials mentioning features or use of this software
5102222606SBen Gras  *    must display the following acknowledgement:
5202222606SBen Gras  *	This product includes software developed by Mark Brinicombe
5302222606SBen Gras  * 4. The name of the author may not be used to endorse or promote products
5402222606SBen Gras  *    derived from this software without specific prior written permission.
5502222606SBen Gras  *
5602222606SBen Gras  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
5702222606SBen Gras  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
5802222606SBen Gras  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5902222606SBen Gras  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
6002222606SBen Gras  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
6102222606SBen Gras  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
6202222606SBen Gras  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
6302222606SBen Gras  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
6402222606SBen Gras  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
6502222606SBen Gras  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6602222606SBen Gras  */
6702222606SBen Gras 
6802222606SBen Gras #ifndef	_ARM32_PMAP_H_
6902222606SBen Gras #define	_ARM32_PMAP_H_
7002222606SBen Gras 
7102222606SBen Gras #ifdef _KERNEL
7202222606SBen Gras 
7302222606SBen Gras #include <arm/cpuconf.h>
7402222606SBen Gras #include <arm/arm32/pte.h>
7502222606SBen Gras #ifndef _LOCORE
7602222606SBen Gras #if defined(_KERNEL_OPT)
7702222606SBen Gras #include "opt_arm32_pmap.h"
78*0a6a1f1dSLionel Sambuc #include "opt_multiprocessor.h"
7902222606SBen Gras #endif
8002222606SBen Gras #include <arm/cpufunc.h>
81*0a6a1f1dSLionel Sambuc #include <arm/locore.h>
8202222606SBen Gras #include <uvm/uvm_object.h>
8302222606SBen Gras #endif
8402222606SBen Gras 
85*0a6a1f1dSLionel Sambuc #ifdef ARM_MMU_EXTENDED
86*0a6a1f1dSLionel Sambuc #define PMAP_TLB_MAX			1
87*0a6a1f1dSLionel Sambuc #define PMAP_TLB_HWPAGEWALKER		1
88*0a6a1f1dSLionel Sambuc #if PMAP_TLB_MAX > 1
89*0a6a1f1dSLionel Sambuc #define PMAP_NEED_TLB_SHOOTDOWN		1
90*0a6a1f1dSLionel Sambuc #endif
91*0a6a1f1dSLionel Sambuc #define PMAP_TLB_FLUSH_ASID_ON_RESET	(arm_has_tlbiasid_p)
92*0a6a1f1dSLionel Sambuc #define PMAP_TLB_NUM_PIDS		256
93*0a6a1f1dSLionel Sambuc #define cpu_set_tlb_info(ci, ti)        ((void)((ci)->ci_tlb_info = (ti)))
94*0a6a1f1dSLionel Sambuc #if PMAP_TLB_MAX > 1
95*0a6a1f1dSLionel Sambuc #define cpu_tlb_info(ci)		((ci)->ci_tlb_info)
96*0a6a1f1dSLionel Sambuc #else
97*0a6a1f1dSLionel Sambuc #define cpu_tlb_info(ci)		(&pmap_tlb0_info)
98*0a6a1f1dSLionel Sambuc #endif
99*0a6a1f1dSLionel Sambuc #define pmap_md_tlb_asid_max()		(PMAP_TLB_NUM_PIDS - 1)
100*0a6a1f1dSLionel Sambuc #include <uvm/pmap/tlb.h>
101*0a6a1f1dSLionel Sambuc #include <uvm/pmap/pmap_tlb.h>
102*0a6a1f1dSLionel Sambuc 
103*0a6a1f1dSLionel Sambuc /*
104*0a6a1f1dSLionel Sambuc  * If we have an EXTENDED MMU and the address space is split evenly between
105*0a6a1f1dSLionel Sambuc  * user and kernel, we can use the TTBR0/TTBR1 to have separate L1 tables for
106*0a6a1f1dSLionel Sambuc  * user and kernel address spaces.
107*0a6a1f1dSLionel Sambuc  */
108*0a6a1f1dSLionel Sambuc #if (KERNEL_BASE & 0x80000000) == 0
109*0a6a1f1dSLionel Sambuc #error ARMv6 or later systems must have a KERNEL_BASE >= 0x80000000
110*0a6a1f1dSLionel Sambuc #endif
111*0a6a1f1dSLionel Sambuc #endif  /* ARM_MMU_EXTENDED */
112*0a6a1f1dSLionel Sambuc 
11302222606SBen Gras /*
11402222606SBen Gras  * a pmap describes a processes' 4GB virtual address space.  this
11502222606SBen Gras  * virtual address space can be broken up into 4096 1MB regions which
11602222606SBen Gras  * are described by L1 PTEs in the L1 table.
11702222606SBen Gras  *
11802222606SBen Gras  * There is a line drawn at KERNEL_BASE.  Everything below that line
11902222606SBen Gras  * changes when the VM context is switched.  Everything above that line
12002222606SBen Gras  * is the same no matter which VM context is running.  This is achieved
12102222606SBen Gras  * by making the L1 PTEs for those slots above KERNEL_BASE reference
12202222606SBen Gras  * kernel L2 tables.
12302222606SBen Gras  *
12402222606SBen Gras  * The basic layout of the virtual address space thus looks like this:
12502222606SBen Gras  *
12602222606SBen Gras  *	0xffffffff
12702222606SBen Gras  *	.
12802222606SBen Gras  *	.
12902222606SBen Gras  *	.
13002222606SBen Gras  *	KERNEL_BASE
13102222606SBen Gras  *	--------------------
13202222606SBen Gras  *	.
13302222606SBen Gras  *	.
13402222606SBen Gras  *	.
13502222606SBen Gras  *	0x00000000
13602222606SBen Gras  */
13702222606SBen Gras 
13802222606SBen Gras /*
13902222606SBen Gras  * The number of L2 descriptor tables which can be tracked by an l2_dtable.
14002222606SBen Gras  * A bucket size of 16 provides for 16MB of contiguous virtual address
14102222606SBen Gras  * space per l2_dtable. Most processes will, therefore, require only two or
14202222606SBen Gras  * three of these to map their whole working set.
14302222606SBen Gras  */
144*0a6a1f1dSLionel Sambuc #define	L2_BUCKET_XLOG2	(L1_S_SHIFT)
145*0a6a1f1dSLionel Sambuc #define L2_BUCKET_XSIZE	(1 << L2_BUCKET_XLOG2)
14602222606SBen Gras #define	L2_BUCKET_LOG2	4
14702222606SBen Gras #define	L2_BUCKET_SIZE	(1 << L2_BUCKET_LOG2)
14802222606SBen Gras 
14902222606SBen Gras /*
15002222606SBen Gras  * Given the above "L2-descriptors-per-l2_dtable" constant, the number
15102222606SBen Gras  * of l2_dtable structures required to track all possible page descriptors
15202222606SBen Gras  * mappable by an L1 translation table is given by the following constants:
15302222606SBen Gras  */
154*0a6a1f1dSLionel Sambuc #define	L2_LOG2		(32 - (L2_BUCKET_XLOG2 + L2_BUCKET_LOG2))
15502222606SBen Gras #define	L2_SIZE		(1 << L2_LOG2)
15602222606SBen Gras 
15702222606SBen Gras /*
15802222606SBen Gras  * tell MI code that the cache is virtually-indexed.
15902222606SBen Gras  * ARMv6 is physically-tagged but all others are virtually-tagged.
16002222606SBen Gras  */
16102222606SBen Gras #if (ARM_MMU_V6 + ARM_MMU_V7) > 0
16202222606SBen Gras #define PMAP_CACHE_VIPT
16302222606SBen Gras #else
16402222606SBen Gras #define PMAP_CACHE_VIVT
16502222606SBen Gras #endif
16602222606SBen Gras 
16702222606SBen Gras #ifndef _LOCORE
16802222606SBen Gras 
169*0a6a1f1dSLionel Sambuc #ifndef PMAP_MMU_EXTENDED
17002222606SBen Gras struct l1_ttable;
17102222606SBen Gras struct l2_dtable;
17202222606SBen Gras 
17302222606SBen Gras /*
17402222606SBen Gras  * Track cache/tlb occupancy using the following structure
17502222606SBen Gras  */
17602222606SBen Gras union pmap_cache_state {
17702222606SBen Gras 	struct {
17802222606SBen Gras 		union {
17984d9c625SLionel Sambuc 			uint8_t csu_cache_b[2];
18084d9c625SLionel Sambuc 			uint16_t csu_cache;
18102222606SBen Gras 		} cs_cache_u;
18202222606SBen Gras 
18302222606SBen Gras 		union {
18484d9c625SLionel Sambuc 			uint8_t csu_tlb_b[2];
18584d9c625SLionel Sambuc 			uint16_t csu_tlb;
18602222606SBen Gras 		} cs_tlb_u;
18702222606SBen Gras 	} cs_s;
18884d9c625SLionel Sambuc 	uint32_t cs_all;
18902222606SBen Gras };
19002222606SBen Gras #define	cs_cache_id	cs_s.cs_cache_u.csu_cache_b[0]
19102222606SBen Gras #define	cs_cache_d	cs_s.cs_cache_u.csu_cache_b[1]
19202222606SBen Gras #define	cs_cache	cs_s.cs_cache_u.csu_cache
19302222606SBen Gras #define	cs_tlb_id	cs_s.cs_tlb_u.csu_tlb_b[0]
19402222606SBen Gras #define	cs_tlb_d	cs_s.cs_tlb_u.csu_tlb_b[1]
19502222606SBen Gras #define	cs_tlb		cs_s.cs_tlb_u.csu_tlb
19602222606SBen Gras 
19702222606SBen Gras /*
19802222606SBen Gras  * Assigned to cs_all to force cacheops to work for a particular pmap
19902222606SBen Gras  */
20002222606SBen Gras #define	PMAP_CACHE_STATE_ALL	0xffffffffu
201*0a6a1f1dSLionel Sambuc #endif /* !ARM_MMU_EXTENDED */
20202222606SBen Gras 
20302222606SBen Gras /*
20402222606SBen Gras  * This structure is used by machine-dependent code to describe
20502222606SBen Gras  * static mappings of devices, created at bootstrap time.
20602222606SBen Gras  */
20702222606SBen Gras struct pmap_devmap {
20802222606SBen Gras 	vaddr_t		pd_va;		/* virtual address */
20902222606SBen Gras 	paddr_t		pd_pa;		/* physical address */
21002222606SBen Gras 	psize_t		pd_size;	/* size of region */
21102222606SBen Gras 	vm_prot_t	pd_prot;	/* protection code */
21202222606SBen Gras 	int		pd_cache;	/* cache attributes */
21302222606SBen Gras };
21402222606SBen Gras 
21502222606SBen Gras /*
21602222606SBen Gras  * The pmap structure itself
21702222606SBen Gras  */
21802222606SBen Gras struct pmap {
21902222606SBen Gras 	struct uvm_object	pm_obj;
22002222606SBen Gras 	kmutex_t		pm_obj_lock;
22102222606SBen Gras #define	pm_lock pm_obj.vmobjlock
222*0a6a1f1dSLionel Sambuc #ifndef ARM_HAS_VBAR
223*0a6a1f1dSLionel Sambuc 	pd_entry_t		*pm_pl1vec;
224*0a6a1f1dSLionel Sambuc 	pd_entry_t		pm_l1vec;
225*0a6a1f1dSLionel Sambuc #endif
22602222606SBen Gras 	struct l2_dtable	*pm_l2[L2_SIZE];
22702222606SBen Gras 	struct pmap_statistics	pm_stats;
22802222606SBen Gras 	LIST_ENTRY(pmap)	pm_list;
229*0a6a1f1dSLionel Sambuc #ifdef ARM_MMU_EXTENDED
230*0a6a1f1dSLionel Sambuc 	pd_entry_t		*pm_l1;
231*0a6a1f1dSLionel Sambuc 	paddr_t			pm_l1_pa;
232*0a6a1f1dSLionel Sambuc 	bool			pm_remove_all;
233*0a6a1f1dSLionel Sambuc #ifdef MULTIPROCESSOR
234*0a6a1f1dSLionel Sambuc 	kcpuset_t		*pm_onproc;
235*0a6a1f1dSLionel Sambuc 	kcpuset_t		*pm_active;
236*0a6a1f1dSLionel Sambuc #if PMAP_TLB_MAX > 1
237*0a6a1f1dSLionel Sambuc 	u_int			pm_shootdown_pending;
238*0a6a1f1dSLionel Sambuc #endif
239*0a6a1f1dSLionel Sambuc #endif
240*0a6a1f1dSLionel Sambuc 	struct pmap_asid_info	pm_pai[PMAP_TLB_MAX];
241*0a6a1f1dSLionel Sambuc #else
242*0a6a1f1dSLionel Sambuc 	struct l1_ttable	*pm_l1;
243*0a6a1f1dSLionel Sambuc 	union pmap_cache_state	pm_cstate;
244*0a6a1f1dSLionel Sambuc 	uint8_t			pm_domain;
245*0a6a1f1dSLionel Sambuc 	bool			pm_activated;
246*0a6a1f1dSLionel Sambuc 	bool			pm_remove_all;
247*0a6a1f1dSLionel Sambuc #endif
248*0a6a1f1dSLionel Sambuc };
249*0a6a1f1dSLionel Sambuc 
250*0a6a1f1dSLionel Sambuc struct pmap_kernel {
251*0a6a1f1dSLionel Sambuc 	struct pmap		kernel_pmap;
25202222606SBen Gras };
25302222606SBen Gras 
25402222606SBen Gras /*
25502222606SBen Gras  * Physical / virtual address structure. In a number of places (particularly
25602222606SBen Gras  * during bootstrapping) we need to keep track of the physical and virtual
25702222606SBen Gras  * addresses of various pages
25802222606SBen Gras  */
25902222606SBen Gras typedef struct pv_addr {
26002222606SBen Gras 	SLIST_ENTRY(pv_addr) pv_list;
26102222606SBen Gras 	paddr_t pv_pa;
26202222606SBen Gras 	vaddr_t pv_va;
26302222606SBen Gras 	vsize_t pv_size;
26402222606SBen Gras 	uint8_t pv_cache;
26502222606SBen Gras 	uint8_t pv_prot;
26602222606SBen Gras } pv_addr_t;
26702222606SBen Gras typedef SLIST_HEAD(, pv_addr) pv_addrqh_t;
26802222606SBen Gras 
26902222606SBen Gras extern pv_addrqh_t pmap_freeq;
27002222606SBen Gras extern pv_addr_t kernelstack;
27102222606SBen Gras extern pv_addr_t abtstack;
27202222606SBen Gras extern pv_addr_t fiqstack;
27302222606SBen Gras extern pv_addr_t irqstack;
27402222606SBen Gras extern pv_addr_t undstack;
27502222606SBen Gras extern pv_addr_t idlestack;
27602222606SBen Gras extern pv_addr_t systempage;
27702222606SBen Gras extern pv_addr_t kernel_l1pt;
27802222606SBen Gras 
279*0a6a1f1dSLionel Sambuc #ifdef ARM_MMU_EXTENDED
280*0a6a1f1dSLionel Sambuc extern bool arm_has_tlbiasid_p;	/* also in <arm/locore.h> */
281*0a6a1f1dSLionel Sambuc #endif
282*0a6a1f1dSLionel Sambuc 
28302222606SBen Gras /*
28402222606SBen Gras  * Determine various modes for PTEs (user vs. kernel, cacheable
28502222606SBen Gras  * vs. non-cacheable).
28602222606SBen Gras  */
28702222606SBen Gras #define	PTE_KERNEL	0
28802222606SBen Gras #define	PTE_USER	1
28902222606SBen Gras #define	PTE_NOCACHE	0
29002222606SBen Gras #define	PTE_CACHE	1
29102222606SBen Gras #define	PTE_PAGETABLE	2
29202222606SBen Gras 
29302222606SBen Gras /*
29402222606SBen Gras  * Flags that indicate attributes of pages or mappings of pages.
29502222606SBen Gras  *
29602222606SBen Gras  * The PVF_MOD and PVF_REF flags are stored in the mdpage for each
29702222606SBen Gras  * page.  PVF_WIRED, PVF_WRITE, and PVF_NC are kept in individual
29802222606SBen Gras  * pv_entry's for each page.  They live in the same "namespace" so
29902222606SBen Gras  * that we can clear multiple attributes at a time.
30002222606SBen Gras  *
30102222606SBen Gras  * Note the "non-cacheable" flag generally means the page has
30202222606SBen Gras  * multiple mappings in a given address space.
30302222606SBen Gras  */
30402222606SBen Gras #define	PVF_MOD		0x01		/* page is modified */
30502222606SBen Gras #define	PVF_REF		0x02		/* page is referenced */
30602222606SBen Gras #define	PVF_WIRED	0x04		/* mapping is wired */
30702222606SBen Gras #define	PVF_WRITE	0x08		/* mapping is writable */
30802222606SBen Gras #define	PVF_EXEC	0x10		/* mapping is executable */
30902222606SBen Gras #ifdef PMAP_CACHE_VIVT
31002222606SBen Gras #define	PVF_UNC		0x20		/* mapping is 'user' non-cacheable */
31102222606SBen Gras #define	PVF_KNC		0x40		/* mapping is 'kernel' non-cacheable */
31202222606SBen Gras #define	PVF_NC		(PVF_UNC|PVF_KNC)
31302222606SBen Gras #endif
31402222606SBen Gras #ifdef PMAP_CACHE_VIPT
31502222606SBen Gras #define	PVF_NC		0x20		/* mapping is 'kernel' non-cacheable */
31602222606SBen Gras #define	PVF_MULTCLR	0x40		/* mapping is multi-colored */
31702222606SBen Gras #endif
31802222606SBen Gras #define	PVF_COLORED	0x80		/* page has or had a color */
31902222606SBen Gras #define	PVF_KENTRY	0x0100		/* page entered via pmap_kenter_pa */
32002222606SBen Gras #define	PVF_KMPAGE	0x0200		/* page is used for kmem */
32102222606SBen Gras #define	PVF_DIRTY	0x0400		/* page may have dirty cache lines */
32202222606SBen Gras #define	PVF_KMOD	0x0800		/* unmanaged page is modified  */
32302222606SBen Gras #define	PVF_KWRITE	(PVF_KENTRY|PVF_WRITE)
32402222606SBen Gras #define	PVF_DMOD	(PVF_MOD|PVF_KMOD|PVF_KMPAGE)
32502222606SBen Gras 
32602222606SBen Gras /*
32702222606SBen Gras  * Commonly referenced structures
32802222606SBen Gras  */
32902222606SBen Gras extern int		pmap_debug_level; /* Only exists if PMAP_DEBUG */
33084d9c625SLionel Sambuc extern int		arm_poolpage_vmfreelist;
33102222606SBen Gras 
33202222606SBen Gras /*
33302222606SBen Gras  * Macros that we need to export
33402222606SBen Gras  */
33502222606SBen Gras #define	pmap_resident_count(pmap)	((pmap)->pm_stats.resident_count)
33602222606SBen Gras #define	pmap_wired_count(pmap)		((pmap)->pm_stats.wired_count)
33702222606SBen Gras 
33802222606SBen Gras #define	pmap_is_modified(pg)	\
33902222606SBen Gras 	(((pg)->mdpage.pvh_attrs & PVF_MOD) != 0)
34002222606SBen Gras #define	pmap_is_referenced(pg)	\
34102222606SBen Gras 	(((pg)->mdpage.pvh_attrs & PVF_REF) != 0)
34202222606SBen Gras #define	pmap_is_page_colored_p(md)	\
34302222606SBen Gras 	(((md)->pvh_attrs & PVF_COLORED) != 0)
34402222606SBen Gras 
34502222606SBen Gras #define	pmap_copy(dp, sp, da, l, sa)	/* nothing */
34602222606SBen Gras 
34702222606SBen Gras #define pmap_phys_address(ppn)		(arm_ptob((ppn)))
34802222606SBen Gras u_int arm32_mmap_flags(paddr_t);
34902222606SBen Gras #define ARM32_MMAP_WRITECOMBINE		0x40000000
35002222606SBen Gras #define ARM32_MMAP_CACHEABLE		0x20000000
35102222606SBen Gras #define pmap_mmap_flags(ppn)		arm32_mmap_flags(ppn)
35202222606SBen Gras 
353*0a6a1f1dSLionel Sambuc #define	PMAP_PTE			0x10000000 /* kenter_pa */
354*0a6a1f1dSLionel Sambuc 
35502222606SBen Gras /*
35602222606SBen Gras  * Functions that we need to export
35702222606SBen Gras  */
35802222606SBen Gras void	pmap_procwr(struct proc *, vaddr_t, int);
35902222606SBen Gras void	pmap_remove_all(pmap_t);
36002222606SBen Gras bool	pmap_extract(pmap_t, vaddr_t, paddr_t *);
36102222606SBen Gras 
36202222606SBen Gras #define	PMAP_NEED_PROCWR
36302222606SBen Gras #define PMAP_GROWKERNEL		/* turn on pmap_growkernel interface */
36402222606SBen Gras #define	PMAP_ENABLE_PMAP_KMPAGE	/* enable the PMAP_KMPAGE flag */
36502222606SBen Gras 
36602222606SBen Gras #if (ARM_MMU_V6 + ARM_MMU_V7) > 0
36702222606SBen Gras #define	PMAP_PREFER(hint, vap, sz, td)	pmap_prefer((hint), (vap), (td))
36802222606SBen Gras void	pmap_prefer(vaddr_t, vaddr_t *, int);
36902222606SBen Gras #endif
37002222606SBen Gras 
37102222606SBen Gras void	pmap_icache_sync_range(pmap_t, vaddr_t, vaddr_t);
37202222606SBen Gras 
37302222606SBen Gras /* Functions we use internally. */
37402222606SBen Gras #ifdef PMAP_STEAL_MEMORY
37502222606SBen Gras void	pmap_boot_pagealloc(psize_t, psize_t, psize_t, pv_addr_t *);
37602222606SBen Gras void	pmap_boot_pageadd(pv_addr_t *);
37702222606SBen Gras vaddr_t	pmap_steal_memory(vsize_t, vaddr_t *, vaddr_t *);
37802222606SBen Gras #endif
37902222606SBen Gras void	pmap_bootstrap(vaddr_t, vaddr_t);
38002222606SBen Gras 
38102222606SBen Gras void	pmap_do_remove(pmap_t, vaddr_t, vaddr_t, int);
38202222606SBen Gras int	pmap_fault_fixup(pmap_t, vaddr_t, vm_prot_t, int);
383*0a6a1f1dSLionel Sambuc int	pmap_prefetchabt_fixup(void *);
38402222606SBen Gras bool	pmap_get_pde_pte(pmap_t, vaddr_t, pd_entry_t **, pt_entry_t **);
38502222606SBen Gras bool	pmap_get_pde(pmap_t, vaddr_t, pd_entry_t **);
38684d9c625SLionel Sambuc struct pcb;
38702222606SBen Gras void	pmap_set_pcb_pagedir(pmap_t, struct pcb *);
38802222606SBen Gras 
38902222606SBen Gras void	pmap_debug(int);
39002222606SBen Gras void	pmap_postinit(void);
39102222606SBen Gras 
39202222606SBen Gras void	vector_page_setprot(int);
39302222606SBen Gras 
39402222606SBen Gras const struct pmap_devmap *pmap_devmap_find_pa(paddr_t, psize_t);
39502222606SBen Gras const struct pmap_devmap *pmap_devmap_find_va(vaddr_t, vsize_t);
39602222606SBen Gras 
39702222606SBen Gras /* Bootstrapping routines. */
39802222606SBen Gras void	pmap_map_section(vaddr_t, vaddr_t, paddr_t, int, int);
39902222606SBen Gras void	pmap_map_entry(vaddr_t, vaddr_t, paddr_t, int, int);
40002222606SBen Gras vsize_t	pmap_map_chunk(vaddr_t, vaddr_t, paddr_t, vsize_t, int, int);
40102222606SBen Gras void	pmap_link_l2pt(vaddr_t, vaddr_t, pv_addr_t *);
40202222606SBen Gras void	pmap_devmap_bootstrap(vaddr_t, const struct pmap_devmap *);
40302222606SBen Gras void	pmap_devmap_register(const struct pmap_devmap *);
40402222606SBen Gras 
40502222606SBen Gras /*
40602222606SBen Gras  * Special page zero routine for use by the idle loop (no cache cleans).
40702222606SBen Gras  */
40802222606SBen Gras bool	pmap_pageidlezero(paddr_t);
40902222606SBen Gras #define PMAP_PAGEIDLEZERO(pa)	pmap_pageidlezero((pa))
41002222606SBen Gras 
411*0a6a1f1dSLionel Sambuc #ifdef __HAVE_MM_MD_DIRECT_MAPPED_PHYS
412*0a6a1f1dSLionel Sambuc /*
413*0a6a1f1dSLionel Sambuc  * For the pmap, this is a more useful way to map a direct mapped page.
414*0a6a1f1dSLionel Sambuc  * It returns either the direct-mapped VA or the VA supplied if it can't
415*0a6a1f1dSLionel Sambuc  * be direct mapped.
416*0a6a1f1dSLionel Sambuc  */
417*0a6a1f1dSLionel Sambuc vaddr_t	pmap_direct_mapped_phys(paddr_t, bool *, vaddr_t);
418*0a6a1f1dSLionel Sambuc #endif
419*0a6a1f1dSLionel Sambuc 
42002222606SBen Gras /*
42102222606SBen Gras  * used by dumpsys to record the PA of the L1 table
42202222606SBen Gras  */
42302222606SBen Gras uint32_t pmap_kernel_L1_addr(void);
42402222606SBen Gras /*
42502222606SBen Gras  * The current top of kernel VM
42602222606SBen Gras  */
42702222606SBen Gras extern vaddr_t	pmap_curmaxkvaddr;
42802222606SBen Gras 
429*0a6a1f1dSLionel Sambuc #if defined(ARM_MMU_EXTENDED) && defined(__HAVE_MM_MD_DIRECT_MAPPED_PHYS)
430*0a6a1f1dSLionel Sambuc /*
431*0a6a1f1dSLionel Sambuc  * Ending VA of direct mapped memory (usually KERNEL_VM_BASE).
432*0a6a1f1dSLionel Sambuc  */
433*0a6a1f1dSLionel Sambuc extern vaddr_t pmap_directlimit;
434*0a6a1f1dSLionel Sambuc #endif
435*0a6a1f1dSLionel Sambuc 
43602222606SBen Gras /*
43702222606SBen Gras  * Useful macros and constants
43802222606SBen Gras  */
43902222606SBen Gras 
44002222606SBen Gras /* Virtual address to page table entry */
44102222606SBen Gras static inline pt_entry_t *
vtopte(vaddr_t va)44202222606SBen Gras vtopte(vaddr_t va)
44302222606SBen Gras {
44402222606SBen Gras 	pd_entry_t *pdep;
44502222606SBen Gras 	pt_entry_t *ptep;
44602222606SBen Gras 
447*0a6a1f1dSLionel Sambuc 	KASSERT(trunc_page(va) == va);
448*0a6a1f1dSLionel Sambuc 
44902222606SBen Gras 	if (pmap_get_pde_pte(pmap_kernel(), va, &pdep, &ptep) == false)
45002222606SBen Gras 		return (NULL);
45102222606SBen Gras 	return (ptep);
45202222606SBen Gras }
45302222606SBen Gras 
45402222606SBen Gras /*
45502222606SBen Gras  * Virtual address to physical address
45602222606SBen Gras  */
45702222606SBen Gras static inline paddr_t
vtophys(vaddr_t va)45802222606SBen Gras vtophys(vaddr_t va)
45902222606SBen Gras {
46002222606SBen Gras 	paddr_t pa;
46102222606SBen Gras 
46202222606SBen Gras 	if (pmap_extract(pmap_kernel(), va, &pa) == false)
46302222606SBen Gras 		return (0);	/* XXXSCW: Panic? */
46402222606SBen Gras 
46502222606SBen Gras 	return (pa);
46602222606SBen Gras }
46702222606SBen Gras 
46802222606SBen Gras /*
46902222606SBen Gras  * The new pmap ensures that page-tables are always mapping Write-Thru.
47002222606SBen Gras  * Thus, on some platforms we can run fast and loose and avoid syncing PTEs
47102222606SBen Gras  * on every change.
47202222606SBen Gras  *
47302222606SBen Gras  * Unfortunately, not all CPUs have a write-through cache mode.  So we
47402222606SBen Gras  * define PMAP_NEEDS_PTE_SYNC for C code to conditionally do PTE syncs,
47502222606SBen Gras  * and if there is the chance for PTE syncs to be needed, we define
47602222606SBen Gras  * PMAP_INCLUDE_PTE_SYNC so e.g. assembly code can include (and run)
47702222606SBen Gras  * the code.
47802222606SBen Gras  */
47902222606SBen Gras extern int pmap_needs_pte_sync;
48002222606SBen Gras #if defined(_KERNEL_OPT)
48102222606SBen Gras /*
48202222606SBen Gras  * StrongARM SA-1 caches do not have a write-through mode.  So, on these,
48302222606SBen Gras  * we need to do PTE syncs.  If only SA-1 is configured, then evaluate
48402222606SBen Gras  * this at compile time.
48502222606SBen Gras  */
48602222606SBen Gras #if (ARM_MMU_SA1 + ARM_MMU_V6 != 0) && (ARM_NMMUS == 1)
48702222606SBen Gras #define	PMAP_INCLUDE_PTE_SYNC
48802222606SBen Gras #if (ARM_MMU_V6 > 0)
48902222606SBen Gras #define	PMAP_NEEDS_PTE_SYNC	1
49002222606SBen Gras #elif (ARM_MMU_SA1 == 0)
49102222606SBen Gras #define	PMAP_NEEDS_PTE_SYNC	0
49202222606SBen Gras #endif
49302222606SBen Gras #endif
49402222606SBen Gras #endif /* _KERNEL_OPT */
49502222606SBen Gras 
49602222606SBen Gras /*
49702222606SBen Gras  * Provide a fallback in case we were not able to determine it at
49802222606SBen Gras  * compile-time.
49902222606SBen Gras  */
50002222606SBen Gras #ifndef PMAP_NEEDS_PTE_SYNC
50102222606SBen Gras #define	PMAP_NEEDS_PTE_SYNC	pmap_needs_pte_sync
50202222606SBen Gras #define	PMAP_INCLUDE_PTE_SYNC
50302222606SBen Gras #endif
50402222606SBen Gras 
50502222606SBen Gras static inline void
pmap_ptesync(pt_entry_t * ptep,size_t cnt)50602222606SBen Gras pmap_ptesync(pt_entry_t *ptep, size_t cnt)
50702222606SBen Gras {
508*0a6a1f1dSLionel Sambuc 	if (PMAP_NEEDS_PTE_SYNC) {
50902222606SBen Gras 		cpu_dcache_wb_range((vaddr_t)ptep, cnt * sizeof(pt_entry_t));
510*0a6a1f1dSLionel Sambuc #ifdef SHEEVA_L2_CACHE
511*0a6a1f1dSLionel Sambuc 		cpu_sdcache_wb_range((vaddr_t)ptep, -1,
512*0a6a1f1dSLionel Sambuc 		    cnt * sizeof(pt_entry_t));
51302222606SBen Gras #endif
51402222606SBen Gras 	}
515*0a6a1f1dSLionel Sambuc 	arm_dsb();
516*0a6a1f1dSLionel Sambuc }
51702222606SBen Gras 
518*0a6a1f1dSLionel Sambuc #define	PDE_SYNC(pdep)			pmap_ptesync((pdep), 1)
519*0a6a1f1dSLionel Sambuc #define	PDE_SYNC_RANGE(pdep, cnt)	pmap_ptesync((pdep), (cnt))
520*0a6a1f1dSLionel Sambuc #define	PTE_SYNC(ptep)			pmap_ptesync((ptep), PAGE_SIZE / L2_S_SIZE)
52102222606SBen Gras #define	PTE_SYNC_RANGE(ptep, cnt)	pmap_ptesync((ptep), (cnt))
52202222606SBen Gras 
523*0a6a1f1dSLionel Sambuc #define l1pte_valid_p(pde)	((pde) != 0)
52402222606SBen Gras #define l1pte_section_p(pde)	(((pde) & L1_TYPE_MASK) == L1_TYPE_S)
52502222606SBen Gras #define l1pte_supersection_p(pde) (l1pte_section_p(pde)	\
52602222606SBen Gras 				&& ((pde) & L1_S_V6_SUPER) != 0)
52702222606SBen Gras #define l1pte_page_p(pde)	(((pde) & L1_TYPE_MASK) == L1_TYPE_C)
52802222606SBen Gras #define l1pte_fpage_p(pde)	(((pde) & L1_TYPE_MASK) == L1_TYPE_F)
529*0a6a1f1dSLionel Sambuc #define l1pte_pa(pde)		((pde) & L1_C_ADDR_MASK)
530*0a6a1f1dSLionel Sambuc #define l1pte_index(v)		((vaddr_t)(v) >> L1_S_SHIFT)
531*0a6a1f1dSLionel Sambuc #define l1pte_pgindex(v)	l1pte_index((v) & L1_ADDR_BITS \
532*0a6a1f1dSLionel Sambuc 		& ~(PAGE_SIZE * PAGE_SIZE / sizeof(pt_entry_t) - 1))
53302222606SBen Gras 
534*0a6a1f1dSLionel Sambuc static inline void
l1pte_setone(pt_entry_t * pdep,pt_entry_t pde)535*0a6a1f1dSLionel Sambuc l1pte_setone(pt_entry_t *pdep, pt_entry_t pde)
536*0a6a1f1dSLionel Sambuc {
537*0a6a1f1dSLionel Sambuc 	*pdep = pde;
538*0a6a1f1dSLionel Sambuc }
539*0a6a1f1dSLionel Sambuc 
540*0a6a1f1dSLionel Sambuc static inline void
l1pte_set(pt_entry_t * pdep,pt_entry_t pde)541*0a6a1f1dSLionel Sambuc l1pte_set(pt_entry_t *pdep, pt_entry_t pde)
542*0a6a1f1dSLionel Sambuc {
543*0a6a1f1dSLionel Sambuc 	*pdep = pde;
544*0a6a1f1dSLionel Sambuc 	if (l1pte_page_p(pde)) {
545*0a6a1f1dSLionel Sambuc 		KASSERTMSG((((uintptr_t)pdep / sizeof(pde)) & (PAGE_SIZE / L2_T_SIZE - 1)) == 0, "%p", pdep);
546*0a6a1f1dSLionel Sambuc 		for (size_t k = 1; k < PAGE_SIZE / L2_T_SIZE; k++) {
547*0a6a1f1dSLionel Sambuc 			pde += L2_T_SIZE;
548*0a6a1f1dSLionel Sambuc 			pdep[k] = pde;
549*0a6a1f1dSLionel Sambuc 		}
550*0a6a1f1dSLionel Sambuc 	} else if (l1pte_supersection_p(pde)) {
551*0a6a1f1dSLionel Sambuc 		KASSERTMSG((((uintptr_t)pdep / sizeof(pde)) & (L1_SS_SIZE / L1_S_SIZE - 1)) == 0, "%p", pdep);
552*0a6a1f1dSLionel Sambuc 		for (size_t k = 1; k < L1_SS_SIZE / L1_S_SIZE; k++) {
553*0a6a1f1dSLionel Sambuc 			pdep[k] = pde;
554*0a6a1f1dSLionel Sambuc 		}
555*0a6a1f1dSLionel Sambuc 	}
556*0a6a1f1dSLionel Sambuc }
557*0a6a1f1dSLionel Sambuc 
558*0a6a1f1dSLionel Sambuc #define l2pte_index(v)		((((v) & L2_ADDR_BITS) >> PGSHIFT) << (PGSHIFT-L2_S_SHIFT))
559*0a6a1f1dSLionel Sambuc #define l2pte_valid_p(pte)	(((pte) & L2_TYPE_MASK) != L2_TYPE_INV)
56002222606SBen Gras #define l2pte_pa(pte)		((pte) & L2_S_FRAME)
561*0a6a1f1dSLionel Sambuc #define l1pte_lpage_p(pte)	(((pte) & L2_TYPE_MASK) == L2_TYPE_L)
562*0a6a1f1dSLionel Sambuc #define l2pte_minidata_p(pte)	(((pte) & \
56302222606SBen Gras 				 (L2_B | L2_C | L2_XS_T_TEX(TEX_XSCALE_X)))\
56402222606SBen Gras 				 == (L2_C | L2_XS_T_TEX(TEX_XSCALE_X)))
56502222606SBen Gras 
56684d9c625SLionel Sambuc static inline void
l2pte_set(pt_entry_t * ptep,pt_entry_t pte,pt_entry_t opte)56784d9c625SLionel Sambuc l2pte_set(pt_entry_t *ptep, pt_entry_t pte, pt_entry_t opte)
56884d9c625SLionel Sambuc {
569*0a6a1f1dSLionel Sambuc 	if (l1pte_lpage_p(pte)) {
570*0a6a1f1dSLionel Sambuc 		KASSERTMSG((((uintptr_t)ptep / sizeof(pte)) & (L2_L_SIZE / L2_S_SIZE - 1)) == 0, "%p", ptep);
571*0a6a1f1dSLionel Sambuc 		for (size_t k = 0; k < L2_L_SIZE / L2_S_SIZE; k++) {
572*0a6a1f1dSLionel Sambuc 			*ptep++ = pte;
573*0a6a1f1dSLionel Sambuc 		}
574*0a6a1f1dSLionel Sambuc 	} else {
575*0a6a1f1dSLionel Sambuc 		KASSERTMSG((((uintptr_t)ptep / sizeof(pte)) & (PAGE_SIZE / L2_S_SIZE - 1)) == 0, "%p", ptep);
576*0a6a1f1dSLionel Sambuc 		for (size_t k = 0; k < PAGE_SIZE / L2_S_SIZE; k++) {
577*0a6a1f1dSLionel Sambuc 			KASSERTMSG(*ptep == opte, "%#x [*%p] != %#x", *ptep, ptep, opte);
578*0a6a1f1dSLionel Sambuc 			*ptep++ = pte;
57984d9c625SLionel Sambuc 			pte += L2_S_SIZE;
580*0a6a1f1dSLionel Sambuc 			if (opte)
581*0a6a1f1dSLionel Sambuc 				opte += L2_S_SIZE;
582*0a6a1f1dSLionel Sambuc 		}
58384d9c625SLionel Sambuc 	}
58484d9c625SLionel Sambuc }
58584d9c625SLionel Sambuc 
58684d9c625SLionel Sambuc static inline void
l2pte_reset(pt_entry_t * ptep)58784d9c625SLionel Sambuc l2pte_reset(pt_entry_t *ptep)
58884d9c625SLionel Sambuc {
589*0a6a1f1dSLionel Sambuc 	KASSERTMSG((((uintptr_t)ptep / sizeof(*ptep)) & (PAGE_SIZE / L2_S_SIZE - 1)) == 0, "%p", ptep);
59084d9c625SLionel Sambuc 	*ptep = 0;
59184d9c625SLionel Sambuc 	for (vsize_t k = 1; k < PAGE_SIZE / L2_S_SIZE; k++) {
59284d9c625SLionel Sambuc 		ptep[k] = 0;
59384d9c625SLionel Sambuc 	}
59484d9c625SLionel Sambuc }
59584d9c625SLionel Sambuc 
59602222606SBen Gras /* L1 and L2 page table macros */
59702222606SBen Gras #define pmap_pde_v(pde)		l1pte_valid(*(pde))
59802222606SBen Gras #define pmap_pde_section(pde)	l1pte_section_p(*(pde))
59902222606SBen Gras #define pmap_pde_supersection(pde)	l1pte_supersection_p(*(pde))
60002222606SBen Gras #define pmap_pde_page(pde)	l1pte_page_p(*(pde))
60102222606SBen Gras #define pmap_pde_fpage(pde)	l1pte_fpage_p(*(pde))
60202222606SBen Gras 
603*0a6a1f1dSLionel Sambuc #define	pmap_pte_v(pte)		l2pte_valid_p(*(pte))
60402222606SBen Gras #define	pmap_pte_pa(pte)	l2pte_pa(*(pte))
60502222606SBen Gras 
60602222606SBen Gras /* Size of the kernel part of the L1 page table */
60702222606SBen Gras #define KERNEL_PD_SIZE	\
60802222606SBen Gras 	(L1_TABLE_SIZE - (KERNEL_BASE >> L1_S_SHIFT) * sizeof(pd_entry_t))
60902222606SBen Gras 
61084d9c625SLionel Sambuc void	bzero_page(vaddr_t);
61184d9c625SLionel Sambuc void	bcopy_page(vaddr_t, vaddr_t);
61284d9c625SLionel Sambuc 
61384d9c625SLionel Sambuc #ifdef FPU_VFP
61484d9c625SLionel Sambuc void	bzero_page_vfp(vaddr_t);
61584d9c625SLionel Sambuc void	bcopy_page_vfp(vaddr_t, vaddr_t);
61684d9c625SLionel Sambuc #endif
61784d9c625SLionel Sambuc 
61802222606SBen Gras /************************* ARM MMU configuration *****************************/
61902222606SBen Gras 
62002222606SBen Gras #if (ARM_MMU_GENERIC + ARM_MMU_SA1 + ARM_MMU_V6 + ARM_MMU_V7) != 0
62102222606SBen Gras void	pmap_copy_page_generic(paddr_t, paddr_t);
62202222606SBen Gras void	pmap_zero_page_generic(paddr_t);
62302222606SBen Gras 
62402222606SBen Gras void	pmap_pte_init_generic(void);
62502222606SBen Gras #if defined(CPU_ARM8)
62602222606SBen Gras void	pmap_pte_init_arm8(void);
62702222606SBen Gras #endif
62802222606SBen Gras #if defined(CPU_ARM9)
62902222606SBen Gras void	pmap_pte_init_arm9(void);
63002222606SBen Gras #endif /* CPU_ARM9 */
63102222606SBen Gras #if defined(CPU_ARM10)
63202222606SBen Gras void	pmap_pte_init_arm10(void);
63302222606SBen Gras #endif /* CPU_ARM10 */
63402222606SBen Gras #if defined(CPU_ARM11)	/* ARM_MMU_V6 */
63502222606SBen Gras void	pmap_pte_init_arm11(void);
63602222606SBen Gras #endif /* CPU_ARM11 */
63702222606SBen Gras #if defined(CPU_ARM11MPCORE)	/* ARM_MMU_V6 */
63802222606SBen Gras void	pmap_pte_init_arm11mpcore(void);
63902222606SBen Gras #endif
64002222606SBen Gras #if ARM_MMU_V7 == 1
64102222606SBen Gras void	pmap_pte_init_armv7(void);
64202222606SBen Gras #endif /* ARM_MMU_V7 */
64302222606SBen Gras #endif /* (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0 */
64402222606SBen Gras 
64502222606SBen Gras #if ARM_MMU_SA1 == 1
64602222606SBen Gras void	pmap_pte_init_sa1(void);
64702222606SBen Gras #endif /* ARM_MMU_SA1 == 1 */
64802222606SBen Gras 
64902222606SBen Gras #if ARM_MMU_XSCALE == 1
65002222606SBen Gras void	pmap_copy_page_xscale(paddr_t, paddr_t);
65102222606SBen Gras void	pmap_zero_page_xscale(paddr_t);
65202222606SBen Gras 
65302222606SBen Gras void	pmap_pte_init_xscale(void);
65402222606SBen Gras 
65502222606SBen Gras void	xscale_setup_minidata(vaddr_t, vaddr_t, paddr_t);
65602222606SBen Gras 
65702222606SBen Gras #define	PMAP_UAREA(va)		pmap_uarea(va)
65802222606SBen Gras void	pmap_uarea(vaddr_t);
65902222606SBen Gras #endif /* ARM_MMU_XSCALE == 1 */
66002222606SBen Gras 
66102222606SBen Gras extern pt_entry_t		pte_l1_s_cache_mode;
66202222606SBen Gras extern pt_entry_t		pte_l1_s_cache_mask;
66302222606SBen Gras 
66402222606SBen Gras extern pt_entry_t		pte_l2_l_cache_mode;
66502222606SBen Gras extern pt_entry_t		pte_l2_l_cache_mask;
66602222606SBen Gras 
66702222606SBen Gras extern pt_entry_t		pte_l2_s_cache_mode;
66802222606SBen Gras extern pt_entry_t		pte_l2_s_cache_mask;
66902222606SBen Gras 
67002222606SBen Gras extern pt_entry_t		pte_l1_s_cache_mode_pt;
67102222606SBen Gras extern pt_entry_t		pte_l2_l_cache_mode_pt;
67202222606SBen Gras extern pt_entry_t		pte_l2_s_cache_mode_pt;
67302222606SBen Gras 
67402222606SBen Gras extern pt_entry_t		pte_l1_s_wc_mode;
67502222606SBen Gras extern pt_entry_t		pte_l2_l_wc_mode;
67602222606SBen Gras extern pt_entry_t		pte_l2_s_wc_mode;
67702222606SBen Gras 
67802222606SBen Gras extern pt_entry_t		pte_l1_s_prot_u;
67902222606SBen Gras extern pt_entry_t		pte_l1_s_prot_w;
68002222606SBen Gras extern pt_entry_t		pte_l1_s_prot_ro;
68102222606SBen Gras extern pt_entry_t		pte_l1_s_prot_mask;
68202222606SBen Gras 
68302222606SBen Gras extern pt_entry_t		pte_l2_s_prot_u;
68402222606SBen Gras extern pt_entry_t		pte_l2_s_prot_w;
68502222606SBen Gras extern pt_entry_t		pte_l2_s_prot_ro;
68602222606SBen Gras extern pt_entry_t		pte_l2_s_prot_mask;
68702222606SBen Gras 
68802222606SBen Gras extern pt_entry_t		pte_l2_l_prot_u;
68902222606SBen Gras extern pt_entry_t		pte_l2_l_prot_w;
69002222606SBen Gras extern pt_entry_t		pte_l2_l_prot_ro;
69102222606SBen Gras extern pt_entry_t		pte_l2_l_prot_mask;
69202222606SBen Gras 
69302222606SBen Gras extern pt_entry_t		pte_l1_ss_proto;
69402222606SBen Gras extern pt_entry_t		pte_l1_s_proto;
69502222606SBen Gras extern pt_entry_t		pte_l1_c_proto;
69602222606SBen Gras extern pt_entry_t		pte_l2_s_proto;
69702222606SBen Gras 
69802222606SBen Gras extern void (*pmap_copy_page_func)(paddr_t, paddr_t);
69902222606SBen Gras extern void (*pmap_zero_page_func)(paddr_t);
70002222606SBen Gras 
70102222606SBen Gras #endif /* !_LOCORE */
70202222606SBen Gras 
70302222606SBen Gras /*****************************************************************************/
70402222606SBen Gras 
705*0a6a1f1dSLionel Sambuc #define	KERNEL_PID		0	/* The kernel uses ASID 0 */
706*0a6a1f1dSLionel Sambuc 
70702222606SBen Gras /*
70802222606SBen Gras  * Definitions for MMU domains
70902222606SBen Gras  */
71002222606SBen Gras #define	PMAP_DOMAINS		15	/* 15 'user' domains (1-15) */
711*0a6a1f1dSLionel Sambuc #define	PMAP_DOMAIN_KERNEL	0	/* The kernel pmap uses domain #0 */
712*0a6a1f1dSLionel Sambuc #ifdef ARM_MMU_EXTENDED
713*0a6a1f1dSLionel Sambuc #define	PMAP_DOMAIN_USER	1	/* User pmaps use domain #1 */
714*0a6a1f1dSLionel Sambuc #endif
71502222606SBen Gras 
71602222606SBen Gras /*
71702222606SBen Gras  * These macros define the various bit masks in the PTE.
71802222606SBen Gras  *
71902222606SBen Gras  * We use these macros since we use different bits on different processor
72002222606SBen Gras  * models.
72102222606SBen Gras  */
72202222606SBen Gras #define	L1_S_PROT_U_generic	(L1_S_AP(AP_U))
72302222606SBen Gras #define	L1_S_PROT_W_generic	(L1_S_AP(AP_W))
72402222606SBen Gras #define	L1_S_PROT_RO_generic	(0)
72502222606SBen Gras #define	L1_S_PROT_MASK_generic	(L1_S_PROT_U|L1_S_PROT_W|L1_S_PROT_RO)
72602222606SBen Gras 
72702222606SBen Gras #define	L1_S_PROT_U_xscale	(L1_S_AP(AP_U))
72802222606SBen Gras #define	L1_S_PROT_W_xscale	(L1_S_AP(AP_W))
72902222606SBen Gras #define	L1_S_PROT_RO_xscale	(0)
73002222606SBen Gras #define	L1_S_PROT_MASK_xscale	(L1_S_PROT_U|L1_S_PROT_W|L1_S_PROT_RO)
73102222606SBen Gras 
73202222606SBen Gras #define	L1_S_PROT_U_armv6	(L1_S_AP(AP_R) | L1_S_AP(AP_U))
73302222606SBen Gras #define	L1_S_PROT_W_armv6	(L1_S_AP(AP_W))
73402222606SBen Gras #define	L1_S_PROT_RO_armv6	(L1_S_AP(AP_R) | L1_S_AP(AP_RO))
73502222606SBen Gras #define	L1_S_PROT_MASK_armv6	(L1_S_PROT_U|L1_S_PROT_W|L1_S_PROT_RO)
73602222606SBen Gras 
73702222606SBen Gras #define	L1_S_PROT_U_armv7	(L1_S_AP(AP_R) | L1_S_AP(AP_U))
73802222606SBen Gras #define	L1_S_PROT_W_armv7	(L1_S_AP(AP_W))
73902222606SBen Gras #define	L1_S_PROT_RO_armv7	(L1_S_AP(AP_R) | L1_S_AP(AP_RO))
74002222606SBen Gras #define	L1_S_PROT_MASK_armv7	(L1_S_PROT_U|L1_S_PROT_W|L1_S_PROT_RO)
74102222606SBen Gras 
74202222606SBen Gras #define	L1_S_CACHE_MASK_generic	(L1_S_B|L1_S_C)
74302222606SBen Gras #define	L1_S_CACHE_MASK_xscale	(L1_S_B|L1_S_C|L1_S_XS_TEX(TEX_XSCALE_X))
74402222606SBen Gras #define	L1_S_CACHE_MASK_armv6	(L1_S_B|L1_S_C|L1_S_XS_TEX(TEX_ARMV6_TEX))
745*0a6a1f1dSLionel Sambuc #define	L1_S_CACHE_MASK_armv6n	(L1_S_B|L1_S_C|L1_S_XS_TEX(TEX_ARMV6_TEX)|L1_S_V6_S)
74602222606SBen Gras #define	L1_S_CACHE_MASK_armv7	(L1_S_B|L1_S_C|L1_S_XS_TEX(TEX_ARMV6_TEX)|L1_S_V6_S)
74702222606SBen Gras 
74802222606SBen Gras #define	L2_L_PROT_U_generic	(L2_AP(AP_U))
74902222606SBen Gras #define	L2_L_PROT_W_generic	(L2_AP(AP_W))
75002222606SBen Gras #define	L2_L_PROT_RO_generic	(0)
75102222606SBen Gras #define	L2_L_PROT_MASK_generic	(L2_L_PROT_U|L2_L_PROT_W|L2_L_PROT_RO)
75202222606SBen Gras 
75302222606SBen Gras #define	L2_L_PROT_U_xscale	(L2_AP(AP_U))
75402222606SBen Gras #define	L2_L_PROT_W_xscale	(L2_AP(AP_W))
75502222606SBen Gras #define	L2_L_PROT_RO_xscale	(0)
75602222606SBen Gras #define	L2_L_PROT_MASK_xscale	(L2_L_PROT_U|L2_L_PROT_W|L2_L_PROT_RO)
75702222606SBen Gras 
75802222606SBen Gras #define	L2_L_PROT_U_armv6n	(L2_AP0(AP_R) | L2_AP0(AP_U))
75902222606SBen Gras #define	L2_L_PROT_W_armv6n	(L2_AP0(AP_W))
76002222606SBen Gras #define	L2_L_PROT_RO_armv6n	(L2_AP0(AP_R) | L2_AP0(AP_RO))
76102222606SBen Gras #define	L2_L_PROT_MASK_armv6n	(L2_L_PROT_U|L2_L_PROT_W|L2_L_PROT_RO)
76202222606SBen Gras 
76302222606SBen Gras #define	L2_L_PROT_U_armv7	(L2_AP0(AP_R) | L2_AP0(AP_U))
76402222606SBen Gras #define	L2_L_PROT_W_armv7	(L2_AP0(AP_W))
76502222606SBen Gras #define	L2_L_PROT_RO_armv7	(L2_AP0(AP_R) | L2_AP0(AP_RO))
76602222606SBen Gras #define	L2_L_PROT_MASK_armv7	(L2_L_PROT_U|L2_L_PROT_W|L2_L_PROT_RO)
76702222606SBen Gras 
76802222606SBen Gras #define	L2_L_CACHE_MASK_generic	(L2_B|L2_C)
76902222606SBen Gras #define	L2_L_CACHE_MASK_xscale	(L2_B|L2_C|L2_XS_L_TEX(TEX_XSCALE_X))
77002222606SBen Gras #define	L2_L_CACHE_MASK_armv6	(L2_B|L2_C|L2_V6_L_TEX(TEX_ARMV6_TEX))
771*0a6a1f1dSLionel Sambuc #define	L2_L_CACHE_MASK_armv6n	(L2_B|L2_C|L2_V6_L_TEX(TEX_ARMV6_TEX)|L2_XS_S)
77202222606SBen Gras #define	L2_L_CACHE_MASK_armv7	(L2_B|L2_C|L2_V6_L_TEX(TEX_ARMV6_TEX)|L2_XS_S)
77302222606SBen Gras 
77402222606SBen Gras #define	L2_S_PROT_U_generic	(L2_AP(AP_U))
77502222606SBen Gras #define	L2_S_PROT_W_generic	(L2_AP(AP_W))
77602222606SBen Gras #define	L2_S_PROT_RO_generic	(0)
77702222606SBen Gras #define	L2_S_PROT_MASK_generic	(L2_S_PROT_U|L2_S_PROT_W|L2_S_PROT_RO)
77802222606SBen Gras 
77902222606SBen Gras #define	L2_S_PROT_U_xscale	(L2_AP0(AP_U))
78002222606SBen Gras #define	L2_S_PROT_W_xscale	(L2_AP0(AP_W))
78102222606SBen Gras #define	L2_S_PROT_RO_xscale	(0)
78202222606SBen Gras #define	L2_S_PROT_MASK_xscale	(L2_S_PROT_U|L2_S_PROT_W|L2_S_PROT_RO)
78302222606SBen Gras 
78402222606SBen Gras #define	L2_S_PROT_U_armv6n	(L2_AP0(AP_R) | L2_AP0(AP_U))
78502222606SBen Gras #define	L2_S_PROT_W_armv6n	(L2_AP0(AP_W))
78602222606SBen Gras #define	L2_S_PROT_RO_armv6n	(L2_AP0(AP_R) | L2_AP0(AP_RO))
78702222606SBen Gras #define	L2_S_PROT_MASK_armv6n	(L2_S_PROT_U|L2_S_PROT_W|L2_S_PROT_RO)
78802222606SBen Gras 
78902222606SBen Gras #define	L2_S_PROT_U_armv7	(L2_AP0(AP_R) | L2_AP0(AP_U))
79002222606SBen Gras #define	L2_S_PROT_W_armv7	(L2_AP0(AP_W))
79102222606SBen Gras #define	L2_S_PROT_RO_armv7	(L2_AP0(AP_R) | L2_AP0(AP_RO))
79202222606SBen Gras #define	L2_S_PROT_MASK_armv7	(L2_S_PROT_U|L2_S_PROT_W|L2_S_PROT_RO)
79302222606SBen Gras 
79402222606SBen Gras #define	L2_S_CACHE_MASK_generic	(L2_B|L2_C)
79502222606SBen Gras #define	L2_S_CACHE_MASK_xscale	(L2_B|L2_C|L2_XS_T_TEX(TEX_XSCALE_X))
79602222606SBen Gras #define	L2_XS_CACHE_MASK_armv6	(L2_B|L2_C|L2_V6_XS_TEX(TEX_ARMV6_TEX))
79702222606SBen Gras #ifdef	ARMV6_EXTENDED_SMALL_PAGE
79802222606SBen Gras #define	L2_S_CACHE_MASK_armv6c	L2_XS_CACHE_MASK_armv6
79902222606SBen Gras #else
80002222606SBen Gras #define	L2_S_CACHE_MASK_armv6c	L2_S_CACHE_MASK_generic
80102222606SBen Gras #endif
802*0a6a1f1dSLionel Sambuc #define	L2_S_CACHE_MASK_armv6n	(L2_B|L2_C|L2_V6_XS_TEX(TEX_ARMV6_TEX)|L2_XS_S)
80302222606SBen Gras #define	L2_S_CACHE_MASK_armv7	(L2_B|L2_C|L2_V6_XS_TEX(TEX_ARMV6_TEX)|L2_XS_S)
80402222606SBen Gras 
80502222606SBen Gras 
80602222606SBen Gras #define	L1_S_PROTO_generic	(L1_TYPE_S | L1_S_IMP)
80702222606SBen Gras #define	L1_S_PROTO_xscale	(L1_TYPE_S)
80802222606SBen Gras #define	L1_S_PROTO_armv6	(L1_TYPE_S)
80902222606SBen Gras #define	L1_S_PROTO_armv7	(L1_TYPE_S)
81002222606SBen Gras 
81102222606SBen Gras #define	L1_SS_PROTO_generic	0
81202222606SBen Gras #define	L1_SS_PROTO_xscale	0
81302222606SBen Gras #define	L1_SS_PROTO_armv6	(L1_TYPE_S | L1_S_V6_SS)
81402222606SBen Gras #define	L1_SS_PROTO_armv7	(L1_TYPE_S | L1_S_V6_SS)
81502222606SBen Gras 
81602222606SBen Gras #define	L1_C_PROTO_generic	(L1_TYPE_C | L1_C_IMP2)
81702222606SBen Gras #define	L1_C_PROTO_xscale	(L1_TYPE_C)
81802222606SBen Gras #define	L1_C_PROTO_armv6	(L1_TYPE_C)
81902222606SBen Gras #define	L1_C_PROTO_armv7	(L1_TYPE_C)
82002222606SBen Gras 
82102222606SBen Gras #define	L2_L_PROTO		(L2_TYPE_L)
82202222606SBen Gras 
82302222606SBen Gras #define	L2_S_PROTO_generic	(L2_TYPE_S)
82402222606SBen Gras #define	L2_S_PROTO_xscale	(L2_TYPE_XS)
82502222606SBen Gras #ifdef	ARMV6_EXTENDED_SMALL_PAGE
82602222606SBen Gras #define	L2_S_PROTO_armv6c	(L2_TYPE_XS)    /* XP=0, extended small page */
82702222606SBen Gras #else
82802222606SBen Gras #define	L2_S_PROTO_armv6c	(L2_TYPE_S)	/* XP=0, subpage APs */
82902222606SBen Gras #endif
830*0a6a1f1dSLionel Sambuc #ifdef ARM_MMU_EXTENDED
831*0a6a1f1dSLionel Sambuc #define	L2_S_PROTO_armv6n	(L2_TYPE_S|L2_XS_XN)
832*0a6a1f1dSLionel Sambuc #else
83302222606SBen Gras #define	L2_S_PROTO_armv6n	(L2_TYPE_S)	/* with XP=1 */
834*0a6a1f1dSLionel Sambuc #endif
835*0a6a1f1dSLionel Sambuc #ifdef ARM_MMU_EXTENDED
836*0a6a1f1dSLionel Sambuc #define	L2_S_PROTO_armv7	(L2_TYPE_S|L2_XS_XN)
837*0a6a1f1dSLionel Sambuc #else
83802222606SBen Gras #define	L2_S_PROTO_armv7	(L2_TYPE_S)
839*0a6a1f1dSLionel Sambuc #endif
84002222606SBen Gras 
84102222606SBen Gras /*
84202222606SBen Gras  * User-visible names for the ones that vary with MMU class.
84302222606SBen Gras  */
84402222606SBen Gras 
84502222606SBen Gras #if ARM_NMMUS > 1
84602222606SBen Gras /* More than one MMU class configured; use variables. */
84702222606SBen Gras #define	L1_S_PROT_U		pte_l1_s_prot_u
84802222606SBen Gras #define	L1_S_PROT_W		pte_l1_s_prot_w
84902222606SBen Gras #define	L1_S_PROT_RO		pte_l1_s_prot_ro
85002222606SBen Gras #define	L1_S_PROT_MASK		pte_l1_s_prot_mask
85102222606SBen Gras 
85202222606SBen Gras #define	L2_S_PROT_U		pte_l2_s_prot_u
85302222606SBen Gras #define	L2_S_PROT_W		pte_l2_s_prot_w
85402222606SBen Gras #define	L2_S_PROT_RO		pte_l2_s_prot_ro
85502222606SBen Gras #define	L2_S_PROT_MASK		pte_l2_s_prot_mask
85602222606SBen Gras 
85702222606SBen Gras #define	L2_L_PROT_U		pte_l2_l_prot_u
85802222606SBen Gras #define	L2_L_PROT_W		pte_l2_l_prot_w
85902222606SBen Gras #define	L2_L_PROT_RO		pte_l2_l_prot_ro
86002222606SBen Gras #define	L2_L_PROT_MASK		pte_l2_l_prot_mask
86102222606SBen Gras 
86202222606SBen Gras #define	L1_S_CACHE_MASK		pte_l1_s_cache_mask
86302222606SBen Gras #define	L2_L_CACHE_MASK		pte_l2_l_cache_mask
86402222606SBen Gras #define	L2_S_CACHE_MASK		pte_l2_s_cache_mask
86502222606SBen Gras 
86602222606SBen Gras #define	L1_SS_PROTO		pte_l1_ss_proto
86702222606SBen Gras #define	L1_S_PROTO		pte_l1_s_proto
86802222606SBen Gras #define	L1_C_PROTO		pte_l1_c_proto
86902222606SBen Gras #define	L2_S_PROTO		pte_l2_s_proto
87002222606SBen Gras 
87102222606SBen Gras #define	pmap_copy_page(s, d)	(*pmap_copy_page_func)((s), (d))
87202222606SBen Gras #define	pmap_zero_page(d)	(*pmap_zero_page_func)((d))
87302222606SBen Gras #elif (ARM_MMU_GENERIC + ARM_MMU_SA1) != 0
87402222606SBen Gras #define	L1_S_PROT_U		L1_S_PROT_U_generic
87502222606SBen Gras #define	L1_S_PROT_W		L1_S_PROT_W_generic
87602222606SBen Gras #define	L1_S_PROT_RO		L1_S_PROT_RO_generic
87702222606SBen Gras #define	L1_S_PROT_MASK		L1_S_PROT_MASK_generic
87802222606SBen Gras 
87902222606SBen Gras #define	L2_S_PROT_U		L2_S_PROT_U_generic
88002222606SBen Gras #define	L2_S_PROT_W		L2_S_PROT_W_generic
88102222606SBen Gras #define	L2_S_PROT_RO		L2_S_PROT_RO_generic
88202222606SBen Gras #define	L2_S_PROT_MASK		L2_S_PROT_MASK_generic
88302222606SBen Gras 
88402222606SBen Gras #define	L2_L_PROT_U		L2_L_PROT_U_generic
88502222606SBen Gras #define	L2_L_PROT_W		L2_L_PROT_W_generic
88602222606SBen Gras #define	L2_L_PROT_RO		L2_L_PROT_RO_generic
88702222606SBen Gras #define	L2_L_PROT_MASK		L2_L_PROT_MASK_generic
88802222606SBen Gras 
88902222606SBen Gras #define	L1_S_CACHE_MASK		L1_S_CACHE_MASK_generic
89002222606SBen Gras #define	L2_L_CACHE_MASK		L2_L_CACHE_MASK_generic
89102222606SBen Gras #define	L2_S_CACHE_MASK		L2_S_CACHE_MASK_generic
89202222606SBen Gras 
89302222606SBen Gras #define	L1_SS_PROTO		L1_SS_PROTO_generic
89402222606SBen Gras #define	L1_S_PROTO		L1_S_PROTO_generic
89502222606SBen Gras #define	L1_C_PROTO		L1_C_PROTO_generic
89602222606SBen Gras #define	L2_S_PROTO		L2_S_PROTO_generic
89702222606SBen Gras 
89802222606SBen Gras #define	pmap_copy_page(s, d)	pmap_copy_page_generic((s), (d))
89902222606SBen Gras #define	pmap_zero_page(d)	pmap_zero_page_generic((d))
90002222606SBen Gras #elif ARM_MMU_V6N != 0
90102222606SBen Gras #define	L1_S_PROT_U		L1_S_PROT_U_armv6
90202222606SBen Gras #define	L1_S_PROT_W		L1_S_PROT_W_armv6
90302222606SBen Gras #define	L1_S_PROT_RO		L1_S_PROT_RO_armv6
90402222606SBen Gras #define	L1_S_PROT_MASK		L1_S_PROT_MASK_armv6
90502222606SBen Gras 
90602222606SBen Gras #define	L2_S_PROT_U		L2_S_PROT_U_armv6n
90702222606SBen Gras #define	L2_S_PROT_W		L2_S_PROT_W_armv6n
90802222606SBen Gras #define	L2_S_PROT_RO		L2_S_PROT_RO_armv6n
90902222606SBen Gras #define	L2_S_PROT_MASK		L2_S_PROT_MASK_armv6n
91002222606SBen Gras 
91102222606SBen Gras #define	L2_L_PROT_U		L2_L_PROT_U_armv6n
91202222606SBen Gras #define	L2_L_PROT_W		L2_L_PROT_W_armv6n
91302222606SBen Gras #define	L2_L_PROT_RO		L2_L_PROT_RO_armv6n
91402222606SBen Gras #define	L2_L_PROT_MASK		L2_L_PROT_MASK_armv6n
91502222606SBen Gras 
916*0a6a1f1dSLionel Sambuc #define	L1_S_CACHE_MASK		L1_S_CACHE_MASK_armv6n
917*0a6a1f1dSLionel Sambuc #define	L2_L_CACHE_MASK		L2_L_CACHE_MASK_armv6n
91802222606SBen Gras #define	L2_S_CACHE_MASK		L2_S_CACHE_MASK_armv6n
91902222606SBen Gras 
92002222606SBen Gras /* These prototypes make writeable mappings, while the other MMU types
92102222606SBen Gras  * make read-only mappings. */
92202222606SBen Gras #define	L1_SS_PROTO		L1_SS_PROTO_armv6
92302222606SBen Gras #define	L1_S_PROTO		L1_S_PROTO_armv6
92402222606SBen Gras #define	L1_C_PROTO		L1_C_PROTO_armv6
92502222606SBen Gras #define	L2_S_PROTO		L2_S_PROTO_armv6n
92602222606SBen Gras 
92702222606SBen Gras #define	pmap_copy_page(s, d)	pmap_copy_page_generic((s), (d))
92802222606SBen Gras #define	pmap_zero_page(d)	pmap_zero_page_generic((d))
92902222606SBen Gras #elif ARM_MMU_V6C != 0
93002222606SBen Gras #define	L1_S_PROT_U		L1_S_PROT_U_generic
93102222606SBen Gras #define	L1_S_PROT_W		L1_S_PROT_W_generic
93202222606SBen Gras #define	L1_S_PROT_RO		L1_S_PROT_RO_generic
93302222606SBen Gras #define	L1_S_PROT_MASK		L1_S_PROT_MASK_generic
93402222606SBen Gras 
93502222606SBen Gras #define	L2_S_PROT_U		L2_S_PROT_U_generic
93602222606SBen Gras #define	L2_S_PROT_W		L2_S_PROT_W_generic
93702222606SBen Gras #define	L2_S_PROT_RO		L2_S_PROT_RO_generic
93802222606SBen Gras #define	L2_S_PROT_MASK		L2_S_PROT_MASK_generic
93902222606SBen Gras 
94002222606SBen Gras #define	L2_L_PROT_U		L2_L_PROT_U_generic
94102222606SBen Gras #define	L2_L_PROT_W		L2_L_PROT_W_generic
94202222606SBen Gras #define	L2_L_PROT_RO		L2_L_PROT_RO_generic
94302222606SBen Gras #define	L2_L_PROT_MASK		L2_L_PROT_MASK_generic
94402222606SBen Gras 
94502222606SBen Gras #define	L1_S_CACHE_MASK		L1_S_CACHE_MASK_generic
94602222606SBen Gras #define	L2_L_CACHE_MASK		L2_L_CACHE_MASK_generic
94702222606SBen Gras #define	L2_S_CACHE_MASK		L2_S_CACHE_MASK_generic
94802222606SBen Gras 
949*0a6a1f1dSLionel Sambuc #define	L1_SS_PROTO		L1_SS_PROTO_armv6
95002222606SBen Gras #define	L1_S_PROTO		L1_S_PROTO_generic
95102222606SBen Gras #define	L1_C_PROTO		L1_C_PROTO_generic
95202222606SBen Gras #define	L2_S_PROTO		L2_S_PROTO_generic
95302222606SBen Gras 
95402222606SBen Gras #define	pmap_copy_page(s, d)	pmap_copy_page_generic((s), (d))
95502222606SBen Gras #define	pmap_zero_page(d)	pmap_zero_page_generic((d))
95602222606SBen Gras #elif ARM_MMU_XSCALE == 1
95702222606SBen Gras #define	L1_S_PROT_U		L1_S_PROT_U_generic
95802222606SBen Gras #define	L1_S_PROT_W		L1_S_PROT_W_generic
95902222606SBen Gras #define	L1_S_PROT_RO		L1_S_PROT_RO_generic
96002222606SBen Gras #define	L1_S_PROT_MASK		L1_S_PROT_MASK_generic
96102222606SBen Gras 
96202222606SBen Gras #define	L2_S_PROT_U		L2_S_PROT_U_xscale
96302222606SBen Gras #define	L2_S_PROT_W		L2_S_PROT_W_xscale
96402222606SBen Gras #define	L2_S_PROT_RO		L2_S_PROT_RO_xscale
96502222606SBen Gras #define	L2_S_PROT_MASK		L2_S_PROT_MASK_xscale
96602222606SBen Gras 
96702222606SBen Gras #define	L2_L_PROT_U		L2_L_PROT_U_generic
96802222606SBen Gras #define	L2_L_PROT_W		L2_L_PROT_W_generic
96902222606SBen Gras #define	L2_L_PROT_RO		L2_L_PROT_RO_generic
97002222606SBen Gras #define	L2_L_PROT_MASK		L2_L_PROT_MASK_generic
97102222606SBen Gras 
97202222606SBen Gras #define	L1_S_CACHE_MASK		L1_S_CACHE_MASK_xscale
97302222606SBen Gras #define	L2_L_CACHE_MASK		L2_L_CACHE_MASK_xscale
97402222606SBen Gras #define	L2_S_CACHE_MASK		L2_S_CACHE_MASK_xscale
97502222606SBen Gras 
97602222606SBen Gras #define	L1_SS_PROTO		L1_SS_PROTO_xscale
97702222606SBen Gras #define	L1_S_PROTO		L1_S_PROTO_xscale
97802222606SBen Gras #define	L1_C_PROTO		L1_C_PROTO_xscale
97902222606SBen Gras #define	L2_S_PROTO		L2_S_PROTO_xscale
98002222606SBen Gras 
98102222606SBen Gras #define	pmap_copy_page(s, d)	pmap_copy_page_xscale((s), (d))
98202222606SBen Gras #define	pmap_zero_page(d)	pmap_zero_page_xscale((d))
98302222606SBen Gras #elif ARM_MMU_V7 == 1
98402222606SBen Gras #define	L1_S_PROT_U		L1_S_PROT_U_armv7
98502222606SBen Gras #define	L1_S_PROT_W		L1_S_PROT_W_armv7
98602222606SBen Gras #define	L1_S_PROT_RO		L1_S_PROT_RO_armv7
98702222606SBen Gras #define	L1_S_PROT_MASK		L1_S_PROT_MASK_armv7
98802222606SBen Gras 
98902222606SBen Gras #define	L2_S_PROT_U		L2_S_PROT_U_armv7
99002222606SBen Gras #define	L2_S_PROT_W		L2_S_PROT_W_armv7
99102222606SBen Gras #define	L2_S_PROT_RO		L2_S_PROT_RO_armv7
99202222606SBen Gras #define	L2_S_PROT_MASK		L2_S_PROT_MASK_armv7
99302222606SBen Gras 
99402222606SBen Gras #define	L2_L_PROT_U		L2_L_PROT_U_armv7
99502222606SBen Gras #define	L2_L_PROT_W		L2_L_PROT_W_armv7
99602222606SBen Gras #define	L2_L_PROT_RO		L2_L_PROT_RO_armv7
99702222606SBen Gras #define	L2_L_PROT_MASK		L2_L_PROT_MASK_armv7
99802222606SBen Gras 
99902222606SBen Gras #define	L1_S_CACHE_MASK		L1_S_CACHE_MASK_armv7
100002222606SBen Gras #define	L2_L_CACHE_MASK		L2_L_CACHE_MASK_armv7
100102222606SBen Gras #define	L2_S_CACHE_MASK		L2_S_CACHE_MASK_armv7
100202222606SBen Gras 
100302222606SBen Gras /* These prototypes make writeable mappings, while the other MMU types
100402222606SBen Gras  * make read-only mappings. */
100502222606SBen Gras #define	L1_SS_PROTO		L1_SS_PROTO_armv7
100602222606SBen Gras #define	L1_S_PROTO		L1_S_PROTO_armv7
100702222606SBen Gras #define	L1_C_PROTO		L1_C_PROTO_armv7
100802222606SBen Gras #define	L2_S_PROTO		L2_S_PROTO_armv7
100902222606SBen Gras 
101002222606SBen Gras #define	pmap_copy_page(s, d)	pmap_copy_page_generic((s), (d))
101102222606SBen Gras #define	pmap_zero_page(d)	pmap_zero_page_generic((d))
101202222606SBen Gras #endif /* ARM_NMMUS > 1 */
101302222606SBen Gras 
101402222606SBen Gras /*
101502222606SBen Gras  * Macros to set and query the write permission on page descriptors.
101602222606SBen Gras  */
101702222606SBen Gras #define l1pte_set_writable(pte)	(((pte) & ~L1_S_PROT_RO) | L1_S_PROT_W)
101802222606SBen Gras #define l1pte_set_readonly(pte)	(((pte) & ~L1_S_PROT_W) | L1_S_PROT_RO)
101902222606SBen Gras #define l2pte_set_writable(pte)	(((pte) & ~L2_S_PROT_RO) | L2_S_PROT_W)
102002222606SBen Gras #define l2pte_set_readonly(pte)	(((pte) & ~L2_S_PROT_W) | L2_S_PROT_RO)
102102222606SBen Gras 
102202222606SBen Gras #define l2pte_writable_p(pte)	(((pte) & L2_S_PROT_W) == L2_S_PROT_W && \
102302222606SBen Gras 				 (L2_S_PROT_RO == 0 || \
102402222606SBen Gras 				  ((pte) & L2_S_PROT_RO) != L2_S_PROT_RO))
102502222606SBen Gras 
102602222606SBen Gras /*
102702222606SBen Gras  * These macros return various bits based on kernel/user and protection.
102802222606SBen Gras  * Note that the compiler will usually fold these at compile time.
102902222606SBen Gras  */
103002222606SBen Gras #define	L1_S_PROT(ku, pr)	((((ku) == PTE_USER) ? L1_S_PROT_U : 0) | \
103102222606SBen Gras 				 (((pr) & VM_PROT_WRITE) ? L1_S_PROT_W : L1_S_PROT_RO))
103202222606SBen Gras 
103302222606SBen Gras #define	L2_L_PROT(ku, pr)	((((ku) == PTE_USER) ? L2_L_PROT_U : 0) | \
103402222606SBen Gras 				 (((pr) & VM_PROT_WRITE) ? L2_L_PROT_W : L2_L_PROT_RO))
103502222606SBen Gras 
103602222606SBen Gras #define	L2_S_PROT(ku, pr)	((((ku) == PTE_USER) ? L2_S_PROT_U : 0) | \
103702222606SBen Gras 				 (((pr) & VM_PROT_WRITE) ? L2_S_PROT_W : L2_S_PROT_RO))
103802222606SBen Gras 
103902222606SBen Gras /*
104002222606SBen Gras  * Macros to test if a mapping is mappable with an L1 SuperSection,
104102222606SBen Gras  * L1 Section, or an L2 Large Page mapping.
104202222606SBen Gras  */
104302222606SBen Gras #define	L1_SS_MAPPABLE_P(va, pa, size)					\
104402222606SBen Gras 	((((va) | (pa)) & L1_SS_OFFSET) == 0 && (size) >= L1_SS_SIZE)
104502222606SBen Gras 
104602222606SBen Gras #define	L1_S_MAPPABLE_P(va, pa, size)					\
104702222606SBen Gras 	((((va) | (pa)) & L1_S_OFFSET) == 0 && (size) >= L1_S_SIZE)
104802222606SBen Gras 
104902222606SBen Gras #define	L2_L_MAPPABLE_P(va, pa, size)					\
105002222606SBen Gras 	((((va) | (pa)) & L2_L_OFFSET) == 0 && (size) >= L2_L_SIZE)
105102222606SBen Gras 
105284d9c625SLionel Sambuc #ifndef _LOCORE
105302222606SBen Gras /*
105402222606SBen Gras  * Hooks for the pool allocator.
105502222606SBen Gras  */
105602222606SBen Gras #define	POOL_VTOPHYS(va)	vtophys((vaddr_t) (va))
105784d9c625SLionel Sambuc extern paddr_t physical_start, physical_end;
105884d9c625SLionel Sambuc #ifdef PMAP_NEED_ALLOC_POOLPAGE
105984d9c625SLionel Sambuc struct vm_page *arm_pmap_alloc_poolpage(int);
106084d9c625SLionel Sambuc #define	PMAP_ALLOC_POOLPAGE	arm_pmap_alloc_poolpage
106184d9c625SLionel Sambuc #endif
106284d9c625SLionel Sambuc #if defined(PMAP_NEED_ALLOC_POOLPAGE) || defined(__HAVE_MM_MD_DIRECT_MAPPED_PHYS)
1063*0a6a1f1dSLionel Sambuc vaddr_t	pmap_map_poolpage(paddr_t);
1064*0a6a1f1dSLionel Sambuc paddr_t	pmap_unmap_poolpage(vaddr_t);
1065*0a6a1f1dSLionel Sambuc #define	PMAP_MAP_POOLPAGE(pa)	pmap_map_poolpage(pa)
1066*0a6a1f1dSLionel Sambuc #define PMAP_UNMAP_POOLPAGE(va)	pmap_unmap_poolpage(va)
106784d9c625SLionel Sambuc #endif
106802222606SBen Gras 
106902222606SBen Gras /*
107002222606SBen Gras  * pmap-specific data store in the vm_page structure.
107102222606SBen Gras  */
107202222606SBen Gras #define	__HAVE_VM_PAGE_MD
107302222606SBen Gras struct vm_page_md {
107402222606SBen Gras 	SLIST_HEAD(,pv_entry) pvh_list;		/* pv_entry list */
107502222606SBen Gras 	int pvh_attrs;				/* page attributes */
107602222606SBen Gras 	u_int uro_mappings;
107702222606SBen Gras 	u_int urw_mappings;
107802222606SBen Gras 	union {
107902222606SBen Gras 		u_short s_mappings[2];	/* Assume kernel count <= 65535 */
108002222606SBen Gras 		u_int i_mappings;
108102222606SBen Gras 	} k_u;
108202222606SBen Gras #define	kro_mappings	k_u.s_mappings[0]
108302222606SBen Gras #define	krw_mappings	k_u.s_mappings[1]
108402222606SBen Gras #define	k_mappings	k_u.i_mappings
108502222606SBen Gras };
108602222606SBen Gras 
108702222606SBen Gras /*
108802222606SBen Gras  * Set the default color of each page.
108902222606SBen Gras  */
109002222606SBen Gras #if ARM_MMU_V6 > 0
109102222606SBen Gras #define	VM_MDPAGE_PVH_ATTRS_INIT(pg) \
109202222606SBen Gras 	(pg)->mdpage.pvh_attrs = (pg)->phys_addr & arm_cache_prefer_mask
109302222606SBen Gras #else
109402222606SBen Gras #define	VM_MDPAGE_PVH_ATTRS_INIT(pg) \
109502222606SBen Gras 	(pg)->mdpage.pvh_attrs = 0
109602222606SBen Gras #endif
109702222606SBen Gras 
109802222606SBen Gras #define	VM_MDPAGE_INIT(pg)						\
109902222606SBen Gras do {									\
110002222606SBen Gras 	SLIST_INIT(&(pg)->mdpage.pvh_list);				\
110102222606SBen Gras 	VM_MDPAGE_PVH_ATTRS_INIT(pg);					\
110202222606SBen Gras 	(pg)->mdpage.uro_mappings = 0;					\
110302222606SBen Gras 	(pg)->mdpage.urw_mappings = 0;					\
110402222606SBen Gras 	(pg)->mdpage.k_mappings = 0;					\
110502222606SBen Gras } while (/*CONSTCOND*/0)
110602222606SBen Gras 
110702222606SBen Gras #endif /* !_LOCORE */
110802222606SBen Gras 
110902222606SBen Gras #endif /* _KERNEL */
111002222606SBen Gras 
111102222606SBen Gras #endif	/* _ARM32_PMAP_H_ */
1112