1 /* $NetBSD: xenpmap.h,v 1.11 2005/12/24 20:07:48 perry 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