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
    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);
319
        set_feature(env, ARM_FEATURE_V8_AES);
320
    }
321 322 323
    if (arm_feature(env, ARM_FEATURE_V7)) {
        set_feature(env, ARM_FEATURE_VAPA);
        set_feature(env, ARM_FEATURE_THUMB2);
P
Peter Maydell 已提交
324
        set_feature(env, ARM_FEATURE_MPIDR);
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 355
        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);
    }
356
    if (arm_feature(env, ARM_FEATURE_LPAE)) {
357
        set_feature(env, ARM_FEATURE_V7MP);
358 359
        set_feature(env, ARM_FEATURE_PXN);
    }
360 361 362
    if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
        set_feature(env, ARM_FEATURE_CBAR);
    }
363

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

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

371 372
    init_cpreg_list(cpu);

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

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

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

    if (!cpu_model) {
        return NULL;
    }

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

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

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

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

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

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

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

    cpu->dtb_compatible = "arm,arm1026";
434 435 436
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
    set_feature(&cpu->env, ARM_FEATURE_AUXCR);
437 438
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
439
    cpu->midr = 0x4106a262;
440
    cpu->reset_fpsid = 0x410110a0;
441
    cpu->ctr = 0x1dd20d2;
442
    cpu->reset_sctlr = 0x00090078;
443
    cpu->reset_auxcr = 1;
444 445 446 447 448
    {
        /* 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,
449
            .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el1),
450 451 452 453
            .resetvalue = 0
        };
        define_one_arm_cp_reg(cpu, &ifar);
    }
454 455 456 457 458
}

static void arm1136_r2_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
459 460 461 462 463 464 465
    /* 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).
     */
466 467

    cpu->dtb_compatible = "arm,arm1136";
468 469
    set_feature(&cpu->env, ARM_FEATURE_V6);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
470 471 472
    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);
473
    cpu->midr = 0x4107b362;
474
    cpu->reset_fpsid = 0x410120b4;
475 476
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
477
    cpu->ctr = 0x1dd20d2;
478
    cpu->reset_sctlr = 0x00050078;
479 480 481 482 483 484 485 486 487 488 489 490
    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;
491
    cpu->reset_auxcr = 7;
492 493 494 495 496
}

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

    cpu->dtb_compatible = "arm,arm1136";
499 500 501
    set_feature(&cpu->env, ARM_FEATURE_V6K);
    set_feature(&cpu->env, ARM_FEATURE_V6);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
502 503 504
    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);
505
    cpu->midr = 0x4117b363;
506
    cpu->reset_fpsid = 0x410120b4;
507 508
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
509
    cpu->ctr = 0x1dd20d2;
510
    cpu->reset_sctlr = 0x00050078;
511 512 513 514 515 516 517 518 519 520 521 522
    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;
523
    cpu->reset_auxcr = 7;
524 525 526 527 528
}

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

    cpu->dtb_compatible = "arm,arm1176";
531 532 533
    set_feature(&cpu->env, ARM_FEATURE_V6K);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
    set_feature(&cpu->env, ARM_FEATURE_VAPA);
534 535 536
    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);
537
    cpu->midr = 0x410fb767;
538
    cpu->reset_fpsid = 0x410120b5;
539 540
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
541
    cpu->ctr = 0x1dd20d2;
542
    cpu->reset_sctlr = 0x00050078;
543 544 545 546 547 548 549 550 551 552 553 554
    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;
555
    cpu->reset_auxcr = 7;
556 557 558 559 560
}

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

    cpu->dtb_compatible = "arm,arm11mpcore";
563 564 565
    set_feature(&cpu->env, ARM_FEATURE_V6K);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
    set_feature(&cpu->env, ARM_FEATURE_VAPA);
P
Peter Maydell 已提交
566
    set_feature(&cpu->env, ARM_FEATURE_MPIDR);
567
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
568
    cpu->midr = 0x410fb022;
569
    cpu->reset_fpsid = 0x410120b4;
570 571
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
572
    cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
573 574 575 576 577 578 579 580 581 582 583 584
    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;
585
    cpu->reset_auxcr = 1;
586 587 588 589 590
}

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

596 597 598 599 600 601 602 603 604
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
}

605 606 607 608 609 610 611 612
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
};

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

    cpu->dtb_compatible = "arm,cortex-a8";
618 619 620 621
    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);
622
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
623
    cpu->midr = 0x410fc080;
624
    cpu->reset_fpsid = 0x410330c0;
625 626
    cpu->mvfr0 = 0x11110222;
    cpu->mvfr1 = 0x00011100;
627
    cpu->ctr = 0x82048004;
628
    cpu->reset_sctlr = 0x00c50078;
629 630 631 632 633 634 635 636 637 638 639 640 641
    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;
642 643 644 645
    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. */
646
    cpu->reset_auxcr = 2;
647
    define_arm_cp_regs(cpu, cortexa8_cp_reginfo);
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 678
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
};

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

    cpu->dtb_compatible = "arm,cortex-a9";
684 685 686 687 688 689 690 691 692 693
    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);
694
    set_feature(&cpu->env, ARM_FEATURE_CBAR);
695
    cpu->midr = 0x410fc090;
696
    cpu->reset_fpsid = 0x41033090;
697 698
    cpu->mvfr0 = 0x11110222;
    cpu->mvfr1 = 0x01111111;
699
    cpu->ctr = 0x80038003;
700
    cpu->reset_sctlr = 0x00c50078;
701 702 703 704 705 706 707 708 709 710 711 712 713
    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;
714 715 716
    cpu->clidr = (1 << 27) | (1 << 24) | 3;
    cpu->ccsidr[0] = 0xe00fe015; /* 16k L1 dcache. */
    cpu->ccsidr[1] = 0x200fe015; /* 16k L1 icache. */
717
    define_arm_cp_regs(cpu, cortexa9_cp_reginfo);
718 719
}

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

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

    cpu->dtb_compatible = "arm,cortex-a15";
746 747 748 749 750 751 752
    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);
753
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
754
    set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
755
    set_feature(&cpu->env, ARM_FEATURE_LPAE);
756
    cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
757
    cpu->midr = 0x412fc0f1;
758
    cpu->reset_fpsid = 0x410430f0;
759 760
    cpu->mvfr0 = 0x10110222;
    cpu->mvfr1 = 0x11111111;
761
    cpu->ctr = 0x8444c004;
762
    cpu->reset_sctlr = 0x00c50078;
763 764 765 766 767 768 769 770 771 772 773 774 775
    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;
776 777 778 779
    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 */
780
    define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
781 782 783 784 785
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

951
#ifdef CONFIG_USER_ONLY
952 953 954
static void arm_any_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
955
    set_feature(&cpu->env, ARM_FEATURE_V8);
956 957 958 959 960 961
    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_V7MP);
962
    set_feature(&cpu->env, ARM_FEATURE_CRC);
963 964 965
#ifdef TARGET_AARCH64
    set_feature(&cpu->env, ARM_FEATURE_AARCH64);
#endif
966
    cpu->midr = 0xffffffff;
967
}
968
#endif
969

970 971
#endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */

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

static const ARMCPUInfo arm_cpus[] = {
979
#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
980 981 982 983 984 985 986 987 988 989 990
    { .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 },
991 992
    { .name = "cortex-m3",   .initfn = cortex_m3_initfn,
                             .class_init = arm_v7m_class_init },
993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011
    { .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 },
1012
#ifdef CONFIG_USER_ONLY
1013
    { .name = "any",         .initfn = arm_any_initfn },
1014
#endif
1015
#endif
1016
    { .name = NULL }
1017 1018
};

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

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

    acc->parent_realize = dc->realize;
    dc->realize = arm_cpu_realizefn;
1033
    dc->props = arm_cpu_properties;
1034 1035 1036

    acc->parent_reset = cc->reset;
    cc->reset = arm_cpu_reset;
1037 1038

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

1055 1056 1057 1058 1059 1060 1061
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),
1062
        .class_init = info->class_init,
1063 1064
    };

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

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

static void arm_cpu_register_types(void)
{
1084
    const ARMCPUInfo *info = arm_cpus;
1085

1086
    type_register_static(&arm_cpu_type_info);
1087 1088 1089 1090

    while (info->name) {
        cpu_register(info);
        info++;
1091
    }
1092 1093 1094
}

type_init(arm_cpu_register_types)