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#define guest_addr_valid(x) ((x) <= GUEST_ADDR_MAX)
  66#define h2g_valid(x) guest_addr_valid((unsigned long)(x) - guest_base)
  67
  68static 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
  84typedef target_ulong abi_ptr;
  85#define TARGET_ABI_FMT_ptr TARGET_ABI_FMT_lx
  86#endif
  87
  88#if defined(CONFIG_USER_ONLY)
  89
  90extern __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
 129static 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.  */
 139static inline uintptr_t tlb_index(CPUArchState *env, uintptr_t mmu_idx,
 140                                  target_ulong addr)
 141{
 142    uintptr_t size_mask = env->tlb_mask[mmu_idx] >> CPU_TLB_ENTRY_BITS;
 143
 144    return (addr >> TARGET_PAGE_BITS) & size_mask;
 145}
 146
 147static inline size_t tlb_n_entries(CPUArchState *env, uintptr_t mmu_idx)
 148{
 149    return (env->tlb_mask[mmu_idx] >> CPU_TLB_ENTRY_BITS) + 1;
 150}
 151
 152/* Find the TLB entry corresponding to the mmu_idx + address pair.  */
 153static inline CPUTLBEntry *tlb_entry(CPUArchState *env, uintptr_t mmu_idx,
 154                                     target_ulong addr)
 155{
 156    return &env->tlb_table[mmu_idx][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 the TLB contains a host virtual address suitable for direct RAM
 437 * access, then return it. Otherwise (TLB miss, TLB entry is for an
 438 * I/O access, etc) return NULL.
 439 *
 440 * This is the equivalent of the initial fast-path code used by
 441 * TCG backends for guest load and store accesses.
 442 */
 443static inline void *tlb_vaddr_to_host(CPUArchState *env, abi_ptr addr,
 444                                      int access_type, int mmu_idx)
 445{
 446#if defined(CONFIG_USER_ONLY)
 447    return g2h(addr);
 448#else
 449    CPUTLBEntry *tlbentry = tlb_entry(env, mmu_idx, addr);
 450    abi_ptr tlb_addr;
 451    uintptr_t haddr;
 452
 453    switch (access_type) {
 454    case 0:
 455        tlb_addr = tlbentry->addr_read;
 456        break;
 457    case 1:
 458        tlb_addr = tlb_addr_write(tlbentry);
 459        break;
 460    case 2:
 461        tlb_addr = tlbentry->addr_code;
 462        break;
 463    default:
 464        g_assert_not_reached();
 465    }
 466
 467    if (!tlb_hit(tlb_addr, addr)) {
 468        /* TLB entry is for a different page */
 469        return NULL;
 470    }
 471
 472    if (tlb_addr & ~TARGET_PAGE_MASK) {
 473        /* IO access */
 474        return NULL;
 475    }
 476
 477    haddr = addr + tlbentry->addend;
 478    return (void *)haddr;
 479#endif /* defined(CONFIG_USER_ONLY) */
 480}
 481
 482#endif /* CPU_LDST_H */
 483