cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

ldst_helper.c (66962B)


      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.1 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 "qemu/osdep.h"
     21#include "cpu.h"
     22#include "tcg/tcg.h"
     23#include "exec/helper-proto.h"
     24#include "exec/exec-all.h"
     25#include "exec/cpu_ldst.h"
     26#include "asi.h"
     27
     28//#define DEBUG_MMU
     29//#define DEBUG_MXCC
     30//#define DEBUG_UNALIGNED
     31//#define DEBUG_UNASSIGNED
     32//#define DEBUG_ASI
     33//#define DEBUG_CACHE_CONTROL
     34
     35#ifdef DEBUG_MMU
     36#define DPRINTF_MMU(fmt, ...)                                   \
     37    do { printf("MMU: " fmt , ## __VA_ARGS__); } while (0)
     38#else
     39#define DPRINTF_MMU(fmt, ...) do {} while (0)
     40#endif
     41
     42#ifdef DEBUG_MXCC
     43#define DPRINTF_MXCC(fmt, ...)                                  \
     44    do { printf("MXCC: " fmt , ## __VA_ARGS__); } while (0)
     45#else
     46#define DPRINTF_MXCC(fmt, ...) do {} while (0)
     47#endif
     48
     49#ifdef DEBUG_ASI
     50#define DPRINTF_ASI(fmt, ...)                                   \
     51    do { printf("ASI: " fmt , ## __VA_ARGS__); } while (0)
     52#endif
     53
     54#ifdef DEBUG_CACHE_CONTROL
     55#define DPRINTF_CACHE_CONTROL(fmt, ...)                                 \
     56    do { printf("CACHE_CONTROL: " fmt , ## __VA_ARGS__); } while (0)
     57#else
     58#define DPRINTF_CACHE_CONTROL(fmt, ...) do {} while (0)
     59#endif
     60
     61#ifdef TARGET_SPARC64
     62#ifndef TARGET_ABI32
     63#define AM_CHECK(env1) ((env1)->pstate & PS_AM)
     64#else
     65#define AM_CHECK(env1) (1)
     66#endif
     67#endif
     68
     69#define QT0 (env->qt0)
     70#define QT1 (env->qt1)
     71
     72#if defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY)
     73/* Calculates TSB pointer value for fault page size
     74 * UltraSPARC IIi has fixed sizes (8k or 64k) for the page pointers
     75 * UA2005 holds the page size configuration in mmu_ctx registers */
     76static uint64_t ultrasparc_tsb_pointer(CPUSPARCState *env,
     77                                       const SparcV9MMU *mmu, const int idx)
     78{
     79    uint64_t tsb_register;
     80    int page_size;
     81    if (cpu_has_hypervisor(env)) {
     82        int tsb_index = 0;
     83        int ctx = mmu->tag_access & 0x1fffULL;
     84        uint64_t ctx_register = mmu->sun4v_ctx_config[ctx ? 1 : 0];
     85        tsb_index = idx;
     86        tsb_index |= ctx ? 2 : 0;
     87        page_size = idx ? ctx_register >> 8 : ctx_register;
     88        page_size &= 7;
     89        tsb_register = mmu->sun4v_tsb_pointers[tsb_index];
     90    } else {
     91        page_size = idx;
     92        tsb_register = mmu->tsb;
     93    }
     94    int tsb_split = (tsb_register & 0x1000ULL) ? 1 : 0;
     95    int tsb_size  = tsb_register & 0xf;
     96
     97    uint64_t tsb_base_mask = (~0x1fffULL) << tsb_size;
     98
     99    /* move va bits to correct position,
    100     * the context bits will be masked out later */
    101    uint64_t va = mmu->tag_access >> (3 * page_size + 9);
    102
    103    /* calculate tsb_base mask and adjust va if split is in use */
    104    if (tsb_split) {
    105        if (idx == 0) {
    106            va &= ~(1ULL << (13 + tsb_size));
    107        } else {
    108            va |= (1ULL << (13 + tsb_size));
    109        }
    110        tsb_base_mask <<= 1;
    111    }
    112
    113    return ((tsb_register & tsb_base_mask) | (va & ~tsb_base_mask)) & ~0xfULL;
    114}
    115
    116/* Calculates tag target register value by reordering bits
    117   in tag access register */
    118static uint64_t ultrasparc_tag_target(uint64_t tag_access_register)
    119{
    120    return ((tag_access_register & 0x1fff) << 48) | (tag_access_register >> 22);
    121}
    122
    123static void replace_tlb_entry(SparcTLBEntry *tlb,
    124                              uint64_t tlb_tag, uint64_t tlb_tte,
    125                              CPUSPARCState *env)
    126{
    127    target_ulong mask, size, va, offset;
    128
    129    /* flush page range if translation is valid */
    130    if (TTE_IS_VALID(tlb->tte)) {
    131        CPUState *cs = env_cpu(env);
    132
    133        size = 8192ULL << 3 * TTE_PGSIZE(tlb->tte);
    134        mask = 1ULL + ~size;
    135
    136        va = tlb->tag & mask;
    137
    138        for (offset = 0; offset < size; offset += TARGET_PAGE_SIZE) {
    139            tlb_flush_page(cs, va + offset);
    140        }
    141    }
    142
    143    tlb->tag = tlb_tag;
    144    tlb->tte = tlb_tte;
    145}
    146
    147static void demap_tlb(SparcTLBEntry *tlb, target_ulong demap_addr,
    148                      const char *strmmu, CPUSPARCState *env1)
    149{
    150    unsigned int i;
    151    target_ulong mask;
    152    uint64_t context;
    153
    154    int is_demap_context = (demap_addr >> 6) & 1;
    155
    156    /* demap context */
    157    switch ((demap_addr >> 4) & 3) {
    158    case 0: /* primary */
    159        context = env1->dmmu.mmu_primary_context;
    160        break;
    161    case 1: /* secondary */
    162        context = env1->dmmu.mmu_secondary_context;
    163        break;
    164    case 2: /* nucleus */
    165        context = 0;
    166        break;
    167    case 3: /* reserved */
    168    default:
    169        return;
    170    }
    171
    172    for (i = 0; i < 64; i++) {
    173        if (TTE_IS_VALID(tlb[i].tte)) {
    174
    175            if (is_demap_context) {
    176                /* will remove non-global entries matching context value */
    177                if (TTE_IS_GLOBAL(tlb[i].tte) ||
    178                    !tlb_compare_context(&tlb[i], context)) {
    179                    continue;
    180                }
    181            } else {
    182                /* demap page
    183                   will remove any entry matching VA */
    184                mask = 0xffffffffffffe000ULL;
    185                mask <<= 3 * ((tlb[i].tte >> 61) & 3);
    186
    187                if (!compare_masked(demap_addr, tlb[i].tag, mask)) {
    188                    continue;
    189                }
    190
    191                /* entry should be global or matching context value */
    192                if (!TTE_IS_GLOBAL(tlb[i].tte) &&
    193                    !tlb_compare_context(&tlb[i], context)) {
    194                    continue;
    195                }
    196            }
    197
    198            replace_tlb_entry(&tlb[i], 0, 0, env1);
    199#ifdef DEBUG_MMU
    200            DPRINTF_MMU("%s demap invalidated entry [%02u]\n", strmmu, i);
    201            dump_mmu(env1);
    202#endif
    203        }
    204    }
    205}
    206
    207static uint64_t sun4v_tte_to_sun4u(CPUSPARCState *env, uint64_t tag,
    208                                   uint64_t sun4v_tte)
    209{
    210    uint64_t sun4u_tte;
    211    if (!(cpu_has_hypervisor(env) && (tag & TLB_UST1_IS_SUN4V_BIT))) {
    212        /* is already in the sun4u format */
    213        return sun4v_tte;
    214    }
    215    sun4u_tte = TTE_PA(sun4v_tte) | (sun4v_tte & TTE_VALID_BIT);
    216    sun4u_tte |= (sun4v_tte & 3ULL) << 61; /* TTE_PGSIZE */
    217    sun4u_tte |= CONVERT_BIT(sun4v_tte, TTE_NFO_BIT_UA2005, TTE_NFO_BIT);
    218    sun4u_tte |= CONVERT_BIT(sun4v_tte, TTE_USED_BIT_UA2005, TTE_USED_BIT);
    219    sun4u_tte |= CONVERT_BIT(sun4v_tte, TTE_W_OK_BIT_UA2005, TTE_W_OK_BIT);
    220    sun4u_tte |= CONVERT_BIT(sun4v_tte, TTE_SIDEEFFECT_BIT_UA2005,
    221                             TTE_SIDEEFFECT_BIT);
    222    sun4u_tte |= CONVERT_BIT(sun4v_tte, TTE_PRIV_BIT_UA2005, TTE_PRIV_BIT);
    223    sun4u_tte |= CONVERT_BIT(sun4v_tte, TTE_LOCKED_BIT_UA2005, TTE_LOCKED_BIT);
    224    return sun4u_tte;
    225}
    226
    227static void replace_tlb_1bit_lru(SparcTLBEntry *tlb,
    228                                 uint64_t tlb_tag, uint64_t tlb_tte,
    229                                 const char *strmmu, CPUSPARCState *env1,
    230                                 uint64_t addr)
    231{
    232    unsigned int i, replace_used;
    233
    234    tlb_tte = sun4v_tte_to_sun4u(env1, addr, tlb_tte);
    235    if (cpu_has_hypervisor(env1)) {
    236        uint64_t new_vaddr = tlb_tag & ~0x1fffULL;
    237        uint64_t new_size = 8192ULL << 3 * TTE_PGSIZE(tlb_tte);
    238        uint32_t new_ctx = tlb_tag & 0x1fffU;
    239        for (i = 0; i < 64; i++) {
    240            uint32_t ctx = tlb[i].tag & 0x1fffU;
    241            /* check if new mapping overlaps an existing one */
    242            if (new_ctx == ctx) {
    243                uint64_t vaddr = tlb[i].tag & ~0x1fffULL;
    244                uint64_t size = 8192ULL << 3 * TTE_PGSIZE(tlb[i].tte);
    245                if (new_vaddr == vaddr
    246                    || (new_vaddr < vaddr + size
    247                        && vaddr < new_vaddr + new_size)) {
    248                    DPRINTF_MMU("auto demap entry [%d] %lx->%lx\n", i, vaddr,
    249                                new_vaddr);
    250                    replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
    251                    return;
    252                }
    253            }
    254
    255        }
    256    }
    257    /* Try replacing invalid entry */
    258    for (i = 0; i < 64; i++) {
    259        if (!TTE_IS_VALID(tlb[i].tte)) {
    260            replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
    261#ifdef DEBUG_MMU
    262            DPRINTF_MMU("%s lru replaced invalid entry [%i]\n", strmmu, i);
    263            dump_mmu(env1);
    264#endif
    265            return;
    266        }
    267    }
    268
    269    /* All entries are valid, try replacing unlocked entry */
    270
    271    for (replace_used = 0; replace_used < 2; ++replace_used) {
    272
    273        /* Used entries are not replaced on first pass */
    274
    275        for (i = 0; i < 64; i++) {
    276            if (!TTE_IS_LOCKED(tlb[i].tte) && !TTE_IS_USED(tlb[i].tte)) {
    277
    278                replace_tlb_entry(&tlb[i], tlb_tag, tlb_tte, env1);
    279#ifdef DEBUG_MMU
    280                DPRINTF_MMU("%s lru replaced unlocked %s entry [%i]\n",
    281                            strmmu, (replace_used ? "used" : "unused"), i);
    282                dump_mmu(env1);
    283#endif
    284                return;
    285            }
    286        }
    287
    288        /* Now reset used bit and search for unused entries again */
    289
    290        for (i = 0; i < 64; i++) {
    291            TTE_SET_UNUSED(tlb[i].tte);
    292        }
    293    }
    294
    295#ifdef DEBUG_MMU
    296    DPRINTF_MMU("%s lru replacement: no free entries available, "
    297                "replacing the last one\n", strmmu);
    298#endif
    299    /* corner case: the last entry is replaced anyway */
    300    replace_tlb_entry(&tlb[63], tlb_tag, tlb_tte, env1);
    301}
    302
    303#endif
    304
    305#ifdef TARGET_SPARC64
    306/* returns true if access using this ASI is to have address translated by MMU
    307   otherwise access is to raw physical address */
    308/* TODO: check sparc32 bits */
    309static inline int is_translating_asi(int asi)
    310{
    311    /* Ultrasparc IIi translating asi
    312       - note this list is defined by cpu implementation
    313    */
    314    switch (asi) {
    315    case 0x04 ... 0x11:
    316    case 0x16 ... 0x19:
    317    case 0x1E ... 0x1F:
    318    case 0x24 ... 0x2C:
    319    case 0x70 ... 0x73:
    320    case 0x78 ... 0x79:
    321    case 0x80 ... 0xFF:
    322        return 1;
    323
    324    default:
    325        return 0;
    326    }
    327}
    328
    329static inline target_ulong address_mask(CPUSPARCState *env1, target_ulong addr)
    330{
    331    if (AM_CHECK(env1)) {
    332        addr &= 0xffffffffULL;
    333    }
    334    return addr;
    335}
    336
    337static inline target_ulong asi_address_mask(CPUSPARCState *env,
    338                                            int asi, target_ulong addr)
    339{
    340    if (is_translating_asi(asi)) {
    341        addr = address_mask(env, addr);
    342    }
    343    return addr;
    344}
    345
    346#ifndef CONFIG_USER_ONLY
    347static inline void do_check_asi(CPUSPARCState *env, int asi, uintptr_t ra)
    348{
    349    /* ASIs >= 0x80 are user mode.
    350     * ASIs >= 0x30 are hyper mode (or super if hyper is not available).
    351     * ASIs <= 0x2f are super mode.
    352     */
    353    if (asi < 0x80
    354        && !cpu_hypervisor_mode(env)
    355        && (!cpu_supervisor_mode(env)
    356            || (asi >= 0x30 && cpu_has_hypervisor(env)))) {
    357        cpu_raise_exception_ra(env, TT_PRIV_ACT, ra);
    358    }
    359}
    360#endif /* !CONFIG_USER_ONLY */
    361#endif
    362
    363static void do_check_align(CPUSPARCState *env, target_ulong addr,
    364                           uint32_t align, uintptr_t ra)
    365{
    366    if (addr & align) {
    367#ifdef DEBUG_UNALIGNED
    368        printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
    369               "\n", addr, env->pc);
    370#endif
    371        cpu_raise_exception_ra(env, TT_UNALIGNED, ra);
    372    }
    373}
    374
    375void helper_check_align(CPUSPARCState *env, target_ulong addr, uint32_t align)
    376{
    377    do_check_align(env, addr, align, GETPC());
    378}
    379
    380#if !defined(TARGET_SPARC64) && !defined(CONFIG_USER_ONLY) &&   \
    381    defined(DEBUG_MXCC)
    382static void dump_mxcc(CPUSPARCState *env)
    383{
    384    printf("mxccdata: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
    385           "\n",
    386           env->mxccdata[0], env->mxccdata[1],
    387           env->mxccdata[2], env->mxccdata[3]);
    388    printf("mxccregs: %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
    389           "\n"
    390           "          %016" PRIx64 " %016" PRIx64 " %016" PRIx64 " %016" PRIx64
    391           "\n",
    392           env->mxccregs[0], env->mxccregs[1],
    393           env->mxccregs[2], env->mxccregs[3],
    394           env->mxccregs[4], env->mxccregs[5],
    395           env->mxccregs[6], env->mxccregs[7]);
    396}
    397#endif
    398
    399#if (defined(TARGET_SPARC64) || !defined(CONFIG_USER_ONLY))     \
    400    && defined(DEBUG_ASI)
    401static void dump_asi(const char *txt, target_ulong addr, int asi, int size,
    402                     uint64_t r1)
    403{
    404    switch (size) {
    405    case 1:
    406        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %02" PRIx64 "\n", txt,
    407                    addr, asi, r1 & 0xff);
    408        break;
    409    case 2:
    410        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %04" PRIx64 "\n", txt,
    411                    addr, asi, r1 & 0xffff);
    412        break;
    413    case 4:
    414        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %08" PRIx64 "\n", txt,
    415                    addr, asi, r1 & 0xffffffff);
    416        break;
    417    case 8:
    418        DPRINTF_ASI("%s "TARGET_FMT_lx " asi 0x%02x = %016" PRIx64 "\n", txt,
    419                    addr, asi, r1);
    420        break;
    421    }
    422}
    423#endif
    424
    425#ifndef CONFIG_USER_ONLY
    426#ifndef TARGET_SPARC64
    427static void sparc_raise_mmu_fault(CPUState *cs, hwaddr addr,
    428                                  bool is_write, bool is_exec, int is_asi,
    429                                  unsigned size, uintptr_t retaddr)
    430{
    431    SPARCCPU *cpu = SPARC_CPU(cs);
    432    CPUSPARCState *env = &cpu->env;
    433    int fault_type;
    434
    435#ifdef DEBUG_UNASSIGNED
    436    if (is_asi) {
    437        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
    438               " asi 0x%02x from " TARGET_FMT_lx "\n",
    439               is_exec ? "exec" : is_write ? "write" : "read", size,
    440               size == 1 ? "" : "s", addr, is_asi, env->pc);
    441    } else {
    442        printf("Unassigned mem %s access of %d byte%s to " TARGET_FMT_plx
    443               " from " TARGET_FMT_lx "\n",
    444               is_exec ? "exec" : is_write ? "write" : "read", size,
    445               size == 1 ? "" : "s", addr, env->pc);
    446    }
    447#endif
    448    /* Don't overwrite translation and access faults */
    449    fault_type = (env->mmuregs[3] & 0x1c) >> 2;
    450    if ((fault_type > 4) || (fault_type == 0)) {
    451        env->mmuregs[3] = 0; /* Fault status register */
    452        if (is_asi) {
    453            env->mmuregs[3] |= 1 << 16;
    454        }
    455        if (env->psrs) {
    456            env->mmuregs[3] |= 1 << 5;
    457        }
    458        if (is_exec) {
    459            env->mmuregs[3] |= 1 << 6;
    460        }
    461        if (is_write) {
    462            env->mmuregs[3] |= 1 << 7;
    463        }
    464        env->mmuregs[3] |= (5 << 2) | 2;
    465        /* SuperSPARC will never place instruction fault addresses in the FAR */
    466        if (!is_exec) {
    467            env->mmuregs[4] = addr; /* Fault address register */
    468        }
    469    }
    470    /* overflow (same type fault was not read before another fault) */
    471    if (fault_type == ((env->mmuregs[3] & 0x1c)) >> 2) {
    472        env->mmuregs[3] |= 1;
    473    }
    474
    475    if ((env->mmuregs[0] & MMU_E) && !(env->mmuregs[0] & MMU_NF)) {
    476        int tt = is_exec ? TT_CODE_ACCESS : TT_DATA_ACCESS;
    477        cpu_raise_exception_ra(env, tt, retaddr);
    478    }
    479
    480    /*
    481     * flush neverland mappings created during no-fault mode,
    482     * so the sequential MMU faults report proper fault types
    483     */
    484    if (env->mmuregs[0] & MMU_NF) {
    485        tlb_flush(cs);
    486    }
    487}
    488#else
    489static void sparc_raise_mmu_fault(CPUState *cs, hwaddr addr,
    490                                  bool is_write, bool is_exec, int is_asi,
    491                                  unsigned size, uintptr_t retaddr)
    492{
    493    SPARCCPU *cpu = SPARC_CPU(cs);
    494    CPUSPARCState *env = &cpu->env;
    495
    496#ifdef DEBUG_UNASSIGNED
    497    printf("Unassigned mem access to " TARGET_FMT_plx " from " TARGET_FMT_lx
    498           "\n", addr, env->pc);
    499#endif
    500
    501    if (is_exec) { /* XXX has_hypervisor */
    502        if (env->lsu & (IMMU_E)) {
    503            cpu_raise_exception_ra(env, TT_CODE_ACCESS, retaddr);
    504        } else if (cpu_has_hypervisor(env) && !(env->hpstate & HS_PRIV)) {
    505            cpu_raise_exception_ra(env, TT_INSN_REAL_TRANSLATION_MISS, retaddr);
    506        }
    507    } else {
    508        if (env->lsu & (DMMU_E)) {
    509            cpu_raise_exception_ra(env, TT_DATA_ACCESS, retaddr);
    510        } else if (cpu_has_hypervisor(env) && !(env->hpstate & HS_PRIV)) {
    511            cpu_raise_exception_ra(env, TT_DATA_REAL_TRANSLATION_MISS, retaddr);
    512        }
    513    }
    514}
    515#endif
    516#endif
    517
    518#ifndef TARGET_SPARC64
    519#ifndef CONFIG_USER_ONLY
    520
    521
    522/* Leon3 cache control */
    523
    524static void leon3_cache_control_st(CPUSPARCState *env, target_ulong addr,
    525                                   uint64_t val, int size)
    526{
    527    DPRINTF_CACHE_CONTROL("st addr:%08x, val:%" PRIx64 ", size:%d\n",
    528                          addr, val, size);
    529
    530    if (size != 4) {
    531        DPRINTF_CACHE_CONTROL("32bits only\n");
    532        return;
    533    }
    534
    535    switch (addr) {
    536    case 0x00:              /* Cache control */
    537
    538        /* These values must always be read as zeros */
    539        val &= ~CACHE_CTRL_FD;
    540        val &= ~CACHE_CTRL_FI;
    541        val &= ~CACHE_CTRL_IB;
    542        val &= ~CACHE_CTRL_IP;
    543        val &= ~CACHE_CTRL_DP;
    544
    545        env->cache_control = val;
    546        break;
    547    case 0x04:              /* Instruction cache configuration */
    548    case 0x08:              /* Data cache configuration */
    549        /* Read Only */
    550        break;
    551    default:
    552        DPRINTF_CACHE_CONTROL("write unknown register %08x\n", addr);
    553        break;
    554    };
    555}
    556
    557static uint64_t leon3_cache_control_ld(CPUSPARCState *env, target_ulong addr,
    558                                       int size)
    559{
    560    uint64_t ret = 0;
    561
    562    if (size != 4) {
    563        DPRINTF_CACHE_CONTROL("32bits only\n");
    564        return 0;
    565    }
    566
    567    switch (addr) {
    568    case 0x00:              /* Cache control */
    569        ret = env->cache_control;
    570        break;
    571
    572        /* Configuration registers are read and only always keep those
    573           predefined values */
    574
    575    case 0x04:              /* Instruction cache configuration */
    576        ret = 0x10220000;
    577        break;
    578    case 0x08:              /* Data cache configuration */
    579        ret = 0x18220000;
    580        break;
    581    default:
    582        DPRINTF_CACHE_CONTROL("read unknown register %08x\n", addr);
    583        break;
    584    };
    585    DPRINTF_CACHE_CONTROL("ld addr:%08x, ret:0x%" PRIx64 ", size:%d\n",
    586                          addr, ret, size);
    587    return ret;
    588}
    589
    590uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
    591                       int asi, uint32_t memop)
    592{
    593    int size = 1 << (memop & MO_SIZE);
    594    int sign = memop & MO_SIGN;
    595    CPUState *cs = env_cpu(env);
    596    uint64_t ret = 0;
    597#if defined(DEBUG_MXCC) || defined(DEBUG_ASI)
    598    uint32_t last_addr = addr;
    599#endif
    600
    601    do_check_align(env, addr, size - 1, GETPC());
    602    switch (asi) {
    603    case ASI_M_MXCC: /* SuperSparc MXCC registers, or... */
    604    /* case ASI_LEON_CACHEREGS:  Leon3 cache control */
    605        switch (addr) {
    606        case 0x00:          /* Leon3 Cache Control */
    607        case 0x08:          /* Leon3 Instruction Cache config */
    608        case 0x0C:          /* Leon3 Date Cache config */
    609            if (env->def.features & CPU_FEATURE_CACHE_CTRL) {
    610                ret = leon3_cache_control_ld(env, addr, size);
    611            }
    612            break;
    613        case 0x01c00a00: /* MXCC control register */
    614            if (size == 8) {
    615                ret = env->mxccregs[3];
    616            } else {
    617                qemu_log_mask(LOG_UNIMP,
    618                              "%08x: unimplemented access size: %d\n", addr,
    619                              size);
    620            }
    621            break;
    622        case 0x01c00a04: /* MXCC control register */
    623            if (size == 4) {
    624                ret = env->mxccregs[3];
    625            } else {
    626                qemu_log_mask(LOG_UNIMP,
    627                              "%08x: unimplemented access size: %d\n", addr,
    628                              size);
    629            }
    630            break;
    631        case 0x01c00c00: /* Module reset register */
    632            if (size == 8) {
    633                ret = env->mxccregs[5];
    634                /* should we do something here? */
    635            } else {
    636                qemu_log_mask(LOG_UNIMP,
    637                              "%08x: unimplemented access size: %d\n", addr,
    638                              size);
    639            }
    640            break;
    641        case 0x01c00f00: /* MBus port address register */
    642            if (size == 8) {
    643                ret = env->mxccregs[7];
    644            } else {
    645                qemu_log_mask(LOG_UNIMP,
    646                              "%08x: unimplemented access size: %d\n", addr,
    647                              size);
    648            }
    649            break;
    650        default:
    651            qemu_log_mask(LOG_UNIMP,
    652                          "%08x: unimplemented address, size: %d\n", addr,
    653                          size);
    654            break;
    655        }
    656        DPRINTF_MXCC("asi = %d, size = %d, sign = %d, "
    657                     "addr = %08x -> ret = %" PRIx64 ","
    658                     "addr = %08x\n", asi, size, sign, last_addr, ret, addr);
    659#ifdef DEBUG_MXCC
    660        dump_mxcc(env);
    661#endif
    662        break;
    663    case ASI_M_FLUSH_PROBE: /* SuperSparc MMU probe */
    664    case ASI_LEON_MMUFLUSH: /* LEON3 MMU probe */
    665        {
    666            int mmulev;
    667
    668            mmulev = (addr >> 8) & 15;
    669            if (mmulev > 4) {
    670                ret = 0;
    671            } else {
    672                ret = mmu_probe(env, addr, mmulev);
    673            }
    674            DPRINTF_MMU("mmu_probe: 0x%08x (lev %d) -> 0x%08" PRIx64 "\n",
    675                        addr, mmulev, ret);
    676        }
    677        break;
    678    case ASI_M_MMUREGS: /* SuperSparc MMU regs */
    679    case ASI_LEON_MMUREGS: /* LEON3 MMU regs */
    680        {
    681            int reg = (addr >> 8) & 0x1f;
    682
    683            ret = env->mmuregs[reg];
    684            if (reg == 3) { /* Fault status cleared on read */
    685                env->mmuregs[3] = 0;
    686            } else if (reg == 0x13) { /* Fault status read */
    687                ret = env->mmuregs[3];
    688            } else if (reg == 0x14) { /* Fault address read */
    689                ret = env->mmuregs[4];
    690            }
    691            DPRINTF_MMU("mmu_read: reg[%d] = 0x%08" PRIx64 "\n", reg, ret);
    692        }
    693        break;
    694    case ASI_M_TLBDIAG: /* Turbosparc ITLB Diagnostic */
    695    case ASI_M_DIAGS:   /* Turbosparc DTLB Diagnostic */
    696    case ASI_M_IODIAG:  /* Turbosparc IOTLB Diagnostic */
    697        break;
    698    case ASI_KERNELTXT: /* Supervisor code access */
    699        switch (size) {
    700        case 1:
    701            ret = cpu_ldub_code(env, addr);
    702            break;
    703        case 2:
    704            ret = cpu_lduw_code(env, addr);
    705            break;
    706        default:
    707        case 4:
    708            ret = cpu_ldl_code(env, addr);
    709            break;
    710        case 8:
    711            ret = cpu_ldq_code(env, addr);
    712            break;
    713        }
    714        break;
    715    case ASI_M_TXTC_TAG:   /* SparcStation 5 I-cache tag */
    716    case ASI_M_TXTC_DATA:  /* SparcStation 5 I-cache data */
    717    case ASI_M_DATAC_TAG:  /* SparcStation 5 D-cache tag */
    718    case ASI_M_DATAC_DATA: /* SparcStation 5 D-cache data */
    719        break;
    720    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
    721    {
    722        MemTxResult result;
    723        hwaddr access_addr = (hwaddr)addr | ((hwaddr)(asi & 0xf) << 32);
    724
    725        switch (size) {
    726        case 1:
    727            ret = address_space_ldub(cs->as, access_addr,
    728                                     MEMTXATTRS_UNSPECIFIED, &result);
    729            break;
    730        case 2:
    731            ret = address_space_lduw(cs->as, access_addr,
    732                                     MEMTXATTRS_UNSPECIFIED, &result);
    733            break;
    734        default:
    735        case 4:
    736            ret = address_space_ldl(cs->as, access_addr,
    737                                    MEMTXATTRS_UNSPECIFIED, &result);
    738            break;
    739        case 8:
    740            ret = address_space_ldq(cs->as, access_addr,
    741                                    MEMTXATTRS_UNSPECIFIED, &result);
    742            break;
    743        }
    744
    745        if (result != MEMTX_OK) {
    746            sparc_raise_mmu_fault(cs, access_addr, false, false, false,
    747                                  size, GETPC());
    748        }
    749        break;
    750    }
    751    case 0x30: /* Turbosparc secondary cache diagnostic */
    752    case 0x31: /* Turbosparc RAM snoop */
    753    case 0x32: /* Turbosparc page table descriptor diagnostic */
    754    case 0x39: /* data cache diagnostic register */
    755        ret = 0;
    756        break;
    757    case 0x38: /* SuperSPARC MMU Breakpoint Control Registers */
    758        {
    759            int reg = (addr >> 8) & 3;
    760
    761            switch (reg) {
    762            case 0: /* Breakpoint Value (Addr) */
    763                ret = env->mmubpregs[reg];
    764                break;
    765            case 1: /* Breakpoint Mask */
    766                ret = env->mmubpregs[reg];
    767                break;
    768            case 2: /* Breakpoint Control */
    769                ret = env->mmubpregs[reg];
    770                break;
    771            case 3: /* Breakpoint Status */
    772                ret = env->mmubpregs[reg];
    773                env->mmubpregs[reg] = 0ULL;
    774                break;
    775            }
    776            DPRINTF_MMU("read breakpoint reg[%d] 0x%016" PRIx64 "\n", reg,
    777                        ret);
    778        }
    779        break;
    780    case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
    781        ret = env->mmubpctrv;
    782        break;
    783    case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
    784        ret = env->mmubpctrc;
    785        break;
    786    case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
    787        ret = env->mmubpctrs;
    788        break;
    789    case 0x4c: /* SuperSPARC MMU Breakpoint Action */
    790        ret = env->mmubpaction;
    791        break;
    792    case ASI_USERTXT: /* User code access, XXX */
    793    default:
    794        sparc_raise_mmu_fault(cs, addr, false, false, asi, size, GETPC());
    795        ret = 0;
    796        break;
    797
    798    case ASI_USERDATA: /* User data access */
    799    case ASI_KERNELDATA: /* Supervisor data access */
    800    case ASI_P: /* Implicit primary context data access (v9 only?) */
    801    case ASI_M_BYPASS:    /* MMU passthrough */
    802    case ASI_LEON_BYPASS: /* LEON MMU passthrough */
    803        /* These are always handled inline.  */
    804        g_assert_not_reached();
    805    }
    806    if (sign) {
    807        switch (size) {
    808        case 1:
    809            ret = (int8_t) ret;
    810            break;
    811        case 2:
    812            ret = (int16_t) ret;
    813            break;
    814        case 4:
    815            ret = (int32_t) ret;
    816            break;
    817        default:
    818            break;
    819        }
    820    }
    821#ifdef DEBUG_ASI
    822    dump_asi("read ", last_addr, asi, size, ret);
    823#endif
    824    return ret;
    825}
    826
    827void helper_st_asi(CPUSPARCState *env, target_ulong addr, uint64_t val,
    828                   int asi, uint32_t memop)
    829{
    830    int size = 1 << (memop & MO_SIZE);
    831    CPUState *cs = env_cpu(env);
    832
    833    do_check_align(env, addr, size - 1, GETPC());
    834    switch (asi) {
    835    case ASI_M_MXCC: /* SuperSparc MXCC registers, or... */
    836    /* case ASI_LEON_CACHEREGS:  Leon3 cache control */
    837        switch (addr) {
    838        case 0x00:          /* Leon3 Cache Control */
    839        case 0x08:          /* Leon3 Instruction Cache config */
    840        case 0x0C:          /* Leon3 Date Cache config */
    841            if (env->def.features & CPU_FEATURE_CACHE_CTRL) {
    842                leon3_cache_control_st(env, addr, val, size);
    843            }
    844            break;
    845
    846        case 0x01c00000: /* MXCC stream data register 0 */
    847            if (size == 8) {
    848                env->mxccdata[0] = val;
    849            } else {
    850                qemu_log_mask(LOG_UNIMP,
    851                              "%08x: unimplemented access size: %d\n", addr,
    852                              size);
    853            }
    854            break;
    855        case 0x01c00008: /* MXCC stream data register 1 */
    856            if (size == 8) {
    857                env->mxccdata[1] = val;
    858            } else {
    859                qemu_log_mask(LOG_UNIMP,
    860                              "%08x: unimplemented access size: %d\n", addr,
    861                              size);
    862            }
    863            break;
    864        case 0x01c00010: /* MXCC stream data register 2 */
    865            if (size == 8) {
    866                env->mxccdata[2] = val;
    867            } else {
    868                qemu_log_mask(LOG_UNIMP,
    869                              "%08x: unimplemented access size: %d\n", addr,
    870                              size);
    871            }
    872            break;
    873        case 0x01c00018: /* MXCC stream data register 3 */
    874            if (size == 8) {
    875                env->mxccdata[3] = val;
    876            } else {
    877                qemu_log_mask(LOG_UNIMP,
    878                              "%08x: unimplemented access size: %d\n", addr,
    879                              size);
    880            }
    881            break;
    882        case 0x01c00100: /* MXCC stream source */
    883        {
    884            int i;
    885
    886            if (size == 8) {
    887                env->mxccregs[0] = val;
    888            } else {
    889                qemu_log_mask(LOG_UNIMP,
    890                              "%08x: unimplemented access size: %d\n", addr,
    891                              size);
    892            }
    893
    894            for (i = 0; i < 4; i++) {
    895                MemTxResult result;
    896                hwaddr access_addr = (env->mxccregs[0] & 0xffffffffULL) + 8 * i;
    897
    898                env->mxccdata[i] = address_space_ldq(cs->as,
    899                                                     access_addr,
    900                                                     MEMTXATTRS_UNSPECIFIED,
    901                                                     &result);
    902                if (result != MEMTX_OK) {
    903                    /* TODO: investigate whether this is the right behaviour */
    904                    sparc_raise_mmu_fault(cs, access_addr, false, false,
    905                                          false, size, GETPC());
    906                }
    907            }
    908            break;
    909        }
    910        case 0x01c00200: /* MXCC stream destination */
    911        {
    912            int i;
    913
    914            if (size == 8) {
    915                env->mxccregs[1] = val;
    916            } else {
    917                qemu_log_mask(LOG_UNIMP,
    918                              "%08x: unimplemented access size: %d\n", addr,
    919                              size);
    920            }
    921
    922            for (i = 0; i < 4; i++) {
    923                MemTxResult result;
    924                hwaddr access_addr = (env->mxccregs[1] & 0xffffffffULL) + 8 * i;
    925
    926                address_space_stq(cs->as, access_addr, env->mxccdata[i],
    927                                  MEMTXATTRS_UNSPECIFIED, &result);
    928
    929                if (result != MEMTX_OK) {
    930                    /* TODO: investigate whether this is the right behaviour */
    931                    sparc_raise_mmu_fault(cs, access_addr, true, false,
    932                                          false, size, GETPC());
    933                }
    934            }
    935            break;
    936        }
    937        case 0x01c00a00: /* MXCC control register */
    938            if (size == 8) {
    939                env->mxccregs[3] = val;
    940            } else {
    941                qemu_log_mask(LOG_UNIMP,
    942                              "%08x: unimplemented access size: %d\n", addr,
    943                              size);
    944            }
    945            break;
    946        case 0x01c00a04: /* MXCC control register */
    947            if (size == 4) {
    948                env->mxccregs[3] = (env->mxccregs[3] & 0xffffffff00000000ULL)
    949                    | val;
    950            } else {
    951                qemu_log_mask(LOG_UNIMP,
    952                              "%08x: unimplemented access size: %d\n", addr,
    953                              size);
    954            }
    955            break;
    956        case 0x01c00e00: /* MXCC error register  */
    957            /* writing a 1 bit clears the error */
    958            if (size == 8) {
    959                env->mxccregs[6] &= ~val;
    960            } else {
    961                qemu_log_mask(LOG_UNIMP,
    962                              "%08x: unimplemented access size: %d\n", addr,
    963                              size);
    964            }
    965            break;
    966        case 0x01c00f00: /* MBus port address register */
    967            if (size == 8) {
    968                env->mxccregs[7] = val;
    969            } else {
    970                qemu_log_mask(LOG_UNIMP,
    971                              "%08x: unimplemented access size: %d\n", addr,
    972                              size);
    973            }
    974            break;
    975        default:
    976            qemu_log_mask(LOG_UNIMP,
    977                          "%08x: unimplemented address, size: %d\n", addr,
    978                          size);
    979            break;
    980        }
    981        DPRINTF_MXCC("asi = %d, size = %d, addr = %08x, val = %" PRIx64 "\n",
    982                     asi, size, addr, val);
    983#ifdef DEBUG_MXCC
    984        dump_mxcc(env);
    985#endif
    986        break;
    987    case ASI_M_FLUSH_PROBE: /* SuperSparc MMU flush */
    988    case ASI_LEON_MMUFLUSH: /* LEON3 MMU flush */
    989        {
    990            int mmulev;
    991
    992            mmulev = (addr >> 8) & 15;
    993            DPRINTF_MMU("mmu flush level %d\n", mmulev);
    994            switch (mmulev) {
    995            case 0: /* flush page */
    996                tlb_flush_page(cs, addr & 0xfffff000);
    997                break;
    998            case 1: /* flush segment (256k) */
    999            case 2: /* flush region (16M) */
   1000            case 3: /* flush context (4G) */
   1001            case 4: /* flush entire */
   1002                tlb_flush(cs);
   1003                break;
   1004            default:
   1005                break;
   1006            }
   1007#ifdef DEBUG_MMU
   1008            dump_mmu(env);
   1009#endif
   1010        }
   1011        break;
   1012    case ASI_M_MMUREGS: /* write MMU regs */
   1013    case ASI_LEON_MMUREGS: /* LEON3 write MMU regs */
   1014        {
   1015            int reg = (addr >> 8) & 0x1f;
   1016            uint32_t oldreg;
   1017
   1018            oldreg = env->mmuregs[reg];
   1019            switch (reg) {
   1020            case 0: /* Control Register */
   1021                env->mmuregs[reg] = (env->mmuregs[reg] & 0xff000000) |
   1022                    (val & 0x00ffffff);
   1023                /* Mappings generated during no-fault mode
   1024                   are invalid in normal mode.  */
   1025                if ((oldreg ^ env->mmuregs[reg])
   1026                    & (MMU_NF | env->def.mmu_bm)) {
   1027                    tlb_flush(cs);
   1028                }
   1029                break;
   1030            case 1: /* Context Table Pointer Register */
   1031                env->mmuregs[reg] = val & env->def.mmu_ctpr_mask;
   1032                break;
   1033            case 2: /* Context Register */
   1034                env->mmuregs[reg] = val & env->def.mmu_cxr_mask;
   1035                if (oldreg != env->mmuregs[reg]) {
   1036                    /* we flush when the MMU context changes because
   1037                       QEMU has no MMU context support */
   1038                    tlb_flush(cs);
   1039                }
   1040                break;
   1041            case 3: /* Synchronous Fault Status Register with Clear */
   1042            case 4: /* Synchronous Fault Address Register */
   1043                break;
   1044            case 0x10: /* TLB Replacement Control Register */
   1045                env->mmuregs[reg] = val & env->def.mmu_trcr_mask;
   1046                break;
   1047            case 0x13: /* Synchronous Fault Status Register with Read
   1048                          and Clear */
   1049                env->mmuregs[3] = val & env->def.mmu_sfsr_mask;
   1050                break;
   1051            case 0x14: /* Synchronous Fault Address Register */
   1052                env->mmuregs[4] = val;
   1053                break;
   1054            default:
   1055                env->mmuregs[reg] = val;
   1056                break;
   1057            }
   1058            if (oldreg != env->mmuregs[reg]) {
   1059                DPRINTF_MMU("mmu change reg[%d]: 0x%08x -> 0x%08x\n",
   1060                            reg, oldreg, env->mmuregs[reg]);
   1061            }
   1062#ifdef DEBUG_MMU
   1063            dump_mmu(env);
   1064#endif
   1065        }
   1066        break;
   1067    case ASI_M_TLBDIAG: /* Turbosparc ITLB Diagnostic */
   1068    case ASI_M_DIAGS:   /* Turbosparc DTLB Diagnostic */
   1069    case ASI_M_IODIAG:  /* Turbosparc IOTLB Diagnostic */
   1070        break;
   1071    case ASI_M_TXTC_TAG:   /* I-cache tag */
   1072    case ASI_M_TXTC_DATA:  /* I-cache data */
   1073    case ASI_M_DATAC_TAG:  /* D-cache tag */
   1074    case ASI_M_DATAC_DATA: /* D-cache data */
   1075    case ASI_M_FLUSH_PAGE:   /* I/D-cache flush page */
   1076    case ASI_M_FLUSH_SEG:    /* I/D-cache flush segment */
   1077    case ASI_M_FLUSH_REGION: /* I/D-cache flush region */
   1078    case ASI_M_FLUSH_CTX:    /* I/D-cache flush context */
   1079    case ASI_M_FLUSH_USER:   /* I/D-cache flush user */
   1080        break;
   1081    case 0x21 ... 0x2f: /* MMU passthrough, 0x100000000 to 0xfffffffff */
   1082        {
   1083            MemTxResult result;
   1084            hwaddr access_addr = (hwaddr)addr | ((hwaddr)(asi & 0xf) << 32);
   1085
   1086            switch (size) {
   1087            case 1:
   1088                address_space_stb(cs->as, access_addr, val,
   1089                                  MEMTXATTRS_UNSPECIFIED, &result);
   1090                break;
   1091            case 2:
   1092                address_space_stw(cs->as, access_addr, val,
   1093                                  MEMTXATTRS_UNSPECIFIED, &result);
   1094                break;
   1095            case 4:
   1096            default:
   1097                address_space_stl(cs->as, access_addr, val,
   1098                                  MEMTXATTRS_UNSPECIFIED, &result);
   1099                break;
   1100            case 8:
   1101                address_space_stq(cs->as, access_addr, val,
   1102                                  MEMTXATTRS_UNSPECIFIED, &result);
   1103                break;
   1104            }
   1105            if (result != MEMTX_OK) {
   1106                sparc_raise_mmu_fault(cs, access_addr, true, false, false,
   1107                                      size, GETPC());
   1108            }
   1109        }
   1110        break;
   1111    case 0x30: /* store buffer tags or Turbosparc secondary cache diagnostic */
   1112    case 0x31: /* store buffer data, Ross RT620 I-cache flush or
   1113                  Turbosparc snoop RAM */
   1114    case 0x32: /* store buffer control or Turbosparc page table
   1115                  descriptor diagnostic */
   1116    case 0x36: /* I-cache flash clear */
   1117    case 0x37: /* D-cache flash clear */
   1118        break;
   1119    case 0x38: /* SuperSPARC MMU Breakpoint Control Registers*/
   1120        {
   1121            int reg = (addr >> 8) & 3;
   1122
   1123            switch (reg) {
   1124            case 0: /* Breakpoint Value (Addr) */
   1125                env->mmubpregs[reg] = (val & 0xfffffffffULL);
   1126                break;
   1127            case 1: /* Breakpoint Mask */
   1128                env->mmubpregs[reg] = (val & 0xfffffffffULL);
   1129                break;
   1130            case 2: /* Breakpoint Control */
   1131                env->mmubpregs[reg] = (val & 0x7fULL);
   1132                break;
   1133            case 3: /* Breakpoint Status */
   1134                env->mmubpregs[reg] = (val & 0xfULL);
   1135                break;
   1136            }
   1137            DPRINTF_MMU("write breakpoint reg[%d] 0x%016x\n", reg,
   1138                        env->mmuregs[reg]);
   1139        }
   1140        break;
   1141    case 0x49: /* SuperSPARC MMU Counter Breakpoint Value */
   1142        env->mmubpctrv = val & 0xffffffff;
   1143        break;
   1144    case 0x4a: /* SuperSPARC MMU Counter Breakpoint Control */
   1145        env->mmubpctrc = val & 0x3;
   1146        break;
   1147    case 0x4b: /* SuperSPARC MMU Counter Breakpoint Status */
   1148        env->mmubpctrs = val & 0x3;
   1149        break;
   1150    case 0x4c: /* SuperSPARC MMU Breakpoint Action */
   1151        env->mmubpaction = val & 0x1fff;
   1152        break;
   1153    case ASI_USERTXT: /* User code access, XXX */
   1154    case ASI_KERNELTXT: /* Supervisor code access, XXX */
   1155    default:
   1156        sparc_raise_mmu_fault(cs, addr, true, false, asi, size, GETPC());
   1157        break;
   1158
   1159    case ASI_USERDATA: /* User data access */
   1160    case ASI_KERNELDATA: /* Supervisor data access */
   1161    case ASI_P:
   1162    case ASI_M_BYPASS:    /* MMU passthrough */
   1163    case ASI_LEON_BYPASS: /* LEON MMU passthrough */
   1164    case ASI_M_BCOPY: /* Block copy, sta access */
   1165    case ASI_M_BFILL: /* Block fill, stda access */
   1166        /* These are always handled inline.  */
   1167        g_assert_not_reached();
   1168    }
   1169#ifdef DEBUG_ASI
   1170    dump_asi("write", addr, asi, size, val);
   1171#endif
   1172}
   1173
   1174#endif /* CONFIG_USER_ONLY */
   1175#else /* TARGET_SPARC64 */
   1176
   1177#ifdef CONFIG_USER_ONLY
   1178uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
   1179                       int asi, uint32_t memop)
   1180{
   1181    int size = 1 << (memop & MO_SIZE);
   1182    int sign = memop & MO_SIGN;
   1183    uint64_t ret = 0;
   1184
   1185    if (asi < 0x80) {
   1186        cpu_raise_exception_ra(env, TT_PRIV_ACT, GETPC());
   1187    }
   1188    do_check_align(env, addr, size - 1, GETPC());
   1189    addr = asi_address_mask(env, asi, addr);
   1190
   1191    switch (asi) {
   1192    case ASI_PNF:  /* Primary no-fault */
   1193    case ASI_PNFL: /* Primary no-fault LE */
   1194    case ASI_SNF:  /* Secondary no-fault */
   1195    case ASI_SNFL: /* Secondary no-fault LE */
   1196        if (page_check_range(addr, size, PAGE_READ) == -1) {
   1197            ret = 0;
   1198            break;
   1199        }
   1200        switch (size) {
   1201        case 1:
   1202            ret = cpu_ldub_data(env, addr);
   1203            break;
   1204        case 2:
   1205            ret = cpu_lduw_data(env, addr);
   1206            break;
   1207        case 4:
   1208            ret = cpu_ldl_data(env, addr);
   1209            break;
   1210        case 8:
   1211            ret = cpu_ldq_data(env, addr);
   1212            break;
   1213        default:
   1214            g_assert_not_reached();
   1215        }
   1216        break;
   1217        break;
   1218
   1219    case ASI_P: /* Primary */
   1220    case ASI_PL: /* Primary LE */
   1221    case ASI_S:  /* Secondary */
   1222    case ASI_SL: /* Secondary LE */
   1223        /* These are always handled inline.  */
   1224        g_assert_not_reached();
   1225
   1226    default:
   1227        cpu_raise_exception_ra(env, TT_DATA_ACCESS, GETPC());
   1228    }
   1229
   1230    /* Convert from little endian */
   1231    switch (asi) {
   1232    case ASI_PNFL: /* Primary no-fault LE */
   1233    case ASI_SNFL: /* Secondary no-fault LE */
   1234        switch (size) {
   1235        case 2:
   1236            ret = bswap16(ret);
   1237            break;
   1238        case 4:
   1239            ret = bswap32(ret);
   1240            break;
   1241        case 8:
   1242            ret = bswap64(ret);
   1243            break;
   1244        }
   1245    }
   1246
   1247    /* Convert to signed number */
   1248    if (sign) {
   1249        switch (size) {
   1250        case 1:
   1251            ret = (int8_t) ret;
   1252            break;
   1253        case 2:
   1254            ret = (int16_t) ret;
   1255            break;
   1256        case 4:
   1257            ret = (int32_t) ret;
   1258            break;
   1259        }
   1260    }
   1261#ifdef DEBUG_ASI
   1262    dump_asi("read", addr, asi, size, ret);
   1263#endif
   1264    return ret;
   1265}
   1266
   1267void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
   1268                   int asi, uint32_t memop)
   1269{
   1270    int size = 1 << (memop & MO_SIZE);
   1271#ifdef DEBUG_ASI
   1272    dump_asi("write", addr, asi, size, val);
   1273#endif
   1274    if (asi < 0x80) {
   1275        cpu_raise_exception_ra(env, TT_PRIV_ACT, GETPC());
   1276    }
   1277    do_check_align(env, addr, size - 1, GETPC());
   1278
   1279    switch (asi) {
   1280    case ASI_P:  /* Primary */
   1281    case ASI_PL: /* Primary LE */
   1282    case ASI_S:  /* Secondary */
   1283    case ASI_SL: /* Secondary LE */
   1284        /* These are always handled inline.  */
   1285        g_assert_not_reached();
   1286
   1287    case ASI_PNF:  /* Primary no-fault, RO */
   1288    case ASI_SNF:  /* Secondary no-fault, RO */
   1289    case ASI_PNFL: /* Primary no-fault LE, RO */
   1290    case ASI_SNFL: /* Secondary no-fault LE, RO */
   1291    default:
   1292        cpu_raise_exception_ra(env, TT_DATA_ACCESS, GETPC());
   1293    }
   1294}
   1295
   1296#else /* CONFIG_USER_ONLY */
   1297
   1298uint64_t helper_ld_asi(CPUSPARCState *env, target_ulong addr,
   1299                       int asi, uint32_t memop)
   1300{
   1301    int size = 1 << (memop & MO_SIZE);
   1302    int sign = memop & MO_SIGN;
   1303    CPUState *cs = env_cpu(env);
   1304    uint64_t ret = 0;
   1305#if defined(DEBUG_ASI)
   1306    target_ulong last_addr = addr;
   1307#endif
   1308
   1309    asi &= 0xff;
   1310
   1311    do_check_asi(env, asi, GETPC());
   1312    do_check_align(env, addr, size - 1, GETPC());
   1313    addr = asi_address_mask(env, asi, addr);
   1314
   1315    switch (asi) {
   1316    case ASI_PNF:
   1317    case ASI_PNFL:
   1318    case ASI_SNF:
   1319    case ASI_SNFL:
   1320        {
   1321            MemOpIdx oi;
   1322            int idx = (env->pstate & PS_PRIV
   1323                       ? (asi & 1 ? MMU_KERNEL_SECONDARY_IDX : MMU_KERNEL_IDX)
   1324                       : (asi & 1 ? MMU_USER_SECONDARY_IDX : MMU_USER_IDX));
   1325
   1326            if (cpu_get_phys_page_nofault(env, addr, idx) == -1ULL) {
   1327#ifdef DEBUG_ASI
   1328                dump_asi("read ", last_addr, asi, size, ret);
   1329#endif
   1330                /* exception_index is set in get_physical_address_data. */
   1331                cpu_raise_exception_ra(env, cs->exception_index, GETPC());
   1332            }
   1333            oi = make_memop_idx(memop, idx);
   1334            switch (size) {
   1335            case 1:
   1336                ret = helper_ret_ldub_mmu(env, addr, oi, GETPC());
   1337                break;
   1338            case 2:
   1339                if (asi & 8) {
   1340                    ret = helper_le_lduw_mmu(env, addr, oi, GETPC());
   1341                } else {
   1342                    ret = helper_be_lduw_mmu(env, addr, oi, GETPC());
   1343                }
   1344                break;
   1345            case 4:
   1346                if (asi & 8) {
   1347                    ret = helper_le_ldul_mmu(env, addr, oi, GETPC());
   1348                } else {
   1349                    ret = helper_be_ldul_mmu(env, addr, oi, GETPC());
   1350                }
   1351                break;
   1352            case 8:
   1353                if (asi & 8) {
   1354                    ret = helper_le_ldq_mmu(env, addr, oi, GETPC());
   1355                } else {
   1356                    ret = helper_be_ldq_mmu(env, addr, oi, GETPC());
   1357                }
   1358                break;
   1359            default:
   1360                g_assert_not_reached();
   1361            }
   1362        }
   1363        break;
   1364
   1365    case ASI_AIUP:  /* As if user primary */
   1366    case ASI_AIUS:  /* As if user secondary */
   1367    case ASI_AIUPL: /* As if user primary LE */
   1368    case ASI_AIUSL: /* As if user secondary LE */
   1369    case ASI_P:  /* Primary */
   1370    case ASI_S:  /* Secondary */
   1371    case ASI_PL: /* Primary LE */
   1372    case ASI_SL: /* Secondary LE */
   1373    case ASI_REAL:      /* Bypass */
   1374    case ASI_REAL_IO:   /* Bypass, non-cacheable */
   1375    case ASI_REAL_L:    /* Bypass LE */
   1376    case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
   1377    case ASI_N:  /* Nucleus */
   1378    case ASI_NL: /* Nucleus Little Endian (LE) */
   1379    case ASI_NUCLEUS_QUAD_LDD:   /* Nucleus quad LDD 128 bit atomic */
   1380    case ASI_NUCLEUS_QUAD_LDD_L: /* Nucleus quad LDD 128 bit atomic LE */
   1381    case ASI_TWINX_AIUP:   /* As if user primary, twinx */
   1382    case ASI_TWINX_AIUS:   /* As if user secondary, twinx */
   1383    case ASI_TWINX_REAL:   /* Real address, twinx */
   1384    case ASI_TWINX_AIUP_L: /* As if user primary, twinx, LE */
   1385    case ASI_TWINX_AIUS_L: /* As if user secondary, twinx, LE */
   1386    case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
   1387    case ASI_TWINX_N:  /* Nucleus, twinx */
   1388    case ASI_TWINX_NL: /* Nucleus, twinx, LE */
   1389    /* ??? From the UA2011 document; overlaps BLK_INIT_QUAD_LDD_* */
   1390    case ASI_TWINX_P:  /* Primary, twinx */
   1391    case ASI_TWINX_PL: /* Primary, twinx, LE */
   1392    case ASI_TWINX_S:  /* Secondary, twinx */
   1393    case ASI_TWINX_SL: /* Secondary, twinx, LE */
   1394        /* These are always handled inline.  */
   1395        g_assert_not_reached();
   1396
   1397    case ASI_UPA_CONFIG: /* UPA config */
   1398        /* XXX */
   1399        break;
   1400    case ASI_LSU_CONTROL: /* LSU */
   1401        ret = env->lsu;
   1402        break;
   1403    case ASI_IMMU: /* I-MMU regs */
   1404        {
   1405            int reg = (addr >> 3) & 0xf;
   1406            switch (reg) {
   1407            case 0:
   1408                /* 0x00 I-TSB Tag Target register */
   1409                ret = ultrasparc_tag_target(env->immu.tag_access);
   1410                break;
   1411            case 3: /* SFSR */
   1412                ret = env->immu.sfsr;
   1413                break;
   1414            case 5: /* TSB access */
   1415                ret = env->immu.tsb;
   1416                break;
   1417            case 6:
   1418                /* 0x30 I-TSB Tag Access register */
   1419                ret = env->immu.tag_access;
   1420                break;
   1421            default:
   1422                sparc_raise_mmu_fault(cs, addr, false, false, 1, size, GETPC());
   1423                ret = 0;
   1424            }
   1425            break;
   1426        }
   1427    case ASI_IMMU_TSB_8KB_PTR: /* I-MMU 8k TSB pointer */
   1428        {
   1429            /* env->immuregs[5] holds I-MMU TSB register value
   1430               env->immuregs[6] holds I-MMU Tag Access register value */
   1431            ret = ultrasparc_tsb_pointer(env, &env->immu, 0);
   1432            break;
   1433        }
   1434    case ASI_IMMU_TSB_64KB_PTR: /* I-MMU 64k TSB pointer */
   1435        {
   1436            /* env->immuregs[5] holds I-MMU TSB register value
   1437               env->immuregs[6] holds I-MMU Tag Access register value */
   1438            ret = ultrasparc_tsb_pointer(env, &env->immu, 1);
   1439            break;
   1440        }
   1441    case ASI_ITLB_DATA_ACCESS: /* I-MMU data access */
   1442        {
   1443            int reg = (addr >> 3) & 0x3f;
   1444
   1445            ret = env->itlb[reg].tte;
   1446            break;
   1447        }
   1448    case ASI_ITLB_TAG_READ: /* I-MMU tag read */
   1449        {
   1450            int reg = (addr >> 3) & 0x3f;
   1451
   1452            ret = env->itlb[reg].tag;
   1453            break;
   1454        }
   1455    case ASI_DMMU: /* D-MMU regs */
   1456        {
   1457            int reg = (addr >> 3) & 0xf;
   1458            switch (reg) {
   1459            case 0:
   1460                /* 0x00 D-TSB Tag Target register */
   1461                ret = ultrasparc_tag_target(env->dmmu.tag_access);
   1462                break;
   1463            case 1: /* 0x08 Primary Context */
   1464                ret = env->dmmu.mmu_primary_context;
   1465                break;
   1466            case 2: /* 0x10 Secondary Context */
   1467                ret = env->dmmu.mmu_secondary_context;
   1468                break;
   1469            case 3: /* SFSR */
   1470                ret = env->dmmu.sfsr;
   1471                break;
   1472            case 4: /* 0x20 SFAR */
   1473                ret = env->dmmu.sfar;
   1474                break;
   1475            case 5: /* 0x28 TSB access */
   1476                ret = env->dmmu.tsb;
   1477                break;
   1478            case 6: /* 0x30 D-TSB Tag Access register */
   1479                ret = env->dmmu.tag_access;
   1480                break;
   1481            case 7:
   1482                ret = env->dmmu.virtual_watchpoint;
   1483                break;
   1484            case 8:
   1485                ret = env->dmmu.physical_watchpoint;
   1486                break;
   1487            default:
   1488                sparc_raise_mmu_fault(cs, addr, false, false, 1, size, GETPC());
   1489                ret = 0;
   1490            }
   1491            break;
   1492        }
   1493    case ASI_DMMU_TSB_8KB_PTR: /* D-MMU 8k TSB pointer */
   1494        {
   1495            /* env->dmmuregs[5] holds D-MMU TSB register value
   1496               env->dmmuregs[6] holds D-MMU Tag Access register value */
   1497            ret = ultrasparc_tsb_pointer(env, &env->dmmu, 0);
   1498            break;
   1499        }
   1500    case ASI_DMMU_TSB_64KB_PTR: /* D-MMU 64k TSB pointer */
   1501        {
   1502            /* env->dmmuregs[5] holds D-MMU TSB register value
   1503               env->dmmuregs[6] holds D-MMU Tag Access register value */
   1504            ret = ultrasparc_tsb_pointer(env, &env->dmmu, 1);
   1505            break;
   1506        }
   1507    case ASI_DTLB_DATA_ACCESS: /* D-MMU data access */
   1508        {
   1509            int reg = (addr >> 3) & 0x3f;
   1510
   1511            ret = env->dtlb[reg].tte;
   1512            break;
   1513        }
   1514    case ASI_DTLB_TAG_READ: /* D-MMU tag read */
   1515        {
   1516            int reg = (addr >> 3) & 0x3f;
   1517
   1518            ret = env->dtlb[reg].tag;
   1519            break;
   1520        }
   1521    case ASI_INTR_DISPATCH_STAT: /* Interrupt dispatch, RO */
   1522        break;
   1523    case ASI_INTR_RECEIVE: /* Interrupt data receive */
   1524        ret = env->ivec_status;
   1525        break;
   1526    case ASI_INTR_R: /* Incoming interrupt vector, RO */
   1527        {
   1528            int reg = (addr >> 4) & 0x3;
   1529            if (reg < 3) {
   1530                ret = env->ivec_data[reg];
   1531            }
   1532            break;
   1533        }
   1534    case ASI_SCRATCHPAD: /* UA2005 privileged scratchpad */
   1535        if (unlikely((addr >= 0x20) && (addr < 0x30))) {
   1536            /* Hyperprivileged access only */
   1537            sparc_raise_mmu_fault(cs, addr, false, false, 1, size, GETPC());
   1538        }
   1539        /* fall through */
   1540    case ASI_HYP_SCRATCHPAD: /* UA2005 hyperprivileged scratchpad */
   1541        {
   1542            unsigned int i = (addr >> 3) & 0x7;
   1543            ret = env->scratch[i];
   1544            break;
   1545        }
   1546    case ASI_MMU: /* UA2005 Context ID registers */
   1547        switch ((addr >> 3) & 0x3) {
   1548        case 1:
   1549            ret = env->dmmu.mmu_primary_context;
   1550            break;
   1551        case 2:
   1552            ret = env->dmmu.mmu_secondary_context;
   1553            break;
   1554        default:
   1555          sparc_raise_mmu_fault(cs, addr, true, false, 1, size, GETPC());
   1556        }
   1557        break;
   1558    case ASI_DCACHE_DATA:     /* D-cache data */
   1559    case ASI_DCACHE_TAG:      /* D-cache tag access */
   1560    case ASI_ESTATE_ERROR_EN: /* E-cache error enable */
   1561    case ASI_AFSR:            /* E-cache asynchronous fault status */
   1562    case ASI_AFAR:            /* E-cache asynchronous fault address */
   1563    case ASI_EC_TAG_DATA:     /* E-cache tag data */
   1564    case ASI_IC_INSTR:        /* I-cache instruction access */
   1565    case ASI_IC_TAG:          /* I-cache tag access */
   1566    case ASI_IC_PRE_DECODE:   /* I-cache predecode */
   1567    case ASI_IC_NEXT_FIELD:   /* I-cache LRU etc. */
   1568    case ASI_EC_W:            /* E-cache tag */
   1569    case ASI_EC_R:            /* E-cache tag */
   1570        break;
   1571    case ASI_DMMU_TSB_DIRECT_PTR: /* D-MMU data pointer */
   1572    case ASI_ITLB_DATA_IN:        /* I-MMU data in, WO */
   1573    case ASI_IMMU_DEMAP:          /* I-MMU demap, WO */
   1574    case ASI_DTLB_DATA_IN:        /* D-MMU data in, WO */
   1575    case ASI_DMMU_DEMAP:          /* D-MMU demap, WO */
   1576    case ASI_INTR_W:              /* Interrupt vector, WO */
   1577    default:
   1578        sparc_raise_mmu_fault(cs, addr, false, false, 1, size, GETPC());
   1579        ret = 0;
   1580        break;
   1581    }
   1582
   1583    /* Convert to signed number */
   1584    if (sign) {
   1585        switch (size) {
   1586        case 1:
   1587            ret = (int8_t) ret;
   1588            break;
   1589        case 2:
   1590            ret = (int16_t) ret;
   1591            break;
   1592        case 4:
   1593            ret = (int32_t) ret;
   1594            break;
   1595        default:
   1596            break;
   1597        }
   1598    }
   1599#ifdef DEBUG_ASI
   1600    dump_asi("read ", last_addr, asi, size, ret);
   1601#endif
   1602    return ret;
   1603}
   1604
   1605void helper_st_asi(CPUSPARCState *env, target_ulong addr, target_ulong val,
   1606                   int asi, uint32_t memop)
   1607{
   1608    int size = 1 << (memop & MO_SIZE);
   1609    CPUState *cs = env_cpu(env);
   1610
   1611#ifdef DEBUG_ASI
   1612    dump_asi("write", addr, asi, size, val);
   1613#endif
   1614
   1615    asi &= 0xff;
   1616
   1617    do_check_asi(env, asi, GETPC());
   1618    do_check_align(env, addr, size - 1, GETPC());
   1619    addr = asi_address_mask(env, asi, addr);
   1620
   1621    switch (asi) {
   1622    case ASI_AIUP:  /* As if user primary */
   1623    case ASI_AIUS:  /* As if user secondary */
   1624    case ASI_AIUPL: /* As if user primary LE */
   1625    case ASI_AIUSL: /* As if user secondary LE */
   1626    case ASI_P:  /* Primary */
   1627    case ASI_S:  /* Secondary */
   1628    case ASI_PL: /* Primary LE */
   1629    case ASI_SL: /* Secondary LE */
   1630    case ASI_REAL:      /* Bypass */
   1631    case ASI_REAL_IO:   /* Bypass, non-cacheable */
   1632    case ASI_REAL_L:    /* Bypass LE */
   1633    case ASI_REAL_IO_L: /* Bypass, non-cacheable LE */
   1634    case ASI_N:  /* Nucleus */
   1635    case ASI_NL: /* Nucleus Little Endian (LE) */
   1636    case ASI_NUCLEUS_QUAD_LDD:   /* Nucleus quad LDD 128 bit atomic */
   1637    case ASI_NUCLEUS_QUAD_LDD_L: /* Nucleus quad LDD 128 bit atomic LE */
   1638    case ASI_TWINX_AIUP:   /* As if user primary, twinx */
   1639    case ASI_TWINX_AIUS:   /* As if user secondary, twinx */
   1640    case ASI_TWINX_REAL:   /* Real address, twinx */
   1641    case ASI_TWINX_AIUP_L: /* As if user primary, twinx, LE */
   1642    case ASI_TWINX_AIUS_L: /* As if user secondary, twinx, LE */
   1643    case ASI_TWINX_REAL_L: /* Real address, twinx, LE */
   1644    case ASI_TWINX_N:  /* Nucleus, twinx */
   1645    case ASI_TWINX_NL: /* Nucleus, twinx, LE */
   1646    /* ??? From the UA2011 document; overlaps BLK_INIT_QUAD_LDD_* */
   1647    case ASI_TWINX_P:  /* Primary, twinx */
   1648    case ASI_TWINX_PL: /* Primary, twinx, LE */
   1649    case ASI_TWINX_S:  /* Secondary, twinx */
   1650    case ASI_TWINX_SL: /* Secondary, twinx, LE */
   1651        /* These are always handled inline.  */
   1652        g_assert_not_reached();
   1653    /* these ASIs have different functions on UltraSPARC-IIIi
   1654     * and UA2005 CPUs. Use the explicit numbers to avoid confusion
   1655     */
   1656    case 0x31:
   1657    case 0x32:
   1658    case 0x39:
   1659    case 0x3a:
   1660        if (cpu_has_hypervisor(env)) {
   1661            /* UA2005
   1662             * ASI_DMMU_CTX_ZERO_TSB_BASE_PS0
   1663             * ASI_DMMU_CTX_ZERO_TSB_BASE_PS1
   1664             * ASI_DMMU_CTX_NONZERO_TSB_BASE_PS0
   1665             * ASI_DMMU_CTX_NONZERO_TSB_BASE_PS1
   1666             */
   1667            int idx = ((asi & 2) >> 1) | ((asi & 8) >> 2);
   1668            env->dmmu.sun4v_tsb_pointers[idx] = val;
   1669        } else {
   1670            helper_raise_exception(env, TT_ILL_INSN);
   1671        }
   1672        break;
   1673    case 0x33:
   1674    case 0x3b:
   1675        if (cpu_has_hypervisor(env)) {
   1676            /* UA2005
   1677             * ASI_DMMU_CTX_ZERO_CONFIG
   1678             * ASI_DMMU_CTX_NONZERO_CONFIG
   1679             */
   1680            env->dmmu.sun4v_ctx_config[(asi & 8) >> 3] = val;
   1681        } else {
   1682            helper_raise_exception(env, TT_ILL_INSN);
   1683        }
   1684        break;
   1685    case 0x35:
   1686    case 0x36:
   1687    case 0x3d:
   1688    case 0x3e:
   1689        if (cpu_has_hypervisor(env)) {
   1690            /* UA2005
   1691             * ASI_IMMU_CTX_ZERO_TSB_BASE_PS0
   1692             * ASI_IMMU_CTX_ZERO_TSB_BASE_PS1
   1693             * ASI_IMMU_CTX_NONZERO_TSB_BASE_PS0
   1694             * ASI_IMMU_CTX_NONZERO_TSB_BASE_PS1
   1695             */
   1696            int idx = ((asi & 2) >> 1) | ((asi & 8) >> 2);
   1697            env->immu.sun4v_tsb_pointers[idx] = val;
   1698        } else {
   1699            helper_raise_exception(env, TT_ILL_INSN);
   1700        }
   1701      break;
   1702    case 0x37:
   1703    case 0x3f:
   1704        if (cpu_has_hypervisor(env)) {
   1705            /* UA2005
   1706             * ASI_IMMU_CTX_ZERO_CONFIG
   1707             * ASI_IMMU_CTX_NONZERO_CONFIG
   1708             */
   1709            env->immu.sun4v_ctx_config[(asi & 8) >> 3] = val;
   1710        } else {
   1711          helper_raise_exception(env, TT_ILL_INSN);
   1712        }
   1713        break;
   1714    case ASI_UPA_CONFIG: /* UPA config */
   1715        /* XXX */
   1716        return;
   1717    case ASI_LSU_CONTROL: /* LSU */
   1718        env->lsu = val & (DMMU_E | IMMU_E);
   1719        return;
   1720    case ASI_IMMU: /* I-MMU regs */
   1721        {
   1722            int reg = (addr >> 3) & 0xf;
   1723            uint64_t oldreg;
   1724
   1725            oldreg = env->immu.mmuregs[reg];
   1726            switch (reg) {
   1727            case 0: /* RO */
   1728                return;
   1729            case 1: /* Not in I-MMU */
   1730            case 2:
   1731                return;
   1732            case 3: /* SFSR */
   1733                if ((val & 1) == 0) {
   1734                    val = 0; /* Clear SFSR */
   1735                }
   1736                env->immu.sfsr = val;
   1737                break;
   1738            case 4: /* RO */
   1739                return;
   1740            case 5: /* TSB access */
   1741                DPRINTF_MMU("immu TSB write: 0x%016" PRIx64 " -> 0x%016"
   1742                            PRIx64 "\n", env->immu.tsb, val);
   1743                env->immu.tsb = val;
   1744                break;
   1745            case 6: /* Tag access */
   1746                env->immu.tag_access = val;
   1747                break;
   1748            case 7:
   1749            case 8:
   1750                return;
   1751            default:
   1752                sparc_raise_mmu_fault(cs, addr, true, false, 1, size, GETPC());
   1753                break;
   1754            }
   1755
   1756            if (oldreg != env->immu.mmuregs[reg]) {
   1757                DPRINTF_MMU("immu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
   1758                            PRIx64 "\n", reg, oldreg, env->immuregs[reg]);
   1759            }
   1760#ifdef DEBUG_MMU
   1761            dump_mmu(env);
   1762#endif
   1763            return;
   1764        }
   1765    case ASI_ITLB_DATA_IN: /* I-MMU data in */
   1766        /* ignore real translation entries */
   1767        if (!(addr & TLB_UST1_IS_REAL_BIT)) {
   1768            replace_tlb_1bit_lru(env->itlb, env->immu.tag_access,
   1769                                 val, "immu", env, addr);
   1770        }
   1771        return;
   1772    case ASI_ITLB_DATA_ACCESS: /* I-MMU data access */
   1773        {
   1774            /* TODO: auto demap */
   1775
   1776            unsigned int i = (addr >> 3) & 0x3f;
   1777
   1778            /* ignore real translation entries */
   1779            if (!(addr & TLB_UST1_IS_REAL_BIT)) {
   1780                replace_tlb_entry(&env->itlb[i], env->immu.tag_access,
   1781                                  sun4v_tte_to_sun4u(env, addr, val), env);
   1782            }
   1783#ifdef DEBUG_MMU
   1784            DPRINTF_MMU("immu data access replaced entry [%i]\n", i);
   1785            dump_mmu(env);
   1786#endif
   1787            return;
   1788        }
   1789    case ASI_IMMU_DEMAP: /* I-MMU demap */
   1790        demap_tlb(env->itlb, addr, "immu", env);
   1791        return;
   1792    case ASI_DMMU: /* D-MMU regs */
   1793        {
   1794            int reg = (addr >> 3) & 0xf;
   1795            uint64_t oldreg;
   1796
   1797            oldreg = env->dmmu.mmuregs[reg];
   1798            switch (reg) {
   1799            case 0: /* RO */
   1800            case 4:
   1801                return;
   1802            case 3: /* SFSR */
   1803                if ((val & 1) == 0) {
   1804                    val = 0; /* Clear SFSR, Fault address */
   1805                    env->dmmu.sfar = 0;
   1806                }
   1807                env->dmmu.sfsr = val;
   1808                break;
   1809            case 1: /* Primary context */
   1810                env->dmmu.mmu_primary_context = val;
   1811                /* can be optimized to only flush MMU_USER_IDX
   1812                   and MMU_KERNEL_IDX entries */
   1813                tlb_flush(cs);
   1814                break;
   1815            case 2: /* Secondary context */
   1816                env->dmmu.mmu_secondary_context = val;
   1817                /* can be optimized to only flush MMU_USER_SECONDARY_IDX
   1818                   and MMU_KERNEL_SECONDARY_IDX entries */
   1819                tlb_flush(cs);
   1820                break;
   1821            case 5: /* TSB access */
   1822                DPRINTF_MMU("dmmu TSB write: 0x%016" PRIx64 " -> 0x%016"
   1823                            PRIx64 "\n", env->dmmu.tsb, val);
   1824                env->dmmu.tsb = val;
   1825                break;
   1826            case 6: /* Tag access */
   1827                env->dmmu.tag_access = val;
   1828                break;
   1829            case 7: /* Virtual Watchpoint */
   1830                env->dmmu.virtual_watchpoint = val;
   1831                break;
   1832            case 8: /* Physical Watchpoint */
   1833                env->dmmu.physical_watchpoint = val;
   1834                break;
   1835            default:
   1836                sparc_raise_mmu_fault(cs, addr, true, false, 1, size, GETPC());
   1837                break;
   1838            }
   1839
   1840            if (oldreg != env->dmmu.mmuregs[reg]) {
   1841                DPRINTF_MMU("dmmu change reg[%d]: 0x%016" PRIx64 " -> 0x%016"
   1842                            PRIx64 "\n", reg, oldreg, env->dmmuregs[reg]);
   1843            }
   1844#ifdef DEBUG_MMU
   1845            dump_mmu(env);
   1846#endif
   1847            return;
   1848        }
   1849    case ASI_DTLB_DATA_IN: /* D-MMU data in */
   1850      /* ignore real translation entries */
   1851      if (!(addr & TLB_UST1_IS_REAL_BIT)) {
   1852          replace_tlb_1bit_lru(env->dtlb, env->dmmu.tag_access,
   1853                               val, "dmmu", env, addr);
   1854      }
   1855      return;
   1856    case ASI_DTLB_DATA_ACCESS: /* D-MMU data access */
   1857        {
   1858            unsigned int i = (addr >> 3) & 0x3f;
   1859
   1860            /* ignore real translation entries */
   1861            if (!(addr & TLB_UST1_IS_REAL_BIT)) {
   1862                replace_tlb_entry(&env->dtlb[i], env->dmmu.tag_access,
   1863                                  sun4v_tte_to_sun4u(env, addr, val), env);
   1864            }
   1865#ifdef DEBUG_MMU
   1866            DPRINTF_MMU("dmmu data access replaced entry [%i]\n", i);
   1867            dump_mmu(env);
   1868#endif
   1869            return;
   1870        }
   1871    case ASI_DMMU_DEMAP: /* D-MMU demap */
   1872        demap_tlb(env->dtlb, addr, "dmmu", env);
   1873        return;
   1874    case ASI_INTR_RECEIVE: /* Interrupt data receive */
   1875        env->ivec_status = val & 0x20;
   1876        return;
   1877    case ASI_SCRATCHPAD: /* UA2005 privileged scratchpad */
   1878        if (unlikely((addr >= 0x20) && (addr < 0x30))) {
   1879            /* Hyperprivileged access only */
   1880            sparc_raise_mmu_fault(cs, addr, true, false, 1, size, GETPC());
   1881        }
   1882        /* fall through */
   1883    case ASI_HYP_SCRATCHPAD: /* UA2005 hyperprivileged scratchpad */
   1884        {
   1885            unsigned int i = (addr >> 3) & 0x7;
   1886            env->scratch[i] = val;
   1887            return;
   1888        }
   1889    case ASI_MMU: /* UA2005 Context ID registers */
   1890        {
   1891          switch ((addr >> 3) & 0x3) {
   1892          case 1:
   1893              env->dmmu.mmu_primary_context = val;
   1894              env->immu.mmu_primary_context = val;
   1895              tlb_flush_by_mmuidx(cs,
   1896                                  (1 << MMU_USER_IDX) | (1 << MMU_KERNEL_IDX));
   1897              break;
   1898          case 2:
   1899              env->dmmu.mmu_secondary_context = val;
   1900              env->immu.mmu_secondary_context = val;
   1901              tlb_flush_by_mmuidx(cs,
   1902                                  (1 << MMU_USER_SECONDARY_IDX) |
   1903                                  (1 << MMU_KERNEL_SECONDARY_IDX));
   1904              break;
   1905          default:
   1906              sparc_raise_mmu_fault(cs, addr, true, false, 1, size, GETPC());
   1907          }
   1908        }
   1909        return;
   1910    case ASI_QUEUE: /* UA2005 CPU mondo queue */
   1911    case ASI_DCACHE_DATA: /* D-cache data */
   1912    case ASI_DCACHE_TAG: /* D-cache tag access */
   1913    case ASI_ESTATE_ERROR_EN: /* E-cache error enable */
   1914    case ASI_AFSR: /* E-cache asynchronous fault status */
   1915    case ASI_AFAR: /* E-cache asynchronous fault address */
   1916    case ASI_EC_TAG_DATA: /* E-cache tag data */
   1917    case ASI_IC_INSTR: /* I-cache instruction access */
   1918    case ASI_IC_TAG: /* I-cache tag access */
   1919    case ASI_IC_PRE_DECODE: /* I-cache predecode */
   1920    case ASI_IC_NEXT_FIELD: /* I-cache LRU etc. */
   1921    case ASI_EC_W: /* E-cache tag */
   1922    case ASI_EC_R: /* E-cache tag */
   1923        return;
   1924    case ASI_IMMU_TSB_8KB_PTR: /* I-MMU 8k TSB pointer, RO */
   1925    case ASI_IMMU_TSB_64KB_PTR: /* I-MMU 64k TSB pointer, RO */
   1926    case ASI_ITLB_TAG_READ: /* I-MMU tag read, RO */
   1927    case ASI_DMMU_TSB_8KB_PTR: /* D-MMU 8k TSB pointer, RO */
   1928    case ASI_DMMU_TSB_64KB_PTR: /* D-MMU 64k TSB pointer, RO */
   1929    case ASI_DMMU_TSB_DIRECT_PTR: /* D-MMU data pointer, RO */
   1930    case ASI_DTLB_TAG_READ: /* D-MMU tag read, RO */
   1931    case ASI_INTR_DISPATCH_STAT: /* Interrupt dispatch, RO */
   1932    case ASI_INTR_R: /* Incoming interrupt vector, RO */
   1933    case ASI_PNF: /* Primary no-fault, RO */
   1934    case ASI_SNF: /* Secondary no-fault, RO */
   1935    case ASI_PNFL: /* Primary no-fault LE, RO */
   1936    case ASI_SNFL: /* Secondary no-fault LE, RO */
   1937    default:
   1938        sparc_raise_mmu_fault(cs, addr, true, false, 1, size, GETPC());
   1939        return;
   1940    }
   1941}
   1942#endif /* CONFIG_USER_ONLY */
   1943#endif /* TARGET_SPARC64 */
   1944
   1945#if !defined(CONFIG_USER_ONLY)
   1946
   1947void sparc_cpu_do_transaction_failed(CPUState *cs, hwaddr physaddr,
   1948                                     vaddr addr, unsigned size,
   1949                                     MMUAccessType access_type,
   1950                                     int mmu_idx, MemTxAttrs attrs,
   1951                                     MemTxResult response, uintptr_t retaddr)
   1952{
   1953    bool is_write = access_type == MMU_DATA_STORE;
   1954    bool is_exec = access_type == MMU_INST_FETCH;
   1955    bool is_asi = false;
   1956
   1957    sparc_raise_mmu_fault(cs, physaddr, is_write, is_exec,
   1958                          is_asi, size, retaddr);
   1959}
   1960#endif
   1961
   1962#if !defined(CONFIG_USER_ONLY)
   1963void QEMU_NORETURN sparc_cpu_do_unaligned_access(CPUState *cs, vaddr addr,
   1964                                                 MMUAccessType access_type,
   1965                                                 int mmu_idx,
   1966                                                 uintptr_t retaddr)
   1967{
   1968    SPARCCPU *cpu = SPARC_CPU(cs);
   1969    CPUSPARCState *env = &cpu->env;
   1970
   1971#ifdef DEBUG_UNALIGNED
   1972    printf("Unaligned access to 0x" TARGET_FMT_lx " from 0x" TARGET_FMT_lx
   1973           "\n", addr, env->pc);
   1974#endif
   1975    cpu_raise_exception_ra(env, TT_UNALIGNED, retaddr);
   1976}
   1977#endif