|
|
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 ! 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 unsigned 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 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 unsigned char *name) ! 421: { ! 422: int i; ! 423: ! 424: for (i = 0; i < sizeof(mips_defs) / sizeof(mips_defs[0]); 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 < sizeof(mips_defs) / sizeof(mips_defs[0]); 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: env->fpu = qemu_mallocz(sizeof(CPUMIPSFPUContext)); ! 493: ! 494: env->fpu->fcr0 = def->CP1_fcr0; ! 495: #ifdef CONFIG_USER_ONLY ! 496: if (env->CP0_Config1 & (1 << CP0C1_FP)) ! 497: env->hflags |= MIPS_HFLAG_FPU; ! 498: if (env->fpu->fcr0 & (1 << FCR0_F64)) ! 499: env->hflags |= MIPS_HFLAG_F64; ! 500: #endif ! 501: } ! 502: ! 503: static void mvp_init (CPUMIPSState *env, const mips_def_t *def) ! 504: { ! 505: env->mvp = qemu_mallocz(sizeof(CPUMIPSMVPContext)); ! 506: ! 507: /* MVPConf1 implemented, TLB sharable, no gating storage support, ! 508: programmable cache partitioning implemented, number of allocatable ! 509: and sharable TLB entries, MVP has allocatable TCs, 2 VPEs ! 510: implemented, 5 TCs implemented. */ ! 511: env->mvp->CP0_MVPConf0 = (1 << CP0MVPC0_M) | (1 << CP0MVPC0_TLBS) | ! 512: (0 << CP0MVPC0_GS) | (1 << CP0MVPC0_PCP) | ! 513: #ifndef CONFIG_USER_ONLY ! 514: /* Usermode has no TLB support */ ! 515: (env->tlb->nb_tlb << CP0MVPC0_PTLBE) | ! 516: #endif ! 517: // TODO: actually do 2 VPEs. ! 518: // (1 << CP0MVPC0_TCA) | (0x1 << CP0MVPC0_PVPE) | ! 519: // (0x04 << CP0MVPC0_PTC); ! 520: (1 << CP0MVPC0_TCA) | (0x0 << CP0MVPC0_PVPE) | ! 521: (0x04 << CP0MVPC0_PTC); ! 522: /* Allocatable CP1 have media extensions, allocatable CP1 have FP support, ! 523: no UDI implemented, no CP2 implemented, 1 CP1 implemented. */ ! 524: env->mvp->CP0_MVPConf1 = (1 << CP0MVPC1_CIM) | (1 << CP0MVPC1_CIF) | ! 525: (0x0 << CP0MVPC1_PCX) | (0x0 << CP0MVPC1_PCP2) | ! 526: (0x1 << CP0MVPC1_PCP1); ! 527: } ! 528: ! 529: static int cpu_mips_register (CPUMIPSState *env, const mips_def_t *def) ! 530: { ! 531: env->CP0_PRid = def->CP0_PRid; ! 532: env->CP0_Config0 = def->CP0_Config0; ! 533: #ifdef TARGET_WORDS_BIGENDIAN ! 534: env->CP0_Config0 |= (1 << CP0C0_BE); ! 535: #endif ! 536: env->CP0_Config1 = def->CP0_Config1; ! 537: env->CP0_Config2 = def->CP0_Config2; ! 538: env->CP0_Config3 = def->CP0_Config3; ! 539: env->CP0_Config6 = def->CP0_Config6; ! 540: env->CP0_Config7 = def->CP0_Config7; ! 541: env->SYNCI_Step = def->SYNCI_Step; ! 542: env->CCRes = def->CCRes; ! 543: env->CP0_Status_rw_bitmask = def->CP0_Status_rw_bitmask; ! 544: env->CP0_TCStatus_rw_bitmask = def->CP0_TCStatus_rw_bitmask; ! 545: env->CP0_SRSCtl = def->CP0_SRSCtl; ! 546: env->SEGBITS = def->SEGBITS; ! 547: env->SEGMask = (target_ulong)((1ULL << def->SEGBITS) - 1); ! 548: #if defined(TARGET_MIPS64) ! 549: if (def->insn_flags & ISA_MIPS3) { ! 550: env->hflags |= MIPS_HFLAG_64; ! 551: env->SEGMask |= 3ULL << 62; ! 552: } ! 553: #endif ! 554: env->PABITS = def->PABITS; ! 555: env->PAMask = (target_ulong)((1ULL << def->PABITS) - 1); ! 556: env->CP0_SRSConf0_rw_bitmask = def->CP0_SRSConf0_rw_bitmask; ! 557: env->CP0_SRSConf0 = def->CP0_SRSConf0; ! 558: env->CP0_SRSConf1_rw_bitmask = def->CP0_SRSConf1_rw_bitmask; ! 559: env->CP0_SRSConf1 = def->CP0_SRSConf1; ! 560: env->CP0_SRSConf2_rw_bitmask = def->CP0_SRSConf2_rw_bitmask; ! 561: env->CP0_SRSConf2 = def->CP0_SRSConf2; ! 562: env->CP0_SRSConf3_rw_bitmask = def->CP0_SRSConf3_rw_bitmask; ! 563: env->CP0_SRSConf3 = def->CP0_SRSConf3; ! 564: env->CP0_SRSConf4_rw_bitmask = def->CP0_SRSConf4_rw_bitmask; ! 565: env->CP0_SRSConf4 = def->CP0_SRSConf4; ! 566: env->insn_flags = def->insn_flags; ! 567: ! 568: #ifndef CONFIG_USER_ONLY ! 569: mmu_init(env, def); ! 570: #endif ! 571: fpu_init(env, def); ! 572: mvp_init(env, def); ! 573: return 0; ! 574: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.