xref: /netbsd-src/sys/arch/xen/include/xenpmap.h (revision e5548b402ae4c44fb816de42c7bba9581ce23ef5)
1 /*	$NetBSD: xenpmap.h,v 1.10 2005/12/11 12:19:48 christos Exp $	*/
2 
3 /*
4  *
5  * Copyright (c) 2004 Christian Limpach.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. All advertising materials mentioning features or use of this software
17  *    must display the following acknowledgement:
18  *      This product includes software developed by Christian Limpach.
19  * 4. The name of the author may not be used to endorse or promote products
20  *    derived from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32  */
33 
34 
35 #ifndef _XEN_XENPMAP_H_
36 #define _XEN_XENPMAP_H_
37 
38 #define	INVALID_P2M_ENTRY	(~0UL)
39 
40 void xpq_queue_machphys_update(paddr_t, paddr_t);
41 void xpq_queue_invlpg(vaddr_t);
42 void xpq_queue_pde_update(pd_entry_t *, pd_entry_t);
43 void xpq_queue_pte_update(pt_entry_t *, pt_entry_t);
44 void xpq_queue_unchecked_pte_update(pt_entry_t *, pt_entry_t);
45 void xpq_queue_pt_switch(paddr_t);
46 void xpq_flush_queue(void);
47 void xpq_queue_set_ldt(vaddr_t, uint32_t);
48 void xpq_queue_tlb_flush(void);
49 void xpq_queue_pin_table(paddr_t, int);
50 void xpq_queue_unpin_table(paddr_t);
51 int  xpq_update_foreign(pt_entry_t *, pt_entry_t, int);
52 
53 extern paddr_t *xpmap_phys_to_machine_mapping;
54 
55 #define	XPQ_PIN_L1_TABLE 1
56 #define	XPQ_PIN_L2_TABLE 2
57 
58 #ifndef XEN
59 #define	PDE_GET(_pdp)						\
60 	*(_pdp)
61 #define PDE_SET(_pdp,_mapdp,_npde)				\
62 	*(_mapdp) = (_npde)
63 #define PDE_CLEAR(_pdp,_mapdp)					\
64 	*(_mapdp) = 0
65 #define PTE_SET(_ptp,_maptp,_npte)				\
66 	*(_maptp) = (_npte)
67 #define PTE_CLEAR(_ptp,_maptp)					\
68 	*(_maptp) = 0
69 #define PTE_ATOMIC_SET(_ptp,_maptp,_npte,_opte)			\
70 	(_opte) = x86_atomic_testset_ul((_maptp), (_npte))
71 #define PTE_ATOMIC_CLEAR(_ptp,_maptp,_opte)			\
72 	(_opte) = x86_atomic_testset_ul((_maptp), 0)
73 #define PDE_CLEARBITS(_pdp,_mapdp,_bits)			\
74 	*(_mapdp) &= ~(_bits)
75 #define PTE_ATOMIC_CLEARBITS(_ptp,_maptp,_bits)			\
76 	x86_atomic_clearbits_l((_maptp), (_bits))
77 #define PTE_SETBITS(_ptp,_maptp,_bits)				\
78 	*(_maptp) |= (_bits)
79 #define PTE_ATOMIC_SETBITS(_ptp,_maptp,_bits)			\
80 	x86_atomic_setbits_l((_maptp), (_bits))
81 #else
82 paddr_t *xpmap_phys_to_machine_mapping;
83 
84 #define	PDE_GET(_pdp)						\
85 	(pmap_valid_entry(*(_pdp)) ? xpmap_mtop(*(_pdp)) : *(_pdp))
86 #define PDE_SET(_pdp,_mapdp,_npde) do {				\
87 	int _s = splvm();					\
88 	xpq_queue_pde_update((_mapdp), xpmap_ptom((_npde)));	\
89 	xpq_flush_queue();					\
90 	splx(_s);						\
91 } while (/*CONSTCOND*/0)
92 #define PDE_CLEAR(_pdp,_mapdp) do {				\
93 	int _s = splvm();					\
94 	xpq_queue_pde_update((_mapdp), 0);			\
95 	xpq_flush_queue();					\
96 	splx(_s);						\
97 } while (/*CONSTCOND*/0)
98 #define	PTE_GET(_ptp)						\
99 	(pmap_valid_entry(*(_ptp)) ? xpmap_mtop(*(_ptp)) : *(_ptp))
100 #define	PTE_GET_MA(_ptp)					\
101 	*(_ptp)
102 #define PTE_SET(_ptp,_maptp,_npte) do {				\
103 	int _s = splvm();					\
104 	xpq_queue_pte_update((_maptp), xpmap_ptom((_npte)));	\
105 	xpq_flush_queue();					\
106 	splx(_s);						\
107 } while (/*CONSTCOND*/0)
108 #define PTE_SET_MA(_ptp,_maptp,_npte) do {			\
109 	int _s = splvm();					\
110 	xpq_queue_pte_update((_maptp), (_npte));		\
111 	xpq_flush_queue();					\
112 	splx(_s);						\
113 } while (/*CONSTCOND*/0)
114 #define PTE_SET_MA_UNCHECKED(_ptp,_maptp,_npte) do {		\
115 	_s = splvm();						\
116 	xpq_queue_unchecked_pte_update((_maptp), (_npte));	\
117 	xpq_flush_queue();					\
118 	splx(_s);						\
119 } while (/*CONSTCOND*/0)
120 #define PTE_CLEAR(_ptp,_maptp) do {				\
121 	int _s = splvm();					\
122 	xpq_queue_pte_update((_maptp), 0);			\
123 	xpq_flush_queue();					\
124 	splx(_s);						\
125 } while (/*CONSTCOND*/0)
126 #define PTE_ATOMIC_SET(_ptp,_maptp,_npte,_opte) do {		\
127 	int _s;							\
128 	(_opte) = PTE_GET(_ptp);				\
129 	_s = splvm();						\
130 	xpq_queue_pte_update((_maptp), xpmap_ptom((_npte)));	\
131 	xpq_flush_queue();					\
132 	splx(_s);						\
133 } while (/*CONSTCOND*/0)
134 #define PTE_ATOMIC_SET_MA(_ptp,_maptp,_npte,_opte) do {		\
135 	int _s;							\
136 	(_opte) = *(_ptp);					\
137 	_s = splvm();						\
138 	xpq_queue_pte_update((_maptp), (_npte));		\
139 	xpq_flush_queue();					\
140 	splx(_s);						\
141 } while (/*CONSTCOND*/0)
142 #define PTE_ATOMIC_CLEAR(_ptp,_maptp,_opte) do {		\
143 	int _s;							\
144 	(_opte) = PTE_GET(_ptp);				\
145 	_s = splvm();						\
146 	xpq_queue_pte_update((_maptp), 0);			\
147 	xpq_flush_queue();					\
148 	splx(_s);						\
149 } while (/*CONSTCOND*/0)
150 #define PTE_ATOMIC_CLEAR_MA(_ptp,_maptp,_opte) do {		\
151 	int _s;							\
152 	(_opte) = *(_ptp);					\
153 	_s = splvm();						\
154 	xpq_queue_pte_update((_maptp), 0);			\
155 	xpq_flush_queue();					\
156 	splx(_s);						\
157 } while (/*CONSTCOND*/0)
158 #define PDE_CLEARBITS(_pdp,_mapdp,_bits) do {			\
159 	int _s = splvm();					\
160 	xpq_queue_pte_update((_mapdp), *(_pdp) & ~((_bits) & ~PG_FRAME)); \
161 	xpq_flush_queue();					\
162 	splx(_s);						\
163 } while (/*CONSTCOND*/0)
164 #define PTE_CLEARBITS(_ptp,_maptp,_bits) do {			\
165 	int _s = splvm();					\
166 	xpq_queue_pte_update((_maptp), *(_ptp) & ~((_bits) & ~PG_FRAME)); \
167 	xpq_flush_queue();					\
168 	splx(_s);						\
169 } while (/*CONSTCOND*/0)
170 #define PDE_ATOMIC_CLEARBITS(_pdp,_mapdp,_bits) do {		\
171 	int _s = splvm();					\
172 	xpq_queue_pde_update((_mapdp), *(_pdp) & ~((_bits) & ~PG_FRAME)); \
173 	xpq_flush_queue();					\
174 	splx(_s);						\
175 } while (/*CONSTCOND*/0)
176 #define PTE_ATOMIC_CLEARBITS(_ptp,_maptp,_bits) do {		\
177 	int _s = splvm();					\
178 	xpq_queue_pte_update((_maptp), *(_ptp) & ~((_bits) & ~PG_FRAME)); \
179 	xpq_flush_queue();					\
180 	splx(_s);						\
181 } while (/*CONSTCOND*/0)
182 #define PTE_SETBITS(_ptp,_maptp,_bits) do {			\
183 	int _s = splvm();					\
184 	xpq_queue_pte_update((_maptp), *(_ptp) | ((_bits) & ~PG_FRAME)); \
185 	xpq_flush_queue();					\
186 	splx(_s);						\
187 } while (/*CONSTCOND*/0)
188 #define PDE_ATOMIC_SETBITS(_pdp,_mapdp,_bits) do {		\
189 	int _s = splvm();					\
190 	xpq_queue_pde_update((_mapdp), *(_pdp) | ((_bits) & ~PG_FRAME)); \
191 	xpq_flush_queue();					\
192 	splx(_s);						\
193 } while (/*CONSTCOND*/0)
194 #define PTE_ATOMIC_SETBITS(_ptp,_maptp,_bits) do {		\
195 	int _s = splvm();					\
196 	xpq_queue_pte_update((_maptp), *(_ptp) | ((_bits) & ~PG_FRAME)); \
197 	xpq_flush_queue();					\
198 	splx(_s);						\
199 } while (/*CONSTCOND*/0)
200 #define PDE_COPY(_dpdp,_madpdp,_spdp) do {			\
201 	int _s = splvm();					\
202 	xpq_queue_pde_update((_madpdp), *(_spdp));		\
203 	xpq_flush_queue();					\
204 	splx(_s);						\
205 } while (/*CONSTCOND*/0)
206 #define	PTE_UPDATES_FLUSH() do {				\
207 	int _s = splvm();					\
208 	xpq_flush_queue();					\
209 	splx(_s);						\
210 } while (/*CONSTCOND*/0)
211 
212 #endif
213 
214 #define	XPMAP_OFFSET	(KERNTEXTOFF - KERNBASE)
215 static __inline paddr_t
216 xpmap_mtop(paddr_t mpa)
217 {
218 	return ((machine_to_phys_mapping[mpa >> PAGE_SHIFT] << PAGE_SHIFT) +
219 	    XPMAP_OFFSET) | (mpa & ~PG_FRAME);
220 }
221 
222 static __inline paddr_t
223 xpmap_ptom(paddr_t ppa)
224 {
225 	return (xpmap_phys_to_machine_mapping[(ppa -
226 	    XPMAP_OFFSET) >> PAGE_SHIFT] << PAGE_SHIFT)
227 		| (ppa & ~PG_FRAME);
228 }
229 
230 static __inline paddr_t
231 xpmap_ptom_masked(paddr_t ppa)
232 {
233 	return (xpmap_phys_to_machine_mapping[(ppa -
234 	    XPMAP_OFFSET) >> PAGE_SHIFT] << PAGE_SHIFT);
235 }
236 
237 #endif /* _XEN_XENPMAP_H_ */
238