1183906Skmacy/*
2183906Skmacy *
3183906Skmacy * Copyright (c) 2004 Christian Limpach.
4183906Skmacy * Copyright (c) 2004,2005 Kip Macy
5183906Skmacy * All rights reserved.
6183906Skmacy *
7183906Skmacy * Redistribution and use in source and binary forms, with or without
8183906Skmacy * modification, are permitted provided that the following conditions
9183906Skmacy * are met:
10183906Skmacy * 1. Redistributions of source code must retain the above copyright
11183906Skmacy *    notice, this list of conditions and the following disclaimer.
12183906Skmacy * 2. Redistributions in binary form must reproduce the above copyright
13183906Skmacy *    notice, this list of conditions and the following disclaimer in the
14183906Skmacy *    documentation and/or other materials provided with the distribution.
15183906Skmacy * 3. All advertising materials mentioning features or use of this software
16183906Skmacy *    must display the following acknowledgement:
17183906Skmacy *      This product includes software developed by Christian Limpach.
18183906Skmacy * 4. The name of the author may not be used to endorse or promote products
19183906Skmacy *    derived from this software without specific prior written permission.
20183906Skmacy *
21183906Skmacy * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22183906Skmacy * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23183906Skmacy * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24183906Skmacy * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25183906Skmacy * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26183906Skmacy * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27183906Skmacy * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28183906Skmacy * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29183906Skmacy * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30183906Skmacy * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31183906Skmacy */
32183906Skmacy
33183906Skmacy
34183906Skmacy#ifndef _XEN_XENPMAP_H_
35183906Skmacy#define _XEN_XENPMAP_H_
36185637Sdfr
37185637Sdfr#include <machine/xen/features.h>
38185637Sdfr
39183906Skmacyvoid _xen_queue_pt_update(vm_paddr_t, vm_paddr_t, char *, int);
40183906Skmacyvoid xen_pt_switch(vm_paddr_t);
41183906Skmacyvoid xen_set_ldt(vm_paddr_t, unsigned long);
42183906Skmacyvoid xen_pgdpt_pin(vm_paddr_t);
43183906Skmacyvoid xen_pgd_pin(vm_paddr_t);
44183906Skmacyvoid xen_pgd_unpin(vm_paddr_t);
45183906Skmacyvoid xen_pt_pin(vm_paddr_t);
46183906Skmacyvoid xen_pt_unpin(vm_paddr_t);
47183906Skmacyvoid xen_flush_queue(void);
48183906Skmacyvoid xen_check_queue(void);
49183906Skmacy#if 0
50183906Skmacyvoid pmap_ref(pt_entry_t *pte, vm_paddr_t ma);
51183906Skmacy#endif
52183906Skmacy
53183906Skmacy#ifdef INVARIANTS
54183906Skmacy#define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), __FILE__, __LINE__)
55183906Skmacy#else
56183906Skmacy#define xen_queue_pt_update(a, b) _xen_queue_pt_update((a), (b), NULL, 0)
57183906Skmacy#endif
58183906Skmacy
59183906Skmacy#ifdef PMAP_DEBUG
60183906Skmacy#define PMAP_REF pmap_ref
61183906Skmacy#define PMAP_DEC_REF_PAGE pmap_dec_ref_page
62183906Skmacy#define PMAP_MARK_PRIV pmap_mark_privileged
63183906Skmacy#define PMAP_MARK_UNPRIV pmap_mark_unprivileged
64183906Skmacy#else
65183906Skmacy#define PMAP_MARK_PRIV(a)
66183906Skmacy#define PMAP_MARK_UNPRIV(a)
67183906Skmacy#define PMAP_REF(a, b)
68183906Skmacy#define PMAP_DEC_REF_PAGE(a)
69183906Skmacy#endif
70183906Skmacy
71183906Skmacy#define ALWAYS_SYNC 0
72183906Skmacy
73183906Skmacy#ifdef PT_DEBUG
74183906Skmacy#define PT_LOG() printk("WP PT_SET %s:%d\n", __FILE__, __LINE__)
75183906Skmacy#else
76183906Skmacy#define PT_LOG()
77183906Skmacy#endif
78183906Skmacy
79183906Skmacy#define INVALID_P2M_ENTRY	(~0UL)
80183906Skmacy
81183906Skmacy#define pmap_valid_entry(E)           ((E) & PG_V) /* is PDE or PTE valid? */
82183906Skmacy
83183906Skmacy#define SH_PD_SET_VA        1
84183906Skmacy#define SH_PD_SET_VA_MA     2
85183906Skmacy#define SH_PD_SET_VA_CLEAR  3
86183906Skmacy
87183906Skmacystruct pmap;
88183906Skmacyvoid pd_set(struct pmap *pmap, int ptepindex, vm_paddr_t val, int type);
89183906Skmacy#ifdef notyet
90183906Skmacystatic vm_paddr_t
91183906Skmacyvptetomachpte(vm_paddr_t *pte)
92183906Skmacy{
93183906Skmacy	vm_offset_t offset, ppte;
94183906Skmacy	vm_paddr_t pgoffset, retval, *pdir_shadow_ptr;
95183906Skmacy	int pgindex;
96183906Skmacy
97183906Skmacy	ppte = (vm_offset_t)pte;
98183906Skmacy	pgoffset = (ppte & PAGE_MASK);
99183906Skmacy	offset = ppte - (vm_offset_t)PTmap;
100183906Skmacy	pgindex = ppte >> PDRSHIFT;
101183906Skmacy
102183906Skmacy	pdir_shadow_ptr = (vm_paddr_t *)PCPU_GET(pdir_shadow);
103183906Skmacy	retval = (pdir_shadow_ptr[pgindex] & ~PAGE_MASK) + pgoffset;
104183906Skmacy	return (retval);
105183906Skmacy}
106183906Skmacy#endif
107183906Skmacy#define	PT_GET(_ptp)						\
108183906Skmacy	(pmap_valid_entry(*(_ptp)) ? xpmap_mtop(*(_ptp)) : (0))
109183906Skmacy
110183906Skmacy#ifdef WRITABLE_PAGETABLES
111183906Skmacy
112183906Skmacy#define PT_SET_VA(_ptp,_npte,sync) do {				\
113183906Skmacy        PMAP_REF((_ptp), xpmap_ptom(_npte));                    \
114183906Skmacy        PT_LOG();                                               \
115183906Skmacy        *(_ptp) = xpmap_ptom((_npte));                          \
116183906Skmacy} while (/*CONSTCOND*/0)
117183906Skmacy#define PT_SET_VA_MA(_ptp,_npte,sync) do {		        \
118183906Skmacy        PMAP_REF((_ptp), (_npte));                              \
119183906Skmacy        PT_LOG();                                               \
120183906Skmacy        *(_ptp) = (_npte);                                      \
121183906Skmacy} while (/*CONSTCOND*/0)
122183906Skmacy#define PT_CLEAR_VA(_ptp, sync) do {				\
123183906Skmacy        PMAP_REF((pt_entry_t *)(_ptp), 0);                      \
124183906Skmacy        PT_LOG();                                               \
125183906Skmacy        *(_ptp) = 0;                                            \
126183906Skmacy} while (/*CONSTCOND*/0)
127183906Skmacy
128183906Skmacy#define PD_SET_VA(_pmap, _ptp, _npte, sync) do {		\
129183906Skmacy        PMAP_REF((_ptp), xpmap_ptom(_npte));                    \
130183906Skmacy        pd_set((_pmap),(_ptp),(_npte), SH_PD_SET_VA);           \
131183906Skmacy	if (sync || ALWAYS_SYNC) xen_flush_queue();     	\
132183906Skmacy} while (/*CONSTCOND*/0)
133183906Skmacy#define PD_SET_VA_MA(_pmap, _ptp, _npte, sync) do {		\
134183906Skmacy        PMAP_REF((_ptp), (_npte));                              \
135183906Skmacy        pd_set((_pmap),(_ptp),(_npte), SH_PD_SET_VA_MA);        \
136183906Skmacy	if (sync || ALWAYS_SYNC) xen_flush_queue();		\
137183906Skmacy} while (/*CONSTCOND*/0)
138183906Skmacy#define PD_CLEAR_VA(_pmap, _ptp, sync) do {			\
139183906Skmacy        PMAP_REF((pt_entry_t *)(_ptp), 0);                      \
140183906Skmacy        pd_set((_pmap),(_ptp), 0, SH_PD_SET_VA_CLEAR);  	\
141183906Skmacy	if (sync || ALWAYS_SYNC) xen_flush_queue();		\
142183906Skmacy} while (/*CONSTCOND*/0)
143183906Skmacy
144183906Skmacy#else /* !WRITABLE_PAGETABLES */
145183906Skmacy
146183906Skmacy#define PT_SET_VA(_ptp,_npte,sync) do {				\
147183906Skmacy        PMAP_REF((_ptp), xpmap_ptom(_npte));                    \
148183906Skmacy	xen_queue_pt_update(vtomach(_ptp), 	        \
149183906Skmacy			    xpmap_ptom(_npte)); 		\
150183906Skmacy	if (sync || ALWAYS_SYNC) xen_flush_queue();		\
151183906Skmacy} while (/*CONSTCOND*/0)
152183906Skmacy#define PT_SET_VA_MA(_ptp,_npte,sync) do {		        \
153183906Skmacy        PMAP_REF((_ptp), (_npte));                              \
154183906Skmacy	xen_queue_pt_update(vtomach(_ptp), _npte);        \
155183906Skmacy	if (sync || ALWAYS_SYNC) xen_flush_queue();		\
156183906Skmacy} while (/*CONSTCOND*/0)
157183906Skmacy#define PT_CLEAR_VA(_ptp, sync) do {				\
158183906Skmacy        PMAP_REF((pt_entry_t *)(_ptp), 0);                      \
159183906Skmacy	xen_queue_pt_update(vtomach(_ptp), 0);            \
160183906Skmacy	if (sync || ALWAYS_SYNC)				\
161183906Skmacy		xen_flush_queue();				\
162183906Skmacy} while (/*CONSTCOND*/0)
163183906Skmacy
164183906Skmacy#define PD_SET_VA(_pmap, _ptepindex,_npte,sync) do {		\
165183906Skmacy        PMAP_REF((_ptp), xpmap_ptom(_npte));                    \
166183906Skmacy        pd_set((_pmap),(_ptepindex),(_npte), SH_PD_SET_VA);     \
167183906Skmacy	if (sync || ALWAYS_SYNC) xen_flush_queue();     	\
168183906Skmacy} while (/*CONSTCOND*/0)
169183906Skmacy#define PD_SET_VA_MA(_pmap, _ptepindex,_npte,sync) do {		\
170183906Skmacy        PMAP_REF((_ptp), (_npte));                              \
171183906Skmacy        pd_set((_pmap),(_ptepindex),(_npte), SH_PD_SET_VA_MA);  \
172183906Skmacy	if (sync || ALWAYS_SYNC) xen_flush_queue();		\
173183906Skmacy} while (/*CONSTCOND*/0)
174183906Skmacy#define PD_CLEAR_VA(_pmap, _ptepindex, sync) do {		\
175183906Skmacy        PMAP_REF((pt_entry_t *)(_ptp), 0);                      \
176183906Skmacy        pd_set((_pmap),(_ptepindex), 0, SH_PD_SET_VA_CLEAR);    \
177183906Skmacy	if (sync || ALWAYS_SYNC) xen_flush_queue();		\
178183906Skmacy} while (/*CONSTCOND*/0)
179183906Skmacy
180183906Skmacy#endif
181183906Skmacy
182183906Skmacy#define PT_SET_MA(_va, _ma) 					\
183183906Skmacydo { 								\
184183906Skmacy   PANIC_IF(HYPERVISOR_update_va_mapping(((unsigned long)(_va)),\
185183906Skmacy	   (_ma),						\
186183906Skmacy	   UVMF_INVLPG| UVMF_ALL) < 0);			\
187183906Skmacy} while (/*CONSTCOND*/0)
188183906Skmacy
189183906Skmacy#define	PT_UPDATES_FLUSH() do {				        \
190183906Skmacy        xen_flush_queue();                                      \
191183906Skmacy} while (/*CONSTCOND*/0)
192183906Skmacy
193183906Skmacystatic __inline vm_paddr_t
194183906Skmacyxpmap_mtop(vm_paddr_t mpa)
195183906Skmacy{
196183906Skmacy	vm_paddr_t tmp = (mpa & PG_FRAME);
197183906Skmacy
198183906Skmacy	return machtophys(tmp) | (mpa & ~PG_FRAME);
199183906Skmacy}
200183906Skmacy
201183906Skmacystatic __inline vm_paddr_t
202183906Skmacyxpmap_ptom(vm_paddr_t ppa)
203183906Skmacy{
204183906Skmacy	vm_paddr_t tmp = (ppa & PG_FRAME);
205183906Skmacy
206183906Skmacy	return phystomach(tmp) | (ppa & ~PG_FRAME);
207183906Skmacy}
208183906Skmacy
209183906Skmacystatic __inline void
210183906Skmacyset_phys_to_machine(unsigned long pfn, unsigned long mfn)
211183906Skmacy{
212183906Skmacy#ifdef notyet
213183906Skmacy        PANIC_IF(max_mapnr && pfn >= max_mapnr);
214183906Skmacy#endif
215183906Skmacy        if (xen_feature(XENFEAT_auto_translated_physmap)) {
216183906Skmacy#ifdef notyet
217183906Skmacy                PANIC_IF((pfn != mfn && mfn != INVALID_P2M_ENTRY));
218183906Skmacy#endif
219183906Skmacy                return;
220183906Skmacy        }
221183906Skmacy        xen_phys_machine[pfn] = mfn;
222183906Skmacy}
223183906Skmacy
224183906Skmacy
225183906Skmacy
226183906Skmacy
227183906Skmacy#endif /* _XEN_XENPMAP_H_ */
228