1292407Sbr/*-
2292407Sbr * Copyright (c) 1991 Regents of the University of California.
3292407Sbr * All rights reserved.
4292407Sbr *
5292407Sbr * This code is derived from software contributed to Berkeley by
6292407Sbr * the Systems Programming Group of the University of Utah Computer
7292407Sbr * Science Department and William Jolitz of UUNET Technologies Inc.
8292407Sbr *
9292407Sbr * Redistribution and use in source and binary forms, with or without
10292407Sbr * modification, are permitted provided that the following conditions
11292407Sbr * are met:
12292407Sbr * 1. Redistributions of source code must retain the above copyright
13292407Sbr *    notice, this list of conditions and the following disclaimer.
14292407Sbr * 2. Redistributions in binary form must reproduce the above copyright
15292407Sbr *    notice, this list of conditions and the following disclaimer in the
16292407Sbr *    documentation and/or other materials provided with the distribution.
17292407Sbr * 3. Neither the name of the University nor the names of its contributors
18292407Sbr *    may be used to endorse or promote products derived from this software
19292407Sbr *    without specific prior written permission.
20292407Sbr *
21292407Sbr * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22292407Sbr * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23292407Sbr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24292407Sbr * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25292407Sbr * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26292407Sbr * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27292407Sbr * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28292407Sbr * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29292407Sbr * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30292407Sbr * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31292407Sbr * SUCH DAMAGE.
32292407Sbr *
33292407Sbr * $FreeBSD$
34292407Sbr */
35292407Sbr
36292407Sbr#ifndef _MACHINE_PMAP_H_
37292407Sbr#define	_MACHINE_PMAP_H_
38292407Sbr
39292407Sbr#include <machine/pte.h>
40292407Sbr
41292407Sbr#ifndef LOCORE
42292407Sbr
43292407Sbr#include <sys/queue.h>
44292407Sbr#include <sys/_lock.h>
45292407Sbr#include <sys/_mutex.h>
46292407Sbr
47292407Sbr#ifdef _KERNEL
48292407Sbr
49292407Sbr#define	vtophys(va)	pmap_kextract((vm_offset_t)(va))
50292407Sbr
51292407Sbr#endif
52292407Sbr
53292407Sbr#define	pmap_page_get_memattr(m)	((m)->md.pv_memattr)
54292407Sbr#define	pmap_page_is_write_mapped(m)	(((m)->aflags & PGA_WRITEABLE) != 0)
55292407Sbrvoid pmap_page_set_memattr(vm_page_t m, vm_memattr_t ma);
56292407Sbr
57292407Sbr/*
58292407Sbr * Pmap stuff
59292407Sbr */
60292407Sbr
61292407Sbrstruct md_page {
62292407Sbr	TAILQ_HEAD(,pv_entry)	pv_list;
63292407Sbr	int			pv_gen;
64292407Sbr	vm_memattr_t		pv_memattr;
65292407Sbr};
66292407Sbr
67292407Sbr/*
68292407Sbr * This structure is used to hold a virtual<->physical address
69292407Sbr * association and is used mostly by bootstrap code
70292407Sbr */
71292407Sbrstruct pv_addr {
72292407Sbr	SLIST_ENTRY(pv_addr) pv_list;
73292407Sbr	vm_offset_t	pv_va;
74292407Sbr	vm_paddr_t	pv_pa;
75292407Sbr};
76292407Sbr
77292407Sbrstruct pmap {
78292407Sbr	struct mtx		pm_mtx;
79292407Sbr	struct pmap_statistics	pm_stats;	/* pmap statictics */
80292407Sbr	pd_entry_t		*pm_l1;
81292407Sbr	TAILQ_HEAD(,pv_chunk)	pm_pvchunk;	/* list of mappings in pmap */
82298641Sbr	LIST_ENTRY(pmap)	pm_list;	/* List of all pmaps */
83292407Sbr};
84292407Sbr
85292407Sbrtypedef struct pv_entry {
86292407Sbr	vm_offset_t		pv_va;	/* virtual address for mapping */
87292407Sbr	TAILQ_ENTRY(pv_entry)	pv_next;
88292407Sbr} *pv_entry_t;
89292407Sbr
90292407Sbr/*
91292407Sbr * pv_entries are allocated in chunks per-process.  This avoids the
92292407Sbr * need to track per-pmap assignments.
93292407Sbr */
94292407Sbr#define	_NPCM	3
95292407Sbr#define	_NPCPV	168
96292407Sbrstruct pv_chunk {
97292407Sbr	struct pmap *		pc_pmap;
98292407Sbr	TAILQ_ENTRY(pv_chunk)	pc_list;
99292407Sbr	uint64_t		pc_map[_NPCM];  /* bitmap; 1 = free */
100292407Sbr	TAILQ_ENTRY(pv_chunk)	pc_lru;
101292407Sbr	struct pv_entry		pc_pventry[_NPCPV];
102292407Sbr};
103292407Sbr
104292407Sbrtypedef struct pmap *pmap_t;
105292407Sbr
106292407Sbr#ifdef _KERNEL
107292407Sbrextern struct pmap	kernel_pmap_store;
108292407Sbr#define	kernel_pmap	(&kernel_pmap_store)
109292407Sbr#define	pmap_kernel()	kernel_pmap
110292407Sbr
111292407Sbr#define	PMAP_ASSERT_LOCKED(pmap) \
112292407Sbr				mtx_assert(&(pmap)->pm_mtx, MA_OWNED)
113292407Sbr#define	PMAP_LOCK(pmap)		mtx_lock(&(pmap)->pm_mtx)
114292407Sbr#define	PMAP_LOCK_ASSERT(pmap, type) \
115292407Sbr				mtx_assert(&(pmap)->pm_mtx, (type))
116292407Sbr#define	PMAP_LOCK_DESTROY(pmap)	mtx_destroy(&(pmap)->pm_mtx)
117292407Sbr#define	PMAP_LOCK_INIT(pmap)	mtx_init(&(pmap)->pm_mtx, "pmap", \
118292407Sbr				    NULL, MTX_DEF | MTX_DUPOK)
119292407Sbr#define	PMAP_OWNED(pmap)	mtx_owned(&(pmap)->pm_mtx)
120292407Sbr#define	PMAP_MTX(pmap)		(&(pmap)->pm_mtx)
121292407Sbr#define	PMAP_TRYLOCK(pmap)	mtx_trylock(&(pmap)->pm_mtx)
122292407Sbr#define	PMAP_UNLOCK(pmap)	mtx_unlock(&(pmap)->pm_mtx)
123292407Sbr
124292407Sbr#define	PHYS_AVAIL_SIZE	10
125292407Sbrextern vm_paddr_t phys_avail[];
126292407Sbrextern vm_paddr_t dump_avail[];
127292407Sbrextern vm_offset_t virtual_avail;
128292407Sbrextern vm_offset_t virtual_end;
129292407Sbr
130292407Sbr/*
131292407Sbr * Macros to test if a mapping is mappable with an L1 Section mapping
132292407Sbr * or an L2 Large Page mapping.
133292407Sbr */
134292407Sbr#define	L1_MAPPABLE_P(va, pa, size)					\
135292407Sbr	((((va) | (pa)) & L1_OFFSET) == 0 && (size) >= L1_SIZE)
136292407Sbr
137292407Sbrvoid	pmap_bootstrap(vm_offset_t, vm_paddr_t, vm_size_t);
138292407Sbrvoid	pmap_kenter_device(vm_offset_t, vm_size_t, vm_paddr_t);
139292407Sbrvm_paddr_t pmap_kextract(vm_offset_t va);
140292407Sbrvoid	pmap_kremove(vm_offset_t);
141292407Sbrvoid	pmap_kremove_device(vm_offset_t, vm_size_t);
142292407Sbr
143292407Sbrvoid	*pmap_mapdev(vm_offset_t, vm_size_t);
144292407Sbrvoid	*pmap_mapbios(vm_paddr_t, vm_size_t);
145292407Sbrvoid	pmap_unmapdev(vm_offset_t, vm_size_t);
146292407Sbrvoid	pmap_unmapbios(vm_offset_t, vm_size_t);
147292407Sbr
148292407Sbrboolean_t pmap_map_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t);
149292407Sbrvoid	pmap_unmap_io_transient(vm_page_t *, vm_offset_t *, int, boolean_t);
150292407Sbr
151292407Sbrbool	pmap_get_tables(pmap_t, vm_offset_t, pd_entry_t **, pd_entry_t **,
152292407Sbr    pt_entry_t **);
153292407Sbr
154292407Sbr#define	pmap_page_is_mapped(m)	(!TAILQ_EMPTY(&(m)->md.pv_list))
155292407Sbr
156292407Sbr#endif	/* _KERNEL */
157292407Sbr
158292407Sbr#endif	/* !LOCORE */
159292407Sbr
160292407Sbr#endif	/* !_MACHINE_PMAP_H_ */
161