Annotation of qemu/target-mips/translate_init.c, revision 1.1.1.4

1.1       root        1: /*
                      2:  *  MIPS emulation for qemu: CPU initialisation routines.
                      3:  *
                      4:  *  Copyright (c) 2004-2005 Jocelyn Mayer
                      5:  *  Copyright (c) 2007 Herve Poussineau
                      6:  *
                      7:  * This library is free software; you can redistribute it and/or
                      8:  * modify it under the terms of the GNU Lesser General Public
                      9:  * License as published by the Free Software Foundation; either
                     10:  * version 2 of the License, or (at your option) any later version.
                     11:  *
                     12:  * This library is distributed in the hope that it will be useful,
                     13:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     15:  * Lesser General Public License for more details.
                     16:  *
                     17:  * You should have received a copy of the GNU Lesser General Public
1.1.1.3   root       18:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       19:  */
                     20: 
                     21: /* CPU / CPU family specific config register values. */
                     22: 
                     23: /* Have config1, uncached coherency */
                     24: #define MIPS_CONFIG0                                              \
                     25:   ((1 << CP0C0_M) | (0x2 << CP0C0_K0))
                     26: 
                     27: /* Have config2, no coprocessor2 attached, no MDMX support attached,
                     28:    no performance counters, watch registers present,
                     29:    no code compression, EJTAG present, no FPU */
                     30: #define MIPS_CONFIG1                                              \
                     31: ((1 << CP0C1_M) |                                                 \
                     32:  (0 << CP0C1_C2) | (0 << CP0C1_MD) | (0 << CP0C1_PC) |            \
                     33:  (1 << CP0C1_WR) | (0 << CP0C1_CA) | (1 << CP0C1_EP) |            \
                     34:  (0 << CP0C1_FP))
                     35: 
                     36: /* Have config3, no tertiary/secondary caches implemented */
                     37: #define MIPS_CONFIG2                                              \
                     38: ((1 << CP0C2_M))
                     39: 
                     40: /* No config4, no DSP ASE, no large physaddr (PABITS),
                     41:    no external interrupt controller, no vectored interupts,
                     42:    no 1kb pages, no SmartMIPS ASE, no trace logic */
                     43: #define MIPS_CONFIG3                                              \
                     44: ((0 << CP0C3_M) | (0 << CP0C3_DSPP) | (0 << CP0C3_LPA) |          \
                     45:  (0 << CP0C3_VEIC) | (0 << CP0C3_VInt) | (0 << CP0C3_SP) |        \
                     46:  (0 << CP0C3_SM) | (0 << CP0C3_TL))
                     47: 
                     48: /* Define a implementation number of 1.
                     49:    Define a major version 1, minor version 0. */
                     50: #define MIPS_FCR0 ((0 << FCR0_S) | (0x1 << FCR0_PRID) | (0x10 << FCR0_REV))
                     51: 
                     52: /* MMU types, the first four entries have the same layout as the
                     53:    CP0C0_MT field.  */
                     54: enum mips_mmu_types {
                     55:     MMU_TYPE_NONE,
                     56:     MMU_TYPE_R4000,
                     57:     MMU_TYPE_RESERVED,
                     58:     MMU_TYPE_FMT,
                     59:     MMU_TYPE_R3000,
                     60:     MMU_TYPE_R6000,
                     61:     MMU_TYPE_R8000
                     62: };
                     63: 
                     64: struct mips_def_t {
1.1.1.2   root       65:     const char *name;
1.1       root       66:     int32_t CP0_PRid;
                     67:     int32_t CP0_Config0;
                     68:     int32_t CP0_Config1;
                     69:     int32_t CP0_Config2;
                     70:     int32_t CP0_Config3;
                     71:     int32_t CP0_Config6;
                     72:     int32_t CP0_Config7;
1.1.1.4 ! root       73:     target_ulong CP0_LLAddr_rw_bitmask;
        !            74:     int CP0_LLAddr_shift;
1.1       root       75:     int32_t SYNCI_Step;
                     76:     int32_t CCRes;
                     77:     int32_t CP0_Status_rw_bitmask;
                     78:     int32_t CP0_TCStatus_rw_bitmask;
                     79:     int32_t CP0_SRSCtl;
                     80:     int32_t CP1_fcr0;
                     81:     int32_t SEGBITS;
                     82:     int32_t PABITS;
                     83:     int32_t CP0_SRSConf0_rw_bitmask;
                     84:     int32_t CP0_SRSConf0;
                     85:     int32_t CP0_SRSConf1_rw_bitmask;
                     86:     int32_t CP0_SRSConf1;
                     87:     int32_t CP0_SRSConf2_rw_bitmask;
                     88:     int32_t CP0_SRSConf2;
                     89:     int32_t CP0_SRSConf3_rw_bitmask;
                     90:     int32_t CP0_SRSConf3;
                     91:     int32_t CP0_SRSConf4_rw_bitmask;
                     92:     int32_t CP0_SRSConf4;
                     93:     int insn_flags;
                     94:     enum mips_mmu_types mmu_type;
                     95: };
                     96: 
                     97: /*****************************************************************************/
                     98: /* MIPS CPU definitions */
1.1.1.2   root       99: static const mips_def_t mips_defs[] =
1.1       root      100: {
                    101:     {
                    102:         .name = "4Kc",
                    103:         .CP0_PRid = 0x00018000,
                    104:         .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 << CP0C0_MT),
                    105:         .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
1.1.1.2   root      106:                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
                    107:                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
1.1       root      108:         .CP0_Config2 = MIPS_CONFIG2,
                    109:         .CP0_Config3 = MIPS_CONFIG3,
1.1.1.4 ! root      110:         .CP0_LLAddr_rw_bitmask = 0,
        !           111:         .CP0_LLAddr_shift = 4,
1.1       root      112:         .SYNCI_Step = 32,
                    113:         .CCRes = 2,
                    114:         .CP0_Status_rw_bitmask = 0x1278FF17,
                    115:         .SEGBITS = 32,
                    116:         .PABITS = 32,
                    117:         .insn_flags = CPU_MIPS32 | ASE_MIPS16,
                    118:         .mmu_type = MMU_TYPE_R4000,
                    119:     },
                    120:     {
                    121:         .name = "4Km",
                    122:         .CP0_PRid = 0x00018300,
                    123:         /* Config1 implemented, fixed mapping MMU,
                    124:            no virtual icache, uncached coherency. */
                    125:         .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT << CP0C0_MT),
                    126:         .CP0_Config1 = MIPS_CONFIG1 |
1.1.1.2   root      127:                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
                    128:                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
1.1       root      129:         .CP0_Config2 = MIPS_CONFIG2,
                    130:         .CP0_Config3 = MIPS_CONFIG3,
1.1.1.4 ! root      131:         .CP0_LLAddr_rw_bitmask = 0,
        !           132:         .CP0_LLAddr_shift = 4,
1.1       root      133:         .SYNCI_Step = 32,
                    134:         .CCRes = 2,
                    135:         .CP0_Status_rw_bitmask = 0x1258FF17,
                    136:         .SEGBITS = 32,
                    137:         .PABITS = 32,
                    138:         .insn_flags = CPU_MIPS32 | ASE_MIPS16,
                    139:         .mmu_type = MMU_TYPE_FMT,
                    140:     },
                    141:     {
                    142:         .name = "4KEcR1",
                    143:         .CP0_PRid = 0x00018400,
                    144:         .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_R4000 << CP0C0_MT),
                    145:         .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
1.1.1.2   root      146:                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
                    147:                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
1.1       root      148:         .CP0_Config2 = MIPS_CONFIG2,
                    149:         .CP0_Config3 = MIPS_CONFIG3,
1.1.1.4 ! root      150:         .CP0_LLAddr_rw_bitmask = 0,
        !           151:         .CP0_LLAddr_shift = 4,
1.1       root      152:         .SYNCI_Step = 32,
                    153:         .CCRes = 2,
                    154:         .CP0_Status_rw_bitmask = 0x1278FF17,
                    155:         .SEGBITS = 32,
                    156:         .PABITS = 32,
                    157:         .insn_flags = CPU_MIPS32 | ASE_MIPS16,
                    158:         .mmu_type = MMU_TYPE_R4000,
                    159:     },
                    160:     {
                    161:         .name = "4KEmR1",
                    162:         .CP0_PRid = 0x00018500,
                    163:         .CP0_Config0 = MIPS_CONFIG0 | (MMU_TYPE_FMT << CP0C0_MT),
                    164:         .CP0_Config1 = MIPS_CONFIG1 |
1.1.1.2   root      165:                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
                    166:                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
1.1       root      167:         .CP0_Config2 = MIPS_CONFIG2,
                    168:         .CP0_Config3 = MIPS_CONFIG3,
1.1.1.4 ! root      169:         .CP0_LLAddr_rw_bitmask = 0,
        !           170:         .CP0_LLAddr_shift = 4,
1.1       root      171:         .SYNCI_Step = 32,
                    172:         .CCRes = 2,
                    173:         .CP0_Status_rw_bitmask = 0x1258FF17,
                    174:         .SEGBITS = 32,
                    175:         .PABITS = 32,
                    176:         .insn_flags = CPU_MIPS32 | ASE_MIPS16,
                    177:         .mmu_type = MMU_TYPE_FMT,
                    178:     },
                    179:     {
                    180:         .name = "4KEc",
                    181:         .CP0_PRid = 0x00019000,
                    182:         .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
                    183:                     (MMU_TYPE_R4000 << CP0C0_MT),
                    184:         .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
1.1.1.2   root      185:                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
                    186:                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
1.1       root      187:         .CP0_Config2 = MIPS_CONFIG2,
                    188:         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
1.1.1.4 ! root      189:         .CP0_LLAddr_rw_bitmask = 0,
        !           190:         .CP0_LLAddr_shift = 4,
1.1       root      191:         .SYNCI_Step = 32,
                    192:         .CCRes = 2,
                    193:         .CP0_Status_rw_bitmask = 0x1278FF17,
                    194:         .SEGBITS = 32,
                    195:         .PABITS = 32,
                    196:         .insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
                    197:         .mmu_type = MMU_TYPE_R4000,
                    198:     },
                    199:     {
                    200:         .name = "4KEm",
                    201:         .CP0_PRid = 0x00019100,
                    202:         .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
1.1.1.2   root      203:                        (MMU_TYPE_FMT << CP0C0_MT),
1.1       root      204:         .CP0_Config1 = MIPS_CONFIG1 |
1.1.1.2   root      205:                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
                    206:                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
1.1       root      207:         .CP0_Config2 = MIPS_CONFIG2,
                    208:         .CP0_Config3 = MIPS_CONFIG3,
1.1.1.4 ! root      209:         .CP0_LLAddr_rw_bitmask = 0,
        !           210:         .CP0_LLAddr_shift = 4,
1.1       root      211:         .SYNCI_Step = 32,
                    212:         .CCRes = 2,
                    213:         .CP0_Status_rw_bitmask = 0x1258FF17,
                    214:         .SEGBITS = 32,
                    215:         .PABITS = 32,
                    216:         .insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
                    217:         .mmu_type = MMU_TYPE_FMT,
                    218:     },
                    219:     {
                    220:         .name = "24Kc",
                    221:         .CP0_PRid = 0x00019300,
                    222:         .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
1.1.1.2   root      223:                        (MMU_TYPE_R4000 << CP0C0_MT),
1.1       root      224:         .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
1.1.1.2   root      225:                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
                    226:                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
1.1       root      227:         .CP0_Config2 = MIPS_CONFIG2,
                    228:         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
1.1.1.4 ! root      229:         .CP0_LLAddr_rw_bitmask = 0,
        !           230:         .CP0_LLAddr_shift = 4,
1.1       root      231:         .SYNCI_Step = 32,
                    232:         .CCRes = 2,
                    233:         /* No DSP implemented. */
                    234:         .CP0_Status_rw_bitmask = 0x1278FF1F,
                    235:         .SEGBITS = 32,
                    236:         .PABITS = 32,
                    237:         .insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
                    238:         .mmu_type = MMU_TYPE_R4000,
                    239:     },
                    240:     {
                    241:         .name = "24Kf",
                    242:         .CP0_PRid = 0x00019300,
                    243:         .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
                    244:                     (MMU_TYPE_R4000 << CP0C0_MT),
                    245:         .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
1.1.1.2   root      246:                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
                    247:                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
1.1       root      248:         .CP0_Config2 = MIPS_CONFIG2,
                    249:         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
1.1.1.4 ! root      250:         .CP0_LLAddr_rw_bitmask = 0,
        !           251:         .CP0_LLAddr_shift = 4,
1.1       root      252:         .SYNCI_Step = 32,
                    253:         .CCRes = 2,
                    254:         /* No DSP implemented. */
                    255:         .CP0_Status_rw_bitmask = 0x3678FF1F,
                    256:         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
                    257:                     (1 << FCR0_D) | (1 << FCR0_S) | (0x93 << FCR0_PRID),
                    258:         .SEGBITS = 32,
                    259:         .PABITS = 32,
                    260:         .insn_flags = CPU_MIPS32R2 | ASE_MIPS16,
                    261:         .mmu_type = MMU_TYPE_R4000,
                    262:     },
                    263:     {
                    264:         .name = "34Kf",
                    265:         .CP0_PRid = 0x00019500,
                    266:         .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) |
1.1.1.2   root      267:                        (MMU_TYPE_R4000 << CP0C0_MT),
1.1       root      268:         .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
1.1.1.2   root      269:                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
                    270:                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
1.1       root      271:         .CP0_Config2 = MIPS_CONFIG2,
                    272:         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt) | (1 << CP0C3_MT),
1.1.1.4 ! root      273:         .CP0_LLAddr_rw_bitmask = 0,
        !           274:         .CP0_LLAddr_shift = 0,
1.1       root      275:         .SYNCI_Step = 32,
                    276:         .CCRes = 2,
                    277:         /* No DSP implemented. */
                    278:         .CP0_Status_rw_bitmask = 0x3678FF1F,
                    279:         /* No DSP implemented. */
                    280:         .CP0_TCStatus_rw_bitmask = (0 << CP0TCSt_TCU3) | (0 << CP0TCSt_TCU2) |
                    281:                     (1 << CP0TCSt_TCU1) | (1 << CP0TCSt_TCU0) |
                    282:                     (0 << CP0TCSt_TMX) | (1 << CP0TCSt_DT) |
                    283:                     (1 << CP0TCSt_DA) | (1 << CP0TCSt_A) |
                    284:                     (0x3 << CP0TCSt_TKSU) | (1 << CP0TCSt_IXMT) |
                    285:                     (0xff << CP0TCSt_TASID),
                    286:         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_L) | (1 << FCR0_W) |
                    287:                     (1 << FCR0_D) | (1 << FCR0_S) | (0x95 << FCR0_PRID),
                    288:         .CP0_SRSCtl = (0xf << CP0SRSCtl_HSS),
                    289:         .CP0_SRSConf0_rw_bitmask = 0x3fffffff,
                    290:         .CP0_SRSConf0 = (1 << CP0SRSC0_M) | (0x3fe << CP0SRSC0_SRS3) |
                    291:                     (0x3fe << CP0SRSC0_SRS2) | (0x3fe << CP0SRSC0_SRS1),
                    292:         .CP0_SRSConf1_rw_bitmask = 0x3fffffff,
                    293:         .CP0_SRSConf1 = (1 << CP0SRSC1_M) | (0x3fe << CP0SRSC1_SRS6) |
                    294:                     (0x3fe << CP0SRSC1_SRS5) | (0x3fe << CP0SRSC1_SRS4),
                    295:         .CP0_SRSConf2_rw_bitmask = 0x3fffffff,
                    296:         .CP0_SRSConf2 = (1 << CP0SRSC2_M) | (0x3fe << CP0SRSC2_SRS9) |
                    297:                     (0x3fe << CP0SRSC2_SRS8) | (0x3fe << CP0SRSC2_SRS7),
                    298:         .CP0_SRSConf3_rw_bitmask = 0x3fffffff,
                    299:         .CP0_SRSConf3 = (1 << CP0SRSC3_M) | (0x3fe << CP0SRSC3_SRS12) |
                    300:                     (0x3fe << CP0SRSC3_SRS11) | (0x3fe << CP0SRSC3_SRS10),
                    301:         .CP0_SRSConf4_rw_bitmask = 0x3fffffff,
                    302:         .CP0_SRSConf4 = (0x3fe << CP0SRSC4_SRS15) |
                    303:                     (0x3fe << CP0SRSC4_SRS14) | (0x3fe << CP0SRSC4_SRS13),
                    304:         .SEGBITS = 32,
                    305:         .PABITS = 32,
                    306:         .insn_flags = CPU_MIPS32R2 | ASE_MIPS16 | ASE_DSP | ASE_MT,
                    307:         .mmu_type = MMU_TYPE_R4000,
                    308:     },
                    309: #if defined(TARGET_MIPS64)
                    310:     {
                    311:         .name = "R4000",
                    312:         .CP0_PRid = 0x00000400,
                    313:         /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */
                    314:         .CP0_Config0 = (1 << 17) | (0x1 << 9) | (0x1 << 6) | (0x2 << CP0C0_K0),
1.1.1.2   root      315:         /* Note: Config1 is only used internally, the R4000 has only Config0. */
1.1       root      316:         .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
1.1.1.4 ! root      317:         .CP0_LLAddr_rw_bitmask = 0xFFFFFFFF,
        !           318:         .CP0_LLAddr_shift = 4,
1.1       root      319:         .SYNCI_Step = 16,
                    320:         .CCRes = 2,
                    321:         .CP0_Status_rw_bitmask = 0x3678FFFF,
1.1.1.2   root      322:         /* The R4000 has a full 64bit FPU but doesn't use the fcr0 bits. */
1.1       root      323:         .CP1_fcr0 = (0x5 << FCR0_PRID) | (0x0 << FCR0_REV),
                    324:         .SEGBITS = 40,
                    325:         .PABITS = 36,
                    326:         .insn_flags = CPU_MIPS3,
                    327:         .mmu_type = MMU_TYPE_R4000,
                    328:     },
                    329:     {
                    330:         .name = "VR5432",
                    331:         .CP0_PRid = 0x00005400,
                    332:         /* No L2 cache, icache size 8k, dcache size 8k, uncached coherency. */
                    333:         .CP0_Config0 = (1 << 17) | (0x1 << 9) | (0x1 << 6) | (0x2 << CP0C0_K0),
                    334:         .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
1.1.1.4 ! root      335:         .CP0_LLAddr_rw_bitmask = 0xFFFFFFFFL,
        !           336:         .CP0_LLAddr_shift = 4,
1.1       root      337:         .SYNCI_Step = 16,
                    338:         .CCRes = 2,
                    339:         .CP0_Status_rw_bitmask = 0x3678FFFF,
                    340:         /* The VR5432 has a full 64bit FPU but doesn't use the fcr0 bits. */
                    341:         .CP1_fcr0 = (0x54 << FCR0_PRID) | (0x0 << FCR0_REV),
                    342:         .SEGBITS = 40,
                    343:         .PABITS = 32,
                    344:         .insn_flags = CPU_VR54XX,
                    345:         .mmu_type = MMU_TYPE_R4000,
                    346:     },
                    347:     {
                    348:         .name = "5Kc",
                    349:         .CP0_PRid = 0x00018100,
                    350:         .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) |
1.1.1.2   root      351:                        (MMU_TYPE_R4000 << CP0C0_MT),
1.1       root      352:         .CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) |
1.1.1.2   root      353:                        (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
                    354:                        (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
                    355:                        (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
1.1       root      356:         .CP0_Config2 = MIPS_CONFIG2,
                    357:         .CP0_Config3 = MIPS_CONFIG3,
1.1.1.4 ! root      358:         .CP0_LLAddr_rw_bitmask = 0,
        !           359:         .CP0_LLAddr_shift = 4,
1.1       root      360:         .SYNCI_Step = 32,
                    361:         .CCRes = 2,
                    362:         .CP0_Status_rw_bitmask = 0x32F8FFFF,
                    363:         .SEGBITS = 42,
                    364:         .PABITS = 36,
                    365:         .insn_flags = CPU_MIPS64,
                    366:         .mmu_type = MMU_TYPE_R4000,
                    367:     },
                    368:     {
                    369:         .name = "5Kf",
                    370:         .CP0_PRid = 0x00018100,
                    371:         .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) |
1.1.1.2   root      372:                        (MMU_TYPE_R4000 << CP0C0_MT),
1.1       root      373:         .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) |
1.1.1.2   root      374:                        (1 << CP0C1_IS) | (4 << CP0C1_IL) | (1 << CP0C1_IA) |
                    375:                        (1 << CP0C1_DS) | (4 << CP0C1_DL) | (1 << CP0C1_DA) |
                    376:                        (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
1.1       root      377:         .CP0_Config2 = MIPS_CONFIG2,
                    378:         .CP0_Config3 = MIPS_CONFIG3,
1.1.1.4 ! root      379:         .CP0_LLAddr_rw_bitmask = 0,
        !           380:         .CP0_LLAddr_shift = 4,
1.1       root      381:         .SYNCI_Step = 32,
                    382:         .CCRes = 2,
                    383:         .CP0_Status_rw_bitmask = 0x36F8FFFF,
1.1.1.2   root      384:         /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
1.1       root      385:         .CP1_fcr0 = (1 << FCR0_D) | (1 << FCR0_S) |
                    386:                     (0x81 << FCR0_PRID) | (0x0 << FCR0_REV),
                    387:         .SEGBITS = 42,
                    388:         .PABITS = 36,
                    389:         .insn_flags = CPU_MIPS64,
                    390:         .mmu_type = MMU_TYPE_R4000,
                    391:     },
                    392:     {
                    393:         .name = "20Kc",
1.1.1.2   root      394:         /* We emulate a later version of the 20Kc, earlier ones had a broken
1.1       root      395:            WAIT instruction. */
                    396:         .CP0_PRid = 0x000182a0,
                    397:         .CP0_Config0 = MIPS_CONFIG0 | (0x2 << CP0C0_AT) |
                    398:                     (MMU_TYPE_R4000 << CP0C0_MT) | (1 << CP0C0_VI),
                    399:         .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (47 << CP0C1_MMU) |
1.1.1.2   root      400:                        (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
                    401:                        (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
                    402:                        (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
1.1       root      403:         .CP0_Config2 = MIPS_CONFIG2,
                    404:         .CP0_Config3 = MIPS_CONFIG3,
1.1.1.4 ! root      405:         .CP0_LLAddr_rw_bitmask = 0,
        !           406:         .CP0_LLAddr_shift = 0,
1.1       root      407:         .SYNCI_Step = 32,
                    408:         .CCRes = 1,
                    409:         .CP0_Status_rw_bitmask = 0x36FBFFFF,
1.1.1.2   root      410:         /* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */
1.1       root      411:         .CP1_fcr0 = (1 << FCR0_3D) | (1 << FCR0_PS) |
                    412:                     (1 << FCR0_D) | (1 << FCR0_S) |
                    413:                     (0x82 << FCR0_PRID) | (0x0 << FCR0_REV),
                    414:         .SEGBITS = 40,
                    415:         .PABITS = 36,
                    416:         .insn_flags = CPU_MIPS64 | ASE_MIPS3D,
                    417:         .mmu_type = MMU_TYPE_R4000,
                    418:     },
                    419:     {
1.1.1.2   root      420:         /* A generic CPU providing MIPS64 Release 2 features.
1.1       root      421:            FIXME: Eventually this should be replaced by a real CPU model. */
                    422:         .name = "MIPS64R2-generic",
                    423:         .CP0_PRid = 0x00010000,
                    424:         .CP0_Config0 = MIPS_CONFIG0 | (0x1 << CP0C0_AR) | (0x2 << CP0C0_AT) |
1.1.1.2   root      425:                        (MMU_TYPE_R4000 << CP0C0_MT),
1.1       root      426:         .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) |
1.1.1.2   root      427:                        (2 << CP0C1_IS) | (4 << CP0C1_IL) | (3 << CP0C1_IA) |
                    428:                        (2 << CP0C1_DS) | (4 << CP0C1_DL) | (3 << CP0C1_DA) |
                    429:                        (1 << CP0C1_PC) | (1 << CP0C1_WR) | (1 << CP0C1_EP),
1.1       root      430:         .CP0_Config2 = MIPS_CONFIG2,
                    431:         .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
1.1.1.4 ! root      432:         .CP0_LLAddr_rw_bitmask = 0,
        !           433:         .CP0_LLAddr_shift = 0,
1.1       root      434:         .SYNCI_Step = 32,
                    435:         .CCRes = 2,
                    436:         .CP0_Status_rw_bitmask = 0x36FBFFFF,
                    437:         .CP1_fcr0 = (1 << FCR0_F64) | (1 << FCR0_3D) | (1 << FCR0_PS) |
                    438:                     (1 << FCR0_L) | (1 << FCR0_W) | (1 << FCR0_D) |
                    439:                     (1 << FCR0_S) | (0x00 << FCR0_PRID) | (0x0 << FCR0_REV),
                    440:         .SEGBITS = 42,
                    441:         /* The architectural limit is 59, but we have hardcoded 36 bit
                    442:            in some places...
                    443:         .PABITS = 59, */ /* the architectural limit */
                    444:         .PABITS = 36,
                    445:         .insn_flags = CPU_MIPS64R2 | ASE_MIPS3D,
                    446:         .mmu_type = MMU_TYPE_R4000,
                    447:     },
                    448: #endif
                    449: };
                    450: 
1.1.1.2   root      451: static const mips_def_t *cpu_mips_find_by_name (const char *name)
1.1       root      452: {
                    453:     int i;
                    454: 
1.1.1.2   root      455:     for (i = 0; i < ARRAY_SIZE(mips_defs); i++) {
1.1       root      456:         if (strcasecmp(name, mips_defs[i].name) == 0) {
                    457:             return &mips_defs[i];
                    458:         }
                    459:     }
                    460:     return NULL;
                    461: }
                    462: 
                    463: void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
                    464: {
                    465:     int i;
                    466: 
1.1.1.2   root      467:     for (i = 0; i < ARRAY_SIZE(mips_defs); i++) {
1.1       root      468:         (*cpu_fprintf)(f, "MIPS '%s'\n",
                    469:                        mips_defs[i].name);
                    470:     }
                    471: }
                    472: 
                    473: #ifndef CONFIG_USER_ONLY
                    474: static void no_mmu_init (CPUMIPSState *env, const mips_def_t *def)
                    475: {
                    476:     env->tlb->nb_tlb = 1;
                    477:     env->tlb->map_address = &no_mmu_map_address;
                    478: }
                    479: 
                    480: static void fixed_mmu_init (CPUMIPSState *env, const mips_def_t *def)
                    481: {
                    482:     env->tlb->nb_tlb = 1;
                    483:     env->tlb->map_address = &fixed_mmu_map_address;
                    484: }
                    485: 
                    486: static void r4k_mmu_init (CPUMIPSState *env, const mips_def_t *def)
                    487: {
                    488:     env->tlb->nb_tlb = 1 + ((def->CP0_Config1 >> CP0C1_MMU) & 63);
                    489:     env->tlb->map_address = &r4k_map_address;
1.1.1.3   root      490:     env->tlb->helper_tlbwi = r4k_helper_tlbwi;
                    491:     env->tlb->helper_tlbwr = r4k_helper_tlbwr;
                    492:     env->tlb->helper_tlbp = r4k_helper_tlbp;
                    493:     env->tlb->helper_tlbr = r4k_helper_tlbr;
1.1       root      494: }
                    495: 
                    496: static void mmu_init (CPUMIPSState *env, const mips_def_t *def)
                    497: {
                    498:     env->tlb = qemu_mallocz(sizeof(CPUMIPSTLBContext));
                    499: 
                    500:     switch (def->mmu_type) {
                    501:         case MMU_TYPE_NONE:
                    502:             no_mmu_init(env, def);
                    503:             break;
                    504:         case MMU_TYPE_R4000:
                    505:             r4k_mmu_init(env, def);
                    506:             break;
                    507:         case MMU_TYPE_FMT:
                    508:             fixed_mmu_init(env, def);
                    509:             break;
                    510:         case MMU_TYPE_R3000:
                    511:         case MMU_TYPE_R6000:
                    512:         case MMU_TYPE_R8000:
                    513:         default:
                    514:             cpu_abort(env, "MMU type not supported\n");
                    515:     }
                    516: }
                    517: #endif /* CONFIG_USER_ONLY */
                    518: 
                    519: static void fpu_init (CPUMIPSState *env, const mips_def_t *def)
                    520: {
1.1.1.2   root      521:     int i;
1.1       root      522: 
1.1.1.2   root      523:     for (i = 0; i < MIPS_FPU_MAX; i++)
                    524:         env->fpus[i].fcr0 = def->CP1_fcr0;
                    525: 
                    526:     memcpy(&env->active_fpu, &env->fpus[0], sizeof(env->active_fpu));
1.1       root      527: }
                    528: 
                    529: static void mvp_init (CPUMIPSState *env, const mips_def_t *def)
                    530: {
                    531:     env->mvp = qemu_mallocz(sizeof(CPUMIPSMVPContext));
                    532: 
                    533:     /* MVPConf1 implemented, TLB sharable, no gating storage support,
                    534:        programmable cache partitioning implemented, number of allocatable
                    535:        and sharable TLB entries, MVP has allocatable TCs, 2 VPEs
                    536:        implemented, 5 TCs implemented. */
                    537:     env->mvp->CP0_MVPConf0 = (1 << CP0MVPC0_M) | (1 << CP0MVPC0_TLBS) |
                    538:                              (0 << CP0MVPC0_GS) | (1 << CP0MVPC0_PCP) |
                    539: // TODO: actually do 2 VPEs.
                    540: //                             (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) |
                    541: //                             (0x04 << CP0MVPC0_PTC);
                    542:                              (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) |
                    543:                              (0x04 << CP0MVPC0_PTC);
1.1.1.2   root      544: #if !defined(CONFIG_USER_ONLY)
                    545:     /* Usermode has no TLB support */
                    546:     env->mvp->CP0_MVPConf0 |= (env->tlb->nb_tlb << CP0MVPC0_PTLBE);
                    547: #endif
                    548: 
1.1       root      549:     /* Allocatable CP1 have media extensions, allocatable CP1 have FP support,
                    550:        no UDI implemented, no CP2 implemented, 1 CP1 implemented. */
                    551:     env->mvp->CP0_MVPConf1 = (1 << CP0MVPC1_CIM) | (1 << CP0MVPC1_CIF) |
                    552:                              (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) |
                    553:                              (0x1 << CP0MVPC1_PCP1);
                    554: }

unix.superglobalmegacorp.com