qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

ldst_helper.c (66192B)


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