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 #if HOST_LONG_BITS <= TARGET_VIRT_ADDR_SPACE_BITS 66 #define guest_addr_valid(x) (1) 67 #else 68 #define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX) 69 #endif 70 #define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base) 71 72 static inline int guest_range_valid(unsigned long start, unsigned long len) 73 { 74 return len - 1 <= GUEST_ADDR_MAX && start <= GUEST_ADDR_MAX - len + 1; 75 } 76 77 #define h2g_nocheck(x) ({ \ 78 unsigned long __ret = (unsigned long)(x) - guest_base; \ 79 (abi_ptr)__ret; \ 80 }) 81 82 #define h2g(x) ({ \ 83 /* Check if given address fits target address space */ \ 84 assert(h2g_valid(x)); \ 85 h2g_nocheck(x); \ 86 }) 87 #else 88 typedef target_ulong abi_ptr; 89 #define TARGET_ABI_FMT_ptr TARGET_ABI_FMT_lx 90 #endif 91 92 #if defined(CONFIG_USER_ONLY) 93 94 extern __thread uintptr_t helper_retaddr; 95 96 static inline void set_helper_retaddr(uintptr_t ra) 97 { 98 helper_retaddr = ra; 99 /* 100 * Ensure that this write is visible to the SIGSEGV handler that 101 * may be invoked due to a subsequent invalid memory operation. 102 */ 103 signal_barrier(); 104 } 105 106 static inline void clear_helper_retaddr(void) 107 { 108 /* 109 * Ensure that previous memory operations have succeeded before 110 * removing the data visible to the signal handler. 111 */ 112 signal_barrier(); 113 helper_retaddr = 0; 114 } 115 116 /* In user-only mode we provide only the _code and _data accessors. */ 117 118 #define MEMSUFFIX _data 119 #define DATA_SIZE 1 120 #include "exec/cpu_ldst_useronly_template.h" 121 122 #define DATA_SIZE 2 123 #include "exec/cpu_ldst_useronly_template.h" 124 125 #define DATA_SIZE 4 126 #include "exec/cpu_ldst_useronly_template.h" 127 128 #define DATA_SIZE 8 129 #include "exec/cpu_ldst_useronly_template.h" 130 #undef MEMSUFFIX 131 132 #define MEMSUFFIX _code 133 #define CODE_ACCESS 134 #define DATA_SIZE 1 135 #include "exec/cpu_ldst_useronly_template.h" 136 137 #define DATA_SIZE 2 138 #include "exec/cpu_ldst_useronly_template.h" 139 140 #define DATA_SIZE 4 141 #include "exec/cpu_ldst_useronly_template.h" 142 143 #define DATA_SIZE 8 144 #include "exec/cpu_ldst_useronly_template.h" 145 #undef MEMSUFFIX 146 #undef CODE_ACCESS 147 148 #else 149 150 /* Needed for TCG_OVERSIZED_GUEST */ 151 #include "tcg.h" 152 153 static inline target_ulong tlb_addr_write(const CPUTLBEntry *entry) 154 { 155 #if TCG_OVERSIZED_GUEST 156 return entry->addr_write; 157 #else 158 return atomic_read(&entry->addr_write); 159 #endif 160 } 161 162 /* Find the TLB index corresponding to the mmu_idx + address pair. */ 163 static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx, 164 target_ulong addr) 165 { 166 uintptr_t size_mask = env_tlb(env)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS; 167 168 return (addr >> TARGET_PAGE_BITS) & size_mask; 169 } 170 171 static inline size_t tlb_n_entries(CPUArchState *env, uintptr_t mmu_idx) 172 { 173 return (env_tlb(env)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS) + 1; 174 } 175 176 /* Find the TLB entry corresponding to the mmu_idx + address pair. */ 177 static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx, 178 target_ulong addr) 179 { 180 return &env_tlb(env)->f[mmu_idx].table[tlb_index(env, mmu_idx, addr)]; 181 } 182 183 uint32_t cpu_ldub_mmuidx_ra(CPUArchState *env, abi_ptr addr, 184 int mmu_idx, uintptr_t ra); 185 uint32_t cpu_lduw_mmuidx_ra(CPUArchState *env, abi_ptr addr, 186 int mmu_idx, uintptr_t ra); 187 uint32_t cpu_ldl_mmuidx_ra(CPUArchState *env, abi_ptr addr, 188 int mmu_idx, uintptr_t ra); 189 uint64_t cpu_ldq_mmuidx_ra(CPUArchState *env, abi_ptr addr, 190 int mmu_idx, uintptr_t ra); 191 192 int cpu_ldsb_mmuidx_ra(CPUArchState *env, abi_ptr addr, 193 int mmu_idx, uintptr_t ra); 194 int cpu_ldsw_mmuidx_ra(CPUArchState *env, abi_ptr addr, 195 int mmu_idx, uintptr_t ra); 196 197 void cpu_stb_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val, 198 int mmu_idx, uintptr_t retaddr); 199 void cpu_stw_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val, 200 int mmu_idx, uintptr_t retaddr); 201 void cpu_stl_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint32_t val, 202 int mmu_idx, uintptr_t retaddr); 203 void cpu_stq_mmuidx_ra(CPUArchState *env, abi_ptr addr, uint64_t val, 204 int mmu_idx, uintptr_t retaddr); 205 206 #ifdef MMU_MODE0_SUFFIX 207 #define CPU_MMU_INDEX 0 208 #define MEMSUFFIX MMU_MODE0_SUFFIX 209 #define DATA_SIZE 1 210 #include "exec/cpu_ldst_template.h" 211 212 #define DATA_SIZE 2 213 #include "exec/cpu_ldst_template.h" 214 215 #define DATA_SIZE 4 216 #include "exec/cpu_ldst_template.h" 217 218 #define DATA_SIZE 8 219 #include "exec/cpu_ldst_template.h" 220 #undef CPU_MMU_INDEX 221 #undef MEMSUFFIX 222 #endif 223 224 #if (NB_MMU_MODES >= 2) && defined(MMU_MODE1_SUFFIX) 225 #define CPU_MMU_INDEX 1 226 #define MEMSUFFIX MMU_MODE1_SUFFIX 227 #define DATA_SIZE 1 228 #include "exec/cpu_ldst_template.h" 229 230 #define DATA_SIZE 2 231 #include "exec/cpu_ldst_template.h" 232 233 #define DATA_SIZE 4 234 #include "exec/cpu_ldst_template.h" 235 236 #define DATA_SIZE 8 237 #include "exec/cpu_ldst_template.h" 238 #undef CPU_MMU_INDEX 239 #undef MEMSUFFIX 240 #endif 241 242 #if (NB_MMU_MODES >= 3) && defined(MMU_MODE2_SUFFIX) 243 244 #define CPU_MMU_INDEX 2 245 #define MEMSUFFIX MMU_MODE2_SUFFIX 246 #define DATA_SIZE 1 247 #include "exec/cpu_ldst_template.h" 248 249 #define DATA_SIZE 2 250 #include "exec/cpu_ldst_template.h" 251 252 #define DATA_SIZE 4 253 #include "exec/cpu_ldst_template.h" 254 255 #define DATA_SIZE 8 256 #include "exec/cpu_ldst_template.h" 257 #undef CPU_MMU_INDEX 258 #undef MEMSUFFIX 259 #endif /* (NB_MMU_MODES >= 3) */ 260 261 #if (NB_MMU_MODES >= 4) && defined(MMU_MODE3_SUFFIX) 262 263 #define CPU_MMU_INDEX 3 264 #define MEMSUFFIX MMU_MODE3_SUFFIX 265 #define DATA_SIZE 1 266 #include "exec/cpu_ldst_template.h" 267 268 #define DATA_SIZE 2 269 #include "exec/cpu_ldst_template.h" 270 271 #define DATA_SIZE 4 272 #include "exec/cpu_ldst_template.h" 273 274 #define DATA_SIZE 8 275 #include "exec/cpu_ldst_template.h" 276 #undef CPU_MMU_INDEX 277 #undef MEMSUFFIX 278 #endif /* (NB_MMU_MODES >= 4) */ 279 280 #if (NB_MMU_MODES >= 5) && defined(MMU_MODE4_SUFFIX) 281 282 #define CPU_MMU_INDEX 4 283 #define MEMSUFFIX MMU_MODE4_SUFFIX 284 #define DATA_SIZE 1 285 #include "exec/cpu_ldst_template.h" 286 287 #define DATA_SIZE 2 288 #include "exec/cpu_ldst_template.h" 289 290 #define DATA_SIZE 4 291 #include "exec/cpu_ldst_template.h" 292 293 #define DATA_SIZE 8 294 #include "exec/cpu_ldst_template.h" 295 #undef CPU_MMU_INDEX 296 #undef MEMSUFFIX 297 #endif /* (NB_MMU_MODES >= 5) */ 298 299 #if (NB_MMU_MODES >= 6) && defined(MMU_MODE5_SUFFIX) 300 301 #define CPU_MMU_INDEX 5 302 #define MEMSUFFIX MMU_MODE5_SUFFIX 303 #define DATA_SIZE 1 304 #include "exec/cpu_ldst_template.h" 305 306 #define DATA_SIZE 2 307 #include "exec/cpu_ldst_template.h" 308 309 #define DATA_SIZE 4 310 #include "exec/cpu_ldst_template.h" 311 312 #define DATA_SIZE 8 313 #include "exec/cpu_ldst_template.h" 314 #undef CPU_MMU_INDEX 315 #undef MEMSUFFIX 316 #endif /* (NB_MMU_MODES >= 6) */ 317 318 #if (NB_MMU_MODES >= 7) && defined(MMU_MODE6_SUFFIX) 319 320 #define CPU_MMU_INDEX 6 321 #define MEMSUFFIX MMU_MODE6_SUFFIX 322 #define DATA_SIZE 1 323 #include "exec/cpu_ldst_template.h" 324 325 #define DATA_SIZE 2 326 #include "exec/cpu_ldst_template.h" 327 328 #define DATA_SIZE 4 329 #include "exec/cpu_ldst_template.h" 330 331 #define DATA_SIZE 8 332 #include "exec/cpu_ldst_template.h" 333 #undef CPU_MMU_INDEX 334 #undef MEMSUFFIX 335 #endif /* (NB_MMU_MODES >= 7) */ 336 337 #if (NB_MMU_MODES >= 8) && defined(MMU_MODE7_SUFFIX) 338 339 #define CPU_MMU_INDEX 7 340 #define MEMSUFFIX MMU_MODE7_SUFFIX 341 #define DATA_SIZE 1 342 #include "exec/cpu_ldst_template.h" 343 344 #define DATA_SIZE 2 345 #include "exec/cpu_ldst_template.h" 346 347 #define DATA_SIZE 4 348 #include "exec/cpu_ldst_template.h" 349 350 #define DATA_SIZE 8 351 #include "exec/cpu_ldst_template.h" 352 #undef CPU_MMU_INDEX 353 #undef MEMSUFFIX 354 #endif /* (NB_MMU_MODES >= 8) */ 355 356 #if (NB_MMU_MODES >= 9) && defined(MMU_MODE8_SUFFIX) 357 358 #define CPU_MMU_INDEX 8 359 #define MEMSUFFIX MMU_MODE8_SUFFIX 360 #define DATA_SIZE 1 361 #include "exec/cpu_ldst_template.h" 362 363 #define DATA_SIZE 2 364 #include "exec/cpu_ldst_template.h" 365 366 #define DATA_SIZE 4 367 #include "exec/cpu_ldst_template.h" 368 369 #define DATA_SIZE 8 370 #include "exec/cpu_ldst_template.h" 371 #undef CPU_MMU_INDEX 372 #undef MEMSUFFIX 373 #endif /* (NB_MMU_MODES >= 9) */ 374 375 #if (NB_MMU_MODES >= 10) && defined(MMU_MODE9_SUFFIX) 376 377 #define CPU_MMU_INDEX 9 378 #define MEMSUFFIX MMU_MODE9_SUFFIX 379 #define DATA_SIZE 1 380 #include "exec/cpu_ldst_template.h" 381 382 #define DATA_SIZE 2 383 #include "exec/cpu_ldst_template.h" 384 385 #define DATA_SIZE 4 386 #include "exec/cpu_ldst_template.h" 387 388 #define DATA_SIZE 8 389 #include "exec/cpu_ldst_template.h" 390 #undef CPU_MMU_INDEX 391 #undef MEMSUFFIX 392 #endif /* (NB_MMU_MODES >= 10) */ 393 394 #if (NB_MMU_MODES >= 11) && defined(MMU_MODE10_SUFFIX) 395 396 #define CPU_MMU_INDEX 10 397 #define MEMSUFFIX MMU_MODE10_SUFFIX 398 #define DATA_SIZE 1 399 #include "exec/cpu_ldst_template.h" 400 401 #define DATA_SIZE 2 402 #include "exec/cpu_ldst_template.h" 403 404 #define DATA_SIZE 4 405 #include "exec/cpu_ldst_template.h" 406 407 #define DATA_SIZE 8 408 #include "exec/cpu_ldst_template.h" 409 #undef CPU_MMU_INDEX 410 #undef MEMSUFFIX 411 #endif /* (NB_MMU_MODES >= 11) */ 412 413 #if (NB_MMU_MODES >= 12) && defined(MMU_MODE11_SUFFIX) 414 415 #define CPU_MMU_INDEX 11 416 #define MEMSUFFIX MMU_MODE11_SUFFIX 417 #define DATA_SIZE 1 418 #include "exec/cpu_ldst_template.h" 419 420 #define DATA_SIZE 2 421 #include "exec/cpu_ldst_template.h" 422 423 #define DATA_SIZE 4 424 #include "exec/cpu_ldst_template.h" 425 426 #define DATA_SIZE 8 427 #include "exec/cpu_ldst_template.h" 428 #undef CPU_MMU_INDEX 429 #undef MEMSUFFIX 430 #endif /* (NB_MMU_MODES >= 12) */ 431 432 #if (NB_MMU_MODES > 12) 433 #error "NB_MMU_MODES > 12 is not supported for now" 434 #endif /* (NB_MMU_MODES > 12) */ 435 436 /* these access are slower, they must be as rare as possible */ 437 #define CPU_MMU_INDEX (cpu_mmu_index(env, false)) 438 #define MEMSUFFIX _data 439 #define DATA_SIZE 1 440 #include "exec/cpu_ldst_template.h" 441 442 #define DATA_SIZE 2 443 #include "exec/cpu_ldst_template.h" 444 445 #define DATA_SIZE 4 446 #include "exec/cpu_ldst_template.h" 447 448 #define DATA_SIZE 8 449 #include "exec/cpu_ldst_template.h" 450 #undef CPU_MMU_INDEX 451 #undef MEMSUFFIX 452 453 uint32_t cpu_ldub_code(CPUArchState *env, abi_ptr addr); 454 uint32_t cpu_lduw_code(CPUArchState *env, abi_ptr addr); 455 uint32_t cpu_ldl_code(CPUArchState *env, abi_ptr addr); 456 uint64_t cpu_ldq_code(CPUArchState *env, abi_ptr addr); 457 458 static inline int cpu_ldsb_code(CPUArchState *env, abi_ptr addr) 459 { 460 return (int8_t)cpu_ldub_code(env, addr); 461 } 462 463 static inline int cpu_ldsw_code(CPUArchState *env, abi_ptr addr) 464 { 465 return (int16_t)cpu_lduw_code(env, addr); 466 } 467 468 #endif /* defined(CONFIG_USER_ONLY) */ 469 470 /** 471 * tlb_vaddr_to_host: 472 * @env: CPUArchState 473 * @addr: guest virtual address to look up 474 * @access_type: 0 for read, 1 for write, 2 for execute 475 * @mmu_idx: MMU index to use for lookup 476 * 477 * Look up the specified guest virtual index in the TCG softmmu TLB. 478 * If we can translate a host virtual address suitable for direct RAM 479 * access, without causing a guest exception, then return it. 480 * Otherwise (TLB entry is for an I/O access, guest software 481 * TLB fill required, etc) return NULL. 482 */ 483 #ifdef CONFIG_USER_ONLY 484 static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr, 485 MMUAccessType access_type, int mmu_idx) 486 { 487 return g2h(addr); 488 } 489 #else 490 void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr, 491 MMUAccessType access_type, int mmu_idx); 492 #endif 493 494 #endif /* CPU_LDST_H */ 495