cpu.c 33.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
/*
 * QEMU ARM CPU
 *
 * Copyright (c) 2012 SUSE LINUX Products GmbH
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see
 * <http://www.gnu.org/licenses/gpl-2.0.html>
 */

21
#include "cpu.h"
22
#include "internals.h"
23
#include "qemu-common.h"
24
#include "hw/qdev-properties.h"
25
#include "qapi/qmp/qerror.h"
26 27 28
#if !defined(CONFIG_USER_ONLY)
#include "hw/loader.h"
#endif
29
#include "hw/arm/arm.h"
30
#include "sysemu/sysemu.h"
31
#include "sysemu/kvm.h"
32
#include "kvm_arm.h"
33

34 35 36 37 38 39 40
static void arm_cpu_set_pc(CPUState *cs, vaddr value)
{
    ARMCPU *cpu = ARM_CPU(cs);

    cpu->env.regs[15] = value;
}

41 42 43 44 45 46
static bool arm_cpu_has_work(CPUState *cs)
{
    return cs->interrupt_request &
        (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD | CPU_INTERRUPT_EXITTB);
}

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
{
    /* Reset a single ARMCPRegInfo register */
    ARMCPRegInfo *ri = value;
    ARMCPU *cpu = opaque;

    if (ri->type & ARM_CP_SPECIAL) {
        return;
    }

    if (ri->resetfn) {
        ri->resetfn(&cpu->env, ri);
        return;
    }

    /* A zero offset is never possible as it would be regs[0]
     * so we use it to indicate that reset is being handled elsewhere.
     * This is basically only used for fields in non-core coprocessors
     * (like the pxa2xx ones).
     */
    if (!ri->fieldoffset) {
        return;
    }

71
    if (cpreg_field_is_64bit(ri)) {
72 73 74 75 76 77
        CPREG_FIELD64(&cpu->env, ri) = ri->resetvalue;
    } else {
        CPREG_FIELD32(&cpu->env, ri) = ri->resetvalue;
    }
}

78 79 80 81 82
/* CPUClass::reset() */
static void arm_cpu_reset(CPUState *s)
{
    ARMCPU *cpu = ARM_CPU(s);
    ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu);
83 84
    CPUARMState *env = &cpu->env;

85 86
    acc->parent_reset(s);

87
    memset(env, 0, offsetof(CPUARMState, features));
88
    g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu);
89 90 91
    env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid;
    env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0;
    env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1;
92
    env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2;
93 94 95 96 97

    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
        env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
    }

98 99 100
    if (arm_feature(env, ARM_FEATURE_AARCH64)) {
        /* 64 bit CPUs always start in 64 bit mode */
        env->aarch64 = 1;
101 102
#if defined(CONFIG_USER_ONLY)
        env->pstate = PSTATE_MODE_EL0t;
103 104
        /* Userspace expects access to CTL_EL0 and the cache ops */
        env->cp15.c1_sys |= SCTLR_UCT | SCTLR_UCI;
105 106
        /* and to the FP/Neon instructions */
        env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 2, 3);
107
#else
108
        env->pstate = PSTATE_MODE_EL1h;
109
        env->pc = cpu->rvbar;
110 111 112 113 114
#endif
    } else {
#if defined(CONFIG_USER_ONLY)
        /* Userspace expects access to cp10 and cp11 for FP/Neon */
        env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 4, 0xf);
115
#endif
116 117
    }

118 119 120 121 122 123 124 125 126 127 128
#if defined(CONFIG_USER_ONLY)
    env->uncached_cpsr = ARM_CPU_MODE_USR;
    /* For user mode we must enable access to coprocessors */
    env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
    if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
        env->cp15.c15_cpar = 3;
    } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
        env->cp15.c15_cpar = 1;
    }
#else
    /* SVC mode with interrupts disabled.  */
129 130
    env->uncached_cpsr = ARM_CPU_MODE_SVC;
    env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
131 132 133 134 135
    /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
       clear at reset.  Initial SP and PC are loaded from ROM.  */
    if (IS_M(env)) {
        uint32_t pc;
        uint8_t *rom;
136
        env->daif &= ~PSTATE_I;
137 138 139 140 141 142
        rom = rom_ptr(0);
        if (rom) {
            /* We should really use ldl_phys here, in case the guest
               modified flash and reset itself.  However images
               loaded via -kernel have not been copied yet, so load the
               values directly from there.  */
143
            env->regs[13] = ldl_p(rom) & 0xFFFFFFFC;
144 145 146 147 148
            pc = ldl_p(rom + 4);
            env->thumb = pc & 1;
            env->regs[15] = pc & ~1;
        }
    }
149

150
    if (env->cp15.c1_sys & SCTLR_V) {
151 152 153
            env->regs[15] = 0xFFFF0000;
    }

154 155 156 157 158 159 160 161 162
    env->vfp.xregs[ARM_VFP_FPEXC] = 0;
#endif
    set_flush_to_zero(1, &env->vfp.standard_fp_status);
    set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status);
    set_default_nan_mode(1, &env->vfp.standard_fp_status);
    set_float_detect_tininess(float_tininess_before_rounding,
                              &env->vfp.fp_status);
    set_float_detect_tininess(float_tininess_before_rounding,
                              &env->vfp.standard_fp_status);
163
    tlb_flush(s, 1);
164 165 166 167 168
    /* Reset is a state change for some CPUARMState fields which we
     * bake assumptions about into translated code, so we need to
     * tb_flush().
     */
    tb_flush(env);
169 170 171 172 173 174

#ifndef CONFIG_USER_ONLY
    if (kvm_enabled()) {
        kvm_arm_reset_vcpu(cpu);
    }
#endif
175 176
}

177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225
#ifndef CONFIG_USER_ONLY
static void arm_cpu_set_irq(void *opaque, int irq, int level)
{
    ARMCPU *cpu = opaque;
    CPUState *cs = CPU(cpu);

    switch (irq) {
    case ARM_CPU_IRQ:
        if (level) {
            cpu_interrupt(cs, CPU_INTERRUPT_HARD);
        } else {
            cpu_reset_interrupt(cs, CPU_INTERRUPT_HARD);
        }
        break;
    case ARM_CPU_FIQ:
        if (level) {
            cpu_interrupt(cs, CPU_INTERRUPT_FIQ);
        } else {
            cpu_reset_interrupt(cs, CPU_INTERRUPT_FIQ);
        }
        break;
    default:
        hw_error("arm_cpu_set_irq: Bad interrupt line %d\n", irq);
    }
}

static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level)
{
#ifdef CONFIG_KVM
    ARMCPU *cpu = opaque;
    CPUState *cs = CPU(cpu);
    int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;

    switch (irq) {
    case ARM_CPU_IRQ:
        kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
        break;
    case ARM_CPU_FIQ:
        kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
        break;
    default:
        hw_error("arm_cpu_kvm_set_irq: Bad interrupt line %d\n", irq);
    }
    kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
    kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
#endif
}
#endif

226 227
static inline void set_feature(CPUARMState *env, int feature)
{
228
    env->features |= 1ULL << feature;
229 230
}

231 232
static void arm_cpu_initfn(Object *obj)
{
233
    CPUState *cs = CPU(obj);
234
    ARMCPU *cpu = ARM_CPU(obj);
235
    static bool inited;
236

237
    cs->env_ptr = &cpu->env;
238
    cpu_exec_init(&cpu->env);
239 240
    cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
                                         g_free, g_free);
241

242 243 244 245 246 247 248
#ifndef CONFIG_USER_ONLY
    /* Our inbound IRQ and FIQ lines */
    if (kvm_enabled()) {
        qdev_init_gpio_in(DEVICE(cpu), arm_cpu_kvm_set_irq, 2);
    } else {
        qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 2);
    }
249

250
    cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
251
                                                arm_gt_ptimer_cb, cpu);
252
    cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
253 254 255
                                                arm_gt_vtimer_cb, cpu);
    qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs,
                       ARRAY_SIZE(cpu->gt_timer_outputs));
256 257
#endif

258 259 260 261 262
    /* DTB consumers generally don't in fact care what the 'compatible'
     * string is, so always provide some string and trust that a hypothetical
     * picky DTB consumer will also provide a helpful error message.
     */
    cpu->dtb_compatible = "qemu,unknown";
263
    cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
264

265 266 267 268
    if (tcg_enabled() && !inited) {
        inited = true;
        arm_translate_init();
    }
269 270
}

271
static Property arm_cpu_reset_cbar_property =
272
            DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
273

274 275 276
static Property arm_cpu_reset_hivecs_property =
            DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false);

277 278 279
static Property arm_cpu_rvbar_property =
            DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0);

280 281 282 283
static void arm_cpu_post_init(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);

284 285
    if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
        arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
286
        qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property,
287
                                 &error_abort);
288
    }
289 290 291

    if (!arm_feature(&cpu->env, ARM_FEATURE_M)) {
        qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property,
292
                                 &error_abort);
293
    }
294 295 296 297 298

    if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
        qdev_property_add_static(DEVICE(obj), &arm_cpu_rvbar_property,
                                 &error_abort);
    }
299 300
}

301 302 303 304
static void arm_cpu_finalizefn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
    g_hash_table_destroy(cpu->cp_regs);
305 306
}

307
static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
308
{
309
    CPUState *cs = CPU(dev);
310 311
    ARMCPU *cpu = ARM_CPU(dev);
    ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev);
312
    CPUARMState *env = &cpu->env;
313

314
    /* Some features automatically imply others: */
315 316 317 318 319
    if (arm_feature(env, ARM_FEATURE_V8)) {
        set_feature(env, ARM_FEATURE_V7);
        set_feature(env, ARM_FEATURE_ARM_DIV);
        set_feature(env, ARM_FEATURE_LPAE);
    }
320 321 322
    if (arm_feature(env, ARM_FEATURE_V7)) {
        set_feature(env, ARM_FEATURE_VAPA);
        set_feature(env, ARM_FEATURE_THUMB2);
P
Peter Maydell 已提交
323
        set_feature(env, ARM_FEATURE_MPIDR);
324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
        if (!arm_feature(env, ARM_FEATURE_M)) {
            set_feature(env, ARM_FEATURE_V6K);
        } else {
            set_feature(env, ARM_FEATURE_V6);
        }
    }
    if (arm_feature(env, ARM_FEATURE_V6K)) {
        set_feature(env, ARM_FEATURE_V6);
        set_feature(env, ARM_FEATURE_MVFR);
    }
    if (arm_feature(env, ARM_FEATURE_V6)) {
        set_feature(env, ARM_FEATURE_V5);
        if (!arm_feature(env, ARM_FEATURE_M)) {
            set_feature(env, ARM_FEATURE_AUXCR);
        }
    }
    if (arm_feature(env, ARM_FEATURE_V5)) {
        set_feature(env, ARM_FEATURE_V4T);
    }
    if (arm_feature(env, ARM_FEATURE_M)) {
        set_feature(env, ARM_FEATURE_THUMB_DIV);
    }
    if (arm_feature(env, ARM_FEATURE_ARM_DIV)) {
        set_feature(env, ARM_FEATURE_THUMB_DIV);
    }
    if (arm_feature(env, ARM_FEATURE_VFP4)) {
        set_feature(env, ARM_FEATURE_VFP3);
    }
    if (arm_feature(env, ARM_FEATURE_VFP3)) {
        set_feature(env, ARM_FEATURE_VFP);
    }
355
    if (arm_feature(env, ARM_FEATURE_LPAE)) {
356
        set_feature(env, ARM_FEATURE_V7MP);
357 358
        set_feature(env, ARM_FEATURE_PXN);
    }
359 360 361
    if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
        set_feature(env, ARM_FEATURE_CBAR);
    }
362

363 364 365 366
    if (cpu->reset_hivecs) {
            cpu->reset_sctlr |= (1 << 13);
    }

367
    register_cp_regs_for_features(cpu);
368 369
    arm_cpu_register_gdb_regs_for_features(cpu);

370 371
    init_cpreg_list(cpu);

372
    qemu_init_vcpu(cs);
373
    cpu_reset(cs);
374 375

    acc->parent_realize(dev, errp);
376 377
}

378 379 380
static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
{
    ObjectClass *oc;
A
Andreas Färber 已提交
381
    char *typename;
382 383 384 385 386

    if (!cpu_model) {
        return NULL;
    }

A
Andreas Färber 已提交
387 388 389
    typename = g_strdup_printf("%s-" TYPE_ARM_CPU, cpu_model);
    oc = object_class_by_name(typename);
    g_free(typename);
390 391
    if (!oc || !object_class_dynamic_cast(oc, TYPE_ARM_CPU) ||
        object_class_is_abstract(oc)) {
392 393 394 395 396
        return NULL;
    }
    return oc;
}

397 398 399
/* CPU models. These are not needed for the AArch64 linux-user build. */
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)

400 401 402
static void arm926_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
403 404

    cpu->dtb_compatible = "arm,arm926";
405 406
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
407 408
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
409
    cpu->midr = 0x41069265;
410
    cpu->reset_fpsid = 0x41011090;
411
    cpu->ctr = 0x1dd20d2;
412
    cpu->reset_sctlr = 0x00090078;
413 414 415 416 417
}

static void arm946_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
418 419

    cpu->dtb_compatible = "arm,arm946";
420 421
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_MPU);
422
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
423
    cpu->midr = 0x41059461;
424
    cpu->ctr = 0x0f004006;
425
    cpu->reset_sctlr = 0x00000078;
426 427 428 429 430
}

static void arm1026_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
431 432

    cpu->dtb_compatible = "arm,arm1026";
433 434 435
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
    set_feature(&cpu->env, ARM_FEATURE_AUXCR);
436 437
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
438
    cpu->midr = 0x4106a262;
439
    cpu->reset_fpsid = 0x410110a0;
440
    cpu->ctr = 0x1dd20d2;
441
    cpu->reset_sctlr = 0x00090078;
442
    cpu->reset_auxcr = 1;
443 444 445 446 447
    {
        /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
        ARMCPRegInfo ifar = {
            .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
            .access = PL1_RW,
448
            .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el1),
449 450 451 452
            .resetvalue = 0
        };
        define_one_arm_cp_reg(cpu, &ifar);
    }
453 454 455 456 457
}

static void arm1136_r2_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
458 459 460 461 462 463 464
    /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
     * older core than plain "arm1136". In particular this does not
     * have the v6K features.
     * These ID register values are correct for 1136 but may be wrong
     * for 1136_r2 (in particular r0p2 does not actually implement most
     * of the ID registers).
     */
465 466

    cpu->dtb_compatible = "arm,arm1136";
467 468
    set_feature(&cpu->env, ARM_FEATURE_V6);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
469 470 471
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
472
    cpu->midr = 0x4107b362;
473
    cpu->reset_fpsid = 0x410120b4;
474 475
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
476
    cpu->ctr = 0x1dd20d2;
477
    cpu->reset_sctlr = 0x00050078;
478 479 480 481 482 483 484 485 486 487 488 489
    cpu->id_pfr0 = 0x111;
    cpu->id_pfr1 = 0x1;
    cpu->id_dfr0 = 0x2;
    cpu->id_afr0 = 0x3;
    cpu->id_mmfr0 = 0x01130003;
    cpu->id_mmfr1 = 0x10030302;
    cpu->id_mmfr2 = 0x01222110;
    cpu->id_isar0 = 0x00140011;
    cpu->id_isar1 = 0x12002111;
    cpu->id_isar2 = 0x11231111;
    cpu->id_isar3 = 0x01102131;
    cpu->id_isar4 = 0x141;
490
    cpu->reset_auxcr = 7;
491 492 493 494 495
}

static void arm1136_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
496 497

    cpu->dtb_compatible = "arm,arm1136";
498 499 500
    set_feature(&cpu->env, ARM_FEATURE_V6K);
    set_feature(&cpu->env, ARM_FEATURE_V6);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
501 502 503
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
504
    cpu->midr = 0x4117b363;
505
    cpu->reset_fpsid = 0x410120b4;
506 507
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
508
    cpu->ctr = 0x1dd20d2;
509
    cpu->reset_sctlr = 0x00050078;
510 511 512 513 514 515 516 517 518 519 520 521
    cpu->id_pfr0 = 0x111;
    cpu->id_pfr1 = 0x1;
    cpu->id_dfr0 = 0x2;
    cpu->id_afr0 = 0x3;
    cpu->id_mmfr0 = 0x01130003;
    cpu->id_mmfr1 = 0x10030302;
    cpu->id_mmfr2 = 0x01222110;
    cpu->id_isar0 = 0x00140011;
    cpu->id_isar1 = 0x12002111;
    cpu->id_isar2 = 0x11231111;
    cpu->id_isar3 = 0x01102131;
    cpu->id_isar4 = 0x141;
522
    cpu->reset_auxcr = 7;
523 524 525 526 527
}

static void arm1176_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
528 529

    cpu->dtb_compatible = "arm,arm1176";
530 531 532
    set_feature(&cpu->env, ARM_FEATURE_V6K);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
    set_feature(&cpu->env, ARM_FEATURE_VAPA);
533 534 535
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
536
    cpu->midr = 0x410fb767;
537
    cpu->reset_fpsid = 0x410120b5;
538 539
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
540
    cpu->ctr = 0x1dd20d2;
541
    cpu->reset_sctlr = 0x00050078;
542 543 544 545 546 547 548 549 550 551 552 553
    cpu->id_pfr0 = 0x111;
    cpu->id_pfr1 = 0x11;
    cpu->id_dfr0 = 0x33;
    cpu->id_afr0 = 0;
    cpu->id_mmfr0 = 0x01130003;
    cpu->id_mmfr1 = 0x10030302;
    cpu->id_mmfr2 = 0x01222100;
    cpu->id_isar0 = 0x0140011;
    cpu->id_isar1 = 0x12002111;
    cpu->id_isar2 = 0x11231121;
    cpu->id_isar3 = 0x01102131;
    cpu->id_isar4 = 0x01141;
554
    cpu->reset_auxcr = 7;
555 556 557 558 559
}

static void arm11mpcore_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
560 561

    cpu->dtb_compatible = "arm,arm11mpcore";
562 563 564
    set_feature(&cpu->env, ARM_FEATURE_V6K);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
    set_feature(&cpu->env, ARM_FEATURE_VAPA);
P
Peter Maydell 已提交
565
    set_feature(&cpu->env, ARM_FEATURE_MPIDR);
566
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
567
    cpu->midr = 0x410fb022;
568
    cpu->reset_fpsid = 0x410120b4;
569 570
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
571
    cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
572 573 574 575 576 577 578 579 580 581 582 583
    cpu->id_pfr0 = 0x111;
    cpu->id_pfr1 = 0x1;
    cpu->id_dfr0 = 0;
    cpu->id_afr0 = 0x2;
    cpu->id_mmfr0 = 0x01100103;
    cpu->id_mmfr1 = 0x10020302;
    cpu->id_mmfr2 = 0x01222000;
    cpu->id_isar0 = 0x00100011;
    cpu->id_isar1 = 0x12002111;
    cpu->id_isar2 = 0x11221011;
    cpu->id_isar3 = 0x01102131;
    cpu->id_isar4 = 0x141;
584
    cpu->reset_auxcr = 1;
585 586 587 588 589
}

static void cortex_m3_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
590 591
    set_feature(&cpu->env, ARM_FEATURE_V7);
    set_feature(&cpu->env, ARM_FEATURE_M);
592
    cpu->midr = 0x410fc231;
593 594
}

595 596 597 598 599 600 601 602 603
static void arm_v7m_class_init(ObjectClass *oc, void *data)
{
#ifndef CONFIG_USER_ONLY
    CPUClass *cc = CPU_CLASS(oc);

    cc->do_interrupt = arm_v7m_cpu_do_interrupt;
#endif
}

604 605 606 607 608 609 610 611
static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
    { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0,
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
    { .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
    REGINFO_SENTINEL
};

612 613 614
static void cortex_a8_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
615 616

    cpu->dtb_compatible = "arm,cortex-a8";
617 618 619 620
    set_feature(&cpu->env, ARM_FEATURE_V7);
    set_feature(&cpu->env, ARM_FEATURE_VFP3);
    set_feature(&cpu->env, ARM_FEATURE_NEON);
    set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
621
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
622
    cpu->midr = 0x410fc080;
623
    cpu->reset_fpsid = 0x410330c0;
624 625
    cpu->mvfr0 = 0x11110222;
    cpu->mvfr1 = 0x00011100;
626
    cpu->ctr = 0x82048004;
627
    cpu->reset_sctlr = 0x00c50078;
628 629 630 631 632 633 634 635 636 637 638 639 640
    cpu->id_pfr0 = 0x1031;
    cpu->id_pfr1 = 0x11;
    cpu->id_dfr0 = 0x400;
    cpu->id_afr0 = 0;
    cpu->id_mmfr0 = 0x31100003;
    cpu->id_mmfr1 = 0x20000000;
    cpu->id_mmfr2 = 0x01202000;
    cpu->id_mmfr3 = 0x11;
    cpu->id_isar0 = 0x00101111;
    cpu->id_isar1 = 0x12112111;
    cpu->id_isar2 = 0x21232031;
    cpu->id_isar3 = 0x11112131;
    cpu->id_isar4 = 0x00111142;
641 642 643 644
    cpu->clidr = (1 << 27) | (2 << 24) | 3;
    cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
    cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
    cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */
645
    cpu->reset_auxcr = 2;
646
    define_arm_cp_regs(cpu, cortexa8_cp_reginfo);
647 648
}

649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677
static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
    /* power_control should be set to maximum latency. Again,
     * default to 0 and set by private hook
     */
    { .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
      .access = PL1_RW, .resetvalue = 0,
      .fieldoffset = offsetof(CPUARMState, cp15.c15_power_control) },
    { .name = "A9_DIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 1,
      .access = PL1_RW, .resetvalue = 0,
      .fieldoffset = offsetof(CPUARMState, cp15.c15_diagnostic) },
    { .name = "A9_PWRDIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 2,
      .access = PL1_RW, .resetvalue = 0,
      .fieldoffset = offsetof(CPUARMState, cp15.c15_power_diagnostic) },
    { .name = "NEONBUSY", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
      .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
    /* TLB lockdown control */
    { .name = "TLB_LOCKR", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 2,
      .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP },
    { .name = "TLB_LOCKW", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 4,
      .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP },
    { .name = "TLB_VA", .cp = 15, .crn = 15, .crm = 5, .opc1 = 5, .opc2 = 2,
      .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
    { .name = "TLB_PA", .cp = 15, .crn = 15, .crm = 6, .opc1 = 5, .opc2 = 2,
      .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
    { .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2,
      .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
    REGINFO_SENTINEL
};

678 679 680
static void cortex_a9_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
681 682

    cpu->dtb_compatible = "arm,cortex-a9";
683 684 685 686 687 688 689 690 691 692
    set_feature(&cpu->env, ARM_FEATURE_V7);
    set_feature(&cpu->env, ARM_FEATURE_VFP3);
    set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
    set_feature(&cpu->env, ARM_FEATURE_NEON);
    set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
    /* Note that A9 supports the MP extensions even for
     * A9UP and single-core A9MP (which are both different
     * and valid configurations; we don't model A9UP).
     */
    set_feature(&cpu->env, ARM_FEATURE_V7MP);
693
    set_feature(&cpu->env, ARM_FEATURE_CBAR);
694
    cpu->midr = 0x410fc090;
695
    cpu->reset_fpsid = 0x41033090;
696 697
    cpu->mvfr0 = 0x11110222;
    cpu->mvfr1 = 0x01111111;
698
    cpu->ctr = 0x80038003;
699
    cpu->reset_sctlr = 0x00c50078;
700 701 702 703 704 705 706 707 708 709 710 711 712
    cpu->id_pfr0 = 0x1031;
    cpu->id_pfr1 = 0x11;
    cpu->id_dfr0 = 0x000;
    cpu->id_afr0 = 0;
    cpu->id_mmfr0 = 0x00100103;
    cpu->id_mmfr1 = 0x20000000;
    cpu->id_mmfr2 = 0x01230000;
    cpu->id_mmfr3 = 0x00002111;
    cpu->id_isar0 = 0x00101111;
    cpu->id_isar1 = 0x13112111;
    cpu->id_isar2 = 0x21232041;
    cpu->id_isar3 = 0x11112131;
    cpu->id_isar4 = 0x00111142;
713 714 715
    cpu->clidr = (1 << 27) | (1 << 24) | 3;
    cpu->ccsidr[0] = 0xe00fe015; /* 16k L1 dcache. */
    cpu->ccsidr[1] = 0x200fe015; /* 16k L1 icache. */
716
    define_arm_cp_regs(cpu, cortexa9_cp_reginfo);
717 718
}

719
#ifndef CONFIG_USER_ONLY
720
static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
721 722 723 724
{
    /* Linux wants the number of processors from here.
     * Might as well set the interrupt-controller bit too.
     */
725
    return ((smp_cpus - 1) << 24) | (1 << 23);
726 727 728 729 730 731 732 733 734 735 736 737 738 739
}
#endif

static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
#ifndef CONFIG_USER_ONLY
    { .name = "L2CTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
      .access = PL1_RW, .resetvalue = 0, .readfn = a15_l2ctlr_read,
      .writefn = arm_cp_write_ignore, },
#endif
    { .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3,
      .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
    REGINFO_SENTINEL
};

740 741 742
static void cortex_a15_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
743 744

    cpu->dtb_compatible = "arm,cortex-a15";
745 746 747 748 749 750 751
    set_feature(&cpu->env, ARM_FEATURE_V7);
    set_feature(&cpu->env, ARM_FEATURE_VFP4);
    set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
    set_feature(&cpu->env, ARM_FEATURE_NEON);
    set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
    set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
    set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
752
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
753
    set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
754
    set_feature(&cpu->env, ARM_FEATURE_LPAE);
755
    cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
756
    cpu->midr = 0x412fc0f1;
757
    cpu->reset_fpsid = 0x410430f0;
758 759
    cpu->mvfr0 = 0x10110222;
    cpu->mvfr1 = 0x11111111;
760
    cpu->ctr = 0x8444c004;
761
    cpu->reset_sctlr = 0x00c50078;
762 763 764 765 766 767 768 769 770 771 772 773 774
    cpu->id_pfr0 = 0x00001131;
    cpu->id_pfr1 = 0x00011011;
    cpu->id_dfr0 = 0x02010555;
    cpu->id_afr0 = 0x00000000;
    cpu->id_mmfr0 = 0x10201105;
    cpu->id_mmfr1 = 0x20000000;
    cpu->id_mmfr2 = 0x01240000;
    cpu->id_mmfr3 = 0x02102211;
    cpu->id_isar0 = 0x02101110;
    cpu->id_isar1 = 0x13112111;
    cpu->id_isar2 = 0x21232041;
    cpu->id_isar3 = 0x11112131;
    cpu->id_isar4 = 0x10011142;
775 776 777 778
    cpu->clidr = 0x0a200023;
    cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
    cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
    cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
779
    define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
780 781 782 783 784
}

static void ti925t_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
785 786
    set_feature(&cpu->env, ARM_FEATURE_V4T);
    set_feature(&cpu->env, ARM_FEATURE_OMAPCP);
787
    cpu->midr = ARM_CPUID_TI925T;
788
    cpu->ctr = 0x5109149;
789
    cpu->reset_sctlr = 0x00000070;
790 791 792 793 794
}

static void sa1100_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
795 796

    cpu->dtb_compatible = "intel,sa1100";
797
    set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
798
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
799
    cpu->midr = 0x4401A11B;
800
    cpu->reset_sctlr = 0x00000070;
801 802 803 804 805
}

static void sa1110_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
806
    set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
807
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
808
    cpu->midr = 0x6901B119;
809
    cpu->reset_sctlr = 0x00000070;
810 811 812 813 814
}

static void pxa250_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
815 816

    cpu->dtb_compatible = "marvell,xscale";
817 818
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
819
    cpu->midr = 0x69052100;
820
    cpu->ctr = 0xd172172;
821
    cpu->reset_sctlr = 0x00000078;
822 823 824 825 826
}

static void pxa255_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
827 828

    cpu->dtb_compatible = "marvell,xscale";
829 830
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
831
    cpu->midr = 0x69052d00;
832
    cpu->ctr = 0xd172172;
833
    cpu->reset_sctlr = 0x00000078;
834 835 836 837 838
}

static void pxa260_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
839 840

    cpu->dtb_compatible = "marvell,xscale";
841 842
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
843
    cpu->midr = 0x69052903;
844
    cpu->ctr = 0xd172172;
845
    cpu->reset_sctlr = 0x00000078;
846 847 848 849 850
}

static void pxa261_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
851 852

    cpu->dtb_compatible = "marvell,xscale";
853 854
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
855
    cpu->midr = 0x69052d05;
856
    cpu->ctr = 0xd172172;
857
    cpu->reset_sctlr = 0x00000078;
858 859 860 861 862
}

static void pxa262_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
863 864

    cpu->dtb_compatible = "marvell,xscale";
865 866
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
867
    cpu->midr = 0x69052d06;
868
    cpu->ctr = 0xd172172;
869
    cpu->reset_sctlr = 0x00000078;
870 871 872 873 874
}

static void pxa270a0_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
875 876

    cpu->dtb_compatible = "marvell,xscale";
877 878 879
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
880
    cpu->midr = 0x69054110;
881
    cpu->ctr = 0xd172172;
882
    cpu->reset_sctlr = 0x00000078;
883 884 885 886 887
}

static void pxa270a1_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
888 889

    cpu->dtb_compatible = "marvell,xscale";
890 891 892
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
893
    cpu->midr = 0x69054111;
894
    cpu->ctr = 0xd172172;
895
    cpu->reset_sctlr = 0x00000078;
896 897 898 899 900
}

static void pxa270b0_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
901 902

    cpu->dtb_compatible = "marvell,xscale";
903 904 905
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
906
    cpu->midr = 0x69054112;
907
    cpu->ctr = 0xd172172;
908
    cpu->reset_sctlr = 0x00000078;
909 910 911 912 913
}

static void pxa270b1_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
914 915

    cpu->dtb_compatible = "marvell,xscale";
916 917 918
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
919
    cpu->midr = 0x69054113;
920
    cpu->ctr = 0xd172172;
921
    cpu->reset_sctlr = 0x00000078;
922 923 924 925 926
}

static void pxa270c0_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
927 928

    cpu->dtb_compatible = "marvell,xscale";
929 930 931
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
932
    cpu->midr = 0x69054114;
933
    cpu->ctr = 0xd172172;
934
    cpu->reset_sctlr = 0x00000078;
935 936 937 938 939
}

static void pxa270c5_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
940 941

    cpu->dtb_compatible = "marvell,xscale";
942 943 944
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
945
    cpu->midr = 0x69054117;
946
    cpu->ctr = 0xd172172;
947
    cpu->reset_sctlr = 0x00000078;
948 949
}

950
#ifdef CONFIG_USER_ONLY
951 952 953
static void arm_any_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
954
    set_feature(&cpu->env, ARM_FEATURE_V8);
955 956 957 958
    set_feature(&cpu->env, ARM_FEATURE_VFP4);
    set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
    set_feature(&cpu->env, ARM_FEATURE_NEON);
    set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
959 960 961 962
    set_feature(&cpu->env, ARM_FEATURE_V8_AES);
    set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
    set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
    set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
963
    set_feature(&cpu->env, ARM_FEATURE_CRC);
964
    cpu->midr = 0xffffffff;
965
}
966
#endif
967

968 969
#endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */

970 971 972
typedef struct ARMCPUInfo {
    const char *name;
    void (*initfn)(Object *obj);
973
    void (*class_init)(ObjectClass *oc, void *data);
974 975 976
} ARMCPUInfo;

static const ARMCPUInfo arm_cpus[] = {
977
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
978 979 980 981 982 983 984 985 986 987 988
    { .name = "arm926",      .initfn = arm926_initfn },
    { .name = "arm946",      .initfn = arm946_initfn },
    { .name = "arm1026",     .initfn = arm1026_initfn },
    /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
     * older core than plain "arm1136". In particular this does not
     * have the v6K features.
     */
    { .name = "arm1136-r2",  .initfn = arm1136_r2_initfn },
    { .name = "arm1136",     .initfn = arm1136_initfn },
    { .name = "arm1176",     .initfn = arm1176_initfn },
    { .name = "arm11mpcore", .initfn = arm11mpcore_initfn },
989 990
    { .name = "cortex-m3",   .initfn = cortex_m3_initfn,
                             .class_init = arm_v7m_class_init },
991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009
    { .name = "cortex-a8",   .initfn = cortex_a8_initfn },
    { .name = "cortex-a9",   .initfn = cortex_a9_initfn },
    { .name = "cortex-a15",  .initfn = cortex_a15_initfn },
    { .name = "ti925t",      .initfn = ti925t_initfn },
    { .name = "sa1100",      .initfn = sa1100_initfn },
    { .name = "sa1110",      .initfn = sa1110_initfn },
    { .name = "pxa250",      .initfn = pxa250_initfn },
    { .name = "pxa255",      .initfn = pxa255_initfn },
    { .name = "pxa260",      .initfn = pxa260_initfn },
    { .name = "pxa261",      .initfn = pxa261_initfn },
    { .name = "pxa262",      .initfn = pxa262_initfn },
    /* "pxa270" is an alias for "pxa270-a0" */
    { .name = "pxa270",      .initfn = pxa270a0_initfn },
    { .name = "pxa270-a0",   .initfn = pxa270a0_initfn },
    { .name = "pxa270-a1",   .initfn = pxa270a1_initfn },
    { .name = "pxa270-b0",   .initfn = pxa270b0_initfn },
    { .name = "pxa270-b1",   .initfn = pxa270b1_initfn },
    { .name = "pxa270-c0",   .initfn = pxa270c0_initfn },
    { .name = "pxa270-c5",   .initfn = pxa270c5_initfn },
1010
#ifdef CONFIG_USER_ONLY
1011
    { .name = "any",         .initfn = arm_any_initfn },
1012
#endif
1013
#endif
1014
    { .name = NULL }
1015 1016
};

1017 1018
static Property arm_cpu_properties[] = {
    DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
1019
    DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
1020 1021 1022
    DEFINE_PROP_END_OF_LIST()
};

1023 1024 1025 1026
static void arm_cpu_class_init(ObjectClass *oc, void *data)
{
    ARMCPUClass *acc = ARM_CPU_CLASS(oc);
    CPUClass *cc = CPU_CLASS(acc);
1027 1028 1029 1030
    DeviceClass *dc = DEVICE_CLASS(oc);

    acc->parent_realize = dc->realize;
    dc->realize = arm_cpu_realizefn;
1031
    dc->props = arm_cpu_properties;
1032 1033 1034

    acc->parent_reset = cc->reset;
    cc->reset = arm_cpu_reset;
1035 1036

    cc->class_by_name = arm_cpu_class_by_name;
1037
    cc->has_work = arm_cpu_has_work;
1038
    cc->do_interrupt = arm_cpu_do_interrupt;
1039
    cc->dump_state = arm_cpu_dump_state;
1040
    cc->set_pc = arm_cpu_set_pc;
1041 1042
    cc->gdb_read_register = arm_cpu_gdb_read_register;
    cc->gdb_write_register = arm_cpu_gdb_write_register;
1043 1044 1045
#ifdef CONFIG_USER_ONLY
    cc->handle_mmu_fault = arm_cpu_handle_mmu_fault;
#else
1046 1047 1048
    cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
    cc->vmsd = &vmstate_arm_cpu;
#endif
1049
    cc->gdb_num_core_regs = 26;
1050
    cc->gdb_core_xml_file = "arm-core.xml";
1051 1052
}

1053 1054 1055 1056 1057 1058 1059
static void cpu_register(const ARMCPUInfo *info)
{
    TypeInfo type_info = {
        .parent = TYPE_ARM_CPU,
        .instance_size = sizeof(ARMCPU),
        .instance_init = info->initfn,
        .class_size = sizeof(ARMCPUClass),
1060
        .class_init = info->class_init,
1061 1062
    };

A
Andreas Färber 已提交
1063
    type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name);
1064
    type_register(&type_info);
A
Andreas Färber 已提交
1065
    g_free((void *)type_info.name);
1066 1067
}

1068 1069 1070 1071
static const TypeInfo arm_cpu_type_info = {
    .name = TYPE_ARM_CPU,
    .parent = TYPE_CPU,
    .instance_size = sizeof(ARMCPU),
1072
    .instance_init = arm_cpu_initfn,
1073
    .instance_post_init = arm_cpu_post_init,
1074
    .instance_finalize = arm_cpu_finalizefn,
1075
    .abstract = true,
1076 1077 1078 1079 1080 1081
    .class_size = sizeof(ARMCPUClass),
    .class_init = arm_cpu_class_init,
};

static void arm_cpu_register_types(void)
{
1082
    const ARMCPUInfo *info = arm_cpus;
1083

1084
    type_register_static(&arm_cpu_type_info);
1085 1086 1087 1088

    while (info->name) {
        cpu_register(info);
        info++;
1089
    }
1090 1091 1092
}

type_init(arm_cpu_register_types)