|
|
1.1 ! root 1: /* ! 2: * QEMU ARM CPU ! 3: * ! 4: * Copyright (c) 2012 SUSE LINUX Products GmbH ! 5: * ! 6: * This program is free software; you can redistribute it and/or ! 7: * modify it under the terms of the GNU General Public License ! 8: * as published by the Free Software Foundation; either version 2 ! 9: * of the License, or (at your option) any later version. ! 10: * ! 11: * This program is distributed in the hope that it will be useful, ! 12: * but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: * GNU General Public License for more details. ! 15: * ! 16: * You should have received a copy of the GNU General Public License ! 17: * along with this program; if not, see ! 18: * <http://www.gnu.org/licenses/gpl-2.0.html> ! 19: */ ! 20: ! 21: #include "cpu.h" ! 22: #include "qemu-common.h" ! 23: #if !defined(CONFIG_USER_ONLY) ! 24: #include "hw/loader.h" ! 25: #endif ! 26: ! 27: /* CPUClass::reset() */ ! 28: static void arm_cpu_reset(CPUState *s) ! 29: { ! 30: ARMCPU *cpu = ARM_CPU(s); ! 31: ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu); ! 32: CPUARMState *env = &cpu->env; ! 33: ! 34: if (qemu_loglevel_mask(CPU_LOG_RESET)) { ! 35: qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); ! 36: log_cpu_state(env, 0); ! 37: } ! 38: ! 39: acc->parent_reset(s); ! 40: ! 41: memset(env, 0, offsetof(CPUARMState, breakpoints)); ! 42: env->cp15.c15_config_base_address = cpu->reset_cbar; ! 43: env->cp15.c0_cpuid = cpu->midr; ! 44: env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid; ! 45: env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0; ! 46: env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1; ! 47: env->cp15.c0_cachetype = cpu->ctr; ! 48: env->cp15.c1_sys = cpu->reset_sctlr; ! 49: env->cp15.c0_c1[0] = cpu->id_pfr0; ! 50: env->cp15.c0_c1[1] = cpu->id_pfr1; ! 51: env->cp15.c0_c1[2] = cpu->id_dfr0; ! 52: env->cp15.c0_c1[3] = cpu->id_afr0; ! 53: env->cp15.c0_c1[4] = cpu->id_mmfr0; ! 54: env->cp15.c0_c1[5] = cpu->id_mmfr1; ! 55: env->cp15.c0_c1[6] = cpu->id_mmfr2; ! 56: env->cp15.c0_c1[7] = cpu->id_mmfr3; ! 57: env->cp15.c0_c2[0] = cpu->id_isar0; ! 58: env->cp15.c0_c2[1] = cpu->id_isar1; ! 59: env->cp15.c0_c2[2] = cpu->id_isar2; ! 60: env->cp15.c0_c2[3] = cpu->id_isar3; ! 61: env->cp15.c0_c2[4] = cpu->id_isar4; ! 62: env->cp15.c0_c2[5] = cpu->id_isar5; ! 63: env->cp15.c15_i_min = 0xff0; ! 64: env->cp15.c0_clid = cpu->clidr; ! 65: memcpy(env->cp15.c0_ccsid, cpu->ccsidr, ARRAY_SIZE(cpu->ccsidr)); ! 66: ! 67: if (arm_feature(env, ARM_FEATURE_IWMMXT)) { ! 68: env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q'; ! 69: } ! 70: ! 71: #if defined(CONFIG_USER_ONLY) ! 72: env->uncached_cpsr = ARM_CPU_MODE_USR; ! 73: /* For user mode we must enable access to coprocessors */ ! 74: env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; ! 75: if (arm_feature(env, ARM_FEATURE_IWMMXT)) { ! 76: env->cp15.c15_cpar = 3; ! 77: } else if (arm_feature(env, ARM_FEATURE_XSCALE)) { ! 78: env->cp15.c15_cpar = 1; ! 79: } ! 80: #else ! 81: /* SVC mode with interrupts disabled. */ ! 82: env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I; ! 83: /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is ! 84: clear at reset. Initial SP and PC are loaded from ROM. */ ! 85: if (IS_M(env)) { ! 86: uint32_t pc; ! 87: uint8_t *rom; ! 88: env->uncached_cpsr &= ~CPSR_I; ! 89: rom = rom_ptr(0); ! 90: if (rom) { ! 91: /* We should really use ldl_phys here, in case the guest ! 92: modified flash and reset itself. However images ! 93: loaded via -kernel have not been copied yet, so load the ! 94: values directly from there. */ ! 95: env->regs[13] = ldl_p(rom); ! 96: pc = ldl_p(rom + 4); ! 97: env->thumb = pc & 1; ! 98: env->regs[15] = pc & ~1; ! 99: } ! 100: } ! 101: env->vfp.xregs[ARM_VFP_FPEXC] = 0; ! 102: env->cp15.c2_base_mask = 0xffffc000u; ! 103: /* v7 performance monitor control register: same implementor ! 104: * field as main ID register, and we implement no event counters. ! 105: */ ! 106: env->cp15.c9_pmcr = (cpu->midr & 0xff000000); ! 107: #endif ! 108: set_flush_to_zero(1, &env->vfp.standard_fp_status); ! 109: set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status); ! 110: set_default_nan_mode(1, &env->vfp.standard_fp_status); ! 111: set_float_detect_tininess(float_tininess_before_rounding, ! 112: &env->vfp.fp_status); ! 113: set_float_detect_tininess(float_tininess_before_rounding, ! 114: &env->vfp.standard_fp_status); ! 115: tlb_flush(env, 1); ! 116: /* Reset is a state change for some CPUARMState fields which we ! 117: * bake assumptions about into translated code, so we need to ! 118: * tb_flush(). ! 119: */ ! 120: tb_flush(env); ! 121: } ! 122: ! 123: static inline void set_feature(CPUARMState *env, int feature) ! 124: { ! 125: env->features |= 1u << feature; ! 126: } ! 127: ! 128: static void arm_cpu_initfn(Object *obj) ! 129: { ! 130: ARMCPU *cpu = ARM_CPU(obj); ! 131: ! 132: cpu_exec_init(&cpu->env); ! 133: } ! 134: ! 135: void arm_cpu_realize(ARMCPU *cpu) ! 136: { ! 137: /* This function is called by cpu_arm_init() because it ! 138: * needs to do common actions based on feature bits, etc ! 139: * that have been set by the subclass init functions. ! 140: * When we have QOM realize support it should become ! 141: * a true realize function instead. ! 142: */ ! 143: CPUARMState *env = &cpu->env; ! 144: /* Some features automatically imply others: */ ! 145: if (arm_feature(env, ARM_FEATURE_V7)) { ! 146: set_feature(env, ARM_FEATURE_VAPA); ! 147: set_feature(env, ARM_FEATURE_THUMB2); ! 148: if (!arm_feature(env, ARM_FEATURE_M)) { ! 149: set_feature(env, ARM_FEATURE_V6K); ! 150: } else { ! 151: set_feature(env, ARM_FEATURE_V6); ! 152: } ! 153: } ! 154: if (arm_feature(env, ARM_FEATURE_V6K)) { ! 155: set_feature(env, ARM_FEATURE_V6); ! 156: set_feature(env, ARM_FEATURE_MVFR); ! 157: } ! 158: if (arm_feature(env, ARM_FEATURE_V6)) { ! 159: set_feature(env, ARM_FEATURE_V5); ! 160: if (!arm_feature(env, ARM_FEATURE_M)) { ! 161: set_feature(env, ARM_FEATURE_AUXCR); ! 162: } ! 163: } ! 164: if (arm_feature(env, ARM_FEATURE_V5)) { ! 165: set_feature(env, ARM_FEATURE_V4T); ! 166: } ! 167: if (arm_feature(env, ARM_FEATURE_M)) { ! 168: set_feature(env, ARM_FEATURE_THUMB_DIV); ! 169: } ! 170: if (arm_feature(env, ARM_FEATURE_ARM_DIV)) { ! 171: set_feature(env, ARM_FEATURE_THUMB_DIV); ! 172: } ! 173: if (arm_feature(env, ARM_FEATURE_VFP4)) { ! 174: set_feature(env, ARM_FEATURE_VFP3); ! 175: } ! 176: if (arm_feature(env, ARM_FEATURE_VFP3)) { ! 177: set_feature(env, ARM_FEATURE_VFP); ! 178: } ! 179: } ! 180: ! 181: /* CPU models */ ! 182: ! 183: static void arm926_initfn(Object *obj) ! 184: { ! 185: ARMCPU *cpu = ARM_CPU(obj); ! 186: set_feature(&cpu->env, ARM_FEATURE_V5); ! 187: set_feature(&cpu->env, ARM_FEATURE_VFP); ! 188: cpu->midr = ARM_CPUID_ARM926; ! 189: cpu->reset_fpsid = 0x41011090; ! 190: cpu->ctr = 0x1dd20d2; ! 191: cpu->reset_sctlr = 0x00090078; ! 192: } ! 193: ! 194: static void arm946_initfn(Object *obj) ! 195: { ! 196: ARMCPU *cpu = ARM_CPU(obj); ! 197: set_feature(&cpu->env, ARM_FEATURE_V5); ! 198: set_feature(&cpu->env, ARM_FEATURE_MPU); ! 199: cpu->midr = ARM_CPUID_ARM946; ! 200: cpu->ctr = 0x0f004006; ! 201: cpu->reset_sctlr = 0x00000078; ! 202: } ! 203: ! 204: static void arm1026_initfn(Object *obj) ! 205: { ! 206: ARMCPU *cpu = ARM_CPU(obj); ! 207: set_feature(&cpu->env, ARM_FEATURE_V5); ! 208: set_feature(&cpu->env, ARM_FEATURE_VFP); ! 209: set_feature(&cpu->env, ARM_FEATURE_AUXCR); ! 210: cpu->midr = ARM_CPUID_ARM1026; ! 211: cpu->reset_fpsid = 0x410110a0; ! 212: cpu->ctr = 0x1dd20d2; ! 213: cpu->reset_sctlr = 0x00090078; ! 214: } ! 215: ! 216: static void arm1136_r2_initfn(Object *obj) ! 217: { ! 218: ARMCPU *cpu = ARM_CPU(obj); ! 219: /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an ! 220: * older core than plain "arm1136". In particular this does not ! 221: * have the v6K features. ! 222: * These ID register values are correct for 1136 but may be wrong ! 223: * for 1136_r2 (in particular r0p2 does not actually implement most ! 224: * of the ID registers). ! 225: */ ! 226: set_feature(&cpu->env, ARM_FEATURE_V6); ! 227: set_feature(&cpu->env, ARM_FEATURE_VFP); ! 228: cpu->midr = ARM_CPUID_ARM1136_R2; ! 229: cpu->reset_fpsid = 0x410120b4; ! 230: cpu->mvfr0 = 0x11111111; ! 231: cpu->mvfr1 = 0x00000000; ! 232: cpu->ctr = 0x1dd20d2; ! 233: cpu->reset_sctlr = 0x00050078; ! 234: cpu->id_pfr0 = 0x111; ! 235: cpu->id_pfr1 = 0x1; ! 236: cpu->id_dfr0 = 0x2; ! 237: cpu->id_afr0 = 0x3; ! 238: cpu->id_mmfr0 = 0x01130003; ! 239: cpu->id_mmfr1 = 0x10030302; ! 240: cpu->id_mmfr2 = 0x01222110; ! 241: cpu->id_isar0 = 0x00140011; ! 242: cpu->id_isar1 = 0x12002111; ! 243: cpu->id_isar2 = 0x11231111; ! 244: cpu->id_isar3 = 0x01102131; ! 245: cpu->id_isar4 = 0x141; ! 246: } ! 247: ! 248: static void arm1136_initfn(Object *obj) ! 249: { ! 250: ARMCPU *cpu = ARM_CPU(obj); ! 251: set_feature(&cpu->env, ARM_FEATURE_V6K); ! 252: set_feature(&cpu->env, ARM_FEATURE_V6); ! 253: set_feature(&cpu->env, ARM_FEATURE_VFP); ! 254: cpu->midr = ARM_CPUID_ARM1136; ! 255: cpu->reset_fpsid = 0x410120b4; ! 256: cpu->mvfr0 = 0x11111111; ! 257: cpu->mvfr1 = 0x00000000; ! 258: cpu->ctr = 0x1dd20d2; ! 259: cpu->reset_sctlr = 0x00050078; ! 260: cpu->id_pfr0 = 0x111; ! 261: cpu->id_pfr1 = 0x1; ! 262: cpu->id_dfr0 = 0x2; ! 263: cpu->id_afr0 = 0x3; ! 264: cpu->id_mmfr0 = 0x01130003; ! 265: cpu->id_mmfr1 = 0x10030302; ! 266: cpu->id_mmfr2 = 0x01222110; ! 267: cpu->id_isar0 = 0x00140011; ! 268: cpu->id_isar1 = 0x12002111; ! 269: cpu->id_isar2 = 0x11231111; ! 270: cpu->id_isar3 = 0x01102131; ! 271: cpu->id_isar4 = 0x141; ! 272: } ! 273: ! 274: static void arm1176_initfn(Object *obj) ! 275: { ! 276: ARMCPU *cpu = ARM_CPU(obj); ! 277: set_feature(&cpu->env, ARM_FEATURE_V6K); ! 278: set_feature(&cpu->env, ARM_FEATURE_VFP); ! 279: set_feature(&cpu->env, ARM_FEATURE_VAPA); ! 280: cpu->midr = ARM_CPUID_ARM1176; ! 281: cpu->reset_fpsid = 0x410120b5; ! 282: cpu->mvfr0 = 0x11111111; ! 283: cpu->mvfr1 = 0x00000000; ! 284: cpu->ctr = 0x1dd20d2; ! 285: cpu->reset_sctlr = 0x00050078; ! 286: cpu->id_pfr0 = 0x111; ! 287: cpu->id_pfr1 = 0x11; ! 288: cpu->id_dfr0 = 0x33; ! 289: cpu->id_afr0 = 0; ! 290: cpu->id_mmfr0 = 0x01130003; ! 291: cpu->id_mmfr1 = 0x10030302; ! 292: cpu->id_mmfr2 = 0x01222100; ! 293: cpu->id_isar0 = 0x0140011; ! 294: cpu->id_isar1 = 0x12002111; ! 295: cpu->id_isar2 = 0x11231121; ! 296: cpu->id_isar3 = 0x01102131; ! 297: cpu->id_isar4 = 0x01141; ! 298: } ! 299: ! 300: static void arm11mpcore_initfn(Object *obj) ! 301: { ! 302: ARMCPU *cpu = ARM_CPU(obj); ! 303: set_feature(&cpu->env, ARM_FEATURE_V6K); ! 304: set_feature(&cpu->env, ARM_FEATURE_VFP); ! 305: set_feature(&cpu->env, ARM_FEATURE_VAPA); ! 306: cpu->midr = ARM_CPUID_ARM11MPCORE; ! 307: cpu->reset_fpsid = 0x410120b4; ! 308: cpu->mvfr0 = 0x11111111; ! 309: cpu->mvfr1 = 0x00000000; ! 310: cpu->ctr = 0x1dd20d2; ! 311: cpu->id_pfr0 = 0x111; ! 312: cpu->id_pfr1 = 0x1; ! 313: cpu->id_dfr0 = 0; ! 314: cpu->id_afr0 = 0x2; ! 315: cpu->id_mmfr0 = 0x01100103; ! 316: cpu->id_mmfr1 = 0x10020302; ! 317: cpu->id_mmfr2 = 0x01222000; ! 318: cpu->id_isar0 = 0x00100011; ! 319: cpu->id_isar1 = 0x12002111; ! 320: cpu->id_isar2 = 0x11221011; ! 321: cpu->id_isar3 = 0x01102131; ! 322: cpu->id_isar4 = 0x141; ! 323: } ! 324: ! 325: static void cortex_m3_initfn(Object *obj) ! 326: { ! 327: ARMCPU *cpu = ARM_CPU(obj); ! 328: set_feature(&cpu->env, ARM_FEATURE_V7); ! 329: set_feature(&cpu->env, ARM_FEATURE_M); ! 330: cpu->midr = ARM_CPUID_CORTEXM3; ! 331: } ! 332: ! 333: static void cortex_a8_initfn(Object *obj) ! 334: { ! 335: ARMCPU *cpu = ARM_CPU(obj); ! 336: set_feature(&cpu->env, ARM_FEATURE_V7); ! 337: set_feature(&cpu->env, ARM_FEATURE_VFP3); ! 338: set_feature(&cpu->env, ARM_FEATURE_NEON); ! 339: set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); ! 340: cpu->midr = ARM_CPUID_CORTEXA8; ! 341: cpu->reset_fpsid = 0x410330c0; ! 342: cpu->mvfr0 = 0x11110222; ! 343: cpu->mvfr1 = 0x00011100; ! 344: cpu->ctr = 0x82048004; ! 345: cpu->reset_sctlr = 0x00c50078; ! 346: cpu->id_pfr0 = 0x1031; ! 347: cpu->id_pfr1 = 0x11; ! 348: cpu->id_dfr0 = 0x400; ! 349: cpu->id_afr0 = 0; ! 350: cpu->id_mmfr0 = 0x31100003; ! 351: cpu->id_mmfr1 = 0x20000000; ! 352: cpu->id_mmfr2 = 0x01202000; ! 353: cpu->id_mmfr3 = 0x11; ! 354: cpu->id_isar0 = 0x00101111; ! 355: cpu->id_isar1 = 0x12112111; ! 356: cpu->id_isar2 = 0x21232031; ! 357: cpu->id_isar3 = 0x11112131; ! 358: cpu->id_isar4 = 0x00111142; ! 359: cpu->clidr = (1 << 27) | (2 << 24) | 3; ! 360: cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */ ! 361: cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */ ! 362: cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */ ! 363: } ! 364: ! 365: static void cortex_a9_initfn(Object *obj) ! 366: { ! 367: ARMCPU *cpu = ARM_CPU(obj); ! 368: set_feature(&cpu->env, ARM_FEATURE_V7); ! 369: set_feature(&cpu->env, ARM_FEATURE_VFP3); ! 370: set_feature(&cpu->env, ARM_FEATURE_VFP_FP16); ! 371: set_feature(&cpu->env, ARM_FEATURE_NEON); ! 372: set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); ! 373: /* Note that A9 supports the MP extensions even for ! 374: * A9UP and single-core A9MP (which are both different ! 375: * and valid configurations; we don't model A9UP). ! 376: */ ! 377: set_feature(&cpu->env, ARM_FEATURE_V7MP); ! 378: cpu->midr = ARM_CPUID_CORTEXA9; ! 379: cpu->reset_fpsid = 0x41033090; ! 380: cpu->mvfr0 = 0x11110222; ! 381: cpu->mvfr1 = 0x01111111; ! 382: cpu->ctr = 0x80038003; ! 383: cpu->reset_sctlr = 0x00c50078; ! 384: cpu->id_pfr0 = 0x1031; ! 385: cpu->id_pfr1 = 0x11; ! 386: cpu->id_dfr0 = 0x000; ! 387: cpu->id_afr0 = 0; ! 388: cpu->id_mmfr0 = 0x00100103; ! 389: cpu->id_mmfr1 = 0x20000000; ! 390: cpu->id_mmfr2 = 0x01230000; ! 391: cpu->id_mmfr3 = 0x00002111; ! 392: cpu->id_isar0 = 0x00101111; ! 393: cpu->id_isar1 = 0x13112111; ! 394: cpu->id_isar2 = 0x21232041; ! 395: cpu->id_isar3 = 0x11112131; ! 396: cpu->id_isar4 = 0x00111142; ! 397: cpu->clidr = (1 << 27) | (1 << 24) | 3; ! 398: cpu->ccsidr[0] = 0xe00fe015; /* 16k L1 dcache. */ ! 399: cpu->ccsidr[1] = 0x200fe015; /* 16k L1 icache. */ ! 400: } ! 401: ! 402: static void cortex_a15_initfn(Object *obj) ! 403: { ! 404: ARMCPU *cpu = ARM_CPU(obj); ! 405: set_feature(&cpu->env, ARM_FEATURE_V7); ! 406: set_feature(&cpu->env, ARM_FEATURE_VFP4); ! 407: set_feature(&cpu->env, ARM_FEATURE_VFP_FP16); ! 408: set_feature(&cpu->env, ARM_FEATURE_NEON); ! 409: set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); ! 410: set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); ! 411: set_feature(&cpu->env, ARM_FEATURE_V7MP); ! 412: set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER); ! 413: cpu->midr = ARM_CPUID_CORTEXA15; ! 414: cpu->reset_fpsid = 0x410430f0; ! 415: cpu->mvfr0 = 0x10110222; ! 416: cpu->mvfr1 = 0x11111111; ! 417: cpu->ctr = 0x8444c004; ! 418: cpu->reset_sctlr = 0x00c50078; ! 419: cpu->id_pfr0 = 0x00001131; ! 420: cpu->id_pfr1 = 0x00011011; ! 421: cpu->id_dfr0 = 0x02010555; ! 422: cpu->id_afr0 = 0x00000000; ! 423: cpu->id_mmfr0 = 0x10201105; ! 424: cpu->id_mmfr1 = 0x20000000; ! 425: cpu->id_mmfr2 = 0x01240000; ! 426: cpu->id_mmfr3 = 0x02102211; ! 427: cpu->id_isar0 = 0x02101110; ! 428: cpu->id_isar1 = 0x13112111; ! 429: cpu->id_isar2 = 0x21232041; ! 430: cpu->id_isar3 = 0x11112131; ! 431: cpu->id_isar4 = 0x10011142; ! 432: cpu->clidr = 0x0a200023; ! 433: cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */ ! 434: cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */ ! 435: cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */ ! 436: } ! 437: ! 438: static void ti925t_initfn(Object *obj) ! 439: { ! 440: ARMCPU *cpu = ARM_CPU(obj); ! 441: set_feature(&cpu->env, ARM_FEATURE_V4T); ! 442: set_feature(&cpu->env, ARM_FEATURE_OMAPCP); ! 443: cpu->midr = ARM_CPUID_TI925T; ! 444: cpu->ctr = 0x5109149; ! 445: cpu->reset_sctlr = 0x00000070; ! 446: } ! 447: ! 448: static void sa1100_initfn(Object *obj) ! 449: { ! 450: ARMCPU *cpu = ARM_CPU(obj); ! 451: set_feature(&cpu->env, ARM_FEATURE_STRONGARM); ! 452: cpu->midr = ARM_CPUID_SA1100; ! 453: cpu->reset_sctlr = 0x00000070; ! 454: } ! 455: ! 456: static void sa1110_initfn(Object *obj) ! 457: { ! 458: ARMCPU *cpu = ARM_CPU(obj); ! 459: set_feature(&cpu->env, ARM_FEATURE_STRONGARM); ! 460: cpu->midr = ARM_CPUID_SA1110; ! 461: cpu->reset_sctlr = 0x00000070; ! 462: } ! 463: ! 464: static void pxa250_initfn(Object *obj) ! 465: { ! 466: ARMCPU *cpu = ARM_CPU(obj); ! 467: set_feature(&cpu->env, ARM_FEATURE_V5); ! 468: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 469: cpu->midr = ARM_CPUID_PXA250; ! 470: cpu->ctr = 0xd172172; ! 471: cpu->reset_sctlr = 0x00000078; ! 472: } ! 473: ! 474: static void pxa255_initfn(Object *obj) ! 475: { ! 476: ARMCPU *cpu = ARM_CPU(obj); ! 477: set_feature(&cpu->env, ARM_FEATURE_V5); ! 478: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 479: cpu->midr = ARM_CPUID_PXA255; ! 480: cpu->ctr = 0xd172172; ! 481: cpu->reset_sctlr = 0x00000078; ! 482: } ! 483: ! 484: static void pxa260_initfn(Object *obj) ! 485: { ! 486: ARMCPU *cpu = ARM_CPU(obj); ! 487: set_feature(&cpu->env, ARM_FEATURE_V5); ! 488: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 489: cpu->midr = ARM_CPUID_PXA260; ! 490: cpu->ctr = 0xd172172; ! 491: cpu->reset_sctlr = 0x00000078; ! 492: } ! 493: ! 494: static void pxa261_initfn(Object *obj) ! 495: { ! 496: ARMCPU *cpu = ARM_CPU(obj); ! 497: set_feature(&cpu->env, ARM_FEATURE_V5); ! 498: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 499: cpu->midr = ARM_CPUID_PXA261; ! 500: cpu->ctr = 0xd172172; ! 501: cpu->reset_sctlr = 0x00000078; ! 502: } ! 503: ! 504: static void pxa262_initfn(Object *obj) ! 505: { ! 506: ARMCPU *cpu = ARM_CPU(obj); ! 507: set_feature(&cpu->env, ARM_FEATURE_V5); ! 508: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 509: cpu->midr = ARM_CPUID_PXA262; ! 510: cpu->ctr = 0xd172172; ! 511: cpu->reset_sctlr = 0x00000078; ! 512: } ! 513: ! 514: static void pxa270a0_initfn(Object *obj) ! 515: { ! 516: ARMCPU *cpu = ARM_CPU(obj); ! 517: set_feature(&cpu->env, ARM_FEATURE_V5); ! 518: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 519: set_feature(&cpu->env, ARM_FEATURE_IWMMXT); ! 520: cpu->midr = ARM_CPUID_PXA270_A0; ! 521: cpu->ctr = 0xd172172; ! 522: cpu->reset_sctlr = 0x00000078; ! 523: } ! 524: ! 525: static void pxa270a1_initfn(Object *obj) ! 526: { ! 527: ARMCPU *cpu = ARM_CPU(obj); ! 528: set_feature(&cpu->env, ARM_FEATURE_V5); ! 529: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 530: set_feature(&cpu->env, ARM_FEATURE_IWMMXT); ! 531: cpu->midr = ARM_CPUID_PXA270_A1; ! 532: cpu->ctr = 0xd172172; ! 533: cpu->reset_sctlr = 0x00000078; ! 534: } ! 535: ! 536: static void pxa270b0_initfn(Object *obj) ! 537: { ! 538: ARMCPU *cpu = ARM_CPU(obj); ! 539: set_feature(&cpu->env, ARM_FEATURE_V5); ! 540: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 541: set_feature(&cpu->env, ARM_FEATURE_IWMMXT); ! 542: cpu->midr = ARM_CPUID_PXA270_B0; ! 543: cpu->ctr = 0xd172172; ! 544: cpu->reset_sctlr = 0x00000078; ! 545: } ! 546: ! 547: static void pxa270b1_initfn(Object *obj) ! 548: { ! 549: ARMCPU *cpu = ARM_CPU(obj); ! 550: set_feature(&cpu->env, ARM_FEATURE_V5); ! 551: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 552: set_feature(&cpu->env, ARM_FEATURE_IWMMXT); ! 553: cpu->midr = ARM_CPUID_PXA270_B1; ! 554: cpu->ctr = 0xd172172; ! 555: cpu->reset_sctlr = 0x00000078; ! 556: } ! 557: ! 558: static void pxa270c0_initfn(Object *obj) ! 559: { ! 560: ARMCPU *cpu = ARM_CPU(obj); ! 561: set_feature(&cpu->env, ARM_FEATURE_V5); ! 562: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 563: set_feature(&cpu->env, ARM_FEATURE_IWMMXT); ! 564: cpu->midr = ARM_CPUID_PXA270_C0; ! 565: cpu->ctr = 0xd172172; ! 566: cpu->reset_sctlr = 0x00000078; ! 567: } ! 568: ! 569: static void pxa270c5_initfn(Object *obj) ! 570: { ! 571: ARMCPU *cpu = ARM_CPU(obj); ! 572: set_feature(&cpu->env, ARM_FEATURE_V5); ! 573: set_feature(&cpu->env, ARM_FEATURE_XSCALE); ! 574: set_feature(&cpu->env, ARM_FEATURE_IWMMXT); ! 575: cpu->midr = ARM_CPUID_PXA270_C5; ! 576: cpu->ctr = 0xd172172; ! 577: cpu->reset_sctlr = 0x00000078; ! 578: } ! 579: ! 580: static void arm_any_initfn(Object *obj) ! 581: { ! 582: ARMCPU *cpu = ARM_CPU(obj); ! 583: set_feature(&cpu->env, ARM_FEATURE_V7); ! 584: set_feature(&cpu->env, ARM_FEATURE_VFP4); ! 585: set_feature(&cpu->env, ARM_FEATURE_VFP_FP16); ! 586: set_feature(&cpu->env, ARM_FEATURE_NEON); ! 587: set_feature(&cpu->env, ARM_FEATURE_THUMB2EE); ! 588: set_feature(&cpu->env, ARM_FEATURE_ARM_DIV); ! 589: set_feature(&cpu->env, ARM_FEATURE_V7MP); ! 590: cpu->midr = ARM_CPUID_ANY; ! 591: } ! 592: ! 593: typedef struct ARMCPUInfo { ! 594: const char *name; ! 595: void (*initfn)(Object *obj); ! 596: } ARMCPUInfo; ! 597: ! 598: static const ARMCPUInfo arm_cpus[] = { ! 599: { .name = "arm926", .initfn = arm926_initfn }, ! 600: { .name = "arm946", .initfn = arm946_initfn }, ! 601: { .name = "arm1026", .initfn = arm1026_initfn }, ! 602: /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an ! 603: * older core than plain "arm1136". In particular this does not ! 604: * have the v6K features. ! 605: */ ! 606: { .name = "arm1136-r2", .initfn = arm1136_r2_initfn }, ! 607: { .name = "arm1136", .initfn = arm1136_initfn }, ! 608: { .name = "arm1176", .initfn = arm1176_initfn }, ! 609: { .name = "arm11mpcore", .initfn = arm11mpcore_initfn }, ! 610: { .name = "cortex-m3", .initfn = cortex_m3_initfn }, ! 611: { .name = "cortex-a8", .initfn = cortex_a8_initfn }, ! 612: { .name = "cortex-a9", .initfn = cortex_a9_initfn }, ! 613: { .name = "cortex-a15", .initfn = cortex_a15_initfn }, ! 614: { .name = "ti925t", .initfn = ti925t_initfn }, ! 615: { .name = "sa1100", .initfn = sa1100_initfn }, ! 616: { .name = "sa1110", .initfn = sa1110_initfn }, ! 617: { .name = "pxa250", .initfn = pxa250_initfn }, ! 618: { .name = "pxa255", .initfn = pxa255_initfn }, ! 619: { .name = "pxa260", .initfn = pxa260_initfn }, ! 620: { .name = "pxa261", .initfn = pxa261_initfn }, ! 621: { .name = "pxa262", .initfn = pxa262_initfn }, ! 622: /* "pxa270" is an alias for "pxa270-a0" */ ! 623: { .name = "pxa270", .initfn = pxa270a0_initfn }, ! 624: { .name = "pxa270-a0", .initfn = pxa270a0_initfn }, ! 625: { .name = "pxa270-a1", .initfn = pxa270a1_initfn }, ! 626: { .name = "pxa270-b0", .initfn = pxa270b0_initfn }, ! 627: { .name = "pxa270-b1", .initfn = pxa270b1_initfn }, ! 628: { .name = "pxa270-c0", .initfn = pxa270c0_initfn }, ! 629: { .name = "pxa270-c5", .initfn = pxa270c5_initfn }, ! 630: { .name = "any", .initfn = arm_any_initfn }, ! 631: }; ! 632: ! 633: static void arm_cpu_class_init(ObjectClass *oc, void *data) ! 634: { ! 635: ARMCPUClass *acc = ARM_CPU_CLASS(oc); ! 636: CPUClass *cc = CPU_CLASS(acc); ! 637: ! 638: acc->parent_reset = cc->reset; ! 639: cc->reset = arm_cpu_reset; ! 640: } ! 641: ! 642: static void cpu_register(const ARMCPUInfo *info) ! 643: { ! 644: TypeInfo type_info = { ! 645: .name = info->name, ! 646: .parent = TYPE_ARM_CPU, ! 647: .instance_size = sizeof(ARMCPU), ! 648: .instance_init = info->initfn, ! 649: .class_size = sizeof(ARMCPUClass), ! 650: }; ! 651: ! 652: type_register_static(&type_info); ! 653: } ! 654: ! 655: static const TypeInfo arm_cpu_type_info = { ! 656: .name = TYPE_ARM_CPU, ! 657: .parent = TYPE_CPU, ! 658: .instance_size = sizeof(ARMCPU), ! 659: .instance_init = arm_cpu_initfn, ! 660: .abstract = true, ! 661: .class_size = sizeof(ARMCPUClass), ! 662: .class_init = arm_cpu_class_init, ! 663: }; ! 664: ! 665: static void arm_cpu_register_types(void) ! 666: { ! 667: int i; ! 668: ! 669: type_register_static(&arm_cpu_type_info); ! 670: for (i = 0; i < ARRAY_SIZE(arm_cpus); i++) { ! 671: cpu_register(&arm_cpus[i]); ! 672: } ! 673: } ! 674: ! 675: type_init(arm_cpu_register_types)
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.