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