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