Annotation of qemu/target-sparc/ldst_helper.c, revision 1.1

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.