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