Home | History | Annotate | Download | only in target-mips
      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
     18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
     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 {
     65     const char *name;
     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;
     73     target_ulong CP0_LLAddr_rw_bitmask;
     74     int CP0_LLAddr_shift;
     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 */
     99 static const mips_def_t mips_defs[] =
    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) |
    106                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
    107                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
    108         .CP0_Config2 = MIPS_CONFIG2,
    109         .CP0_Config3 = MIPS_CONFIG3,
    110         .CP0_LLAddr_rw_bitmask = 0,
    111         .CP0_LLAddr_shift = 4,
    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 |
    127                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
    128                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
    129         .CP0_Config2 = MIPS_CONFIG2,
    130         .CP0_Config3 = MIPS_CONFIG3,
    131         .CP0_LLAddr_rw_bitmask = 0,
    132         .CP0_LLAddr_shift = 4,
    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) |
    146                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
    147                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
    148         .CP0_Config2 = MIPS_CONFIG2,
    149         .CP0_Config3 = MIPS_CONFIG3,
    150         .CP0_LLAddr_rw_bitmask = 0,
    151         .CP0_LLAddr_shift = 4,
    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 |
    165                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
    166                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
    167         .CP0_Config2 = MIPS_CONFIG2,
    168         .CP0_Config3 = MIPS_CONFIG3,
    169         .CP0_LLAddr_rw_bitmask = 0,
    170         .CP0_LLAddr_shift = 4,
    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) |
    185                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
    186                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
    187         .CP0_Config2 = MIPS_CONFIG2,
    188         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
    189         .CP0_LLAddr_rw_bitmask = 0,
    190         .CP0_LLAddr_shift = 4,
    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) |
    203                        (MMU_TYPE_FMT << CP0C0_MT),
    204         .CP0_Config1 = MIPS_CONFIG1 |
    205                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
    206                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
    207         .CP0_Config2 = MIPS_CONFIG2,
    208         .CP0_Config3 = MIPS_CONFIG3,
    209         .CP0_LLAddr_rw_bitmask = 0,
    210         .CP0_LLAddr_shift = 4,
    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) |
    223                        (MMU_TYPE_R4000 << CP0C0_MT),
    224         .CP0_Config1 = MIPS_CONFIG1 | (15 << CP0C1_MMU) |
    225                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
    226                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
    227         .CP0_Config2 = MIPS_CONFIG2,
    228         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
    229         .CP0_LLAddr_rw_bitmask = 0,
    230         .CP0_LLAddr_shift = 4,
    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) |
    246                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
    247                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
    248         .CP0_Config2 = MIPS_CONFIG2,
    249         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt),
    250         .CP0_LLAddr_rw_bitmask = 0,
    251         .CP0_LLAddr_shift = 4,
    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) |
    267                        (MMU_TYPE_R4000 << CP0C0_MT),
    268         .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (15 << CP0C1_MMU) |
    269                        (0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
    270                        (0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
    271         .CP0_Config2 = MIPS_CONFIG2,
    272         .CP0_Config3 = MIPS_CONFIG3 | (0 << CP0C3_VInt) | (1 << CP0C3_MT),
    273         .CP0_LLAddr_rw_bitmask = 0,
    274         .CP0_LLAddr_shift = 0,
    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),
    315         /* Note: Config1 is only used internally, the R4000 has only Config0. */
    316         .CP0_Config1 = (1 << CP0C1_FP) | (47 << CP0C1_MMU),
    317         .CP0_LLAddr_rw_bitmask = 0xFFFFFFFF,
    318         .CP0_LLAddr_shift = 4,
    319         .SYNCI_Step = 16,
    320         .CCRes = 2,
    321         .CP0_Status_rw_bitmask = 0x3678FFFF,
    322         /* The R4000 has a full 64bit FPU but doesn't use the fcr0 bits. */
    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),
    335         .CP0_LLAddr_rw_bitmask = 0xFFFFFFFFL,
    336         .CP0_LLAddr_shift = 4,
    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) |
    351                        (MMU_TYPE_R4000 << CP0C0_MT),
    352         .CP0_Config1 = MIPS_CONFIG1 | (31 << CP0C1_MMU) |
    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),
    356         .CP0_Config2 = MIPS_CONFIG2,
    357         .CP0_Config3 = MIPS_CONFIG3,
    358         .CP0_LLAddr_rw_bitmask = 0,
    359         .CP0_LLAddr_shift = 4,
    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) |
    372                        (MMU_TYPE_R4000 << CP0C0_MT),
    373         .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (31 << CP0C1_MMU) |
    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),
    377         .CP0_Config2 = MIPS_CONFIG2,
    378         .CP0_Config3 = MIPS_CONFIG3,
    379         .CP0_LLAddr_rw_bitmask = 0,
    380         .CP0_LLAddr_shift = 4,
    381         .SYNCI_Step = 32,
    382         .CCRes = 2,
    383         .CP0_Status_rw_bitmask = 0x36F8FFFF,
    384         /* The 5Kf has F64 / L / W but doesn't use the fcr0 bits. */
    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",
    394         /* We emulate a later version of the 20Kc, earlier ones had a broken
    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) |
    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),
    403         .CP0_Config2 = MIPS_CONFIG2,
    404         .CP0_Config3 = MIPS_CONFIG3,
    405         .CP0_LLAddr_rw_bitmask = 0,
    406         .CP0_LLAddr_shift = 0,
    407         .SYNCI_Step = 32,
    408         .CCRes = 1,
    409         .CP0_Status_rw_bitmask = 0x36FBFFFF,
    410         /* The 20Kc has F64 / L / W but doesn't use the fcr0 bits. */
    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     {
    420         /* A generic CPU providing MIPS64 Release 2 features.
    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) |
    425                        (MMU_TYPE_R4000 << CP0C0_MT),
    426         .CP0_Config1 = MIPS_CONFIG1 | (1 << CP0C1_FP) | (63 << CP0C1_MMU) |
    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),
    430         .CP0_Config2 = MIPS_CONFIG2,
    431         .CP0_Config3 = MIPS_CONFIG3 | (1 << CP0C3_LPA),
    432         .CP0_LLAddr_rw_bitmask = 0,
    433         .CP0_LLAddr_shift = 0,
    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 
    451 static const mips_def_t *cpu_mips_find_by_name (const char *name)
    452 {
    453     int i;
    454 
    455     for (i = 0; i < ARRAY_SIZE(mips_defs); i++) {
    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 
    467     for (i = 0; i < ARRAY_SIZE(mips_defs); i++) {
    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;
    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;
    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 {
    521     int i;
    522 
    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));
    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);
    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 
    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 }
    555