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#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/* The memory helpers for tcg-generated code need tcg_target_long etc.  */
 151#include "tcg.h"
 152
 153static 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.  */
 163static 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
 171static 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.  */
 177static 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#ifdef MMU_MODE0_SUFFIX
 184#define CPU_MMU_INDEX 0
 185#define MEMSUFFIX MMU_MODE0_SUFFIX
 186#define DATA_SIZE 1
 187#include "exec/cpu_ldst_template.h"
 188
 189#define DATA_SIZE 2
 190#include "exec/cpu_ldst_template.h"
 191
 192#define DATA_SIZE 4
 193#include "exec/cpu_ldst_template.h"
 194
 195#define DATA_SIZE 8
 196#include "exec/cpu_ldst_template.h"
 197#undef CPU_MMU_INDEX
 198#undef MEMSUFFIX
 199#endif
 200
 201#if (NB_MMU_MODES >= 2) && defined(MMU_MODE1_SUFFIX)
 202#define CPU_MMU_INDEX 1
 203#define MEMSUFFIX MMU_MODE1_SUFFIX
 204#define DATA_SIZE 1
 205#include "exec/cpu_ldst_template.h"
 206
 207#define DATA_SIZE 2
 208#include "exec/cpu_ldst_template.h"
 209
 210#define DATA_SIZE 4
 211#include "exec/cpu_ldst_template.h"
 212
 213#define DATA_SIZE 8
 214#include "exec/cpu_ldst_template.h"
 215#undef CPU_MMU_INDEX
 216#undef MEMSUFFIX
 217#endif
 218
 219#if (NB_MMU_MODES >= 3) && defined(MMU_MODE2_SUFFIX)
 220
 221#define CPU_MMU_INDEX 2
 222#define MEMSUFFIX MMU_MODE2_SUFFIX
 223#define DATA_SIZE 1
 224#include "exec/cpu_ldst_template.h"
 225
 226#define DATA_SIZE 2
 227#include "exec/cpu_ldst_template.h"
 228
 229#define DATA_SIZE 4
 230#include "exec/cpu_ldst_template.h"
 231
 232#define DATA_SIZE 8
 233#include "exec/cpu_ldst_template.h"
 234#undef CPU_MMU_INDEX
 235#undef MEMSUFFIX
 236#endif /* (NB_MMU_MODES >= 3) */
 237
 238#if (NB_MMU_MODES >= 4) && defined(MMU_MODE3_SUFFIX)
 239
 240#define CPU_MMU_INDEX 3
 241#define MEMSUFFIX MMU_MODE3_SUFFIX
 242#define DATA_SIZE 1
 243#include "exec/cpu_ldst_template.h"
 244
 245#define DATA_SIZE 2
 246#include "exec/cpu_ldst_template.h"
 247
 248#define DATA_SIZE 4
 249#include "exec/cpu_ldst_template.h"
 250
 251#define DATA_SIZE 8
 252#include "exec/cpu_ldst_template.h"
 253#undef CPU_MMU_INDEX
 254#undef MEMSUFFIX
 255#endif /* (NB_MMU_MODES >= 4) */
 256
 257#if (NB_MMU_MODES >= 5) && defined(MMU_MODE4_SUFFIX)
 258
 259#define CPU_MMU_INDEX 4
 260#define MEMSUFFIX MMU_MODE4_SUFFIX
 261#define DATA_SIZE 1
 262#include "exec/cpu_ldst_template.h"
 263
 264#define DATA_SIZE 2
 265#include "exec/cpu_ldst_template.h"
 266
 267#define DATA_SIZE 4
 268#include "exec/cpu_ldst_template.h"
 269
 270#define DATA_SIZE 8
 271#include "exec/cpu_ldst_template.h"
 272#undef CPU_MMU_INDEX
 273#undef MEMSUFFIX
 274#endif /* (NB_MMU_MODES >= 5) */
 275
 276#if (NB_MMU_MODES >= 6) && defined(MMU_MODE5_SUFFIX)
 277
 278#define CPU_MMU_INDEX 5
 279#define MEMSUFFIX MMU_MODE5_SUFFIX
 280#define DATA_SIZE 1
 281#include "exec/cpu_ldst_template.h"
 282
 283#define DATA_SIZE 2
 284#include "exec/cpu_ldst_template.h"
 285
 286#define DATA_SIZE 4
 287#include "exec/cpu_ldst_template.h"
 288
 289#define DATA_SIZE 8
 290#include "exec/cpu_ldst_template.h"
 291#undef CPU_MMU_INDEX
 292#undef MEMSUFFIX
 293#endif /* (NB_MMU_MODES >= 6) */
 294
 295#if (NB_MMU_MODES >= 7) && defined(MMU_MODE6_SUFFIX)
 296
 297#define CPU_MMU_INDEX 6
 298#define MEMSUFFIX MMU_MODE6_SUFFIX
 299#define DATA_SIZE 1
 300#include "exec/cpu_ldst_template.h"
 301
 302#define DATA_SIZE 2
 303#include "exec/cpu_ldst_template.h"
 304
 305#define DATA_SIZE 4
 306#include "exec/cpu_ldst_template.h"
 307
 308#define DATA_SIZE 8
 309#include "exec/cpu_ldst_template.h"
 310#undef CPU_MMU_INDEX
 311#undef MEMSUFFIX
 312#endif /* (NB_MMU_MODES >= 7) */
 313
 314#if (NB_MMU_MODES >= 8) && defined(MMU_MODE7_SUFFIX)
 315
 316#define CPU_MMU_INDEX 7
 317#define MEMSUFFIX MMU_MODE7_SUFFIX
 318#define DATA_SIZE 1
 319#include "exec/cpu_ldst_template.h"
 320
 321#define DATA_SIZE 2
 322#include "exec/cpu_ldst_template.h"
 323
 324#define DATA_SIZE 4
 325#include "exec/cpu_ldst_template.h"
 326
 327#define DATA_SIZE 8
 328#include "exec/cpu_ldst_template.h"
 329#undef CPU_MMU_INDEX
 330#undef MEMSUFFIX
 331#endif /* (NB_MMU_MODES >= 8) */
 332
 333#if (NB_MMU_MODES >= 9) && defined(MMU_MODE8_SUFFIX)
 334
 335#define CPU_MMU_INDEX 8
 336#define MEMSUFFIX MMU_MODE8_SUFFIX
 337#define DATA_SIZE 1
 338#include "exec/cpu_ldst_template.h"
 339
 340#define DATA_SIZE 2
 341#include "exec/cpu_ldst_template.h"
 342
 343#define DATA_SIZE 4
 344#include "exec/cpu_ldst_template.h"
 345
 346#define DATA_SIZE 8
 347#include "exec/cpu_ldst_template.h"
 348#undef CPU_MMU_INDEX
 349#undef MEMSUFFIX
 350#endif /* (NB_MMU_MODES >= 9) */
 351
 352#if (NB_MMU_MODES >= 10) && defined(MMU_MODE9_SUFFIX)
 353
 354#define CPU_MMU_INDEX 9
 355#define MEMSUFFIX MMU_MODE9_SUFFIX
 356#define DATA_SIZE 1
 357#include "exec/cpu_ldst_template.h"
 358
 359#define DATA_SIZE 2
 360#include "exec/cpu_ldst_template.h"
 361
 362#define DATA_SIZE 4
 363#include "exec/cpu_ldst_template.h"
 364
 365#define DATA_SIZE 8
 366#include "exec/cpu_ldst_template.h"
 367#undef CPU_MMU_INDEX
 368#undef MEMSUFFIX
 369#endif /* (NB_MMU_MODES >= 10) */
 370
 371#if (NB_MMU_MODES >= 11) && defined(MMU_MODE10_SUFFIX)
 372
 373#define CPU_MMU_INDEX 10
 374#define MEMSUFFIX MMU_MODE10_SUFFIX
 375#define DATA_SIZE 1
 376#include "exec/cpu_ldst_template.h"
 377
 378#define DATA_SIZE 2
 379#include "exec/cpu_ldst_template.h"
 380
 381#define DATA_SIZE 4
 382#include "exec/cpu_ldst_template.h"
 383
 384#define DATA_SIZE 8
 385#include "exec/cpu_ldst_template.h"
 386#undef CPU_MMU_INDEX
 387#undef MEMSUFFIX
 388#endif /* (NB_MMU_MODES >= 11) */
 389
 390#if (NB_MMU_MODES >= 12) && defined(MMU_MODE11_SUFFIX)
 391
 392#define CPU_MMU_INDEX 11
 393#define MEMSUFFIX MMU_MODE11_SUFFIX
 394#define DATA_SIZE 1
 395#include "exec/cpu_ldst_template.h"
 396
 397#define DATA_SIZE 2
 398#include "exec/cpu_ldst_template.h"
 399
 400#define DATA_SIZE 4
 401#include "exec/cpu_ldst_template.h"
 402
 403#define DATA_SIZE 8
 404#include "exec/cpu_ldst_template.h"
 405#undef CPU_MMU_INDEX
 406#undef MEMSUFFIX
 407#endif /* (NB_MMU_MODES >= 12) */
 408
 409#if (NB_MMU_MODES > 12)
 410#error "NB_MMU_MODES > 12 is not supported for now"
 411#endif /* (NB_MMU_MODES > 12) */
 412
 413/* these access are slower, they must be as rare as possible */
 414#define CPU_MMU_INDEX (cpu_mmu_index(env, false))
 415#define MEMSUFFIX _data
 416#define DATA_SIZE 1
 417#include "exec/cpu_ldst_template.h"
 418
 419#define DATA_SIZE 2
 420#include "exec/cpu_ldst_template.h"
 421
 422#define DATA_SIZE 4
 423#include "exec/cpu_ldst_template.h"
 424
 425#define DATA_SIZE 8
 426#include "exec/cpu_ldst_template.h"
 427#undef CPU_MMU_INDEX
 428#undef MEMSUFFIX
 429
 430#define CPU_MMU_INDEX (cpu_mmu_index(env, true))
 431#define MEMSUFFIX _code
 432#define SOFTMMU_CODE_ACCESS
 433
 434#define DATA_SIZE 1
 435#include "exec/cpu_ldst_template.h"
 436
 437#define DATA_SIZE 2
 438#include "exec/cpu_ldst_template.h"
 439
 440#define DATA_SIZE 4
 441#include "exec/cpu_ldst_template.h"
 442
 443#define DATA_SIZE 8
 444#include "exec/cpu_ldst_template.h"
 445
 446#undef CPU_MMU_INDEX
 447#undef MEMSUFFIX
 448#undef SOFTMMU_CODE_ACCESS
 449
 450#endif /* defined(CONFIG_USER_ONLY) */
 451
 452/**
 453 * tlb_vaddr_to_host:
 454 * @env: CPUArchState
 455 * @addr: guest virtual address to look up
 456 * @access_type: 0 for read, 1 for write, 2 for execute
 457 * @mmu_idx: MMU index to use for lookup
 458 *
 459 * Look up the specified guest virtual index in the TCG softmmu TLB.
 460 * If we can translate a host virtual address suitable for direct RAM
 461 * access, without causing a guest exception, then return it.
 462 * Otherwise (TLB entry is for an I/O access, guest software
 463 * TLB fill required, etc) return NULL.
 464 */
 465#ifdef CONFIG_USER_ONLY
 466static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
 467                                      MMUAccessType access_type, int mmu_idx)
 468{
 469    return g2h(addr);
 470}
 471#else
 472void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
 473                        MMUAccessType access_type, int mmu_idx);
 474#endif
 475
 476#endif /* CPU_LDST_H */
 477