]> git.ipfire.org Git - thirdparty/qemu.git/blame - target-arm/cpu.c
gdbstub: Allow target CPUs to specify watchpoint STOP_BEFORE_ACCESS flag
[thirdparty/qemu.git] / target-arm / cpu.c
CommitLineData
dec9c2d4
AF
1/*
2 * QEMU ARM CPU
3 *
4 * Copyright (c) 2012 SUSE LINUX Products GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, see
18 * <http://www.gnu.org/licenses/gpl-2.0.html>
19 */
20
778c3a06 21#include "cpu.h"
ccd38087 22#include "internals.h"
dec9c2d4 23#include "qemu-common.h"
5de16430 24#include "hw/qdev-properties.h"
07a5b0d2 25#include "qapi/qmp/qerror.h"
3c30dd5a
PM
26#if !defined(CONFIG_USER_ONLY)
27#include "hw/loader.h"
28#endif
7c1840b6 29#include "hw/arm/arm.h"
9c17d615 30#include "sysemu/sysemu.h"
7c1840b6 31#include "sysemu/kvm.h"
50a2c6e5 32#include "kvm_arm.h"
dec9c2d4 33
f45748f1
AF
34static void arm_cpu_set_pc(CPUState *cs, vaddr value)
35{
36 ARMCPU *cpu = ARM_CPU(cs);
37
38 cpu->env.regs[15] = value;
39}
40
8c2e1b00
AF
41static bool arm_cpu_has_work(CPUState *cs)
42{
43 return cs->interrupt_request &
136e67e9
EI
44 (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
45 | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ
46 | CPU_INTERRUPT_EXITTB);
8c2e1b00
AF
47}
48
4b6a83fb
PM
49static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
50{
51 /* Reset a single ARMCPRegInfo register */
52 ARMCPRegInfo *ri = value;
53 ARMCPU *cpu = opaque;
54
55 if (ri->type & ARM_CP_SPECIAL) {
56 return;
57 }
58
59 if (ri->resetfn) {
60 ri->resetfn(&cpu->env, ri);
61 return;
62 }
63
64 /* A zero offset is never possible as it would be regs[0]
65 * so we use it to indicate that reset is being handled elsewhere.
66 * This is basically only used for fields in non-core coprocessors
67 * (like the pxa2xx ones).
68 */
69 if (!ri->fieldoffset) {
70 return;
71 }
72
67ed771d 73 if (cpreg_field_is_64bit(ri)) {
4b6a83fb
PM
74 CPREG_FIELD64(&cpu->env, ri) = ri->resetvalue;
75 } else {
76 CPREG_FIELD32(&cpu->env, ri) = ri->resetvalue;
77 }
78}
79
dec9c2d4
AF
80/* CPUClass::reset() */
81static void arm_cpu_reset(CPUState *s)
82{
83 ARMCPU *cpu = ARM_CPU(s);
84 ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu);
3c30dd5a 85 CPUARMState *env = &cpu->env;
3c30dd5a 86
dec9c2d4
AF
87 acc->parent_reset(s);
88
f0c3c505 89 memset(env, 0, offsetof(CPUARMState, features));
4b6a83fb 90 g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu);
3c30dd5a
PM
91 env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid;
92 env->vfp.xregs[ARM_VFP_MVFR0] = cpu->mvfr0;
93 env->vfp.xregs[ARM_VFP_MVFR1] = cpu->mvfr1;
a50c0f51 94 env->vfp.xregs[ARM_VFP_MVFR2] = cpu->mvfr2;
3c30dd5a
PM
95
96 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
97 env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
98 }
99
3926cc84
AG
100 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
101 /* 64 bit CPUs always start in 64 bit mode */
102 env->aarch64 = 1;
d356312f
PM
103#if defined(CONFIG_USER_ONLY)
104 env->pstate = PSTATE_MODE_EL0t;
8af35c37
PM
105 /* Userspace expects access to CTL_EL0 and the cache ops */
106 env->cp15.c1_sys |= SCTLR_UCT | SCTLR_UCI;
8c6afa6a
PM
107 /* and to the FP/Neon instructions */
108 env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 2, 3);
d356312f 109#else
4cc35614 110 env->pstate = PSTATE_MODE_EL1h;
3933443e 111 env->pc = cpu->rvbar;
8c6afa6a
PM
112#endif
113 } else {
114#if defined(CONFIG_USER_ONLY)
115 /* Userspace expects access to cp10 and cp11 for FP/Neon */
116 env->cp15.c1_coproc = deposit64(env->cp15.c1_coproc, 20, 4, 0xf);
d356312f 117#endif
3926cc84
AG
118 }
119
3c30dd5a
PM
120#if defined(CONFIG_USER_ONLY)
121 env->uncached_cpsr = ARM_CPU_MODE_USR;
122 /* For user mode we must enable access to coprocessors */
123 env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
124 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
125 env->cp15.c15_cpar = 3;
126 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
127 env->cp15.c15_cpar = 1;
128 }
129#else
130 /* SVC mode with interrupts disabled. */
4cc35614
PM
131 env->uncached_cpsr = ARM_CPU_MODE_SVC;
132 env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
3c30dd5a 133 /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
6e3cf5df
MG
134 * clear at reset. Initial SP and PC are loaded from ROM.
135 */
3c30dd5a 136 if (IS_M(env)) {
6e3cf5df
MG
137 uint32_t initial_msp; /* Loaded from 0x0 */
138 uint32_t initial_pc; /* Loaded from 0x4 */
3c30dd5a 139 uint8_t *rom;
6e3cf5df 140
4cc35614 141 env->daif &= ~PSTATE_I;
3c30dd5a
PM
142 rom = rom_ptr(0);
143 if (rom) {
6e3cf5df
MG
144 /* Address zero is covered by ROM which hasn't yet been
145 * copied into physical memory.
146 */
147 initial_msp = ldl_p(rom);
148 initial_pc = ldl_p(rom + 4);
149 } else {
150 /* Address zero not covered by a ROM blob, or the ROM blob
151 * is in non-modifiable memory and this is a second reset after
152 * it got copied into memory. In the latter case, rom_ptr
153 * will return a NULL pointer and we should use ldl_phys instead.
154 */
155 initial_msp = ldl_phys(s->as, 0);
156 initial_pc = ldl_phys(s->as, 4);
3c30dd5a 157 }
6e3cf5df
MG
158
159 env->regs[13] = initial_msp & 0xFFFFFFFC;
160 env->regs[15] = initial_pc & ~1;
161 env->thumb = initial_pc & 1;
3c30dd5a 162 }
387f9806 163
76e3e1bc 164 if (env->cp15.c1_sys & SCTLR_V) {
34bf7744 165 env->regs[15] = 0xFFFF0000;
387f9806
AP
166 }
167
3c30dd5a 168 env->vfp.xregs[ARM_VFP_FPEXC] = 0;
3c30dd5a
PM
169#endif
170 set_flush_to_zero(1, &env->vfp.standard_fp_status);
171 set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status);
172 set_default_nan_mode(1, &env->vfp.standard_fp_status);
173 set_float_detect_tininess(float_tininess_before_rounding,
174 &env->vfp.fp_status);
175 set_float_detect_tininess(float_tininess_before_rounding,
176 &env->vfp.standard_fp_status);
00c8cb0a 177 tlb_flush(s, 1);
50a2c6e5
PB
178
179#ifndef CONFIG_USER_ONLY
180 if (kvm_enabled()) {
181 kvm_arm_reset_vcpu(cpu);
182 }
183#endif
9ee98ce8 184
46747d15 185 hw_breakpoint_update_all(cpu);
9ee98ce8 186 hw_watchpoint_update_all(cpu);
dec9c2d4
AF
187}
188
e8925712
RH
189bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
190{
191 CPUClass *cc = CPU_GET_CLASS(cs);
e8925712
RH
192 bool ret = false;
193
194 if (interrupt_request & CPU_INTERRUPT_FIQ
043b7f8d 195 && arm_excp_unmasked(cs, EXCP_FIQ)) {
e8925712
RH
196 cs->exception_index = EXCP_FIQ;
197 cc->do_interrupt(cs);
198 ret = true;
199 }
200 /* ARMv7-M interrupt return works by loading a magic value
201 into the PC. On real hardware the load causes the
202 return to occur. The qemu implementation performs the
203 jump normally, then does the exception return when the
204 CPU tries to execute code at the magic address.
205 This will cause the magic PC value to be pushed to
206 the stack if an interrupt occurred at the wrong time.
207 We avoid this by disabling interrupts when
208 pc contains a magic address. */
209 if (interrupt_request & CPU_INTERRUPT_HARD
043b7f8d 210 && arm_excp_unmasked(cs, EXCP_IRQ)) {
e8925712
RH
211 cs->exception_index = EXCP_IRQ;
212 cc->do_interrupt(cs);
213 ret = true;
214 }
136e67e9
EI
215 if (interrupt_request & CPU_INTERRUPT_VIRQ
216 && arm_excp_unmasked(cs, EXCP_VIRQ)) {
217 cs->exception_index = EXCP_VIRQ;
218 cc->do_interrupt(cs);
219 ret = true;
220 }
221 if (interrupt_request & CPU_INTERRUPT_VFIQ
222 && arm_excp_unmasked(cs, EXCP_VFIQ)) {
223 cs->exception_index = EXCP_VFIQ;
224 cc->do_interrupt(cs);
225 ret = true;
226 }
e8925712
RH
227
228 return ret;
229}
230
7c1840b6
PM
231#ifndef CONFIG_USER_ONLY
232static void arm_cpu_set_irq(void *opaque, int irq, int level)
233{
234 ARMCPU *cpu = opaque;
136e67e9 235 CPUARMState *env = &cpu->env;
7c1840b6 236 CPUState *cs = CPU(cpu);
136e67e9
EI
237 static const int mask[] = {
238 [ARM_CPU_IRQ] = CPU_INTERRUPT_HARD,
239 [ARM_CPU_FIQ] = CPU_INTERRUPT_FIQ,
240 [ARM_CPU_VIRQ] = CPU_INTERRUPT_VIRQ,
241 [ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ
242 };
7c1840b6
PM
243
244 switch (irq) {
136e67e9
EI
245 case ARM_CPU_VIRQ:
246 case ARM_CPU_VFIQ:
247 if (!arm_feature(env, ARM_FEATURE_EL2)) {
248 hw_error("%s: Virtual interrupt line %d with no EL2 support\n",
249 __func__, irq);
7c1840b6 250 }
136e67e9
EI
251 /* fall through */
252 case ARM_CPU_IRQ:
7c1840b6
PM
253 case ARM_CPU_FIQ:
254 if (level) {
136e67e9 255 cpu_interrupt(cs, mask[irq]);
7c1840b6 256 } else {
136e67e9 257 cpu_reset_interrupt(cs, mask[irq]);
7c1840b6
PM
258 }
259 break;
260 default:
261 hw_error("arm_cpu_set_irq: Bad interrupt line %d\n", irq);
262 }
263}
264
265static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level)
266{
267#ifdef CONFIG_KVM
268 ARMCPU *cpu = opaque;
269 CPUState *cs = CPU(cpu);
270 int kvm_irq = KVM_ARM_IRQ_TYPE_CPU << KVM_ARM_IRQ_TYPE_SHIFT;
271
272 switch (irq) {
273 case ARM_CPU_IRQ:
274 kvm_irq |= KVM_ARM_IRQ_CPU_IRQ;
275 break;
276 case ARM_CPU_FIQ:
277 kvm_irq |= KVM_ARM_IRQ_CPU_FIQ;
278 break;
279 default:
280 hw_error("arm_cpu_kvm_set_irq: Bad interrupt line %d\n", irq);
281 }
282 kvm_irq |= cs->cpu_index << KVM_ARM_IRQ_VCPU_SHIFT;
283 kvm_set_irq(kvm_state, kvm_irq, level ? 1 : 0);
284#endif
285}
286#endif
287
581be094
PM
288static inline void set_feature(CPUARMState *env, int feature)
289{
918f5dca 290 env->features |= 1ULL << feature;
581be094
PM
291}
292
777dc784
PM
293static void arm_cpu_initfn(Object *obj)
294{
c05efcb1 295 CPUState *cs = CPU(obj);
777dc784 296 ARMCPU *cpu = ARM_CPU(obj);
79614b78 297 static bool inited;
777dc784 298
c05efcb1 299 cs->env_ptr = &cpu->env;
777dc784 300 cpu_exec_init(&cpu->env);
4b6a83fb
PM
301 cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
302 g_free, g_free);
79614b78 303
7c1840b6
PM
304#ifndef CONFIG_USER_ONLY
305 /* Our inbound IRQ and FIQ lines */
306 if (kvm_enabled()) {
136e67e9
EI
307 /* VIRQ and VFIQ are unused with KVM but we add them to maintain
308 * the same interface as non-KVM CPUs.
309 */
310 qdev_init_gpio_in(DEVICE(cpu), arm_cpu_kvm_set_irq, 4);
7c1840b6 311 } else {
136e67e9 312 qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 4);
7c1840b6 313 }
55d284af 314
bc72ad67 315 cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
55d284af 316 arm_gt_ptimer_cb, cpu);
bc72ad67 317 cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, GTIMER_SCALE,
55d284af
PM
318 arm_gt_vtimer_cb, cpu);
319 qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs,
320 ARRAY_SIZE(cpu->gt_timer_outputs));
7c1840b6
PM
321#endif
322
54d3e3f5
PM
323 /* DTB consumers generally don't in fact care what the 'compatible'
324 * string is, so always provide some string and trust that a hypothetical
325 * picky DTB consumer will also provide a helpful error message.
326 */
327 cpu->dtb_compatible = "qemu,unknown";
dd032e34 328 cpu->psci_version = 1; /* By default assume PSCI v0.1 */
3541addc 329 cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
54d3e3f5 330
79614b78
AF
331 if (tcg_enabled() && !inited) {
332 inited = true;
333 arm_translate_init();
334 }
4b6a83fb
PM
335}
336
07a5b0d2 337static Property arm_cpu_reset_cbar_property =
f318cec6 338 DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
07a5b0d2 339
68e0a40a
AP
340static Property arm_cpu_reset_hivecs_property =
341 DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false);
342
3933443e
PM
343static Property arm_cpu_rvbar_property =
344 DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0);
345
07a5b0d2
PC
346static void arm_cpu_post_init(Object *obj)
347{
348 ARMCPU *cpu = ARM_CPU(obj);
07a5b0d2 349
f318cec6
PM
350 if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
351 arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
07a5b0d2 352 qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property,
5433a0a8 353 &error_abort);
07a5b0d2 354 }
68e0a40a
AP
355
356 if (!arm_feature(&cpu->env, ARM_FEATURE_M)) {
357 qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property,
5433a0a8 358 &error_abort);
68e0a40a 359 }
3933443e
PM
360
361 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
362 qdev_property_add_static(DEVICE(obj), &arm_cpu_rvbar_property,
363 &error_abort);
364 }
07a5b0d2
PC
365}
366
4b6a83fb
PM
367static void arm_cpu_finalizefn(Object *obj)
368{
369 ARMCPU *cpu = ARM_CPU(obj);
370 g_hash_table_destroy(cpu->cp_regs);
777dc784
PM
371}
372
14969266 373static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
581be094 374{
14a10fc3 375 CPUState *cs = CPU(dev);
14969266
AF
376 ARMCPU *cpu = ARM_CPU(dev);
377 ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev);
581be094 378 CPUARMState *env = &cpu->env;
14969266 379
581be094 380 /* Some features automatically imply others: */
81e69fb0
MR
381 if (arm_feature(env, ARM_FEATURE_V8)) {
382 set_feature(env, ARM_FEATURE_V7);
383 set_feature(env, ARM_FEATURE_ARM_DIV);
384 set_feature(env, ARM_FEATURE_LPAE);
385 }
581be094
PM
386 if (arm_feature(env, ARM_FEATURE_V7)) {
387 set_feature(env, ARM_FEATURE_VAPA);
388 set_feature(env, ARM_FEATURE_THUMB2);
81bdde9d 389 set_feature(env, ARM_FEATURE_MPIDR);
581be094
PM
390 if (!arm_feature(env, ARM_FEATURE_M)) {
391 set_feature(env, ARM_FEATURE_V6K);
392 } else {
393 set_feature(env, ARM_FEATURE_V6);
394 }
395 }
396 if (arm_feature(env, ARM_FEATURE_V6K)) {
397 set_feature(env, ARM_FEATURE_V6);
398 set_feature(env, ARM_FEATURE_MVFR);
399 }
400 if (arm_feature(env, ARM_FEATURE_V6)) {
401 set_feature(env, ARM_FEATURE_V5);
402 if (!arm_feature(env, ARM_FEATURE_M)) {
403 set_feature(env, ARM_FEATURE_AUXCR);
404 }
405 }
406 if (arm_feature(env, ARM_FEATURE_V5)) {
407 set_feature(env, ARM_FEATURE_V4T);
408 }
409 if (arm_feature(env, ARM_FEATURE_M)) {
410 set_feature(env, ARM_FEATURE_THUMB_DIV);
411 }
412 if (arm_feature(env, ARM_FEATURE_ARM_DIV)) {
413 set_feature(env, ARM_FEATURE_THUMB_DIV);
414 }
415 if (arm_feature(env, ARM_FEATURE_VFP4)) {
416 set_feature(env, ARM_FEATURE_VFP3);
da5141fc 417 set_feature(env, ARM_FEATURE_VFP_FP16);
581be094
PM
418 }
419 if (arm_feature(env, ARM_FEATURE_VFP3)) {
420 set_feature(env, ARM_FEATURE_VFP);
421 }
de9b05b8 422 if (arm_feature(env, ARM_FEATURE_LPAE)) {
bdcc150d 423 set_feature(env, ARM_FEATURE_V7MP);
de9b05b8
PM
424 set_feature(env, ARM_FEATURE_PXN);
425 }
f318cec6
PM
426 if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
427 set_feature(env, ARM_FEATURE_CBAR);
428 }
2ceb98c0 429
68e0a40a
AP
430 if (cpu->reset_hivecs) {
431 cpu->reset_sctlr |= (1 << 13);
432 }
433
2ceb98c0 434 register_cp_regs_for_features(cpu);
14969266
AF
435 arm_cpu_register_gdb_regs_for_features(cpu);
436
721fae12
PM
437 init_cpreg_list(cpu);
438
14a10fc3 439 qemu_init_vcpu(cs);
00d0f7cb 440 cpu_reset(cs);
14969266
AF
441
442 acc->parent_realize(dev, errp);
581be094
PM
443}
444
5900d6b2
AF
445static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
446{
447 ObjectClass *oc;
51492fd1 448 char *typename;
5900d6b2
AF
449
450 if (!cpu_model) {
451 return NULL;
452 }
453
51492fd1
AF
454 typename = g_strdup_printf("%s-" TYPE_ARM_CPU, cpu_model);
455 oc = object_class_by_name(typename);
456 g_free(typename);
245fb54d
AF
457 if (!oc || !object_class_dynamic_cast(oc, TYPE_ARM_CPU) ||
458 object_class_is_abstract(oc)) {
5900d6b2
AF
459 return NULL;
460 }
461 return oc;
462}
463
15ee776b
PM
464/* CPU models. These are not needed for the AArch64 linux-user build. */
465#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
466
777dc784
PM
467static void arm926_initfn(Object *obj)
468{
469 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
470
471 cpu->dtb_compatible = "arm,arm926";
581be094
PM
472 set_feature(&cpu->env, ARM_FEATURE_V5);
473 set_feature(&cpu->env, ARM_FEATURE_VFP);
c4804214
PM
474 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
475 set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
b2d06f96 476 cpu->midr = 0x41069265;
325b3cef 477 cpu->reset_fpsid = 0x41011090;
64e1671f 478 cpu->ctr = 0x1dd20d2;
0ca7e01c 479 cpu->reset_sctlr = 0x00090078;
777dc784
PM
480}
481
482static void arm946_initfn(Object *obj)
483{
484 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
485
486 cpu->dtb_compatible = "arm,arm946";
581be094
PM
487 set_feature(&cpu->env, ARM_FEATURE_V5);
488 set_feature(&cpu->env, ARM_FEATURE_MPU);
c4804214 489 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
b2d06f96 490 cpu->midr = 0x41059461;
64e1671f 491 cpu->ctr = 0x0f004006;
0ca7e01c 492 cpu->reset_sctlr = 0x00000078;
777dc784
PM
493}
494
495static void arm1026_initfn(Object *obj)
496{
497 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
498
499 cpu->dtb_compatible = "arm,arm1026";
581be094
PM
500 set_feature(&cpu->env, ARM_FEATURE_V5);
501 set_feature(&cpu->env, ARM_FEATURE_VFP);
502 set_feature(&cpu->env, ARM_FEATURE_AUXCR);
c4804214
PM
503 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
504 set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
b2d06f96 505 cpu->midr = 0x4106a262;
325b3cef 506 cpu->reset_fpsid = 0x410110a0;
64e1671f 507 cpu->ctr = 0x1dd20d2;
0ca7e01c 508 cpu->reset_sctlr = 0x00090078;
2771db27 509 cpu->reset_auxcr = 1;
06d76f31
PM
510 {
511 /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
512 ARMCPRegInfo ifar = {
513 .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
514 .access = PL1_RW,
2f0180c5 515 .fieldoffset = offsetofhigh32(CPUARMState, cp15.far_el[1]),
06d76f31
PM
516 .resetvalue = 0
517 };
518 define_one_arm_cp_reg(cpu, &ifar);
519 }
777dc784
PM
520}
521
522static void arm1136_r2_initfn(Object *obj)
523{
524 ARMCPU *cpu = ARM_CPU(obj);
2e4d7e3e
PM
525 /* What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
526 * older core than plain "arm1136". In particular this does not
527 * have the v6K features.
528 * These ID register values are correct for 1136 but may be wrong
529 * for 1136_r2 (in particular r0p2 does not actually implement most
530 * of the ID registers).
531 */
54d3e3f5
PM
532
533 cpu->dtb_compatible = "arm,arm1136";
581be094
PM
534 set_feature(&cpu->env, ARM_FEATURE_V6);
535 set_feature(&cpu->env, ARM_FEATURE_VFP);
c4804214
PM
536 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
537 set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
538 set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
b2d06f96 539 cpu->midr = 0x4107b362;
325b3cef 540 cpu->reset_fpsid = 0x410120b4;
bd35c355
PM
541 cpu->mvfr0 = 0x11111111;
542 cpu->mvfr1 = 0x00000000;
64e1671f 543 cpu->ctr = 0x1dd20d2;
0ca7e01c 544 cpu->reset_sctlr = 0x00050078;
2e4d7e3e
PM
545 cpu->id_pfr0 = 0x111;
546 cpu->id_pfr1 = 0x1;
547 cpu->id_dfr0 = 0x2;
548 cpu->id_afr0 = 0x3;
549 cpu->id_mmfr0 = 0x01130003;
550 cpu->id_mmfr1 = 0x10030302;
551 cpu->id_mmfr2 = 0x01222110;
552 cpu->id_isar0 = 0x00140011;
553 cpu->id_isar1 = 0x12002111;
554 cpu->id_isar2 = 0x11231111;
555 cpu->id_isar3 = 0x01102131;
556 cpu->id_isar4 = 0x141;
2771db27 557 cpu->reset_auxcr = 7;
777dc784
PM
558}
559
560static void arm1136_initfn(Object *obj)
561{
562 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
563
564 cpu->dtb_compatible = "arm,arm1136";
581be094
PM
565 set_feature(&cpu->env, ARM_FEATURE_V6K);
566 set_feature(&cpu->env, ARM_FEATURE_V6);
567 set_feature(&cpu->env, ARM_FEATURE_VFP);
c4804214
PM
568 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
569 set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
570 set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
b2d06f96 571 cpu->midr = 0x4117b363;
325b3cef 572 cpu->reset_fpsid = 0x410120b4;
bd35c355
PM
573 cpu->mvfr0 = 0x11111111;
574 cpu->mvfr1 = 0x00000000;
64e1671f 575 cpu->ctr = 0x1dd20d2;
0ca7e01c 576 cpu->reset_sctlr = 0x00050078;
2e4d7e3e
PM
577 cpu->id_pfr0 = 0x111;
578 cpu->id_pfr1 = 0x1;
579 cpu->id_dfr0 = 0x2;
580 cpu->id_afr0 = 0x3;
581 cpu->id_mmfr0 = 0x01130003;
582 cpu->id_mmfr1 = 0x10030302;
583 cpu->id_mmfr2 = 0x01222110;
584 cpu->id_isar0 = 0x00140011;
585 cpu->id_isar1 = 0x12002111;
586 cpu->id_isar2 = 0x11231111;
587 cpu->id_isar3 = 0x01102131;
588 cpu->id_isar4 = 0x141;
2771db27 589 cpu->reset_auxcr = 7;
777dc784
PM
590}
591
592static void arm1176_initfn(Object *obj)
593{
594 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
595
596 cpu->dtb_compatible = "arm,arm1176";
581be094
PM
597 set_feature(&cpu->env, ARM_FEATURE_V6K);
598 set_feature(&cpu->env, ARM_FEATURE_VFP);
599 set_feature(&cpu->env, ARM_FEATURE_VAPA);
c4804214
PM
600 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
601 set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
602 set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
b2d06f96 603 cpu->midr = 0x410fb767;
325b3cef 604 cpu->reset_fpsid = 0x410120b5;
bd35c355
PM
605 cpu->mvfr0 = 0x11111111;
606 cpu->mvfr1 = 0x00000000;
64e1671f 607 cpu->ctr = 0x1dd20d2;
0ca7e01c 608 cpu->reset_sctlr = 0x00050078;
2e4d7e3e
PM
609 cpu->id_pfr0 = 0x111;
610 cpu->id_pfr1 = 0x11;
611 cpu->id_dfr0 = 0x33;
612 cpu->id_afr0 = 0;
613 cpu->id_mmfr0 = 0x01130003;
614 cpu->id_mmfr1 = 0x10030302;
615 cpu->id_mmfr2 = 0x01222100;
616 cpu->id_isar0 = 0x0140011;
617 cpu->id_isar1 = 0x12002111;
618 cpu->id_isar2 = 0x11231121;
619 cpu->id_isar3 = 0x01102131;
620 cpu->id_isar4 = 0x01141;
2771db27 621 cpu->reset_auxcr = 7;
777dc784
PM
622}
623
624static void arm11mpcore_initfn(Object *obj)
625{
626 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
627
628 cpu->dtb_compatible = "arm,arm11mpcore";
581be094
PM
629 set_feature(&cpu->env, ARM_FEATURE_V6K);
630 set_feature(&cpu->env, ARM_FEATURE_VFP);
631 set_feature(&cpu->env, ARM_FEATURE_VAPA);
81bdde9d 632 set_feature(&cpu->env, ARM_FEATURE_MPIDR);
c4804214 633 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
b2d06f96 634 cpu->midr = 0x410fb022;
325b3cef 635 cpu->reset_fpsid = 0x410120b4;
bd35c355
PM
636 cpu->mvfr0 = 0x11111111;
637 cpu->mvfr1 = 0x00000000;
200bf596 638 cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
2e4d7e3e
PM
639 cpu->id_pfr0 = 0x111;
640 cpu->id_pfr1 = 0x1;
641 cpu->id_dfr0 = 0;
642 cpu->id_afr0 = 0x2;
643 cpu->id_mmfr0 = 0x01100103;
644 cpu->id_mmfr1 = 0x10020302;
645 cpu->id_mmfr2 = 0x01222000;
646 cpu->id_isar0 = 0x00100011;
647 cpu->id_isar1 = 0x12002111;
648 cpu->id_isar2 = 0x11221011;
649 cpu->id_isar3 = 0x01102131;
650 cpu->id_isar4 = 0x141;
2771db27 651 cpu->reset_auxcr = 1;
777dc784
PM
652}
653
654static void cortex_m3_initfn(Object *obj)
655{
656 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
657 set_feature(&cpu->env, ARM_FEATURE_V7);
658 set_feature(&cpu->env, ARM_FEATURE_M);
b2d06f96 659 cpu->midr = 0x410fc231;
777dc784
PM
660}
661
e6f010cc
AF
662static void arm_v7m_class_init(ObjectClass *oc, void *data)
663{
664#ifndef CONFIG_USER_ONLY
665 CPUClass *cc = CPU_CLASS(oc);
666
667 cc->do_interrupt = arm_v7m_cpu_do_interrupt;
668#endif
669}
670
34f90529
PM
671static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
672 { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0,
673 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
674 { .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
675 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
676 REGINFO_SENTINEL
677};
678
777dc784
PM
679static void cortex_a8_initfn(Object *obj)
680{
681 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
682
683 cpu->dtb_compatible = "arm,cortex-a8";
581be094
PM
684 set_feature(&cpu->env, ARM_FEATURE_V7);
685 set_feature(&cpu->env, ARM_FEATURE_VFP3);
686 set_feature(&cpu->env, ARM_FEATURE_NEON);
687 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
c4804214 688 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
b2d06f96 689 cpu->midr = 0x410fc080;
325b3cef 690 cpu->reset_fpsid = 0x410330c0;
bd35c355
PM
691 cpu->mvfr0 = 0x11110222;
692 cpu->mvfr1 = 0x00011100;
64e1671f 693 cpu->ctr = 0x82048004;
0ca7e01c 694 cpu->reset_sctlr = 0x00c50078;
2e4d7e3e
PM
695 cpu->id_pfr0 = 0x1031;
696 cpu->id_pfr1 = 0x11;
697 cpu->id_dfr0 = 0x400;
698 cpu->id_afr0 = 0;
699 cpu->id_mmfr0 = 0x31100003;
700 cpu->id_mmfr1 = 0x20000000;
701 cpu->id_mmfr2 = 0x01202000;
702 cpu->id_mmfr3 = 0x11;
703 cpu->id_isar0 = 0x00101111;
704 cpu->id_isar1 = 0x12112111;
705 cpu->id_isar2 = 0x21232031;
706 cpu->id_isar3 = 0x11112131;
707 cpu->id_isar4 = 0x00111142;
48eb3ae6 708 cpu->dbgdidr = 0x15141000;
85df3786
PM
709 cpu->clidr = (1 << 27) | (2 << 24) | 3;
710 cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
711 cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
712 cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */
2771db27 713 cpu->reset_auxcr = 2;
34f90529 714 define_arm_cp_regs(cpu, cortexa8_cp_reginfo);
777dc784
PM
715}
716
1047b9d7
PM
717static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
718 /* power_control should be set to maximum latency. Again,
719 * default to 0 and set by private hook
720 */
721 { .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
722 .access = PL1_RW, .resetvalue = 0,
723 .fieldoffset = offsetof(CPUARMState, cp15.c15_power_control) },
724 { .name = "A9_DIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 1,
725 .access = PL1_RW, .resetvalue = 0,
726 .fieldoffset = offsetof(CPUARMState, cp15.c15_diagnostic) },
727 { .name = "A9_PWRDIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 2,
728 .access = PL1_RW, .resetvalue = 0,
729 .fieldoffset = offsetof(CPUARMState, cp15.c15_power_diagnostic) },
730 { .name = "NEONBUSY", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
731 .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
732 /* TLB lockdown control */
733 { .name = "TLB_LOCKR", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 2,
734 .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP },
735 { .name = "TLB_LOCKW", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 4,
736 .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP },
737 { .name = "TLB_VA", .cp = 15, .crn = 15, .crm = 5, .opc1 = 5, .opc2 = 2,
738 .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
739 { .name = "TLB_PA", .cp = 15, .crn = 15, .crm = 6, .opc1 = 5, .opc2 = 2,
740 .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
741 { .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2,
742 .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
743 REGINFO_SENTINEL
744};
745
777dc784
PM
746static void cortex_a9_initfn(Object *obj)
747{
748 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
749
750 cpu->dtb_compatible = "arm,cortex-a9";
581be094
PM
751 set_feature(&cpu->env, ARM_FEATURE_V7);
752 set_feature(&cpu->env, ARM_FEATURE_VFP3);
753 set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
754 set_feature(&cpu->env, ARM_FEATURE_NEON);
755 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
756 /* Note that A9 supports the MP extensions even for
757 * A9UP and single-core A9MP (which are both different
758 * and valid configurations; we don't model A9UP).
759 */
760 set_feature(&cpu->env, ARM_FEATURE_V7MP);
d8ba780b 761 set_feature(&cpu->env, ARM_FEATURE_CBAR);
b2d06f96 762 cpu->midr = 0x410fc090;
325b3cef 763 cpu->reset_fpsid = 0x41033090;
bd35c355
PM
764 cpu->mvfr0 = 0x11110222;
765 cpu->mvfr1 = 0x01111111;
64e1671f 766 cpu->ctr = 0x80038003;
0ca7e01c 767 cpu->reset_sctlr = 0x00c50078;
2e4d7e3e
PM
768 cpu->id_pfr0 = 0x1031;
769 cpu->id_pfr1 = 0x11;
770 cpu->id_dfr0 = 0x000;
771 cpu->id_afr0 = 0;
772 cpu->id_mmfr0 = 0x00100103;
773 cpu->id_mmfr1 = 0x20000000;
774 cpu->id_mmfr2 = 0x01230000;
775 cpu->id_mmfr3 = 0x00002111;
776 cpu->id_isar0 = 0x00101111;
777 cpu->id_isar1 = 0x13112111;
778 cpu->id_isar2 = 0x21232041;
779 cpu->id_isar3 = 0x11112131;
780 cpu->id_isar4 = 0x00111142;
48eb3ae6 781 cpu->dbgdidr = 0x35141000;
85df3786 782 cpu->clidr = (1 << 27) | (1 << 24) | 3;
f7838b52
PC
783 cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
784 cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */
d8ba780b 785 define_arm_cp_regs(cpu, cortexa9_cp_reginfo);
777dc784
PM
786}
787
34f90529 788#ifndef CONFIG_USER_ONLY
c4241c7d 789static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
34f90529
PM
790{
791 /* Linux wants the number of processors from here.
792 * Might as well set the interrupt-controller bit too.
793 */
c4241c7d 794 return ((smp_cpus - 1) << 24) | (1 << 23);
34f90529
PM
795}
796#endif
797
798static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
799#ifndef CONFIG_USER_ONLY
800 { .name = "L2CTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
801 .access = PL1_RW, .resetvalue = 0, .readfn = a15_l2ctlr_read,
802 .writefn = arm_cp_write_ignore, },
803#endif
804 { .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3,
805 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
806 REGINFO_SENTINEL
807};
808
777dc784
PM
809static void cortex_a15_initfn(Object *obj)
810{
811 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
812
813 cpu->dtb_compatible = "arm,cortex-a15";
581be094
PM
814 set_feature(&cpu->env, ARM_FEATURE_V7);
815 set_feature(&cpu->env, ARM_FEATURE_VFP4);
581be094
PM
816 set_feature(&cpu->env, ARM_FEATURE_NEON);
817 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
818 set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
581be094 819 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
c4804214 820 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
c29f9a0a 821 set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
de9b05b8 822 set_feature(&cpu->env, ARM_FEATURE_LPAE);
3541addc 823 cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A15;
b2d06f96 824 cpu->midr = 0x412fc0f1;
325b3cef 825 cpu->reset_fpsid = 0x410430f0;
bd35c355
PM
826 cpu->mvfr0 = 0x10110222;
827 cpu->mvfr1 = 0x11111111;
64e1671f 828 cpu->ctr = 0x8444c004;
0ca7e01c 829 cpu->reset_sctlr = 0x00c50078;
2e4d7e3e
PM
830 cpu->id_pfr0 = 0x00001131;
831 cpu->id_pfr1 = 0x00011011;
832 cpu->id_dfr0 = 0x02010555;
833 cpu->id_afr0 = 0x00000000;
834 cpu->id_mmfr0 = 0x10201105;
835 cpu->id_mmfr1 = 0x20000000;
836 cpu->id_mmfr2 = 0x01240000;
837 cpu->id_mmfr3 = 0x02102211;
838 cpu->id_isar0 = 0x02101110;
839 cpu->id_isar1 = 0x13112111;
840 cpu->id_isar2 = 0x21232041;
841 cpu->id_isar3 = 0x11112131;
842 cpu->id_isar4 = 0x10011142;
48eb3ae6 843 cpu->dbgdidr = 0x3515f021;
85df3786
PM
844 cpu->clidr = 0x0a200023;
845 cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
846 cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
847 cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
34f90529 848 define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
777dc784
PM
849}
850
851static void ti925t_initfn(Object *obj)
852{
853 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
854 set_feature(&cpu->env, ARM_FEATURE_V4T);
855 set_feature(&cpu->env, ARM_FEATURE_OMAPCP);
777dc784 856 cpu->midr = ARM_CPUID_TI925T;
64e1671f 857 cpu->ctr = 0x5109149;
0ca7e01c 858 cpu->reset_sctlr = 0x00000070;
777dc784
PM
859}
860
861static void sa1100_initfn(Object *obj)
862{
863 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
864
865 cpu->dtb_compatible = "intel,sa1100";
581be094 866 set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
c4804214 867 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
b2d06f96 868 cpu->midr = 0x4401A11B;
0ca7e01c 869 cpu->reset_sctlr = 0x00000070;
777dc784
PM
870}
871
872static void sa1110_initfn(Object *obj)
873{
874 ARMCPU *cpu = ARM_CPU(obj);
581be094 875 set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
c4804214 876 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
b2d06f96 877 cpu->midr = 0x6901B119;
0ca7e01c 878 cpu->reset_sctlr = 0x00000070;
777dc784
PM
879}
880
881static void pxa250_initfn(Object *obj)
882{
883 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
884
885 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
886 set_feature(&cpu->env, ARM_FEATURE_V5);
887 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
b2d06f96 888 cpu->midr = 0x69052100;
64e1671f 889 cpu->ctr = 0xd172172;
0ca7e01c 890 cpu->reset_sctlr = 0x00000078;
777dc784
PM
891}
892
893static void pxa255_initfn(Object *obj)
894{
895 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
896
897 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
898 set_feature(&cpu->env, ARM_FEATURE_V5);
899 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
b2d06f96 900 cpu->midr = 0x69052d00;
64e1671f 901 cpu->ctr = 0xd172172;
0ca7e01c 902 cpu->reset_sctlr = 0x00000078;
777dc784
PM
903}
904
905static void pxa260_initfn(Object *obj)
906{
907 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
908
909 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
910 set_feature(&cpu->env, ARM_FEATURE_V5);
911 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
b2d06f96 912 cpu->midr = 0x69052903;
64e1671f 913 cpu->ctr = 0xd172172;
0ca7e01c 914 cpu->reset_sctlr = 0x00000078;
777dc784
PM
915}
916
917static void pxa261_initfn(Object *obj)
918{
919 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
920
921 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
922 set_feature(&cpu->env, ARM_FEATURE_V5);
923 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
b2d06f96 924 cpu->midr = 0x69052d05;
64e1671f 925 cpu->ctr = 0xd172172;
0ca7e01c 926 cpu->reset_sctlr = 0x00000078;
777dc784
PM
927}
928
929static void pxa262_initfn(Object *obj)
930{
931 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
932
933 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
934 set_feature(&cpu->env, ARM_FEATURE_V5);
935 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
b2d06f96 936 cpu->midr = 0x69052d06;
64e1671f 937 cpu->ctr = 0xd172172;
0ca7e01c 938 cpu->reset_sctlr = 0x00000078;
777dc784
PM
939}
940
941static void pxa270a0_initfn(Object *obj)
942{
943 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
944
945 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
946 set_feature(&cpu->env, ARM_FEATURE_V5);
947 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
948 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
b2d06f96 949 cpu->midr = 0x69054110;
64e1671f 950 cpu->ctr = 0xd172172;
0ca7e01c 951 cpu->reset_sctlr = 0x00000078;
777dc784
PM
952}
953
954static void pxa270a1_initfn(Object *obj)
955{
956 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
957
958 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
959 set_feature(&cpu->env, ARM_FEATURE_V5);
960 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
961 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
b2d06f96 962 cpu->midr = 0x69054111;
64e1671f 963 cpu->ctr = 0xd172172;
0ca7e01c 964 cpu->reset_sctlr = 0x00000078;
777dc784
PM
965}
966
967static void pxa270b0_initfn(Object *obj)
968{
969 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
970
971 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
972 set_feature(&cpu->env, ARM_FEATURE_V5);
973 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
974 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
b2d06f96 975 cpu->midr = 0x69054112;
64e1671f 976 cpu->ctr = 0xd172172;
0ca7e01c 977 cpu->reset_sctlr = 0x00000078;
777dc784
PM
978}
979
980static void pxa270b1_initfn(Object *obj)
981{
982 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
983
984 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
985 set_feature(&cpu->env, ARM_FEATURE_V5);
986 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
987 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
b2d06f96 988 cpu->midr = 0x69054113;
64e1671f 989 cpu->ctr = 0xd172172;
0ca7e01c 990 cpu->reset_sctlr = 0x00000078;
777dc784
PM
991}
992
993static void pxa270c0_initfn(Object *obj)
994{
995 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
996
997 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
998 set_feature(&cpu->env, ARM_FEATURE_V5);
999 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
1000 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
b2d06f96 1001 cpu->midr = 0x69054114;
64e1671f 1002 cpu->ctr = 0xd172172;
0ca7e01c 1003 cpu->reset_sctlr = 0x00000078;
777dc784
PM
1004}
1005
1006static void pxa270c5_initfn(Object *obj)
1007{
1008 ARMCPU *cpu = ARM_CPU(obj);
54d3e3f5
PM
1009
1010 cpu->dtb_compatible = "marvell,xscale";
581be094
PM
1011 set_feature(&cpu->env, ARM_FEATURE_V5);
1012 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
1013 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
b2d06f96 1014 cpu->midr = 0x69054117;
64e1671f 1015 cpu->ctr = 0xd172172;
0ca7e01c 1016 cpu->reset_sctlr = 0x00000078;
777dc784
PM
1017}
1018
f5f6d38b 1019#ifdef CONFIG_USER_ONLY
777dc784
PM
1020static void arm_any_initfn(Object *obj)
1021{
1022 ARMCPU *cpu = ARM_CPU(obj);
81e69fb0 1023 set_feature(&cpu->env, ARM_FEATURE_V8);
581be094 1024 set_feature(&cpu->env, ARM_FEATURE_VFP4);
581be094
PM
1025 set_feature(&cpu->env, ARM_FEATURE_NEON);
1026 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
25f748e3
PM
1027 set_feature(&cpu->env, ARM_FEATURE_V8_AES);
1028 set_feature(&cpu->env, ARM_FEATURE_V8_SHA1);
1029 set_feature(&cpu->env, ARM_FEATURE_V8_SHA256);
1030 set_feature(&cpu->env, ARM_FEATURE_V8_PMULL);
eb0ecd5a 1031 set_feature(&cpu->env, ARM_FEATURE_CRC);
b2d06f96 1032 cpu->midr = 0xffffffff;
777dc784 1033}
f5f6d38b 1034#endif
777dc784 1035
15ee776b
PM
1036#endif /* !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64) */
1037
777dc784
PM
1038typedef struct ARMCPUInfo {
1039 const char *name;
1040 void (*initfn)(Object *obj);
e6f010cc 1041 void (*class_init)(ObjectClass *oc, void *data);
777dc784
PM
1042} ARMCPUInfo;
1043
1044static const ARMCPUInfo arm_cpus[] = {
15ee776b 1045#if !defined(CONFIG_USER_ONLY) || !defined(TARGET_AARCH64)
777dc784
PM
1046 { .name = "arm926", .initfn = arm926_initfn },
1047 { .name = "arm946", .initfn = arm946_initfn },
1048 { .name = "arm1026", .initfn = arm1026_initfn },
1049 /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
1050 * older core than plain "arm1136". In particular this does not
1051 * have the v6K features.
1052 */
1053 { .name = "arm1136-r2", .initfn = arm1136_r2_initfn },
1054 { .name = "arm1136", .initfn = arm1136_initfn },
1055 { .name = "arm1176", .initfn = arm1176_initfn },
1056 { .name = "arm11mpcore", .initfn = arm11mpcore_initfn },
e6f010cc
AF
1057 { .name = "cortex-m3", .initfn = cortex_m3_initfn,
1058 .class_init = arm_v7m_class_init },
777dc784
PM
1059 { .name = "cortex-a8", .initfn = cortex_a8_initfn },
1060 { .name = "cortex-a9", .initfn = cortex_a9_initfn },
1061 { .name = "cortex-a15", .initfn = cortex_a15_initfn },
1062 { .name = "ti925t", .initfn = ti925t_initfn },
1063 { .name = "sa1100", .initfn = sa1100_initfn },
1064 { .name = "sa1110", .initfn = sa1110_initfn },
1065 { .name = "pxa250", .initfn = pxa250_initfn },
1066 { .name = "pxa255", .initfn = pxa255_initfn },
1067 { .name = "pxa260", .initfn = pxa260_initfn },
1068 { .name = "pxa261", .initfn = pxa261_initfn },
1069 { .name = "pxa262", .initfn = pxa262_initfn },
1070 /* "pxa270" is an alias for "pxa270-a0" */
1071 { .name = "pxa270", .initfn = pxa270a0_initfn },
1072 { .name = "pxa270-a0", .initfn = pxa270a0_initfn },
1073 { .name = "pxa270-a1", .initfn = pxa270a1_initfn },
1074 { .name = "pxa270-b0", .initfn = pxa270b0_initfn },
1075 { .name = "pxa270-b1", .initfn = pxa270b1_initfn },
1076 { .name = "pxa270-c0", .initfn = pxa270c0_initfn },
1077 { .name = "pxa270-c5", .initfn = pxa270c5_initfn },
f5f6d38b 1078#ifdef CONFIG_USER_ONLY
777dc784 1079 { .name = "any", .initfn = arm_any_initfn },
f5f6d38b 1080#endif
15ee776b 1081#endif
83e6813a 1082 { .name = NULL }
777dc784
PM
1083};
1084
5de16430
PM
1085static Property arm_cpu_properties[] = {
1086 DEFINE_PROP_BOOL("start-powered-off", ARMCPU, start_powered_off, false),
51a9b04b 1087 DEFINE_PROP_UINT32("midr", ARMCPU, midr, 0),
5de16430
PM
1088 DEFINE_PROP_END_OF_LIST()
1089};
1090
dec9c2d4
AF
1091static void arm_cpu_class_init(ObjectClass *oc, void *data)
1092{
1093 ARMCPUClass *acc = ARM_CPU_CLASS(oc);
1094 CPUClass *cc = CPU_CLASS(acc);
14969266
AF
1095 DeviceClass *dc = DEVICE_CLASS(oc);
1096
1097 acc->parent_realize = dc->realize;
1098 dc->realize = arm_cpu_realizefn;
5de16430 1099 dc->props = arm_cpu_properties;
dec9c2d4
AF
1100
1101 acc->parent_reset = cc->reset;
1102 cc->reset = arm_cpu_reset;
5900d6b2
AF
1103
1104 cc->class_by_name = arm_cpu_class_by_name;
8c2e1b00 1105 cc->has_work = arm_cpu_has_work;
97a8ea5a 1106 cc->do_interrupt = arm_cpu_do_interrupt;
e8925712 1107 cc->cpu_exec_interrupt = arm_cpu_exec_interrupt;
878096ee 1108 cc->dump_state = arm_cpu_dump_state;
f45748f1 1109 cc->set_pc = arm_cpu_set_pc;
5b50e790
AF
1110 cc->gdb_read_register = arm_cpu_gdb_read_register;
1111 cc->gdb_write_register = arm_cpu_gdb_write_register;
7510454e
AF
1112#ifdef CONFIG_USER_ONLY
1113 cc->handle_mmu_fault = arm_cpu_handle_mmu_fault;
1114#else
00b941e5
AF
1115 cc->get_phys_page_debug = arm_cpu_get_phys_page_debug;
1116 cc->vmsd = &vmstate_arm_cpu;
1117#endif
a0e372f0 1118 cc->gdb_num_core_regs = 26;
5b24c641 1119 cc->gdb_core_xml_file = "arm-core.xml";
2472b6c0 1120 cc->gdb_stop_before_watchpoint = true;
3ff6fc91 1121 cc->debug_excp_handler = arm_debug_excp_handler;
dec9c2d4
AF
1122}
1123
777dc784
PM
1124static void cpu_register(const ARMCPUInfo *info)
1125{
1126 TypeInfo type_info = {
777dc784
PM
1127 .parent = TYPE_ARM_CPU,
1128 .instance_size = sizeof(ARMCPU),
1129 .instance_init = info->initfn,
1130 .class_size = sizeof(ARMCPUClass),
e6f010cc 1131 .class_init = info->class_init,
777dc784
PM
1132 };
1133
51492fd1 1134 type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name);
918fd083 1135 type_register(&type_info);
51492fd1 1136 g_free((void *)type_info.name);
777dc784
PM
1137}
1138
dec9c2d4
AF
1139static const TypeInfo arm_cpu_type_info = {
1140 .name = TYPE_ARM_CPU,
1141 .parent = TYPE_CPU,
1142 .instance_size = sizeof(ARMCPU),
777dc784 1143 .instance_init = arm_cpu_initfn,
07a5b0d2 1144 .instance_post_init = arm_cpu_post_init,
4b6a83fb 1145 .instance_finalize = arm_cpu_finalizefn,
777dc784 1146 .abstract = true,
dec9c2d4
AF
1147 .class_size = sizeof(ARMCPUClass),
1148 .class_init = arm_cpu_class_init,
1149};
1150
1151static void arm_cpu_register_types(void)
1152{
83e6813a 1153 const ARMCPUInfo *info = arm_cpus;
777dc784 1154
dec9c2d4 1155 type_register_static(&arm_cpu_type_info);
83e6813a
PM
1156
1157 while (info->name) {
1158 cpu_register(info);
1159 info++;
777dc784 1160 }
dec9c2d4
AF
1161}
1162
1163type_init(arm_cpu_register_types)