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