| 1 | /* |
| 2 | * QEMU ARM TCG-only CPUs. |
| 3 | * |
| 4 | * Copyright (c) 2012 SUSE LINUX Products GmbH |
| 5 | * |
| 6 | * This code is licensed under the GNU GPL v2 or later. |
| 7 | * |
| 8 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 9 | */ |
| 10 | |
| 11 | #include "qemu/osdep.h" |
| 12 | #include "qemu/units.h" |
| 13 | #include "cpu.h" |
| 14 | #include "accel/tcg/cpu-ops.h" |
| 15 | #include "internals.h" |
| 16 | #if !defined(CONFIG_USER_ONLY) |
| 17 | #include "hw/core/boards.h" |
| 18 | #endif |
| 19 | #include "cpregs.h" |
| 20 | |
| 21 | |
| 22 | static void arm926_initfn(Object *obj) |
| 23 | { |
| 24 | ARMCPU *cpu = ARM_CPU(obj); |
| 25 | |
| 26 | cpu->dtb_compatible = "arm,arm926"; |
| 27 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 28 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 29 | set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); |
| 30 | cpu->midr = 0x41069265; |
| 31 | cpu->reset_fpsid = 0x41011090; |
| 32 | cpu->ctr = 0x1dd20d2; |
| 33 | cpu->reset_sctlr = 0x00050078; |
| 34 | |
| 35 | /* |
| 36 | * ARMv5 does not have the ID_ISAR registers, but we can still |
| 37 | * set the field to indicate Jazelle support within QEMU. |
| 38 | */ |
| 39 | FIELD_DP32_IDREG(&cpu->isar, ID_ISAR1, JAZELLE, 1); |
| 40 | /* |
| 41 | * Similarly, we need to set MVFR0 fields to enable vfp and short vector |
| 42 | * support even though ARMv5 doesn't have this register. |
| 43 | */ |
| 44 | cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1); |
| 45 | cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1); |
| 46 | cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1); |
| 47 | } |
| 48 | |
| 49 | static void arm946_initfn(Object *obj) |
| 50 | { |
| 51 | ARMCPU *cpu = ARM_CPU(obj); |
| 52 | |
| 53 | cpu->dtb_compatible = "arm,arm946"; |
| 54 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 55 | set_feature(&cpu->env, ARM_FEATURE_PMSA); |
| 56 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 57 | cpu->midr = 0x41059461; |
| 58 | cpu->ctr = 0x0f004006; |
| 59 | cpu->reset_sctlr = 0x00000078; |
| 60 | } |
| 61 | |
| 62 | static void arm1026_initfn(Object *obj) |
| 63 | { |
| 64 | ARMCPU *cpu = ARM_CPU(obj); |
| 65 | |
| 66 | cpu->dtb_compatible = "arm,arm1026"; |
| 67 | set_feature(&cpu->env, ARM_FEATURE_V5); |
| 68 | set_feature(&cpu->env, ARM_FEATURE_AUXCR); |
| 69 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 70 | set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN); |
| 71 | cpu->midr = 0x4106a262; |
| 72 | cpu->reset_fpsid = 0x410110a0; |
| 73 | cpu->ctr = 0x1dd20d2; |
| 74 | cpu->reset_sctlr = 0x00050078; |
| 75 | cpu->reset_auxcr = 1; |
| 76 | |
| 77 | /* |
| 78 | * ARMv5 does not have the ID_ISAR registers, but we can still |
| 79 | * set the field to indicate Jazelle support within QEMU. |
| 80 | */ |
| 81 | FIELD_DP32_IDREG(&cpu->isar, ID_ISAR1, JAZELLE, 1); |
| 82 | /* |
| 83 | * Similarly, we need to set MVFR0 fields to enable vfp and short vector |
| 84 | * support even though ARMv5 doesn't have this register. |
| 85 | */ |
| 86 | cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1); |
| 87 | cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1); |
| 88 | cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1); |
| 89 | |
| 90 | { |
| 91 | /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */ |
| 92 | ARMCPRegInfo ifar = { |
| 93 | .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1, |
| 94 | .access = PL1_RW, |
| 95 | .fieldoffset = offsetof(CPUARMState, cp15.ifar_ns), |
| 96 | .resetvalue = 0 |
| 97 | }; |
| 98 | define_one_arm_cp_reg(cpu, &ifar); |
| 99 | } |
| 100 | } |
| 101 | |
| 102 | static void arm1136_r2_initfn(Object *obj) |
| 103 | { |
| 104 | ARMCPU *cpu = ARM_CPU(obj); |
| 105 | ARMISARegisters *isar = &cpu->isar; |
| 106 | /* |
| 107 | * What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an |
| 108 | * older core than plain "arm1136". In particular this does not |
| 109 | * have the v6K features. |
| 110 | * These ID register values are correct for 1136 but may be wrong |
| 111 | * for 1136_r2 (in particular r0p2 does not actually implement most |
| 112 | * of the ID registers). |
| 113 | */ |
| 114 | |
| 115 | cpu->dtb_compatible = "arm,arm1136"; |
| 116 | set_feature(&cpu->env, ARM_FEATURE_V6); |
| 117 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 118 | set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); |
| 119 | set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); |
| 120 | cpu->midr = 0x4107b362; |
| 121 | cpu->reset_fpsid = 0x410120b4; |
| 122 | cpu->isar.mvfr0 = 0x11111111; |
| 123 | cpu->isar.mvfr1 = 0x00000000; |
| 124 | cpu->ctr = 0x1dd20d2; |
| 125 | cpu->reset_sctlr = 0x00050078; |
| 126 | SET_IDREG(isar, ID_PFR0, 0x111); |
| 127 | SET_IDREG(isar, ID_PFR1, 0x1); |
| 128 | SET_IDREG(isar, ID_DFR0, 0x2); |
| 129 | SET_IDREG(isar, ID_AFR0, 0x3); |
| 130 | SET_IDREG(isar, ID_MMFR0, 0x01130003); |
| 131 | SET_IDREG(isar, ID_MMFR1, 0x10030302); |
| 132 | SET_IDREG(isar, ID_MMFR2, 0x01222110); |
| 133 | SET_IDREG(isar, ID_ISAR0, 0x00140011); |
| 134 | SET_IDREG(isar, ID_ISAR1, 0x12002111); |
| 135 | SET_IDREG(isar, ID_ISAR2, 0x11231111); |
| 136 | SET_IDREG(isar, ID_ISAR3, 0x01102131); |
| 137 | SET_IDREG(isar, ID_ISAR4, 0x141); |
| 138 | cpu->reset_auxcr = 7; |
| 139 | } |
| 140 | |
| 141 | static void arm1136_initfn(Object *obj) |
| 142 | { |
| 143 | ARMCPU *cpu = ARM_CPU(obj); |
| 144 | ARMISARegisters *isar = &cpu->isar; |
| 145 | |
| 146 | cpu->dtb_compatible = "arm,arm1136"; |
| 147 | set_feature(&cpu->env, ARM_FEATURE_V6K); |
| 148 | set_feature(&cpu->env, ARM_FEATURE_V6); |
| 149 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 150 | set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); |
| 151 | set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); |
| 152 | cpu->midr = 0x4117b363; |
| 153 | cpu->reset_fpsid = 0x410120b4; |
| 154 | cpu->isar.mvfr0 = 0x11111111; |
| 155 | cpu->isar.mvfr1 = 0x00000000; |
| 156 | cpu->ctr = 0x1dd20d2; |
| 157 | cpu->reset_sctlr = 0x00050078; |
| 158 | SET_IDREG(isar, ID_PFR0, 0x111); |
| 159 | SET_IDREG(isar, ID_PFR1, 0x1); |
| 160 | SET_IDREG(isar, ID_DFR0, 0x2); |
| 161 | SET_IDREG(isar, ID_AFR0, 0x3); |
| 162 | SET_IDREG(isar, ID_MMFR0, 0x01130003); |
| 163 | SET_IDREG(isar, ID_MMFR1, 0x10030302); |
| 164 | SET_IDREG(isar, ID_MMFR2, 0x01222110); |
| 165 | SET_IDREG(isar, ID_ISAR0, 0x00140011); |
| 166 | SET_IDREG(isar, ID_ISAR1, 0x12002111); |
| 167 | SET_IDREG(isar, ID_ISAR2, 0x11231111); |
| 168 | SET_IDREG(isar, ID_ISAR3, 0x01102131); |
| 169 | SET_IDREG(isar, ID_ISAR4, 0x141); |
| 170 | cpu->reset_auxcr = 7; |
| 171 | } |
| 172 | |
| 173 | static void arm1176_initfn(Object *obj) |
| 174 | { |
| 175 | ARMCPU *cpu = ARM_CPU(obj); |
| 176 | ARMISARegisters *isar = &cpu->isar; |
| 177 | |
| 178 | cpu->dtb_compatible = "arm,arm1176"; |
| 179 | set_feature(&cpu->env, ARM_FEATURE_V6K); |
| 180 | set_feature(&cpu->env, ARM_FEATURE_VAPA); |
| 181 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 182 | set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG); |
| 183 | set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS); |
| 184 | set_feature(&cpu->env, ARM_FEATURE_EL3); |
| 185 | cpu->midr = 0x410fb767; |
| 186 | cpu->reset_fpsid = 0x410120b5; |
| 187 | cpu->isar.mvfr0 = 0x11111111; |
| 188 | cpu->isar.mvfr1 = 0x00000000; |
| 189 | cpu->ctr = 0x1dd20d2; |
| 190 | cpu->reset_sctlr = 0x00050078; |
| 191 | SET_IDREG(isar, ID_PFR0, 0x111); |
| 192 | SET_IDREG(isar, ID_PFR1, 0x11); |
| 193 | SET_IDREG(isar, ID_DFR0, 0x33); |
| 194 | SET_IDREG(isar, ID_AFR0, 0); |
| 195 | SET_IDREG(isar, ID_MMFR0, 0x01130003); |
| 196 | SET_IDREG(isar, ID_MMFR1, 0x10030302); |
| 197 | SET_IDREG(isar, ID_MMFR2, 0x01222100); |
| 198 | SET_IDREG(isar, ID_ISAR0, 0x0140011); |
| 199 | SET_IDREG(isar, ID_ISAR1, 0x12002111); |
| 200 | SET_IDREG(isar, ID_ISAR2, 0x11231121); |
| 201 | SET_IDREG(isar, ID_ISAR3, 0x01102131); |
| 202 | SET_IDREG(isar, ID_ISAR4, 0x01141); |
| 203 | cpu->reset_auxcr = 7; |
| 204 | } |
| 205 | |
| 206 | static void arm11mpcore_initfn(Object *obj) |
| 207 | { |
| 208 | ARMCPU *cpu = ARM_CPU(obj); |
| 209 | ARMISARegisters *isar = &cpu->isar; |
| 210 | |
| 211 | cpu->dtb_compatible = "arm,arm11mpcore"; |
| 212 | set_feature(&cpu->env, ARM_FEATURE_V6K); |
| 213 | set_feature(&cpu->env, ARM_FEATURE_VAPA); |
| 214 | set_feature(&cpu->env, ARM_FEATURE_MPIDR); |
| 215 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 216 | cpu->midr = 0x410fb022; |
| 217 | cpu->reset_fpsid = 0x410120b4; |
| 218 | cpu->isar.mvfr0 = 0x11111111; |
| 219 | cpu->isar.mvfr1 = 0x00000000; |
| 220 | cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */ |
| 221 | SET_IDREG(isar, ID_PFR0, 0x111); |
| 222 | SET_IDREG(isar, ID_PFR1, 0x1); |
| 223 | SET_IDREG(isar, ID_DFR0, 0); |
| 224 | SET_IDREG(isar, ID_AFR0, 0x2); |
| 225 | SET_IDREG(isar, ID_MMFR0, 0x01100103); |
| 226 | SET_IDREG(isar, ID_MMFR1, 0x10020302); |
| 227 | SET_IDREG(isar, ID_MMFR2, 0x01222000); |
| 228 | SET_IDREG(isar, ID_ISAR0, 0x00100011); |
| 229 | SET_IDREG(isar, ID_ISAR1, 0x12002111); |
| 230 | SET_IDREG(isar, ID_ISAR2, 0x11221011); |
| 231 | SET_IDREG(isar, ID_ISAR3, 0x01102131); |
| 232 | SET_IDREG(isar, ID_ISAR4, 0x141); |
| 233 | cpu->reset_auxcr = 1; |
| 234 | } |
| 235 | |
| 236 | static const ARMCPRegInfo cortexa8_cp_reginfo[] = { |
| 237 | { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0, |
| 238 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 239 | { .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2, |
| 240 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 241 | }; |
| 242 | |
| 243 | static void cortex_a8_initfn(Object *obj) |
| 244 | { |
| 245 | ARMCPU *cpu = ARM_CPU(obj); |
| 246 | ARMISARegisters *isar = &cpu->isar; |
| 247 | |
| 248 | cpu->dtb_compatible = "arm,cortex-a8"; |
| 249 | set_feature(&cpu->env, ARM_FEATURE_V7); |
| 250 | set_feature(&cpu->env, ARM_FEATURE_NEON); |
| 251 | /* |
| 252 | * The Cortex-A8 doesn't have CPACR.ASEDIS and HCPTR.TASE, |
| 253 | * so don't set ARM_FEATURE_NEON_TRAPS. |
| 254 | */ |
| 255 | set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); |
| 256 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 257 | set_feature(&cpu->env, ARM_FEATURE_EL3); |
| 258 | set_feature(&cpu->env, ARM_FEATURE_PMU); |
| 259 | cpu->midr = 0x410fc080; |
| 260 | cpu->reset_fpsid = 0x410330c0; |
| 261 | cpu->isar.mvfr0 = 0x11110222; |
| 262 | cpu->isar.mvfr1 = 0x00011111; |
| 263 | cpu->ctr = 0x82048004; |
| 264 | cpu->reset_sctlr = 0x00c50078; |
| 265 | SET_IDREG(isar, ID_PFR0, 0x1031); |
| 266 | SET_IDREG(isar, ID_PFR1, 0x11); |
| 267 | SET_IDREG(isar, ID_DFR0, 0x400); |
| 268 | SET_IDREG(isar, ID_AFR0, 0); |
| 269 | SET_IDREG(isar, ID_MMFR0, 0x31100003); |
| 270 | SET_IDREG(isar, ID_MMFR1, 0x20000000); |
| 271 | SET_IDREG(isar, ID_MMFR2, 0x01202000); |
| 272 | SET_IDREG(isar, ID_MMFR3, 0x11); |
| 273 | SET_IDREG(isar, ID_ISAR0, 0x00101111); |
| 274 | SET_IDREG(isar, ID_ISAR1, 0x12112111); |
| 275 | SET_IDREG(isar, ID_ISAR2, 0x21232031); |
| 276 | SET_IDREG(isar, ID_ISAR3, 0x11112131); |
| 277 | SET_IDREG(isar, ID_ISAR4, 0x00111142); |
| 278 | cpu->isar.dbgdidr = 0x15141000; |
| 279 | SET_IDREG(isar, CLIDR, (1 << 27) | (2 << 24) | 3); |
| 280 | cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */ |
| 281 | cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */ |
| 282 | cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */ |
| 283 | cpu->reset_auxcr = 2; |
| 284 | cpu->isar.reset_pmcr_el0 = 0x41002000; |
| 285 | define_arm_cp_regs(cpu, cortexa8_cp_reginfo); |
| 286 | } |
| 287 | |
| 288 | static const ARMCPRegInfo cortexa9_cp_reginfo[] = { |
| 289 | /* |
| 290 | * power_control should be set to maximum latency. Again, |
| 291 | * default to 0 and set by private hook |
| 292 | */ |
| 293 | { .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0, |
| 294 | .access = PL1_RW, .resetvalue = 0, |
| 295 | .fieldoffset = offsetof(CPUARMState, cp15.c15_power_control) }, |
| 296 | { .name = "A9_DIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 1, |
| 297 | .access = PL1_RW, .resetvalue = 0, |
| 298 | .fieldoffset = offsetof(CPUARMState, cp15.c15_diagnostic) }, |
| 299 | { .name = "A9_PWRDIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 2, |
| 300 | .access = PL1_RW, .resetvalue = 0, |
| 301 | .fieldoffset = offsetof(CPUARMState, cp15.c15_power_diagnostic) }, |
| 302 | { .name = "NEONBUSY", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0, |
| 303 | .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, |
| 304 | /* TLB lockdown control */ |
| 305 | { .name = "TLB_LOCKR", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 2, |
| 306 | .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP }, |
| 307 | { .name = "TLB_LOCKW", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 4, |
| 308 | .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP }, |
| 309 | { .name = "TLB_VA", .cp = 15, .crn = 15, .crm = 5, .opc1 = 5, .opc2 = 2, |
| 310 | .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, |
| 311 | { .name = "TLB_PA", .cp = 15, .crn = 15, .crm = 6, .opc1 = 5, .opc2 = 2, |
| 312 | .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, |
| 313 | { .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2, |
| 314 | .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST }, |
| 315 | }; |
| 316 | |
| 317 | static void cortex_a9_initfn(Object *obj) |
| 318 | { |
| 319 | ARMCPU *cpu = ARM_CPU(obj); |
| 320 | ARMISARegisters *isar = &cpu->isar; |
| 321 | |
| 322 | cpu->dtb_compatible = "arm,cortex-a9"; |
| 323 | set_feature(&cpu->env, ARM_FEATURE_V7); |
| 324 | set_feature(&cpu->env, ARM_FEATURE_NEON); |
| 325 | set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); |
| 326 | set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); |
| 327 | set_feature(&cpu->env, ARM_FEATURE_EL3); |
| 328 | set_feature(&cpu->env, ARM_FEATURE_PMU); |
| 329 | /* |
| 330 | * Note that A9 supports the MP extensions even for |
| 331 | * A9UP and single-core A9MP (which are both different |
| 332 | * and valid configurations; we don't model A9UP). |
| 333 | */ |
| 334 | set_feature(&cpu->env, ARM_FEATURE_V7MP); |
| 335 | set_feature(&cpu->env, ARM_FEATURE_CBAR); |
| 336 | set_feature(&cpu->env, ARM_FEATURE_D32DIS); |
| 337 | cpu->midr = 0x410fc090; |
| 338 | cpu->reset_fpsid = 0x41033090; |
| 339 | cpu->isar.mvfr0 = 0x11110222; |
| 340 | cpu->isar.mvfr1 = 0x01111111; |
| 341 | cpu->ctr = 0x80038003; |
| 342 | cpu->reset_sctlr = 0x00c50078; |
| 343 | SET_IDREG(isar, ID_PFR0, 0x1031); |
| 344 | SET_IDREG(isar, ID_PFR1, 0x11); |
| 345 | SET_IDREG(isar, ID_DFR0, 0x000); |
| 346 | SET_IDREG(isar, ID_AFR0, 0); |
| 347 | SET_IDREG(isar, ID_MMFR0, 0x00100103); |
| 348 | SET_IDREG(isar, ID_MMFR1, 0x20000000); |
| 349 | SET_IDREG(isar, ID_MMFR2, 0x01230000); |
| 350 | SET_IDREG(isar, ID_MMFR3, 0x00002111); |
| 351 | SET_IDREG(isar, ID_ISAR0, 0x00101111); |
| 352 | SET_IDREG(isar, ID_ISAR1, 0x13112111); |
| 353 | SET_IDREG(isar, ID_ISAR2, 0x21232041); |
| 354 | SET_IDREG(isar, ID_ISAR3, 0x11112131); |
| 355 | SET_IDREG(isar, ID_ISAR4, 0x00111142); |
| 356 | cpu->isar.dbgdidr = 0x35141000; |
| 357 | SET_IDREG(isar, CLIDR, (1 << 27) | (1 << 24) | 3); |
| 358 | cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */ |
| 359 | cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */ |
| 360 | cpu->isar.reset_pmcr_el0 = 0x41093000; |
| 361 | define_arm_cp_regs(cpu, cortexa9_cp_reginfo); |
| 362 | } |
| 363 | |
| 364 | #ifndef CONFIG_USER_ONLY |
| 365 | static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri) |
| 366 | { |
| 367 | MachineState *ms = MACHINE(qdev_get_machine()); |
| 368 | |
| 369 | /* |
| 370 | * Linux wants the number of processors from here. |
| 371 | * Might as well set the interrupt-controller bit too. |
| 372 | */ |
| 373 | return ((ms->smp.cpus - 1) << 24) | (1 << 23); |
| 374 | } |
| 375 | #endif |
| 376 | |
| 377 | static const ARMCPRegInfo cortexa15_cp_reginfo[] = { |
| 378 | #ifndef CONFIG_USER_ONLY |
| 379 | { .name = "L2CTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2, |
| 380 | .access = PL1_RW, .resetvalue = 0, .readfn = a15_l2ctlr_read, |
| 381 | .writefn = arm_cp_write_ignore, }, |
| 382 | #endif |
| 383 | { .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3, |
| 384 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 385 | }; |
| 386 | |
| 387 | static void cortex_a7_initfn(Object *obj) |
| 388 | { |
| 389 | ARMCPU *cpu = ARM_CPU(obj); |
| 390 | ARMISARegisters *isar = &cpu->isar; |
| 391 | |
| 392 | cpu->dtb_compatible = "arm,cortex-a7"; |
| 393 | set_feature(&cpu->env, ARM_FEATURE_V7VE); |
| 394 | set_feature(&cpu->env, ARM_FEATURE_NEON); |
| 395 | set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); |
| 396 | set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); |
| 397 | set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); |
| 398 | set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); |
| 399 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 400 | set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); |
| 401 | set_feature(&cpu->env, ARM_FEATURE_EL2); |
| 402 | set_feature(&cpu->env, ARM_FEATURE_EL3); |
| 403 | set_feature(&cpu->env, ARM_FEATURE_PMU); |
| 404 | set_feature(&cpu->env, ARM_FEATURE_D32DIS); |
| 405 | cpu->midr = 0x410fc075; |
| 406 | cpu->reset_fpsid = 0x41023075; |
| 407 | cpu->isar.mvfr0 = 0x10110222; |
| 408 | cpu->isar.mvfr1 = 0x11111111; |
| 409 | cpu->ctr = 0x84448003; |
| 410 | cpu->reset_sctlr = 0x00c50078; |
| 411 | SET_IDREG(isar, ID_PFR0, 0x00001131); |
| 412 | SET_IDREG(isar, ID_PFR1, 0x00011011); |
| 413 | SET_IDREG(isar, ID_DFR0, 0x02010555); |
| 414 | SET_IDREG(isar, ID_AFR0, 0x00000000); |
| 415 | SET_IDREG(isar, ID_MMFR0, 0x10101105); |
| 416 | SET_IDREG(isar, ID_MMFR1, 0x40000000); |
| 417 | SET_IDREG(isar, ID_MMFR2, 0x01240000); |
| 418 | SET_IDREG(isar, ID_MMFR3, 0x02102211); |
| 419 | /* |
| 420 | * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but |
| 421 | * table 4-41 gives 0x02101110, which includes the arm div insns. |
| 422 | */ |
| 423 | SET_IDREG(isar, ID_ISAR0, 0x02101110); |
| 424 | SET_IDREG(isar, ID_ISAR1, 0x13112111); |
| 425 | SET_IDREG(isar, ID_ISAR2, 0x21232041); |
| 426 | SET_IDREG(isar, ID_ISAR3, 0x11112131); |
| 427 | SET_IDREG(isar, ID_ISAR4, 0x10011142); |
| 428 | cpu->isar.dbgdidr = 0x3515f005; |
| 429 | cpu->isar.dbgdevid = 0x01110f13; |
| 430 | cpu->isar.dbgdevid1 = 0x1; |
| 431 | SET_IDREG(isar, CLIDR, 0x0a200023); |
| 432 | cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ |
| 433 | cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ |
| 434 | cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ |
| 435 | cpu->isar.reset_pmcr_el0 = 0x41072000; |
| 436 | define_arm_cp_regs(cpu, cortexa15_cp_reginfo); /* Same as A15 */ |
| 437 | } |
| 438 | |
| 439 | static void cortex_a15_initfn(Object *obj) |
| 440 | { |
| 441 | ARMCPU *cpu = ARM_CPU(obj); |
| 442 | ARMISARegisters *isar = &cpu->isar; |
| 443 | |
| 444 | cpu->dtb_compatible = "arm,cortex-a15"; |
| 445 | set_feature(&cpu->env, ARM_FEATURE_V7VE); |
| 446 | set_feature(&cpu->env, ARM_FEATURE_NEON); |
| 447 | set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); |
| 448 | set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); |
| 449 | set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); |
| 450 | set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); |
| 451 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 452 | set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); |
| 453 | set_feature(&cpu->env, ARM_FEATURE_EL2); |
| 454 | set_feature(&cpu->env, ARM_FEATURE_EL3); |
| 455 | set_feature(&cpu->env, ARM_FEATURE_PMU); |
| 456 | /* r4p0 cpu, not requiring expensive tlb flush errata */ |
| 457 | cpu->midr = 0x414fc0f0; |
| 458 | cpu->revidr = 0x0; |
| 459 | cpu->reset_fpsid = 0x410430f0; |
| 460 | cpu->isar.mvfr0 = 0x10110222; |
| 461 | cpu->isar.mvfr1 = 0x11111111; |
| 462 | cpu->ctr = 0x8444c004; |
| 463 | cpu->reset_sctlr = 0x00c50078; |
| 464 | SET_IDREG(isar, ID_PFR0, 0x00001131); |
| 465 | SET_IDREG(isar, ID_PFR1, 0x00011011); |
| 466 | SET_IDREG(isar, ID_DFR0, 0x02010555); |
| 467 | SET_IDREG(isar, ID_AFR0, 0x00000000); |
| 468 | SET_IDREG(isar, ID_MMFR0, 0x10201105); |
| 469 | SET_IDREG(isar, ID_MMFR1, 0x20000000); |
| 470 | SET_IDREG(isar, ID_MMFR2, 0x01240000); |
| 471 | SET_IDREG(isar, ID_MMFR3, 0x02102211); |
| 472 | SET_IDREG(isar, ID_ISAR0, 0x02101110); |
| 473 | SET_IDREG(isar, ID_ISAR1, 0x13112111); |
| 474 | SET_IDREG(isar, ID_ISAR2, 0x21232041); |
| 475 | SET_IDREG(isar, ID_ISAR3, 0x11112131); |
| 476 | SET_IDREG(isar, ID_ISAR4, 0x10011142); |
| 477 | cpu->isar.dbgdidr = 0x3515f021; |
| 478 | cpu->isar.dbgdevid = 0x01110f13; |
| 479 | cpu->isar.dbgdevid1 = 0x0; |
| 480 | SET_IDREG(isar, CLIDR, 0x0a200023); |
| 481 | cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ |
| 482 | cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ |
| 483 | cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ |
| 484 | cpu->isar.reset_pmcr_el0 = 0x410F3000; |
| 485 | define_arm_cp_regs(cpu, cortexa15_cp_reginfo); |
| 486 | } |
| 487 | |
| 488 | static const ARMCPRegInfo cortexr5_cp_reginfo[] = { |
| 489 | /* Dummy the TCM region regs for the moment */ |
| 490 | { .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, |
| 491 | .access = PL1_RW, .type = ARM_CP_CONST }, |
| 492 | { .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, |
| 493 | .access = PL1_RW, .type = ARM_CP_CONST }, |
| 494 | { .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5, |
| 495 | .opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP }, |
| 496 | }; |
| 497 | |
| 498 | static void cortex_r5_initfn(Object *obj) |
| 499 | { |
| 500 | ARMCPU *cpu = ARM_CPU(obj); |
| 501 | ARMISARegisters *isar = &cpu->isar; |
| 502 | |
| 503 | set_feature(&cpu->env, ARM_FEATURE_V7); |
| 504 | set_feature(&cpu->env, ARM_FEATURE_V7MP); |
| 505 | set_feature(&cpu->env, ARM_FEATURE_PMSA); |
| 506 | set_feature(&cpu->env, ARM_FEATURE_PMU); |
| 507 | cpu->midr = 0x411fc153; /* r1p3 */ |
| 508 | SET_IDREG(isar, ID_PFR0, 0x0131); |
| 509 | SET_IDREG(isar, ID_PFR1, 0x001); |
| 510 | SET_IDREG(isar, ID_DFR0, 0x010400); |
| 511 | SET_IDREG(isar, ID_AFR0, 0x0); |
| 512 | SET_IDREG(isar, ID_MMFR0, 0x0210030); |
| 513 | SET_IDREG(isar, ID_MMFR1, 0x00000000); |
| 514 | SET_IDREG(isar, ID_MMFR2, 0x01200000); |
| 515 | SET_IDREG(isar, ID_MMFR3, 0x0211); |
| 516 | SET_IDREG(isar, ID_ISAR0, 0x02101111); |
| 517 | SET_IDREG(isar, ID_ISAR1, 0x13112111); |
| 518 | SET_IDREG(isar, ID_ISAR2, 0x21232141); |
| 519 | SET_IDREG(isar, ID_ISAR3, 0x01112131); |
| 520 | SET_IDREG(isar, ID_ISAR4, 0x0010142); |
| 521 | SET_IDREG(isar, ID_ISAR5, 0x0); |
| 522 | SET_IDREG(isar, ID_ISAR6, 0x0); |
| 523 | cpu->mp_is_up = true; |
| 524 | cpu->pmsav7_dregion = 16; |
| 525 | cpu->isar.reset_pmcr_el0 = 0x41151800; |
| 526 | define_arm_cp_regs(cpu, cortexr5_cp_reginfo); |
| 527 | } |
| 528 | |
| 529 | static const ARMCPRegInfo cortex_r52_cp_reginfo[] = { |
| 530 | { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15, |
| 531 | .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 }, |
| 532 | { .name = "IMP_ATCMREGIONR", |
| 533 | .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0, |
| 534 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 535 | { .name = "IMP_BTCMREGIONR", |
| 536 | .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1, |
| 537 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 538 | { .name = "IMP_CTCMREGIONR", |
| 539 | .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2, |
| 540 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 541 | { .name = "IMP_CSCTLR", |
| 542 | .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0, |
| 543 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 544 | { .name = "IMP_BPCTLR", |
| 545 | .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1, |
| 546 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 547 | { .name = "IMP_MEMPROTCLR", |
| 548 | .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 2, |
| 549 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 550 | { .name = "IMP_SLAVEPCTLR", |
| 551 | .cp = 15, .opc1 = 0, .crn = 11, .crm = 0, .opc2 = 0, |
| 552 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 553 | { .name = "IMP_PERIPHREGIONR", |
| 554 | .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0, |
| 555 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 556 | { .name = "IMP_FLASHIFREGIONR", |
| 557 | .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 1, |
| 558 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 559 | { .name = "IMP_BUILDOPTR", |
| 560 | .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0, |
| 561 | .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 562 | { .name = "IMP_PINOPTR", |
| 563 | .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7, |
| 564 | .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 565 | { .name = "IMP_QOSR", |
| 566 | .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 1, |
| 567 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 568 | { .name = "IMP_BUSTIMEOUTR", |
| 569 | .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 2, |
| 570 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 571 | { .name = "IMP_INTMONR", |
| 572 | .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 4, |
| 573 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 574 | { .name = "IMP_ICERR0", |
| 575 | .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 0, |
| 576 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 577 | { .name = "IMP_ICERR1", |
| 578 | .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 1, |
| 579 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 580 | { .name = "IMP_DCERR0", |
| 581 | .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 0, |
| 582 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 583 | { .name = "IMP_DCERR1", |
| 584 | .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 1, |
| 585 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 586 | { .name = "IMP_TCMERR0", |
| 587 | .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 0, |
| 588 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 589 | { .name = "IMP_TCMERR1", |
| 590 | .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 1, |
| 591 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 592 | { .name = "IMP_TCMSYNDR0", |
| 593 | .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 2, |
| 594 | .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 595 | { .name = "IMP_TCMSYNDR1", |
| 596 | .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 3, |
| 597 | .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 598 | { .name = "IMP_FLASHERR0", |
| 599 | .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 0, |
| 600 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 601 | { .name = "IMP_FLASHERR1", |
| 602 | .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 1, |
| 603 | .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 604 | { .name = "IMP_CDBGDR0", |
| 605 | .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 0, |
| 606 | .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 607 | { .name = "IMP_CBDGBR1", |
| 608 | .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 1, |
| 609 | .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 610 | { .name = "IMP_TESTR0", |
| 611 | .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 0, |
| 612 | .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 }, |
| 613 | { .name = "IMP_TESTR1", |
| 614 | .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 1, |
| 615 | .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 }, |
| 616 | { .name = "IMP_CDBGDCI", |
| 617 | .cp = 15, .opc1 = 0, .crn = 15, .crm = 15, .opc2 = 0, |
| 618 | .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 }, |
| 619 | { .name = "IMP_CDBGDCT", |
| 620 | .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 0, |
| 621 | .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 }, |
| 622 | { .name = "IMP_CDBGICT", |
| 623 | .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 1, |
| 624 | .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 }, |
| 625 | { .name = "IMP_CDBGDCD", |
| 626 | .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 0, |
| 627 | .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 }, |
| 628 | { .name = "IMP_CDBGICD", |
| 629 | .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 1, |
| 630 | .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 }, |
| 631 | }; |
| 632 | |
| 633 | |
| 634 | static void cortex_r52_initfn(Object *obj) |
| 635 | { |
| 636 | ARMCPU *cpu = ARM_CPU(obj); |
| 637 | ARMISARegisters *isar = &cpu->isar; |
| 638 | |
| 639 | set_feature(&cpu->env, ARM_FEATURE_V8); |
| 640 | set_feature(&cpu->env, ARM_FEATURE_EL2); |
| 641 | set_feature(&cpu->env, ARM_FEATURE_PMSA); |
| 642 | set_feature(&cpu->env, ARM_FEATURE_NEON); |
| 643 | set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS); |
| 644 | set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); |
| 645 | set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ); |
| 646 | set_feature(&cpu->env, ARM_FEATURE_CBAR_RO); |
| 647 | set_feature(&cpu->env, ARM_FEATURE_AUXCR); |
| 648 | cpu->midr = 0x411fd133; /* r1p3 */ |
| 649 | cpu->revidr = 0x00000000; |
| 650 | cpu->reset_fpsid = 0x41034023; |
| 651 | cpu->isar.mvfr0 = 0x10110222; |
| 652 | cpu->isar.mvfr1 = 0x12111111; |
| 653 | cpu->isar.mvfr2 = 0x00000043; |
| 654 | cpu->ctr = 0x8144c004; |
| 655 | cpu->reset_sctlr = 0x30c50838; |
| 656 | SET_IDREG(isar, ID_PFR0, 0x00000131); |
| 657 | SET_IDREG(isar, ID_PFR1, 0x10111001); |
| 658 | SET_IDREG(isar, ID_DFR0, 0x03010006); |
| 659 | SET_IDREG(isar, ID_AFR0, 0x00000000); |
| 660 | SET_IDREG(isar, ID_MMFR0, 0x00211040); |
| 661 | SET_IDREG(isar, ID_MMFR1, 0x40000000); |
| 662 | SET_IDREG(isar, ID_MMFR2, 0x01200000); |
| 663 | SET_IDREG(isar, ID_MMFR3, 0xf0102211); |
| 664 | SET_IDREG(isar, ID_MMFR4, 0x00000010); |
| 665 | SET_IDREG(isar, ID_ISAR0, 0x02101110); |
| 666 | SET_IDREG(isar, ID_ISAR1, 0x13112111); |
| 667 | SET_IDREG(isar, ID_ISAR2, 0x21232142); |
| 668 | SET_IDREG(isar, ID_ISAR3, 0x01112131); |
| 669 | SET_IDREG(isar, ID_ISAR4, 0x00010142); |
| 670 | SET_IDREG(isar, ID_ISAR5, 0x00010001); |
| 671 | cpu->isar.dbgdidr = 0x77168000; |
| 672 | SET_IDREG(isar, CLIDR, (1 << 27) | (1 << 24) | 0x3); |
| 673 | cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */ |
| 674 | cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */ |
| 675 | |
| 676 | cpu->pmsav7_dregion = 16; |
| 677 | cpu->pmsav8r_hdregion = 16; |
| 678 | |
| 679 | define_arm_cp_regs(cpu, cortex_r52_cp_reginfo); |
| 680 | } |
| 681 | |
| 682 | static void cortex_r5f_initfn(Object *obj) |
| 683 | { |
| 684 | ARMCPU *cpu = ARM_CPU(obj); |
| 685 | |
| 686 | cortex_r5_initfn(obj); |
| 687 | cpu->isar.mvfr0 = 0x10110221; |
| 688 | cpu->isar.mvfr1 = 0x00000011; |
| 689 | } |
| 690 | |
| 691 | static void ti925t_initfn(Object *obj) |
| 692 | { |
| 693 | ARMCPU *cpu = ARM_CPU(obj); |
| 694 | set_feature(&cpu->env, ARM_FEATURE_V4T); |
| 695 | set_feature(&cpu->env, ARM_FEATURE_OMAPCP); |
| 696 | cpu->midr = ARM_CPUID_TI925T; |
| 697 | cpu->ctr = 0x5109149; |
| 698 | cpu->reset_sctlr = 0x00000070; |
| 699 | } |
| 700 | |
| 701 | static void sa1100_initfn(Object *obj) |
| 702 | { |
| 703 | ARMCPU *cpu = ARM_CPU(obj); |
| 704 | |
| 705 | cpu->dtb_compatible = "intel,sa1100"; |
| 706 | set_feature(&cpu->env, ARM_FEATURE_STRONGARM); |
| 707 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 708 | cpu->midr = 0x4401A11B; |
| 709 | cpu->reset_sctlr = 0x00000070; |
| 710 | } |
| 711 | |
| 712 | static void sa1110_initfn(Object *obj) |
| 713 | { |
| 714 | ARMCPU *cpu = ARM_CPU(obj); |
| 715 | set_feature(&cpu->env, ARM_FEATURE_STRONGARM); |
| 716 | set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS); |
| 717 | cpu->midr = 0x6901B119; |
| 718 | cpu->reset_sctlr = 0x00000070; |
| 719 | } |
| 720 | |
| 721 | static const ARMCPUInfo arm_tcg_cpus[] = { |
| 722 | { .name = "arm926", .initfn = arm926_initfn }, |
| 723 | { .name = "arm946", .initfn = arm946_initfn }, |
| 724 | { .name = "arm1026", .initfn = arm1026_initfn }, |
| 725 | /* |
| 726 | * What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an |
| 727 | * older core than plain "arm1136". In particular this does not |
| 728 | * have the v6K features. |
| 729 | */ |
| 730 | { .name = "arm1136-r2", .initfn = arm1136_r2_initfn }, |
| 731 | { .name = "arm1136", .initfn = arm1136_initfn }, |
| 732 | { .name = "arm1176", .initfn = arm1176_initfn }, |
| 733 | { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, |
| 734 | { .name = "cortex-a7", .initfn = cortex_a7_initfn }, |
| 735 | { .name = "cortex-a8", .initfn = cortex_a8_initfn }, |
| 736 | { .name = "cortex-a9", .initfn = cortex_a9_initfn }, |
| 737 | { .name = "cortex-a15", .initfn = cortex_a15_initfn }, |
| 738 | { .name = "cortex-r5", .initfn = cortex_r5_initfn }, |
| 739 | { .name = "cortex-r5f", .initfn = cortex_r5f_initfn }, |
| 740 | { .name = "cortex-r52", .initfn = cortex_r52_initfn }, |
| 741 | { .name = "ti925t", .initfn = ti925t_initfn }, |
| 742 | { .name = "sa1100", .initfn = sa1100_initfn }, |
| 743 | { .name = "sa1110", .initfn = sa1110_initfn }, |
| 744 | }; |
| 745 | |
| 746 | static void arm_tcg_cpu_register_types(void) |
| 747 | { |
| 748 | size_t i; |
| 749 | |
| 750 | for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) { |
| 751 | arm_cpu_register(&arm_tcg_cpus[i]); |
| 752 | } |
| 753 | } |
| 754 | |
| 755 | type_init(arm_tcg_cpu_register_types) |