cpu.c 29.5 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 "qemu-common.h"
23 24 25
#if !defined(CONFIG_USER_ONLY)
#include "hw/loader.h"
#endif
26
#include "hw/arm/arm.h"
27
#include "sysemu/sysemu.h"
28
#include "sysemu/kvm.h"
29

30 31 32 33 34 35 36
static void arm_cpu_set_pc(CPUState *cs, vaddr value)
{
    ARMCPU *cpu = ARM_CPU(cs);

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

37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
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;
    }

    if (ri->type & ARM_CP_64BIT) {
        CPREG_FIELD64(&cpu->env, ri) = ri->resetvalue;
    } else {
        CPREG_FIELD32(&cpu->env, ri) = ri->resetvalue;
    }
}

68 69 70 71 72
/* CPUClass::reset() */
static void arm_cpu_reset(CPUState *s)
{
    ARMCPU *cpu = ARM_CPU(s);
    ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu);
73 74
    CPUARMState *env = &cpu->env;

75 76
    acc->parent_reset(s);

77
    memset(env, 0, offsetof(CPUARMState, breakpoints));
78
    g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu);
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
    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;

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

#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.  */
    env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
    /* 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;
        env->uncached_cpsr &= ~CPSR_I;
        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.  */
            env->regs[13] = ldl_p(rom);
            pc = ldl_p(rom + 4);
            env->thumb = pc & 1;
            env->regs[15] = pc & ~1;
        }
    }
    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);
    tlb_flush(env, 1);
    /* 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);
132 133
}

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
#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

183 184
static inline void set_feature(CPUARMState *env, int feature)
{
185
    env->features |= 1ULL << feature;
186 187
}

188 189
static void arm_cpu_initfn(Object *obj)
{
190
    CPUState *cs = CPU(obj);
191
    ARMCPU *cpu = ARM_CPU(obj);
192
    static bool inited;
193

194
    cs->env_ptr = &cpu->env;
195
    cpu_exec_init(&cpu->env);
196 197
    cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
                                         g_free, g_free);
198

199 200 201 202 203 204 205
#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);
    }
206

207
    cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
208
                                                arm_gt_ptimer_cb, cpu);
209
    cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
210 211 212
                                                arm_gt_vtimer_cb, cpu);
    qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs,
                       ARRAY_SIZE(cpu->gt_timer_outputs));
213 214
#endif

215 216 217 218
    if (tcg_enabled() && !inited) {
        inited = true;
        arm_translate_init();
    }
219 220 221 222 223 224
}

static void arm_cpu_finalizefn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
    g_hash_table_destroy(cpu->cp_regs);
225 226
}

227
static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
228
{
229
    CPUState *cs = CPU(dev);
230 231
    ARMCPU *cpu = ARM_CPU(dev);
    ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev);
232
    CPUARMState *env = &cpu->env;
233

234
    /* Some features automatically imply others: */
235 236 237 238 239
    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);
    }
240 241 242
    if (arm_feature(env, ARM_FEATURE_V7)) {
        set_feature(env, ARM_FEATURE_VAPA);
        set_feature(env, ARM_FEATURE_THUMB2);
P
Peter Maydell 已提交
243
        set_feature(env, ARM_FEATURE_MPIDR);
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
        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);
    }
275
    if (arm_feature(env, ARM_FEATURE_LPAE)) {
276
        set_feature(env, ARM_FEATURE_V7MP);
277 278
        set_feature(env, ARM_FEATURE_PXN);
    }
279 280

    register_cp_regs_for_features(cpu);
281 282
    arm_cpu_register_gdb_regs_for_features(cpu);

283 284
    init_cpreg_list(cpu);

285 286
    cpu_reset(cs);
    qemu_init_vcpu(cs);
287 288

    acc->parent_realize(dev, errp);
289 290
}

291 292
/* CPU models */

293 294 295
static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
{
    ObjectClass *oc;
A
Andreas Färber 已提交
296
    char *typename;
297 298 299 300 301

    if (!cpu_model) {
        return NULL;
    }

A
Andreas Färber 已提交
302 303 304
    typename = g_strdup_printf("%s-" TYPE_ARM_CPU, cpu_model);
    oc = object_class_by_name(typename);
    g_free(typename);
305 306
    if (!oc || !object_class_dynamic_cast(oc, TYPE_ARM_CPU) ||
        object_class_is_abstract(oc)) {
307 308 309 310 311
        return NULL;
    }
    return oc;
}

312 313 314
static void arm926_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
315 316
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
317 318
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
319
    cpu->midr = 0x41069265;
320
    cpu->reset_fpsid = 0x41011090;
321
    cpu->ctr = 0x1dd20d2;
322
    cpu->reset_sctlr = 0x00090078;
323 324 325 326 327
}

static void arm946_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
328 329
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_MPU);
330
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
331
    cpu->midr = 0x41059461;
332
    cpu->ctr = 0x0f004006;
333
    cpu->reset_sctlr = 0x00000078;
334 335 336 337 338
}

static void arm1026_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
339 340 341
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
    set_feature(&cpu->env, ARM_FEATURE_AUXCR);
342 343
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
    set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
344
    cpu->midr = 0x4106a262;
345
    cpu->reset_fpsid = 0x410110a0;
346
    cpu->ctr = 0x1dd20d2;
347
    cpu->reset_sctlr = 0x00090078;
348
    cpu->reset_auxcr = 1;
349 350 351 352 353 354 355 356 357 358
    {
        /* 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,
            .fieldoffset = offsetof(CPUARMState, cp15.c6_insn),
            .resetvalue = 0
        };
        define_one_arm_cp_reg(cpu, &ifar);
    }
359 360 361 362 363
}

static void arm1136_r2_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
364 365 366 367 368 369 370
    /* 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).
     */
371 372
    set_feature(&cpu->env, ARM_FEATURE_V6);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
373 374 375
    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);
376
    cpu->midr = 0x4107b362;
377
    cpu->reset_fpsid = 0x410120b4;
378 379
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
380
    cpu->ctr = 0x1dd20d2;
381
    cpu->reset_sctlr = 0x00050078;
382 383 384 385 386 387 388 389 390 391 392 393
    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;
394
    cpu->reset_auxcr = 7;
395 396 397 398 399
}

static void arm1136_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
400 401 402
    set_feature(&cpu->env, ARM_FEATURE_V6K);
    set_feature(&cpu->env, ARM_FEATURE_V6);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
403 404 405
    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);
406
    cpu->midr = 0x4117b363;
407
    cpu->reset_fpsid = 0x410120b4;
408 409
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
410
    cpu->ctr = 0x1dd20d2;
411
    cpu->reset_sctlr = 0x00050078;
412 413 414 415 416 417 418 419 420 421 422 423
    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;
424
    cpu->reset_auxcr = 7;
425 426 427 428 429
}

static void arm1176_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
430 431 432
    set_feature(&cpu->env, ARM_FEATURE_V6K);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
    set_feature(&cpu->env, ARM_FEATURE_VAPA);
433 434 435
    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);
436
    cpu->midr = 0x410fb767;
437
    cpu->reset_fpsid = 0x410120b5;
438 439
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
440
    cpu->ctr = 0x1dd20d2;
441
    cpu->reset_sctlr = 0x00050078;
442 443 444 445 446 447 448 449 450 451 452 453
    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;
454
    cpu->reset_auxcr = 7;
455 456 457 458 459
}

static void arm11mpcore_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
460 461 462
    set_feature(&cpu->env, ARM_FEATURE_V6K);
    set_feature(&cpu->env, ARM_FEATURE_VFP);
    set_feature(&cpu->env, ARM_FEATURE_VAPA);
P
Peter Maydell 已提交
463
    set_feature(&cpu->env, ARM_FEATURE_MPIDR);
464
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
465
    cpu->midr = 0x410fb022;
466
    cpu->reset_fpsid = 0x410120b4;
467 468
    cpu->mvfr0 = 0x11111111;
    cpu->mvfr1 = 0x00000000;
469
    cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
470 471 472 473 474 475 476 477 478 479 480 481
    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;
482
    cpu->reset_auxcr = 1;
483 484 485 486 487
}

static void cortex_m3_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
488 489
    set_feature(&cpu->env, ARM_FEATURE_V7);
    set_feature(&cpu->env, ARM_FEATURE_M);
490
    cpu->midr = 0x410fc231;
491 492
}

493 494 495 496 497 498 499 500 501
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
}

502 503 504 505 506 507 508 509
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
};

510 511 512
static void cortex_a8_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
513 514 515 516
    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);
517
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
518
    cpu->midr = 0x410fc080;
519
    cpu->reset_fpsid = 0x410330c0;
520 521
    cpu->mvfr0 = 0x11110222;
    cpu->mvfr1 = 0x00011100;
522
    cpu->ctr = 0x82048004;
523
    cpu->reset_sctlr = 0x00c50078;
524 525 526 527 528 529 530 531 532 533 534 535 536
    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;
537 538 539 540
    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. */
541
    cpu->reset_auxcr = 2;
542
    define_arm_cp_regs(cpu, cortexa8_cp_reginfo);
543 544
}

545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573
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
};

574 575 576
static void cortex_a9_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
577 578 579 580 581 582 583 584 585 586
    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);
587
    cpu->midr = 0x410fc090;
588
    cpu->reset_fpsid = 0x41033090;
589 590
    cpu->mvfr0 = 0x11110222;
    cpu->mvfr1 = 0x01111111;
591
    cpu->ctr = 0x80038003;
592
    cpu->reset_sctlr = 0x00c50078;
593 594 595 596 597 598 599 600 601 602 603 604 605
    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;
606 607 608
    cpu->clidr = (1 << 27) | (1 << 24) | 3;
    cpu->ccsidr[0] = 0xe00fe015; /* 16k L1 dcache. */
    cpu->ccsidr[1] = 0x200fe015; /* 16k L1 icache. */
609 610 611 612 613 614 615 616 617
    {
        ARMCPRegInfo cbar = {
            .name = "CBAR", .cp = 15, .crn = 15,  .crm = 0, .opc1 = 4,
            .opc2 = 0, .access = PL1_R|PL3_W, .resetvalue = cpu->reset_cbar,
            .fieldoffset = offsetof(CPUARMState, cp15.c15_config_base_address)
        };
        define_one_arm_cp_reg(cpu, &cbar);
        define_arm_cp_regs(cpu, cortexa9_cp_reginfo);
    }
618 619
}

620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642
#ifndef CONFIG_USER_ONLY
static int a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri,
                           uint64_t *value)
{
    /* Linux wants the number of processors from here.
     * Might as well set the interrupt-controller bit too.
     */
    *value = ((smp_cpus - 1) << 24) | (1 << 23);
    return 0;
}
#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
};

643 644 645
static void cortex_a15_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
646 647 648 649 650 651 652
    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);
653
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
654
    set_feature(&cpu->env, ARM_FEATURE_LPAE);
655
    cpu->midr = 0x412fc0f1;
656
    cpu->reset_fpsid = 0x410430f0;
657 658
    cpu->mvfr0 = 0x10110222;
    cpu->mvfr1 = 0x11111111;
659
    cpu->ctr = 0x8444c004;
660
    cpu->reset_sctlr = 0x00c50078;
661 662 663 664 665 666 667 668 669 670 671 672 673
    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;
674 675 676 677
    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 */
678
    define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
679 680 681 682 683
}

static void ti925t_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
684 685
    set_feature(&cpu->env, ARM_FEATURE_V4T);
    set_feature(&cpu->env, ARM_FEATURE_OMAPCP);
686
    cpu->midr = ARM_CPUID_TI925T;
687
    cpu->ctr = 0x5109149;
688
    cpu->reset_sctlr = 0x00000070;
689 690 691 692 693
}

static void sa1100_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
694
    set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
695
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
696
    cpu->midr = 0x4401A11B;
697
    cpu->reset_sctlr = 0x00000070;
698 699 700 701 702
}

static void sa1110_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
703
    set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
704
    set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
705
    cpu->midr = 0x6901B119;
706
    cpu->reset_sctlr = 0x00000070;
707 708 709 710 711
}

static void pxa250_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
712 713
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
714
    cpu->midr = 0x69052100;
715
    cpu->ctr = 0xd172172;
716
    cpu->reset_sctlr = 0x00000078;
717 718 719 720 721
}

static void pxa255_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
722 723
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
724
    cpu->midr = 0x69052d00;
725
    cpu->ctr = 0xd172172;
726
    cpu->reset_sctlr = 0x00000078;
727 728 729 730 731
}

static void pxa260_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
732 733
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
734
    cpu->midr = 0x69052903;
735
    cpu->ctr = 0xd172172;
736
    cpu->reset_sctlr = 0x00000078;
737 738 739 740 741
}

static void pxa261_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
742 743
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
744
    cpu->midr = 0x69052d05;
745
    cpu->ctr = 0xd172172;
746
    cpu->reset_sctlr = 0x00000078;
747 748 749 750 751
}

static void pxa262_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
752 753
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
754
    cpu->midr = 0x69052d06;
755
    cpu->ctr = 0xd172172;
756
    cpu->reset_sctlr = 0x00000078;
757 758 759 760 761
}

static void pxa270a0_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
762 763 764
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
765
    cpu->midr = 0x69054110;
766
    cpu->ctr = 0xd172172;
767
    cpu->reset_sctlr = 0x00000078;
768 769 770 771 772
}

static void pxa270a1_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
773 774 775
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
776
    cpu->midr = 0x69054111;
777
    cpu->ctr = 0xd172172;
778
    cpu->reset_sctlr = 0x00000078;
779 780 781 782 783
}

static void pxa270b0_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
784 785 786
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
787
    cpu->midr = 0x69054112;
788
    cpu->ctr = 0xd172172;
789
    cpu->reset_sctlr = 0x00000078;
790 791 792 793 794
}

static void pxa270b1_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
795 796 797
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
798
    cpu->midr = 0x69054113;
799
    cpu->ctr = 0xd172172;
800
    cpu->reset_sctlr = 0x00000078;
801 802 803 804 805
}

static void pxa270c0_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
806 807 808
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
809
    cpu->midr = 0x69054114;
810
    cpu->ctr = 0xd172172;
811
    cpu->reset_sctlr = 0x00000078;
812 813 814 815 816
}

static void pxa270c5_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
817 818 819
    set_feature(&cpu->env, ARM_FEATURE_V5);
    set_feature(&cpu->env, ARM_FEATURE_XSCALE);
    set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
820
    cpu->midr = 0x69054117;
821
    cpu->ctr = 0xd172172;
822
    cpu->reset_sctlr = 0x00000078;
823 824 825 826 827
}

static void arm_any_initfn(Object *obj)
{
    ARMCPU *cpu = ARM_CPU(obj);
828
    set_feature(&cpu->env, ARM_FEATURE_V8);
829 830 831 832 833 834
    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);
835
    cpu->midr = 0xffffffff;
836 837 838 839 840
}

typedef struct ARMCPUInfo {
    const char *name;
    void (*initfn)(Object *obj);
841
    void (*class_init)(ObjectClass *oc, void *data);
842 843 844 845 846 847 848 849 850 851 852 853 854 855
} ARMCPUInfo;

static const ARMCPUInfo arm_cpus[] = {
    { .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 },
856 857
    { .name = "cortex-m3",   .initfn = cortex_m3_initfn,
                             .class_init = arm_v7m_class_init },
858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879
    { .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 },
    { .name = "any",         .initfn = arm_any_initfn },
};

880 881 882 883
static void arm_cpu_class_init(ObjectClass *oc, void *data)
{
    ARMCPUClass *acc = ARM_CPU_CLASS(oc);
    CPUClass *cc = CPU_CLASS(acc);
884 885 886 887
    DeviceClass *dc = DEVICE_CLASS(oc);

    acc->parent_realize = dc->realize;
    dc->realize = arm_cpu_realizefn;
888 889 890

    acc->parent_reset = cc->reset;
    cc->reset = arm_cpu_reset;
891 892

    cc->class_by_name = arm_cpu_class_by_name;
893
    cc->do_interrupt = arm_cpu_do_interrupt;
894
    cc->dump_state = arm_cpu_dump_state;
895
    cc->set_pc = arm_cpu_set_pc;
896 897
    cc->gdb_read_register = arm_cpu_gdb_read_register;
    cc->gdb_write_register = arm_cpu_gdb_write_register;
898 899 900 901
#ifndef CONFIG_USER_ONLY
    cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
    cc->vmsd = &vmstate_arm_cpu;
#endif
902
    cc->gdb_num_core_regs = 26;
903
    cc->gdb_core_xml_file = "arm-core.xml";
904 905
}

906 907 908 909 910 911 912
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),
913
        .class_init = info->class_init,
914 915
    };

A
Andreas Färber 已提交
916
    type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name);
917
    type_register(&type_info);
A
Andreas Färber 已提交
918
    g_free((void *)type_info.name);
919 920
}

921 922 923 924
static const TypeInfo arm_cpu_type_info = {
    .name = TYPE_ARM_CPU,
    .parent = TYPE_CPU,
    .instance_size = sizeof(ARMCPU),
925
    .instance_init = arm_cpu_initfn,
926
    .instance_finalize = arm_cpu_finalizefn,
927
    .abstract = true,
928 929 930 931 932 933
    .class_size = sizeof(ARMCPUClass),
    .class_init = arm_cpu_class_init,
};

static void arm_cpu_register_types(void)
{
934 935
    int i;

936
    type_register_static(&arm_cpu_type_info);
937 938 939
    for (i = 0; i < ARRAY_SIZE(arm_cpus); i++) {
        cpu_register(&arm_cpus[i]);
    }
940 941 942
}

type_init(arm_cpu_register_types)