qemu/include/exec/cpu_ldst.h
<<
>>
Prefs
   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
  55typedef uint32_t abi_ptr;
  56#define TARGET_ABI_FMT_ptr "%x"
  57#else
  58typedef 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
  72static 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
  88typedef target_ulong abi_ptr;
  89#define TARGET_ABI_FMT_ptr TARGET_ABI_FMT_lx
  90#endif
  91
  92#if defined(CONFIG_USER_ONLY)
  93
  94extern __thread uintptr_t helper_retaddr;
  95
  96static 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
 106static 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/*
 133 * Code access is deprecated in favour of translator_ld* functions
 134 * (see translator.h). However there are still users that need to
 135 * converted so for now these stay.
 136 */
 137#define MEMSUFFIX _code
 138#define CODE_ACCESS
 139#define DATA_SIZE 1
 140#include "exec/cpu_ldst_useronly_template.h"
 141
 142#define DATA_SIZE 2
 143#include "exec/cpu_ldst_useronly_template.h"
 144
 145#define DATA_SIZE 4
 146#include "exec/cpu_ldst_useronly_template.h"
 147
 148#define DATA_SIZE 8
 149#include "exec/cpu_ldst_useronly_template.h"
 150#undef MEMSUFFIX
 151#undef CODE_ACCESS
 152
 153#else
 154
 155/* The memory helpers for tcg-generated code need tcg_target_long etc.  */
 156#include "tcg.h"
 157
 158static inline target_ulong tlb_addr_write(const CPUTLBEntry *entry)
 159{
 160#if TCG_OVERSIZED_GUEST
 161    return entry->addr_write;
 162#else
 163    return atomic_read(&entry->addr_write);
 164#endif
 165}
 166
 167/* Find the TLB index corresponding to the mmu_idx + address pair.  */
 168static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
 169                                  target_ulong addr)
 170{
 171    uintptr_t size_mask = env_tlb(env)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS;
 172
 173    return (addr >> TARGET_PAGE_BITS) & size_mask;
 174}
 175
 176static inline size_t tlb_n_entries(CPUArchState *env, uintptr_t mmu_idx)
 177{
 178    return (env_tlb(env)->f[mmu_idx].mask >> CPU_TLB_ENTRY_BITS) + 1;
 179}
 180
 181/* Find the TLB entry corresponding to the mmu_idx + address pair.  */
 182static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
 183                                     target_ulong addr)
 184{
 185    return &env_tlb(env)->f[mmu_idx].table[tlb_index(env, mmu_idx, addr)];
 186}
 187
 188#ifdef MMU_MODE0_SUFFIX
 189#define CPU_MMU_INDEX 0
 190#define MEMSUFFIX MMU_MODE0_SUFFIX
 191#define DATA_SIZE 1
 192#include "exec/cpu_ldst_template.h"
 193
 194#define DATA_SIZE 2
 195#include "exec/cpu_ldst_template.h"
 196
 197#define DATA_SIZE 4
 198#include "exec/cpu_ldst_template.h"
 199
 200#define DATA_SIZE 8
 201#include "exec/cpu_ldst_template.h"
 202#undef CPU_MMU_INDEX
 203#undef MEMSUFFIX
 204#endif
 205
 206#if (NB_MMU_MODES >= 2) && defined(MMU_MODE1_SUFFIX)
 207#define CPU_MMU_INDEX 1
 208#define MEMSUFFIX MMU_MODE1_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 >= 3) && defined(MMU_MODE2_SUFFIX)
 225
 226#define CPU_MMU_INDEX 2
 227#define MEMSUFFIX MMU_MODE2_SUFFIX
 228#define DATA_SIZE 1
 229#include "exec/cpu_ldst_template.h"
 230
 231#define DATA_SIZE 2
 232#include "exec/cpu_ldst_template.h"
 233
 234#define DATA_SIZE 4
 235#include "exec/cpu_ldst_template.h"
 236
 237#define DATA_SIZE 8
 238#include "exec/cpu_ldst_template.h"
 239#undef CPU_MMU_INDEX
 240#undef MEMSUFFIX
 241#endif /* (NB_MMU_MODES >= 3) */
 242
 243#if (NB_MMU_MODES >= 4) && defined(MMU_MODE3_SUFFIX)
 244
 245#define CPU_MMU_INDEX 3
 246#define MEMSUFFIX MMU_MODE3_SUFFIX
 247#define DATA_SIZE 1
 248#include "exec/cpu_ldst_template.h"
 249
 250#define DATA_SIZE 2
 251#include "exec/cpu_ldst_template.h"
 252
 253#define DATA_SIZE 4
 254#include "exec/cpu_ldst_template.h"
 255
 256#define DATA_SIZE 8
 257#include "exec/cpu_ldst_template.h"
 258#undef CPU_MMU_INDEX
 259#undef MEMSUFFIX
 260#endif /* (NB_MMU_MODES >= 4) */
 261
 262#if (NB_MMU_MODES >= 5) && defined(MMU_MODE4_SUFFIX)
 263
 264#define CPU_MMU_INDEX 4
 265#define MEMSUFFIX MMU_MODE4_SUFFIX
 266#define DATA_SIZE 1
 267#include "exec/cpu_ldst_template.h"
 268
 269#define DATA_SIZE 2
 270#include "exec/cpu_ldst_template.h"
 271
 272#define DATA_SIZE 4
 273#include "exec/cpu_ldst_template.h"
 274
 275#define DATA_SIZE 8
 276#include "exec/cpu_ldst_template.h"
 277#undef CPU_MMU_INDEX
 278#undef MEMSUFFIX
 279#endif /* (NB_MMU_MODES >= 5) */
 280
 281#if (NB_MMU_MODES >= 6) && defined(MMU_MODE5_SUFFIX)
 282
 283#define CPU_MMU_INDEX 5
 284#define MEMSUFFIX MMU_MODE5_SUFFIX
 285#define DATA_SIZE 1
 286#include "exec/cpu_ldst_template.h"
 287
 288#define DATA_SIZE 2
 289#include "exec/cpu_ldst_template.h"
 290
 291#define DATA_SIZE 4
 292#include "exec/cpu_ldst_template.h"
 293
 294#define DATA_SIZE 8
 295#include "exec/cpu_ldst_template.h"
 296#undef CPU_MMU_INDEX
 297#undef MEMSUFFIX
 298#endif /* (NB_MMU_MODES >= 6) */
 299
 300#if (NB_MMU_MODES >= 7) && defined(MMU_MODE6_SUFFIX)
 301
 302#define CPU_MMU_INDEX 6
 303#define MEMSUFFIX MMU_MODE6_SUFFIX
 304#define DATA_SIZE 1
 305#include "exec/cpu_ldst_template.h"
 306
 307#define DATA_SIZE 2
 308#include "exec/cpu_ldst_template.h"
 309
 310#define DATA_SIZE 4
 311#include "exec/cpu_ldst_template.h"
 312
 313#define DATA_SIZE 8
 314#include "exec/cpu_ldst_template.h"
 315#undef CPU_MMU_INDEX
 316#undef MEMSUFFIX
 317#endif /* (NB_MMU_MODES >= 7) */
 318
 319#if (NB_MMU_MODES >= 8) && defined(MMU_MODE7_SUFFIX)
 320
 321#define CPU_MMU_INDEX 7
 322#define MEMSUFFIX MMU_MODE7_SUFFIX
 323#define DATA_SIZE 1
 324#include "exec/cpu_ldst_template.h"
 325
 326#define DATA_SIZE 2
 327#include "exec/cpu_ldst_template.h"
 328
 329#define DATA_SIZE 4
 330#include "exec/cpu_ldst_template.h"
 331
 332#define DATA_SIZE 8
 333#include "exec/cpu_ldst_template.h"
 334#undef CPU_MMU_INDEX
 335#undef MEMSUFFIX
 336#endif /* (NB_MMU_MODES >= 8) */
 337
 338#if (NB_MMU_MODES >= 9) && defined(MMU_MODE8_SUFFIX)
 339
 340#define CPU_MMU_INDEX 8
 341#define MEMSUFFIX MMU_MODE8_SUFFIX
 342#define DATA_SIZE 1
 343#include "exec/cpu_ldst_template.h"
 344
 345#define DATA_SIZE 2
 346#include "exec/cpu_ldst_template.h"
 347
 348#define DATA_SIZE 4
 349#include "exec/cpu_ldst_template.h"
 350
 351#define DATA_SIZE 8
 352#include "exec/cpu_ldst_template.h"
 353#undef CPU_MMU_INDEX
 354#undef MEMSUFFIX
 355#endif /* (NB_MMU_MODES >= 9) */
 356
 357#if (NB_MMU_MODES >= 10) && defined(MMU_MODE9_SUFFIX)
 358
 359#define CPU_MMU_INDEX 9
 360#define MEMSUFFIX MMU_MODE9_SUFFIX
 361#define DATA_SIZE 1
 362#include "exec/cpu_ldst_template.h"
 363
 364#define DATA_SIZE 2
 365#include "exec/cpu_ldst_template.h"
 366
 367#define DATA_SIZE 4
 368#include "exec/cpu_ldst_template.h"
 369
 370#define DATA_SIZE 8
 371#include "exec/cpu_ldst_template.h"
 372#undef CPU_MMU_INDEX
 373#undef MEMSUFFIX
 374#endif /* (NB_MMU_MODES >= 10) */
 375
 376#if (NB_MMU_MODES >= 11) && defined(MMU_MODE10_SUFFIX)
 377
 378#define CPU_MMU_INDEX 10
 379#define MEMSUFFIX MMU_MODE10_SUFFIX
 380#define DATA_SIZE 1
 381#include "exec/cpu_ldst_template.h"
 382
 383#define DATA_SIZE 2
 384#include "exec/cpu_ldst_template.h"
 385
 386#define DATA_SIZE 4
 387#include "exec/cpu_ldst_template.h"
 388
 389#define DATA_SIZE 8
 390#include "exec/cpu_ldst_template.h"
 391#undef CPU_MMU_INDEX
 392#undef MEMSUFFIX
 393#endif /* (NB_MMU_MODES >= 11) */
 394
 395#if (NB_MMU_MODES >= 12) && defined(MMU_MODE11_SUFFIX)
 396
 397#define CPU_MMU_INDEX 11
 398#define MEMSUFFIX MMU_MODE11_SUFFIX
 399#define DATA_SIZE 1
 400#include "exec/cpu_ldst_template.h"
 401
 402#define DATA_SIZE 2
 403#include "exec/cpu_ldst_template.h"
 404
 405#define DATA_SIZE 4
 406#include "exec/cpu_ldst_template.h"
 407
 408#define DATA_SIZE 8
 409#include "exec/cpu_ldst_template.h"
 410#undef CPU_MMU_INDEX
 411#undef MEMSUFFIX
 412#endif /* (NB_MMU_MODES >= 12) */
 413
 414#if (NB_MMU_MODES > 12)
 415#error "NB_MMU_MODES > 12 is not supported for now"
 416#endif /* (NB_MMU_MODES > 12) */
 417
 418/* these access are slower, they must be as rare as possible */
 419#define CPU_MMU_INDEX (cpu_mmu_index(env, false))
 420#define MEMSUFFIX _data
 421#define DATA_SIZE 1
 422#include "exec/cpu_ldst_template.h"
 423
 424#define DATA_SIZE 2
 425#include "exec/cpu_ldst_template.h"
 426
 427#define DATA_SIZE 4
 428#include "exec/cpu_ldst_template.h"
 429
 430#define DATA_SIZE 8
 431#include "exec/cpu_ldst_template.h"
 432#undef CPU_MMU_INDEX
 433#undef MEMSUFFIX
 434
 435/*
 436 * Code access is deprecated in favour of translator_ld* functions
 437 * (see translator.h). However there are still users that need to
 438 * converted so for now these stay.
 439 */
 440
 441#define CPU_MMU_INDEX (cpu_mmu_index(env, true))
 442#define MEMSUFFIX _code
 443#define SOFTMMU_CODE_ACCESS
 444
 445#define DATA_SIZE 1
 446#include "exec/cpu_ldst_template.h"
 447
 448#define DATA_SIZE 2
 449#include "exec/cpu_ldst_template.h"
 450
 451#define DATA_SIZE 4
 452#include "exec/cpu_ldst_template.h"
 453
 454#define DATA_SIZE 8
 455#include "exec/cpu_ldst_template.h"
 456
 457#undef CPU_MMU_INDEX
 458#undef MEMSUFFIX
 459#undef SOFTMMU_CODE_ACCESS
 460
 461#endif /* defined(CONFIG_USER_ONLY) */
 462
 463/**
 464 * tlb_vaddr_to_host:
 465 * @env: CPUArchState
 466 * @addr: guest virtual address to look up
 467 * @access_type: 0 for read, 1 for write, 2 for execute
 468 * @mmu_idx: MMU index to use for lookup
 469 *
 470 * Look up the specified guest virtual index in the TCG softmmu TLB.
 471 * If we can translate a host virtual address suitable for direct RAM
 472 * access, without causing a guest exception, then return it.
 473 * Otherwise (TLB entry is for an I/O access, guest software
 474 * TLB fill required, etc) return NULL.
 475 */
 476#ifdef CONFIG_USER_ONLY
 477static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
 478                                      MMUAccessType access_type, int mmu_idx)
 479{
 480    return g2h(addr);
 481}
 482#else
 483void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
 484                        MMUAccessType access_type, int mmu_idx);
 485#endif
 486
 487#endif /* CPU_LDST_H */
 488