qemu/target-sparc/ldst_helper.c
<<
>>
Prefs
   1/*
   2 * Helpers for loads and stores
   3 *
   4 *  Copyright (c) 2003-2005 Fabrice Bellard
   5 *
   6 * This library is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU Lesser General Public
   8 * License as published by the Free Software Foundation; either
   9 * version 2 of the License, or (at your option) any later version.
  10 *
  11 * This library is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14 * Lesser General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU Lesser General Public
  17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  18 */
  19
  20#include "cpu.h"
  21#include "exec/helper-proto.h"
  22#include "exec/cpu_ldst.h"
  23
  24//#define DEBUG_MMU
  25//#define DEBUG_MXCC
  26//#define DEBUG_UNALIGNED
  27//#define DEBUG_UNASSIGNED
  28//#define DEBUG_ASI
  29//#define DEBUG_CACHE_CONTROL
  30
  31#ifdef DEBUG_MMU
  32#define DPRINTF_MMU(fmt, ...)                                   \
  33    do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0)
  34#else
  35#define DPRINTF_MMU(fmt, ...) do {} while (0)
  36#endif
  37
  38#ifdef DEBUG_MXCC
  39#define DPRINTF_MXCC(fmt, ...)                                  \
  40    do { printf("MXCC: " fmt , ## __VA_ARGS__); } while (0)
  41#else
  42#define DPRINTF_MXCC(fmt, ...) do {} while (0)
  43#endif
  44
  45#ifdef DEBUG_ASI
  46#define DPRINTF_ASI(fmt, ...)                                   \
  47    do { printf("ASI: " fmt , ## __VA_ARGS__); } while (0)
  48#endif
  49
  50#ifdef DEBUG_CACHE_CONTROL
  51#define DPRINTF_CACHE_CONTROL(fmt, ...)                                 \
  52    do { printf("CACHE_CONTROL: " fmt , ## __VA_ARGS__); } while (0)
  53#else
  54#define DPRINTF_CACHE_CONTROL(fmt, ...) do {} while (0)
  55#endif
  56
  57#ifdef TARGET_SPARC64
  58#ifndef TARGET_ABI32
  59#define AM_CHECK(env1) ((env1)->pstate & PS_AM)
  60#else
  61#define AM_CHECK(env1) (1)
  62#endif
  63#endif
  64
  65#define QT0 (env->qt0)
  66#define QT1 (env->qt1)
  67
  68#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
  69/* Calculates TSB pointer value for fault page size 8k or 64k */
  70static uint64_t ultrasparc_tsb_pointer(uint64_t tsb_register,
  71                                       uint64_t tag_access_register,
  72                                       int page_size)
  73{
  74    uint64_t tsb_base = tsb_register & ~0x1fffULL;
  75    int tsb_split = (tsb_register & 0x1000ULL) ? 1 : 0;
  76    int tsb_size  = tsb_register & 0xf;
  77
  78    /* discard lower 13 bits which hold tag access context */
  79    uint64_t tag_access_va = tag_access_register & ~0x1fffULL;
  80
  81    /* now reorder bits */
  82    uint64_t tsb_base_mask = ~0x1fffULL;
  83    uint64_t va = tag_access_va;
  84
  85    /* move va bits to correct position */
  86    if (page_size == 8*1024) {
  87        va >>= 9;
  88    } else if (page_size == 64*1024) {
  89        va >>= 12;
  90    }
  91
  92    if (tsb_size) {
  93        tsb_base_mask <<= tsb_size;
  94    }
  95
  96    /* calculate tsb_base mask and adjust va if split is in use */
  97    if (tsb_split) {
  98        if (page_size == 8*1024) {
  99            va &= ~(1ULL << (13 + tsb_size));
 100        } else if (page_size == 64*1024) {
 101            va |= (1ULL << (13 + tsb_size));
 102        }
 103        tsb_base_mask <<= 1;
 104    }
 105
 106    return ((tsb_base & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL;
 107}
 108
 109/* Calculates tag target register value by reordering bits
 110   in tag access register */
 111static uint64_t ultrasparc_tag_target(uint64_t tag_access_register)
 112{
 113    return ((tag_access_register & 0x1fff) << 48) | (tag_access_register >> 22);
 114}
 115
 116static void replace_tlb_entry(SparcTLBEntry *tlb,
 117                              uint64_t tlb_tag, uint64_t tlb_tte,
 118                              CPUSPARCState *env1)
 119{
 120    target_ulong mask, size, va, offset;
 121
 122    /* flush page range if translation is valid */
 123    if (TTE_IS_VALID(tlb->tte)) {
 124        CPUState *cs = CPU(sparc_env_get_cpu(env1));
 125
 126        mask = 0xffffffffffffe000ULL;
 127        mask <<= 3 * ((tlb->tte >> 61) & 3);
 128        size = ~mask + 1;
 129
 130        va = tlb->tag & mask;
 131
 132        for (offset = 0; offset < size; offset += TARGET_PAGE_SIZE) {
 133            tlb_flush_page(cs, va + offset);
 134        }
 135    }
 136
 137    tlb->tag = tlb_tag;
 138    tlb->tte = tlb_tte;
 139}
 140
 141static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr,
 142                      const char *strmmu, CPUSPARCState *env1)
 143{
 144    unsigned int i;
 145    target_ulong mask;
 146    uint64_t context;
 147
 148    int is_demap_context = (demap_addr >> 6) & 1;
 149
 150    /* demap context */
 151    switch ((demap_addr >> 4) & 3) {
 152    case 0: /* primary */
 153        context = env1->dmmu.mmu_primary_context;
 154        break;
 155    case 1: /* secondary */
 156        context = env1->dmmu.mmu_secondary_context;
 157        break;
 158    case 2: /* nucleus */
 159        context = 0;
 160        break;
 161    case 3: /* reserved */
 162    default:
 163        return;
 164    }
 165
 166    for (i = 0; i < 64; i++) {
 167        if (TTE_IS_VALID(tlb[i].tte)) {
 168
 169            if (is_demap_context) {
 170                /* will remove non-global entries matching context value */
 171                if (TTE_IS_GLOBAL(tlb[i].tte) ||
 172                    !tlb_compare_context(&tlb[i], context)) {
 173                    continue;
 174                }
 175            } else {
 176                /* demap page
 177                   will remove any entry matching VA */
 178                mask = 0xffffffffffffe000ULL;
 179                mask <<= 3 * ((tlb[i].tte >> 61) & 3);
 180
 181                if (!compare_masked(demap_addr, tlb[i].tag, mask)) {
 182                    continue;
 183                }
 184
 185                /* entry should be global or matching context value */
 186                if (!TTE_IS_GLOBAL(tlb[i].tte) &&
 187                    !tlb_compare_context(&tlb[i], context)) {
 188                    continue;
 189                }
 190            }
 191
 192            replace_tlb_entry(&tlb[i], 0, 0, env1);
 193#ifdef DEBUG_MMU
 194            DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i);
 195            dump_mmu(stdout, fprintf, env1);
 196#endif
 197        }
 198    }
 199}
 200
 201static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
 202                                 uint64_t tlb_tag, uint64_t tlb_tte,
 203                                 const char *strmmu, CPUSPARCState *env1)
 204{
 205    unsigned int i, replace_used;
 206
 207    /* Try replacing invalid entry */
 208    for (i = 0; i < 64; i++) {
 209        if (!TTE_IS_VALID(tlb[i].tte)) {
 210            replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
 211#ifdef DEBUG_MMU
 212            DPRINTF_MMU("%s lru replaced invalid entry [%i]\n", strmmu, i);
 213            dump_mmu(stdout, fprintf, env1);
 214#endif
 215            return;
 216        }
 217    }
 218
 219    /* All entries are valid, try replacing unlocked entry */
 220
 221    for (replace_used = 0; replace_used < 2; ++replace_used) {
 222
 223        /* Used entries are not replaced on first pass */
 224
 225        for (i = 0; i < 64; i++) {
 226            if (!TTE_IS_LOCKED(tlb[i].tte) && !TTE_IS_USED(tlb[i].tte)) {
 227
 228                replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
 229#ifdef DEBUG_MMU
 230                DPRINTF_MMU("%s lru replaced unlocked %s entry [%i]\n",
 231                            strmmu, (replace_used ? "used" : "unused"), i);
 232                dump_mmu(stdout, fprintf, env1);
 233#endif
 234                return;
 235            }
 236        }
 237
 238        /* Now reset used bit and search for unused entries again */
 239
 240        for (i = 0; i < 64; i++) {
 241            TTE_SET_UNUSED(tlb[i].tte);
 242        }
 243    }
 244
 245#ifdef DEBUG_MMU
 246    DPRINTF_MMU("%s lru replacement failed: no entries available\n", strmmu);
 247#endif
 248    /* error state? */
 249}
 250
 251#endif
 252
 253#if defined(TARGET_SPARC64) || defined(CONFIG_USER_ONLY)
 254static inline target_ulong address_mask(CPUSPARCState *env1, target_ulong addr)
 255{
 256#ifdef TARGET_SPARC64
 257    if (AM_CHECK(env1)) {
 258        addr &= 0xffffffffULL;
 259    }
 260#endif
 261    return addr;
 262}
 263#endif
 264
 265#ifdef TARGET_SPARC64
 266/* returns true if access using this ASI is to have address translated by MMU
 267   otherwise access is to raw physical address */
 268/* TODO: check sparc32 bits */
 269static inline int is_translating_asi(int asi)
 270{
 271    /* Ultrasparc IIi translating asi
 272       - note this list is defined by cpu implementation
 273    */
 274    switch (asi) {
 275    case 0x04 ... 0x11:
 276    case 0x16 ... 0x19:
 277    case 0x1E ... 0x1F:
 278    case 0x24 ... 0x2C:
 279    case 0x70 ... 0x73:
 280    case 0x78 ... 0x79:
 281    case 0x80 ... 0xFF:
 282        return 1;
 283
 284    default:
 285        return 0;
 286    }
 287}
 288
 289static inline target_ulong asi_address_mask(CPUSPARCState *env,
 290                                            int asi, target_ulong addr)
 291{
 292    if (is_translating_asi(asi)) {
 293        return address_mask(env, addr);
 294    } else {
 295        return addr;
 296    }
 297}
 298#endif
 299
 300void helper_check_align(CPUSPARCState *env, target_ulong addr, uint32_t align)
 301{
 302    if (addr & align) {
 303#ifdef DEBUG_UNALIGNED
 304        printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
 305               "\n", addr, env->pc);
 306#endif
 307        helper_raise_exception(env, TT_UNALIGNED);
 308    }
 309}
 310
 311#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) &&   \
 312    defined(DEBUG_MXCC)
 313static void dump_mxcc(CPUSPARCState *env)
 314{
 315    printf("mxccdata: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
 316           "\n",
 317           env->mxccdata[0], env->mxccdata[1],
 318           env->mxccdata[2], env->mxccdata[3]);
 319    printf("mxccregs: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
 320           "\n"
 321           "          %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
 322           "\n",
 323           env->mxccregs[0], env->mxccregs[1],
 324           env->mxccregs[2], env->mxccregs[3],
 325           env->mxccregs[4], env->mxccregs[5],
 326           env->mxccregs[6], env->mxccregs[7]);
 327}
 328#endif
 329
 330#if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY))     \
 331    && defined(DEBUG_ASI)
 332static void dump_asi(const char *txt, target_ulong addr, int asi, int size,
 333                     uint64_t r1)
 334{
 335    switch (size) {
 336    case 1:
 337        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %02" PRIx64 "\n", txt,
 338                    addr, asi, r1 & 0xff);
 339        break;
 340    case 2:
 341        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %04" PRIx64 "\n", txt,
 342                    addr, asi, r1 & 0xffff);
 343        break;
 344    case 4:
 345        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %08" PRIx64 "\n", txt,
 346                    addr, asi, r1 & 0xffffffff);
 347        break;
 348    case 8:
 349        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %016" PRIx64 "\n", txt,
 350                    addr, asi, r1);
 351        break;
 352    }
 353}
 354#endif
 355
 356#ifndef TARGET_SPARC64
 357#ifndef CONFIG_USER_ONLY
 358
 359
 360/* Leon3 cache control */
 361
 362static void leon3_cache_control_st(CPUSPARCState *env, target_ulong addr,
 363                                   uint64_t val, int size)
 364{
 365    DPRINTF_CACHE_CONTROL("st addr:%08x, val:%" PRIx64 ", size:%d\n",
 366                          addr, val, size);
 367
 368    if (size != 4) {
 369        DPRINTF_CACHE_CONTROL("32bits only\n");
 370        return;
 371    }
 372
 373    switch (addr) {
 374    case 0x00:              /* Cache control */
 375
 376        /* These values must always be read as zeros */
 377        val &= ~CACHE_CTRL_FD;
 378        val &= ~CACHE_CTRL_FI;
 379        val &= ~CACHE_CTRL_IB;
 380        val &= ~CACHE_CTRL_IP;
 381        val &= ~CACHE_CTRL_DP;
 382
 383        env->cache_control = val;
 384        break;
 385    case 0x04:              /* Instruction cache configuration */
 386    case 0x08:              /* Data cache configuration */
 387        /* Read Only */
 388        break;
 389    default:
 390        DPRINTF_CACHE_CONTROL("write unknown register %08x\n", addr);
 391        break;
 392    };
 393}
 394
 395static uint64_t leon3_cache_control_ld(CPUSPARCState *env, target_ulong addr,
 396                                       int size)
 397{
 398    uint64_t ret = 0;
 399
 400    if (size != 4) {
 401        DPRINTF_CACHE_CONTROL("32bits only\n");
 402        return 0;
 403    }
 404
 405    switch (addr) {
 406    case 0x00:              /* Cache control */
 407        ret = env->cache_control;
 408        break;
 409
 410        /* Configuration registers are read and only always keep those
 411           predefined values */
 412
 413    case 0x04:              /* Instruction cache configuration */
 414        ret = 0x10220000;
 415        break;
 416    case 0x08:              /* Data cache configuration */
 417        ret = 0x18220000;
 418        break;
 419    default:
 420        DPRINTF_CACHE_CONTROL("read unknown register %08x\n", addr);
 421        break;
 422    };
 423    DPRINTF_CACHE_CONTROL("ld addr:%08x, ret:0x%" PRIx64 ", size:%d\n",
 424                          addr, ret, size);
 425    return ret;
 426}
 427
 428uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
 429                       int sign)
 430{
 431    CPUState *cs = CPU(sparc_env_get_cpu(env));
 432    uint64_t ret = 0;
 433#if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
 434    uint32_t last_addr = addr;
 435#endif
 436
 437    helper_check_align(env, addr, size - 1);
 438    switch (asi) {
 439    case 2: /* SuperSparc MXCC registers and Leon3 cache control */
 440        switch (addr) {
 441        case 0x00:          /* Leon3 Cache Control */
 442        case 0x08:          /* Leon3 Instruction Cache config */
 443        case 0x0C:          /* Leon3 Date Cache config */
 444            if (env->def->features & CPU_FEATURE_CACHE_CTRL) {
 445                ret = leon3_cache_control_ld(env, addr, size);
 446            }
 447            break;
 448        case 0x01c00a00: /* MXCC control register */
 449            if (size == 8) {
 450                ret = env->mxccregs[3];
 451            } else {
 452                qemu_log_mask(LOG_UNIMP,
 453                              "%08x: unimplemented access size: %d\n", addr,
 454                              size);
 455            }
 456            break;
 457        case 0x01c00a04: /* MXCC control register */
 458            if (size == 4) {
 459                ret = env->mxccregs[3];
 460            } else {
 461                qemu_log_mask(LOG_UNIMP,
 462                              "%08x: unimplemented access size: %d\n", addr,
 463                              size);
 464            }
 465            break;
 466        case 0x01c00c00: /* Module reset register */
 467            if (size == 8) {
 468                ret = env->mxccregs[5];
 469                /* should we do something here? */
 470            } else {
 471                qemu_log_mask(LOG_UNIMP,
 472                              "%08x: unimplemented access size: %d\n", addr,
 473                              size);
 474            }
 475            break;
 476        case 0x01c00f00: /* MBus port address register */
 477            if (size == 8) {
 478                ret = env->mxccregs[7];
 479            } else {
 480                qemu_log_mask(LOG_UNIMP,
 481                              "%08x: unimplemented access size: %d\n", addr,
 482                              size);
 483            }
 484            break;
 485        default:
 486            qemu_log_mask(LOG_UNIMP,
 487                          "%08x: unimplemented address, size: %d\n", addr,
 488                          size);
 489            break;
 490        }
 491        DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
 492                     "addr = %08x -> ret = %" PRIx64 ","
 493                     "addr = %08x\n", asi, size, sign, last_addr, ret, addr);
 494#ifdef DEBUG_MXCC
 495        dump_mxcc(env);
 496#endif
 497        break;
 498    case 3: /* MMU probe */
 499    case 0x18: /* LEON3 MMU probe */
 500        {
 501            int mmulev;
 502
 503            mmulev = (addr >> 8) & 15;
 504            if (mmulev > 4) {
 505                ret = 0;
 506            } else {
 507                ret = mmu_probe(env, addr, mmulev);
 508            }
 509            DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64 "\n",
 510                        addr, mmulev, ret);
 511        }
 512        break;
 513    case 4: /* read MMU regs */
 514    case 0x19: /* LEON3 read MMU regs */
 515        {
 516            int reg = (addr >> 8) & 0x1f;
 517
 518            ret = env->mmuregs[reg];
 519            if (reg == 3) { /* Fault status cleared on read */
 520                env->mmuregs[3] = 0;
 521            } else if (reg == 0x13) { /* Fault status read */
 522                ret = env->mmuregs[3];
 523            } else if (reg == 0x14) { /* Fault address read */
 524                ret = env->mmuregs[4];
 525            }
 526            DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret);
 527        }
 528        break;
 529    case 5: /* Turbosparc ITLB Diagnostic */
 530    case 6: /* Turbosparc DTLB Diagnostic */
 531    case 7: /* Turbosparc IOTLB Diagnostic */
 532        break;
 533    case 9: /* Supervisor code access */
 534        switch (size) {
 535        case 1:
 536            ret = cpu_ldub_code(env, addr);
 537            break;
 538        case 2:
 539            ret = cpu_lduw_code(env, addr);
 540            break;
 541        default:
 542        case 4:
 543            ret = cpu_ldl_code(env, addr);
 544            break;
 545        case 8:
 546            ret = cpu_ldq_code(env, addr);
 547            break;
 548        }
 549        break;
 550    case 0xa: /* User data access */
 551        switch (size) {
 552        case 1:
 553            ret = cpu_ldub_user(env, addr);
 554            break;
 555        case 2:
 556            ret = cpu_lduw_user(env, addr);
 557            break;
 558        default:
 559        case 4:
 560            ret = cpu_ldl_user(env, addr);
 561            break;
 562        case 8:
 563            ret = cpu_ldq_user(env, addr);
 564            break;
 565        }
 566        break;
 567    case 0xb: /* Supervisor data access */
 568    case 0x80:
 569        switch (size) {
 570        case 1:
 571            ret = cpu_ldub_kernel(env, addr);
 572            break;
 573        case 2:
 574            ret = cpu_lduw_kernel(env, addr);
 575            break;
 576        default:
 577        case 4:
 578            ret = cpu_ldl_kernel(env, addr);
 579            break;
 580        case 8:
 581            ret = cpu_ldq_kernel(env, addr);
 582            break;
 583        }
 584        break;
 585    case 0xc: /* I-cache tag */
 586    case 0xd: /* I-cache data */
 587    case 0xe: /* D-cache tag */
 588    case 0xf: /* D-cache data */
 589        break;
 590    case 0x20: /* MMU passthrough */
 591    case 0x1c: /* LEON MMU passthrough */
 592        switch (size) {
 593        case 1:
 594            ret = ldub_phys(cs->as, addr);
 595            break;
 596        case 2:
 597            ret = lduw_phys(cs->as, addr);
 598            break;
 599        default:
 600        case 4:
 601            ret = ldl_phys(cs->as, addr);
 602            break;
 603        case 8:
 604            ret = ldq_phys(cs->as, addr);
 605            break;
 606        }
 607        break;
 608    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
 609        switch (size) {
 610        case 1:
 611            ret = ldub_phys(cs->as, (hwaddr)addr
 612                            | ((hwaddr)(asi & 0xf) << 32));
 613            break;
 614        case 2:
 615            ret = lduw_phys(cs->as, (hwaddr)addr
 616                            | ((hwaddr)(asi & 0xf) << 32));
 617            break;
 618        default:
 619        case 4:
 620            ret = ldl_phys(cs->as, (hwaddr)addr
 621                           | ((hwaddr)(asi & 0xf) << 32));
 622            break;
 623        case 8:
 624            ret = ldq_phys(cs->as, (hwaddr)addr
 625                           | ((hwaddr)(asi & 0xf) << 32));
 626            break;
 627        }
 628        break;
 629    case 0x30: /* Turbosparc secondary cache diagnostic */
 630    case 0x31: /* Turbosparc RAM snoop */
 631    case 0x32: /* Turbosparc page table descriptor diagnostic */
 632    case 0x39: /* data cache diagnostic register */
 633        ret = 0;
 634        break;
 635    case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
 636        {
 637            int reg = (addr >> 8) & 3;
 638
 639            switch (reg) {
 640            case 0: /* Breakpoint Value (Addr) */
 641                ret = env->mmubpregs[reg];
 642                break;
 643            case 1: /* Breakpoint Mask */
 644                ret = env->mmubpregs[reg];
 645                break;
 646            case 2: /* Breakpoint Control */
 647                ret = env->mmubpregs[reg];
 648                break;
 649            case 3: /* Breakpoint Status */
 650                ret = env->mmubpregs[reg];
 651                env->mmubpregs[reg] = 0ULL;
 652                break;
 653            }
 654            DPRINTF_MMU("read breakpoint reg[%d] 0x%016" PRIx64 "\n", reg,
 655                        ret);
 656        }
 657        break;
 658    case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
 659        ret = env->mmubpctrv;
 660        break;
 661    case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
 662        ret = env->mmubpctrc;
 663        break;
 664    case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
 665        ret = env->mmubpctrs;
 666        break;
 667    case 0x4c: /* SuperSPARC MMU Breakpoint Action */
 668        ret = env->mmubpaction;
 669        break;
 670    case 8: /* User code access, XXX */
 671    default:
 672        cpu_unassigned_access(cs, addr, false, false, asi, size);
 673        ret = 0;
 674        break;
 675    }
 676    if (sign) {
 677        switch (size) {
 678        case 1:
 679            ret = (int8_t) ret;
 680            break;
 681        case 2:
 682            ret = (int16_t) ret;
 683            break;
 684        case 4:
 685            ret = (int32_t) ret;
 686            break;
 687        default:
 688            break;
 689        }
 690    }
 691#ifdef DEBUG_ASI
 692    dump_asi("read ", last_addr, asi, size, ret);
 693#endif
 694    return ret;
 695}
 696
 697void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val, int asi,
 698                   int size)
 699{
 700    SPARCCPU *cpu = sparc_env_get_cpu(env);
 701    CPUState *cs = CPU(cpu);
 702
 703    helper_check_align(env, addr, size - 1);
 704    switch (asi) {
 705    case 2: /* SuperSparc MXCC registers and Leon3 cache control */
 706        switch (addr) {
 707        case 0x00:          /* Leon3 Cache Control */
 708        case 0x08:          /* Leon3 Instruction Cache config */
 709        case 0x0C:          /* Leon3 Date Cache config */
 710            if (env->def->features & CPU_FEATURE_CACHE_CTRL) {
 711                leon3_cache_control_st(env, addr, val, size);
 712            }
 713            break;
 714
 715        case 0x01c00000: /* MXCC stream data register 0 */
 716            if (size == 8) {
 717                env->mxccdata[0] = val;
 718            } else {
 719                qemu_log_mask(LOG_UNIMP,
 720                              "%08x: unimplemented access size: %d\n", addr,
 721                              size);
 722            }
 723            break;
 724        case 0x01c00008: /* MXCC stream data register 1 */
 725            if (size == 8) {
 726                env->mxccdata[1] = val;
 727            } else {
 728                qemu_log_mask(LOG_UNIMP,
 729                              "%08x: unimplemented access size: %d\n", addr,
 730                              size);
 731            }
 732            break;
 733        case 0x01c00010: /* MXCC stream data register 2 */
 734            if (size == 8) {
 735                env->mxccdata[2] = val;
 736            } else {
 737                qemu_log_mask(LOG_UNIMP,
 738                              "%08x: unimplemented access size: %d\n", addr,
 739                              size);
 740            }
 741            break;
 742        case 0x01c00018: /* MXCC stream data register 3 */
 743            if (size == 8) {
 744                env->mxccdata[3] = val;
 745            } else {
 746                qemu_log_mask(LOG_UNIMP,
 747                              "%08x: unimplemented access size: %d\n", addr,
 748                              size);
 749            }
 750            break;
 751        case 0x01c00100: /* MXCC stream source */
 752            if (size == 8) {
 753                env->mxccregs[0] = val;
 754            } else {
 755                qemu_log_mask(LOG_UNIMP,
 756                              "%08x: unimplemented access size: %d\n", addr,
 757                              size);
 758            }
 759            env->mxccdata[0] = ldq_phys(cs->as,
 760                                        (env->mxccregs[0] & 0xffffffffULL) +
 761                                        0);
 762            env->mxccdata[1] = ldq_phys(cs->as,
 763                                        (env->mxccregs[0] & 0xffffffffULL) +
 764                                        8);
 765            env->mxccdata[2] = ldq_phys(cs->as,
 766                                        (env->mxccregs[0] & 0xffffffffULL) +
 767                                        16);
 768            env->mxccdata[3] = ldq_phys(cs->as,
 769                                        (env->mxccregs[0] & 0xffffffffULL) +
 770                                        24);
 771            break;
 772        case 0x01c00200: /* MXCC stream destination */
 773            if (size == 8) {
 774                env->mxccregs[1] = val;
 775            } else {
 776                qemu_log_mask(LOG_UNIMP,
 777                              "%08x: unimplemented access size: %d\n", addr,
 778                              size);
 779            }
 780            stq_phys(cs->as, (env->mxccregs[1] & 0xffffffffULL) +  0,
 781                     env->mxccdata[0]);
 782            stq_phys(cs->as, (env->mxccregs[1] & 0xffffffffULL) +  8,
 783                     env->mxccdata[1]);
 784            stq_phys(cs->as, (env->mxccregs[1] & 0xffffffffULL) + 16,
 785                     env->mxccdata[2]);
 786            stq_phys(cs->as, (env->mxccregs[1] & 0xffffffffULL) + 24,
 787                     env->mxccdata[3]);
 788            break;
 789        case 0x01c00a00: /* MXCC control register */
 790            if (size == 8) {
 791                env->mxccregs[3] = val;
 792            } else {
 793                qemu_log_mask(LOG_UNIMP,
 794                              "%08x: unimplemented access size: %d\n", addr,
 795                              size);
 796            }
 797            break;
 798        case 0x01c00a04: /* MXCC control register */
 799            if (size == 4) {
 800                env->mxccregs[3] = (env->mxccregs[3] & 0xffffffff00000000ULL)
 801                    | val;
 802            } else {
 803                qemu_log_mask(LOG_UNIMP,
 804                              "%08x: unimplemented access size: %d\n", addr,
 805                              size);
 806            }
 807            break;
 808        case 0x01c00e00: /* MXCC error register  */
 809            /* writing a 1 bit clears the error */
 810            if (size == 8) {
 811                env->mxccregs[6] &= ~val;
 812            } else {
 813                qemu_log_mask(LOG_UNIMP,
 814                              "%08x: unimplemented access size: %d\n", addr,
 815                              size);
 816            }
 817            break;
 818        case 0x01c00f00: /* MBus port address register */
 819            if (size == 8) {
 820                env->mxccregs[7] = val;
 821            } else {
 822                qemu_log_mask(LOG_UNIMP,
 823                              "%08x: unimplemented access size: %d\n", addr,
 824                              size);
 825            }
 826            break;
 827        default:
 828            qemu_log_mask(LOG_UNIMP,
 829                          "%08x: unimplemented address, size: %d\n", addr,
 830                          size);
 831            break;
 832        }
 833        DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64 "\n",
 834                     asi, size, addr, val);
 835#ifdef DEBUG_MXCC
 836        dump_mxcc(env);
 837#endif
 838        break;
 839    case 3: /* MMU flush */
 840    case 0x18: /* LEON3 MMU flush */
 841        {
 842            int mmulev;
 843
 844            mmulev = (addr >> 8) & 15;
 845            DPRINTF_MMU("mmu flush level %d\n", mmulev);
 846            switch (mmulev) {
 847            case 0: /* flush page */
 848                tlb_flush_page(CPU(cpu), addr & 0xfffff000);
 849                break;
 850            case 1: /* flush segment (256k) */
 851            case 2: /* flush region (16M) */
 852            case 3: /* flush context (4G) */
 853            case 4: /* flush entire */
 854                tlb_flush(CPU(cpu), 1);
 855                break;
 856            default:
 857                break;
 858            }
 859#ifdef DEBUG_MMU
 860            dump_mmu(stdout, fprintf, env);
 861#endif
 862        }
 863        break;
 864    case 4: /* write MMU regs */
 865    case 0x19: /* LEON3 write MMU regs */
 866        {
 867            int reg = (addr >> 8) & 0x1f;
 868            uint32_t oldreg;
 869
 870            oldreg = env->mmuregs[reg];
 871            switch (reg) {
 872            case 0: /* Control Register */
 873                env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
 874                    (val & 0x00ffffff);
 875                /* Mappings generated during no-fault mode or MMU
 876                   disabled mode are invalid in normal mode */
 877                if ((oldreg & (MMU_E | MMU_NF | env->def->mmu_bm)) !=
 878                    (env->mmuregs[reg] & (MMU_E | MMU_NF | env->def->mmu_bm))) {
 879                    tlb_flush(CPU(cpu), 1);
 880                }
 881                break;
 882            case 1: /* Context Table Pointer Register */
 883                env->mmuregs[reg] = val & env->def->mmu_ctpr_mask;
 884                break;
 885            case 2: /* Context Register */
 886                env->mmuregs[reg] = val & env->def->mmu_cxr_mask;
 887                if (oldreg != env->mmuregs[reg]) {
 888                    /* we flush when the MMU context changes because
 889                       QEMU has no MMU context support */
 890                    tlb_flush(CPU(cpu), 1);
 891                }
 892                break;
 893            case 3: /* Synchronous Fault Status Register with Clear */
 894            case 4: /* Synchronous Fault Address Register */
 895                break;
 896            case 0x10: /* TLB Replacement Control Register */
 897                env->mmuregs[reg] = val & env->def->mmu_trcr_mask;
 898                break;
 899            case 0x13: /* Synchronous Fault Status Register with Read
 900                          and Clear */
 901                env->mmuregs[3] = val & env->def->mmu_sfsr_mask;
 902                break;
 903            case 0x14: /* Synchronous Fault Address Register */
 904                env->mmuregs[4] = val;
 905                break;
 906            default:
 907                env->mmuregs[reg] = val;
 908                break;
 909            }
 910            if (oldreg != env->mmuregs[reg]) {
 911                DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n",
 912                            reg, oldreg, env->mmuregs[reg]);
 913            }
 914#ifdef DEBUG_MMU
 915            dump_mmu(stdout, fprintf, env);
 916#endif
 917        }
 918        break;
 919    case 5: /* Turbosparc ITLB Diagnostic */
 920    case 6: /* Turbosparc DTLB Diagnostic */
 921    case 7: /* Turbosparc IOTLB Diagnostic */
 922        break;
 923    case 0xa: /* User data access */
 924        switch (size) {
 925        case 1:
 926            cpu_stb_user(env, addr, val);
 927            break;
 928        case 2:
 929            cpu_stw_user(env, addr, val);
 930            break;
 931        default:
 932        case 4:
 933            cpu_stl_user(env, addr, val);
 934            break;
 935        case 8:
 936            cpu_stq_user(env, addr, val);
 937            break;
 938        }
 939        break;
 940    case 0xb: /* Supervisor data access */
 941    case 0x80:
 942        switch (size) {
 943        case 1:
 944            cpu_stb_kernel(env, addr, val);
 945            break;
 946        case 2:
 947            cpu_stw_kernel(env, addr, val);
 948            break;
 949        default:
 950        case 4:
 951            cpu_stl_kernel(env, addr, val);
 952            break;
 953        case 8:
 954            cpu_stq_kernel(env, addr, val);
 955            break;
 956        }
 957        break;
 958    case 0xc: /* I-cache tag */
 959    case 0xd: /* I-cache data */
 960    case 0xe: /* D-cache tag */
 961    case 0xf: /* D-cache data */
 962    case 0x10: /* I/D-cache flush page */
 963    case 0x11: /* I/D-cache flush segment */
 964    case 0x12: /* I/D-cache flush region */
 965    case 0x13: /* I/D-cache flush context */
 966    case 0x14: /* I/D-cache flush user */
 967        break;
 968    case 0x17: /* Block copy, sta access */
 969        {
 970            /* val = src
 971               addr = dst
 972               copy 32 bytes */
 973            unsigned int i;
 974            uint32_t src = val & ~3, dst = addr & ~3, temp;
 975
 976            for (i = 0; i < 32; i += 4, src += 4, dst += 4) {
 977                temp = cpu_ldl_kernel(env, src);
 978                cpu_stl_kernel(env, dst, temp);
 979            }
 980        }
 981        break;
 982    case 0x1f: /* Block fill, stda access */
 983        {
 984            /* addr = dst
 985               fill 32 bytes with val */
 986            unsigned int i;
 987            uint32_t dst = addr & 7;
 988
 989            for (i = 0; i < 32; i += 8, dst += 8) {
 990                cpu_stq_kernel(env, dst, val);
 991            }
 992        }
 993        break;
 994    case 0x20: /* MMU passthrough */
 995    case 0x1c: /* LEON MMU passthrough */
 996        {
 997            switch (size) {
 998            case 1:
 999                stb_phys(cs->as, addr, val);
1000                break;
1001            case 2:
1002                stw_phys(cs->as, addr, val);
1003                break;
1004            case 4:
1005            default:
1006                stl_phys(cs->as, addr, val);
1007                break;
1008            case 8:
1009                stq_phys(cs->as, addr, val);
1010                break;
1011            }
1012        }
1013        break;
1014    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
1015        {
1016            switch (size) {
1017            case 1:
1018                stb_phys(cs->as, (hwaddr)addr
1019                         | ((hwaddr)(asi & 0xf) << 32), val);
1020                break;
1021            case 2:
1022                stw_phys(cs->as, (hwaddr)addr
1023                         | ((hwaddr)(asi & 0xf) << 32), val);
1024                break;
1025            case 4:
1026            default:
1027                stl_phys(cs->as, (hwaddr)addr
1028                         | ((hwaddr)(asi & 0xf) << 32), val);
1029                break;
1030            case 8:
1031                stq_phys(cs->as, (hwaddr)addr
1032                         | ((hwaddr)(asi & 0xf) << 32), val);
1033                break;
1034            }
1035        }
1036        break;
1037    case 0x30: /* store buffer tags or Turbosparc secondary cache diagnostic */
1038    case 0x31: /* store buffer data, Ross RT620 I-cache flush or
1039                  Turbosparc snoop RAM */
1040    case 0x32: /* store buffer control or Turbosparc page table
1041                  descriptor diagnostic */
1042    case 0x36: /* I-cache flash clear */
1043    case 0x37: /* D-cache flash clear */
1044        break;
1045    case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
1046        {
1047            int reg = (addr >> 8) & 3;
1048
1049            switch (reg) {
1050            case 0: /* Breakpoint Value (Addr) */
1051                env->mmubpregs[reg] = (val & 0xfffffffffULL);
1052                break;
1053            case 1: /* Breakpoint Mask */
1054                env->mmubpregs[reg] = (val & 0xfffffffffULL);
1055                break;
1056            case 2: /* Breakpoint Control */
1057                env->mmubpregs[reg] = (val & 0x7fULL);
1058                break;
1059            case 3: /* Breakpoint Status */
1060                env->mmubpregs[reg] = (val & 0xfULL);
1061                break;
1062            }
1063            DPRINTF_MMU("write breakpoint reg[%d] 0x%016x\n", reg,
1064                        env->mmuregs[reg]);
1065        }
1066        break;
1067    case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
1068        env->mmubpctrv = val & 0xffffffff;
1069        break;
1070    case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
1071        env->mmubpctrc = val & 0x3;
1072        break;
1073    case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
1074        env->mmubpctrs = val & 0x3;
1075        break;
1076    case 0x4c: /* SuperSPARC MMU Breakpoint Action */
1077        env->mmubpaction = val & 0x1fff;
1078        break;
1079    case 8: /* User code access, XXX */
1080    case 9: /* Supervisor code access, XXX */
1081    default:
1082        cpu_unassigned_access(CPU(sparc_env_get_cpu(env)),
1083                              addr, true, false, asi, size);
1084        break;
1085    }
1086#ifdef DEBUG_ASI
1087    dump_asi("write", addr, asi, size, val);
1088#endif
1089}
1090
1091#endif /* CONFIG_USER_ONLY */
1092#else /* TARGET_SPARC64 */
1093
1094#ifdef CONFIG_USER_ONLY
1095uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
1096                       int sign)
1097{
1098    uint64_t ret = 0;
1099#if defined(DEBUG_ASI)
1100    target_ulong last_addr = addr;
1101#endif
1102
1103    if (asi < 0x80) {
1104        helper_raise_exception(env, TT_PRIV_ACT);
1105    }
1106
1107    helper_check_align(env, addr, size - 1);
1108    addr = asi_address_mask(env, asi, addr);
1109
1110    switch (asi) {
1111    case 0x82: /* Primary no-fault */
1112    case 0x8a: /* Primary no-fault LE */
1113        if (page_check_range(addr, size, PAGE_READ) == -1) {
1114#ifdef DEBUG_ASI
1115            dump_asi("read ", last_addr, asi, size, ret);
1116#endif
1117            return 0;
1118        }
1119        /* Fall through */
1120    case 0x80: /* Primary */
1121    case 0x88: /* Primary LE */
1122        {
1123            switch (size) {
1124            case 1:
1125                ret = cpu_ldub_data(env, addr);
1126                break;
1127            case 2:
1128                ret = cpu_lduw_data(env, addr);
1129                break;
1130            case 4:
1131                ret = cpu_ldl_data(env, addr);
1132                break;
1133            default:
1134            case 8:
1135                ret = cpu_ldq_data(env, addr);
1136                break;
1137            }
1138        }
1139        break;
1140    case 0x83: /* Secondary no-fault */
1141    case 0x8b: /* Secondary no-fault LE */
1142        if (page_check_range(addr, size, PAGE_READ) == -1) {
1143#ifdef DEBUG_ASI
1144            dump_asi("read ", last_addr, asi, size, ret);
1145#endif
1146            return 0;
1147        }
1148        /* Fall through */
1149    case 0x81: /* Secondary */
1150    case 0x89: /* Secondary LE */
1151        /* XXX */
1152        break;
1153    default:
1154        break;
1155    }
1156
1157    /* Convert from little endian */
1158    switch (asi) {
1159    case 0x88: /* Primary LE */
1160    case 0x89: /* Secondary LE */
1161    case 0x8a: /* Primary no-fault LE */
1162    case 0x8b: /* Secondary no-fault LE */
1163        switch (size) {
1164        case 2:
1165            ret = bswap16(ret);
1166            break;
1167        case 4:
1168            ret = bswap32(ret);
1169            break;
1170        case 8:
1171            ret = bswap64(ret);
1172            break;
1173        default:
1174            break;
1175        }
1176    default:
1177        break;
1178    }
1179
1180    /* Convert to signed number */
1181    if (sign) {
1182        switch (size) {
1183        case 1:
1184            ret = (int8_t) ret;
1185            break;
1186        case 2:
1187            ret = (int16_t) ret;
1188            break;
1189        case 4:
1190            ret = (int32_t) ret;
1191            break;
1192        default:
1193            break;
1194        }
1195    }
1196#ifdef DEBUG_ASI
1197    dump_asi("read ", last_addr, asi, size, ret);
1198#endif
1199    return ret;
1200}
1201
1202void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
1203                   int asi, int size)
1204{
1205#ifdef DEBUG_ASI
1206    dump_asi("write", addr, asi, size, val);
1207#endif
1208    if (asi < 0x80) {
1209        helper_raise_exception(env, TT_PRIV_ACT);
1210    }
1211
1212    helper_check_align(env, addr, size - 1);
1213    addr = asi_address_mask(env, asi, addr);
1214
1215    /* Convert to little endian */
1216    switch (asi) {
1217    case 0x88: /* Primary LE */
1218    case 0x89: /* Secondary LE */
1219        switch (size) {
1220        case 2:
1221            val = bswap16(val);
1222            break;
1223        case 4:
1224            val = bswap32(val);
1225            break;
1226        case 8:
1227            val = bswap64(val);
1228            break;
1229        default:
1230            break;
1231        }
1232    default:
1233        break;
1234    }
1235
1236    switch (asi) {
1237    case 0x80: /* Primary */
1238    case 0x88: /* Primary LE */
1239        {
1240            switch (size) {
1241            case 1:
1242                cpu_stb_data(env, addr, val);
1243                break;
1244            case 2:
1245                cpu_stw_data(env, addr, val);
1246                break;
1247            case 4:
1248                cpu_stl_data(env, addr, val);
1249                break;
1250            case 8:
1251            default:
1252                cpu_stq_data(env, addr, val);
1253                break;
1254            }
1255        }
1256        break;
1257    case 0x81: /* Secondary */
1258    case 0x89: /* Secondary LE */
1259        /* XXX */
1260        return;
1261
1262    case 0x82: /* Primary no-fault, RO */
1263    case 0x83: /* Secondary no-fault, RO */
1264    case 0x8a: /* Primary no-fault LE, RO */
1265    case 0x8b: /* Secondary no-fault LE, RO */
1266    default:
1267        helper_raise_exception(env, TT_DATA_ACCESS);
1268        return;
1269    }
1270}
1271
1272#else /* CONFIG_USER_ONLY */
1273
1274uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
1275                       int sign)
1276{
1277    CPUState *cs = CPU(sparc_env_get_cpu(env));
1278    uint64_t ret = 0;
1279#if defined(DEBUG_ASI)
1280    target_ulong last_addr = addr;
1281#endif
1282
1283    asi &= 0xff;
1284
1285    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1286        || (cpu_has_hypervisor(env)
1287            && asi >= 0x30 && asi < 0x80
1288            && !(env->hpstate & HS_PRIV))) {
1289        helper_raise_exception(env, TT_PRIV_ACT);
1290    }
1291
1292    helper_check_align(env, addr, size - 1);
1293    addr = asi_address_mask(env, asi, addr);
1294
1295    /* process nonfaulting loads first */
1296    if ((asi & 0xf6) == 0x82) {
1297        int mmu_idx;
1298
1299        /* secondary space access has lowest asi bit equal to 1 */
1300        if (env->pstate & PS_PRIV) {
1301            mmu_idx = (asi & 1) ? MMU_KERNEL_SECONDARY_IDX : MMU_KERNEL_IDX;
1302        } else {
1303            mmu_idx = (asi & 1) ? MMU_USER_SECONDARY_IDX : MMU_USER_IDX;
1304        }
1305
1306        if (cpu_get_phys_page_nofault(env, addr, mmu_idx) == -1ULL) {
1307#ifdef DEBUG_ASI
1308            dump_asi("read ", last_addr, asi, size, ret);
1309#endif
1310            /* env->exception_index is set in get_physical_address_data(). */
1311            helper_raise_exception(env, cs->exception_index);
1312        }
1313
1314        /* convert nonfaulting load ASIs to normal load ASIs */
1315        asi &= ~0x02;
1316    }
1317
1318    switch (asi) {
1319    case 0x10: /* As if user primary */
1320    case 0x11: /* As if user secondary */
1321    case 0x18: /* As if user primary LE */
1322    case 0x19: /* As if user secondary LE */
1323    case 0x80: /* Primary */
1324    case 0x81: /* Secondary */
1325    case 0x88: /* Primary LE */
1326    case 0x89: /* Secondary LE */
1327    case 0xe2: /* UA2007 Primary block init */
1328    case 0xe3: /* UA2007 Secondary block init */
1329        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1330            if (cpu_hypervisor_mode(env)) {
1331                switch (size) {
1332                case 1:
1333                    ret = cpu_ldub_hypv(env, addr);
1334                    break;
1335                case 2:
1336                    ret = cpu_lduw_hypv(env, addr);
1337                    break;
1338                case 4:
1339                    ret = cpu_ldl_hypv(env, addr);
1340                    break;
1341                default:
1342                case 8:
1343                    ret = cpu_ldq_hypv(env, addr);
1344                    break;
1345                }
1346            } else {
1347                /* secondary space access has lowest asi bit equal to 1 */
1348                if (asi & 1) {
1349                    switch (size) {
1350                    case 1:
1351                        ret = cpu_ldub_kernel_secondary(env, addr);
1352                        break;
1353                    case 2:
1354                        ret = cpu_lduw_kernel_secondary(env, addr);
1355                        break;
1356                    case 4:
1357                        ret = cpu_ldl_kernel_secondary(env, addr);
1358                        break;
1359                    default:
1360                    case 8:
1361                        ret = cpu_ldq_kernel_secondary(env, addr);
1362                        break;
1363                    }
1364                } else {
1365                    switch (size) {
1366                    case 1:
1367                        ret = cpu_ldub_kernel(env, addr);
1368                        break;
1369                    case 2:
1370                        ret = cpu_lduw_kernel(env, addr);
1371                        break;
1372                    case 4:
1373                        ret = cpu_ldl_kernel(env, addr);
1374                        break;
1375                    default:
1376                    case 8:
1377                        ret = cpu_ldq_kernel(env, addr);
1378                        break;
1379                    }
1380                }
1381            }
1382        } else {
1383            /* secondary space access has lowest asi bit equal to 1 */
1384            if (asi & 1) {
1385                switch (size) {
1386                case 1:
1387                    ret = cpu_ldub_user_secondary(env, addr);
1388                    break;
1389                case 2:
1390                    ret = cpu_lduw_user_secondary(env, addr);
1391                    break;
1392                case 4:
1393                    ret = cpu_ldl_user_secondary(env, addr);
1394                    break;
1395                default:
1396                case 8:
1397                    ret = cpu_ldq_user_secondary(env, addr);
1398                    break;
1399                }
1400            } else {
1401                switch (size) {
1402                case 1:
1403                    ret = cpu_ldub_user(env, addr);
1404                    break;
1405                case 2:
1406                    ret = cpu_lduw_user(env, addr);
1407                    break;
1408                case 4:
1409                    ret = cpu_ldl_user(env, addr);
1410                    break;
1411                default:
1412                case 8:
1413                    ret = cpu_ldq_user(env, addr);
1414                    break;
1415                }
1416            }
1417        }
1418        break;
1419    case 0x14: /* Bypass */
1420    case 0x15: /* Bypass, non-cacheable */
1421    case 0x1c: /* Bypass LE */
1422    case 0x1d: /* Bypass, non-cacheable LE */
1423        {
1424            switch (size) {
1425            case 1:
1426                ret = ldub_phys(cs->as, addr);
1427                break;
1428            case 2:
1429                ret = lduw_phys(cs->as, addr);
1430                break;
1431            case 4:
1432                ret = ldl_phys(cs->as, addr);
1433                break;
1434            default:
1435            case 8:
1436                ret = ldq_phys(cs->as, addr);
1437                break;
1438            }
1439            break;
1440        }
1441    case 0x24: /* Nucleus quad LDD 128 bit atomic */
1442    case 0x2c: /* Nucleus quad LDD 128 bit atomic LE
1443                  Only ldda allowed */
1444        helper_raise_exception(env, TT_ILL_INSN);
1445        return 0;
1446    case 0x04: /* Nucleus */
1447    case 0x0c: /* Nucleus Little Endian (LE) */
1448        {
1449            switch (size) {
1450            case 1:
1451                ret = cpu_ldub_nucleus(env, addr);
1452                break;
1453            case 2:
1454                ret = cpu_lduw_nucleus(env, addr);
1455                break;
1456            case 4:
1457                ret = cpu_ldl_nucleus(env, addr);
1458                break;
1459            default:
1460            case 8:
1461                ret = cpu_ldq_nucleus(env, addr);
1462                break;
1463            }
1464            break;
1465        }
1466    case 0x4a: /* UPA config */
1467        /* XXX */
1468        break;
1469    case 0x45: /* LSU */
1470        ret = env->lsu;
1471        break;
1472    case 0x50: /* I-MMU regs */
1473        {
1474            int reg = (addr >> 3) & 0xf;
1475
1476            if (reg == 0) {
1477                /* I-TSB Tag Target register */
1478                ret = ultrasparc_tag_target(env->immu.tag_access);
1479            } else {
1480                ret = env->immuregs[reg];
1481            }
1482
1483            break;
1484        }
1485    case 0x51: /* I-MMU 8k TSB pointer */
1486        {
1487            /* env->immuregs[5] holds I-MMU TSB register value
1488               env->immuregs[6] holds I-MMU Tag Access register value */
1489            ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access,
1490                                         8*1024);
1491            break;
1492        }
1493    case 0x52: /* I-MMU 64k TSB pointer */
1494        {
1495            /* env->immuregs[5] holds I-MMU TSB register value
1496               env->immuregs[6] holds I-MMU Tag Access register value */
1497            ret = ultrasparc_tsb_pointer(env->immu.tsb, env->immu.tag_access,
1498                                         64*1024);
1499            break;
1500        }
1501    case 0x55: /* I-MMU data access */
1502        {
1503            int reg = (addr >> 3) & 0x3f;
1504
1505            ret = env->itlb[reg].tte;
1506            break;
1507        }
1508    case 0x56: /* I-MMU tag read */
1509        {
1510            int reg = (addr >> 3) & 0x3f;
1511
1512            ret = env->itlb[reg].tag;
1513            break;
1514        }
1515    case 0x58: /* D-MMU regs */
1516        {
1517            int reg = (addr >> 3) & 0xf;
1518
1519            if (reg == 0) {
1520                /* D-TSB Tag Target register */
1521                ret = ultrasparc_tag_target(env->dmmu.tag_access);
1522            } else {
1523                ret = env->dmmuregs[reg];
1524            }
1525            break;
1526        }
1527    case 0x59: /* D-MMU 8k TSB pointer */
1528        {
1529            /* env->dmmuregs[5] holds D-MMU TSB register value
1530               env->dmmuregs[6] holds D-MMU Tag Access register value */
1531            ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access,
1532                                         8*1024);
1533            break;
1534        }
1535    case 0x5a: /* D-MMU 64k TSB pointer */
1536        {
1537            /* env->dmmuregs[5] holds D-MMU TSB register value
1538               env->dmmuregs[6] holds D-MMU Tag Access register value */
1539            ret = ultrasparc_tsb_pointer(env->dmmu.tsb, env->dmmu.tag_access,
1540                                         64*1024);
1541            break;
1542        }
1543    case 0x5d: /* D-MMU data access */
1544        {
1545            int reg = (addr >> 3) & 0x3f;
1546
1547            ret = env->dtlb[reg].tte;
1548            break;
1549        }
1550    case 0x5e: /* D-MMU tag read */
1551        {
1552            int reg = (addr >> 3) & 0x3f;
1553
1554            ret = env->dtlb[reg].tag;
1555            break;
1556        }
1557    case 0x48: /* Interrupt dispatch, RO */
1558        break;
1559    case 0x49: /* Interrupt data receive */
1560        ret = env->ivec_status;
1561        break;
1562    case 0x7f: /* Incoming interrupt vector, RO */
1563        {
1564            int reg = (addr >> 4) & 0x3;
1565            if (reg < 3) {
1566                ret = env->ivec_data[reg];
1567            }
1568            break;
1569        }
1570    case 0x46: /* D-cache data */
1571    case 0x47: /* D-cache tag access */
1572    case 0x4b: /* E-cache error enable */
1573    case 0x4c: /* E-cache asynchronous fault status */
1574    case 0x4d: /* E-cache asynchronous fault address */
1575    case 0x4e: /* E-cache tag data */
1576    case 0x66: /* I-cache instruction access */
1577    case 0x67: /* I-cache tag access */
1578    case 0x6e: /* I-cache predecode */
1579    case 0x6f: /* I-cache LRU etc. */
1580    case 0x76: /* E-cache tag */
1581    case 0x7e: /* E-cache tag */
1582        break;
1583    case 0x5b: /* D-MMU data pointer */
1584    case 0x54: /* I-MMU data in, WO */
1585    case 0x57: /* I-MMU demap, WO */
1586    case 0x5c: /* D-MMU data in, WO */
1587    case 0x5f: /* D-MMU demap, WO */
1588    case 0x77: /* Interrupt vector, WO */
1589    default:
1590        cpu_unassigned_access(cs, addr, false, false, 1, size);
1591        ret = 0;
1592        break;
1593    }
1594
1595    /* Convert from little endian */
1596    switch (asi) {
1597    case 0x0c: /* Nucleus Little Endian (LE) */
1598    case 0x18: /* As if user primary LE */
1599    case 0x19: /* As if user secondary LE */
1600    case 0x1c: /* Bypass LE */
1601    case 0x1d: /* Bypass, non-cacheable LE */
1602    case 0x88: /* Primary LE */
1603    case 0x89: /* Secondary LE */
1604        switch(size) {
1605        case 2:
1606            ret = bswap16(ret);
1607            break;
1608        case 4:
1609            ret = bswap32(ret);
1610            break;
1611        case 8:
1612            ret = bswap64(ret);
1613            break;
1614        default:
1615            break;
1616        }
1617    default:
1618        break;
1619    }
1620
1621    /* Convert to signed number */
1622    if (sign) {
1623        switch (size) {
1624        case 1:
1625            ret = (int8_t) ret;
1626            break;
1627        case 2:
1628            ret = (int16_t) ret;
1629            break;
1630        case 4:
1631            ret = (int32_t) ret;
1632            break;
1633        default:
1634            break;
1635        }
1636    }
1637#ifdef DEBUG_ASI
1638    dump_asi("read ", last_addr, asi, size, ret);
1639#endif
1640    return ret;
1641}
1642
1643void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
1644                   int asi, int size)
1645{
1646    SPARCCPU *cpu = sparc_env_get_cpu(env);
1647    CPUState *cs = CPU(cpu);
1648
1649#ifdef DEBUG_ASI
1650    dump_asi("write", addr, asi, size, val);
1651#endif
1652
1653    asi &= 0xff;
1654
1655    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
1656        || (cpu_has_hypervisor(env)
1657            && asi >= 0x30 && asi < 0x80
1658            && !(env->hpstate & HS_PRIV))) {
1659        helper_raise_exception(env, TT_PRIV_ACT);
1660    }
1661
1662    helper_check_align(env, addr, size - 1);
1663    addr = asi_address_mask(env, asi, addr);
1664
1665    /* Convert to little endian */
1666    switch (asi) {
1667    case 0x0c: /* Nucleus Little Endian (LE) */
1668    case 0x18: /* As if user primary LE */
1669    case 0x19: /* As if user secondary LE */
1670    case 0x1c: /* Bypass LE */
1671    case 0x1d: /* Bypass, non-cacheable LE */
1672    case 0x88: /* Primary LE */
1673    case 0x89: /* Secondary LE */
1674        switch (size) {
1675        case 2:
1676            val = bswap16(val);
1677            break;
1678        case 4:
1679            val = bswap32(val);
1680            break;
1681        case 8:
1682            val = bswap64(val);
1683            break;
1684        default:
1685            break;
1686        }
1687    default:
1688        break;
1689    }
1690
1691    switch (asi) {
1692    case 0x10: /* As if user primary */
1693    case 0x11: /* As if user secondary */
1694    case 0x18: /* As if user primary LE */
1695    case 0x19: /* As if user secondary LE */
1696    case 0x80: /* Primary */
1697    case 0x81: /* Secondary */
1698    case 0x88: /* Primary LE */
1699    case 0x89: /* Secondary LE */
1700    case 0xe2: /* UA2007 Primary block init */
1701    case 0xe3: /* UA2007 Secondary block init */
1702        if ((asi & 0x80) && (env->pstate & PS_PRIV)) {
1703            if (cpu_hypervisor_mode(env)) {
1704                switch (size) {
1705                case 1:
1706                    cpu_stb_hypv(env, addr, val);
1707                    break;
1708                case 2:
1709                    cpu_stw_hypv(env, addr, val);
1710                    break;
1711                case 4:
1712                    cpu_stl_hypv(env, addr, val);
1713                    break;
1714                case 8:
1715                default:
1716                    cpu_stq_hypv(env, addr, val);
1717                    break;
1718                }
1719            } else {
1720                /* secondary space access has lowest asi bit equal to 1 */
1721                if (asi & 1) {
1722                    switch (size) {
1723                    case 1:
1724                        cpu_stb_kernel_secondary(env, addr, val);
1725                        break;
1726                    case 2:
1727                        cpu_stw_kernel_secondary(env, addr, val);
1728                        break;
1729                    case 4:
1730                        cpu_stl_kernel_secondary(env, addr, val);
1731                        break;
1732                    case 8:
1733                    default:
1734                        cpu_stq_kernel_secondary(env, addr, val);
1735                        break;
1736                    }
1737                } else {
1738                    switch (size) {
1739                    case 1:
1740                        cpu_stb_kernel(env, addr, val);
1741                        break;
1742                    case 2:
1743                        cpu_stw_kernel(env, addr, val);
1744                        break;
1745                    case 4:
1746                        cpu_stl_kernel(env, addr, val);
1747                        break;
1748                    case 8:
1749                    default:
1750                        cpu_stq_kernel(env, addr, val);
1751                        break;
1752                    }
1753                }
1754            }
1755        } else {
1756            /* secondary space access has lowest asi bit equal to 1 */
1757            if (asi & 1) {
1758                switch (size) {
1759                case 1:
1760                    cpu_stb_user_secondary(env, addr, val);
1761                    break;
1762                case 2:
1763                    cpu_stw_user_secondary(env, addr, val);
1764                    break;
1765                case 4:
1766                    cpu_stl_user_secondary(env, addr, val);
1767                    break;
1768                case 8:
1769                default:
1770                    cpu_stq_user_secondary(env, addr, val);
1771                    break;
1772                }
1773            } else {
1774                switch (size) {
1775                case 1:
1776                    cpu_stb_user(env, addr, val);
1777                    break;
1778                case 2:
1779                    cpu_stw_user(env, addr, val);
1780                    break;
1781                case 4:
1782                    cpu_stl_user(env, addr, val);
1783                    break;
1784                case 8:
1785                default:
1786                    cpu_stq_user(env, addr, val);
1787                    break;
1788                }
1789            }
1790        }
1791        break;
1792    case 0x14: /* Bypass */
1793    case 0x15: /* Bypass, non-cacheable */
1794    case 0x1c: /* Bypass LE */
1795    case 0x1d: /* Bypass, non-cacheable LE */
1796        {
1797            switch (size) {
1798            case 1:
1799                stb_phys(cs->as, addr, val);
1800                break;
1801            case 2:
1802                stw_phys(cs->as, addr, val);
1803                break;
1804            case 4:
1805                stl_phys(cs->as, addr, val);
1806                break;
1807            case 8:
1808            default:
1809                stq_phys(cs->as, addr, val);
1810                break;
1811            }
1812        }
1813        return;
1814    case 0x24: /* Nucleus quad LDD 128 bit atomic */
1815    case 0x2c: /* Nucleus quad LDD 128 bit atomic LE
1816                  Only ldda allowed */
1817        helper_raise_exception(env, TT_ILL_INSN);
1818        return;
1819    case 0x04: /* Nucleus */
1820    case 0x0c: /* Nucleus Little Endian (LE) */
1821        {
1822            switch (size) {
1823            case 1:
1824                cpu_stb_nucleus(env, addr, val);
1825                break;
1826            case 2:
1827                cpu_stw_nucleus(env, addr, val);
1828                break;
1829            case 4:
1830                cpu_stl_nucleus(env, addr, val);
1831                break;
1832            default:
1833            case 8:
1834                cpu_stq_nucleus(env, addr, val);
1835                break;
1836            }
1837            break;
1838        }
1839
1840    case 0x4a: /* UPA config */
1841        /* XXX */
1842        return;
1843    case 0x45: /* LSU */
1844        {
1845            uint64_t oldreg;
1846
1847            oldreg = env->lsu;
1848            env->lsu = val & (DMMU_E | IMMU_E);
1849            /* Mappings generated during D/I MMU disabled mode are
1850               invalid in normal mode */
1851            if (oldreg != env->lsu) {
1852                DPRINTF_MMU("LSU change: 0x%" PRIx64 " -> 0x%" PRIx64 "\n",
1853                            oldreg, env->lsu);
1854#ifdef DEBUG_MMU
1855                dump_mmu(stdout, fprintf, env);
1856#endif
1857                tlb_flush(CPU(cpu), 1);
1858            }
1859            return;
1860        }
1861    case 0x50: /* I-MMU regs */
1862        {
1863            int reg = (addr >> 3) & 0xf;
1864            uint64_t oldreg;
1865
1866            oldreg = env->immuregs[reg];
1867            switch (reg) {
1868            case 0: /* RO */
1869                return;
1870            case 1: /* Not in I-MMU */
1871            case 2:
1872                return;
1873            case 3: /* SFSR */
1874                if ((val & 1) == 0) {
1875                    val = 0; /* Clear SFSR */
1876                }
1877                env->immu.sfsr = val;
1878                break;
1879            case 4: /* RO */
1880                return;
1881            case 5: /* TSB access */
1882                DPRINTF_MMU("immu TSB write: 0x%016" PRIx64 " -> 0x%016"
1883                            PRIx64 "\n", env->immu.tsb, val);
1884                env->immu.tsb = val;
1885                break;
1886            case 6: /* Tag access */
1887                env->immu.tag_access = val;
1888                break;
1889            case 7:
1890            case 8:
1891                return;
1892            default:
1893                break;
1894            }
1895
1896            if (oldreg != env->immuregs[reg]) {
1897                DPRINTF_MMU("immu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
1898                            PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
1899            }
1900#ifdef DEBUG_MMU
1901            dump_mmu(stdout, fprintf, env);
1902#endif
1903            return;
1904        }
1905    case 0x54: /* I-MMU data in */
1906        replace_tlb_1bit_lru(env->itlb, env->immu.tag_access, val, "immu", env);
1907        return;
1908    case 0x55: /* I-MMU data access */
1909        {
1910            /* TODO: auto demap */
1911
1912            unsigned int i = (addr >> 3) & 0x3f;
1913
1914            replace_tlb_entry(&env->itlb[i], env->immu.tag_access, val, env);
1915
1916#ifdef DEBUG_MMU
1917            DPRINTF_MMU("immu data access replaced entry [%i]\n", i);
1918            dump_mmu(stdout, fprintf, env);
1919#endif
1920            return;
1921        }
1922    case 0x57: /* I-MMU demap */
1923        demap_tlb(env->itlb, addr, "immu", env);
1924        return;
1925    case 0x58: /* D-MMU regs */
1926        {
1927            int reg = (addr >> 3) & 0xf;
1928            uint64_t oldreg;
1929
1930            oldreg = env->dmmuregs[reg];
1931            switch (reg) {
1932            case 0: /* RO */
1933            case 4:
1934                return;
1935            case 3: /* SFSR */
1936                if ((val & 1) == 0) {
1937                    val = 0; /* Clear SFSR, Fault address */
1938                    env->dmmu.sfar = 0;
1939                }
1940                env->dmmu.sfsr = val;
1941                break;
1942            case 1: /* Primary context */
1943                env->dmmu.mmu_primary_context = val;
1944                /* can be optimized to only flush MMU_USER_IDX
1945                   and MMU_KERNEL_IDX entries */
1946                tlb_flush(CPU(cpu), 1);
1947                break;
1948            case 2: /* Secondary context */
1949                env->dmmu.mmu_secondary_context = val;
1950                /* can be optimized to only flush MMU_USER_SECONDARY_IDX
1951                   and MMU_KERNEL_SECONDARY_IDX entries */
1952                tlb_flush(CPU(cpu), 1);
1953                break;
1954            case 5: /* TSB access */
1955                DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64 " -> 0x%016"
1956                            PRIx64 "\n", env->dmmu.tsb, val);
1957                env->dmmu.tsb = val;
1958                break;
1959            case 6: /* Tag access */
1960                env->dmmu.tag_access = val;
1961                break;
1962            case 7: /* Virtual Watchpoint */
1963            case 8: /* Physical Watchpoint */
1964            default:
1965                env->dmmuregs[reg] = val;
1966                break;
1967            }
1968
1969            if (oldreg != env->dmmuregs[reg]) {
1970                DPRINTF_MMU("dmmu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
1971                            PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
1972            }
1973#ifdef DEBUG_MMU
1974            dump_mmu(stdout, fprintf, env);
1975#endif
1976            return;
1977        }
1978    case 0x5c: /* D-MMU data in */
1979        replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access, val, "dmmu", env);
1980        return;
1981    case 0x5d: /* D-MMU data access */
1982        {
1983            unsigned int i = (addr >> 3) & 0x3f;
1984
1985            replace_tlb_entry(&env->dtlb[i], env->dmmu.tag_access, val, env);
1986
1987#ifdef DEBUG_MMU
1988            DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i);
1989            dump_mmu(stdout, fprintf, env);
1990#endif
1991            return;
1992        }
1993    case 0x5f: /* D-MMU demap */
1994        demap_tlb(env->dtlb, addr, "dmmu", env);
1995        return;
1996    case 0x49: /* Interrupt data receive */
1997        env->ivec_status = val & 0x20;
1998        return;
1999    case 0x46: /* D-cache data */
2000    case 0x47: /* D-cache tag access */
2001    case 0x4b: /* E-cache error enable */
2002    case 0x4c: /* E-cache asynchronous fault status */
2003    case 0x4d: /* E-cache asynchronous fault address */
2004    case 0x4e: /* E-cache tag data */
2005    case 0x66: /* I-cache instruction access */
2006    case 0x67: /* I-cache tag access */
2007    case 0x6e: /* I-cache predecode */
2008    case 0x6f: /* I-cache LRU etc. */
2009    case 0x76: /* E-cache tag */
2010    case 0x7e: /* E-cache tag */
2011        return;
2012    case 0x51: /* I-MMU 8k TSB pointer, RO */
2013    case 0x52: /* I-MMU 64k TSB pointer, RO */
2014    case 0x56: /* I-MMU tag read, RO */
2015    case 0x59: /* D-MMU 8k TSB pointer, RO */
2016    case 0x5a: /* D-MMU 64k TSB pointer, RO */
2017    case 0x5b: /* D-MMU data pointer, RO */
2018    case 0x5e: /* D-MMU tag read, RO */
2019    case 0x48: /* Interrupt dispatch, RO */
2020    case 0x7f: /* Incoming interrupt vector, RO */
2021    case 0x82: /* Primary no-fault, RO */
2022    case 0x83: /* Secondary no-fault, RO */
2023    case 0x8a: /* Primary no-fault LE, RO */
2024    case 0x8b: /* Secondary no-fault LE, RO */
2025    default:
2026        cpu_unassigned_access(cs, addr, true, false, 1, size);
2027        return;
2028    }
2029}
2030#endif /* CONFIG_USER_ONLY */
2031
2032void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi, int rd)
2033{
2034    if ((asi < 0x80 && (env->pstate & PS_PRIV) == 0)
2035        || (cpu_has_hypervisor(env)
2036            && asi >= 0x30 && asi < 0x80
2037            && !(env->hpstate & HS_PRIV))) {
2038        helper_raise_exception(env, TT_PRIV_ACT);
2039    }
2040
2041    addr = asi_address_mask(env, asi, addr);
2042
2043    switch (asi) {
2044#if !defined(CONFIG_USER_ONLY)
2045    case 0x24: /* Nucleus quad LDD 128 bit atomic */
2046    case 0x2c: /* Nucleus quad LDD 128 bit atomic LE */
2047        helper_check_align(env, addr, 0xf);
2048        if (rd == 0) {
2049            env->gregs[1] = cpu_ldq_nucleus(env, addr + 8);
2050            if (asi == 0x2c) {
2051                bswap64s(&env->gregs[1]);
2052            }
2053        } else if (rd < 8) {
2054            env->gregs[rd] = cpu_ldq_nucleus(env, addr);
2055            env->gregs[rd + 1] = cpu_ldq_nucleus(env, addr + 8);
2056            if (asi == 0x2c) {
2057                bswap64s(&env->gregs[rd]);
2058                bswap64s(&env->gregs[rd + 1]);
2059            }
2060        } else {
2061            env->regwptr[rd] = cpu_ldq_nucleus(env, addr);
2062            env->regwptr[rd + 1] = cpu_ldq_nucleus(env, addr + 8);
2063            if (asi == 0x2c) {
2064                bswap64s(&env->regwptr[rd]);
2065                bswap64s(&env->regwptr[rd + 1]);
2066            }
2067        }
2068        break;
2069#endif
2070    default:
2071        helper_check_align(env, addr, 0x3);
2072        if (rd == 0) {
2073            env->gregs[1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2074        } else if (rd < 8) {
2075            env->gregs[rd] = helper_ld_asi(env, addr, asi, 4, 0);
2076            env->gregs[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2077        } else {
2078            env->regwptr[rd] = helper_ld_asi(env, addr, asi, 4, 0);
2079            env->regwptr[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
2080        }
2081        break;
2082    }
2083}
2084
2085void helper_ldf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
2086                    int rd)
2087{
2088    unsigned int i;
2089    target_ulong val;
2090
2091    helper_check_align(env, addr, 3);
2092    addr = asi_address_mask(env, asi, addr);
2093
2094    switch (asi) {
2095    case 0xf0: /* UA2007/JPS1 Block load primary */
2096    case 0xf1: /* UA2007/JPS1 Block load secondary */
2097    case 0xf8: /* UA2007/JPS1 Block load primary LE */
2098    case 0xf9: /* UA2007/JPS1 Block load secondary LE */
2099        if (rd & 7) {
2100            helper_raise_exception(env, TT_ILL_INSN);
2101            return;
2102        }
2103        helper_check_align(env, addr, 0x3f);
2104        for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2105            env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x8f, 8, 0);
2106        }
2107        return;
2108
2109    case 0x16: /* UA2007 Block load primary, user privilege */
2110    case 0x17: /* UA2007 Block load secondary, user privilege */
2111    case 0x1e: /* UA2007 Block load primary LE, user privilege */
2112    case 0x1f: /* UA2007 Block load secondary LE, user privilege */
2113    case 0x70: /* JPS1 Block load primary, user privilege */
2114    case 0x71: /* JPS1 Block load secondary, user privilege */
2115    case 0x78: /* JPS1 Block load primary LE, user privilege */
2116    case 0x79: /* JPS1 Block load secondary LE, user privilege */
2117        if (rd & 7) {
2118            helper_raise_exception(env, TT_ILL_INSN);
2119            return;
2120        }
2121        helper_check_align(env, addr, 0x3f);
2122        for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2123            env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi & 0x19, 8, 0);
2124        }
2125        return;
2126
2127    default:
2128        break;
2129    }
2130
2131    switch (size) {
2132    default:
2133    case 4:
2134        val = helper_ld_asi(env, addr, asi, size, 0);
2135        if (rd & 1) {
2136            env->fpr[rd / 2].l.lower = val;
2137        } else {
2138            env->fpr[rd / 2].l.upper = val;
2139        }
2140        break;
2141    case 8:
2142        env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, size, 0);
2143        break;
2144    case 16:
2145        env->fpr[rd / 2].ll = helper_ld_asi(env, addr, asi, 8, 0);
2146        env->fpr[rd / 2 + 1].ll = helper_ld_asi(env, addr + 8, asi, 8, 0);
2147        break;
2148    }
2149}
2150
2151void helper_stf_asi(CPUSPARCState *env, target_ulong addr, int asi, int size,
2152                    int rd)
2153{
2154    unsigned int i;
2155    target_ulong val;
2156
2157    addr = asi_address_mask(env, asi, addr);
2158
2159    switch (asi) {
2160    case 0xe0: /* UA2007/JPS1 Block commit store primary (cache flush) */
2161    case 0xe1: /* UA2007/JPS1 Block commit store secondary (cache flush) */
2162    case 0xf0: /* UA2007/JPS1 Block store primary */
2163    case 0xf1: /* UA2007/JPS1 Block store secondary */
2164    case 0xf8: /* UA2007/JPS1 Block store primary LE */
2165    case 0xf9: /* UA2007/JPS1 Block store secondary LE */
2166        if (rd & 7) {
2167            helper_raise_exception(env, TT_ILL_INSN);
2168            return;
2169        }
2170        helper_check_align(env, addr, 0x3f);
2171        for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2172            helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x8f, 8);
2173        }
2174
2175        return;
2176    case 0x16: /* UA2007 Block load primary, user privilege */
2177    case 0x17: /* UA2007 Block load secondary, user privilege */
2178    case 0x1e: /* UA2007 Block load primary LE, user privilege */
2179    case 0x1f: /* UA2007 Block load secondary LE, user privilege */
2180    case 0x70: /* JPS1 Block store primary, user privilege */
2181    case 0x71: /* JPS1 Block store secondary, user privilege */
2182    case 0x78: /* JPS1 Block load primary LE, user privilege */
2183    case 0x79: /* JPS1 Block load secondary LE, user privilege */
2184        if (rd & 7) {
2185            helper_raise_exception(env, TT_ILL_INSN);
2186            return;
2187        }
2188        helper_check_align(env, addr, 0x3f);
2189        for (i = 0; i < 8; i++, rd += 2, addr += 8) {
2190            helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi & 0x19, 8);
2191        }
2192
2193        return;
2194    case 0xd2: /* 16-bit floating point load primary */
2195    case 0xd3: /* 16-bit floating point load secondary */
2196    case 0xda: /* 16-bit floating point load primary, LE */
2197    case 0xdb: /* 16-bit floating point load secondary, LE */
2198        helper_check_align(env, addr, 1);
2199        /* Fall through */
2200    case 0xd0: /* 8-bit floating point load primary */
2201    case 0xd1: /* 8-bit floating point load secondary */
2202    case 0xd8: /* 8-bit floating point load primary, LE */
2203    case 0xd9: /* 8-bit floating point load secondary, LE */
2204        val = env->fpr[rd / 2].l.lower;
2205        helper_st_asi(env, addr, val, asi & 0x8d, ((asi & 2) >> 1) + 1);
2206        return;
2207    default:
2208        helper_check_align(env, addr, 3);
2209        break;
2210    }
2211
2212    switch (size) {
2213    default:
2214    case 4:
2215        if (rd & 1) {
2216            val = env->fpr[rd / 2].l.lower;
2217        } else {
2218            val = env->fpr[rd / 2].l.upper;
2219        }
2220        helper_st_asi(env, addr, val, asi, size);
2221        break;
2222    case 8:
2223        helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi, size);
2224        break;
2225    case 16:
2226        helper_st_asi(env, addr, env->fpr[rd / 2].ll, asi, 8);
2227        helper_st_asi(env, addr + 8, env->fpr[rd / 2 + 1].ll, asi, 8);
2228        break;
2229    }
2230}
2231
2232target_ulong helper_casx_asi(CPUSPARCState *env, target_ulong addr,
2233                             target_ulong val1, target_ulong val2,
2234                             uint32_t asi)
2235{
2236    target_ulong ret;
2237
2238    ret = helper_ld_asi(env, addr, asi, 8, 0);
2239    if (val2 == ret) {
2240        helper_st_asi(env, addr, val1, asi, 8);
2241    }
2242    return ret;
2243}
2244#endif /* TARGET_SPARC64 */
2245
2246#if !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64)
2247target_ulong helper_cas_asi(CPUSPARCState *env, target_ulong addr,
2248                            target_ulong val1, target_ulong val2, uint32_t asi)
2249{
2250    target_ulong ret;
2251
2252    val2 &= 0xffffffffUL;
2253    ret = helper_ld_asi(env, addr, asi, 4, 0);
2254    ret &= 0xffffffffUL;
2255    if (val2 == ret) {
2256        helper_st_asi(env, addr, val1 & 0xffffffffUL, asi, 4);
2257    }
2258    return ret;
2259}
2260#endif /* !defined(CONFIG_USER_ONLY) || defined(TARGET_SPARC64) */
2261
2262void helper_ldqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
2263{
2264    /* XXX add 128 bit load */
2265    CPU_QuadU u;
2266
2267    helper_check_align(env, addr, 7);
2268#if !defined(CONFIG_USER_ONLY)
2269    switch (mem_idx) {
2270    case MMU_USER_IDX:
2271        u.ll.upper = cpu_ldq_user(env, addr);
2272        u.ll.lower = cpu_ldq_user(env, addr + 8);
2273        QT0 = u.q;
2274        break;
2275    case MMU_KERNEL_IDX:
2276        u.ll.upper = cpu_ldq_kernel(env, addr);
2277        u.ll.lower = cpu_ldq_kernel(env, addr + 8);
2278        QT0 = u.q;
2279        break;
2280#ifdef TARGET_SPARC64
2281    case MMU_HYPV_IDX:
2282        u.ll.upper = cpu_ldq_hypv(env, addr);
2283        u.ll.lower = cpu_ldq_hypv(env, addr + 8);
2284        QT0 = u.q;
2285        break;
2286#endif
2287    default:
2288        DPRINTF_MMU("helper_ldqf: need to check MMU idx %d\n", mem_idx);
2289        break;
2290    }
2291#else
2292    u.ll.upper = cpu_ldq_data(env, address_mask(env, addr));
2293    u.ll.lower = cpu_ldq_data(env, address_mask(env, addr + 8));
2294    QT0 = u.q;
2295#endif
2296}
2297
2298void helper_stqf(CPUSPARCState *env, target_ulong addr, int mem_idx)
2299{
2300    /* XXX add 128 bit store */
2301    CPU_QuadU u;
2302
2303    helper_check_align(env, addr, 7);
2304#if !defined(CONFIG_USER_ONLY)
2305    switch (mem_idx) {
2306    case MMU_USER_IDX:
2307        u.q = QT0;
2308        cpu_stq_user(env, addr, u.ll.upper);
2309        cpu_stq_user(env, addr + 8, u.ll.lower);
2310        break;
2311    case MMU_KERNEL_IDX:
2312        u.q = QT0;
2313        cpu_stq_kernel(env, addr, u.ll.upper);
2314        cpu_stq_kernel(env, addr + 8, u.ll.lower);
2315        break;
2316#ifdef TARGET_SPARC64
2317    case MMU_HYPV_IDX:
2318        u.q = QT0;
2319        cpu_stq_hypv(env, addr, u.ll.upper);
2320        cpu_stq_hypv(env, addr + 8, u.ll.lower);
2321        break;
2322#endif
2323    default:
2324        DPRINTF_MMU("helper_stqf: need to check MMU idx %d\n", mem_idx);
2325        break;
2326    }
2327#else
2328    u.q = QT0;
2329    cpu_stq_data(env, address_mask(env, addr), u.ll.upper);
2330    cpu_stq_data(env, address_mask(env, addr + 8), u.ll.lower);
2331#endif
2332}
2333
2334#if !defined(CONFIG_USER_ONLY)
2335#ifndef TARGET_SPARC64
2336void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
2337                                 bool is_write, bool is_exec, int is_asi,
2338                                 unsigned size)
2339{
2340    SPARCCPU *cpu = SPARC_CPU(cs);
2341    CPUSPARCState *env = &cpu->env;
2342    int fault_type;
2343
2344#ifdef DEBUG_UNASSIGNED
2345    if (is_asi) {
2346        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
2347               " asi 0x%02x from " TARGET_FMT_lx "\n",
2348               is_exec ? "exec" : is_write ? "write" : "read", size,
2349               size == 1 ? "" : "s", addr, is_asi, env->pc);
2350    } else {
2351        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
2352               " from " TARGET_FMT_lx "\n",
2353               is_exec ? "exec" : is_write ? "write" : "read", size,
2354               size == 1 ? "" : "s", addr, env->pc);
2355    }
2356#endif
2357    /* Don't overwrite translation and access faults */
2358    fault_type = (env->mmuregs[3] & 0x1c) >> 2;
2359    if ((fault_type > 4) || (fault_type == 0)) {
2360        env->mmuregs[3] = 0; /* Fault status register */
2361        if (is_asi) {
2362            env->mmuregs[3] |= 1 << 16;
2363        }
2364        if (env->psrs) {
2365            env->mmuregs[3] |= 1 << 5;
2366        }
2367        if (is_exec) {
2368            env->mmuregs[3] |= 1 << 6;
2369        }
2370        if (is_write) {
2371            env->mmuregs[3] |= 1 << 7;
2372        }
2373        env->mmuregs[3] |= (5 << 2) | 2;
2374        /* SuperSPARC will never place instruction fault addresses in the FAR */
2375        if (!is_exec) {
2376            env->mmuregs[4] = addr; /* Fault address register */
2377        }
2378    }
2379    /* overflow (same type fault was not read before another fault) */
2380    if (fault_type == ((env->mmuregs[3] & 0x1c)) >> 2) {
2381        env->mmuregs[3] |= 1;
2382    }
2383
2384    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
2385        if (is_exec) {
2386            helper_raise_exception(env, TT_CODE_ACCESS);
2387        } else {
2388            helper_raise_exception(env, TT_DATA_ACCESS);
2389        }
2390    }
2391
2392    /* flush neverland mappings created during no-fault mode,
2393       so the sequential MMU faults report proper fault types */
2394    if (env->mmuregs[0] & MMU_NF) {
2395        tlb_flush(cs, 1);
2396    }
2397}
2398#else
2399void sparc_cpu_unassigned_access(CPUState *cs, hwaddr addr,
2400                                 bool is_write, bool is_exec, int is_asi,
2401                                 unsigned size)
2402{
2403    SPARCCPU *cpu = SPARC_CPU(cs);
2404    CPUSPARCState *env = &cpu->env;
2405
2406#ifdef DEBUG_UNASSIGNED
2407    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
2408           "\n", addr, env->pc);
2409#endif
2410
2411    if (is_exec) {
2412        helper_raise_exception(env, TT_CODE_ACCESS);
2413    } else {
2414        helper_raise_exception(env, TT_DATA_ACCESS);
2415    }
2416}
2417#endif
2418#endif
2419
2420#if !defined(CONFIG_USER_ONLY)
2421void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cs,
2422                                                 vaddr addr, int is_write,
2423                                                 int is_user, uintptr_t retaddr)
2424{
2425    SPARCCPU *cpu = SPARC_CPU(cs);
2426    CPUSPARCState *env = &cpu->env;
2427
2428#ifdef DEBUG_UNALIGNED
2429    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
2430           "\n", addr, env->pc);
2431#endif
2432    if (retaddr) {
2433        cpu_restore_state(CPU(cpu), retaddr);
2434    }
2435    helper_raise_exception(env, TT_UNALIGNED);
2436}
2437
2438/* try to fill the TLB and return an exception if error. If retaddr is
2439   NULL, it means that the function was called in C code (i.e. not
2440   from generated code or from helper.c) */
2441/* XXX: fix it to restore all registers */
2442void tlb_fill(CPUState *cs, target_ulong addr, int is_write, int mmu_idx,
2443              uintptr_t retaddr)
2444{
2445    int ret;
2446
2447    ret = sparc_cpu_handle_mmu_fault(cs, addr, is_write, mmu_idx);
2448    if (ret) {
2449        if (retaddr) {
2450            cpu_restore_state(cs, retaddr);
2451        }
2452        cpu_loop_exit(cs);
2453    }
2454}
2455#endif
2456