Annotation of tme/ic/sparc/stp103x.c, revision 1.1

1.1     ! root        1: /* $Id: stp103x.c,v 1.5 2010/06/05 18:57:04 fredette Exp $ */
        !             2: 
        !             3: /* ic/sparc/stp103x.c - implementation of UltraSPARC I (STP1030) and II (STP1031) emulation: */
        !             4: 
        !             5: /*
        !             6:  * Copyright (c) 2008 Matt Fredette
        !             7:  * All rights reserved.
        !             8:  *
        !             9:  * Redistribution and use in source and binary forms, with or without
        !            10:  * modification, are permitted provided that the following conditions
        !            11:  * are met:
        !            12:  * 1. Redistributions of source code must retain the above copyright
        !            13:  *    notice, this list of conditions and the following disclaimer.
        !            14:  * 2. Redistributions in binary form must reproduce the above copyright
        !            15:  *    notice, this list of conditions and the following disclaimer in the
        !            16:  *    documentation and/or other materials provided with the distribution.
        !            17:  * 3. All advertising materials mentioning features or use of this software
        !            18:  *    must display the following acknowledgement:
        !            19:  *      This product includes software developed by Matt Fredette.
        !            20:  * 4. The name of the author may not be used to endorse or promote products
        !            21:  *    derived from this software without specific prior written permission.
        !            22:  *
        !            23:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            24:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
        !            25:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
        !            26:  * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
        !            27:  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
        !            28:  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
        !            29:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            30:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
        !            31:  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
        !            32:  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            33:  * POSSIBILITY OF SUCH DAMAGE.
        !            34:  */
        !            35: 
        !            36: #include <tme/common.h>
        !            37: _TME_RCSID("$Id: stp103x.c,v 1.5 2010/06/05 18:57:04 fredette Exp $");
        !            38: 
        !            39: /* includes: */
        !            40: #include "sparc-impl.h"
        !            41: 
        !            42: /* macros: */
        !            43: 
        !            44: /* the PSTATE extensions: */
        !            45: #define TME_STP103X_PSTATE_IG                  TME_BIT(11)
        !            46: #define TME_STP103X_PSTATE_MG                  TME_BIT(10)
        !            47: 
        !            48: /* the load/store unit control register: */
        !            49: #define TME_STP103X_LSU_IC                     TME_BIT(0)
        !            50: #define TME_STP103X_LSU_DC                     TME_BIT(1)
        !            51: #define TME_STP103X_LSU_IM                     TME_BIT(2)
        !            52: #define TME_STP103X_LSU_DM                     TME_BIT(3)
        !            53: #define TME_STP103X_LSU_FM                     (TME_BIT(20) - TME_BIT(4))
        !            54: #define TME_STP103X_LSU_VW                     TME_BIT(21)
        !            55: #define TME_STP103X_LSU_VR                     TME_BIT(22)
        !            56: #define TME_STP103X_LSU_PW                     TME_BIT(23)
        !            57: #define TME_STP103X_LSU_PR                     TME_BIT(24)
        !            58: 
        !            59: /* the E-Cache (E-state) error enable register: */
        !            60: #define TME_STP103X_ESTATE_ERROR_ENABLE_CEEN   TME_BIT(0)
        !            61: #define TME_STP103X_ESTATE_ERROR_ENABLE_NCEEN  TME_BIT(1)
        !            62: #define TME_STP103X_ESTATE_ERROR_ENABLE_ISAPEN TME_BIT(2)
        !            63: 
        !            64: /* the start of the virtual address hole: */
        !            65: #define TME_STP103X_VA_HOLE_START              (((tme_uint64_t) 1) << 43)
        !            66: 
        !            67: /* the size of the physical address space: */
        !            68: #define TME_STP103X_PA_SIZE                    (((tme_uint64_t) 1) << 41)
        !            69: 
        !            70: /* the maximum context number: */
        !            71: #define TME_STP103X_CONTEXT_MAX                        (8191)
        !            72: 
        !            73: /* the different page sizes: */
        !            74: #define TME_STP103X_PAGE_SIZE_8KB              (8 * 1024)
        !            75: #define TME_STP103X_PAGE_SIZE_64KB             (64 * 1024)
        !            76: #define TME_STP103X_PAGE_SIZE_512KB            (512 * 1024)
        !            77: #define TME_STP103X_PAGE_SIZE_4MB              (4 * 1024 * 1024)
        !            78: 
        !            79: /* because we often deal with the tme_uint64_t TLB/TTE entry tag and
        !            80:    data as tme_uint32_t halves for performance, we need to easily
        !            81:    generate the right bitfield masks for both types.  this macro
        !            82:    converts the constant x to the type of e, and then shifts it by
        !            83:    (shift mod (8 * sizeof(e))).  e is only typed, never evaluated: */
        !            84: #define _TME_STP103X_TLB_X(e, x, shift)                ((1 ? (x) : (e)) << ((shift) % (8 * sizeof(e))))
        !            85: 
        !            86: /* TLB/TTE data: */
        !            87: #define TME_STP103X_TLB_DATA_V(e)              _TME_STP103X_TLB_X(e, 1, 63)
        !            88: #define TME_STP103X_TLB_DATA_SIZE_MASK(e)      _TME_STP103X_TLB_X(e, 0x3, 61)
        !            89: #define  TME_STP103X_TLB_DATA_SIZE_8KB(e)       _TME_STP103X_TLB_X(e, 0x0, 61)
        !            90: #define  TME_STP103X_TLB_DATA_SIZE_64KB(e)      _TME_STP103X_TLB_X(e, 0x1, 61)
        !            91: #define  TME_STP103X_TLB_DATA_SIZE_512KB(e)     _TME_STP103X_TLB_X(e, 0x2, 61)
        !            92: #define  TME_STP103X_TLB_DATA_SIZE_4MB(e)       _TME_STP103X_TLB_X(e, 0x3, 61)
        !            93: #define TME_STP103X_TLB_DATA_NFO(e)            _TME_STP103X_TLB_X(e, 1, 60)
        !            94: #define TME_STP103X_TLB_DATA_IE(e)             _TME_STP103X_TLB_X(e, 1, 59)
        !            95: #define TME_STP103X_TLB_DATA_SOFT2(e)          _TME_STP103X_TLB_X(e, 0x1ff, 50)
        !            96: #define TME_STP103X_TLB_DATA_SIZE_CAM_MASK(e)  _TME_STP103X_TLB_X(e, 0x7, 45)
        !            97: #define  TME_STP103X_TLB_DATA_SIZE_CAM_8KB(e)   _TME_STP103X_TLB_X(e, 0x0, 45)
        !            98: #define  TME_STP103X_TLB_DATA_SIZE_CAM_64KB(e)  _TME_STP103X_TLB_X(e, 0x1, 45)
        !            99: #define  TME_STP103X_TLB_DATA_SIZE_CAM_512KB(e)         _TME_STP103X_TLB_X(e, 0x3, 45)
        !           100: #define  TME_STP103X_TLB_DATA_SIZE_CAM_4MB(e)   _TME_STP103X_TLB_X(e, 0x7, 45)
        !           101: #define TME_STP103X_TLB_DATA_SIZE_RAM_MASK(e)  _TME_STP103X_TLB_X(e, 0x7, 42)
        !           102: #define  TME_STP103X_TLB_DATA_SIZE_RAM_8KB(e)   _TME_STP103X_TLB_X(e, 0x0, 42)
        !           103: #define  TME_STP103X_TLB_DATA_SIZE_RAM_64KB(e)  _TME_STP103X_TLB_X(e, 0x1, 42)
        !           104: #define  TME_STP103X_TLB_DATA_SIZE_RAM_512KB(e)         _TME_STP103X_TLB_X(e, 0x3, 42)
        !           105: #define  TME_STP103X_TLB_DATA_SIZE_RAM_4MB(e)   _TME_STP103X_TLB_X(e, 0x7, 42)
        !           106: #define TME_STP103X_TLB_DATA_DIAG_USED(e)      _TME_STP103X_TLB_X(e, 1, 41)
        !           107: #define TME_STP103X_TLB_DATA_PA                        ((((tme_uint64_t) 1) << 41) - (1 << 13))
        !           108: #define TME_STP103X_TLB_DATA_SOFT(e)           _TME_STP103X_TLB_X(e, 0x3f, 7)
        !           109: #define TME_STP103X_TLB_DATA_L(e)              _TME_STP103X_TLB_X(e, 1, 6)
        !           110: #define TME_STP103X_TLB_DATA_CP(e)             _TME_STP103X_TLB_X(e, 1, 5)
        !           111: #define TME_STP103X_TLB_DATA_CV(e)             _TME_STP103X_TLB_X(e, 1, 4)
        !           112: #define TME_STP103X_TLB_DATA_E(e)              _TME_STP103X_TLB_X(e, 1, 3)
        !           113: #define TME_STP103X_TLB_DATA_P(e)              _TME_STP103X_TLB_X(e, 1, 2)
        !           114: #define TME_STP103X_TLB_DATA_W(e)              _TME_STP103X_TLB_X(e, 1, 1)
        !           115: #define TME_STP103X_TLB_DATA_G(e)              _TME_STP103X_TLB_X(e, 1, 0)
        !           116: 
        !           117: /* the DMMU and IMMU SFSR: */
        !           118: #define TME_STP103X_SFSR_ASI                   (0xff << 16)
        !           119: #define TME_STP103X_SFSR_FT_PRIVILEGE          (0x01 << 7)
        !           120: #define TME_STP103X_SFSR_FT_SIDE_EFFECTS       (0x02 << 7)
        !           121: #define TME_STP103X_SFSR_FT_UNCACHEABLE                (0x04 << 7)
        !           122: #define TME_STP103X_SFSR_FT_ILLEGAL            (0x08 << 7)
        !           123: #define TME_STP103X_SFSR_FT_NO_FAULT_FAULT     (0x10 << 7)
        !           124: #define TME_STP103X_SFSR_FT_VA_RANGE           (0x20 << 7)
        !           125: #define TME_STP103X_SFSR_FT_VA_RANGE_NNPC      (0x40 << 7)
        !           126: #define TME_STP103X_SFSR_E                     TME_BIT(6)
        !           127: #define TME_STP103X_SFSR_CT_PRIMARY            (0x0 << 4)
        !           128: #define TME_STP103X_SFSR_CT_SECONDARY          (0x1 << 4)
        !           129: #define TME_STP103X_SFSR_CT_NUCLEUS            (0x2 << 4)
        !           130: #define TME_STP103X_SFSR_CT_RESERVED           (0x3 << 4)
        !           131: #define TME_STP103X_SFSR_PR                    TME_BIT(3)
        !           132: #define TME_STP103X_SFSR_W                     TME_BIT(2)
        !           133: #define TME_STP103X_SFSR_OW                    TME_BIT(1)
        !           134: #define TME_STP103X_SFSR_FV                    TME_BIT(0)
        !           135: 
        !           136: /* the AFSR: */
        !           137: #define TME_STP103X_AFSR_ME                    (((tme_uint64_t) 1) << 32)
        !           138: #define TME_STP103X_AFSR_PRIV                  TME_BIT(31)
        !           139: #define TME_STP103X_AFSR_TO                    TME_BIT(27)
        !           140: 
        !           141: /* a TSB register: */
        !           142: #define TME_STP103X_TSB_SIZE                   (0x7)
        !           143: #define TME_STP103X_TSB_SPLIT                  TME_BIT(12)
        !           144: 
        !           145: /* specific traps: */
        !           146: #define TME_STP103X_TRAP_MG                    _TME_SPARC_TRAP_IMPDEP(0)
        !           147: #define TME_STP103X_TRAP_IG                    _TME_SPARC_TRAP_IMPDEP(1)
        !           148: #define TME_STP103X_TRAP_interrupt_vector \
        !           149:   (TME_STP103X_TRAP_IG | _TME_SPARC_TRAP(16, 0x060))
        !           150: #define TME_STP103X_TRAP_fast_instruction_access_MMU_miss \
        !           151:   (TME_STP103X_TRAP_MG | _TME_SPARC_TRAP(2, 0x064))
        !           152: #define TME_STP103X_TRAP_fast_data_access_MMU_miss \
        !           153:   (TME_STP103X_TRAP_MG | _TME_SPARC_TRAP(12, 0x068))
        !           154: #define TME_STP103X_TRAP_fast_data_access_protection \
        !           155:   (TME_STP103X_TRAP_MG | _TME_SPARC_TRAP(12, 0x06c))
        !           156: 
        !           157: /* specific ASIs and flags: */
        !           158: #define TME_STP103X_ASI_LSU_CONTROL_REG                (0x45)
        !           159: #define TME_STP103X_ASI_DCACHE_DATA            (0x46)
        !           160: #define TME_STP103X_ASI_DCACHE_TAG             (0x47)
        !           161: #define TME_STP103X_ASI_INTR_DISPATCH_STATUS   (0x48)
        !           162: #define TME_STP103X_ASI_INTR_RECEIVE           (0x49)
        !           163: #define TME_STP103X_ASI_UPA_CONFIG_REG         (0x4a)
        !           164: #define TME_STP103X_ASI_ESTATE_ERROR_EN_REG    (0x4b)
        !           165: #define TME_STP103X_ASI_AFSR                   (0x4c)
        !           166: #define TME_STP103X_ASI_AFAR                   (0x4d)
        !           167: #define TME_STP103X_ASI_ECACHE_TAG_DATA                (0x4e)
        !           168: #define TME_STP103X_ASI_IMMU                   (0x50)
        !           169: #define TME_STP103X_ASI_DMMU                   (0x58)
        !           170: #define TME_STP103X_ASI_FLAG_TSB_8KB_PTR       (0x1)
        !           171: #define TME_STP103X_ASI_FLAG_TSB_64KB_PTR      (0x2)
        !           172: #define TME_STP103X_ASI_BLK_COMMIT             (0xe0)
        !           173: 
        !           174: /* the size of the IMMU and DMMU TLBs: */
        !           175: #define TME_STP103X_TLB_SIZE                   (64)
        !           176: 
        !           177: /* the size of the E-Cache: */
        !           178: #define TME_STP103X_ECACHE_SIZE                        (512 * 1024)
        !           179: 
        !           180: /* the block size of the I-Cache: */
        !           181: #define TME_STP103X_ICACHE_BLOCK_SIZE          (32)
        !           182: 
        !           183: /* the TICK_compare register: */
        !           184: #define TME_STP103X_TCR_INT_DIS                        (((tme_uint64_t) 1) << 63)
        !           185: #define TME_STP103X_TCR_TICK_CMPR              (TME_STP103X_TCR_INT_DIS - 1)
        !           186: 
        !           187: /* the SIR: */
        !           188: #define TME_STP103X_SIR_SOFTINT(x)             (1 << (x))
        !           189: #define TME_STP103X_SIR_TICK_INT               (1 << 0)
        !           190: 
        !           191: /* ASI_INTR_RECEIVE: */
        !           192: #define TME_STP103X_INTR_RECEIVE_BUSY          (1 << 5)
        !           193: 
        !           194: /* the block load and store sizes: */
        !           195: #define TME_STP103X_BLOCK_SIZE                 (64)
        !           196: #define TME_STP103X_BLOCK_FPREGS_DOUBLE                (TME_STP103X_BLOCK_SIZE / sizeof(tme_uint64_t))
        !           197: 
        !           198: /* other constants: */
        !           199: #define TME_STP103X_MAXTL                      (5)
        !           200: 
        !           201: /* the UPA configuration register: */
        !           202: /* NB: this is a partial list: */
        !           203: #define TME_STP1030_UPA_CONFIG_PCON            ((2 << 29) - (1 << 22))
        !           204: #define TME_STP1031_UPA_CONFIG_PCON            ((((tme_uint64_t) 2) << 32) - (1 << 22))
        !           205: #define TME_STP1031_UPA_CONFIG_ELIM            ((((tme_uint64_t) 2) << 35) - (((tme_uint64_t) 1) << 33))
        !           206: 
        !           207: /* the UPA queue depths and capabilities: */
        !           208: #define TME_STP103X_UPA_PINT_RDQ               (1)
        !           209: #define TME_STP103X_UPA_PREQ_DQ                        (0)
        !           210: #define TME_STP103X_UPA_PREQ_RQ                        (1)
        !           211: #define TME_STP103X_UPA_UPACAP                 \
        !           212:   (TME_UPA_UPACAP_HANDLERSLAVE                 \
        !           213:    | TME_UPA_UPACAP_INTERRUPTMASTER            \
        !           214:    | !TME_UPA_UPACAP_SLAVE_INT_L               \
        !           215:    | TME_UPA_UPACAP_CACHEMASTER                        \
        !           216:    | TME_UPA_UPACAP_MASTER)
        !           217: 
        !           218: /* fixed characteristics of the stp103x: */
        !           219: #undef  TME_SPARC_VERSION
        !           220: #define TME_SPARC_VERSION(ic)  (9)
        !           221: #undef  TME_SPARC_NWINDOWS
        !           222: #define TME_SPARC_NWINDOWS(ic) (8)
        !           223: #undef  TME_SPARC_MEMORY_FLAGS
        !           224: #define TME_SPARC_MEMORY_FLAGS(ic)             \
        !           225:   (TME_SPARC_MEMORY_FLAG_HAS_NUCLEUS           \
        !           226:    + TME_SPARC_MEMORY_FLAG_HAS_INVERT_ENDIAN   \
        !           227:    + !TME_SPARC_MEMORY_FLAG_HAS_LDDF_STDF_32)
        !           228: 
        !           229: /* this recovers the stp103x state from the generic sparc state: */
        !           230: #define TME_STP103X(ic) ((struct tme_stp103x *) (TRUE ? (ic) : (struct tme_sparc *) 0))
        !           231: 
        !           232: /* this evaluates to nonzero if an ASI mask from an ASI_DMMU* or
        !           233:    ASI_IMMU* ASI is from an ASI_DMMU* ASI: */
        !           234: #if (TME_STP103X_ASI_DMMU <= TME_STP103X_ASI_IMMU) || ((TME_STP103X_ASI_DMMU ^ TME_STP103X_ASI_IMMU) & ((TME_STP103X_ASI_DMMU ^ TME_STP103X_ASI_IMMU) - 1)) != 0
        !           235: #error "TME_STP103X_ASI_DMMU or TME_STP103X_ASI_IMMU changed"
        !           236: #endif
        !           237: #define TME_STP103X_ASI_MMU_MASK_IS_DMMU(asi_mask)     \
        !           238:   ((asi_mask)                                          \
        !           239:    & TME_SPARC_ASI_MASK_RAW(TME_STP103X_ASI_DMMU       \
        !           240:                            ^ TME_STP103X_ASI_IMMU))
        !           241: 
        !           242: /* specific load/store information: */
        !           243: #define TME_STP103X_LSINFO_ASSERT_NO_FAULTS    _TME_SPARC_LSINFO_X(0)
        !           244: 
        !           245: /* specific load/store faults: */
        !           246: #define TME_STP103X_LS_FAULT_MMU_MISS          _TME_SPARC64_LS_FAULT_X(0)
        !           247: #define TME_STP103X_LS_FAULT_PRIVILEGE         _TME_SPARC64_LS_FAULT_X(1)
        !           248: #define TME_STP103X_LS_FAULT_PROTECTION                _TME_SPARC64_LS_FAULT_X(2)
        !           249: #define TME_STP103X_LS_FAULT_ILLEGAL           _TME_SPARC64_LS_FAULT_X(3)
        !           250: 
        !           251: /* update flags: */
        !           252: #define TME_STP103X_UPDATE_NONE                        (0)
        !           253: #define TME_STP103X_UPDATE_DMMU                        TME_BIT(0)
        !           254: #define TME_STP103X_UPDATE_IMMU                        (0)
        !           255: #define TME_STP103X_UPDATE_MMU_TAG_ACCESS      TME_BIT(1)
        !           256: #define TME_STP103X_UPDATE_MMU_SFSR            TME_BIT(2)
        !           257: #define TME_STP103X_UPDATE_DMMU_SFAR           TME_BIT(3)
        !           258: 
        !           259: /* the first IMMU and DMMU TLB entry parts: */
        !           260: #define TME_STP103X_TLB_PART_0_DMMU            (TME_STP103X_TLB_SIZE * 2 * 0)
        !           261: #define TME_STP103X_TLB_PART_0_IMMU            (TME_STP103X_TLB_SIZE * 2 * 1)
        !           262: 
        !           263: /* this returns nonzero if this is an stp1030: */
        !           264: #define TME_STP103X_IS_1030(ic)                        (TME_STP103X(ic)->tme_stp103x_is_1030)
        !           265: 
        !           266: /* types: */
        !           267: 
        !           268: /* the stp103x DMMU and IMMU common state: */
        !           269: struct tme_stp103x_mmu {
        !           270: 
        !           271:   /* the DMMU or IMMU synchronous fault status register: */
        !           272:   tme_uint64_t tme_stp103x_mmu_sfsr;
        !           273: 
        !           274:   /* the DMMU or IMMU tag access register: */
        !           275:   tme_uint64_t tme_stp103x_mmu_tag_access;
        !           276: 
        !           277:   /* the DMMU or IMMU translation storage buffer register: */
        !           278:   tme_uint64_t tme_stp103x_mmu_tsb;
        !           279: };
        !           280: 
        !           281: /* the stp103x state: */
        !           282: struct tme_stp103x {
        !           283: 
        !           284:   /* the generic sparc state: */
        !           285:   struct tme_sparc tme_stp103x_sparc;
        !           286: 
        !           287:   /* the tick comparison register: */
        !           288:   tme_uint64_t tme_stp103x_tcr;
        !           289: 
        !           290:   /* the softint register: */
        !           291:   tme_uint16_t tme_stp103x_sir;
        !           292:   tme_memory_atomic_flag_t tme_stp103x_sir_tick_int;
        !           293: 
        !           294:   /* the dispatch control register: */
        !           295:   tme_uint8_t tme_stp103x_dcr;
        !           296: 
        !           297:   /* this is nonzero if this is an stp1030: */
        !           298:   tme_uint8_t tme_stp103x_is_1030;
        !           299: 
        !           300:   /* the performance control register: */
        !           301:   tme_uint16_t tme_stp103x_pcr;
        !           302: 
        !           303:   /* the performance instrumentation counters: */
        !           304:   union tme_value64 tme_stp103x_pic;
        !           305: 
        !           306:   /* the UPA configuration register: */
        !           307:   tme_uint64_t tme_stp103x_upa_config;
        !           308: 
        !           309:   /* the load/store unit control register: */
        !           310:   tme_uint64_t tme_stp103x_lsu;
        !           311: 
        !           312:   /* the estate error enable register: */
        !           313:   tme_uint32_t tme_stp103x_estate_error_enable;
        !           314: 
        !           315:   /* the ecache tag data register: */
        !           316:   tme_uint32_t tme_stp103x_ecache_tag_data;
        !           317: 
        !           318:   /* the ecache probe line: */
        !           319:   tme_uint64_t tme_stp103x_ecache_data_probe;
        !           320: 
        !           321:   /* the transmit and receive interrupt vector data: */
        !           322:   tme_uint64_t tme_stp103x_udb_intr_transmit[3];
        !           323:   tme_shared tme_uint64_t tme_stp103x_udb_intr_receive[3];
        !           324:   tme_shared tme_uint8_t tme_stp103x_intr_receive_mid;
        !           325:   tme_memory_atomic_flag_t tme_stp103x_intr_receive_busy;
        !           326: 
        !           327:   /* the tick compare condition and time: */
        !           328:   tme_cond_t tme_stp103x_tick_compare_cond;
        !           329:   struct timeval tme_stp103x_tick_compare_time;
        !           330: 
        !           331:   /* the UDB low and high control registers: */
        !           332:   tme_uint16_t tme_stp103x_udb_control[2];
        !           333: 
        !           334:   /* the asynchronous fault address and status registers: */
        !           335:   tme_uint64_t tme_stp103x_afar;
        !           336:   tme_uint64_t tme_stp103x_afsr;
        !           337: 
        !           338:   /* the DMMU and IMMU common state: */
        !           339:   struct tme_stp103x_mmu tme_stp103x_immu;
        !           340:   struct tme_stp103x_mmu tme_stp103x_dmmu;
        !           341: 
        !           342:   /* the DMMU synchronous fault address register: */
        !           343:   tme_uint64_t tme_stp103x_dmmu_sfar;
        !           344: 
        !           345:   /* this is nonzero if the last fast_data_access_protection trap was
        !           346:      for a 64KB page: */
        !           347:   tme_uint8_t tme_stp103x_dmmu_direct_64KB;
        !           348: 
        !           349:   /* the DMMU and IMMU TLB: */
        !           350:   /* NB: this single array is half IMMU TLB, half DMMU TLB, and each
        !           351:      entry has two parts: tag and data: */
        !           352:   union {
        !           353:     tme_uint64_t _tme_stp103x_tlb_u_64s[2 * 2 * TME_STP103X_TLB_SIZE];
        !           354: #define tme_stp103x_tlb_64s(x) _tme_stp103x_tlb_u._tme_stp103x_tlb_u_64s[x]
        !           355:     tme_uint32_t _tme_stp103x_tlb_u_32s[2 * 4 * TME_STP103X_TLB_SIZE];
        !           356: #if (TME_ENDIAN_NATIVE != TME_ENDIAN_BIG) && (TME_ENDIAN_NATIVE != TME_ENDIAN_LITTLE)
        !           357: #error "only big- and little-endian hosts are supported"
        !           358: #endif
        !           359: #define tme_stp103x_tlb_32s(x, y) _tme_stp103x_tlb_u._tme_stp103x_tlb_u_32s[((x) * 2) + ((y) ^ (TME_ENDIAN_NATIVE == TME_ENDIAN_BIG))]
        !           360:   } _tme_stp103x_tlb_u;
        !           361: };
        !           362: 
        !           363: /* globals: */
        !           364: 
        !           365: /* the cacheable access bus router: */
        !           366: static const tme_bus_lane_t _tme_stp103x_bus_router_cacheable[1 << TME_BUS128_LOG2][1 << TME_BUS128_LOG2] = {
        !           367:   /* a byte access: */
        !           368:   {
        !           369:     TME_BUS_LANE_ROUTE(0),
        !           370:     TME_BUS_LANE_UNDEF,
        !           371:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF,
        !           372:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF,
        !           373:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF,
        !           374:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF
        !           375:   },
        !           376:   /* a word access: */
        !           377:   {
        !           378:     TME_BUS_LANE_ROUTE(1),
        !           379:     TME_BUS_LANE_ROUTE(0),
        !           380:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF,
        !           381:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF,
        !           382:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF,
        !           383:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF
        !           384:   },
        !           385:   /* a doubleword access: */
        !           386:   {
        !           387:     TME_BUS_LANE_ROUTE(3),
        !           388:     TME_BUS_LANE_ROUTE(2),
        !           389:     TME_BUS_LANE_ROUTE(1),
        !           390:     TME_BUS_LANE_ROUTE(0),
        !           391:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF,
        !           392:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF,
        !           393:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF
        !           394:   },
        !           395:   /* an extended word access: */
        !           396:   {
        !           397:     TME_BUS_LANE_ROUTE(7),
        !           398:     TME_BUS_LANE_ROUTE(6),
        !           399:     TME_BUS_LANE_ROUTE(5),
        !           400:     TME_BUS_LANE_ROUTE(4),
        !           401:     TME_BUS_LANE_ROUTE(3),
        !           402:     TME_BUS_LANE_ROUTE(2),
        !           403:     TME_BUS_LANE_ROUTE(1),
        !           404:     TME_BUS_LANE_ROUTE(0),
        !           405:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF,
        !           406:     TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF, TME_BUS_LANE_UNDEF
        !           407:   },
        !           408:   /* a quadword access: */
        !           409:   {
        !           410:     TME_BUS_LANE_ROUTE(15),
        !           411:     TME_BUS_LANE_ROUTE(14),
        !           412:     TME_BUS_LANE_ROUTE(13),
        !           413:     TME_BUS_LANE_ROUTE(12),
        !           414:     TME_BUS_LANE_ROUTE(11),
        !           415:     TME_BUS_LANE_ROUTE(10),
        !           416:     TME_BUS_LANE_ROUTE(9),
        !           417:     TME_BUS_LANE_ROUTE(8),
        !           418:     TME_BUS_LANE_ROUTE(7),
        !           419:     TME_BUS_LANE_ROUTE(6),
        !           420:     TME_BUS_LANE_ROUTE(5),
        !           421:     TME_BUS_LANE_ROUTE(4),
        !           422:     TME_BUS_LANE_ROUTE(3),
        !           423:     TME_BUS_LANE_ROUTE(2),
        !           424:     TME_BUS_LANE_ROUTE(1),
        !           425:     TME_BUS_LANE_ROUTE(0),
        !           426:   }
        !           427: };
        !           428: 
        !           429: /* this maps a virtual address: */
        !           430: static void _tme_stp103x_ls_address_map _TME_P((struct tme_sparc *, struct tme_sparc_ls *));
        !           431: 
        !           432: /* this makes a never struct timeval: */
        !           433: static inline void
        !           434: tme_misc_timeval_never(struct timeval *tv)
        !           435: {
        !           436:   tv->tv_sec = 0;
        !           437:   tv->tv_sec--;
        !           438:   if (tv->tv_sec < 1) {
        !           439:     tv->tv_sec = 1;
        !           440:     tv->tv_sec <<= ((8 * sizeof(tv->tv_sec)) - 2);
        !           441:     tv->tv_sec += (tv->tv_sec - 1);
        !           442:   }
        !           443:   tv->tv_usec = 999999;
        !           444: }
        !           445: 
        !           446: /* this does an interrupt check: */
        !           447: /* NB: this may do a preinstruction trap: */
        !           448: static void
        !           449: _tme_stp103x_interrupt_check(struct tme_sparc *ic,
        !           450:                             int flags)
        !           451: {
        !           452:   tme_uint32_t sir;
        !           453:   tme_uint32_t ipl;
        !           454:   tme_uint32_t trap;
        !           455: 
        !           456:   /* if we're replaying instructions, return now: */
        !           457:   if (tme_sparc_recode_verify_replay_last_pc(ic) != 0) {
        !           458:     return;
        !           459:   }
        !           460: 
        !           461:   /* if PSTATE.IE is clear, return now: */
        !           462:   if ((ic->tme_sparc64_ireg_pstate & TME_SPARC64_PSTATE_IE) == 0) {
        !           463:     return;
        !           464:   }
        !           465: 
        !           466:   /* if the incoming interrupt vector data is busy: */
        !           467:   if (tme_memory_atomic_read_flag(&TME_STP103X(ic)->tme_stp103x_intr_receive_busy)) {
        !           468: 
        !           469:     /* start interrupt vector trap processing: */
        !           470:     trap = TME_STP103X_TRAP_interrupt_vector;
        !           471:   }
        !           472: 
        !           473:   /* otherwise, the incoming interrupt vector data is not busy: */
        !           474:   else {
        !           475: 
        !           476:     /* if no SOFTINT bits greater than PIL are set, return now: */
        !           477:     sir = TME_STP103X(ic)->tme_stp103x_sir;
        !           478:     if (tme_memory_atomic_read_flag(&TME_STP103X(ic)->tme_stp103x_sir_tick_int)) {
        !           479:       sir |= TME_STP103X_SIR_SOFTINT(14);
        !           480:     }
        !           481:     ipl = ic->tme_sparc64_ireg_pil + 1;
        !           482:     sir >>= ipl;
        !           483:     if (sir == 0) {
        !           484:       return;
        !           485:     }
        !           486: 
        !           487:     /* get the greatest SOFTINT bit greater than PIL that is set: */
        !           488:     for (; sir != 1; sir >>= 1, ipl++);
        !           489: 
        !           490:     /* start interrupt trap processing: */
        !           491:     trap = TME_SPARC64_TRAP_interrupt_level(ipl);
        !           492:   }
        !           493: 
        !           494:   /* start trap processing: */
        !           495:   if (flags & TME_SPARC_EXTERNAL_CHECK_MUTEX_LOCKED) {
        !           496:     tme_mutex_unlock(&ic->tme_sparc_external_mutex);
        !           497:   }
        !           498:   if (flags & TME_SPARC_EXTERNAL_CHECK_PCS_UPDATED) {
        !           499:     ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_PC_NEXT_NEXT) = ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_PC_NEXT);
        !           500:     ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_PC_NEXT) = ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_PC);
        !           501: #ifdef _TME_SPARC_RECODE_VERIFY
        !           502:     ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_PC) = TME_SPARC_RECODE_VERIFY_PC_NONE;
        !           503: #endif /* _TME_SPARC_RECODE_VERIFY */
        !           504:   }  
        !           505:   tme_sparc64_trap_preinstruction(ic, trap);
        !           506: }
        !           507: 
        !           508: /* this updates the SIR: */
        !           509: /* NB: this may do a preinstruction trap: */
        !           510: static void
        !           511: _tme_stp103x_update_sir(struct tme_sparc *ic,
        !           512:                        tme_uint32_t sir_andn,
        !           513:                        tme_uint32_t sir_or)
        !           514: {
        !           515: 
        !           516:   /* if we're clearing SIR.TICK_INT: */
        !           517:   if (sir_andn & TME_STP103X_SIR_TICK_INT) {
        !           518: 
        !           519:     /* do an interrupt check: */
        !           520:     _tme_stp103x_interrupt_check(ic, TME_SPARC_EXTERNAL_CHECK_PCS_UPDATED);
        !           521:     
        !           522:     /* clear the tick interrupt atomic flag: */
        !           523:     tme_memory_atomic_write_flag(&TME_STP103X(ic)->tme_stp103x_sir_tick_int, FALSE);
        !           524:   }
        !           525: 
        !           526:   /* if we're setting SIR.TICK_INT: */
        !           527:   if (sir_or & TME_STP103X_SIR_TICK_INT) {
        !           528: 
        !           529:     /* set the tick interrupt atomic flag: */
        !           530:     tme_memory_atomic_write_flag(&TME_STP103X(ic)->tme_stp103x_sir_tick_int, TRUE);
        !           531: 
        !           532:     /* we won't set SIR.TICK_INT in the normal SIR image: */
        !           533:     sir_or ^= TME_STP103X_SIR_TICK_INT;
        !           534:   }
        !           535: 
        !           536:   /* update all other bits in SIR: */
        !           537:   TME_STP103X(ic)->tme_stp103x_sir
        !           538:     = ((TME_STP103X(ic)->tme_stp103x_sir
        !           539:        & ~sir_andn)
        !           540:        | sir_or);
        !           541: 
        !           542:   /* do an interrupt check: */
        !           543:   _tme_stp103x_interrupt_check(ic, TME_SPARC_EXTERNAL_CHECK_NULL);
        !           544: }
        !           545: 
        !           546: /* this updates the LSU control register: */
        !           547: static void
        !           548: _tme_stp103x_update_lsu(struct tme_sparc *ic, tme_uint64_t lsu_new)
        !           549: {
        !           550:   tme_uint64_t lsu_xor;
        !           551:   struct tme_sparc_tlb *tlb;
        !           552: 
        !           553:   /* get a change mask: */
        !           554:   lsu_xor = lsu_new ^ TME_STP103X(ic)->tme_stp103x_lsu;
        !           555: 
        !           556:   /* if LSU.IC or LSU.DC are changing: */
        !           557:   if (lsu_xor
        !           558:       & (TME_STP103X_LSU_IC
        !           559:         | TME_STP103X_LSU_DC)) {
        !           560: 
        !           561:     /* nothing to do, since we don't emulate the caches: */
        !           562:   }
        !           563: 
        !           564:   /* if LSU.IM or LSU.DM are changing: */
        !           565:   if (lsu_xor
        !           566:       & (TME_STP103X_LSU_IM
        !           567:         | TME_STP103X_LSU_DM)) {
        !           568: 
        !           569:     /* invalidate all of the sparc TLB entries: */
        !           570:     tlb = &ic->tme_sparc_tlbs[0];
        !           571:     do {
        !           572:       tme_token_invalidate_nosync(tlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_token);
        !           573:     } while (++tlb <= &ic->tme_sparc_tlbs[TME_ARRAY_ELS(ic->tme_sparc_tlbs) - 1]);
        !           574:   }
        !           575: 
        !           576:   /* if LSU.FM is changing: */
        !           577:   if (lsu_xor & TME_STP103X_LSU_FM) {
        !           578:     /* XXX FIXME WRITEME: */
        !           579:     abort();
        !           580:   }
        !           581: 
        !           582:   /* if any of LSU.VR, LSU.VW, LSU.PR, LSU.PW are changing: */
        !           583:   if (lsu_xor
        !           584:       & (TME_STP103X_LSU_VR
        !           585:         | TME_STP103X_LSU_VW
        !           586:         | TME_STP103X_LSU_PR
        !           587:         | TME_STP103X_LSU_PW)) {
        !           588:     /* XXX FIXME WRITEME: */
        !           589:     abort();
        !           590:   }
        !           591: 
        !           592:   /* update the register: */
        !           593:   TME_STP103X(ic)->tme_stp103x_lsu = lsu_new;
        !           594: }
        !           595: 
        !           596: /* this updates the UPA configuration register: */
        !           597: static void
        !           598: _tme_stp103x_update_upa_config(struct tme_sparc *ic, tme_uint64_t upa_config)
        !           599: {
        !           600: 
        !           601:   /* if this is an STP1030: */
        !           602:   if (TME_STP103X_IS_1030(ic)) {
        !           603: 
        !           604:     /* only the PCON field is writable: */
        !           605:     upa_config &= TME_STP1030_UPA_CONFIG_PCON;
        !           606:   }
        !           607: 
        !           608:   /* otherwise, this is an STP1031: */
        !           609:   else {
        !           610: 
        !           611:     /* only the PCON and ELIM fields are writable: */
        !           612:     upa_config
        !           613:       &= (TME_STP1031_UPA_CONFIG_PCON
        !           614:          | TME_STP1031_UPA_CONFIG_ELIM);
        !           615: 
        !           616:     /* all read-only STP1031-specific fields are hardwired to zero: */
        !           617:   }
        !           618: 
        !           619:   /* add the MID: */
        !           620:   upa_config += (ic->_tme_upa_bus_connection->tme_upa_bus_connection_mid << 17);
        !           621: 
        !           622:   /* add the PCAP fields: */
        !           623:   upa_config
        !           624:     += ((TME_STP103X_UPA_PINT_RDQ << 15)
        !           625:        + (TME_STP103X_UPA_PREQ_DQ << 9)
        !           626:        + (TME_STP103X_UPA_PREQ_RQ << 5)
        !           627:        + (TME_STP103X_UPA_UPACAP << 0));
        !           628: 
        !           629:   /* set the UPA configuration register: */
        !           630:   TME_STP103X(ic)->tme_stp103x_upa_config = upa_config;
        !           631: }
        !           632: 
        !           633: /* this handles a PSTATE update: */
        !           634: /* NB: this may do a preinstruction trap: */
        !           635: static void
        !           636: _tme_stp103x_update_pstate(struct tme_sparc *ic,
        !           637:                           tme_uint32_t pstate,
        !           638:                           tme_uint32_t trap)
        !           639: {
        !           640:   tme_uint64_t lsu_new;
        !           641:   tme_uint32_t pstate_xor;
        !           642:   tme_uint64_t address_mask;
        !           643: 
        !           644:   /* if we are in RED_state: */
        !           645:   if (pstate & TME_SPARC64_PSTATE_RED) {
        !           646: 
        !           647:     /* traps that enter RED_state, and traps in RED_state, always
        !           648:        clear the LSU_Control_Register.  a write of one to PSTATE.RED
        !           649:        only clears LSU.IM: */
        !           650:     lsu_new
        !           651:       = (trap != TME_SPARC_TRAP_none
        !           652:         ? 0
        !           653:         : (TME_STP103X(ic)->tme_stp103x_lsu
        !           654:            & ~ (tme_uint64_t) TME_STP103X_LSU_IM));
        !           655:     _tme_stp103x_update_lsu(ic, lsu_new);
        !           656: 
        !           657:     /* if this is a power-on reset: */
        !           658:     if (trap == TME_SPARC64_TRAP_power_on_reset) {
        !           659:     
        !           660:       /* a POR clears the E-Cache (E-State) error enable register: */
        !           661:       TME_STP103X(ic)->tme_stp103x_estate_error_enable = 0;
        !           662: 
        !           663:       /* a POR zeroes the writable fields in the UPA configuration
        !           664:         register: */
        !           665:       _tme_stp103x_update_upa_config(ic, 0);
        !           666:     }
        !           667:   }
        !           668: 
        !           669:   /* if this is a trap that uses the MMU globals: */
        !           670:   if (trap & TME_STP103X_TRAP_MG) {
        !           671:     assert (trap != TME_SPARC_TRAP_none);
        !           672:     pstate
        !           673:       = ((pstate
        !           674:          & ~(TME_SPARC64_PSTATE_AG
        !           675:              + TME_STP103X_PSTATE_MG
        !           676:              + TME_STP103X_PSTATE_IG))
        !           677:         + TME_STP103X_PSTATE_MG);
        !           678:   }
        !           679: 
        !           680:   /* otherwise, if this is a trap that uses the interrupt globals: */
        !           681:   else if (trap & TME_STP103X_TRAP_IG) {
        !           682:     assert (trap != TME_SPARC_TRAP_none);
        !           683:     pstate
        !           684:       = ((pstate
        !           685:          & ~(TME_SPARC64_PSTATE_AG
        !           686:              + TME_STP103X_PSTATE_MG
        !           687:              + TME_STP103X_PSTATE_IG))
        !           688:         + TME_STP103X_PSTATE_IG);
        !           689:   }
        !           690: 
        !           691:   /* otherwise, if this is another trap: */
        !           692:   else if (trap != TME_SPARC_TRAP_none) {
        !           693:     pstate
        !           694:       &= ~(TME_STP103X_PSTATE_IG
        !           695:           + TME_STP103X_PSTATE_MG);
        !           696:     assert (pstate & TME_SPARC64_PSTATE_AG);
        !           697:   }
        !           698: 
        !           699:   /* the global register selection can't be reserved: */
        !           700:   assert ((((pstate & TME_SPARC64_PSTATE_AG) != 0)
        !           701:           + ((pstate & TME_STP103X_PSTATE_MG) != 0)
        !           702:           + ((pstate & TME_STP103X_PSTATE_IG) != 0)) < 2);
        !           703: 
        !           704:   /* update the global register offset: */
        !           705:   ic->tme_sparc_reg8_offset[0]
        !           706:     = ((pstate & TME_SPARC64_PSTATE_AG)
        !           707: #if (TME_SPARC64_IREG_AG_G0 % 8)
        !           708: #error "TME_SPARC64_IREG_AG_G0 must be a multiple of eight"
        !           709: #endif
        !           710:        ? (TME_SPARC64_IREG_AG_G0 / 8)
        !           711:        : (pstate & TME_STP103X_PSTATE_MG)
        !           712: #if (TME_SPARC64_IREG_MG_G0 % 8)
        !           713: #error "TME_SPARC64_IREG_MG_G0 must be a multiple of eight"
        !           714: #endif
        !           715:        ? (TME_SPARC64_IREG_MG_G0 / 8)
        !           716:        : (pstate & TME_STP103X_PSTATE_IG)
        !           717: #if (TME_SPARC64_IREG_IG_G0 % 8)
        !           718: #error "TME_SPARC64_IREG_IG_G0 must be a multiple of eight"
        !           719: #endif
        !           720:        ? (TME_SPARC64_IREG_IG_G0 / 8)
        !           721: #if (TME_SPARC_IREG_G0 % 8)
        !           722: #error "TME_SPARC_IREG_G0 must be a multiple of eight"
        !           723: #endif
        !           724:        : (TME_SPARC_IREG_G0 / 8));
        !           725:   _TME_SPARC_RECODE_CWP_UPDATE(ic, tme_uint64_t);
        !           726: 
        !           727:   /* make sure that %g0 is zero in the normal global register set and
        !           728:      the current global register set.  recode instructions thunks
        !           729:      always refer to %g0 in the normal global register set: */
        !           730:   ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_G0) = 0;
        !           731:   ic->tme_sparc_ireg_uint64(TME_SPARC_G0_OFFSET(ic) + TME_SPARC_IREG_G0) = 0;
        !           732: 
        !           733:   /* get the changing bits in PSTATE: */
        !           734:   pstate_xor = ic->tme_sparc64_ireg_pstate ^ pstate;
        !           735: 
        !           736: #if TME_HAVE_RECODE && TME_RECODE_SIZE_GUEST_MAX > TME_RECODE_SIZE_32
        !           737:   
        !           738:   /* if PSTATE.AM and/or PSTATE.CLE are changing: */
        !           739:   if (__tme_predict_false(pstate_xor
        !           740:                          & (TME_SPARC64_PSTATE_AM
        !           741:                             | TME_SPARC64_PSTATE_CLE
        !           742:                             ))) {
        !           743: 
        !           744:     /* clear the return address stack, since chaining doesn't check that
        !           745:        PSTATE matches instructions thunks: */
        !           746:     tme_recode_chain_ras_clear(ic->tme_sparc_recode_ic,
        !           747:                               &ic->tme_sparc_ic);
        !           748:   }
        !           749: 
        !           750: #endif /* TME_HAVE_RECODE && TME_RECODE_SIZE_GUEST_MAX > TME_RECODE_SIZE_32 */
        !           751: 
        !           752:   /* set PSTATE: */
        !           753:   ic->tme_sparc64_ireg_pstate = pstate;
        !           754: 
        !           755:   /* update the address mask: */
        !           756:   address_mask
        !           757:     = ((0 - (tme_uint64_t) ((~pstate / TME_SPARC64_PSTATE_AM) & 1))
        !           758:        | (tme_uint32_t) (0 - (tme_uint32_t) 1));
        !           759:   ic->tme_sparc_address_mask = address_mask;
        !           760: 
        !           761:   /* mask the PCs: */
        !           762:   ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_PC_NEXT) &= address_mask;
        !           763:   ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_PC_NEXT_NEXT) &= address_mask;
        !           764: 
        !           765:   /* if interrupts are enabled, we can't be trapping, because
        !           766:      _tme_stp103x_interrupt_check() might trap with an interrupt,
        !           767:      discarding the initial trap: */
        !           768:   assert ((pstate & TME_SPARC64_PSTATE_IE) == 0
        !           769:          || trap == TME_SPARC_TRAP_none);
        !           770: 
        !           771:   /* do an interrupt check: */
        !           772:   _tme_stp103x_interrupt_check(ic, TME_SPARC_EXTERNAL_CHECK_NULL);
        !           773: }
        !           774: 
        !           775: /* this updates the AFSR: */
        !           776: static void
        !           777: _tme_stp103x_update_afsr(struct tme_sparc *ic, tme_uint64_t afsr_reset)
        !           778: {
        !           779: 
        !           780:   /* one bits in positions 20..32 clear those bits in the AFSR: */
        !           781:   TME_STP103X(ic)->tme_stp103x_afsr
        !           782:     &= ~(afsr_reset
        !           783:         & ((((tme_uint64_t) 1) << (32 + 1)) - (1 << 20)));
        !           784: }
        !           785: 
        !           786: /* this updates the interrupt vector receive: */
        !           787: static void
        !           788: _tme_stp103x_update_intr_receive(struct tme_sparc *ic, tme_uint64_t intr_receive)
        !           789: {
        !           790:   tme_memory_atomic_write_flag(&TME_STP103X(ic)->tme_stp103x_intr_receive_busy,
        !           791:                               (intr_receive & TME_STP103X_INTR_RECEIVE_BUSY) != 0);
        !           792: }
        !           793: 
        !           794: /* the stp103x rdasr: */
        !           795: static
        !           796: TME_SPARC_FORMAT3(_tme_stp103x_rdasr, tme_uint64_t)
        !           797: {
        !           798:   unsigned int reg_rs1;
        !           799:   tme_uint64_t value;
        !           800: 
        !           801:   /* if this is an implementation-specific ASR: */
        !           802:   if (TME_SPARC_INSN & (0x10 << 14)) {
        !           803: 
        !           804:     /* get rs1: */
        !           805:     reg_rs1 = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RS1);
        !           806: 
        !           807:     /* if this is an undefined implementation-specific ASR: */
        !           808:     if (__tme_predict_false(reg_rs1 >= 0x18)) {
        !           809:       TME_SPARC_INSN_ILL(ic);
        !           810:     }
        !           811: 
        !           812:     /* if this is a read of GSR: */
        !           813:     if (reg_rs1 == 0x13) {
        !           814:       if (__tme_predict_false((ic->tme_sparc64_ireg_pstate & TME_SPARC64_PSTATE_PEF) == 0
        !           815:                              || (ic->tme_sparc64_ireg_fprs & TME_SPARC64_FPRS_FEF) == 0)) {
        !           816:        tme_sparc64_trap(ic, TME_SPARC64_TRAP_fp_disabled);
        !           817:       }
        !           818:       value = ic->tme_sparc_vis_gsr;
        !           819:     }
        !           820: 
        !           821:     /* otherwise, this is not a read of GSR: */
        !           822:     else {
        !           823: 
        !           824:       /* if this is a nonprivileged read: */
        !           825:       if (__tme_predict_false(!TME_SPARC_PRIV(ic))) {
        !           826: 
        !           827:        /* if this is not a read of PIC, or if PCR.PRIV is set: */
        !           828:        if (reg_rs1 != 0x11
        !           829:            || (TME_STP103X(ic)->tme_stp103x_pcr & TME_BIT(0))) {
        !           830:          tme_sparc64_trap(ic, TME_SPARC64_TRAP_privileged_opcode);
        !           831:        }
        !           832:       }
        !           833: 
        !           834:       /* dispatch on rs1: */
        !           835:       switch (reg_rs1) {
        !           836:       default: TME_SPARC_INSN_ILL(ic);
        !           837:       case 0x10: value = TME_STP103X(ic)->tme_stp103x_pcr; break;
        !           838:       case 0x11: value = TME_STP103X(ic)->tme_stp103x_pic.tme_value64_uint; break;
        !           839:       case 0x12: value = TME_STP103X(ic)->tme_stp103x_dcr; break;
        !           840:       case 0x16: 
        !           841:        value = TME_STP103X(ic)->tme_stp103x_sir;
        !           842:        if (tme_memory_atomic_read_flag(&TME_STP103X(ic)->tme_stp103x_sir_tick_int)) {
        !           843:          value += TME_STP103X_SIR_TICK_INT;
        !           844:        }
        !           845:        break;
        !           846:       case 0x17: value = TME_STP103X(ic)->tme_stp103x_tcr; break;
        !           847:       }
        !           848:     }
        !           849:     TME_SPARC_FORMAT3_RD = value;
        !           850:     TME_SPARC_INSN_OK;
        !           851:   }
        !           852:   tme_sparc64_rdasr(ic, _rs1, _rs2, _rd);
        !           853: }
        !           854: 
        !           855: /* the stp103x rdpr: */
        !           856: static
        !           857: TME_SPARC_FORMAT3(_tme_stp103x_rdpr, tme_uint64_t)
        !           858: {
        !           859:   unsigned long offset_in_insns;
        !           860:   tme_uint32_t delay_factor;
        !           861:   tme_uint32_t insn;
        !           862:   const struct tme_sparc_tlb *itlb_current;
        !           863:   
        !           864:   /* the PROM (at least, SUNW,501-3082-update7.bin) calculates a delay
        !           865:      factor by waiting for a timer interrupt while running these two
        !           866:      instructions:
        !           867: 
        !           868:      f0055720: 10 80 00 00     b  0xf0055720
        !           869:      f0055724: a4 04 a0 01     inc  %l2
        !           870: 
        !           871:      the PROM then does a delay by running these two instructions:
        !           872: 
        !           873:      f00557e0: 14 68 00 00     bg  %xcc, 0xf00557e0
        !           874:      f00557e4: a2 a4 60 01     deccc  %l1
        !           875: 
        !           876:      unfortunately, in the stp103x emulation, a deccc is more
        !           877:      expensive than an inc, because it must update the condition
        !           878:      codes.  the difference is significant enough to cause what
        !           879:      should be a brief delay between these two PROM messages:
        !           880: 
        !           881:      Probing Memory Bank #3   0 +   0 :   0 Megabytes
        !           882:      Probing /sbus@1f,0 at 0,0  Nothing there
        !           883: 
        !           884:      to be very, very long.  the cost difference appears to be even
        !           885:      worse when recode is on, and the extreme delay gives the user the
        !           886:      impression that the emulator is stuck.
        !           887: 
        !           888:      there's a chance that there's a cost difference between inc and
        !           889:      deccc even on a real stp103x; "1000 ms" on the PROM on a real
        !           890:      Ultra-1 delays noticeably longer than one second.
        !           891: 
        !           892:      this function is a gross hack that attempts to reduce the delay.
        !           893:      it modifies the original loop that calculates the delay factor to
        !           894:      use (for the "best" factor) an inccc instruction instead of a
        !           895:      inc, to make it more symmetric with the delay loop.
        !           896: 
        !           897:      it detects the original loop by this instruction that precedes it:
        !           898: 
        !           899:      f0055708: a7 51 00 00     rdpr  %tick, %l3
        !           900:   */
        !           901: 
        !           902:   /* if this is a "rdpr %tick, %l3" instruction: */
        !           903:   if (__tme_predict_false(TME_SPARC_INSN == 0xa7510000)) {
        !           904: 
        !           905:     /* get the offset, in units of instructions, to the next PC that
        !           906:        is I-Cache block aligned: */
        !           907:     offset_in_insns = ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_PC);
        !           908:     offset_in_insns = ~offset_in_insns;
        !           909:     offset_in_insns %= TME_STP103X_ICACHE_BLOCK_SIZE;
        !           910:     offset_in_insns = (offset_in_insns + 1) / sizeof(TME_SPARC_INSN);
        !           911: 
        !           912:     /* if the CPU is in privileged mode, and the first two
        !           913:        instructions at that PC are "b ." and "inc %l2": */
        !           914:     if (TME_SPARC_PRIV(ic)
        !           915:        && tme_sparc_fetch_nearby(ic, offset_in_insns + 0) == 0x10800000
        !           916:        && tme_sparc_fetch_nearby(ic, offset_in_insns + 1) == 0xa404a001) {
        !           917: 
        !           918:       /* if the PROM delay factor is to be corrected: */
        !           919:       delay_factor = ic->tme_sparc_prom_delay_factor;
        !           920:       if (delay_factor != TME_SPARC_PROM_DELAY_FACTOR_UNCORRECTED) {
        !           921: 
        !           922:        /* if the PROM delay factor correction is "min": */
        !           923:        if (delay_factor == TME_SPARC_PROM_DELAY_FACTOR_MIN) {
        !           924: 
        !           925:          /* the delay factor is calculated by running the loop for
        !           926:             64ms and then dividing the count by 64, so a raw count of
        !           927:             64 will get the minimum delay: */
        !           928:          delay_factor = 64;
        !           929:        }
        !           930: 
        !           931:        /* if the PROM delay factor correction is "best": */
        !           932:        if (delay_factor == TME_SPARC_PROM_DELAY_FACTOR_BEST) {
        !           933: 
        !           934:          /* modify the "inc %l2" to be "inccc %l2": */
        !           935:          insn = 0xa484a001;
        !           936:        }
        !           937: 
        !           938:        /* otherwise, the PROM delay factor is given directly: */
        !           939:        else {
        !           940: 
        !           941:          /* modify the "inc %l2" to be "or %g0, simm13, %l2": */
        !           942:          insn = 0xa4102000 + TME_MIN(delay_factor, 0xfff);
        !           943:        }
        !           944: 
        !           945:        /* get the current instruction TLB entry: */
        !           946:        /* NB: we don't repeat the assert()s or the address-covering
        !           947:           checks of tme_sparc_fetch_nearby(): */
        !           948:        itlb_current = tme_sparc_itlb_current(ic);
        !           949: 
        !           950:        /* modify the "inc %l2": */
        !           951:        /* NB: we break const here: */
        !           952:        ((tme_shared tme_uint32_t *)
        !           953:         (unsigned long) 
        !           954:         (itlb_current->tme_sparc_tlb_emulator_off_read
        !           955:          + ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_PC)))
        !           956:          [offset_in_insns + 1] = tme_htobe_u32(insn);
        !           957: 
        !           958:        /* NB: we don't invalidate the memory page that we just modified
        !           959:           (in the tme_sparc_recode_cacheable_valids sense), because we
        !           960:           assume that the loop that calculates the delay factor hasn't
        !           961:           been recoded yet, and we assume that no other CPUs or other
        !           962:           bus masters care about the modification: */
        !           963:       }
        !           964:     }
        !           965:   }
        !           966: 
        !           967:   /* do the normal rdpr: */
        !           968:   tme_sparc64_rdpr(ic, _rs1, _rs2, _rd);
        !           969: }
        !           970: 
        !           971: /* the stp103x wrasr: */
        !           972: static
        !           973: TME_SPARC_FORMAT3(_tme_stp103x_wrasr, tme_uint64_t)
        !           974: {
        !           975:   tme_uint64_t value_xor;
        !           976:   unsigned int reg_rd;
        !           977:   tme_uint64_t tick;
        !           978:   struct timeval tick_compare_time;
        !           979:   tme_uint64_t cycles_scaled;
        !           980:   tme_uint64_t usec64;
        !           981:   tme_uint32_t usec32;
        !           982: 
        !           983:   /* if this is an implementation-specific ASR: */
        !           984:   if (TME_SPARC_INSN & (0x10 << 25)) {
        !           985: 
        !           986:     /* get the value to write: */
        !           987:     value_xor = TME_SPARC_FORMAT3_RS1 ^ TME_SPARC_FORMAT3_RS2;
        !           988: 
        !           989:     /* get rd: */
        !           990:     reg_rd = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, TME_SPARC_FORMAT3_MASK_RD);
        !           991: 
        !           992:     /* if this is an undefined implementation-specific ASR: */
        !           993:     if (__tme_predict_false(reg_rd >= 0x18)) {
        !           994:       TME_SPARC_INSN_ILL(ic);
        !           995:     }
        !           996: 
        !           997:     /* if this is an write to GSR: */
        !           998:     if (reg_rd == 0x13) {
        !           999:       if (__tme_predict_false((ic->tme_sparc64_ireg_pstate & TME_SPARC64_PSTATE_PEF) == 0
        !          1000:                              || (ic->tme_sparc64_ireg_fprs & TME_SPARC64_FPRS_FEF) == 0)) {
        !          1001:        tme_sparc64_trap(ic, TME_SPARC64_TRAP_fp_disabled);
        !          1002:       }
        !          1003:       ic->tme_sparc_vis_gsr = value_xor;
        !          1004:     }
        !          1005: 
        !          1006:     /* otherwise, this is not a write to GSR: */
        !          1007:     else {
        !          1008: 
        !          1009:       /* if this is a nonprivileged write: */
        !          1010:       if (__tme_predict_false(!TME_SPARC_PRIV(ic))) {
        !          1011: 
        !          1012:        /* if this is not a write to PIC, or if PCR.PRIV is set: */
        !          1013:        if (reg_rd != 0x11
        !          1014:            || (TME_STP103X(ic)->tme_stp103x_pcr & TME_BIT(0))) {
        !          1015:          tme_sparc64_trap(ic, TME_SPARC64_TRAP_privileged_action);
        !          1016:        }
        !          1017:       }
        !          1018: 
        !          1019:       /* dispatch on rd: */
        !          1020:       switch (reg_rd) {
        !          1021:       default: assert (FALSE);
        !          1022:       case 0x10: TME_STP103X(ic)->tme_stp103x_pcr = value_xor; break;
        !          1023:       case 0x11: TME_STP103X(ic)->tme_stp103x_pic.tme_value64_uint = value_xor; break;
        !          1024:       case 0x12: TME_STP103X(ic)->tme_stp103x_dcr = value_xor; break;
        !          1025:       case 0x14: _tme_stp103x_update_sir(ic, 0, value_xor); break;
        !          1026:       case 0x15: _tme_stp103x_update_sir(ic, value_xor, 0); break;
        !          1027:       case 0x16: _tme_stp103x_update_sir(ic, 0xffff, value_xor); break;
        !          1028: 
        !          1029:       case 0x17:
        !          1030:        TME_STP103X(ic)->tme_stp103x_tcr = value_xor;
        !          1031: 
        !          1032:        /* if we're not replaying instructions: */
        !          1033:        if (tme_sparc_recode_verify_replay_last_pc(ic) == 0) {
        !          1034: 
        !          1035:          /* if INT_DIS is set: */
        !          1036:          if (__tme_predict_false(value_xor & TME_STP103X_TCR_INT_DIS)) {
        !          1037: 
        !          1038:            /* the tick compare time is never: */
        !          1039:            tme_misc_timeval_never(&tick_compare_time);
        !          1040:          }
        !          1041: 
        !          1042:          /* otherwise, INT_DIS is clear: */
        !          1043:          else {
        !          1044: 
        !          1045:            /* get the current value of TICK.counter: */
        !          1046:            tick = tme_misc_cycles_scaled(&ic->tme_sparc_cycles_scaling, 0).tme_value64_uint;
        !          1047:            tick += ic->tme_sparc64_ireg_tick_offset;
        !          1048:            tick &= TME_SPARC64_TICK_COUNTER;
        !          1049: 
        !          1050:            /* get the current time: */
        !          1051:            gettimeofday(&tick_compare_time, NULL);
        !          1052: 
        !          1053:            /* get the number of cycles until the compare value is
        !          1054:               reached: */
        !          1055:            cycles_scaled = TME_STP103X(ic)->tme_stp103x_tcr - tick;
        !          1056:            cycles_scaled &= TME_SPARC64_TICK_COUNTER;
        !          1057: 
        !          1058:            /* if the number of cycles doesn't fit in 32 bits: */
        !          1059:            if (__tme_predict_false(cycles_scaled > (tme_uint32_t) (0 - (tme_uint32_t) 1))) {
        !          1060: 
        !          1061:              /* convert cycles into microseconds: */
        !          1062:              usec64 = cycles_scaled / ic->tme_sparc_cycles_scaled_per_usec;
        !          1063: 
        !          1064:              /* add in the whole seconds: */
        !          1065:              tick_compare_time.tv_sec += (usec64 / 1000000);
        !          1066: 
        !          1067:              /* get the remaining microseconds: */
        !          1068:              usec32 = (usec64 % 1000000);
        !          1069:            }
        !          1070: 
        !          1071:            /* otherwise, the number of cycles fits in 32 bits: */
        !          1072:            else {
        !          1073: 
        !          1074:              /* convert cycles into microseconds: */
        !          1075:              usec32 = ((tme_uint32_t) cycles_scaled) / ic->tme_sparc_cycles_scaled_per_usec;
        !          1076: 
        !          1077:              /* if there is at least one whole second: */
        !          1078:              if (__tme_predict_false(usec32 >= 1000000)) {
        !          1079: 
        !          1080:                /* add in the whole seconds: */
        !          1081:                tick_compare_time.tv_sec += (usec32 / 1000000);
        !          1082: 
        !          1083:                /* get the remaining microseconds: */
        !          1084:                usec32 %= 1000000;
        !          1085:              }
        !          1086:            }
        !          1087: 
        !          1088:            /* add in the microseconds: */
        !          1089:            usec32 += tick_compare_time.tv_usec;
        !          1090:            if (usec32 >= 1000000) {
        !          1091:              tick_compare_time.tv_sec++;
        !          1092:              usec32 -= 1000000;
        !          1093:            }
        !          1094:            tick_compare_time.tv_usec = usec32;
        !          1095:          }
        !          1096: 
        !          1097:          /* lock the external mutex: */
        !          1098:          tme_mutex_lock(&ic->tme_sparc_external_mutex);
        !          1099: 
        !          1100:          /* set the tick compare time: */
        !          1101:          TME_STP103X(ic)->tme_stp103x_tick_compare_time = tick_compare_time;
        !          1102: 
        !          1103:          /* notify the tick compare thread: */
        !          1104:          tme_cond_notify(&TME_STP103X(ic)->tme_stp103x_tick_compare_cond, FALSE);
        !          1105: 
        !          1106:          /* unlock the external mutex: */
        !          1107:          tme_mutex_unlock(&ic->tme_sparc_external_mutex);
        !          1108:        }
        !          1109:        break;
        !          1110:       }
        !          1111:     }
        !          1112:     TME_SPARC_INSN_OK;
        !          1113:   }
        !          1114:   tme_sparc64_wrasr(ic, _rs1, _rs2, _rd);
        !          1115: }
        !          1116: 
        !          1117: /* the stp103x impdep1: */
        !          1118: static
        !          1119: TME_SPARC_FORMAT3(_tme_stp103x_impdep1, tme_uint64_t)
        !          1120: {
        !          1121:   tme_uint32_t opf;
        !          1122:   tme_uint64_t rd;
        !          1123:   unsigned int alignaddr_off;
        !          1124: 
        !          1125:   /* extract the opf field: */
        !          1126:   opf = TME_FIELD_MASK_EXTRACTU(TME_SPARC_INSN, (0x1ff << 5));
        !          1127: 
        !          1128:   /* if this is a shutdown instruction: */
        !          1129:   if (opf == 0x80) {
        !          1130:     TME_SPARC_INSN_PRIV;
        !          1131: 
        !          1132:     /* XXX WRITEME: */
        !          1133:     abort();
        !          1134:   }
        !          1135: 
        !          1136:   /* if this is the VIS alignaddr instruction: */
        !          1137:   if ((opf | TME_BIT(1)) == 0x1a) {
        !          1138: 
        !          1139:     /* add the two registers into an address: */
        !          1140:     rd = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
        !          1141: 
        !          1142:     /* store the alignaddr offset: */
        !          1143:     alignaddr_off
        !          1144:       = (((opf & TME_BIT(1))
        !          1145:          ? (sizeof(tme_uint64_t) - 1)
        !          1146:          : 0)
        !          1147:         ^ rd);
        !          1148:     TME_FIELD_MASK_DEPOSITU(ic->tme_sparc_vis_gsr,
        !          1149:                            TME_SPARC_VIS_GSR_ALIGNADDR_OFF,
        !          1150:                            alignaddr_off);
        !          1151: 
        !          1152:     /* truncate the address: */
        !          1153:     TME_SPARC_FORMAT3_RD = rd & (0 - (tme_uint64_t) sizeof(tme_uint64_t));
        !          1154: 
        !          1155:     TME_SPARC_INSN_OK;
        !          1156:   }
        !          1157: 
        !          1158:   /* otherwise, assume that this is some other VIS instruction: */
        !          1159:   tme_sparc_vis(ic);
        !          1160:   TME_SPARC_INSN_OK;
        !          1161: }
        !          1162: 
        !          1163: /* the stp103x impdep2: */
        !          1164: static
        !          1165: TME_SPARC_FORMAT3(_tme_stp103x_impdep2, tme_uint64_t)
        !          1166: {
        !          1167:   TME_SPARC_INSN_ILL(ic);
        !          1168: }
        !          1169: 
        !          1170: /* the stp103x flush: */
        !          1171: static
        !          1172: TME_SPARC_FORMAT3(_tme_stp103x_flush, tme_uint64_t)
        !          1173: {
        !          1174:   tme_uint64_t address;
        !          1175:   tme_uint32_t context;
        !          1176:   struct tme_sparc_tlb *dtlb;
        !          1177:   tme_uint64_t rd;
        !          1178: 
        !          1179:   /* if we're replaying instructions, return now: */
        !          1180:   if (tme_sparc_recode_verify_replay_last_pc(ic) != 0) {
        !          1181:     TME_SPARC_INSN_OK;
        !          1182:   }
        !          1183: 
        !          1184:   /* get the address: */
        !          1185:   address = TME_SPARC_FORMAT3_RS1 + TME_SPARC_FORMAT3_RS2;
        !          1186:   address &= ic->tme_sparc_address_mask;
        !          1187: 
        !          1188:   /* get the context: */
        !          1189:   context = ic->tme_sparc_memory_context_default;
        !          1190: 
        !          1191:   /* get and busy the DTLB entry: */
        !          1192:   dtlb = &ic->tme_sparc_tlbs[TME_SPARC_DTLB_ENTRY(ic, TME_SPARC_TLB_HASH(ic, context, address))];
        !          1193:   tme_sparc_tlb_busy(dtlb);
        !          1194: 
        !          1195:   /* a flush instruction behaves like a non-faulting load: */
        !          1196:   tme_sparc64_ls(ic,
        !          1197:                 address,
        !          1198:                 &rd,
        !          1199:                 (TME_SPARC_LSINFO_OP_LD
        !          1200:                  + TME_SPARC_LSINFO_ASI_FLAGS(TME_SPARC64_ASI_FLAG_NO_FAULT)
        !          1201:                  + sizeof(tme_uint8_t)));
        !          1202: 
        !          1203:   /* unbusy the DTLB entry: */
        !          1204:   tme_sparc_tlb_unbusy(dtlb);
        !          1205: 
        !          1206:   TME_SPARC_INSN_OK;
        !          1207: }
        !          1208: 
        !          1209: /* the format three opcode map: */
        !          1210: #define _TME_SPARC_EXECUTE_OPMAP tme_sparc_opcodes_stp103x
        !          1211: static const _tme_sparc64_format3 _TME_SPARC_EXECUTE_OPMAP[] = {
        !          1212: 
        !          1213:   /* op=2: arithmetic, logical, shift, and remaining: */
        !          1214: 
        !          1215:   /* 000000 */ tme_sparc64_add,
        !          1216:   /* 000001 */ tme_sparc64_and,
        !          1217:   /* 000010 */ tme_sparc64_or,
        !          1218:   /* 000011 */ tme_sparc64_xor,
        !          1219:   /* 000100 */ tme_sparc64_sub,
        !          1220:   /* 000101 */ tme_sparc64_andn,
        !          1221:   /* 000110 */ tme_sparc64_orn,
        !          1222:   /* 000111 */ tme_sparc64_xnor,
        !          1223:   /* 001000 */ tme_sparc64_addx,
        !          1224:   /* 001001 */ tme_sparc64_mulx,
        !          1225:   /* 001010 */ tme_sparc64_umul,
        !          1226:   /* 001011 */ tme_sparc64_smul,
        !          1227:   /* 001100 */ tme_sparc64_subx,
        !          1228:   /* 001101 */ tme_sparc64_udivx,
        !          1229:   /* 001110 */ tme_sparc64_udiv,
        !          1230:   /* 001111 */ tme_sparc64_sdiv,
        !          1231:   /* 010000 */ tme_sparc64_addcc,
        !          1232:   /* 010001 */ tme_sparc64_andcc,
        !          1233:   /* 010010 */ tme_sparc64_orcc,
        !          1234:   /* 010011 */ tme_sparc64_xorcc,
        !          1235:   /* 010100 */ tme_sparc64_subcc,
        !          1236:   /* 010101 */ tme_sparc64_andncc,
        !          1237:   /* 010110 */ tme_sparc64_orncc,
        !          1238:   /* 010111 */ tme_sparc64_xnorcc,
        !          1239:   /* 011000 */ tme_sparc64_addxcc,
        !          1240:   /* 011001 */ NULL,
        !          1241:   /* 011010 */ tme_sparc64_umulcc,
        !          1242:   /* 011011 */ tme_sparc64_smulcc,
        !          1243:   /* 011100 */ tme_sparc64_subxcc,
        !          1244:   /* 011101 */ NULL,
        !          1245:   /* 011110 */ tme_sparc64_udivcc,
        !          1246:   /* 011111 */ tme_sparc64_sdivcc,
        !          1247:   /* 100000 */ tme_sparc64_taddcc,
        !          1248:   /* 100001 */ tme_sparc64_tsubcc,
        !          1249:   /* 100010 */ tme_sparc64_taddcctv,
        !          1250:   /* 100011 */ tme_sparc64_tsubcctv,
        !          1251:   /* 100100 */ tme_sparc64_mulscc,
        !          1252:   /* 100101 */ tme_sparc64_sll,
        !          1253:   /* 100110 */ tme_sparc64_srl,
        !          1254:   /* 100111 */ tme_sparc64_sra,
        !          1255:   /* 101000 */ _tme_stp103x_rdasr,
        !          1256:   /* 101001 */ NULL,
        !          1257:   /* 101010 */ _tme_stp103x_rdpr,
        !          1258:   /* 101011 */ tme_sparc64_flushw,
        !          1259:   /* 101100 */ tme_sparc64_movcc,
        !          1260:   /* 101101 */ tme_sparc64_sdivx,
        !          1261:   /* 101110 */ NULL,
        !          1262:   /* 101111 */ tme_sparc64_movr,
        !          1263:   /* 110000 */ _tme_stp103x_wrasr,
        !          1264:   /* 110001 */ tme_sparc64_saved_restored,
        !          1265:   /* 110010 */ tme_sparc64_wrpr,
        !          1266:   /* 110011 */ NULL,
        !          1267:   /* 110100 */ tme_sparc64_fpop1,
        !          1268:   /* 110101 */ tme_sparc64_fpop2,
        !          1269:   /* 110110 */ _tme_stp103x_impdep1,
        !          1270:   /* 110111 */ _tme_stp103x_impdep2,
        !          1271:   /* 111000 */ tme_sparc64_jmpl,
        !          1272:   /* 111001 */ tme_sparc64_return,
        !          1273:   /* 111010 */ tme_sparc64_tcc,
        !          1274:   /* 111011 */ _tme_stp103x_flush,
        !          1275:   /* 111100 */ tme_sparc64_save_restore,
        !          1276:   /* 111101 */ tme_sparc64_save_restore,
        !          1277:   /* 111110 */ tme_sparc64_done_retry,
        !          1278:   /* 111111 */ NULL,
        !          1279: 
        !          1280:   /* op=3: memory instructions: */
        !          1281: 
        !          1282:   /* 000000 */ tme_sparc64_ld,
        !          1283:   /* 000001 */ tme_sparc64_ldb,
        !          1284:   /* 000010 */ tme_sparc64_ldh,
        !          1285:   /* 000011 */ tme_sparc64_ldd,
        !          1286:   /* 000100 */ tme_sparc64_st,
        !          1287:   /* 000101 */ tme_sparc64_stb,
        !          1288:   /* 000110 */ tme_sparc64_sth,
        !          1289:   /* 000111 */ tme_sparc64_std,
        !          1290:   /* 001000 */ tme_sparc64_ld,
        !          1291:   /* 001001 */ tme_sparc64_ldb,
        !          1292:   /* 001010 */ tme_sparc64_ldh,
        !          1293:   /* 001011 */ tme_sparc64_ldx,
        !          1294:   /* 001100 */ NULL,
        !          1295:   /* 001101 */ tme_sparc64_ldstub,
        !          1296:   /* 001110 */ tme_sparc64_stx,
        !          1297:   /* 001111 */ tme_sparc64_swap,
        !          1298:   /* 010000 */ tme_sparc64_lda,
        !          1299:   /* 010001 */ tme_sparc64_ldba,
        !          1300:   /* 010010 */ tme_sparc64_ldha,
        !          1301:   /* 010011 */ tme_sparc64_ldda,
        !          1302:   /* 010100 */ tme_sparc64_sta,
        !          1303:   /* 010101 */ tme_sparc64_stba,
        !          1304:   /* 010110 */ tme_sparc64_stha,
        !          1305:   /* 010111 */ tme_sparc64_stda,
        !          1306:   /* 011000 */ tme_sparc64_lda,
        !          1307:   /* 011001 */ tme_sparc64_ldba,
        !          1308:   /* 011010 */ tme_sparc64_ldha,
        !          1309:   /* 011011 */ tme_sparc64_ldxa,
        !          1310:   /* 011100 */ NULL,
        !          1311:   /* 011101 */ tme_sparc64_ldstuba,
        !          1312:   /* 011110 */ tme_sparc64_stxa,
        !          1313:   /* 011111 */ tme_sparc64_swapa,
        !          1314:   /* 100000 */ tme_sparc64_ldf,
        !          1315:   /* 100001 */ tme_sparc64_ldfsr,
        !          1316:   /* 100010 */ tme_sparc64_illegal_instruction, /* ldqf */
        !          1317:   /* 100011 */ tme_sparc64_lddf,
        !          1318:   /* 100100 */ tme_sparc64_stf,
        !          1319:   /* 100101 */ tme_sparc64_stfsr,
        !          1320:   /* 100110 */ tme_sparc64_illegal_instruction, /* stqf */
        !          1321:   /* 100111 */ tme_sparc64_stdf,
        !          1322:   /* 101000 */ NULL,
        !          1323:   /* 101001 */ NULL,
        !          1324:   /* 101010 */ NULL,
        !          1325:   /* 101011 */ NULL,
        !          1326:   /* 101100 */ NULL,
        !          1327:   /* 101101 */ tme_sparc64_prefetch,
        !          1328:   /* 101110 */ NULL,
        !          1329:   /* 101111 */ NULL,
        !          1330:   /* 110000 */ tme_sparc64_ldfa,
        !          1331:   /* 110001 */ NULL,
        !          1332:   /* 110010 */ tme_sparc64_illegal_instruction, /* ldqfa */
        !          1333:   /* 110011 */ tme_sparc64_lddfa,
        !          1334:   /* 110100 */ tme_sparc64_stfa,
        !          1335:   /* 110101 */ NULL,
        !          1336:   /* 110110 */ tme_sparc64_illegal_instruction, /* stqfa */
        !          1337:   /* 110111 */ tme_sparc64_stdfa,
        !          1338:   /* 111000 */ NULL,
        !          1339:   /* 111001 */ NULL,
        !          1340:   /* 111010 */ NULL,
        !          1341:   /* 111011 */ NULL,
        !          1342:   /* 111100 */ tme_sparc64_casa,
        !          1343:   /* 111101 */ tme_sparc64_prefetch,
        !          1344:   /* 111110 */ tme_sparc64_casxa,
        !          1345:   /* 111111 */ NULL,
        !          1346: };
        !          1347: 
        !          1348: /* make the executor for the STP103x: */
        !          1349: #define _TME_SPARC_EXECUTE_NAME _tme_sparc_execute_stp103x
        !          1350: #include "sparc-execute.c"
        !          1351: 
        !          1352: /* this invalidates a specific valid stp103x TLB entry: */
        !          1353: static void
        !          1354: _tme_stp103x_tlb_invalidate(struct tme_sparc *ic,
        !          1355:                            signed long tlb_part_i)
        !          1356: {
        !          1357:   tme_uint32_t tlb_data_32_63;
        !          1358:   struct tme_sparc_tlb *tlb;
        !          1359:   tme_uint32_t tlb_count;
        !          1360:   tme_uint32_t size;
        !          1361:   tme_uint64_t address;
        !          1362:   tme_uint32_t context;
        !          1363: 
        !          1364:   /* load bits 32..63 of the TLB entry's data: */
        !          1365:   tlb_data_32_63 = TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 1);
        !          1366: 
        !          1367:   /* this TLB entry must be valid: */
        !          1368:   assert (tlb_data_32_63 & TME_STP103X_TLB_DATA_V(tlb_data_32_63));
        !          1369: 
        !          1370:   /* this TLB entry is now invalid: */
        !          1371:   tlb_data_32_63 &= ~TME_STP103X_TLB_DATA_V(tlb_data_32_63);
        !          1372:   TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 1) = tlb_data_32_63;
        !          1373: 
        !          1374:   /* if this TLB entry is global: */
        !          1375:   if (TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 0)
        !          1376:       & TME_STP103X_TLB_DATA_G((tme_uint32_t) 0)) {
        !          1377: 
        !          1378:     /* assume that this is an stp103x DTLB entry, and we need to
        !          1379:        invalidate sparc DTLB entries: */
        !          1380:     tlb = &ic->tme_sparc_tlbs[0];
        !          1381:     tlb_count = _TME_SPARC_DTLB_HASH_SIZE;
        !          1382: 
        !          1383:     /* if this is an stp103x ITLB entry: */
        !          1384: #if TME_STP103X_TLB_PART_0_DMMU >= TME_STP103X_TLB_PART_0_IMMU
        !          1385: #error "TME_STP103X_TLB_PART_0_DMMU or TME_STP103X_TLB_PART_0_IMMU changed"
        !          1386: #endif
        !          1387:     if (tlb_part_i >= TME_STP103X_TLB_PART_0_IMMU) {
        !          1388: 
        !          1389:       /* we need to invalidate sparc ITLB entries: */
        !          1390:       tlb += _TME_SPARC_DTLB_HASH_SIZE;
        !          1391:       tlb_count = _TME_SPARC_ITLB_HASH_SIZE;
        !          1392:     }
        !          1393: 
        !          1394:     /* invalidate all of the sparc TLB entries linked to this stp103x
        !          1395:        TLB entry: */
        !          1396:     do {
        !          1397:       if (tlb->tme_sparc_tlb_link == tlb_part_i) {
        !          1398:        tme_token_invalidate_nosync(tlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_token);
        !          1399:       }
        !          1400:       tlb++;
        !          1401:     } while (--tlb_count);
        !          1402:   }
        !          1403: 
        !          1404:   /* otherwise, this TLB entry isn't global: */
        !          1405:   else {
        !          1406: 
        !          1407:     /* get the size of this mapping: */
        !          1408:     size
        !          1409:       = (TME_STP103X_PAGE_SIZE_8KB
        !          1410:         << (3 * TME_FIELD_MASK_EXTRACTU(tlb_data_32_63,
        !          1411:                                         TME_STP103X_TLB_DATA_SIZE_MASK(tlb_data_32_63))));
        !          1412: 
        !          1413:     /* get the tag, and divide it into context and address: */
        !          1414:     address = TME_STP103X(ic)->tme_stp103x_tlb_64s(tlb_part_i + 0);
        !          1415:     context = address;
        !          1416:     context &= TME_STP103X_CONTEXT_MAX;
        !          1417:     address &= (0 - (tme_uint64_t) size);
        !          1418: 
        !          1419:     /* we assume that a stride of 8KB will find all sparc TLB entries
        !          1420:        for this stp103x TLB entry: */
        !          1421:     assert ((1 << ic->tme_sparc_tlb_page_size_log2) == TME_STP103X_PAGE_SIZE_8KB);
        !          1422: 
        !          1423:     /* if this is an stp103x DTLB entry: */
        !          1424: #if TME_STP103X_TLB_PART_0_DMMU >= TME_STP103X_TLB_PART_0_IMMU
        !          1425: #error "TME_STP103X_TLB_PART_0_DMMU or TME_STP103X_TLB_PART_0_IMMU changed"
        !          1426: #endif
        !          1427:     if (tlb_part_i < TME_STP103X_TLB_PART_0_IMMU) {
        !          1428: 
        !          1429:       /* invalidate all of the sparc DTLB entries linked to this
        !          1430:         stp103x DTLB entry: */
        !          1431:       do {
        !          1432:        tlb = &ic->tme_sparc_tlbs[TME_SPARC_DTLB_ENTRY(ic, TME_SPARC_TLB_HASH(ic, context, address))];
        !          1433:        if (tlb->tme_sparc_tlb_link == tlb_part_i) {
        !          1434:          tme_token_invalidate_nosync(tlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_token);
        !          1435:        }
        !          1436:        address += TME_STP103X_PAGE_SIZE_8KB;
        !          1437:       } while ((size -= TME_STP103X_PAGE_SIZE_8KB) > 0);
        !          1438:     }
        !          1439: 
        !          1440:     /* otherwise, this is an stp103x ITLB entry: */
        !          1441:     else {
        !          1442: 
        !          1443:       /* invalidate all of the sparc ITLB entries linked to this
        !          1444:         stp103x ITLB entry: */
        !          1445:       do {
        !          1446:        tlb = &ic->tme_sparc_tlbs[TME_SPARC_ITLB_ENTRY(ic, TME_SPARC_TLB_HASH(ic, context, address))];
        !          1447:        if (tlb->tme_sparc_tlb_link == tlb_part_i) {
        !          1448:          tme_token_invalidate_nosync(tlb->tme_sparc_tlb_bus_tlb.tme_bus_tlb_token);
        !          1449:        }
        !          1450:        address += TME_STP103X_PAGE_SIZE_8KB;
        !          1451:       } while ((size -= TME_STP103X_PAGE_SIZE_8KB) > 0);
        !          1452:     }
        !          1453:   }
        !          1454: }
        !          1455: 
        !          1456: /* this handles a load/store trap: */
        !          1457: static void
        !          1458: _tme_stp103x_ls_trap(struct tme_sparc *ic,
        !          1459:                     struct tme_sparc_ls *ls)
        !          1460: {
        !          1461:   tme_uint32_t lsinfo;
        !          1462:   tme_uint32_t sfsr;
        !          1463:   tme_uint32_t ls_faults;
        !          1464:   tme_uint32_t trap;
        !          1465:   tme_uint32_t updates;
        !          1466:   tme_uint32_t insn;
        !          1467:   tme_uint64_t afsr;
        !          1468:   tme_uint64_t address;
        !          1469:   tme_uint32_t asi_mask;
        !          1470:   struct tme_stp103x_mmu *mmu;
        !          1471: 
        !          1472:   /* get the information about this load/store: */
        !          1473:   lsinfo = ls->tme_sparc_ls_lsinfo;
        !          1474: 
        !          1475:   /* check that we weren't supposed to fault: */
        !          1476:   assert ((lsinfo & TME_STP103X_LSINFO_ASSERT_NO_FAULTS) == 0);
        !          1477: 
        !          1478:   /* if we're supposed to ignore faults: */
        !          1479:   if (__tme_predict_false(lsinfo & TME_SPARC_LSINFO_NO_FAULT)) {
        !          1480: 
        !          1481:     /* clear all faults and complete the load/store: */
        !          1482:     ls->tme_sparc_ls_faults = TME_SPARC_LS_FAULT_NONE;
        !          1483:     ls->tme_sparc_ls_size = 0;
        !          1484:     return;
        !          1485:   }
        !          1486: 
        !          1487:   /* start an SFSR value: */
        !          1488:   sfsr = 0;
        !          1489: 
        !          1490:   /* get the list of faults from this load/store: */
        !          1491:   ls_faults = ls->tme_sparc_ls_faults;
        !          1492: 
        !          1493:   /* there must be at least one fault: */
        !          1494:   assert (ls_faults != TME_SPARC_LS_FAULT_NONE);
        !          1495: 
        !          1496:   /* we don't support generic bus faults: */
        !          1497:   assert ((ls_faults
        !          1498:           & (TME_SPARC_LS_FAULT_BUS_FAULT)) == 0);
        !          1499: 
        !          1500:   /* if this is an IMMU miss, this must be the only fault.  we rely on
        !          1501:      this to honor trap priorities, since we handle IMMU misses and
        !          1502:      DMMU misses as if they have the same priority, even though they
        !          1503:      don't: */
        !          1504:   assert ((ls_faults & TME_STP103X_LS_FAULT_MMU_MISS) == 0
        !          1505:          || (lsinfo & TME_SPARC_LSINFO_OP_FETCH) == 0
        !          1506:          || ls_faults == TME_STP103X_LS_FAULT_MMU_MISS);
        !          1507: 
        !          1508:   /* if this is a instruction access error, it must happen alone.  we
        !          1509:      rely on this to honor trap priorities, since we handle
        !          1510:      instruction access errors and data access errors as if they have
        !          1511:      the same priority, even though they don't: */
        !          1512:   assert ((ls_faults & TME_SPARC_LS_FAULT_BUS_ERROR) == 0
        !          1513:          || (lsinfo & TME_SPARC_LSINFO_OP_FETCH) == 0
        !          1514:          || ls_faults == TME_SPARC_LS_FAULT_BUS_ERROR);
        !          1515: 
        !          1516:   /* if this is an instruction access exception, it either happens
        !          1517:      alone (because of a privilege violation), or it's because of a
        !          1518:      jmpl/return target address out-of-range.  we rely on this to
        !          1519:      honor trap priorities, since we handle privilege violation
        !          1520:      instruction access exceptions and data access exceptions as if
        !          1521:      they have the same priority, even though they don't.  (a
        !          1522:      jmpl/return target instruction access exception explicitly has
        !          1523:      the same priority as a data access exception): */
        !          1524:   assert ((ls_faults
        !          1525:           & (TME_STP103X_LS_FAULT_PRIVILEGE
        !          1526:              | TME_SPARC64_LS_FAULT_SIDE_EFFECTS
        !          1527:              | TME_SPARC64_LS_FAULT_UNCACHEABLE
        !          1528:              | TME_SPARC64_LS_FAULT_NO_FAULT_NON_LOAD
        !          1529:              | TME_STP103X_LS_FAULT_ILLEGAL
        !          1530:              | TME_SPARC64_LS_FAULT_NO_FAULT_FAULT
        !          1531:              | TME_SPARC64_LS_FAULT_VA_RANGE
        !          1532:              | TME_SPARC64_LS_FAULT_VA_RANGE_NNPC)) == 0
        !          1533:          || (lsinfo & TME_SPARC_LSINFO_OP_FETCH) == 0
        !          1534:          || ls_faults == TME_STP103X_LS_FAULT_PRIVILEGE
        !          1535:          || ls_faults == TME_SPARC64_LS_FAULT_VA_RANGE_NNPC);
        !          1536: 
        !          1537:   /* these traps are sorted by priority, most important first: */
        !          1538: 
        !          1539:   /* if this was an illegal instruction: */
        !          1540:   if (ls_faults
        !          1541:       & (TME_SPARC_LS_FAULT_LDD_STD_RD_ODD)) {
        !          1542: 
        !          1543:     /* make an illegal_instruction trap, which doesn't update any MMU
        !          1544:        registers: */
        !          1545:     trap = TME_SPARC64_TRAP_illegal_instruction;
        !          1546:     updates = TME_STP103X_UPDATE_NONE;
        !          1547:   }
        !          1548: 
        !          1549:   /* otherwise, if the address isn't aligned: */
        !          1550:   else if (ls_faults & TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED) {
        !          1551: 
        !          1552:     /* assume that this is not an lddf or stdf instruction, or that
        !          1553:        the address is not even 32-bit aligned, and make the normal
        !          1554:        mem_address_not_aligned trap: */
        !          1555:     trap = TME_SPARC64_TRAP_mem_address_not_aligned;
        !          1556: 
        !          1557:     /* if this is an lddf or stdf instruction: */
        !          1558:     insn = ic->_tme_sparc_insn;
        !          1559:     if ((insn
        !          1560:         & (0x3b << 19))
        !          1561:        == (0x23 << 19)) {
        !          1562: 
        !          1563:       /* if the address is 32-bit aligned, but not 64-bit aligned: */
        !          1564:       if ((ls->tme_sparc_ls_address64 % sizeof(tme_uint64_t))
        !          1565:          == sizeof(tme_uint32_t)) {
        !          1566: 
        !          1567:        /* make the LDDF_mem_address_not_aligned or
        !          1568:           STDF_mem_address_not_aligned trap: */
        !          1569:        trap
        !          1570:          = ((insn & (4 << 19))
        !          1571:             ? TME_SPARC64_TRAP_STDF_mem_address_not_aligned
        !          1572:             : TME_SPARC64_TRAP_LDDF_mem_address_not_aligned);
        !          1573:       }
        !          1574:     }
        !          1575: 
        !          1576:     /* these traps update the DMMU SFSR and SFAR: */
        !          1577:     updates
        !          1578:       = (TME_STP103X_UPDATE_DMMU
        !          1579:         + TME_STP103X_UPDATE_MMU_SFSR
        !          1580:         + TME_STP103X_UPDATE_DMMU_SFAR);
        !          1581:   }
        !          1582: 
        !          1583:   /* otherwise, if the ASI is privileged: */
        !          1584:   else if (ls_faults & TME_SPARC64_LS_FAULT_PRIVILEGED_ASI) {
        !          1585: 
        !          1586:     /* make a privileged_action trap, which updates the DMMU SFSR and
        !          1587:        SFAR: */
        !          1588:     trap = TME_SPARC64_TRAP_privileged_action;
        !          1589:     updates
        !          1590:       = (TME_STP103X_UPDATE_DMMU
        !          1591:         + TME_STP103X_UPDATE_MMU_SFSR
        !          1592:         + TME_STP103X_UPDATE_DMMU_SFAR);
        !          1593:   }
        !          1594: 
        !          1595:   /* otherwise, if this is an access exception: */
        !          1596:   else if (ls_faults
        !          1597:           & (TME_STP103X_LS_FAULT_PRIVILEGE
        !          1598:              | TME_SPARC64_LS_FAULT_SIDE_EFFECTS
        !          1599:              | TME_SPARC64_LS_FAULT_UNCACHEABLE
        !          1600:              | TME_SPARC64_LS_FAULT_NO_FAULT_NON_LOAD
        !          1601:              | TME_STP103X_LS_FAULT_ILLEGAL
        !          1602:              | TME_SPARC64_LS_FAULT_NO_FAULT_FAULT
        !          1603:              | TME_SPARC64_LS_FAULT_VA_RANGE
        !          1604:              | TME_SPARC64_LS_FAULT_VA_RANGE_NNPC)) {
        !          1605: 
        !          1606:     /* make the SFSR FT field: */
        !          1607:     if (ls_faults & TME_STP103X_LS_FAULT_PRIVILEGE) {
        !          1608:       sfsr += TME_STP103X_SFSR_FT_PRIVILEGE;
        !          1609:     }
        !          1610:     if (ls_faults & TME_SPARC64_LS_FAULT_SIDE_EFFECTS) {
        !          1611:       sfsr += TME_STP103X_SFSR_FT_SIDE_EFFECTS;
        !          1612:     }
        !          1613:     if (ls_faults & TME_SPARC64_LS_FAULT_UNCACHEABLE) {
        !          1614:       /* XXX FIXME WRITEME table 6-11 hints that it's possible to do a
        !          1615:         casxa to DTLB_DATA_ACCESS_REG, and that a fault while doing
        !          1616:         so will set this bit: */
        !          1617:       sfsr += TME_STP103X_SFSR_FT_UNCACHEABLE;
        !          1618:     }
        !          1619:     if (ls_faults & 
        !          1620:        (TME_SPARC64_LS_FAULT_NO_FAULT_NON_LOAD
        !          1621:         | TME_STP103X_LS_FAULT_ILLEGAL)) {
        !          1622:       sfsr += TME_STP103X_SFSR_FT_ILLEGAL;
        !          1623:     }
        !          1624:     if (ls_faults & TME_SPARC64_LS_FAULT_NO_FAULT_FAULT) {
        !          1625:       sfsr += TME_STP103X_SFSR_FT_NO_FAULT_FAULT;
        !          1626:     }
        !          1627:     if (ls_faults & TME_SPARC64_LS_FAULT_VA_RANGE) {
        !          1628:       sfsr += TME_STP103X_SFSR_FT_VA_RANGE;
        !          1629:     }
        !          1630:     if (ls_faults & TME_SPARC64_LS_FAULT_VA_RANGE_NNPC) {
        !          1631:       sfsr += TME_STP103X_SFSR_FT_VA_RANGE_NNPC;
        !          1632:     }
        !          1633: 
        !          1634:     /* if this is an instruction fetch: */
        !          1635:     if (lsinfo & TME_SPARC_LSINFO_OP_FETCH) {
        !          1636: 
        !          1637:       /* the IMMU SFSR FT field must have exactly one of the privilege
        !          1638:         and VA range bits set: */
        !          1639:       assert (sfsr != 0
        !          1640:              && (sfsr
        !          1641:                  & ~(TME_STP103X_SFSR_FT_PRIVILEGE
        !          1642:                      | TME_STP103X_SFSR_FT_VA_RANGE
        !          1643:                      | TME_STP103X_SFSR_FT_VA_RANGE_NNPC)) == 0
        !          1644:              && (sfsr & (sfsr - 1)) == 0);
        !          1645: 
        !          1646:       /* make an instruction_access_exception trap, which updates the
        !          1647:         IMMU SFSR and tag access register: */
        !          1648:       trap = (TME_STP103X_TRAP_MG | TME_SPARC64_TRAP_instruction_access_exception);
        !          1649:       updates
        !          1650:        = (TME_STP103X_UPDATE_IMMU
        !          1651:           + TME_STP103X_UPDATE_MMU_SFSR
        !          1652:           + TME_STP103X_UPDATE_MMU_TAG_ACCESS);
        !          1653:     }
        !          1654: 
        !          1655:     /* otherwise, this is not an instruction fetch: */
        !          1656:     else {
        !          1657: 
        !          1658:       /* make a data_access_exception trap, which updates the DMMU
        !          1659:         SFSR, SFAR, and tag access register: */
        !          1660:       trap = (TME_STP103X_TRAP_MG | TME_SPARC64_TRAP_data_access_exception);
        !          1661:       updates
        !          1662:        = (TME_STP103X_UPDATE_DMMU
        !          1663:           + TME_STP103X_UPDATE_MMU_SFSR
        !          1664:           + TME_STP103X_UPDATE_DMMU_SFAR
        !          1665:           + TME_STP103X_UPDATE_MMU_TAG_ACCESS);
        !          1666:     }
        !          1667:   }
        !          1668: 
        !          1669:   /* otherwise, if this is an MMU miss: */
        !          1670:   else if (ls_faults & TME_STP103X_LS_FAULT_MMU_MISS) {
        !          1671: 
        !          1672:     /* if this is an instruction fetch: */
        !          1673:     if (lsinfo & TME_SPARC_LSINFO_OP_FETCH) {
        !          1674: 
        !          1675:       /* make an instruction_access_MMU_miss trap, which updates the
        !          1676:         IMMU tag access register: */
        !          1677:       trap = TME_STP103X_TRAP_fast_instruction_access_MMU_miss;
        !          1678:       updates
        !          1679:        = (TME_STP103X_UPDATE_IMMU
        !          1680:           + TME_STP103X_UPDATE_MMU_TAG_ACCESS);
        !          1681:     }
        !          1682: 
        !          1683:     /* otherwise, this is not an instruction fetch: */
        !          1684:     else {
        !          1685: 
        !          1686:       /* make a data_access_MMU_miss trap, which updates the DMMU tag
        !          1687:         access: */
        !          1688:       trap = TME_STP103X_TRAP_fast_data_access_MMU_miss;
        !          1689:       updates
        !          1690:        = (TME_STP103X_UPDATE_DMMU
        !          1691:           + TME_STP103X_UPDATE_MMU_TAG_ACCESS);
        !          1692:     }
        !          1693:   }
        !          1694: 
        !          1695:   /* otherwise, if this is a data access protection fault: */
        !          1696:   else if (ls_faults & TME_STP103X_LS_FAULT_PROTECTION) {
        !          1697: 
        !          1698:       /* make a fast_data_access_protection trap, which updates the
        !          1699:         DMMU SFSR, SFAR, and tag access register: */
        !          1700:       trap = TME_STP103X_TRAP_fast_data_access_protection;
        !          1701:       updates
        !          1702:        = (TME_STP103X_UPDATE_DMMU
        !          1703:           + TME_STP103X_UPDATE_MMU_SFSR
        !          1704:           + TME_STP103X_UPDATE_DMMU_SFAR
        !          1705:           + TME_STP103X_UPDATE_MMU_TAG_ACCESS);
        !          1706:   }
        !          1707: 
        !          1708:   /* otherwise, this must be an access error fault: */
        !          1709:   else {
        !          1710:     assert (ls_faults & TME_SPARC_LS_FAULT_BUS_ERROR);
        !          1711: 
        !          1712:     /* get the asynchronous fault status register bit for this
        !          1713:        fault: */
        !          1714:     /* NB: we assume that all bus errors are timeouts: */
        !          1715:     afsr = TME_STP103X_AFSR_TO;
        !          1716: 
        !          1717:     /* if no same or higher-priority asynchronous fault has already
        !          1718:        happened: */
        !          1719:     if ((TME_STP103X(ic)->tme_stp103x_afsr
        !          1720:         & (TME_STP103X_AFSR_ME - afsr)) == 0) {
        !          1721:       
        !          1722:       /* update the asynchronous fault address register: */
        !          1723:       assert (ls->tme_sparc_ls_tlb->tme_sparc_tlb_addr_shift == 0);
        !          1724:       TME_STP103X(ic)->tme_stp103x_afar
        !          1725:        = ((ls->tme_sparc_ls_address64
        !          1726:            + (tme_uint64_t) ls->tme_sparc_ls_tlb->tme_sparc_tlb_addr_offset)
        !          1727:           & (0 - (tme_uint64_t) (1 << 4)));
        !          1728:     }
        !          1729: 
        !          1730:     /* update the asynchronous fault status register: */
        !          1731:     TME_STP103X(ic)->tme_stp103x_afsr
        !          1732:       |= (((TME_STP103X(ic)->tme_stp103x_afsr
        !          1733:            & afsr)
        !          1734:           ? TME_STP103X_AFSR_ME
        !          1735:           : !TME_STP103X_AFSR_ME)
        !          1736:          + (TME_SPARC_PRIV(ic)
        !          1737:             ? TME_STP103X_AFSR_PRIV
        !          1738:             : !TME_STP103X_AFSR_PRIV));
        !          1739: 
        !          1740:     /* if noncacheable errors are not enabled: */
        !          1741:     if ((TME_STP103X(ic)->tme_stp103x_estate_error_enable & TME_STP103X_ESTATE_ERROR_ENABLE_NCEEN) == 0) {
        !          1742: 
        !          1743:       /* clear the fault: */
        !          1744:       ls->tme_sparc_ls_faults = TME_SPARC_LS_FAULT_NONE;
        !          1745: 
        !          1746:       /* if this is a load: */
        !          1747:       if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_LD) {
        !          1748: 
        !          1749:        /* force all bytes read to be all-bits-one by filling the
        !          1750:           entire memory buffer with all-bits-one: */
        !          1751:        /* NB: we do this even though earlier parts of the load may
        !          1752:           have succeeded, to keep things simple.  we assume that
        !          1753:           nothing depends on partially successful loads: */
        !          1754:        memset (ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer8s,
        !          1755:                0xff, 
        !          1756:                sizeof(ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer8s));
        !          1757:       }
        !          1758: 
        !          1759:       /* stop this load or store: */
        !          1760:       /* NB: we do this even though later parts of the load or store
        !          1761:         may succeed, to keep things simple.  we assume that nothing
        !          1762:         depends on partially successful loads or stores: */
        !          1763:       /* NB: we don't set TME_SPARC_LSINFO_LD_COMPLETED because we are
        !          1764:         only stopping the load or store here, not completing it.  we
        !          1765:         still let the original load instruction function complete the
        !          1766:         load from the memory buffer: */
        !          1767:       ls->tme_sparc_ls_size = 0;
        !          1768: 
        !          1769:       /* make no trap: */
        !          1770:       trap = TME_SPARC_TRAP_none;
        !          1771:     }
        !          1772: 
        !          1773:     /* otherwise, if this is an instruction fetch: */
        !          1774:     else if (lsinfo & TME_SPARC_LSINFO_OP_FETCH) {
        !          1775: 
        !          1776:       /* make an instruction_access_error trap: */
        !          1777:       trap = TME_SPARC64_TRAP_instruction_access_error;
        !          1778:     }
        !          1779: 
        !          1780:     /* otherwise, this is not an instruction fetch: */
        !          1781:     else {
        !          1782: 
        !          1783:       /* make a data_access_error trap: */
        !          1784:       trap = TME_SPARC64_TRAP_data_access_error;
        !          1785:     }
        !          1786: 
        !          1787:     /* this trap doesn't update any other state: */
        !          1788:     updates = TME_STP103X_UPDATE_NONE;
        !          1789:   }
        !          1790: 
        !          1791:   /* get the virtual address, forced to be in range: */
        !          1792:   address = ls->tme_sparc_ls_address64;
        !          1793:   address |= (0 - (TME_STP103X_VA_HOLE_START * 2));
        !          1794:   address = (address ^ TME_STP103X_VA_HOLE_START) + TME_STP103X_VA_HOLE_START;
        !          1795: 
        !          1796:   /* if this trap updates the DMMU SFAR: */
        !          1797:   if (updates & TME_STP103X_UPDATE_DMMU_SFAR) {
        !          1798:     TME_STP103X(ic)->tme_stp103x_dmmu_sfar = address;
        !          1799:   }
        !          1800: 
        !          1801:   /* assume that this trap updates the IMMU: */
        !          1802:   mmu = &TME_STP103X(ic)->tme_stp103x_immu;
        !          1803: 
        !          1804:   /* if this trap updates the DMMU: */
        !          1805:   if ((updates
        !          1806:        & (TME_STP103X_UPDATE_DMMU
        !          1807:          | TME_STP103X_UPDATE_IMMU))
        !          1808:       != TME_STP103X_UPDATE_IMMU) {
        !          1809: 
        !          1810:     /* assume that this trap updates the DMMU SFSR and define
        !          1811:        SFSR.E: */
        !          1812:     if (ls->tme_sparc_ls_tlb->tme_sparc_tlb_asi_mask
        !          1813:        & TME_SPARC64_ASI_MASK_FLAG_TLB_SIDE_EFFECTS) {
        !          1814:       sfsr += TME_STP103X_SFSR_E;
        !          1815:     }
        !          1816: 
        !          1817:     /* update the common DMMU state: */
        !          1818:     mmu = &TME_STP103X(ic)->tme_stp103x_dmmu;
        !          1819:   }
        !          1820: 
        !          1821:   /* get the ASI mask from the instruction: */
        !          1822:   asi_mask = ls->tme_sparc_ls_asi_mask;
        !          1823: 
        !          1824:   /* if this trap updates the DMMU or IMMU tag access register: */
        !          1825:   if (updates & TME_STP103X_UPDATE_MMU_TAG_ACCESS) {
        !          1826: 
        !          1827:     /* update the tag access: */
        !          1828:     mmu->tme_stp103x_mmu_tag_access
        !          1829:       = ((address
        !          1830:          & (0 - (tme_uint64_t) (TME_STP103X_CONTEXT_MAX + 1)))
        !          1831:         + ((asi_mask & TME_SPARC64_ASI_MASK_FLAG_SPECIAL)
        !          1832:            ? 0
        !          1833:            : ls->tme_sparc_ls_context));
        !          1834:   }
        !          1835: 
        !          1836:   /* if this trap updates the DMMU or IMMU SFSR: */
        !          1837:   if (updates & TME_STP103X_UPDATE_MMU_SFSR) {
        !          1838: 
        !          1839:     /* define SFSR.ASI: */
        !          1840:     TME_FIELD_MASK_DEPOSITU(sfsr,
        !          1841:                            TME_STP103X_SFSR_ASI,
        !          1842:                            TME_SPARC_ASI_MASK_WHICH(asi_mask));
        !          1843: 
        !          1844:     /* define SFSR.CT: */
        !          1845:     sfsr
        !          1846:       += ((asi_mask & TME_SPARC64_ASI_MASK_FLAG_SPECIAL)
        !          1847:          ? TME_STP103X_SFSR_CT_RESERVED
        !          1848:          : (asi_mask & TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS)
        !          1849:          ? TME_STP103X_SFSR_CT_NUCLEUS
        !          1850:          : (asi_mask & TME_SPARC64_ASI_FLAG_SECONDARY)
        !          1851:          ? TME_STP103X_SFSR_CT_SECONDARY
        !          1852:          : TME_STP103X_SFSR_CT_PRIMARY);
        !          1853: 
        !          1854:     /* define SFSR.PR: */
        !          1855:     if (TME_SPARC_PRIV(ic)) {
        !          1856:       sfsr += TME_STP103X_SFSR_PR;
        !          1857:     }
        !          1858: 
        !          1859:     /* define SFSR.W: */
        !          1860:     if (lsinfo
        !          1861:        & (TME_SPARC_LSINFO_OP_ST
        !          1862:           | TME_SPARC_LSINFO_OP_ATOMIC)) {
        !          1863:       sfsr += TME_STP103X_SFSR_W;
        !          1864:     }
        !          1865: 
        !          1866:     /* define SFSR.FV: */
        !          1867:     sfsr += TME_STP103X_SFSR_FV;
        !          1868: 
        !          1869:     /* define SFSR.OW: */
        !          1870:     if (mmu->tme_stp103x_mmu_sfsr & TME_STP103X_SFSR_FV) {
        !          1871:       sfsr += TME_STP103X_SFSR_OW;
        !          1872:     }
        !          1873: 
        !          1874:     /* update the DMMU or IMMU SFSR: */
        !          1875:     mmu->tme_stp103x_mmu_sfsr = sfsr;
        !          1876:   }
        !          1877: 
        !          1878:   /* if there is a trap: */
        !          1879:   if (__tme_predict_true(trap != TME_SPARC_TRAP_none)) {
        !          1880: 
        !          1881:     /* trap: */
        !          1882:     tme_sparc64_trap(ic, trap);
        !          1883:   }
        !          1884: }
        !          1885: 
        !          1886: /* this checks that the virtual address of a load/store is in range.
        !          1887:    if it is out of range and ic is non-NULL, it traps immediately: */
        !          1888: static tme_uint64_t
        !          1889: _tme_stp103x_ls_address_check(struct tme_sparc *ic,
        !          1890:                              struct tme_sparc_ls *ls)
        !          1891: {
        !          1892:   tme_uint64_t address;
        !          1893:   tme_uint32_t address_32_63;
        !          1894: 
        !          1895:   /* get bits 32..63 of the address: */
        !          1896:   address = ls->tme_sparc_ls_address64;
        !          1897:   address_32_63 = address >> 32;
        !          1898: 
        !          1899:   /* if this address is in the address space hole: */
        !          1900:   if (__tme_predict_false((address_32_63 + (tme_uint32_t) (TME_STP103X_VA_HOLE_START >> 32))
        !          1901:                          >= (tme_uint32_t) ((TME_STP103X_VA_HOLE_START * 2) >> 32))) {
        !          1902: 
        !          1903:     /* note the fault: */
        !          1904:     ls->tme_sparc_ls_faults |= TME_SPARC64_LS_FAULT_VA_RANGE;
        !          1905: 
        !          1906:     /* if we can, trap now: */
        !          1907:     if (ic != NULL) {
        !          1908:       _tme_stp103x_ls_trap(ic, ls);
        !          1909:       abort();
        !          1910:       /* NOTREACHED */
        !          1911:     }
        !          1912:   }
        !          1913: 
        !          1914:   /* return the address: */
        !          1915:   return (address);
        !          1916: }
        !          1917: 
        !          1918: /* this maps a virtual address directly into a physical address: */
        !          1919: static void
        !          1920: _tme_stp103x_ls_address_map_phys(struct tme_sparc *ic,
        !          1921:                                 struct tme_sparc_ls *ls)
        !          1922: {
        !          1923:   tme_uint64_t address;
        !          1924:   tme_uint32_t asi;
        !          1925:   tme_uint32_t asi_mask;
        !          1926: 
        !          1927:   /* check the address: */
        !          1928:   address = _tme_stp103x_ls_address_check(ic, ls);
        !          1929: 
        !          1930:   /* get the original ASI: */
        !          1931:   asi = TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask);
        !          1932: 
        !          1933:   /* all of the bypass ASIs behave as if the P bit were clear: */
        !          1934:   asi_mask
        !          1935:     = (TME_SPARC64_ASI_MASK_PRIV
        !          1936:        + TME_SPARC64_ASI_MASK_USER);
        !          1937: 
        !          1938:   /* ASIs 0x15 and 0x1d behave as if the E bit were set and the CP bit
        !          1939:      were clear: */
        !          1940:   if (asi & 1) {
        !          1941:     asi_mask
        !          1942:       += (TME_SPARC64_ASI_MASK_FLAG_TLB_SIDE_EFFECTS
        !          1943:          + TME_SPARC64_ASI_MASK_FLAG_TLB_UNCACHEABLE);
        !          1944:   }
        !          1945: 
        !          1946:   /* update the flags on the TLB entry: */
        !          1947:   ls->tme_sparc_ls_tlb->tme_sparc_tlb_asi_mask
        !          1948:     |= asi_mask;
        !          1949: 
        !          1950:   /* do the truncating mapping: */
        !          1951:   address &= (0 - (tme_uint64_t) TME_STP103X_PAGE_SIZE_8KB);
        !          1952:   ls->tme_sparc_ls_tlb_map.tme_bus_tlb_addr_first = address;
        !          1953:   address |= (TME_STP103X_PAGE_SIZE_8KB - 1);
        !          1954:   ls->tme_sparc_ls_tlb_map.tme_bus_tlb_addr_last = address;
        !          1955:   ls->tme_sparc_ls_tlb_map.tme_bus_tlb_cycles_ok = (TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE);
        !          1956:   ls->tme_sparc_ls_tlb_map.tme_bus_tlb_addr_offset
        !          1957:     = ((address % TME_STP103X_PA_SIZE)
        !          1958:        - address);
        !          1959: }
        !          1960: 
        !          1961: /* this maps a virtual address: */
        !          1962: static void
        !          1963: _tme_stp103x_ls_address_map(struct tme_sparc *ic,
        !          1964:                            struct tme_sparc_ls *ls)
        !          1965: {
        !          1966:   tme_uint64_t address;
        !          1967:   tme_uint32_t lsu_0_31;
        !          1968:   signed long tlb_part_i;
        !          1969:   tme_uint32_t tlb_tag_match_0_31;
        !          1970:   tme_uint32_t tlb_tag_match_32_63;
        !          1971:   tme_uint32_t tlb_tag_xor_0_31;
        !          1972:   tme_uint32_t tlb_data_32_63;
        !          1973:   tme_uint32_t size;
        !          1974:   tme_uint32_t tlb_data_0_31;
        !          1975:   struct tme_sparc_tlb *tlb;
        !          1976:   tme_uint32_t asi_mask;
        !          1977:   tme_uint32_t cycles_ok;
        !          1978: 
        !          1979:   /* check the address: */
        !          1980:   address = _tme_stp103x_ls_address_check(ic, ls);
        !          1981: 
        !          1982:   /* get bits 0..31 of the load/store unit control register: */
        !          1983:   lsu_0_31 = TME_STP103X(ic)->tme_stp103x_lsu;
        !          1984: 
        !          1985:   /* assume that this is not an instruction fetch, and start at the
        !          1986:      beginning of the DMMU TLB entries: */
        !          1987:   tlb_part_i = TME_STP103X_TLB_PART_0_DMMU;
        !          1988: 
        !          1989:   /* if this is an instruction fetch: */
        !          1990:   if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_FETCH) {
        !          1991: 
        !          1992:     /* assume that LSU.IM is set, and set LSU.DM to indicate an
        !          1993:        enabled IMMU (!): */
        !          1994:     lsu_0_31 |= TME_STP103X_LSU_DM;
        !          1995: 
        !          1996:     /* if the IMMU is disabled, or if the CPU is in RED_state: */
        !          1997:     if (__tme_predict_false((lsu_0_31 & TME_STP103X_LSU_IM) == 0
        !          1998:                            || (ic->tme_sparc64_ireg_pstate & TME_SPARC64_PSTATE_RED))) {
        !          1999: 
        !          2000:       /* clear LSU.DM, to indicate a disabled IMMU (!): */
        !          2001:       lsu_0_31 &= ~TME_STP103X_LSU_DM;
        !          2002:     }
        !          2003: 
        !          2004:     /* start at the beginning of the IMMU TLB entries: */
        !          2005:     tlb_part_i = TME_STP103X_TLB_PART_0_IMMU;
        !          2006:   }
        !          2007: 
        !          2008:   /* if the MMU is disabled: */
        !          2009:   if (__tme_predict_false((lsu_0_31 & TME_STP103X_LSU_DM) == 0)) {
        !          2010: 
        !          2011:     /* a disabled MMU behaves as if the E bit were set, and the P and
        !          2012:        CP bits were clear: */
        !          2013:     ls->tme_sparc_ls_tlb->tme_sparc_tlb_asi_mask
        !          2014:       |= (TME_SPARC64_ASI_MASK_PRIV
        !          2015:          + TME_SPARC64_ASI_MASK_USER
        !          2016:          + TME_SPARC64_ASI_MASK_FLAG_TLB_SIDE_EFFECTS
        !          2017:          + TME_SPARC64_ASI_MASK_FLAG_TLB_UNCACHEABLE);
        !          2018: 
        !          2019:     /* do the truncating mapping: */
        !          2020:     address &= (0 - (tme_uint64_t) TME_STP103X_PAGE_SIZE_8KB);
        !          2021:     ls->tme_sparc_ls_tlb_map.tme_bus_tlb_addr_first = address;
        !          2022:     address |= (TME_STP103X_PAGE_SIZE_8KB - 1);
        !          2023:     ls->tme_sparc_ls_tlb_map.tme_bus_tlb_addr_last = address;
        !          2024:     ls->tme_sparc_ls_tlb_map.tme_bus_tlb_cycles_ok = (TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE);
        !          2025:     ls->tme_sparc_ls_tlb_map.tme_bus_tlb_addr_offset
        !          2026:       = ((address % TME_STP103X_PA_SIZE)
        !          2027:         - address);
        !          2028:     return;
        !          2029:   }
        !          2030: 
        !          2031:   /* make the tag to match: */
        !          2032:   tlb_tag_match_32_63 = (address >> 32);
        !          2033:   tlb_tag_match_0_31 = address;
        !          2034:   tlb_tag_match_0_31 &= ~TME_STP103X_CONTEXT_MAX;
        !          2035:   tlb_tag_match_0_31 += ls->tme_sparc_ls_context;
        !          2036: 
        !          2037:   /* loop over TLB entries: */
        !          2038:   do {
        !          2039: 
        !          2040:     /* if bits 32..63 of the tag match: */
        !          2041:     if (TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 0), 1) == tlb_tag_match_32_63) {
        !          2042: 
        !          2043:       /* if bits 22..31 of the tag match: */
        !          2044:       tlb_tag_xor_0_31 = TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 0), 0) ^ tlb_tag_match_0_31;
        !          2045:       if (tlb_tag_xor_0_31 < TME_STP103X_PAGE_SIZE_4MB) {
        !          2046: 
        !          2047:        /* load bits 32..63 of the data: */
        !          2048:        tlb_data_32_63 = TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 1);
        !          2049: 
        !          2050:        /* if the data is valid: */
        !          2051:        if (tlb_data_32_63 & TME_STP103X_TLB_DATA_V(tlb_data_32_63)) {
        !          2052: 
        !          2053:          /* get the size of this mapping: */
        !          2054:          size
        !          2055:            = (TME_STP103X_PAGE_SIZE_8KB
        !          2056:               << (3 * TME_FIELD_MASK_EXTRACTU(tlb_data_32_63,
        !          2057:                                               TME_STP103X_TLB_DATA_SIZE_MASK(tlb_data_32_63))));
        !          2058: 
        !          2059:          /* load bits 0..31 of the data: */
        !          2060:          tlb_data_0_31 = TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 0);
        !          2061: 
        !          2062:          /* if bits 0..31 of the tag match: */
        !          2063:          if ((tlb_tag_xor_0_31
        !          2064:               & ((0 - size)
        !          2065:                  + ((tlb_data_0_31
        !          2066:                      & TME_STP103X_TLB_DATA_G(tlb_data_0_31))
        !          2067:                     ? 0
        !          2068:                     : TME_STP103X_CONTEXT_MAX))) == 0) {
        !          2069: 
        !          2070:            /* set the used bit: */
        !          2071:            tlb_data_32_63 |= TME_STP103X_TLB_DATA_DIAG_USED(tlb_data_32_63);
        !          2072:            TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 1) = tlb_data_32_63;
        !          2073: 
        !          2074:            /* get the sparc TLB entry: */
        !          2075:            tlb = ls->tme_sparc_ls_tlb;
        !          2076: 
        !          2077:            /* if this is a global mapping, update the TLB context: */
        !          2078:            if (tlb_data_0_31 & TME_STP103X_TLB_DATA_G(tlb_data_0_31)) {
        !          2079:              tlb->tme_sparc_tlb_context = TME_STP103X_CONTEXT_MAX + 1;
        !          2080:            }
        !          2081: 
        !          2082:            /* link the TLB entries: */
        !          2083:            tlb->tme_sparc_tlb_link = tlb_part_i;
        !          2084: 
        !          2085:            /* start the address offset for this mapping: */
        !          2086:            ls->tme_sparc_ls_tlb_map.tme_bus_tlb_addr_offset
        !          2087:              = ((tlb_data_0_31
        !          2088:                  & (tme_uint32_t) TME_STP103X_TLB_DATA_PA)
        !          2089:                 + (((tme_uint64_t)
        !          2090:                     (tlb_data_32_63
        !          2091:                      & (tme_uint32_t) (TME_STP103X_TLB_DATA_PA >> 32)))
        !          2092:                    << 32));
        !          2093: 
        !          2094:            /* copy the E, !CP, IE, and NFO bits into the TLB entry's
        !          2095:               ASI mask.  we predict for the common case, which has CP
        !          2096:               set and all of the other bits clear: */
        !          2097:            /* NB: we ignore the CV bit, because it's always zero in
        !          2098:               the IMMU, and in the DMMU it doesn't count as
        !          2099:               uncacheable as far as atomic instructions are
        !          2100:               concerned: */
        !          2101:            if (__tme_predict_false((tlb_data_0_31
        !          2102:                                     & (TME_STP103X_TLB_DATA_E(tlb_data_0_31)
        !          2103:                                        | TME_STP103X_TLB_DATA_CP(tlb_data_0_31)))
        !          2104:                                    != TME_STP103X_TLB_DATA_CP(tlb_data_0_31))) {
        !          2105:              asi_mask = 0;
        !          2106:              if (tlb_data_0_31 & TME_STP103X_TLB_DATA_E(tlb_data_0_31)) {
        !          2107:                asi_mask += TME_SPARC64_ASI_MASK_FLAG_TLB_SIDE_EFFECTS;
        !          2108:              }
        !          2109:              if ((tlb_data_0_31 & TME_STP103X_TLB_DATA_CP(tlb_data_0_31)) == 0) {
        !          2110:                asi_mask += TME_SPARC64_ASI_MASK_FLAG_TLB_UNCACHEABLE;
        !          2111:              }
        !          2112:            }
        !          2113:            else {
        !          2114:              asi_mask = 0;
        !          2115:            }
        !          2116:            if (__tme_predict_false(tlb_data_32_63
        !          2117:                                    & (TME_STP103X_TLB_DATA_NFO(tlb_data_32_63)
        !          2118:                                       | TME_STP103X_TLB_DATA_IE(tlb_data_32_63)))) {
        !          2119:              if (tlb_data_32_63 & TME_STP103X_TLB_DATA_NFO(tlb_data_32_63)) {
        !          2120:                asi_mask += TME_SPARC64_ASI_FLAG_NO_FAULT;
        !          2121:              }
        !          2122:              if (tlb_data_32_63 & TME_STP103X_TLB_DATA_IE(tlb_data_32_63)) {
        !          2123:                asi_mask += TME_SPARC64_ASI_FLAG_LITTLE;
        !          2124:              }
        !          2125:            }
        !          2126: 
        !          2127:            /* if this mapping is privileged: */
        !          2128:            if (tlb_data_0_31 & TME_STP103X_TLB_DATA_P(tlb_data_0_31)) {
        !          2129: 
        !          2130:              /* if this access is not privileged: */
        !          2131:              if (__tme_predict_false(!TME_SPARC_PRIV(ic))) {
        !          2132: 
        !          2133:                /* trap: */
        !          2134:                ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_PRIVILEGE;
        !          2135:                _tme_stp103x_ls_trap(ic, ls);
        !          2136:                assert (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_NO_FAULT);
        !          2137:                return;
        !          2138:              }
        !          2139:            }
        !          2140: 
        !          2141:            /* otherwise, this mapping is not privileged: */
        !          2142:            else {
        !          2143: 
        !          2144:              /* this TLB entry can be used for privileged and nonprivileged
        !          2145:                 accesses: */
        !          2146:              asi_mask
        !          2147:                += (TME_SPARC64_ASI_MASK_PRIV
        !          2148:                    + TME_SPARC64_ASI_MASK_USER);
        !          2149:            }
        !          2150: 
        !          2151:            /* update the TLB entry's ASI mask: */
        !          2152:            ls->tme_sparc_ls_tlb->tme_sparc_tlb_asi_mask |= asi_mask;
        !          2153: 
        !          2154:            /* if this page is writable: */
        !          2155:            if (tlb_data_0_31 & TME_STP103X_TLB_DATA_W(tlb_data_0_31)) {
        !          2156: 
        !          2157:              /* this mapping can be read and written: */
        !          2158:              cycles_ok = TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE;
        !          2159:            }
        !          2160: 
        !          2161:            /* otherwise, this page is not writable: */
        !          2162:            else {
        !          2163: 
        !          2164:              /* if this is a store or an atomic: */
        !          2165:              if (__tme_predict_false(ls->tme_sparc_ls_lsinfo
        !          2166:                                      & (TME_SPARC_LSINFO_OP_ST
        !          2167:                                         | TME_SPARC_LSINFO_OP_ATOMIC))) {
        !          2168: 
        !          2169:                /* remember if this is a 64KB page: */
        !          2170:                TME_STP103X(ic)->tme_stp103x_dmmu_direct_64KB = (size == TME_STP103X_PAGE_SIZE_64KB);
        !          2171: 
        !          2172:                /* trap: */
        !          2173:                ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_PROTECTION;
        !          2174:                _tme_stp103x_ls_trap(ic, ls);
        !          2175:                abort();
        !          2176:                /* NOTREACHED */
        !          2177:              }
        !          2178: 
        !          2179:              /* this mapping can only be read: */
        !          2180:              cycles_ok = TME_BUS_CYCLE_READ;
        !          2181:            }
        !          2182: 
        !          2183:            /* set the cycles for this mapping: */
        !          2184:            ls->tme_sparc_ls_tlb_map.tme_bus_tlb_cycles_ok = cycles_ok;
        !          2185: 
        !          2186:            /* set the first and last addresses for this mapping: */
        !          2187:            address = ls->tme_sparc_ls_address64;
        !          2188:            address |= (size - 1);
        !          2189:            ls->tme_sparc_ls_tlb_map.tme_bus_tlb_addr_last = address;
        !          2190:            address &= (0 - (tme_uint64_t) size);
        !          2191:            ls->tme_sparc_ls_tlb_map.tme_bus_tlb_addr_first = address;
        !          2192: 
        !          2193:            /* finish the address offset for this mapping: */
        !          2194:            ls->tme_sparc_ls_tlb_map.tme_bus_tlb_addr_offset -= address;
        !          2195: 
        !          2196:            return;
        !          2197:          }
        !          2198:        }
        !          2199:       }
        !          2200:     }
        !          2201: 
        !          2202:     tlb_part_i += 2;
        !          2203:   } while (tlb_part_i % (2 * TME_STP103X_TLB_SIZE));
        !          2204: 
        !          2205:   /* this is a miss: */
        !          2206:   ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_MMU_MISS;
        !          2207:   _tme_stp103x_ls_trap(ic, ls);
        !          2208:   assert (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_NO_FAULT);
        !          2209: }
        !          2210: 
        !          2211: /* the ASI handler for ASI_PHYS_USE_EC*, ASI_PHYS_BYPASS_EC_WITH_EBIT*: */
        !          2212: static void
        !          2213: _tme_stp103x_ls_asi_phys(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          2214: {
        !          2215: 
        !          2216:   /* override the address map function: */
        !          2217:   ls->tme_sparc_ls_address_map = _tme_stp103x_ls_address_map_phys;
        !          2218: }
        !          2219: 
        !          2220: /* the cycle handler for ASI_NUCLEUS_QUAD_LDD*: */
        !          2221: static void
        !          2222: _tme_stp103x_ls_cycle_quad(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          2223: {
        !          2224:   struct tme_sparc_tlb *tlb;
        !          2225:   tme_uint32_t asi_mask;
        !          2226:   _tme_const tme_shared tme_uint8_t *memory;
        !          2227: #if !TME_THREADS_COOPERATIVE
        !          2228: #ifdef tme_memory_atomic_read128
        !          2229:   tme_uint128_t quad;
        !          2230: #endif /* tme_memory_atomic_read128 */
        !          2231: #endif /* !TME_THREADS_COOPERATIVE */
        !          2232:   tme_uint64_t quad_64lo;
        !          2233:   tme_uint64_t quad_64hi;
        !          2234:   tme_uint64_t *_rd;
        !          2235: 
        !          2236:   /* get the TLB entry: */
        !          2237:   tlb = ls->tme_sparc_ls_tlb;
        !          2238: 
        !          2239:   /* get the ASI mask: */
        !          2240:   asi_mask = tlb->tme_sparc_tlb_asi_mask;
        !          2241:   
        !          2242:   /* this TLB entry must be for cacheable memory: */
        !          2243:   if (__tme_predict_false(asi_mask
        !          2244:                          & TME_SPARC64_ASI_MASK_FLAG_TLB_UNCACHEABLE)) {
        !          2245: 
        !          2246:     /* we must have caught this on the first cycle: */
        !          2247:     assert (ls->tme_sparc_ls_buffer_offset == 0);
        !          2248: 
        !          2249:     /* fault: */
        !          2250:     ls->tme_sparc_ls_faults |= TME_SPARC64_LS_FAULT_UNCACHEABLE;
        !          2251:     return;
        !          2252:   }
        !          2253: 
        !          2254:   /* assume that we can't do a fast transfer: */
        !          2255:   memory = TME_EMULATOR_OFF_UNDEF;
        !          2256: 
        !          2257:   /* if this is the first cycle: */
        !          2258:   if (ls->tme_sparc_ls_buffer_offset == 0) {
        !          2259: 
        !          2260:     /* if this TLB entry allows fast transfer of all of the addresses: */
        !          2261:     if (__tme_predict_true((((tme_bus_addr64_t) tlb->tme_sparc_tlb_addr_last)
        !          2262:                            - ls->tme_sparc_ls_address64)
        !          2263:                           >= ((sizeof(tme_uint64_t) * 2) - 1))) {
        !          2264: 
        !          2265:       /* we may be able do a fast transfer: */
        !          2266:       memory = tlb->tme_sparc_tlb_emulator_off_read;
        !          2267:     }
        !          2268:   }
        !          2269: 
        !          2270:   /* if we can't do a fast transfer: */
        !          2271:   if (__tme_predict_false(memory == TME_EMULATOR_OFF_UNDEF)) {
        !          2272: 
        !          2273:     /* do a slow cycle: */
        !          2274:     tme_sparc64_load(ic, ls);
        !          2275: 
        !          2276:     /* if this was not the last cycle, return now: */
        !          2277:     if (ls->tme_sparc_ls_size != 0) {
        !          2278:       return;
        !          2279:     }
        !          2280: 
        !          2281:     /* fake a fast transfer from the memory buffer: */
        !          2282:     memory = &ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer8s[0];
        !          2283:     memory -= ls->tme_sparc_ls_address64;
        !          2284:   }
        !          2285: 
        !          2286:   /* finish the memory address: */
        !          2287:   memory += ls->tme_sparc_ls_address64;
        !          2288: 
        !          2289:   /* if threads are cooperative: */
        !          2290: #if TME_THREADS_COOPERATIVE
        !          2291: 
        !          2292:   /* do two 64-bit loads: */
        !          2293:   quad_64lo
        !          2294:     = tme_memory_bus_read64(((_tme_const tme_shared tme_uint64_t *) memory) + 0,
        !          2295:                            tlb->tme_sparc_tlb_bus_rwlock,
        !          2296:                            (sizeof(tme_uint64_t) * 2),
        !          2297:                            sizeof(tme_uint64_t));
        !          2298:   quad_64hi
        !          2299:     = tme_memory_bus_read64(((_tme_const tme_shared tme_uint64_t *) memory) + 1,
        !          2300:                            tlb->tme_sparc_tlb_bus_rwlock,
        !          2301:                            (sizeof(tme_uint64_t) * 1),
        !          2302:                            sizeof(tme_uint64_t));
        !          2303: 
        !          2304:   /* otherwise, threads are not cooperative: */
        !          2305: #else  /* !TME_THREADS_COOPERATIVE */
        !          2306: 
        !          2307:   /* if host supports an atomic 128-bit read: */
        !          2308: #ifdef tme_memory_atomic_read128
        !          2309: 
        !          2310:   /* do the atomic 128-bit read: */
        !          2311:   quad
        !          2312:     = tme_memory_atomic_read128((_tme_const tme_shared tme_uint128_t *) memory,
        !          2313:                                tlb->tme_sparc_tlb_bus_rwlock,
        !          2314:                                sizeof(tme_uint128_t));
        !          2315: 
        !          2316:   /* get the two parts of the load: */
        !          2317: #if TME_ENDIAN_NATIVE == TME_ENDIAN_BIG
        !          2318:   quad_64lo = quad >> 64;
        !          2319:   quad_64hi = quad;
        !          2320: #elif TME_ENDIAN_NATIVE == TME_ENDIAN_LITTLE
        !          2321:   quad_64lo = quad;
        !          2322:   quad_64hi = quad >> 64;
        !          2323: #endif
        !          2324: #else  /* !tme_memory_atomic_read128 */
        !          2325: #error "non-cooperative threads requires an atomic 128-bit read"
        !          2326: #endif /* !tme_memory_atomic_read128 */
        !          2327: #endif /* !TME_THREADS_COOPERATIVE */
        !          2328: 
        !          2329:   /* swap the two 64-bit values as needed: */
        !          2330:   if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_ENDIAN_LITTLE) {
        !          2331:     quad_64lo = tme_letoh_u64(quad_64lo);
        !          2332:     quad_64hi = tme_letoh_u64(quad_64hi);
        !          2333:   }
        !          2334:   else {
        !          2335:     quad_64lo = tme_betoh_u64(quad_64lo);
        !          2336:     quad_64hi = tme_betoh_u64(quad_64hi);
        !          2337:   }
        !          2338: 
        !          2339:   /* complete the load: */
        !          2340:   ls->tme_sparc_ls_size = 0;
        !          2341:   _rd = ls->tme_sparc_ls_rd64;
        !          2342:   TME_SPARC_FORMAT3_RD = quad_64lo;
        !          2343:   TME_SPARC_FORMAT3_RD_ODD(tme_ic_ireg_uint64) = quad_64hi;
        !          2344: }
        !          2345: 
        !          2346: /* the ASI handler for ASI_NUCLEUS_QUAD_LDD*: */
        !          2347: static void
        !          2348: _tme_stp103x_ls_asi_quad(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          2349: {
        !          2350: 
        !          2351:   /* we need to do the complete load: */
        !          2352:   ls->tme_sparc_ls_size = sizeof(tme_uint64_t) * 2;
        !          2353:   ls->tme_sparc_ls_buffer_offset = 0;
        !          2354:   ls->tme_sparc_ls_lsinfo
        !          2355:     |= (TME_SPARC_LSINFO_SLOW_CYCLES
        !          2356:        + TME_SPARC_LSINFO_LD_COMPLETED);
        !          2357:   ls->tme_sparc_ls_cycle = _tme_stp103x_ls_cycle_quad;
        !          2358: 
        !          2359:   /* an instruction other than ldda is illegal: */
        !          2360:   if (__tme_predict_false((ic->_tme_sparc_insn
        !          2361:                           & (0x3f << 19))
        !          2362:                          != (0x13 << 19))) {
        !          2363:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          2364:   }
        !          2365: 
        !          2366:   /* the address must be 128-bit aligned: */
        !          2367:   if (__tme_predict_false(((tme_uint32_t) ls->tme_sparc_ls_address64)
        !          2368:                          % (sizeof(tme_uint64_t) * 2))) {
        !          2369:     ls->tme_sparc_ls_faults |= TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED;
        !          2370:   }
        !          2371: }
        !          2372: 
        !          2373: /* the ASI handler for various infrequently-used ASIs: */
        !          2374: static void
        !          2375: _tme_stp103x_ls_asi_slow(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          2376: {
        !          2377:   tme_uint32_t lsinfo_ops;
        !          2378:   int size_ok;
        !          2379:   int address_ok;
        !          2380:   tme_uint64_t value_mask;
        !          2381:   void (*update_write) _TME_P((struct tme_sparc *, tme_uint64_t));
        !          2382:   int redispatch;
        !          2383:   tme_uint64_t *_value64;
        !          2384:   tme_uint32_t *_value32;
        !          2385:   tme_uint64_t value;
        !          2386:   tme_uint64_t value_now;
        !          2387: 
        !          2388:   /* assume that this ASI allows reads and writes: */
        !          2389:   lsinfo_ops
        !          2390:     = (TME_SPARC_LSINFO_OP_LD
        !          2391:        | TME_SPARC_LSINFO_OP_ST);
        !          2392: 
        !          2393:   /* assume that this ASI allows only 64-bit accesses: */
        !          2394:   size_ok = (ls->tme_sparc_ls_size == sizeof(tme_uint64_t));
        !          2395: 
        !          2396:   /* assume that this ASI allows only accesses to address zero: */
        !          2397:   address_ok = (ls->tme_sparc_ls_address64 == 0);
        !          2398: 
        !          2399:   /* assume that this ASI doesn't mask values written: */
        !          2400:   value_mask = 0 - (tme_uint64_t) 1;
        !          2401: 
        !          2402:   /* assume that this ASI has no write side-effects: */
        !          2403:   update_write = NULL;
        !          2404: 
        !          2405:   /* assume that a write won't need a redispatch: */
        !          2406:   redispatch = FALSE;
        !          2407: 
        !          2408:   /* assume that the access is invalid: */
        !          2409:   _value64 = NULL;
        !          2410:   _value32 = NULL;
        !          2411: 
        !          2412:   /* dispatch on the ASI: */
        !          2413:   switch (TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask)) {
        !          2414: 
        !          2415:     /* all unknown ASIs: */
        !          2416:   default:
        !          2417:     address_ok = FALSE;
        !          2418:     break;
        !          2419: 
        !          2420:   case TME_STP103X_ASI_LSU_CONTROL_REG:
        !          2421:     _value64 = &TME_STP103X(ic)->tme_stp103x_lsu;
        !          2422:     update_write = _tme_stp103x_update_lsu;
        !          2423:     break;
        !          2424: 
        !          2425:   case TME_STP103X_ASI_INTR_DISPATCH_STATUS:
        !          2426:     lsinfo_ops = TME_SPARC_LSINFO_OP_LD;
        !          2427:     /* XXX FIXME WRITEME: */
        !          2428:     abort();
        !          2429:     break;
        !          2430: 
        !          2431:   case TME_STP103X_ASI_INTR_RECEIVE:
        !          2432:     value_now
        !          2433:       = ((tme_memory_atomic_read_flag(&TME_STP103X(ic)->tme_stp103x_intr_receive_busy)
        !          2434:          ? TME_STP103X_INTR_RECEIVE_BUSY
        !          2435:          : 0)
        !          2436:         + TME_STP103X(ic)->tme_stp103x_intr_receive_mid);
        !          2437:     _value64 = &value_now;
        !          2438:     update_write = _tme_stp103x_update_intr_receive;
        !          2439:     break;
        !          2440: 
        !          2441:   case TME_STP103X_ASI_UPA_CONFIG_REG:
        !          2442:     _value64 = &TME_STP103X(ic)->tme_stp103x_upa_config;
        !          2443:     update_write = _tme_stp103x_update_upa_config;
        !          2444:     break;
        !          2445:     
        !          2446:   case TME_STP103X_ASI_ESTATE_ERROR_EN_REG:
        !          2447:     _value32 = &TME_STP103X(ic)->tme_stp103x_estate_error_enable;
        !          2448:     value_mask
        !          2449:       = (TME_STP103X_ESTATE_ERROR_ENABLE_CEEN
        !          2450:         | TME_STP103X_ESTATE_ERROR_ENABLE_NCEEN
        !          2451:         | TME_STP103X_ESTATE_ERROR_ENABLE_ISAPEN);
        !          2452:     break;
        !          2453: 
        !          2454:   case TME_STP103X_ASI_AFSR:
        !          2455:     _value64 = &TME_STP103X(ic)->tme_stp103x_afsr;
        !          2456:     update_write = _tme_stp103x_update_afsr;
        !          2457:     break;
        !          2458: 
        !          2459:   case TME_STP103X_ASI_AFAR:
        !          2460:     _value64 = &TME_STP103X(ic)->tme_stp103x_afar;
        !          2461:     value_mask = TME_STP103X_PA_SIZE - (1 << 4);
        !          2462:     break;
        !          2463: 
        !          2464:   case TME_STP103X_ASI_ECACHE_TAG_DATA:
        !          2465:     _value32 = &TME_STP103X(ic)->tme_stp103x_ecache_tag_data;
        !          2466:     break;
        !          2467:   }
        !          2468: 
        !          2469:   /* check the access: */
        !          2470:   if (__tme_predict_false((ls->tme_sparc_ls_lsinfo & lsinfo_ops) == 0
        !          2471:                          || !size_ok
        !          2472:                          || !address_ok)) {
        !          2473:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          2474:   }
        !          2475: 
        !          2476:   /* if there are any faults: */
        !          2477:   if (__tme_predict_false(ls->tme_sparc_ls_faults |= TME_SPARC_LS_FAULT_NONE)) {
        !          2478:     return;
        !          2479:   }
        !          2480: 
        !          2481:   /* get the raw value to read or write: */
        !          2482:   value
        !          2483:     = ((ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_ST)
        !          2484:        ? *ls->tme_sparc_ls_rd64
        !          2485:        : _value64 != NULL
        !          2486:        ? *_value64
        !          2487:        : *_value32);
        !          2488: 
        !          2489:   /* mask the value: */
        !          2490:   value &= value_mask;
        !          2491: 
        !          2492:   /* complete the load or store: */
        !          2493:   ls->tme_sparc_ls_size = 0;
        !          2494: 
        !          2495:   /* if this is a load: */
        !          2496:   if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_LD) {
        !          2497: 
        !          2498:     /* complete the load: */
        !          2499:     *ls->tme_sparc_ls_rd64 = value;
        !          2500:     ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_LD_COMPLETED;
        !          2501:   }
        !          2502: 
        !          2503:   /* otherwise, this is a store: */
        !          2504:   else {
        !          2505: 
        !          2506:     /* if this value has write side-effects: */
        !          2507:     if (update_write != NULL) {
        !          2508: 
        !          2509:       /* do the write side-effects: */
        !          2510:       (*update_write)(ic, value);
        !          2511:     }
        !          2512: 
        !          2513:     /* otherwise, this value has no write side-effects: */
        !          2514:     else {
        !          2515: 
        !          2516:       /* complete the store: */
        !          2517:       if (_value64 != NULL) {
        !          2518:        *_value64 = value;
        !          2519:       }
        !          2520:       else {
        !          2521:        *_value32 = value;
        !          2522:       }
        !          2523:     }
        !          2524: 
        !          2525:     /* if this store needs a redispatch: */
        !          2526:     if (redispatch) {
        !          2527:       tme_bus_tlb_unbusy(&ic->tme_sparc_tlbs[ls->tme_sparc_ls_tlb_i].tme_sparc_tlb_bus_tlb);
        !          2528:       tme_sparc_redispatch(ic);
        !          2529:     }
        !          2530:   }
        !          2531: }
        !          2532: 
        !          2533: /* the ASI handler for ASI_DMMU and ASI_IMMU: */
        !          2534: static void
        !          2535: _tme_stp103x_ls_asi_mmu(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          2536: {
        !          2537:   tme_uint64_t address;
        !          2538:   tme_uint32_t address_0_31;
        !          2539:   struct tme_stp103x_mmu *mmu;
        !          2540:   tme_uint32_t lsinfo;
        !          2541:   tme_uint64_t tag_target;
        !          2542:   tme_uint32_t context;
        !          2543:   tme_uint64_t *_value64;
        !          2544:   tme_uint32_t *_value32;
        !          2545:   int value_has_va;
        !          2546:   tme_uint64_t value_mask;
        !          2547:   tme_uint32_t lsinfo_ops;
        !          2548:   int redispatch;
        !          2549:   tme_uint64_t value;
        !          2550: 
        !          2551:   /* if this is a 64-bit access that hasn't faulted yet: */
        !          2552:   if (__tme_predict_true(ls->tme_sparc_ls_size == sizeof(tme_uint64_t)
        !          2553:                         && ls->tme_sparc_ls_faults == TME_SPARC_LS_FAULT_NONE)) {
        !          2554: 
        !          2555:     /* get the address: */
        !          2556:     address = ls->tme_sparc_ls_address64;
        !          2557: 
        !          2558:     /* if the address fits into 32 bits: */
        !          2559:     if (__tme_predict_true((address & (0 - (((tme_uint64_t) 1) << 32))) == 0)) {
        !          2560: 
        !          2561:       /* truncate the address to 32 bits: */
        !          2562:       address_0_31 = address;
        !          2563: 
        !          2564:       /* get the MMU state: */
        !          2565:       mmu
        !          2566:        = (TME_STP103X_ASI_MMU_MASK_IS_DMMU(ls->tme_sparc_ls_asi_mask)
        !          2567:           ? &TME_STP103X(ic)->tme_stp103x_dmmu
        !          2568:           : &TME_STP103X(ic)->tme_stp103x_immu);
        !          2569: 
        !          2570:       /* get the load/store information: */
        !          2571:       lsinfo = ls->tme_sparc_ls_lsinfo;
        !          2572: 
        !          2573:       /* address 0x0 is the tag target register: */
        !          2574:       if (address_0_31 == 0) {
        !          2575: 
        !          2576:        /* if this is a load: */
        !          2577:        if (lsinfo & TME_SPARC_LSINFO_OP_LD) {
        !          2578: 
        !          2579:          /* make the value for the tag target register: */
        !          2580:          tag_target = mmu->tme_stp103x_mmu_tag_access;
        !          2581:          context = ((tme_uint32_t) tag_target) & TME_STP103X_CONTEXT_MAX;
        !          2582:          tag_target >>= 22;
        !          2583:          tag_target |= ((tme_uint64_t) (context << (48 - 32))) << 32;
        !          2584: 
        !          2585:          /* complete the load: */
        !          2586:          *ls->tme_sparc_ls_rd64 = tag_target;
        !          2587:          ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_LD_COMPLETED;
        !          2588:          ls->tme_sparc_ls_size = 0;
        !          2589:          return;
        !          2590:        }
        !          2591:       }
        !          2592: 
        !          2593:       else {
        !          2594: 
        !          2595:        /* assume that the register is invalid: */
        !          2596:        _value64 = NULL;
        !          2597:        _value32 = NULL;
        !          2598: 
        !          2599:        /* assume that values for this register aren't virtual
        !          2600:           addresses, and don't have any masked bits: */
        !          2601:        value_has_va = FALSE;
        !          2602:        value_mask = 0 - (tme_uint64_t) 1;
        !          2603: 
        !          2604:        /* assume that this register allows reads and writes: */
        !          2605:        lsinfo_ops
        !          2606:          = (TME_SPARC_LSINFO_OP_LD
        !          2607:             | TME_SPARC_LSINFO_OP_ST);
        !          2608: 
        !          2609:        /* assume that a write to this register won't need a redispatch: */
        !          2610:        redispatch = FALSE;
        !          2611: 
        !          2612:        /* address 0x18 is the synchronous fault status register: */
        !          2613:        if (address_0_31 == 0x18) {
        !          2614:          _value64 = &mmu->tme_stp103x_mmu_sfsr;
        !          2615:        }
        !          2616: 
        !          2617:        /* address 0x28 is the TSB register: */
        !          2618:        else if (address_0_31 == 0x28) {
        !          2619:          _value64 = &mmu->tme_stp103x_mmu_tsb;
        !          2620:          value_has_va = TRUE;
        !          2621:        }
        !          2622: 
        !          2623:        /* address 0x30 is the tag access register: */
        !          2624:        else if (address_0_31 == 0x30) {
        !          2625:          _value64 = &mmu->tme_stp103x_mmu_tag_access;
        !          2626:          value_has_va = TRUE;
        !          2627:        }
        !          2628: 
        !          2629:        /* if this is ASI_DMMU: */
        !          2630:        else if (mmu == &TME_STP103X(ic)->tme_stp103x_dmmu) {
        !          2631: 
        !          2632:          /* address 0x8 is the primary context register: */
        !          2633:          if (address_0_31 == 0x8) {
        !          2634:            _value32 = &ic->tme_sparc_memory_context_primary;
        !          2635:            value_mask = TME_STP103X_CONTEXT_MAX;
        !          2636:            redispatch = TRUE;
        !          2637:          }
        !          2638: 
        !          2639:          /* address 0x10 is the secondary context register: */
        !          2640:          else if (address_0_31 == 0x10) {
        !          2641:            _value32 = &ic->tme_sparc_memory_context_secondary;
        !          2642:            value_mask = TME_STP103X_CONTEXT_MAX;
        !          2643:          }
        !          2644: 
        !          2645:          /* address 0x20 is the synchronous fault address register: */
        !          2646:          else if (address_0_31 == 0x20) {
        !          2647:            _value64 = &TME_STP103X(ic)->tme_stp103x_dmmu_sfar;
        !          2648:            lsinfo_ops = TME_SPARC_LSINFO_OP_LD;
        !          2649:          }
        !          2650: 
        !          2651:          /* address 0x38 is the VA Data Watchpoint register: */
        !          2652:          else if (address_0_31 == 0x38) {
        !          2653:            abort();
        !          2654:          }
        !          2655: 
        !          2656:          /* address 0x40 is the PA Data Watchpoint register: */
        !          2657:          else if (address_0_31 == 0x38) {
        !          2658:            abort();
        !          2659:          }
        !          2660:        }
        !          2661: 
        !          2662:        /* if the register valid and supports this access: */
        !          2663:        if (__tme_predict_true((_value64 != NULL
        !          2664:                                || _value32 != NULL)
        !          2665:                               && (lsinfo & lsinfo_ops) != 0)) {
        !          2666: 
        !          2667:          /* get the raw value to read or write: */
        !          2668:          value
        !          2669:            = (lsinfo & TME_SPARC_LSINFO_OP_ST
        !          2670:               ? *ls->tme_sparc_ls_rd64
        !          2671:               : _value64 != NULL
        !          2672:               ? *_value64
        !          2673:               : *_value32);
        !          2674: 
        !          2675:          /* if this value has a virtual address: */
        !          2676:          if (value_has_va) {
        !          2677: 
        !          2678:            /* force the virtual address to be in range: */
        !          2679:            value |= (0 - (TME_STP103X_VA_HOLE_START * 2));
        !          2680:            value = (value ^ TME_STP103X_VA_HOLE_START) + TME_STP103X_VA_HOLE_START;
        !          2681:          }
        !          2682: 
        !          2683:          /* mask the value: */
        !          2684:          value &= value_mask;
        !          2685: 
        !          2686:          /* if this is a load: */
        !          2687:          if (lsinfo & TME_SPARC_LSINFO_OP_LD) {
        !          2688: 
        !          2689:            /* complete the load: */
        !          2690:            *ls->tme_sparc_ls_rd64 = value;
        !          2691:            ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_LD_COMPLETED;
        !          2692:          }
        !          2693: 
        !          2694:          /* otherwise, this is a store: */
        !          2695:          else {
        !          2696: 
        !          2697:            /* complete the store: */
        !          2698:            if (_value64 != NULL) {
        !          2699:              *_value64 = value;
        !          2700:            }
        !          2701:            else {
        !          2702:              *_value32 = value;
        !          2703:            }
        !          2704: 
        !          2705:            /* if this store needs a redispatch: */
        !          2706:            if (redispatch) {
        !          2707:              tme_bus_tlb_unbusy(&ic->tme_sparc_tlbs[ls->tme_sparc_ls_tlb_i].tme_sparc_tlb_bus_tlb);
        !          2708:              tme_sparc_redispatch(ic);
        !          2709:            }
        !          2710:          }
        !          2711: 
        !          2712:          /* complete the load or store: */
        !          2713:          ls->tme_sparc_ls_size = 0;
        !          2714:          return;
        !          2715:        }
        !          2716:       }
        !          2717:     }
        !          2718:   }
        !          2719: 
        !          2720:   /* this is an illegal access: */
        !          2721:   ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          2722: }  
        !          2723: 
        !          2724: /* the ASI handler for:
        !          2725:    ASI_DMMU_TSB_8KB_PTR_REG, ASI_DMMU_TSB_64KB_PTR_REG,
        !          2726:    ASI_IMMU_TSB_8KB_PTR_REG, ASI_IMMU_TSB_64KB_PTR_REG,
        !          2727:    ASI_DMMU_TSB_DIRECT_PTR_REG: */
        !          2728: static void
        !          2729: _tme_stp103x_ls_asi_tsb_ptr(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          2730: {
        !          2731:   tme_uint32_t asi_mask;
        !          2732:   struct tme_stp103x_mmu *mmu;
        !          2733:   tme_uint32_t pointer_0_31;
        !          2734:   tme_uint32_t size_64KB;
        !          2735:   tme_uint32_t tsb_0_31;
        !          2736:   tme_uint32_t tsb_size;
        !          2737: 
        !          2738:   /* if this is not a 64-bit load of address zero: */
        !          2739:   if (__tme_predict_false(ls->tme_sparc_ls_size != sizeof(tme_uint64_t)
        !          2740:                          || (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_LD) == 0
        !          2741:                          || ls->tme_sparc_ls_address64 != 0)) {
        !          2742: 
        !          2743:     /* this is an illegal access: */
        !          2744:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          2745:   }
        !          2746: 
        !          2747:   /* if this access has faulted: */
        !          2748:   if (__tme_predict_false(ls->tme_sparc_ls_faults != TME_SPARC_LS_FAULT_NONE)) {
        !          2749:     return;
        !          2750:   }
        !          2751: 
        !          2752:   /* get the ASI mask from the instruction: */
        !          2753:   asi_mask = ls->tme_sparc_ls_asi_mask;
        !          2754: 
        !          2755:   /* get the common MMU state: */
        !          2756:   mmu
        !          2757:     = (TME_STP103X_ASI_MMU_MASK_IS_DMMU(asi_mask)
        !          2758:        ? &TME_STP103X(ic)->tme_stp103x_dmmu
        !          2759:        : &TME_STP103X(ic)->tme_stp103x_immu);
        !          2760: 
        !          2761:   /* start the TSB pointer with the tag access register: */
        !          2762:   pointer_0_31 = mmu->tme_stp103x_mmu_tag_access;
        !          2763: 
        !          2764:   /* if this might be a 64KB page: */
        !          2765:   size_64KB = asi_mask & TME_SPARC_ASI_MASK_RAW(TME_STP103X_ASI_FLAG_TSB_64KB_PTR);
        !          2766:   if (size_64KB) {
        !          2767: 
        !          2768:     /* if this is ASI_DMMU_TSB_DIRECT_PTR_REG: */
        !          2769:     if (asi_mask & TME_SPARC_ASI_MASK_RAW(TME_STP103X_ASI_FLAG_TSB_8KB_PTR)) {
        !          2770: 
        !          2771:       /* this is a 64KB page if the last fast_data_access_protection
        !          2772:         trap was for a 64KB page: */
        !          2773:       size_64KB = TME_STP103X(ic)->tme_stp103x_dmmu_direct_64KB;
        !          2774:     }
        !          2775: 
        !          2776:     /* if this is a 64KB page, shift the TSB pointer: */
        !          2777:     if (size_64KB) {
        !          2778:       pointer_0_31 /= (TME_STP103X_PAGE_SIZE_64KB / TME_STP103X_PAGE_SIZE_8KB);
        !          2779:     }
        !          2780:   }
        !          2781: 
        !          2782:   /* shift the tag access register in the TSB pointer down to index a
        !          2783:      16-byte TSB entry: */
        !          2784:   pointer_0_31 = (pointer_0_31 / (TME_STP103X_PAGE_SIZE_8KB / 16)) & (0 - (tme_uint32_t) 16);
        !          2785: 
        !          2786:   /* get bits 0..31 of the TSB register: */
        !          2787:   tsb_0_31 = mmu->tme_stp103x_mmu_tsb;
        !          2788: 
        !          2789:   /* get the size of (one half of) the TSB: */
        !          2790:   tsb_size = TME_STP103X_PAGE_SIZE_8KB;
        !          2791:   tsb_size <<= (tsb_0_31 & TME_STP103X_TSB_SIZE);
        !          2792: 
        !          2793:   /* finish the offset of the entry in (one half of) the TSB: */
        !          2794:   pointer_0_31 &= (tsb_size - 1);
        !          2795: 
        !          2796:   /* if this is a split TSB: */
        !          2797:   if (tsb_0_31 & TME_STP103X_TSB_SPLIT) {
        !          2798: 
        !          2799:     /* if this is a 64KB page, select the other half of the TSB: */
        !          2800:     if (size_64KB) {
        !          2801:       pointer_0_31 += tsb_size;
        !          2802:     }
        !          2803: 
        !          2804:     /* the TSB is actually two halves: */
        !          2805:     tsb_size *= 2;
        !          2806:   }
        !          2807: 
        !          2808:   /* finish bits 0..31 of the TSB pointer: */
        !          2809:   pointer_0_31 += (tsb_0_31 & (0 - tsb_size));
        !          2810: 
        !          2811:   /* complete the load: */
        !          2812:   *ls->tme_sparc_ls_rd64
        !          2813:     = ((mmu->tme_stp103x_mmu_tsb
        !          2814:        & (0 - (((tme_uint64_t) 1) << 32)))
        !          2815:        | pointer_0_31);
        !          2816:   ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_LD_COMPLETED;
        !          2817:   ls->tme_sparc_ls_size = 0;
        !          2818: }
        !          2819: 
        !          2820: /* the ASI handler for ASI_ITLB_DATA_IN_REG, ASI_DTLB_DATA_IN_REG: */
        !          2821: static void
        !          2822: _tme_stp103x_ls_asi_tlb_data_in(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          2823: {
        !          2824:   signed long tlb_part_i;
        !          2825:   signed long tlb_part_i_invalid;
        !          2826:   signed long tlb_part_i_unlocked;
        !          2827:   signed long tlb_part_i_unlocked_unused;
        !          2828:   tme_uint32_t tlb_data_32_63;
        !          2829: 
        !          2830:   /* if this is not a 64-bit store of address zero: */
        !          2831:   if (__tme_predict_false(ls->tme_sparc_ls_size != sizeof(tme_uint64_t)
        !          2832:                          || (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_ST) == 0
        !          2833:                          || ls->tme_sparc_ls_address64 != 0)) {
        !          2834: 
        !          2835:     /* this is an illegal access: */
        !          2836:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          2837:   }
        !          2838: 
        !          2839:   /* if this access has faulted: */
        !          2840:   if (__tme_predict_false(ls->tme_sparc_ls_faults != TME_SPARC_LS_FAULT_NONE)) {
        !          2841:     return;
        !          2842:   }
        !          2843: 
        !          2844:   /* if this is ASI_DTLB_DATA_IN_REG, start at the last entry of the
        !          2845:      DTLB, otherwise start at the last entry of the ITLB: */
        !          2846:   tlb_part_i
        !          2847:     = (TME_STP103X_ASI_MMU_MASK_IS_DMMU(ls->tme_sparc_ls_asi_mask)
        !          2848:        ? TME_STP103X_TLB_PART_0_DMMU + (TME_STP103X_TLB_SIZE * 2) - 2
        !          2849:        : TME_STP103X_TLB_PART_0_IMMU + (TME_STP103X_TLB_SIZE * 2) - 2);
        !          2850: 
        !          2851:   /* search for invalid, unlocked, and unlocked+unused TLB entries: */
        !          2852:   tlb_part_i_invalid = -1;
        !          2853:   tlb_part_i_unlocked = -1;
        !          2854:   tlb_part_i_unlocked_unused = -1;
        !          2855:   for (;;) {
        !          2856: 
        !          2857:     /* load bits 32..63 of the TLB entry's data: */
        !          2858:     tlb_data_32_63 = TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 1);
        !          2859: 
        !          2860:     /* if this TLB entry is invalid: */
        !          2861:     if ((tlb_data_32_63 & TME_STP103X_TLB_DATA_V(tlb_data_32_63)) == 0) {
        !          2862: 
        !          2863:       /* track the lowest-numbered invalid TLB entry: */
        !          2864:       tlb_part_i_invalid = tlb_part_i;
        !          2865:     }
        !          2866: 
        !          2867:     /* if this TLB entry is not locked: */
        !          2868:     if ((TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 0)
        !          2869:         & TME_STP103X_TLB_DATA_L((tme_uint32_t) 0)) == 0) {
        !          2870: 
        !          2871:       /* track the lowest-numbered unlocked TLB entry: */
        !          2872:       tlb_part_i_unlocked = tlb_part_i;
        !          2873: 
        !          2874:       /* if the TLB entry's used bit is clear: */
        !          2875:       if ((tlb_data_32_63 & TME_STP103X_TLB_DATA_DIAG_USED(tlb_data_32_63)) == 0) {
        !          2876: 
        !          2877:        /* track the lowest-numbered unlocked and unused TLB entry: */
        !          2878:        tlb_part_i_unlocked_unused = tlb_part_i;
        !          2879:       }
        !          2880:     }
        !          2881: 
        !          2882:     /* if we have not exhausted the TLB: */
        !          2883:     if (tlb_part_i % (TME_STP103X_TLB_SIZE * 2)) {
        !          2884:       tlb_part_i -= 2;
        !          2885:       continue;
        !          2886:     }
        !          2887: 
        !          2888:     /* if there is an invalid TLB entry: */
        !          2889:     if (tlb_part_i_invalid >= 0) {
        !          2890:       tlb_part_i = tlb_part_i_invalid;
        !          2891:       break;
        !          2892:     }
        !          2893: 
        !          2894:     /* otherwise, if there is an unlocked and unused TLB entry: */
        !          2895:     if (tlb_part_i_unlocked_unused >= 0) {
        !          2896:       tlb_part_i = tlb_part_i_unlocked_unused;
        !          2897:     }
        !          2898: 
        !          2899:     /* otherwise, there is no invalid TLB entry and no unlocked and
        !          2900:        unused TLB entry: */
        !          2901:     else {
        !          2902: 
        !          2903:       /* clear the used bits on all TLB entries: */
        !          2904:       do {
        !          2905:        TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 1)
        !          2906:          &= ~TME_STP103X_TLB_DATA_DIAG_USED(tlb_data_32_63);
        !          2907:        tlb_part_i += 2;
        !          2908:       } while (tlb_part_i % (TME_STP103X_TLB_SIZE * 2));
        !          2909: 
        !          2910:       /* there must be an unlocked TLB entry: */
        !          2911:       assert (tlb_part_i_unlocked >= 0);
        !          2912:       tlb_part_i = tlb_part_i_unlocked;
        !          2913:     }
        !          2914: 
        !          2915:     /* invalidate this TLB entry: */
        !          2916:     _tme_stp103x_tlb_invalidate(ic, tlb_part_i);
        !          2917:     break;
        !          2918:   }
        !          2919: 
        !          2920:   /* complete the store: */
        !          2921: #if TME_STP103X_TLB_PART_0_DMMU >= TME_STP103X_TLB_PART_0_IMMU
        !          2922: #error "TME_STP103X_TLB_PART_0_DMMU or TME_STP103X_TLB_PART_0_IMMU changed"
        !          2923: #endif
        !          2924:   TME_STP103X(ic)->tme_stp103x_tlb_64s(tlb_part_i + 0)
        !          2925:     = (tlb_part_i < TME_STP103X_TLB_PART_0_IMMU
        !          2926:        ? &TME_STP103X(ic)->tme_stp103x_dmmu
        !          2927:        : &TME_STP103X(ic)->tme_stp103x_immu)->tme_stp103x_mmu_tag_access;
        !          2928:   TME_STP103X(ic)->tme_stp103x_tlb_64s(tlb_part_i + 1) = *ls->tme_sparc_ls_rd64;
        !          2929:   ls->tme_sparc_ls_size = 0;
        !          2930: }
        !          2931: 
        !          2932: /* ASI_ITLB_DATA_ACCESS_REG, ASI_DTLB_DATA_ACCESS_REG: */
        !          2933: static void
        !          2934: _tme_stp103x_ls_asi_tlb_data_access(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          2935: {
        !          2936:   unsigned long tlb_part_i;
        !          2937:   tme_uint64_t *_tag_access;
        !          2938: 
        !          2939:   /* XXX FIXME WRITEME table 6-11 hints that it's possible to do a
        !          2940:      casxa to DTLB_DATA_ACCESS_REG.  also see the WRITEME in
        !          2941:      _tme_stp103x_ls_trap(): */
        !          2942:   assert ((ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_ATOMIC) == 0);
        !          2943: 
        !          2944:   /* if this is not a 64-bit load or store: */
        !          2945:   if (__tme_predict_false(ls->tme_sparc_ls_size != sizeof(tme_uint64_t)
        !          2946:                          || (ls->tme_sparc_ls_lsinfo
        !          2947:                              & (TME_SPARC_LSINFO_OP_LD
        !          2948:                                 | TME_SPARC_LSINFO_OP_ST)) == 0)) {
        !          2949: 
        !          2950:     /* this is an illegal access: */
        !          2951:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          2952:   }
        !          2953: 
        !          2954:   /* if this access has faulted: */
        !          2955:   if (__tme_predict_false(ls->tme_sparc_ls_faults != TME_SPARC_LS_FAULT_NONE)) {
        !          2956:     return;
        !          2957:   }
        !          2958: 
        !          2959:   /* get the addressed TLB entry and common MMU state: */
        !          2960:   tlb_part_i = ls->tme_sparc_ls_address64;
        !          2961:   tlb_part_i %= TME_STP103X_TLB_SIZE * sizeof(tme_uint64_t);
        !          2962:   tlb_part_i /= (sizeof(tme_uint64_t) / 2);
        !          2963:   tlb_part_i += TME_STP103X_TLB_PART_0_DMMU;
        !          2964:   _tag_access = &TME_STP103X(ic)->tme_stp103x_dmmu.tme_stp103x_mmu_tag_access;
        !          2965:   if (!TME_STP103X_ASI_MMU_MASK_IS_DMMU(ls->tme_sparc_ls_asi_mask)) {
        !          2966:     tlb_part_i = (tlb_part_i - TME_STP103X_TLB_PART_0_DMMU) + TME_STP103X_TLB_PART_0_IMMU;
        !          2967:     _tag_access = &TME_STP103X(ic)->tme_stp103x_immu.tme_stp103x_mmu_tag_access;
        !          2968:   }
        !          2969: 
        !          2970:   /* if this is a load: */
        !          2971:   if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_LD) {
        !          2972: 
        !          2973:     /* complete the load: */
        !          2974:     *ls->tme_sparc_ls_rd64 = TME_STP103X(ic)->tme_stp103x_tlb_64s(tlb_part_i + 1);
        !          2975:     ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_LD_COMPLETED;
        !          2976:   }
        !          2977: 
        !          2978:   /* otherwise, this is a store: */
        !          2979:   else {
        !          2980: 
        !          2981:     /* if the TLB entry is valid: */
        !          2982:     if (TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 1)
        !          2983:        & TME_STP103X_TLB_DATA_V((tme_uint32_t) 0)) {
        !          2984: 
        !          2985:       /* invalidate this TLB entry: */
        !          2986:       _tme_stp103x_tlb_invalidate(ic,
        !          2987:                                  tlb_part_i);
        !          2988:     }
        !          2989: 
        !          2990:     /* complete the store: */
        !          2991:     TME_STP103X(ic)->tme_stp103x_tlb_64s(tlb_part_i + 0) = *_tag_access;
        !          2992:     TME_STP103X(ic)->tme_stp103x_tlb_64s(tlb_part_i + 1) = *ls->tme_sparc_ls_rd64;
        !          2993:   }
        !          2994: 
        !          2995:   /* we completed the load or store: */
        !          2996:   ls->tme_sparc_ls_size = 0;
        !          2997: }
        !          2998: 
        !          2999: /* the ASI handler for ASI_ITLB_TAG_READ_REG, ASI_DTLB_TAG_READ_REG: */
        !          3000: static void
        !          3001: _tme_stp103x_ls_asi_tlb_tag_read(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          3002: {
        !          3003:   unsigned long tlb_part_i;
        !          3004: 
        !          3005:   /* if this is not a 64-bit load: */
        !          3006:   if (__tme_predict_false(ls->tme_sparc_ls_size != sizeof(tme_uint64_t)
        !          3007:                          || (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_LD) == 0)) {
        !          3008: 
        !          3009:     /* this is an illegal access: */
        !          3010:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          3011:   }
        !          3012: 
        !          3013:   /* if this access has faulted: */
        !          3014:   if (__tme_predict_false(ls->tme_sparc_ls_faults != TME_SPARC_LS_FAULT_NONE)) {
        !          3015:     return;
        !          3016:   }
        !          3017: 
        !          3018:   /* get the addressed TLB entry and common MMU state: */
        !          3019:   tlb_part_i = ls->tme_sparc_ls_address64;
        !          3020:   tlb_part_i %= TME_STP103X_TLB_SIZE * sizeof(tme_uint64_t);
        !          3021:   tlb_part_i /= (sizeof(tme_uint64_t) / 2);
        !          3022:   tlb_part_i += TME_STP103X_TLB_PART_0_DMMU;
        !          3023:   if (!TME_STP103X_ASI_MMU_MASK_IS_DMMU(ls->tme_sparc_ls_asi_mask)) {
        !          3024:     tlb_part_i = (tlb_part_i - TME_STP103X_TLB_PART_0_DMMU) + TME_STP103X_TLB_PART_0_IMMU;
        !          3025:   }
        !          3026: 
        !          3027:   /* complete the load: */
        !          3028:   *ls->tme_sparc_ls_rd64 = TME_STP103X(ic)->tme_stp103x_tlb_64s(tlb_part_i + 0);
        !          3029:   ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_LD_COMPLETED;
        !          3030:   ls->tme_sparc_ls_size = 0;
        !          3031: }
        !          3032: 
        !          3033: /* the ASI handler for ASI_IMMU_DEMAP, ASI_DMMU_DEMAP: */
        !          3034: static void
        !          3035: _tme_stp103x_ls_asi_mmu_demap(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          3036: {
        !          3037:   tme_uint64_t address;
        !          3038:   tme_uint32_t tlb_tag_match_32_63;
        !          3039:   tme_uint32_t tlb_tag_match_0_31;
        !          3040:   tme_uint32_t context;
        !          3041:   tme_uint32_t tlb_tag_mask32;
        !          3042:   unsigned long tlb_part_i;
        !          3043:   tme_uint32_t tlb_tag_xor_32_63;
        !          3044:   tme_uint32_t tlb_data_0_31;
        !          3045:   tme_uint32_t tlb_tag_xor_0_31;
        !          3046:   tme_uint32_t tlb_data_32_63;
        !          3047:   tme_uint32_t size;
        !          3048: 
        !          3049:   /* if this is not a 64-bit store: */
        !          3050:   if (__tme_predict_false(ls->tme_sparc_ls_size != sizeof(tme_uint64_t)
        !          3051:                          || (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_ST) == 0)) {
        !          3052: 
        !          3053:     /* this is an illegal access: */
        !          3054:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          3055:   }
        !          3056: 
        !          3057:   /* check the address: */
        !          3058:   address = _tme_stp103x_ls_address_check(NULL, ls);
        !          3059:   tlb_tag_match_32_63 = address >> 32;
        !          3060:   tlb_tag_match_0_31 = address;
        !          3061: 
        !          3062:   /* if this access has faulted: */
        !          3063:   if (__tme_predict_false(ls->tme_sparc_ls_faults != TME_SPARC_LS_FAULT_NONE)) {
        !          3064:     return;
        !          3065:   }
        !          3066: 
        !          3067:   /* we will complete this store: */
        !          3068:   ls->tme_sparc_ls_size = 0;
        !          3069: 
        !          3070:   /* assume that this demap uses the primary context: */
        !          3071:   context = ic->tme_sparc_memory_context_primary;
        !          3072: 
        !          3073:   /* if this demap might use the secondary context: */
        !          3074:   if (tlb_tag_match_0_31 & TME_BIT(4)) {
        !          3075:     context = ic->tme_sparc_memory_context_secondary;
        !          3076:   }
        !          3077: 
        !          3078:   /* if this demap uses the nucleus context: */
        !          3079:   if (tlb_tag_match_0_31 & TME_BIT(5)) {
        !          3080:     context = 0;
        !          3081: 
        !          3082:     /* "Use of the reserved value causes the demap to be ignored" */
        !          3083:     if (tlb_tag_match_0_31 & TME_BIT(4)) {
        !          3084:       return;
        !          3085:     }
        !          3086:   }
        !          3087: 
        !          3088:   /* if this is a demap page, we must match the VA part of a tag.  if
        !          3089:      this is a demap context, we must ignore the VA part of a tag: */
        !          3090:   tlb_tag_mask32 = 0 - (tme_uint32_t) ((tlb_tag_match_0_31 & TME_BIT(6)) == 0);
        !          3091: 
        !          3092:   /* finish the tag to match: */
        !          3093:   tlb_tag_match_0_31 &= ~TME_STP103X_CONTEXT_MAX;
        !          3094:   tlb_tag_match_0_31 += context;
        !          3095: 
        !          3096:   /* if this is ASI_DMMU_DEMAP, start at the first entry of the DTLB,
        !          3097:      otherwise start at the first entry of the ITLB: */
        !          3098:   tlb_part_i
        !          3099:     = (TME_STP103X_ASI_MMU_MASK_IS_DMMU(ls->tme_sparc_ls_asi_mask)
        !          3100:        ? TME_STP103X_TLB_PART_0_DMMU
        !          3101:        : TME_STP103X_TLB_PART_0_IMMU);
        !          3102: 
        !          3103:   /* loop over the TLB entries: */
        !          3104:   do {
        !          3105: 
        !          3106:     /* if bits 32..63 of the tag match: */
        !          3107:     tlb_tag_xor_32_63 = TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 0), 1) ^ tlb_tag_match_32_63;
        !          3108:     if ((tlb_tag_xor_32_63 & tlb_tag_mask32) == 0) {
        !          3109: 
        !          3110:       /* load bits 0..31 of the data: */
        !          3111:       tlb_data_0_31 = TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 0);
        !          3112: 
        !          3113:       /* exclusive-OR bits 0..31 of the tag with bits 0..31 of the tag
        !          3114:         to match: */
        !          3115:       tlb_tag_xor_0_31 = TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 0), 0) ^ tlb_tag_match_0_31;
        !          3116: 
        !          3117:       /* if this is a global entry: */
        !          3118:       if (tlb_data_0_31 & TME_STP103X_TLB_DATA_G(tlb_data_0_31)) {
        !          3119: 
        !          3120:        /* assume that this is a demap page, which can match a global
        !          3121:           page, and force a match of the context field of the tag: */
        !          3122:        tlb_tag_xor_0_31 &= ~TME_STP103X_CONTEXT_MAX;
        !          3123: 
        !          3124:        /* if this a demap context: */
        !          3125:        if (tlb_tag_mask32 == 0) {
        !          3126: 
        !          3127:          /* a demap context never matches a global page.  force a
        !          3128:             mismatch of the context field of the tag: */
        !          3129:          tlb_tag_xor_0_31 += 1;
        !          3130:        }
        !          3131:       }
        !          3132: 
        !          3133:       /* load bits 32..63 of the data: */
        !          3134:       tlb_data_32_63 = TME_STP103X(ic)->tme_stp103x_tlb_32s((tlb_part_i + 1), 1);
        !          3135: 
        !          3136:       /* if this TLB entry is valid: */
        !          3137:       if (tlb_data_32_63 & TME_STP103X_TLB_DATA_V(tlb_data_32_63)) {
        !          3138: 
        !          3139:        /* get the size of this mapping: */
        !          3140:        size
        !          3141:          = (TME_STP103X_PAGE_SIZE_8KB
        !          3142:             << (3 * TME_FIELD_MASK_EXTRACTU(tlb_data_32_63,
        !          3143:                                             TME_STP103X_TLB_DATA_SIZE_MASK(tlb_data_32_63))));
        !          3144: 
        !          3145:        /* if bits 0..31 of the tag match: */
        !          3146:        if ((tlb_tag_xor_0_31
        !          3147:             & (((0 - size)
        !          3148:                 & tlb_tag_mask32)
        !          3149:                + TME_STP103X_CONTEXT_MAX)) == 0) {
        !          3150: 
        !          3151:          /* invalidate this TLB entry: */
        !          3152:          _tme_stp103x_tlb_invalidate(ic, tlb_part_i);
        !          3153:        }
        !          3154:       }
        !          3155:     }
        !          3156: 
        !          3157:     tlb_part_i += 2;
        !          3158:   } while (tlb_part_i % (2 * TME_STP103X_TLB_SIZE));
        !          3159: }
        !          3160: 
        !          3161: /* the ASI handler for ASI_ECACHE_W and ASI_ECACHE_R: */
        !          3162: static void
        !          3163: _tme_stp103x_ls_asi_ecache(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          3164: {
        !          3165:   tme_uint64_t address;
        !          3166:   tme_uint32_t address_0_31;
        !          3167:   tme_uint32_t address_32_63;
        !          3168:   unsigned int ecache_what;
        !          3169:   int is_write;
        !          3170: 
        !          3171:   /* get the address: */
        !          3172:   address = ls->tme_sparc_ls_address64;
        !          3173:   address_32_63 = (address >> 32);
        !          3174:   address_0_31 = address;
        !          3175:   
        !          3176:   /* see if this is an E-Cache data access, or a tag/state/parity
        !          3177:      access: */
        !          3178:   ecache_what = (address_32_63 >> (39 - 32)) & 0x3;
        !          3179: 
        !          3180:   /* truncate the E-Cache address to the cache size, and 64-bit align
        !          3181:      it: */
        !          3182:   address_0_31 &= (TME_STP103X_ECACHE_SIZE - sizeof(tme_uint64_t));
        !          3183: 
        !          3184:   /* see if this is ASI_ECACHE_W or ASI_ECACHE_R: */
        !          3185:   is_write = (TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask) == 0x76);
        !          3186:   assert (is_write || TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask) == 0x7e);
        !          3187: 
        !          3188:   /* check the access: */
        !          3189:   if (__tme_predict_false((ls->tme_sparc_ls_lsinfo
        !          3190:                           & (is_write
        !          3191:                              ? TME_SPARC_LSINFO_OP_ST
        !          3192:                              : TME_SPARC_LSINFO_OP_LD)) == 0
        !          3193:                          || ls->tme_sparc_ls_size != sizeof(tme_uint64_t)
        !          3194:                          || (ecache_what != 0x1
        !          3195:                              && ecache_what != 0x2))) {
        !          3196:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          3197:   }
        !          3198: 
        !          3199:   /* if the access has faulted: */
        !          3200:   if (__tme_predict_false(ls->tme_sparc_ls_faults != TME_SPARC_LS_FAULT_NONE)) {
        !          3201:     return;
        !          3202:   }
        !          3203: 
        !          3204:   /* if this is a data access: */
        !          3205:   if (ecache_what == 0x1) {
        !          3206: 
        !          3207:     /* the PROM probes the size of the E-Cache by writing power-of-two
        !          3208:        sizes to those same addresses in the E-Cache, from high sizes
        !          3209:        to low sizes.  then it reads address zero to see the last size
        !          3210:        that got truncated to address zero.  we don't emulate the
        !          3211:        E-Cache, but we do emulate a single line at address zero, so we
        !          3212:        appear to the probe as having the smallest E-Cache size
        !          3213:        (512KB): */
        !          3214: #if TME_STP103X_ECACHE_SIZE != (512 * 1024)
        !          3215: #error "TME_STP103X_ECACHE_SIZE changed"
        !          3216: #endif
        !          3217:     if (address_0_31 == 0) {
        !          3218:       if (is_write) {
        !          3219:        TME_STP103X(ic)->tme_stp103x_ecache_data_probe = *ls->tme_sparc_ls_rd64;
        !          3220:       }
        !          3221:       else {
        !          3222:        *ls->tme_sparc_ls_rd64 = TME_STP103X(ic)->tme_stp103x_ecache_data_probe;
        !          3223:       }
        !          3224:     }
        !          3225:     else {
        !          3226:       abort();
        !          3227:     }
        !          3228:   }
        !          3229: 
        !          3230:   /* otherwise, this must be a tag access: */
        !          3231:   else {
        !          3232:     assert (ecache_what == 0x2);
        !          3233: 
        !          3234:     /* the PROM initializes all tags in the E-Cache.  we don't emulate
        !          3235:        the E-Cache, but we do support initializing any tag: */
        !          3236:     if (is_write
        !          3237:        && ((TME_STP103X(ic)->tme_stp103x_ecache_tag_data % (2 << 28))
        !          3238:            == (0x00000 /* a EC_tag of zero */
        !          3239:                + (0x0 << 22) /* an EC_state of Invalid */
        !          3240:                + (0xf << 25)))) { /* correct odd EC_parity */
        !          3241:       /* nothing to do */
        !          3242:     }
        !          3243:     else {
        !          3244:       abort();
        !          3245:     }
        !          3246:   }
        !          3247: 
        !          3248:   /* complete the load or store: */
        !          3249:   if (!is_write) {
        !          3250:     ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_LD_COMPLETED;
        !          3251:   }
        !          3252:   ls->tme_sparc_ls_size = 0;
        !          3253: }
        !          3254: 
        !          3255: /* the ASI handler for ASI_DCACHE_DATA and ASI_DCACHE_TAG: */
        !          3256: static void
        !          3257: _tme_stp103x_ls_asi_dcache(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          3258: {
        !          3259:   tme_uint32_t address_0_31;
        !          3260:   tme_uint64_t value;
        !          3261: 
        !          3262:   /* get the address: */
        !          3263:   address_0_31 = ls->tme_sparc_ls_address64 % (16 * 1024);
        !          3264: 
        !          3265:   /* check the access: */
        !          3266:   if (__tme_predict_false((ls->tme_sparc_ls_lsinfo
        !          3267:                           & (TME_SPARC_LSINFO_OP_ST
        !          3268:                              | TME_SPARC_LSINFO_OP_LD)) == 0
        !          3269:                          || ls->tme_sparc_ls_size != sizeof(tme_uint64_t))) {
        !          3270:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          3271:   }
        !          3272: 
        !          3273:   /* if the access has faulted: */
        !          3274:   if (__tme_predict_false(ls->tme_sparc_ls_faults != TME_SPARC_LS_FAULT_NONE)) {
        !          3275:     return;
        !          3276:   }
        !          3277: 
        !          3278:   /* if this is a store: */
        !          3279:   if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_ST) {
        !          3280:     
        !          3281:     /* get the value being stored: */
        !          3282:     value = *ls->tme_sparc_ls_rd64;
        !          3283: 
        !          3284:     /* we support writing zeros to tags - the PROM does this to
        !          3285:        initialize all tags in the D-cache, and kernels do this to
        !          3286:        flush the D-cache: */
        !          3287:     if (__tme_predict_true(TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask) == TME_STP103X_ASI_DCACHE_TAG
        !          3288:                           && value == 0)) {
        !          3289: 
        !          3290:       /* complete this store: */
        !          3291:       ls->tme_sparc_ls_size = 0;
        !          3292:       return;
        !          3293:     }
        !          3294: 
        !          3295:     /* soon after POR, the PROM writes 0xdeadbeef to address zero in
        !          3296:        both ASI_DCACHE_DATA and ASI_DCACHE_TAG.  we support these
        !          3297:        writes: */
        !          3298:     if (address_0_31 == 0
        !          3299:        && value == 0xdeadbeef) {
        !          3300: 
        !          3301:       /* complete this store: */
        !          3302:       ls->tme_sparc_ls_size = 0;
        !          3303:       return;
        !          3304:     }
        !          3305:   }
        !          3306: 
        !          3307:   /* otherwise, this is a load: */
        !          3308:   else {
        !          3309: 
        !          3310:     /* we support reading tags, which always read as zeroes.  kernels
        !          3311:        may read tags when flushing the D-cache: */
        !          3312:     if (__tme_predict_true(TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask) == TME_STP103X_ASI_DCACHE_TAG)) {
        !          3313: 
        !          3314:       /* complete this load: */
        !          3315:       *ls->tme_sparc_ls_rd64 = 0;
        !          3316:       ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_LD_COMPLETED;
        !          3317:       ls->tme_sparc_ls_size = 0;
        !          3318:       return;
        !          3319:     }
        !          3320:   }
        !          3321: 
        !          3322:   /* XXX FIXME WRITEME: */
        !          3323:   abort();
        !          3324: }
        !          3325: 
        !          3326: /* the ASI handler for ASI_ICACHE_INSTR, ASI_ICACHE_TAG,
        !          3327:    ASI_ICACHE_PRE_DECODE, ASI_ICACHE_NEXT_FIELD: */
        !          3328: static void
        !          3329: _tme_stp103x_ls_asi_icache(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          3330: {
        !          3331:   tme_uint32_t address_0_31;
        !          3332:   tme_uint64_t value;
        !          3333: 
        !          3334:   /* get the address: */
        !          3335:   address_0_31 = ls->tme_sparc_ls_address64 % (16 * 1024);
        !          3336: 
        !          3337:   /* check the access: */
        !          3338:   if (__tme_predict_false((ls->tme_sparc_ls_lsinfo
        !          3339:                           & (TME_SPARC_LSINFO_OP_ST
        !          3340:                              | TME_SPARC_LSINFO_OP_LD)) == 0
        !          3341:                          || ls->tme_sparc_ls_size != sizeof(tme_uint64_t))) {
        !          3342:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          3343:   }
        !          3344: 
        !          3345:   /* if the access has faulted: */
        !          3346:   if (__tme_predict_false(ls->tme_sparc_ls_faults != TME_SPARC_LS_FAULT_NONE)) {
        !          3347:     return;
        !          3348:   }
        !          3349: 
        !          3350:   /* if this is a store: */
        !          3351:   if (ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_OP_ST) {
        !          3352:     
        !          3353:     /* get the value being stored: */
        !          3354:     value = *ls->tme_sparc_ls_rd64;
        !          3355: 
        !          3356:     /* soon after POR, the PROM writes 0xdeadbeef to address zero in
        !          3357:        both ASI_ICACHE_DATA and ASI_ICACHE_TAG.  later, the PROM
        !          3358:        initializes all tags in the I-cache.  we don't emulate the
        !          3359:        I-cache, but we do support these writes: */
        !          3360:     if ((address_0_31 == 0
        !          3361:         && value == 0xdeadbeef)
        !          3362:        || (TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask) == 0x67
        !          3363:            && value == 0)) {
        !          3364: 
        !          3365:       /* complete this store: */
        !          3366:       ls->tme_sparc_ls_size = 0;
        !          3367:       return;
        !          3368:     }
        !          3369:   }
        !          3370: 
        !          3371:   /* XXX FIXME WRITEME: */
        !          3372:   abort();
        !          3373: }
        !          3374: 
        !          3375: /* this swaps double-precision floating-point register values in the
        !          3376:    memory buffer for the block transfer ASIs: */
        !          3377: static void
        !          3378: _tme_stp103x_block_buffer_bswap(struct tme_sparc *ic,
        !          3379:                                const struct tme_sparc_ls *ls)
        !          3380: {
        !          3381:   const struct tme_sparc_tlb *tlb;
        !          3382:   tme_uint32_t endian_little;
        !          3383:   signed int value_i;
        !          3384: 
        !          3385:   /* get the TLB entry: */
        !          3386:   tlb = ls->tme_sparc_ls_tlb;
        !          3387: 
        !          3388:   /* get the byte order of the memory: */
        !          3389:   endian_little = ls->tme_sparc_ls_lsinfo & TME_SPARC_LSINFO_ENDIAN_LITTLE;
        !          3390: 
        !          3391:   /* if the host and memory byte orders don't match: */
        !          3392:   if (TME_ENDIAN_NATIVE == TME_ENDIAN_LITTLE
        !          3393:       ? !endian_little
        !          3394:       : TME_ENDIAN_NATIVE == TME_ENDIAN_BIG
        !          3395:       ? endian_little
        !          3396:       : TRUE) {
        !          3397: 
        !          3398:     /* if the host is big- or little-endian: */
        !          3399:     if (TME_ENDIAN_NATIVE == TME_ENDIAN_LITTLE
        !          3400:        || TME_ENDIAN_NATIVE == TME_ENDIAN_BIG) {
        !          3401: 
        !          3402:       /* swap the values in the memory buffer: */
        !          3403:       value_i = TME_STP103X_BLOCK_FPREGS_DOUBLE - 1;
        !          3404:       do {
        !          3405:        ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer64s[value_i]
        !          3406:          = tme_bswap_u64(ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer64s[value_i]);
        !          3407:       } while (--value_i >= 0);
        !          3408:     }
        !          3409: 
        !          3410:     /* otherwise, the host has an unusual byte order: */
        !          3411:     else {
        !          3412:       abort();
        !          3413:     }
        !          3414:   }
        !          3415: }
        !          3416: 
        !          3417: /* the cycle handler for loads with ASI_BLOCK_AS_IF_USER*,
        !          3418:    ASI_BLK_COMMIT*, and ASI_BLOCK*: */
        !          3419: static void
        !          3420: _tme_stp103x_ls_cycle_block_ld(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          3421: {
        !          3422:   unsigned int fpreg_number;
        !          3423: 
        !          3424:   /* do a load cycle: */
        !          3425:   tme_sparc64_load(ic, ls);
        !          3426: 
        !          3427:   /* if this was not the last cycle, return now: */
        !          3428:   if (ls->tme_sparc_ls_size != 0) {
        !          3429:     return;
        !          3430:   }
        !          3431: 
        !          3432:   /* swap the memory buffer: */
        !          3433:   _tme_stp103x_block_buffer_bswap(ic, ls);
        !          3434: 
        !          3435:   /* save the block load for verification: */
        !          3436:   tme_sparc_recode_verify_mem_block(ic, TME_SPARC_RECODE_VERIFY_MEM_LOAD);
        !          3437: 
        !          3438:   /* decode rd: */
        !          3439:   fpreg_number
        !          3440:     = tme_sparc_fpu_fpreg_decode(ic,
        !          3441:                                 TME_FIELD_MASK_EXTRACTU(ic->_tme_sparc_insn,
        !          3442:                                                         TME_SPARC_FORMAT3_MASK_RD),
        !          3443:                                 TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !          3444: 
        !          3445:   /* loop over a block's worth of double-precision floating-point
        !          3446:      registers: */
        !          3447:   do {
        !          3448: 
        !          3449:     /* make sure the floating-point register is double-precision: */
        !          3450:     tme_sparc_fpu_fpreg_format(ic,
        !          3451:                               fpreg_number,
        !          3452:                               (TME_IEEE754_FPREG_FORMAT_DOUBLE
        !          3453:                                | TME_IEEE754_FPREG_FORMAT_BUILTIN));
        !          3454: 
        !          3455:     /* copy the double-precision value from the memory buffer: */
        !          3456:     ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_format = TME_FLOAT_FORMAT_IEEE754_DOUBLE;
        !          3457:     ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_double.tme_value64_uint
        !          3458:       = (ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer64s
        !          3459:         [(fpreg_number / 2)
        !          3460:          % TME_STP103X_BLOCK_FPREGS_DOUBLE]);
        !          3461: 
        !          3462:     /* NB: tme_sparc64_lddfa() will eventually use
        !          3463:        TME_SPARC_FPU_DIRTY() to mark the right half of the FPU
        !          3464:        dirty: */
        !          3465: 
        !          3466:     /* log the value loaded, except for the first, which will be
        !          3467:        logged eventually by tme_sparc64_ldxa(): */
        !          3468:     if (((fpreg_number / 2) % TME_STP103X_BLOCK_FPREGS_DOUBLE) != 0) {
        !          3469:       tme_sparc_log(ic, 1000, TME_OK,
        !          3470:                    (TME_SPARC_LOG_HANDLE(ic),
        !          3471:                     _("ldxa 0x%02x:0x%016" TME_PRIx64 ":    0x%016" TME_PRIx64),
        !          3472:                     TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask),
        !          3473:                     ((ls->tme_sparc_ls_address64
        !          3474:                       - TME_STP103X_BLOCK_SIZE)
        !          3475:                      + (sizeof(tme_uint64_t)
        !          3476:                         * ((fpreg_number / 2)
        !          3477:                            % TME_STP103X_BLOCK_FPREGS_DOUBLE))),
        !          3478:                     ic->tme_sparc_fpu_fpregs[fpreg_number].tme_float_value_ieee754_double.tme_value64_uint));
        !          3479:     }
        !          3480: 
        !          3481:   } while ((fpreg_number += 2)
        !          3482:           % (TME_STP103X_BLOCK_FPREGS_DOUBLE * 2));
        !          3483: 
        !          3484:   /* complete this load for the lddfa function: */
        !          3485:   assert (ls->tme_sparc_ls_rd64
        !          3486:          == &ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_FPX));
        !          3487:   ic->tme_sparc_ireg_uint64(TME_SPARC_IREG_FPX)
        !          3488:     = ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer64s[0];
        !          3489: }
        !          3490: 
        !          3491: /* the cycle handler for stores with ASI_BLOCK_AS_IF_USER*,
        !          3492:    ASI_BLK_COMMIT*, and ASI_BLOCK*: */
        !          3493: static void
        !          3494: _tme_stp103x_ls_cycle_block_st(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          3495: {
        !          3496:   unsigned int fpreg_number;
        !          3497:   union tme_value64 value_double_buffer;
        !          3498: 
        !          3499:   /* this must be the first cycle: */
        !          3500:   assert (ls->tme_sparc_ls_buffer_offset == 0);
        !          3501: 
        !          3502:   /* decode rd: */
        !          3503:   fpreg_number
        !          3504:     = tme_sparc_fpu_fpreg_decode(ic,
        !          3505:                                 TME_FIELD_MASK_EXTRACTU(ic->_tme_sparc_insn,
        !          3506:                                                         TME_SPARC_FORMAT3_MASK_RD),
        !          3507:                                 TME_IEEE754_FPREG_FORMAT_DOUBLE);
        !          3508: 
        !          3509:   /* loop over a block's worth of double-precision floating-point
        !          3510:      registers: */
        !          3511:   do {
        !          3512: 
        !          3513:     /* make sure the floating-point register is double-precision: */
        !          3514:     tme_sparc_fpu_fpreg_format(ic,
        !          3515:                               fpreg_number,
        !          3516:                               (TME_IEEE754_FPREG_FORMAT_DOUBLE
        !          3517:                                | TME_IEEE754_FPREG_FORMAT_BUILTIN));
        !          3518: 
        !          3519:     /* copy the double-precision value into the memory buffer: */
        !          3520:     ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer64s
        !          3521:       [(fpreg_number / 2)
        !          3522:        % TME_STP103X_BLOCK_FPREGS_DOUBLE]
        !          3523:       = (tme_ieee754_double_value_get(&ic->tme_sparc_fpu_fpregs[fpreg_number],
        !          3524:                                      &value_double_buffer)
        !          3525:         ->tme_value64_uint);
        !          3526: 
        !          3527:     /* log the value stored, except for the first, which was already
        !          3528:        logged by tme_sparc64_stxa(): */
        !          3529:     if (((fpreg_number / 2) % TME_STP103X_BLOCK_FPREGS_DOUBLE) != 0) {
        !          3530:       tme_sparc_log(ic, 1000, TME_OK,
        !          3531:                    (TME_SPARC_LOG_HANDLE(ic),
        !          3532:                     _("stxa 0x%02x:0x%016" TME_PRIx64 ":    0x%016" TME_PRIx64),
        !          3533:                     TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask),
        !          3534:                     (ls->tme_sparc_ls_address64
        !          3535:                      + (sizeof(tme_uint64_t)
        !          3536:                         * ((fpreg_number / 2)
        !          3537:                            % TME_STP103X_BLOCK_FPREGS_DOUBLE))),
        !          3538:                     ic->tme_sparc_memory_buffer.tme_sparc_memory_buffer64s
        !          3539:                     [(fpreg_number / 2)
        !          3540:                      % TME_STP103X_BLOCK_FPREGS_DOUBLE]));
        !          3541:     }
        !          3542: 
        !          3543:   } while ((fpreg_number += 2)
        !          3544:           % (TME_STP103X_BLOCK_FPREGS_DOUBLE * 2));
        !          3545: 
        !          3546:   /* save the block store for verification: */
        !          3547:   tme_sparc_recode_verify_mem_block(ic, TME_SPARC_RECODE_VERIFY_MEM_STORE);
        !          3548: 
        !          3549:   /* swap the memory buffer: */
        !          3550:   _tme_stp103x_block_buffer_bswap(ic, ls);
        !          3551: 
        !          3552:   /* do any leftover store cycles directly: */
        !          3553:   ls->tme_sparc_ls_cycle = tme_sparc64_store;
        !          3554: 
        !          3555:   /* do a store cycle: */
        !          3556:   tme_sparc64_store(ic, ls);
        !          3557: }
        !          3558: 
        !          3559: /* the ASI handler for ASI_BLOCK_AS_IF_USER*, ASI_BLK_COMMIT*, and
        !          3560:    ASI_BLOCK*: */
        !          3561: static void
        !          3562: _tme_stp103x_ls_asi_block(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          3563: {  
        !          3564:   tme_uint32_t insn;
        !          3565: 
        !          3566:   /* NB: tme_sparc64_lddfa() or tme_sparc64_stdfa() has already done
        !          3567:      an TME_SPARC_INSN_FPU: */
        !          3568: 
        !          3569:   /* we need to do the complete transfer: */
        !          3570:   /* NB: even if this is an stdfa, the TME_SPARC_LSINFO_LD_COMPLETED
        !          3571:      won't cause any problems: */
        !          3572:   assert (sizeof(ic->tme_sparc_memory_buffer) >= TME_STP103X_BLOCK_SIZE);
        !          3573:   ls->tme_sparc_ls_size = TME_STP103X_BLOCK_SIZE;
        !          3574:   ls->tme_sparc_ls_buffer_offset = 0;
        !          3575:   ls->tme_sparc_ls_lsinfo
        !          3576:     |= (TME_SPARC_LSINFO_SLOW_CYCLES
        !          3577:        | TME_SPARC_LSINFO_LD_COMPLETED);
        !          3578: 
        !          3579:   /* an instruction other than lddfa or stdfa, or an lddfa with an
        !          3580:      ASI_BLK_COMMIT*, or with an rd that isn't a multiple of 16 is
        !          3581:      illegal: */
        !          3582:   insn = ic->_tme_sparc_insn;
        !          3583:   /* NB: we flip the stdfa op3 bits, and check that the whole op3
        !          3584:      field becomes zero (for ASI_BLK_COMMIT*) or that all op3 bits
        !          3585:      except the one that differentiates stdfa from lddfa become zero
        !          3586:      (for all other ASIs): */
        !          3587:   /* NB: we only need to test bits 1, 2, and 3 in the double-precision
        !          3588:      encoded rd, since bit 0 is the encoded bit 5: */
        !          3589:   insn ^= (0x37 << 19);
        !          3590:   if (__tme_predict_false((insn
        !          3591:                           & ((((TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask)
        !          3592:                                 ^ TME_STP103X_ASI_BLK_COMMIT)
        !          3593:                                & ~TME_SPARC64_ASI_FLAG_SECONDARY)
        !          3594:                               ? (0x3b << 19)
        !          3595:                               : (0x3f << 19))
        !          3596:                              | TME_BIT(3 + 25)
        !          3597:                              | TME_BIT(2 + 25)
        !          3598:                              | TME_BIT(1 + 25))))) {
        !          3599:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          3600:   }
        !          3601: 
        !          3602:   /* the address must be block-aligned: */
        !          3603:   else if (__tme_predict_false(((tme_uint32_t) ls->tme_sparc_ls_address64)
        !          3604:                               % TME_STP103X_BLOCK_SIZE)) {
        !          3605:     ls->tme_sparc_ls_faults |= TME_SPARC_LS_FAULT_ADDRESS_NOT_ALIGNED;
        !          3606:   }
        !          3607: 
        !          3608:   /* set the cycle function: */
        !          3609:   /* NB: we flipped the stdfa op3 bits in insn above, so bit two of
        !          3610:      op3 is now set for an lddfa, and clear for an stdfa: */
        !          3611:   ls->tme_sparc_ls_cycle
        !          3612:     = ((insn & (4 << 19))
        !          3613:        ? _tme_stp103x_ls_cycle_block_ld
        !          3614:        : _tme_stp103x_ls_cycle_block_st);
        !          3615: }
        !          3616: 
        !          3617: /* the ASI handler for the UDB registers: */
        !          3618: static void
        !          3619: _tme_stp103x_ls_asi_udb(struct tme_sparc *ic, struct tme_sparc_ls *ls)
        !          3620: {
        !          3621:   tme_uint32_t address_0_31;
        !          3622:   int is_write;
        !          3623:   tme_uint16_t value16;
        !          3624:   unsigned int intr_reg;
        !          3625: 
        !          3626:   /* get the address: */
        !          3627:   address_0_31 = ls->tme_sparc_ls_address64;
        !          3628: 
        !          3629:   /* see if this is should be a write or a read: */
        !          3630:   is_write = (TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask) == 0x77);
        !          3631:   assert (is_write || TME_SPARC_ASI_MASK_WHICH(ls->tme_sparc_ls_asi_mask) == 0x7f);
        !          3632: 
        !          3633:   /* check the access type and size, and that the address fits in 32
        !          3634:      bits: */
        !          3635:   if (__tme_predict_false((ls->tme_sparc_ls_lsinfo
        !          3636:                           & (is_write
        !          3637:                              ? TME_SPARC_LSINFO_OP_ST
        !          3638:                              : TME_SPARC_LSINFO_OP_LD)) == 0
        !          3639:                          || ls->tme_sparc_ls_size != sizeof(tme_uint64_t)
        !          3640:                          || ls->tme_sparc_ls_address64 > (tme_uint32_t) (0 - (tme_uint32_t) 1))) {
        !          3641:     ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          3642:   }
        !          3643: 
        !          3644:   /* if the access hasn't faulted yet: */
        !          3645:   if (__tme_predict_true(ls->tme_sparc_ls_faults == TME_SPARC_LS_FAULT_NONE)) {
        !          3646: 
        !          3647:     /* dispatch on the address: */
        !          3648:     switch (address_0_31) {
        !          3649: 
        !          3650:       /* the low and high UDB error registers: */
        !          3651:     case 0x00:
        !          3652:     case 0x18:
        !          3653:       /* we never generate ECC errors, so these registers
        !          3654:         always read as zero, and writes are ignored: */
        !          3655:       if (!is_write) {
        !          3656:        *ls->tme_sparc_ls_rd64 = 0;
        !          3657:       }
        !          3658:       break;
        !          3659: 
        !          3660:       /* the low and high UDB control registers: */
        !          3661:     case 0x20:
        !          3662:     case 0x38:
        !          3663:       if (is_write) {
        !          3664:        value16 = *ls->tme_sparc_ls_rd64;
        !          3665:        if (value16 & TME_BIT(8)) { /* F_MODE */
        !          3666:          abort();
        !          3667:        }
        !          3668:        TME_STP103X(ic)->tme_stp103x_udb_control[(address_0_31 & 8) == 0] = value16;
        !          3669:       }
        !          3670:       else {
        !          3671:        *ls->tme_sparc_ls_rd64
        !          3672:          = ((0x00 << 9) /* UDB version number */
        !          3673:             + (TME_STP103X(ic)->tme_stp103x_udb_control[(address_0_31 & 8) == 0]
        !          3674:                % (2 << 8))); /* F_MODE, FCBV */
        !          3675:       }
        !          3676:       break;
        !          3677: 
        !          3678:       /* the UDB transmit and receive interrupt vector data: */
        !          3679:     case 0x40:
        !          3680:     case 0x50:
        !          3681:     case 0x60:
        !          3682:       intr_reg = (address_0_31 - 0x40) / sizeof(tme_uint64_t);
        !          3683:       if (is_write) {
        !          3684:        TME_STP103X(ic)->tme_stp103x_udb_intr_transmit[intr_reg]
        !          3685:          = *ls->tme_sparc_ls_rd64;
        !          3686:       }
        !          3687:       else {
        !          3688:        *ls->tme_sparc_ls_rd64
        !          3689:          = TME_STP103X(ic)->tme_stp103x_udb_intr_receive[intr_reg];
        !          3690:       }
        !          3691:     break;
        !          3692: 
        !          3693:     default:
        !          3694: 
        !          3695:       /* if this isn't a write of the UDB interrupt vector dispatch: */
        !          3696:       if (!is_write
        !          3697:          || (address_0_31 & ~((2 << 18) - (1 << 14))) != 0x70) {
        !          3698: 
        !          3699:        /* this is an illegal access: */
        !          3700:        ls->tme_sparc_ls_faults |= TME_STP103X_LS_FAULT_ILLEGAL;
        !          3701:        break;
        !          3702:       }
        !          3703: 
        !          3704:       abort();
        !          3705:       break;
        !          3706:     }
        !          3707:   }
        !          3708: 
        !          3709:   /* if the access has faulted: */
        !          3710:   if (__tme_predict_false(ls->tme_sparc_ls_faults != TME_SPARC_LS_FAULT_NONE)) {
        !          3711:     return;
        !          3712:   }
        !          3713: 
        !          3714:   /* complete the load or store: */
        !          3715:   if (!is_write) {
        !          3716:     ls->tme_sparc_ls_lsinfo |= TME_SPARC_LSINFO_LD_COMPLETED;
        !          3717:   }
        !          3718:   ls->tme_sparc_ls_size = 0;
        !          3719: }
        !          3720: 
        !          3721: /* the ASI handlers: */
        !          3722: static const _tme_sparc_ls_asi_handler _tme_stp103x_ls_asi_handlers[] = {
        !          3723:   NULL,
        !          3724:   _tme_stp103x_ls_asi_mmu,
        !          3725:   _tme_stp103x_ls_asi_tsb_ptr,
        !          3726:   _tme_stp103x_ls_asi_quad,
        !          3727:   _tme_stp103x_ls_asi_tlb_data_in,
        !          3728:   _tme_stp103x_ls_asi_mmu_demap,
        !          3729:   _tme_stp103x_ls_asi_slow,
        !          3730:   _tme_stp103x_ls_asi_phys,
        !          3731:   _tme_stp103x_ls_asi_dcache,
        !          3732:   _tme_stp103x_ls_asi_ecache,
        !          3733:   _tme_stp103x_ls_asi_tlb_data_access,
        !          3734:   _tme_stp103x_ls_asi_tlb_tag_read,
        !          3735:   _tme_stp103x_ls_asi_icache,
        !          3736:   _tme_stp103x_ls_asi_block,
        !          3737:   _tme_stp103x_ls_asi_udb,
        !          3738:   tme_sparc64_vis_ls_asi_pst,
        !          3739:   tme_sparc64_vis_ls_asi_fl,
        !          3740: };
        !          3741: 
        !          3742: /* the tick compare register thread: */
        !          3743: static void
        !          3744: _tme_stp103x_tick_compare_th(void *_ic)
        !          3745: {
        !          3746:   struct tme_sparc *ic;
        !          3747:   struct timeval now;
        !          3748:   unsigned long now_tv_sec;
        !          3749:   unsigned long now_tv_usec;
        !          3750:   unsigned long tick_compare_time_tv_sec;
        !          3751:   unsigned long tick_compare_time_tv_usec;
        !          3752:   struct timeval sleep;
        !          3753: 
        !          3754:   /* recover our data structure: */
        !          3755:   ic = (struct tme_sparc *) _ic;
        !          3756: 
        !          3757:   /* lock the external mutex: */
        !          3758:   tme_mutex_lock(&ic->tme_sparc_external_mutex);
        !          3759: 
        !          3760:   /* loop forever: */
        !          3761:   for (;;) {
        !          3762: 
        !          3763:     /* get the current time: */
        !          3764:     tme_gettimeofday(&now);
        !          3765: 
        !          3766:     /* if the current time is greater than or equal to the tick compare time: */
        !          3767:     now_tv_sec = now.tv_sec;
        !          3768:     now_tv_usec = now.tv_usec;
        !          3769:     tick_compare_time_tv_sec = TME_STP103X(ic)->tme_stp103x_tick_compare_time.tv_sec;
        !          3770:     tick_compare_time_tv_usec = TME_STP103X(ic)->tme_stp103x_tick_compare_time.tv_usec;
        !          3771:     if (now_tv_sec > tick_compare_time_tv_sec
        !          3772:        || (now_tv_sec == tick_compare_time_tv_sec
        !          3773:            && now_tv_usec >= tick_compare_time_tv_usec)) {
        !          3774: 
        !          3775:       /* set the tick interrupt atomic flag: */
        !          3776:       tme_memory_atomic_write_flag(&TME_STP103X(ic)->tme_stp103x_sir_tick_int, TRUE);
        !          3777: 
        !          3778:       /* set the external flag: */
        !          3779:       tme_memory_atomic_write_flag(&ic->tme_sparc_external_flag, TRUE);
        !          3780: 
        !          3781:       /* notify any thread waiting on the external condition: */
        !          3782:       tme_cond_notify(&ic->tme_sparc_external_cond, FALSE);
        !          3783: 
        !          3784:       /* wait on the tick compare condition: */
        !          3785:       tme_cond_wait_yield(&TME_STP103X(ic)->tme_stp103x_tick_compare_cond,
        !          3786:                          &ic->tme_sparc_external_mutex);
        !          3787:     }
        !          3788: 
        !          3789:     /* otherwise, the current time is less than the tick compare
        !          3790:        time: */
        !          3791:     else {
        !          3792:       
        !          3793:       /* make the sleep time, but don't sleep more than a minute at a time: */
        !          3794:       if (tick_compare_time_tv_usec < now_tv_usec) {
        !          3795:        tick_compare_time_tv_sec--;
        !          3796:        tick_compare_time_tv_usec += 1000000;
        !          3797:       }
        !          3798:       sleep.tv_sec = TME_MIN(tick_compare_time_tv_sec - now_tv_sec, 60);
        !          3799:       sleep.tv_usec = tick_compare_time_tv_usec - now_tv_usec;
        !          3800: 
        !          3801:       /* sleep on the tick compare condition: */
        !          3802:       tme_cond_sleep_yield(&TME_STP103X(ic)->tme_stp103x_tick_compare_cond,
        !          3803:                           &ic->tme_sparc_external_mutex,
        !          3804:                           &sleep);
        !          3805:     }
        !          3806:   }
        !          3807:   /* NOTREACHED */
        !          3808: }
        !          3809: 
        !          3810: /* this checks for external signals: */
        !          3811: /* NB: this may do a preinstruction trap: */
        !          3812: static void
        !          3813: _tme_stp103x_external_check(struct tme_sparc *ic,
        !          3814:                            int flags)
        !          3815: {
        !          3816: 
        !          3817:   /* if RESET_L has been negated since the last check: */
        !          3818:   if (__tme_predict_false(tme_memory_atomic_read_flag(&ic->tme_sparc_external_reset_negated))) {
        !          3819: 
        !          3820:     /* clear the XIR and RESET_L asserted flags, then clear the
        !          3821:        RESET_L negated flag: */
        !          3822:     tme_memory_atomic_write_flag(&ic->tme_sparc_external_halt_asserted, FALSE);
        !          3823:     tme_memory_atomic_write_flag(&ic->tme_sparc_external_reset_asserted, FALSE);
        !          3824:     tme_memory_barrier(ic, sizeof(*ic), TME_MEMORY_BARRIER_WRITE_BEFORE_WRITE);
        !          3825:     tme_memory_atomic_write_flag(&ic->tme_sparc_external_reset_negated, FALSE);
        !          3826: 
        !          3827:     /* start POR trap processing: */
        !          3828:     if (flags & TME_SPARC_EXTERNAL_CHECK_MUTEX_LOCKED) {
        !          3829:       tme_mutex_unlock(&ic->tme_sparc_external_mutex);
        !          3830:     }
        !          3831:     tme_sparc64_trap_preinstruction(ic, TME_SPARC64_TRAP_power_on_reset);
        !          3832:   }
        !          3833: 
        !          3834:   /* if RESET_L is asserted: */
        !          3835:   if (__tme_predict_false(tme_memory_atomic_read_flag(&ic->tme_sparc_external_reset_asserted))) {
        !          3836: 
        !          3837:     /* halt: */
        !          3838:     if (flags & TME_SPARC_EXTERNAL_CHECK_MUTEX_LOCKED) {
        !          3839:       tme_mutex_unlock(&ic->tme_sparc_external_mutex);
        !          3840:     }
        !          3841:     ic->_tme_sparc_mode = TME_SPARC_MODE_HALT;
        !          3842:     tme_sparc_redispatch(ic);
        !          3843:   }
        !          3844: 
        !          3845:   /* if XIR has been asserted since the last check: */
        !          3846:   if (__tme_predict_false(tme_memory_atomic_read_flag(&ic->tme_sparc_external_halt_asserted))) {
        !          3847: 
        !          3848:     /* clear the XIR asserted flag: */
        !          3849:     tme_memory_atomic_write_flag(&ic->tme_sparc_external_halt_asserted, FALSE);
        !          3850: 
        !          3851:     /* start XIR trap processing: */
        !          3852:     if (flags & TME_SPARC_EXTERNAL_CHECK_MUTEX_LOCKED) {
        !          3853:       tme_mutex_unlock(&ic->tme_sparc_external_mutex);
        !          3854:     }
        !          3855:     tme_sparc64_trap_preinstruction(ic, TME_SPARC64_TRAP_externally_initiated_reset);
        !          3856:   }
        !          3857: 
        !          3858:   /* do an interrupt check: */
        !          3859:   _tme_stp103x_interrupt_check(ic, flags);
        !          3860: }
        !          3861: 
        !          3862: /* the bus cycle function: */
        !          3863: static void
        !          3864: _tme_stp103x_ls_bus_cycle(const struct tme_sparc *ic,
        !          3865:                          struct tme_sparc_ls *ls)
        !          3866: {
        !          3867:   tme_uint32_t asi_mask;
        !          3868:   unsigned int cycle_size_log2;
        !          3869: 
        !          3870:   /* NB: we provide the old sparc32 bus routing information when
        !          3871:      emulating stp103x noncached read and write transactions on the
        !          3872:      UPA bus.
        !          3873: 
        !          3874:      this is a bad hack that we do only to save duplicating that same
        !          3875:      information in the stp2220 emulation, which needs it for cycles
        !          3876:      that pass through it onto its SBus.
        !          3877: 
        !          3878:      since the old sparc32 bus routing information doesn't have
        !          3879:      anything to do with how the UPA bus works, we assume that all TLB
        !          3880:      fills for noncacheable accesses that don't allow fast transfers
        !          3881:      will either end up at another CPU (which will know about the
        !          3882:      disagreement and ignore the bus routing information), or end up
        !          3883:      at an I/O bridge, which will either rely on the sparc32 bus
        !          3884:      routing information (stp2220), or replace it with its own bus
        !          3885:      routing information (stp2222), before running the cycle on its
        !          3886:      I/O bus.  if the cycle is for an I/O bridge's internal registers,
        !          3887:      like a CPU it will know about the disagreement and ignore the bus
        !          3888:      routing information.
        !          3889: 
        !          3890:      we assume that all TLB fills for cacheable accesses target main
        !          3891:      memory, which we assume will tolerate any bus routing: */
        !          3892: 
        !          3893:   /* get the ASI mask for this TLB entry: */
        !          3894:   asi_mask = ls->tme_sparc_ls_tlb->tme_sparc_tlb_asi_mask;
        !          3895: 
        !          3896:   /* if the TLB entry is for noncacheable accesses: */
        !          3897:   if (asi_mask & TME_SPARC64_ASI_MASK_FLAG_TLB_UNCACHEABLE) {
        !          3898: 
        !          3899:     /* call the default sparc32 bus cycle function: */
        !          3900:     tme_sparc32_ls_bus_cycle(ic, ls);
        !          3901:     return;
        !          3902:   }
        !          3903: 
        !          3904:   /* provide a simple bus routing for cacheable accesses: */
        !          3905:   cycle_size_log2 = TME_BUS8_LOG2;
        !          3906:   for (; (1 << cycle_size_log2) != ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_size; ) {
        !          3907:     assert (cycle_size_log2 < TME_BUS128_LOG2);
        !          3908:     cycle_size_log2++;
        !          3909:   }
        !          3910:   ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_port = TME_BUS_CYCLE_PORT(0, TME_BUS128_LOG2);
        !          3911:   ls->tme_sparc_ls_bus_cycle.tme_bus_cycle_lane_routing
        !          3912:     = (&(_tme_stp103x_bus_router_cacheable
        !          3913:         [cycle_size_log2]
        !          3914:         [0])
        !          3915:        - TME_BUS_ROUTER_INDEX(TME_BUS128_LOG2, TME_BUS128_LOG2, 0));
        !          3916: }
        !          3917: 
        !          3918: /* this fills a TLB for the CPU: */
        !          3919: static int
        !          3920: _tme_stp103x_tlb_fill(struct tme_bus_connection *conn_bus,
        !          3921:                      struct tme_bus_tlb *tlb,
        !          3922:                      tme_bus_addr_t address,
        !          3923:                      unsigned int cycle_type)
        !          3924: {
        !          3925:   abort();
        !          3926: }
        !          3927: 
        !          3928: /* this handles an interrupt: */
        !          3929: static void
        !          3930: _tme_stp103x_interrupt(struct tme_upa_bus_connection *conn_upa,
        !          3931:                       tme_uint32_t master_mid,
        !          3932:                       const tme_uint64_t *data,
        !          3933:                       struct tme_completion *completion)
        !          3934: {
        !          3935:   struct tme_sparc *ic;
        !          3936: 
        !          3937:   /* recover our data structure: */
        !          3938:   ic = conn_upa->tme_upa_bus_connection.tme_bus_connection.tme_connection_element->tme_element_private;
        !          3939: 
        !          3940:   /* if the receive interrupt vector data is already busy: */
        !          3941:   if (tme_memory_atomic_read_flag(&TME_STP103X(ic)->tme_stp103x_intr_receive_busy)) {
        !          3942: 
        !          3943:     /* NACK this interrupt: */
        !          3944:     completion->tme_completion_error = EAGAIN;
        !          3945:     tme_memory_barrier(completion, sizeof(*completion), TME_MEMORY_BARRIER_WRITE_BEFORE_WRITE);
        !          3946:   }
        !          3947: 
        !          3948:   /* otherwise, the incoming data isn't busy: */
        !          3949:   else {
        !          3950: 
        !          3951:     /* save the interrupt data and ACK this interrupt: */
        !          3952:     /* NB: the interrupt data is an array of eight big-endian
        !          3953:        tme_uint64_t, since an interrupt packet is four 128-bit values.
        !          3954:        the even indices are the least-significant halves of the
        !          3955:        128-bit values: */
        !          3956:     TME_STP103X(ic)->tme_stp103x_intr_receive_mid = master_mid;
        !          3957:     TME_STP103X(ic)->tme_stp103x_udb_intr_receive[0] = tme_betoh_u64(data[2 * 0]);
        !          3958:     TME_STP103X(ic)->tme_stp103x_udb_intr_receive[1] = tme_betoh_u64(data[2 * 1]);
        !          3959:     TME_STP103X(ic)->tme_stp103x_udb_intr_receive[2] = tme_betoh_u64(data[2 * 2]);
        !          3960:     completion->tme_completion_error = TME_OK;
        !          3961:     tme_memory_barrier(0, 0, TME_MEMORY_BARRIER_WRITE_BEFORE_WRITE);
        !          3962:     tme_memory_atomic_write_flag(&TME_STP103X(ic)->tme_stp103x_intr_receive_busy, 1);
        !          3963:     tme_memory_barrier(ic, sizeof(*ic), TME_MEMORY_BARRIER_WRITE_BEFORE_WRITE);
        !          3964:     tme_memory_atomic_write_flag(&ic->tme_sparc_external_flag, 1);
        !          3965:     tme_cond_notify(&ic->tme_sparc_external_cond, FALSE);
        !          3966:   }
        !          3967: 
        !          3968:   /* validate this completion: */
        !          3969:   tme_completion_validate(completion);
        !          3970: }
        !          3971: 
        !          3972: /* this returns the version of an FPU for an stp103x: */
        !          3973: static tme_uint32_t
        !          3974: _tme_sparc_fpu_ver_stp103x(struct tme_sparc *ic, const char *fpu_name, char **_output)
        !          3975: {
        !          3976:   tme_uint32_t ver;
        !          3977: 
        !          3978:   /* if we're returning a usage: */
        !          3979:   if (_output != NULL) {
        !          3980:     tme_output_append_error(_output, 
        !          3981:                            "builtin");
        !          3982:     return (TME_SPARC_FSR_VER_missing);
        !          3983:   }
        !          3984: 
        !          3985:   if (TME_ARG_IS(fpu_name, "builtin")) {
        !          3986:     /* XXX FIXME - the stp1030 has an FSR_version of zero.  we assume
        !          3987:        that the stp1031 does too: */
        !          3988:     ver = 0;
        !          3989:   }
        !          3990:   else {
        !          3991:     return (TME_SPARC_FSR_VER_missing);
        !          3992:   }
        !          3993: 
        !          3994:   ic->tme_sparc_fpu_flags
        !          3995:     = (!TME_SPARC_FPU_FLAG_OK_REG_MISALIGNED);
        !          3996:   return (ver * _TME_FIELD_MASK_FACTOR(TME_SPARC_FSR_VER));
        !          3997: }
        !          3998: 
        !          3999: /* this creates and returns a new stp103x: */
        !          4000: static int
        !          4001: _tme_stp103x_new(struct tme_element *element,
        !          4002:                 const char * const *args,
        !          4003:                 const void *extra,
        !          4004:                 char **_output,
        !          4005:                 int is_1030)
        !          4006: {
        !          4007:   struct tme_sparc *ic;
        !          4008:   tme_uint32_t psr;
        !          4009:   tme_uint32_t asi;
        !          4010:   tme_uint32_t asi_mask_flags;
        !          4011:   void (*handler) _TME_P((struct tme_sparc *, struct tme_sparc_ls *));
        !          4012:   tme_uint32_t handler_i;
        !          4013: 
        !          4014:   /* allocate the stp103x structure: */
        !          4015:   ic = &tme_new0(struct tme_stp103x, 1)->tme_stp103x_sparc;
        !          4016:   ic->tme_sparc_element = element;
        !          4017: 
        !          4018:   /* set the type: */
        !          4019:   is_1030 = !!is_1030;
        !          4020:   TME_STP103X(ic)->tme_stp103x_is_1030 = is_1030;
        !          4021:   if (TME_STP103X_IS_1030(ic) != is_1030) {
        !          4022:     tme_free(ic);
        !          4023:     return (ENXIO);
        !          4024:   }
        !          4025: 
        !          4026:   /* initialize the synchronization parts of the structure: */
        !          4027:   tme_sparc_sync_init(ic);
        !          4028: 
        !          4029:   /* initialize the stp103x private structure: */
        !          4030:   TME_STP103X(ic)->tme_stp103x_tcr = TME_STP103X_TCR_INT_DIS;
        !          4031:   tme_cond_init(&TME_STP103X(ic)->tme_stp103x_tick_compare_cond);
        !          4032:   tme_misc_timeval_never(&TME_STP103X(ic)->tme_stp103x_tick_compare_time);
        !          4033:   tme_memory_atomic_init_flag(&TME_STP103X(ic)->tme_stp103x_sir_tick_int, FALSE);
        !          4034:   tme_memory_atomic_init_flag(&TME_STP103X(ic)->tme_stp103x_intr_receive_busy, FALSE);
        !          4035: 
        !          4036:   /* start the tick compare thread: */
        !          4037:   tme_thread_create((tme_thread_t) _tme_stp103x_tick_compare_th, ic);
        !          4038: 
        !          4039:   /* fill in the stp103x-specific parts of the structure: */
        !          4040:   psr = 0;
        !          4041:   TME_FIELD_MASK_DEPOSITU(psr, TME_SPARC32_PSR_IMPL, 1);
        !          4042:   TME_FIELD_MASK_DEPOSITU(psr, TME_SPARC32_PSR_VER, 1);
        !          4043:   ic->tme_sparc32_ireg_psr = psr;
        !          4044:   ic->tme_sparc_version = TME_SPARC_VERSION(ic);
        !          4045:   ic->tme_sparc_nwindows = TME_SPARC_NWINDOWS(ic);
        !          4046:   ic->tme_sparc_memory_flags = TME_SPARC_MEMORY_FLAGS(ic);
        !          4047:   ic->tme_sparc64_maxtl = TME_STP103X_MAXTL;
        !          4048:   ic->tme_sparc_tlb_page_size_log2 = 13; /* log2(TME_STP103X_PAGE_SIZE_8KB) */
        !          4049:   ic->tme_sparc_memory_context_max = TME_STP103X_CONTEXT_MAX;
        !          4050:   ic->_tme_sparc64_execute_opmap = _TME_SPARC_EXECUTE_OPMAP;
        !          4051:   ic->tme_sparc64_rstvaddr = 0 - (tme_uint64_t) (1 << 28);
        !          4052:   ic->tme_sparc64_ireg_va_hole_start = TME_STP103X_VA_HOLE_START;
        !          4053:   ic->tme_sparc64_ireg_ver
        !          4054:     = ((0x0017 * _TME_FIELD_MASK_FACTOR(TME_SPARC64_VER_MANUF))
        !          4055:        + (0x0010 * _TME_FIELD_MASK_FACTOR(TME_SPARC64_VER_IMPL))
        !          4056:        + (0x40 * _TME_FIELD_MASK_FACTOR(TME_SPARC64_VER_MASK))
        !          4057:        + (ic->tme_sparc64_maxtl * _TME_FIELD_MASK_FACTOR(TME_SPARC64_VER_MAXTL))
        !          4058:        + ((TME_SPARC_NWINDOWS(ic) - 1) * _TME_FIELD_MASK_FACTOR(TME_SPARC64_VER_MAXWIN)));
        !          4059:   ic->tme_sparc64_ireg_winstates_mask
        !          4060:     = (TME_SPARC64_WINSTATES_CWP(TME_SPARC_NWINDOWS(ic) - 1)
        !          4061:        + TME_SPARC64_WINSTATES_CANRESTORE(TME_SPARC_NWINDOWS(ic) - 1)
        !          4062:        + TME_SPARC64_WINSTATES_CANSAVE(TME_SPARC_NWINDOWS(ic) - 1)
        !          4063:        + TME_SPARC64_WINSTATES_OTHERWIN(TME_SPARC_NWINDOWS(ic) - 1));
        !          4064:   ic->_tme_sparc_execute = _tme_sparc_execute_stp103x;
        !          4065:   ic->_tme_sparc_fpu_ver = _tme_sparc_fpu_ver_stp103x;
        !          4066:   ic->_tme_sparc_external_check = _tme_stp103x_external_check;
        !          4067:   ic->_tme_sparc_tlb_fill = _tme_stp103x_tlb_fill;
        !          4068:   ic->_tme_sparc_upa_interrupt = _tme_stp103x_interrupt;
        !          4069:   ic->_tme_sparc_ls_asi_misaligned = tme_sparc64_vis_ls_asi_misaligned;
        !          4070:   ic->_tme_sparc_ls_asi_handlers = _tme_stp103x_ls_asi_handlers;
        !          4071:   ic->_tme_sparc_ls_address_map = _tme_stp103x_ls_address_map;
        !          4072:   ic->_tme_sparc_ls_bus_cycle = _tme_stp103x_ls_bus_cycle;
        !          4073:   ic->_tme_sparc_ls_bus_fault = tme_sparc_ls_bus_fault;
        !          4074:   ic->_tme_sparc_ls_trap = _tme_stp103x_ls_trap;
        !          4075:   ic->_tme_sparc64_update_pstate = _tme_stp103x_update_pstate;
        !          4076:   ic->tme_sparc_vis_ls_fault_illegal = TME_STP103X_LS_FAULT_ILLEGAL;
        !          4077:   ic->tme_sparc_timing_loop_cycles_each = 1;
        !          4078: #ifdef _TME_SPARC_RECODE_VERIFY
        !          4079:   /* NB: struct tme_stp103x has been deliberately laid out to have all
        !          4080:      of the verifiable contents first, followed by everything that
        !          4081:      isn't verifiable (basically, anything that is accessed using
        !          4082:      loads and stores, since replay only simulates them): */
        !          4083:   ic->tme_sparc_recode_verify_ic_size
        !          4084:     = (((char *) &((struct tme_stp103x *) 0)->tme_stp103x_upa_config)
        !          4085:        - (char *) ((struct tme_stp103x *) 0));
        !          4086:   ic->tme_sparc_recode_verify_ic_size_total = sizeof(struct tme_stp103x);
        !          4087: #endif /* _TME_SPARC_RECODE_VERIFY */
        !          4088: 
        !          4089:   /* initialize the ASIs: */
        !          4090:   for (asi = 0; asi < TME_ARRAY_ELS(ic->tme_sparc_asis); asi++) {
        !          4091: 
        !          4092:     /* dispatch on this ASI: */
        !          4093:     switch (asi) {
        !          4094: 
        !          4095:       /* ASI_PHYS_USE_EC*, ASI_PHYS_BYPASS_EC_WITH_EBIT*: */
        !          4096:     case (0x14):
        !          4097:     case (0x14
        !          4098:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4099:     case (0x15):
        !          4100:     case (0x15
        !          4101:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4102:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4103:       handler = _tme_stp103x_ls_asi_phys;
        !          4104:       break;
        !          4105: 
        !          4106:       /* ASI_NUCLEUS_QUAD_LDD*: */
        !          4107:     case (0x24):
        !          4108:     case (0x24
        !          4109:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4110:       asi_mask_flags
        !          4111:        = (TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS
        !          4112:           + (asi
        !          4113:              & TME_SPARC64_ASI_FLAG_LITTLE));
        !          4114:       handler = _tme_stp103x_ls_asi_quad;
        !          4115:       break;
        !          4116: 
        !          4117:       /* ASI_DCACHE_DATA, ASI_DCACHE_TAG: */
        !          4118:     case TME_STP103X_ASI_DCACHE_DATA:
        !          4119:     case TME_STP103X_ASI_DCACHE_TAG:
        !          4120:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4121:       handler = _tme_stp103x_ls_asi_dcache;
        !          4122:       break;
        !          4123: 
        !          4124:       /* ASI_ECACHE_W, ASI_ECACHE_R: */
        !          4125:     case 0x76:
        !          4126:     case 0x7e:
        !          4127:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4128:       handler = _tme_stp103x_ls_asi_ecache;
        !          4129:       break;
        !          4130: 
        !          4131:       /* ASI_IMMU, ASI_DMMU: */
        !          4132:     case TME_STP103X_ASI_IMMU:
        !          4133:     case TME_STP103X_ASI_DMMU:
        !          4134:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4135:       handler = _tme_stp103x_ls_asi_mmu;
        !          4136:       break;
        !          4137: 
        !          4138:       /* ASI_IMMU_TSB_8KB_PTR_REG, ASI_IMMU_TSB_64KB_PTR_REG,
        !          4139:         ASI_DMMU_TSB_8KB_PTR_REG, ASI_DMMU_TSB_64KB_PTR_REG,
        !          4140:         ASI_DMMU_TSB_DIRECT_PTR_REG: */
        !          4141:     case (TME_STP103X_ASI_IMMU
        !          4142:          + TME_STP103X_ASI_FLAG_TSB_8KB_PTR):
        !          4143:     case (TME_STP103X_ASI_IMMU
        !          4144:          + TME_STP103X_ASI_FLAG_TSB_64KB_PTR):
        !          4145:     case (TME_STP103X_ASI_DMMU
        !          4146:          + TME_STP103X_ASI_FLAG_TSB_8KB_PTR):
        !          4147:     case (TME_STP103X_ASI_DMMU
        !          4148:          + TME_STP103X_ASI_FLAG_TSB_64KB_PTR):
        !          4149:     case (TME_STP103X_ASI_DMMU
        !          4150:          + (TME_STP103X_ASI_FLAG_TSB_8KB_PTR
        !          4151:             | TME_STP103X_ASI_FLAG_TSB_64KB_PTR)):
        !          4152:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4153:       handler = _tme_stp103x_ls_asi_tsb_ptr;
        !          4154:       break;
        !          4155: 
        !          4156:       /* ASI_ITLB_DATA_IN_REG, ASI_DTLB_DATA_IN_REG: */
        !          4157:     case (TME_STP103X_ASI_IMMU + 0x4):
        !          4158:     case (TME_STP103X_ASI_DMMU + 0x4):
        !          4159:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4160:       handler = _tme_stp103x_ls_asi_tlb_data_in;
        !          4161:       break;
        !          4162: 
        !          4163:       /* ASI_ITLB_DATA_ACCESS_REG, ASI_DTLB_DATA_ACCESS_REG: */
        !          4164:     case (TME_STP103X_ASI_IMMU + 0x5):
        !          4165:     case (TME_STP103X_ASI_DMMU + 0x5):
        !          4166:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4167:       handler = _tme_stp103x_ls_asi_tlb_data_access;
        !          4168:       break;
        !          4169: 
        !          4170:       /* ASI_ITLB_TAG_READ_REG, ASI_DTLB_TAG_READ_REG: */
        !          4171:     case (TME_STP103X_ASI_IMMU + 0x6):
        !          4172:     case (TME_STP103X_ASI_DMMU + 0x6):
        !          4173:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4174:       handler = _tme_stp103x_ls_asi_tlb_tag_read;
        !          4175:       break;
        !          4176: 
        !          4177:       /* ASI_IMMU_DEMAP, ASI_DMMU_DEMAP: */
        !          4178:     case (TME_STP103X_ASI_IMMU + 0x7):
        !          4179:     case (TME_STP103X_ASI_DMMU + 0x7):
        !          4180:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4181:       handler = _tme_stp103x_ls_asi_mmu_demap;
        !          4182:       break;
        !          4183: 
        !          4184:       /* ASI_ICACHE_INSTR: */
        !          4185:       /* ASI_ICACHE_TAG: */
        !          4186:       /* ASI_ICACHE_PRE_DECODE: */
        !          4187:       /* ASI_ICACHE_NEXT_FIELD: */
        !          4188:     case 0x66:
        !          4189:     case 0x67:
        !          4190:     case 0x6e:
        !          4191:     case 0x6f:
        !          4192:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4193:       handler = _tme_stp103x_ls_asi_icache;
        !          4194:       break;
        !          4195: 
        !          4196:       /* ASI_BLOCK_AS_IF_USER*: */
        !          4197:     case (0x70):
        !          4198:     case (0x70
        !          4199:          + TME_SPARC64_ASI_FLAG_SECONDARY):
        !          4200:     case (0x70
        !          4201:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4202:     case (0x70
        !          4203:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4204:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4205:       asi_mask_flags
        !          4206:        = (TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER
        !          4207:           + (asi
        !          4208:              & (TME_SPARC64_ASI_FLAG_SECONDARY
        !          4209:                 | TME_SPARC64_ASI_FLAG_LITTLE)));
        !          4210:       handler = _tme_stp103x_ls_asi_block;
        !          4211:       break;
        !          4212: 
        !          4213:       /* ASI_UDB*: */
        !          4214:     case 0x77:
        !          4215:     case 0x7f:
        !          4216:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4217:       handler = _tme_stp103x_ls_asi_udb;
        !          4218:       break;
        !          4219: 
        !          4220:       /* the mandatory v9 ASIs: */
        !          4221: #if TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS != 4
        !          4222: #error "TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS changed"
        !          4223: #endif
        !          4224:     case (TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS):
        !          4225:     case (TME_SPARC64_ASI_MASK_FLAG_INSN_NUCLEUS
        !          4226:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4227: #if TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER != 0x10
        !          4228: #error "TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER changed"
        !          4229: #endif
        !          4230:     case (TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER):
        !          4231:     case (TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER
        !          4232:          + TME_SPARC64_ASI_FLAG_SECONDARY):
        !          4233:     case (TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER
        !          4234:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4235:     case (TME_SPARC64_ASI_MASK_FLAG_INSN_AS_IF_USER
        !          4236:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4237:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4238:     case (TME_SPARC64_ASI_FLAG_UNRESTRICTED):
        !          4239:     case (TME_SPARC64_ASI_FLAG_UNRESTRICTED
        !          4240:          + TME_SPARC64_ASI_FLAG_SECONDARY):
        !          4241:     case (TME_SPARC64_ASI_FLAG_UNRESTRICTED
        !          4242:          + TME_SPARC64_ASI_FLAG_NO_FAULT):
        !          4243:     case (TME_SPARC64_ASI_FLAG_UNRESTRICTED
        !          4244:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4245:          + TME_SPARC64_ASI_FLAG_NO_FAULT):
        !          4246:     case (TME_SPARC64_ASI_FLAG_UNRESTRICTED
        !          4247:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4248:     case (TME_SPARC64_ASI_FLAG_UNRESTRICTED
        !          4249:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4250:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4251:     case (TME_SPARC64_ASI_FLAG_UNRESTRICTED
        !          4252:          + TME_SPARC64_ASI_FLAG_NO_FAULT
        !          4253:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4254:     case (TME_SPARC64_ASI_FLAG_UNRESTRICTED
        !          4255:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4256:          + TME_SPARC64_ASI_FLAG_NO_FAULT
        !          4257:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4258: 
        !          4259:       /* the mandatory v9 ASIs are all normal and have no handlers: */
        !          4260:       asi_mask_flags = asi;
        !          4261:       handler = NULL;
        !          4262:       assert ((asi_mask_flags & TME_SPARC64_ASI_MASK_FLAG_SPECIAL) == 0);
        !          4263:       assert (_tme_stp103x_ls_asi_handlers[0] == handler);
        !          4264:       break;
        !          4265: 
        !          4266:       /* ASI_PST*: */
        !          4267:     case (TME_SPARC_VIS_ASI_PST8):
        !          4268:     case (TME_SPARC_VIS_ASI_PST8
        !          4269:          + TME_SPARC64_ASI_FLAG_SECONDARY):
        !          4270:     case (TME_SPARC_VIS_ASI_PST8
        !          4271:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4272:     case (TME_SPARC_VIS_ASI_PST8
        !          4273:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4274:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4275:     case (TME_SPARC_VIS_ASI_PST16):
        !          4276:     case (TME_SPARC_VIS_ASI_PST16
        !          4277:          + TME_SPARC64_ASI_FLAG_SECONDARY):
        !          4278:     case (TME_SPARC_VIS_ASI_PST16
        !          4279:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4280:     case (TME_SPARC_VIS_ASI_PST16
        !          4281:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4282:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4283:     case (TME_SPARC_VIS_ASI_PST32):
        !          4284:     case (TME_SPARC_VIS_ASI_PST32
        !          4285:          + TME_SPARC64_ASI_FLAG_SECONDARY):
        !          4286:     case (TME_SPARC_VIS_ASI_PST32
        !          4287:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4288:     case (TME_SPARC_VIS_ASI_PST32
        !          4289:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4290:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4291:       asi_mask_flags
        !          4292:        = (asi
        !          4293:           & (TME_SPARC64_ASI_FLAG_SECONDARY
        !          4294:              | TME_SPARC64_ASI_FLAG_LITTLE));
        !          4295:       handler = tme_sparc64_vis_ls_asi_pst;
        !          4296:       break;
        !          4297: 
        !          4298:       /* ASI_FL*: */
        !          4299:     case (TME_SPARC_VIS_ASI_FL8):
        !          4300:     case (TME_SPARC_VIS_ASI_FL8
        !          4301:          + TME_SPARC64_ASI_FLAG_SECONDARY):
        !          4302:     case (TME_SPARC_VIS_ASI_FL8
        !          4303:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4304:     case (TME_SPARC_VIS_ASI_FL8
        !          4305:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4306:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4307:     case (TME_SPARC_VIS_ASI_FL16):
        !          4308:     case (TME_SPARC_VIS_ASI_FL16
        !          4309:          + TME_SPARC64_ASI_FLAG_SECONDARY):
        !          4310:     case (TME_SPARC_VIS_ASI_FL16
        !          4311:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4312:     case (TME_SPARC_VIS_ASI_FL16
        !          4313:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4314:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4315:       asi_mask_flags
        !          4316:        = (asi
        !          4317:           & (TME_SPARC64_ASI_FLAG_SECONDARY
        !          4318:              | TME_SPARC64_ASI_FLAG_LITTLE));
        !          4319:       handler = tme_sparc64_vis_ls_asi_fl;
        !          4320:       break;
        !          4321: 
        !          4322:       /* ASI_BLK_COMMIT*: */
        !          4323:     case (TME_STP103X_ASI_BLK_COMMIT):
        !          4324:     case (TME_STP103X_ASI_BLK_COMMIT
        !          4325:          + TME_SPARC64_ASI_FLAG_SECONDARY):
        !          4326:       asi_mask_flags
        !          4327:        = (asi
        !          4328:           & (TME_SPARC64_ASI_FLAG_SECONDARY));
        !          4329:       handler = _tme_stp103x_ls_asi_block;
        !          4330:       break;
        !          4331: 
        !          4332:       /* ASI_BLOCK*: */
        !          4333:     case (0xf0):
        !          4334:     case (0xf0
        !          4335:          + TME_SPARC64_ASI_FLAG_SECONDARY):
        !          4336:     case (0xf0
        !          4337:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4338:     case (0xf0
        !          4339:          + TME_SPARC64_ASI_FLAG_SECONDARY
        !          4340:          + TME_SPARC64_ASI_FLAG_LITTLE):
        !          4341:       asi_mask_flags
        !          4342:        = (asi
        !          4343:           & (TME_SPARC64_ASI_FLAG_SECONDARY
        !          4344:              | TME_SPARC64_ASI_FLAG_LITTLE));
        !          4345:       handler = _tme_stp103x_ls_asi_block;
        !          4346:       break;
        !          4347: 
        !          4348:     case TME_STP103X_ASI_LSU_CONTROL_REG:
        !          4349:     case TME_STP103X_ASI_INTR_DISPATCH_STATUS:
        !          4350:     case TME_STP103X_ASI_INTR_RECEIVE:
        !          4351:     case TME_STP103X_ASI_UPA_CONFIG_REG:
        !          4352:     case TME_STP103X_ASI_ESTATE_ERROR_EN_REG:
        !          4353:     case TME_STP103X_ASI_AFSR:
        !          4354:     case TME_STP103X_ASI_AFAR:
        !          4355:     case TME_STP103X_ASI_ECACHE_TAG_DATA:
        !          4356:     default:
        !          4357:       asi_mask_flags = TME_SPARC64_ASI_MASK_FLAG_SPECIAL;
        !          4358:       handler = _tme_stp103x_ls_asi_slow;
        !          4359:       break;
        !          4360:     }
        !          4361: 
        !          4362:     /* get any ASI handler index: */
        !          4363:     for (handler_i = 0; _tme_stp103x_ls_asi_handlers[handler_i] != handler; handler_i++) {
        !          4364:       assert (handler_i < (TME_ARRAY_ELS(_tme_stp103x_ls_asi_handlers) - 1));
        !          4365:     }
        !          4366: 
        !          4367:     /* initialize this ASI: */
        !          4368:     ic->tme_sparc_asis[asi].tme_sparc_asi_mask_flags = asi_mask_flags;
        !          4369:     ic->tme_sparc_asis[asi].tme_sparc_asi_handler = handler_i;
        !          4370:   }
        !          4371: 
        !          4372:   /* call the common sparc new function: */
        !          4373:   return (tme_sparc_new(ic, args, extra, _output));
        !          4374: }
        !          4375: 
        !          4376: /* this creates and returns a new stp1030: */
        !          4377: TME_ELEMENT_X_NEW_DECL(tme_ic_,sparc,stp1030) {
        !          4378:   return (_tme_stp103x_new(element, args, extra, _output, TRUE));
        !          4379: }
        !          4380: 
        !          4381: #undef  TME_SPARC_VERSION
        !          4382: #define TME_SPARC_VERSION(ic) _TME_SPARC_VERSION(ic)
        !          4383: #undef  TME_SPARC_NWINDOWS
        !          4384: #define TME_SPARC_NWINDOWS(ic) _TME_SPARC_NWINDOWS(ic)
        !          4385: #undef _TME_SPARC_EXECUTE_NAME
        !          4386: #undef _TME_SPARC_EXECUTE_OPMAP

unix.superglobalmegacorp.com

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