Annotation of qemu/target-mips/cpu.h, revision 1.1.1.14

1.1       root        1: #if !defined (__MIPS_CPU_H__)
                      2: #define __MIPS_CPU_H__
                      3: 
1.1.1.14! root        4: //#define DEBUG_OP
        !             5: 
1.1.1.2   root        6: #define TARGET_HAS_ICE 1
                      7: 
1.1.1.5   root        8: #define ELF_MACHINE    EM_MIPS
                      9: 
1.1.1.8   root       10: #define CPUState struct CPUMIPSState
                     11: 
1.1.1.4   root       12: #include "config.h"
1.1.1.12  root       13: #include "qemu-common.h"
1.1       root       14: #include "mips-defs.h"
                     15: #include "cpu-defs.h"
                     16: #include "softfloat.h"
                     17: 
1.1.1.4   root       18: // uint_fast8_t and uint_fast16_t not in <sys/int_types.h>
                     19: // XXX: move that elsewhere
1.1.1.9   root       20: #if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10
1.1.1.4   root       21: typedef unsigned char           uint_fast8_t;
                     22: typedef unsigned int            uint_fast16_t;
                     23: #endif
                     24: 
1.1.1.6   root       25: struct CPUMIPSState;
                     26: 
                     27: typedef struct r4k_tlb_t r4k_tlb_t;
                     28: struct r4k_tlb_t {
                     29:     target_ulong VPN;
                     30:     uint32_t PageMask;
                     31:     uint_fast8_t ASID;
                     32:     uint_fast16_t G:1;
                     33:     uint_fast16_t C0:3;
                     34:     uint_fast16_t C1:3;
                     35:     uint_fast16_t V0:1;
                     36:     uint_fast16_t V1:1;
                     37:     uint_fast16_t D0:1;
                     38:     uint_fast16_t D1:1;
                     39:     target_ulong PFN[2];
                     40: };
                     41: 
1.1.1.11  root       42: #if !defined(CONFIG_USER_ONLY)
1.1.1.6   root       43: typedef struct CPUMIPSTLBContext CPUMIPSTLBContext;
                     44: struct CPUMIPSTLBContext {
                     45:     uint32_t nb_tlb;
                     46:     uint32_t tlb_in_use;
1.1.1.9   root       47:     int (*map_address) (struct CPUMIPSState *env, target_phys_addr_t *physical, int *prot, target_ulong address, int rw, int access_type);
1.1.1.8   root       48:     void (*helper_tlbwi) (void);
                     49:     void (*helper_tlbwr) (void);
                     50:     void (*helper_tlbp) (void);
                     51:     void (*helper_tlbr) (void);
1.1.1.6   root       52:     union {
                     53:         struct {
                     54:             r4k_tlb_t tlb[MIPS_TLB_MAX];
                     55:         } r4k;
                     56:     } mmu;
                     57: };
1.1.1.11  root       58: #endif
1.1.1.5   root       59: 
1.1       root       60: typedef union fpr_t fpr_t;
                     61: union fpr_t {
1.1.1.4   root       62:     float64  fd;   /* ieee double precision */
                     63:     float32  fs[2];/* ieee single precision */
1.1.1.6   root       64:     uint64_t d;    /* binary double fixed-point */
1.1.1.4   root       65:     uint32_t w[2]; /* binary single fixed-point */
1.1       root       66: };
1.1.1.4   root       67: /* define FP_ENDIAN_IDX to access the same location
1.1.1.13  root       68:  * in the fpr_t union regardless of the host endianness
1.1.1.4   root       69:  */
1.1.1.9   root       70: #if defined(HOST_WORDS_BIGENDIAN)
1.1.1.4   root       71: #  define FP_ENDIAN_IDX 1
                     72: #else
                     73: #  define FP_ENDIAN_IDX 0
                     74: #endif
1.1       root       75: 
1.1.1.6   root       76: typedef struct CPUMIPSFPUContext CPUMIPSFPUContext;
                     77: struct CPUMIPSFPUContext {
1.1       root       78:     /* Floating point registers */
1.1.1.6   root       79:     fpr_t fpr[32];
1.1.1.4   root       80:     float_status fp_status;
1.1.1.6   root       81:     /* fpu implementation/revision register (fir) */
1.1       root       82:     uint32_t fcr0;
1.1.1.6   root       83: #define FCR0_F64 22
                     84: #define FCR0_L 21
                     85: #define FCR0_W 20
                     86: #define FCR0_3D 19
                     87: #define FCR0_PS 18
                     88: #define FCR0_D 17
                     89: #define FCR0_S 16
                     90: #define FCR0_PRID 8
                     91: #define FCR0_REV 0
1.1.1.4   root       92:     /* fcsr */
                     93:     uint32_t fcr31;
1.1.1.7   root       94: #define SET_FP_COND(num,env)     do { ((env).fcr31) |= ((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
                     95: #define CLEAR_FP_COND(num,env)   do { ((env).fcr31) &= ~((num) ? (1 << ((num) + 24)) : (1 << 23)); } while(0)
                     96: #define GET_FP_COND(env)         ((((env).fcr31 >> 24) & 0xfe) | (((env).fcr31 >> 23) & 0x1))
1.1.1.6   root       97: #define GET_FP_CAUSE(reg)        (((reg) >> 12) & 0x3f)
                     98: #define GET_FP_ENABLE(reg)       (((reg) >>  7) & 0x1f)
                     99: #define GET_FP_FLAGS(reg)        (((reg) >>  2) & 0x1f)
                    100: #define SET_FP_CAUSE(reg,v)      do { (reg) = ((reg) & ~(0x3f << 12)) | ((v & 0x3f) << 12); } while(0)
                    101: #define SET_FP_ENABLE(reg,v)     do { (reg) = ((reg) & ~(0x1f <<  7)) | ((v & 0x1f) << 7); } while(0)
                    102: #define SET_FP_FLAGS(reg,v)      do { (reg) = ((reg) & ~(0x1f <<  2)) | ((v & 0x1f) << 2); } while(0)
                    103: #define UPDATE_FP_FLAGS(reg,v)   do { (reg) |= ((v & 0x1f) << 2); } while(0)
1.1.1.4   root      104: #define FP_INEXACT        1
                    105: #define FP_UNDERFLOW      2
                    106: #define FP_OVERFLOW       4
                    107: #define FP_DIV0           8
                    108: #define FP_INVALID        16
                    109: #define FP_UNIMPLEMENTED  32
1.1.1.6   root      110: };
                    111: 
                    112: #define NB_MMU_MODES 3
                    113: 
                    114: typedef struct CPUMIPSMVPContext CPUMIPSMVPContext;
                    115: struct CPUMIPSMVPContext {
                    116:     int32_t CP0_MVPControl;
                    117: #define CP0MVPCo_CPA   3
                    118: #define CP0MVPCo_STLB  2
                    119: #define CP0MVPCo_VPC   1
                    120: #define CP0MVPCo_EVP   0
                    121:     int32_t CP0_MVPConf0;
                    122: #define CP0MVPC0_M     31
                    123: #define CP0MVPC0_TLBS  29
                    124: #define CP0MVPC0_GS    28
                    125: #define CP0MVPC0_PCP   27
                    126: #define CP0MVPC0_PTLBE 16
                    127: #define CP0MVPC0_TCA   15
                    128: #define CP0MVPC0_PVPE  10
                    129: #define CP0MVPC0_PTC   0
                    130:     int32_t CP0_MVPConf1;
                    131: #define CP0MVPC1_CIM   31
                    132: #define CP0MVPC1_CIF   30
                    133: #define CP0MVPC1_PCX   20
                    134: #define CP0MVPC1_PCP2  10
                    135: #define CP0MVPC1_PCP1  0
                    136: };
                    137: 
                    138: typedef struct mips_def_t mips_def_t;
                    139: 
                    140: #define MIPS_SHADOW_SET_MAX 16
                    141: #define MIPS_TC_MAX 5
1.1.1.7   root      142: #define MIPS_FPU_MAX 1
1.1.1.6   root      143: #define MIPS_DSP_ACC 4
                    144: 
1.1.1.7   root      145: typedef struct TCState TCState;
                    146: struct TCState {
                    147:     target_ulong gpr[32];
                    148:     target_ulong PC;
                    149:     target_ulong HI[MIPS_DSP_ACC];
                    150:     target_ulong LO[MIPS_DSP_ACC];
                    151:     target_ulong ACX[MIPS_DSP_ACC];
                    152:     target_ulong DSPControl;
                    153:     int32_t CP0_TCStatus;
                    154: #define CP0TCSt_TCU3   31
                    155: #define CP0TCSt_TCU2   30
                    156: #define CP0TCSt_TCU1   29
                    157: #define CP0TCSt_TCU0   28
                    158: #define CP0TCSt_TMX    27
                    159: #define CP0TCSt_RNST   23
                    160: #define CP0TCSt_TDS    21
                    161: #define CP0TCSt_DT     20
                    162: #define CP0TCSt_DA     15
                    163: #define CP0TCSt_A      13
                    164: #define CP0TCSt_TKSU   11
                    165: #define CP0TCSt_IXMT   10
                    166: #define CP0TCSt_TASID  0
                    167:     int32_t CP0_TCBind;
                    168: #define CP0TCBd_CurTC  21
                    169: #define CP0TCBd_TBE    17
                    170: #define CP0TCBd_CurVPE 0
                    171:     target_ulong CP0_TCHalt;
                    172:     target_ulong CP0_TCContext;
                    173:     target_ulong CP0_TCSchedule;
                    174:     target_ulong CP0_TCScheFBack;
                    175:     int32_t CP0_Debug_tcstatus;
                    176: };
                    177: 
1.1.1.6   root      178: typedef struct CPUMIPSState CPUMIPSState;
                    179: struct CPUMIPSState {
1.1.1.7   root      180:     TCState active_tc;
                    181:     CPUMIPSFPUContext active_fpu;
1.1.1.6   root      182: 
                    183:     uint32_t current_tc;
1.1.1.7   root      184:     uint32_t current_fpu;
1.1.1.6   root      185: 
                    186:     uint32_t SEGBITS;
                    187:     uint32_t PABITS;
1.1.1.7   root      188:     target_ulong SEGMask;
1.1.1.6   root      189:     target_ulong PAMask;
                    190: 
1.1.1.5   root      191:     int32_t CP0_Index;
1.1.1.6   root      192:     /* CP0_MVP* are per MVP registers. */
1.1.1.5   root      193:     int32_t CP0_Random;
1.1.1.6   root      194:     int32_t CP0_VPEControl;
                    195: #define CP0VPECo_YSI   21
                    196: #define CP0VPECo_GSI   20
                    197: #define CP0VPECo_EXCPT 16
                    198: #define CP0VPECo_TE    15
                    199: #define CP0VPECo_TargTC        0
                    200:     int32_t CP0_VPEConf0;
                    201: #define CP0VPEC0_M     31
                    202: #define CP0VPEC0_XTC   21
                    203: #define CP0VPEC0_TCS   19
                    204: #define CP0VPEC0_SCS   18
                    205: #define CP0VPEC0_DSC   17
                    206: #define CP0VPEC0_ICS   16
                    207: #define CP0VPEC0_MVP   1
                    208: #define CP0VPEC0_VPA   0
                    209:     int32_t CP0_VPEConf1;
                    210: #define CP0VPEC1_NCX   20
                    211: #define CP0VPEC1_NCP2  10
                    212: #define CP0VPEC1_NCP1  0
                    213:     target_ulong CP0_YQMask;
                    214:     target_ulong CP0_VPESchedule;
                    215:     target_ulong CP0_VPEScheFBack;
                    216:     int32_t CP0_VPEOpt;
                    217: #define CP0VPEOpt_IWX7 15
                    218: #define CP0VPEOpt_IWX6 14
                    219: #define CP0VPEOpt_IWX5 13
                    220: #define CP0VPEOpt_IWX4 12
                    221: #define CP0VPEOpt_IWX3 11
                    222: #define CP0VPEOpt_IWX2 10
                    223: #define CP0VPEOpt_IWX1 9
                    224: #define CP0VPEOpt_IWX0 8
                    225: #define CP0VPEOpt_DWX7 7
                    226: #define CP0VPEOpt_DWX6 6
                    227: #define CP0VPEOpt_DWX5 5
                    228: #define CP0VPEOpt_DWX4 4
                    229: #define CP0VPEOpt_DWX3 3
                    230: #define CP0VPEOpt_DWX2 2
                    231: #define CP0VPEOpt_DWX1 1
                    232: #define CP0VPEOpt_DWX0 0
1.1.1.5   root      233:     target_ulong CP0_EntryLo0;
                    234:     target_ulong CP0_EntryLo1;
                    235:     target_ulong CP0_Context;
                    236:     int32_t CP0_PageMask;
                    237:     int32_t CP0_PageGrain;
                    238:     int32_t CP0_Wired;
1.1.1.6   root      239:     int32_t CP0_SRSConf0_rw_bitmask;
                    240:     int32_t CP0_SRSConf0;
                    241: #define CP0SRSC0_M     31
                    242: #define CP0SRSC0_SRS3  20
                    243: #define CP0SRSC0_SRS2  10
                    244: #define CP0SRSC0_SRS1  0
                    245:     int32_t CP0_SRSConf1_rw_bitmask;
                    246:     int32_t CP0_SRSConf1;
                    247: #define CP0SRSC1_M     31
                    248: #define CP0SRSC1_SRS6  20
                    249: #define CP0SRSC1_SRS5  10
                    250: #define CP0SRSC1_SRS4  0
                    251:     int32_t CP0_SRSConf2_rw_bitmask;
                    252:     int32_t CP0_SRSConf2;
                    253: #define CP0SRSC2_M     31
                    254: #define CP0SRSC2_SRS9  20
                    255: #define CP0SRSC2_SRS8  10
                    256: #define CP0SRSC2_SRS7  0
                    257:     int32_t CP0_SRSConf3_rw_bitmask;
                    258:     int32_t CP0_SRSConf3;
                    259: #define CP0SRSC3_M     31
                    260: #define CP0SRSC3_SRS12 20
                    261: #define CP0SRSC3_SRS11 10
                    262: #define CP0SRSC3_SRS10 0
                    263:     int32_t CP0_SRSConf4_rw_bitmask;
                    264:     int32_t CP0_SRSConf4;
                    265: #define CP0SRSC4_SRS15 20
                    266: #define CP0SRSC4_SRS14 10
                    267: #define CP0SRSC4_SRS13 0
1.1.1.5   root      268:     int32_t CP0_HWREna;
                    269:     target_ulong CP0_BadVAddr;
                    270:     int32_t CP0_Count;
                    271:     target_ulong CP0_EntryHi;
                    272:     int32_t CP0_Compare;
                    273:     int32_t CP0_Status;
1.1       root      274: #define CP0St_CU3   31
                    275: #define CP0St_CU2   30
                    276: #define CP0St_CU1   29
                    277: #define CP0St_CU0   28
                    278: #define CP0St_RP    27
1.1.1.4   root      279: #define CP0St_FR    26
1.1       root      280: #define CP0St_RE    25
1.1.1.5   root      281: #define CP0St_MX    24
                    282: #define CP0St_PX    23
1.1       root      283: #define CP0St_BEV   22
                    284: #define CP0St_TS    21
                    285: #define CP0St_SR    20
                    286: #define CP0St_NMI   19
                    287: #define CP0St_IM    8
1.1.1.5   root      288: #define CP0St_KX    7
                    289: #define CP0St_SX    6
                    290: #define CP0St_UX    5
1.1.1.6   root      291: #define CP0St_KSU   3
1.1       root      292: #define CP0St_ERL   2
                    293: #define CP0St_EXL   1
                    294: #define CP0St_IE    0
1.1.1.5   root      295:     int32_t CP0_IntCtl;
1.1.1.6   root      296: #define CP0IntCtl_IPTI 29
                    297: #define CP0IntCtl_IPPC1 26
                    298: #define CP0IntCtl_VS 5
1.1.1.5   root      299:     int32_t CP0_SRSCtl;
1.1.1.6   root      300: #define CP0SRSCtl_HSS 26
                    301: #define CP0SRSCtl_EICSS 18
                    302: #define CP0SRSCtl_ESS 12
                    303: #define CP0SRSCtl_PSS 6
                    304: #define CP0SRSCtl_CSS 0
1.1.1.5   root      305:     int32_t CP0_SRSMap;
1.1.1.6   root      306: #define CP0SRSMap_SSV7 28
                    307: #define CP0SRSMap_SSV6 24
                    308: #define CP0SRSMap_SSV5 20
                    309: #define CP0SRSMap_SSV4 16
                    310: #define CP0SRSMap_SSV3 12
                    311: #define CP0SRSMap_SSV2 8
                    312: #define CP0SRSMap_SSV1 4
                    313: #define CP0SRSMap_SSV0 0
1.1.1.5   root      314:     int32_t CP0_Cause;
                    315: #define CP0Ca_BD   31
                    316: #define CP0Ca_TI   30
                    317: #define CP0Ca_CE   28
                    318: #define CP0Ca_DC   27
                    319: #define CP0Ca_PCI  26
1.1       root      320: #define CP0Ca_IV   23
1.1.1.5   root      321: #define CP0Ca_WP   22
                    322: #define CP0Ca_IP    8
                    323: #define CP0Ca_IP_mask 0x0000FF00
                    324: #define CP0Ca_EC    2
                    325:     target_ulong CP0_EPC;
                    326:     int32_t CP0_PRid;
                    327:     int32_t CP0_EBase;
                    328:     int32_t CP0_Config0;
1.1       root      329: #define CP0C0_M    31
                    330: #define CP0C0_K23  28
                    331: #define CP0C0_KU   25
                    332: #define CP0C0_MDU  20
                    333: #define CP0C0_MM   17
                    334: #define CP0C0_BM   16
                    335: #define CP0C0_BE   15
                    336: #define CP0C0_AT   13
                    337: #define CP0C0_AR   10
                    338: #define CP0C0_MT   7
1.1.1.5   root      339: #define CP0C0_VI   3
1.1       root      340: #define CP0C0_K0   0
1.1.1.5   root      341:     int32_t CP0_Config1;
                    342: #define CP0C1_M    31
1.1       root      343: #define CP0C1_MMU  25
                    344: #define CP0C1_IS   22
                    345: #define CP0C1_IL   19
                    346: #define CP0C1_IA   16
                    347: #define CP0C1_DS   13
                    348: #define CP0C1_DL   10
                    349: #define CP0C1_DA   7
1.1.1.5   root      350: #define CP0C1_C2   6
                    351: #define CP0C1_MD   5
1.1       root      352: #define CP0C1_PC   4
                    353: #define CP0C1_WR   3
                    354: #define CP0C1_CA   2
                    355: #define CP0C1_EP   1
                    356: #define CP0C1_FP   0
1.1.1.5   root      357:     int32_t CP0_Config2;
                    358: #define CP0C2_M    31
                    359: #define CP0C2_TU   28
                    360: #define CP0C2_TS   24
                    361: #define CP0C2_TL   20
                    362: #define CP0C2_TA   16
                    363: #define CP0C2_SU   12
                    364: #define CP0C2_SS   8
                    365: #define CP0C2_SL   4
                    366: #define CP0C2_SA   0
                    367:     int32_t CP0_Config3;
                    368: #define CP0C3_M    31
1.1.1.11  root      369: #define CP0C3_ISA_ON_EXC 16
1.1.1.5   root      370: #define CP0C3_DSPP 10
                    371: #define CP0C3_LPA  7
                    372: #define CP0C3_VEIC 6
                    373: #define CP0C3_VInt 5
                    374: #define CP0C3_SP   4
                    375: #define CP0C3_MT   2
                    376: #define CP0C3_SM   1
                    377: #define CP0C3_TL   0
1.1.1.6   root      378:     int32_t CP0_Config6;
                    379:     int32_t CP0_Config7;
                    380:     /* XXX: Maybe make LLAddr per-TC? */
1.1.1.9   root      381:     target_ulong lladdr;
1.1.1.8   root      382:     target_ulong llval;
                    383:     target_ulong llnewval;
                    384:     target_ulong llreg;
1.1.1.9   root      385:     target_ulong CP0_LLAddr_rw_bitmask;
                    386:     int CP0_LLAddr_shift;
1.1.1.6   root      387:     target_ulong CP0_WatchLo[8];
                    388:     int32_t CP0_WatchHi[8];
1.1.1.5   root      389:     target_ulong CP0_XContext;
                    390:     int32_t CP0_Framemask;
                    391:     int32_t CP0_Debug;
1.1.1.6   root      392: #define CP0DB_DBD  31
1.1       root      393: #define CP0DB_DM   30
                    394: #define CP0DB_LSNM 28
                    395: #define CP0DB_Doze 27
                    396: #define CP0DB_Halt 26
                    397: #define CP0DB_CNT  25
                    398: #define CP0DB_IBEP 24
                    399: #define CP0DB_DBEP 21
                    400: #define CP0DB_IEXI 20
                    401: #define CP0DB_VER  15
                    402: #define CP0DB_DEC  10
                    403: #define CP0DB_SSt  8
                    404: #define CP0DB_DINT 5
                    405: #define CP0DB_DIB  4
                    406: #define CP0DB_DDBS 3
                    407: #define CP0DB_DDBL 2
                    408: #define CP0DB_DBp  1
                    409: #define CP0DB_DSS  0
1.1.1.5   root      410:     target_ulong CP0_DEPC;
                    411:     int32_t CP0_Performance0;
                    412:     int32_t CP0_TagLo;
                    413:     int32_t CP0_DataLo;
                    414:     int32_t CP0_TagHi;
                    415:     int32_t CP0_DataHi;
                    416:     target_ulong CP0_ErrorEPC;
                    417:     int32_t CP0_DESAVE;
1.1.1.7   root      418:     /* We waste some space so we can handle shadow registers like TCs. */
                    419:     TCState tcs[MIPS_SHADOW_SET_MAX];
                    420:     CPUMIPSFPUContext fpus[MIPS_FPU_MAX];
1.1       root      421:     /* Qemu */
                    422:     int error_code;
                    423:     uint32_t hflags;    /* CPU State */
                    424:     /* TMASK defines different execution modes */
1.1.1.11  root      425: #define MIPS_HFLAG_TMASK  0x007FF
                    426: #define MIPS_HFLAG_MODE   0x00007 /* execution modes                    */
1.1.1.6   root      427:     /* The KSU flags must be the lowest bits in hflags. The flag order
                    428:        must be the same as defined for CP0 Status. This allows to use
                    429:        the bits as the value of mmu_idx. */
1.1.1.11  root      430: #define MIPS_HFLAG_KSU    0x00003 /* kernel/supervisor/user mode mask   */
                    431: #define MIPS_HFLAG_UM     0x00002 /* user mode flag                     */
                    432: #define MIPS_HFLAG_SM     0x00001 /* supervisor mode flag               */
                    433: #define MIPS_HFLAG_KM     0x00000 /* kernel mode flag                   */
                    434: #define MIPS_HFLAG_DM     0x00004 /* Debug mode                         */
                    435: #define MIPS_HFLAG_64     0x00008 /* 64-bit instructions enabled        */
                    436: #define MIPS_HFLAG_CP0    0x00010 /* CP0 enabled                        */
                    437: #define MIPS_HFLAG_FPU    0x00020 /* FPU enabled                        */
                    438: #define MIPS_HFLAG_F64    0x00040 /* 64-bit FPU enabled                 */
1.1.1.6   root      439:     /* True if the MIPS IV COP1X instructions can be used.  This also
                    440:        controls the non-COP1X instructions RECIP.S, RECIP.D, RSQRT.S
                    441:        and RSQRT.D.  */
1.1.1.11  root      442: #define MIPS_HFLAG_COP1X  0x00080 /* COP1X instructions enabled         */
                    443: #define MIPS_HFLAG_RE     0x00100 /* Reversed endianness                */
                    444: #define MIPS_HFLAG_UX     0x00200 /* 64-bit user mode                   */
                    445: #define MIPS_HFLAG_M16    0x00400 /* MIPS16 mode flag                   */
                    446: #define MIPS_HFLAG_M16_SHIFT 10
1.1.1.2   root      447:     /* If translation is interrupted between the branch instruction and
                    448:      * the delay slot, record what type of branch it is so that we can
                    449:      * resume translation properly.  It might be possible to reduce
                    450:      * this from three bits to two.  */
1.1.1.11  root      451: #define MIPS_HFLAG_BMASK_BASE  0x03800
                    452: #define MIPS_HFLAG_B      0x00800 /* Unconditional branch               */
                    453: #define MIPS_HFLAG_BC     0x01000 /* Conditional branch                 */
                    454: #define MIPS_HFLAG_BL     0x01800 /* Likely branch                      */
                    455: #define MIPS_HFLAG_BR     0x02000 /* branch to register (can't link TB) */
                    456:     /* Extra flags about the current pending branch.  */
                    457: #define MIPS_HFLAG_BMASK_EXT 0x3C000
                    458: #define MIPS_HFLAG_B16    0x04000 /* branch instruction was 16 bits     */
                    459: #define MIPS_HFLAG_BDS16  0x08000 /* branch requires 16-bit delay slot  */
                    460: #define MIPS_HFLAG_BDS32  0x10000 /* branch requires 32-bit delay slot  */
                    461: #define MIPS_HFLAG_BX     0x20000 /* branch exchanges execution mode    */
                    462: #define MIPS_HFLAG_BMASK  (MIPS_HFLAG_BMASK_BASE | MIPS_HFLAG_BMASK_EXT)
1.1       root      463:     target_ulong btarget;        /* Jump / branch target               */
1.1.1.8   root      464:     target_ulong bcond;          /* Branch condition (if needed)       */
1.1.1.2   root      465: 
1.1.1.5   root      466:     int SYNCI_Step; /* Address step size for SYNCI */
                    467:     int CCRes; /* Cycle count resolution/divisor */
1.1.1.6   root      468:     uint32_t CP0_Status_rw_bitmask; /* Read/write bits in CP0_Status */
                    469:     uint32_t CP0_TCStatus_rw_bitmask; /* Read/write bits in CP0_TCStatus */
                    470:     int insn_flags; /* Supported instruction set */
                    471: 
1.1.1.7   root      472:     target_ulong tls_value; /* For usermode emulation */
1.1.1.5   root      473: 
1.1.1.2   root      474:     CPU_COMMON
1.1.1.5   root      475: 
1.1.1.9   root      476:     CPUMIPSMVPContext *mvp;
1.1.1.11  root      477: #if !defined(CONFIG_USER_ONLY)
1.1.1.9   root      478:     CPUMIPSTLBContext *tlb;
1.1.1.11  root      479: #endif
1.1.1.9   root      480: 
1.1.1.6   root      481:     const mips_def_t *cpu_model;
                    482:     void *irq[8];
1.1.1.5   root      483:     struct QEMUTimer *timer; /* Internal timer */
1.1       root      484: };
                    485: 
1.1.1.11  root      486: #if !defined(CONFIG_USER_ONLY)
1.1.1.9   root      487: int no_mmu_map_address (CPUMIPSState *env, target_phys_addr_t *physical, int *prot,
1.1.1.6   root      488:                         target_ulong address, int rw, int access_type);
1.1.1.9   root      489: int fixed_mmu_map_address (CPUMIPSState *env, target_phys_addr_t *physical, int *prot,
1.1.1.6   root      490:                            target_ulong address, int rw, int access_type);
1.1.1.9   root      491: int r4k_map_address (CPUMIPSState *env, target_phys_addr_t *physical, int *prot,
1.1.1.6   root      492:                      target_ulong address, int rw, int access_type);
1.1.1.8   root      493: void r4k_helper_tlbwi (void);
                    494: void r4k_helper_tlbwr (void);
                    495: void r4k_helper_tlbp (void);
                    496: void r4k_helper_tlbr (void);
1.1.1.6   root      497: 
1.1.1.13  root      498: void cpu_unassigned_access(CPUState *env, target_phys_addr_t addr,
                    499:                            int is_write, int is_exec, int unused, int size);
1.1.1.11  root      500: #endif
                    501: 
1.1.1.12  root      502: void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
1.1.1.6   root      503: 
                    504: #define cpu_init cpu_mips_init
                    505: #define cpu_exec cpu_mips_exec
                    506: #define cpu_gen_code cpu_mips_gen_code
                    507: #define cpu_signal_handler cpu_mips_signal_handler
                    508: #define cpu_list mips_cpu_list
                    509: 
1.1.1.7   root      510: #define CPU_SAVE_VERSION 3
                    511: 
1.1.1.6   root      512: /* MMU modes definitions. We carefully match the indices with our
                    513:    hflags layout. */
                    514: #define MMU_MODE0_SUFFIX _kernel
                    515: #define MMU_MODE1_SUFFIX _super
                    516: #define MMU_MODE2_SUFFIX _user
                    517: #define MMU_USER_IDX 2
                    518: static inline int cpu_mmu_index (CPUState *env)
                    519: {
                    520:     return env->hflags & MIPS_HFLAG_KSU;
                    521: }
                    522: 
1.1.1.7   root      523: static inline void cpu_clone_regs(CPUState *env, target_ulong newsp)
                    524: {
                    525:     if (newsp)
                    526:         env->active_tc.gpr[29] = newsp;
                    527:     env->active_tc.gpr[7] = 0;
                    528:     env->active_tc.gpr[2] = 0;
                    529: }
                    530: 
1.1.1.12  root      531: static inline int cpu_mips_hw_interrupts_pending(CPUState *env)
                    532: {
                    533:     int32_t pending;
                    534:     int32_t status;
                    535:     int r;
                    536: 
                    537:     if (!(env->CP0_Status & (1 << CP0St_IE)) ||
                    538:         (env->CP0_Status & (1 << CP0St_EXL)) ||
                    539:         (env->CP0_Status & (1 << CP0St_ERL)) ||
1.1.1.14! root      540:         /* Note that the TCStatus IXMT field is initialized to zero,
        !           541:            and only MT capable cores can set it to one. So we don't
        !           542:            need to check for MT capabilities here.  */
        !           543:         (env->active_tc.CP0_TCStatus & (1 << CP0TCSt_IXMT)) ||
1.1.1.12  root      544:         (env->hflags & MIPS_HFLAG_DM)) {
                    545:         /* Interrupts are disabled */
                    546:         return 0;
                    547:     }
                    548: 
                    549:     pending = env->CP0_Cause & CP0Ca_IP_mask;
                    550:     status = env->CP0_Status & CP0Ca_IP_mask;
                    551: 
                    552:     if (env->CP0_Config3 & (1 << CP0C3_VEIC)) {
                    553:         /* A MIPS configured with a vectorizing external interrupt controller
                    554:            will feed a vector into the Cause pending lines. The core treats
                    555:            the status lines as a vector level, not as indiviual masks.  */
                    556:         r = pending > status;
                    557:     } else {
                    558:         /* A MIPS configured with compatibility or VInt (Vectored Interrupts)
                    559:            treats the pending lines as individual interrupt lines, the status
                    560:            lines are individual masks.  */
                    561:         r = pending & status;
                    562:     }
                    563:     return r;
                    564: }
                    565: 
1.1       root      566: #include "cpu-all.h"
                    567: 
                    568: /* Memory access type :
                    569:  * may be needed for precise access rights control and precise exceptions.
                    570:  */
                    571: enum {
                    572:     /* 1 bit to define user level / supervisor access */
                    573:     ACCESS_USER  = 0x00,
                    574:     ACCESS_SUPER = 0x01,
                    575:     /* 1 bit to indicate direction */
                    576:     ACCESS_STORE = 0x02,
                    577:     /* Type of instruction that generated the access */
                    578:     ACCESS_CODE  = 0x10, /* Code fetch access                */
                    579:     ACCESS_INT   = 0x20, /* Integer load/store access        */
                    580:     ACCESS_FLOAT = 0x30, /* floating point load/store access */
                    581: };
                    582: 
                    583: /* Exceptions */
                    584: enum {
                    585:     EXCP_NONE          = -1,
                    586:     EXCP_RESET         = 0,
                    587:     EXCP_SRESET,
                    588:     EXCP_DSS,
                    589:     EXCP_DINT,
1.1.1.6   root      590:     EXCP_DDBL,
                    591:     EXCP_DDBS,
1.1       root      592:     EXCP_NMI,
                    593:     EXCP_MCHECK,
1.1.1.6   root      594:     EXCP_EXT_INTERRUPT, /* 8 */
1.1       root      595:     EXCP_DFWATCH,
1.1.1.6   root      596:     EXCP_DIB,
1.1       root      597:     EXCP_IWATCH,
                    598:     EXCP_AdEL,
                    599:     EXCP_AdES,
                    600:     EXCP_TLBF,
                    601:     EXCP_IBE,
1.1.1.6   root      602:     EXCP_DBp, /* 16 */
1.1       root      603:     EXCP_SYSCALL,
1.1.1.6   root      604:     EXCP_BREAK,
1.1.1.2   root      605:     EXCP_CpU,
1.1       root      606:     EXCP_RI,
                    607:     EXCP_OVERFLOW,
                    608:     EXCP_TRAP,
1.1.1.6   root      609:     EXCP_FPE,
                    610:     EXCP_DWATCH, /* 24 */
1.1       root      611:     EXCP_LTLBL,
                    612:     EXCP_TLBL,
                    613:     EXCP_TLBS,
                    614:     EXCP_DBE,
1.1.1.6   root      615:     EXCP_THREAD,
                    616:     EXCP_MDMX,
                    617:     EXCP_C2E,
                    618:     EXCP_CACHE, /* 32 */
                    619: 
                    620:     EXCP_LAST = EXCP_CACHE,
1.1       root      621: };
1.1.1.8   root      622: /* Dummy exception for conditional stores.  */
                    623: #define EXCP_SC 0x100
1.1       root      624: 
1.1.1.14! root      625: /*
        !           626:  * This is an interrnally generated WAKE request line.
        !           627:  * It is driven by the CPU itself. Raised when the MT
        !           628:  * block wants to wake a VPE from an inactive state and
        !           629:  * cleared when VPE goes from active to inactive.
        !           630:  */
        !           631: #define CPU_INTERRUPT_WAKE CPU_INTERRUPT_TGT_INT_0
        !           632: 
1.1       root      633: int cpu_mips_exec(CPUMIPSState *s);
1.1.1.6   root      634: CPUMIPSState *cpu_mips_init(const char *cpu_model);
1.1.1.7   root      635: //~ uint32_t cpu_mips_get_clock (void);
1.1.1.6   root      636: int cpu_mips_signal_handler(int host_signum, void *pinfo, void *puc);
1.1       root      637: 
1.1.1.7   root      638: /* mips_timer.c */
                    639: uint32_t cpu_mips_get_random (CPUState *env);
                    640: uint32_t cpu_mips_get_count (CPUState *env);
                    641: void cpu_mips_store_count (CPUState *env, uint32_t value);
                    642: void cpu_mips_store_compare (CPUState *env, uint32_t value);
                    643: void cpu_mips_start_count(CPUState *env);
                    644: void cpu_mips_stop_count(CPUState *env);
                    645: 
                    646: /* mips_int.c */
1.1.1.11  root      647: void cpu_mips_soft_irq(CPUState *env, int irq, int level);
1.1.1.7   root      648: 
                    649: /* helper.c */
                    650: int cpu_mips_handle_mmu_fault (CPUState *env, target_ulong address, int rw,
1.1.1.14! root      651:                                int mmu_idx);
1.1.1.9   root      652: #define cpu_handle_mmu_fault cpu_mips_handle_mmu_fault
1.1.1.7   root      653: void do_interrupt (CPUState *env);
1.1.1.11  root      654: #if !defined(CONFIG_USER_ONLY)
1.1.1.7   root      655: void r4k_invalidate_tlb (CPUState *env, int idx, int use_extra);
1.1.1.10  root      656: target_phys_addr_t cpu_mips_translate_address (CPUState *env, target_ulong address,
                    657:                                               int rw);
1.1.1.11  root      658: #endif
1.1.1.7   root      659: 
                    660: static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
                    661:                                         target_ulong *cs_base, int *flags)
                    662: {
                    663:     *pc = env->active_tc.PC;
                    664:     *cs_base = 0;
                    665:     *flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
                    666: }
                    667: 
1.1.1.8   root      668: static inline void cpu_set_tls(CPUState *env, target_ulong newtls)
                    669: {
                    670:     env->tls_value = newtls;
                    671: }
                    672: 
1.1.1.14! root      673: static inline int mips_vpe_active(CPUState *env)
        !           674: {
        !           675:     int active = 1;
        !           676: 
        !           677:     /* Check that the VPE is enabled.  */
        !           678:     if (!(env->mvp->CP0_MVPControl & (1 << CP0MVPCo_EVP))) {
        !           679:         active = 0;
        !           680:     }
        !           681:     /* Check that the VPE is actived.  */
        !           682:     if (!(env->CP0_VPEConf0 & (1 << CP0VPEC0_VPA))) {
        !           683:         active = 0;
        !           684:     }
        !           685: 
        !           686:     /* Now verify that there are active thread contexts in the VPE.
        !           687: 
        !           688:        This assumes the CPU model will internally reschedule threads
        !           689:        if the active one goes to sleep. If there are no threads available
        !           690:        the active one will be in a sleeping state, and we can turn off
        !           691:        the entire VPE.  */
        !           692:     if (!(env->active_tc.CP0_TCStatus & (1 << CP0TCSt_A))) {
        !           693:         /* TC is not activated.  */
        !           694:         active = 0;
        !           695:     }
        !           696:     if (env->active_tc.CP0_TCHalt & 1) {
        !           697:         /* TC is in halt state.  */
        !           698:         active = 0;
        !           699:     }
        !           700: 
        !           701:     return active;
        !           702: }
        !           703: 
1.1.1.13  root      704: static inline int cpu_has_work(CPUState *env)
                    705: {
                    706:     int has_work = 0;
                    707: 
                    708:     /* It is implementation dependent if non-enabled interrupts
                    709:        wake-up the CPU, however most of the implementations only
                    710:        check for interrupts that can be taken. */
                    711:     if ((env->interrupt_request & CPU_INTERRUPT_HARD) &&
                    712:         cpu_mips_hw_interrupts_pending(env)) {
                    713:         has_work = 1;
                    714:     }
                    715: 
1.1.1.14! root      716:     /* MIPS-MT has the ability to halt the CPU.  */
        !           717:     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
        !           718:         /* The QEMU model will issue an _WAKE request whenever the CPUs
        !           719:            should be woken up.  */
        !           720:         if (env->interrupt_request & CPU_INTERRUPT_WAKE) {
        !           721:             has_work = 1;
        !           722:         }
        !           723: 
        !           724:         if (!mips_vpe_active(env)) {
        !           725:             has_work = 0;
        !           726:         }
        !           727:     }
1.1.1.13  root      728:     return has_work;
                    729: }
                    730: 
                    731: #include "exec-all.h"
                    732: 
                    733: static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
                    734: {
                    735:     env->active_tc.PC = tb->pc;
                    736:     env->hflags &= ~MIPS_HFLAG_BMASK;
                    737:     env->hflags |= tb->flags & MIPS_HFLAG_BMASK;
                    738: }
                    739: 
1.1       root      740: #endif /* !defined (__MIPS_CPU_H__) */

unix.superglobalmegacorp.com

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