1 /* 2 * Software MMU support 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 16 * 17 */ 18 19 /* 20 * Generate inline load/store functions for all MMU modes (typically 21 * at least _user and _kernel) as well as _data versions, for all data 22 * sizes. 23 * 24 * Used by target op helpers. 25 * 26 * The syntax for the accessors is: 27 * 28 * load: cpu_ld{sign}{size}_{mmusuffix}(env, ptr) 29 * 30 * store: cpu_st{sign}{size}_{mmusuffix}(env, ptr, val) 31 * 32 * sign is: 33 * (empty): for 32 and 64 bit sizes 34 * u : unsigned 35 * s : signed 36 * 37 * size is: 38 * b: 8 bits 39 * w: 16 bits 40 * l: 32 bits 41 * q: 64 bits 42 * 43 * mmusuffix is one of the generic suffixes "data" or "code", or 44 * (for softmmu configs) a target-specific MMU mode suffix as defined 45 * in target cpu.h. 46 */ 47 #ifndef CPU_LDST_H 48 #define CPU_LDST_H 49 50 #if defined(CONFIG_USER_ONLY) 51 /* sparc32plus has 64bit long but 32bit space address 52 * this can make bad result with g2h() and h2g() 53 */ 54 #if TARGET_VIRT_ADDR_SPACE_BITS <= 32 55 typedef uint32_t abi_ptr; 56 #define TARGET_ABI_FMT_ptr "%x" 57 #else 58 typedef uint64_t abi_ptr; 59 #define TARGET_ABI_FMT_ptr "%"PRIx64 60 #endif 61 62 /* All direct uses of g2h and h2g need to go away for usermode softmmu. */ 63 #define g2h(x) ((void *)((unsigned long)(abi_ptr)(x) + guest_base)) 64 65 #define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX) 66 #define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base) 67 68 static inline int guest_range_valid(unsigned long start, unsigned long len) 69 { 70 return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1; 71 } 72 73 #define h2g_nocheck(x) ({ \ 74 unsigned long __ret = (unsigned long)(x) - guest_base; \ 75 (abi_ptr)__ret; \ 76 }) 77 78 #define h2g(x) ({ \ 79 /* Check if given address fits target address space */ \ 80 assert(h2g_valid(x)); \ 81 h2g_nocheck(x); \ 82 }) 83 #else 84 typedef target_ulong abi_ptr; 85 #define TARGET_ABI_FMT_ptr TARGET_ABI_FMT_lx 86 #endif 87 88 #if defined(CONFIG_USER_ONLY) 89 90 extern __thread uintptr_t helper_retaddr; 91 92 /* In user-only mode we provide only the _code and _data accessors. */ 93 94 #define MEMSUFFIX _data 95 #define DATA_SIZE 1 96 #include "exec/cpu_ldst_useronly_template.h" 97 98 #define DATA_SIZE 2 99 #include "exec/cpu_ldst_useronly_template.h" 100 101 #define DATA_SIZE 4 102 #include "exec/cpu_ldst_useronly_template.h" 103 104 #define DATA_SIZE 8 105 #include "exec/cpu_ldst_useronly_template.h" 106 #undef MEMSUFFIX 107 108 #define MEMSUFFIX _code 109 #define CODE_ACCESS 110 #define DATA_SIZE 1 111 #include "exec/cpu_ldst_useronly_template.h" 112 113 #define DATA_SIZE 2 114 #include "exec/cpu_ldst_useronly_template.h" 115 116 #define DATA_SIZE 4 117 #include "exec/cpu_ldst_useronly_template.h" 118 119 #define DATA_SIZE 8 120 #include "exec/cpu_ldst_useronly_template.h" 121 #undef MEMSUFFIX 122 #undef CODE_ACCESS 123 124 #else 125 126 /* The memory helpers for tcg-generated code need tcg_target_long etc. */ 127 #include "tcg.h" 128 129 static inline target_ulong tlb_addr_write(const CPUTLBEntry *entry) 130 { 131 #if TCG_OVERSIZED_GUEST 132 return entry->addr_write; 133 #else 134 return atomic_read(&entry->addr_write); 135 #endif 136 } 137 138 /* Find the TLB index corresponding to the mmu_idx + address pair. */ 139 static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx, 140 target_ulong addr) 141 { 142 uintptr_t size_mask = env_tlb(env)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS; 143 144 return (addr >> TARGET_PAGE_BITS) & size_mask; 145 } 146 147 static inline size_t tlb_n_entries(CPUArchState *env, uintptr_t mmu_idx) 148 { 149 return (env_tlb(env)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS) + 1; 150 } 151 152 /* Find the TLB entry corresponding to the mmu_idx + address pair. */ 153 static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx, 154 target_ulong addr) 155 { 156 return &env_tlb(env)->f[mmu_idx].table[tlb_index(env, mmu_idx, addr)]; 157 } 158 159 #ifdef MMU_MODE0_SUFFIX 160 #define CPU_MMU_INDEX 0 161 #define MEMSUFFIX MMU_MODE0_SUFFIX 162 #define DATA_SIZE 1 163 #include "exec/cpu_ldst_template.h" 164 165 #define DATA_SIZE 2 166 #include "exec/cpu_ldst_template.h" 167 168 #define DATA_SIZE 4 169 #include "exec/cpu_ldst_template.h" 170 171 #define DATA_SIZE 8 172 #include "exec/cpu_ldst_template.h" 173 #undef CPU_MMU_INDEX 174 #undef MEMSUFFIX 175 #endif 176 177 #if (NB_MMU_MODES >= 2) && defined(MMU_MODE1_SUFFIX) 178 #define CPU_MMU_INDEX 1 179 #define MEMSUFFIX MMU_MODE1_SUFFIX 180 #define DATA_SIZE 1 181 #include "exec/cpu_ldst_template.h" 182 183 #define DATA_SIZE 2 184 #include "exec/cpu_ldst_template.h" 185 186 #define DATA_SIZE 4 187 #include "exec/cpu_ldst_template.h" 188 189 #define DATA_SIZE 8 190 #include "exec/cpu_ldst_template.h" 191 #undef CPU_MMU_INDEX 192 #undef MEMSUFFIX 193 #endif 194 195 #if (NB_MMU_MODES >= 3) && defined(MMU_MODE2_SUFFIX) 196 197 #define CPU_MMU_INDEX 2 198 #define MEMSUFFIX MMU_MODE2_SUFFIX 199 #define DATA_SIZE 1 200 #include "exec/cpu_ldst_template.h" 201 202 #define DATA_SIZE 2 203 #include "exec/cpu_ldst_template.h" 204 205 #define DATA_SIZE 4 206 #include "exec/cpu_ldst_template.h" 207 208 #define DATA_SIZE 8 209 #include "exec/cpu_ldst_template.h" 210 #undef CPU_MMU_INDEX 211 #undef MEMSUFFIX 212 #endif /* (NB_MMU_MODES >= 3) */ 213 214 #if (NB_MMU_MODES >= 4) && defined(MMU_MODE3_SUFFIX) 215 216 #define CPU_MMU_INDEX 3 217 #define MEMSUFFIX MMU_MODE3_SUFFIX 218 #define DATA_SIZE 1 219 #include "exec/cpu_ldst_template.h" 220 221 #define DATA_SIZE 2 222 #include "exec/cpu_ldst_template.h" 223 224 #define DATA_SIZE 4 225 #include "exec/cpu_ldst_template.h" 226 227 #define DATA_SIZE 8 228 #include "exec/cpu_ldst_template.h" 229 #undef CPU_MMU_INDEX 230 #undef MEMSUFFIX 231 #endif /* (NB_MMU_MODES >= 4) */ 232 233 #if (NB_MMU_MODES >= 5) && defined(MMU_MODE4_SUFFIX) 234 235 #define CPU_MMU_INDEX 4 236 #define MEMSUFFIX MMU_MODE4_SUFFIX 237 #define DATA_SIZE 1 238 #include "exec/cpu_ldst_template.h" 239 240 #define DATA_SIZE 2 241 #include "exec/cpu_ldst_template.h" 242 243 #define DATA_SIZE 4 244 #include "exec/cpu_ldst_template.h" 245 246 #define DATA_SIZE 8 247 #include "exec/cpu_ldst_template.h" 248 #undef CPU_MMU_INDEX 249 #undef MEMSUFFIX 250 #endif /* (NB_MMU_MODES >= 5) */ 251 252 #if (NB_MMU_MODES >= 6) && defined(MMU_MODE5_SUFFIX) 253 254 #define CPU_MMU_INDEX 5 255 #define MEMSUFFIX MMU_MODE5_SUFFIX 256 #define DATA_SIZE 1 257 #include "exec/cpu_ldst_template.h" 258 259 #define DATA_SIZE 2 260 #include "exec/cpu_ldst_template.h" 261 262 #define DATA_SIZE 4 263 #include "exec/cpu_ldst_template.h" 264 265 #define DATA_SIZE 8 266 #include "exec/cpu_ldst_template.h" 267 #undef CPU_MMU_INDEX 268 #undef MEMSUFFIX 269 #endif /* (NB_MMU_MODES >= 6) */ 270 271 #if (NB_MMU_MODES >= 7) && defined(MMU_MODE6_SUFFIX) 272 273 #define CPU_MMU_INDEX 6 274 #define MEMSUFFIX MMU_MODE6_SUFFIX 275 #define DATA_SIZE 1 276 #include "exec/cpu_ldst_template.h" 277 278 #define DATA_SIZE 2 279 #include "exec/cpu_ldst_template.h" 280 281 #define DATA_SIZE 4 282 #include "exec/cpu_ldst_template.h" 283 284 #define DATA_SIZE 8 285 #include "exec/cpu_ldst_template.h" 286 #undef CPU_MMU_INDEX 287 #undef MEMSUFFIX 288 #endif /* (NB_MMU_MODES >= 7) */ 289 290 #if (NB_MMU_MODES >= 8) && defined(MMU_MODE7_SUFFIX) 291 292 #define CPU_MMU_INDEX 7 293 #define MEMSUFFIX MMU_MODE7_SUFFIX 294 #define DATA_SIZE 1 295 #include "exec/cpu_ldst_template.h" 296 297 #define DATA_SIZE 2 298 #include "exec/cpu_ldst_template.h" 299 300 #define DATA_SIZE 4 301 #include "exec/cpu_ldst_template.h" 302 303 #define DATA_SIZE 8 304 #include "exec/cpu_ldst_template.h" 305 #undef CPU_MMU_INDEX 306 #undef MEMSUFFIX 307 #endif /* (NB_MMU_MODES >= 8) */ 308 309 #if (NB_MMU_MODES >= 9) && defined(MMU_MODE8_SUFFIX) 310 311 #define CPU_MMU_INDEX 8 312 #define MEMSUFFIX MMU_MODE8_SUFFIX 313 #define DATA_SIZE 1 314 #include "exec/cpu_ldst_template.h" 315 316 #define DATA_SIZE 2 317 #include "exec/cpu_ldst_template.h" 318 319 #define DATA_SIZE 4 320 #include "exec/cpu_ldst_template.h" 321 322 #define DATA_SIZE 8 323 #include "exec/cpu_ldst_template.h" 324 #undef CPU_MMU_INDEX 325 #undef MEMSUFFIX 326 #endif /* (NB_MMU_MODES >= 9) */ 327 328 #if (NB_MMU_MODES >= 10) && defined(MMU_MODE9_SUFFIX) 329 330 #define CPU_MMU_INDEX 9 331 #define MEMSUFFIX MMU_MODE9_SUFFIX 332 #define DATA_SIZE 1 333 #include "exec/cpu_ldst_template.h" 334 335 #define DATA_SIZE 2 336 #include "exec/cpu_ldst_template.h" 337 338 #define DATA_SIZE 4 339 #include "exec/cpu_ldst_template.h" 340 341 #define DATA_SIZE 8 342 #include "exec/cpu_ldst_template.h" 343 #undef CPU_MMU_INDEX 344 #undef MEMSUFFIX 345 #endif /* (NB_MMU_MODES >= 10) */ 346 347 #if (NB_MMU_MODES >= 11) && defined(MMU_MODE10_SUFFIX) 348 349 #define CPU_MMU_INDEX 10 350 #define MEMSUFFIX MMU_MODE10_SUFFIX 351 #define DATA_SIZE 1 352 #include "exec/cpu_ldst_template.h" 353 354 #define DATA_SIZE 2 355 #include "exec/cpu_ldst_template.h" 356 357 #define DATA_SIZE 4 358 #include "exec/cpu_ldst_template.h" 359 360 #define DATA_SIZE 8 361 #include "exec/cpu_ldst_template.h" 362 #undef CPU_MMU_INDEX 363 #undef MEMSUFFIX 364 #endif /* (NB_MMU_MODES >= 11) */ 365 366 #if (NB_MMU_MODES >= 12) && defined(MMU_MODE11_SUFFIX) 367 368 #define CPU_MMU_INDEX 11 369 #define MEMSUFFIX MMU_MODE11_SUFFIX 370 #define DATA_SIZE 1 371 #include "exec/cpu_ldst_template.h" 372 373 #define DATA_SIZE 2 374 #include "exec/cpu_ldst_template.h" 375 376 #define DATA_SIZE 4 377 #include "exec/cpu_ldst_template.h" 378 379 #define DATA_SIZE 8 380 #include "exec/cpu_ldst_template.h" 381 #undef CPU_MMU_INDEX 382 #undef MEMSUFFIX 383 #endif /* (NB_MMU_MODES >= 12) */ 384 385 #if (NB_MMU_MODES > 12) 386 #error "NB_MMU_MODES > 12 is not supported for now" 387 #endif /* (NB_MMU_MODES > 12) */ 388 389 /* these access are slower, they must be as rare as possible */ 390 #define CPU_MMU_INDEX (cpu_mmu_index(env, false)) 391 #define MEMSUFFIX _data 392 #define DATA_SIZE 1 393 #include "exec/cpu_ldst_template.h" 394 395 #define DATA_SIZE 2 396 #include "exec/cpu_ldst_template.h" 397 398 #define DATA_SIZE 4 399 #include "exec/cpu_ldst_template.h" 400 401 #define DATA_SIZE 8 402 #include "exec/cpu_ldst_template.h" 403 #undef CPU_MMU_INDEX 404 #undef MEMSUFFIX 405 406 #define CPU_MMU_INDEX (cpu_mmu_index(env, true)) 407 #define MEMSUFFIX _code 408 #define SOFTMMU_CODE_ACCESS 409 410 #define DATA_SIZE 1 411 #include "exec/cpu_ldst_template.h" 412 413 #define DATA_SIZE 2 414 #include "exec/cpu_ldst_template.h" 415 416 #define DATA_SIZE 4 417 #include "exec/cpu_ldst_template.h" 418 419 #define DATA_SIZE 8 420 #include "exec/cpu_ldst_template.h" 421 422 #undef CPU_MMU_INDEX 423 #undef MEMSUFFIX 424 #undef SOFTMMU_CODE_ACCESS 425 426 #endif /* defined(CONFIG_USER_ONLY) */ 427 428 /** 429 * tlb_vaddr_to_host: 430 * @env: CPUArchState 431 * @addr: guest virtual address to look up 432 * @access_type: 0 for read, 1 for write, 2 for execute 433 * @mmu_idx: MMU index to use for lookup 434 * 435 * Look up the specified guest virtual index in the TCG softmmu TLB. 436 * If we can translate a host virtual address suitable for direct RAM 437 * access, without causing a guest exception, then return it. 438 * Otherwise (TLB entry is for an I/O access, guest software 439 * TLB fill required, etc) return NULL. 440 */ 441 #ifdef CONFIG_USER_ONLY 442 static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr, 443 MMUAccessType access_type, int mmu_idx) 444 { 445 return g2h(addr); 446 } 447 #else 448 void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr, 449 MMUAccessType access_type, int mmu_idx); 450 #endif 451 452 #endif /* CPU_LDST_H */ 453