]> git.proxmox.com Git - mirror_qemu.git/blame - target-arm/cpu.c
target-arm: Move CTR setup to per cpu init fns
[mirror_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
21#include "cpu-qom.h"
22#include "qemu-common.h"
23
24/* CPUClass::reset() */
25static void arm_cpu_reset(CPUState *s)
26{
27 ARMCPU *cpu = ARM_CPU(s);
28 ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu);
29
30 acc->parent_reset(s);
31
32 /* TODO Inline the current contents of cpu_state_reset(),
33 once cpu_reset_model_id() is eliminated. */
34 cpu_state_reset(&cpu->env);
35}
36
581be094
PM
37static inline void set_feature(CPUARMState *env, int feature)
38{
39 env->features |= 1u << feature;
40}
41
777dc784
PM
42static void arm_cpu_initfn(Object *obj)
43{
44 ARMCPU *cpu = ARM_CPU(obj);
45
46 cpu_exec_init(&cpu->env);
47}
48
581be094
PM
49void arm_cpu_realize(ARMCPU *cpu)
50{
51 /* This function is called by cpu_arm_init() because it
52 * needs to do common actions based on feature bits, etc
53 * that have been set by the subclass init functions.
54 * When we have QOM realize support it should become
55 * a true realize function instead.
56 */
57 CPUARMState *env = &cpu->env;
58 /* Some features automatically imply others: */
59 if (arm_feature(env, ARM_FEATURE_V7)) {
60 set_feature(env, ARM_FEATURE_VAPA);
61 set_feature(env, ARM_FEATURE_THUMB2);
62 if (!arm_feature(env, ARM_FEATURE_M)) {
63 set_feature(env, ARM_FEATURE_V6K);
64 } else {
65 set_feature(env, ARM_FEATURE_V6);
66 }
67 }
68 if (arm_feature(env, ARM_FEATURE_V6K)) {
69 set_feature(env, ARM_FEATURE_V6);
70 set_feature(env, ARM_FEATURE_MVFR);
71 }
72 if (arm_feature(env, ARM_FEATURE_V6)) {
73 set_feature(env, ARM_FEATURE_V5);
74 if (!arm_feature(env, ARM_FEATURE_M)) {
75 set_feature(env, ARM_FEATURE_AUXCR);
76 }
77 }
78 if (arm_feature(env, ARM_FEATURE_V5)) {
79 set_feature(env, ARM_FEATURE_V4T);
80 }
81 if (arm_feature(env, ARM_FEATURE_M)) {
82 set_feature(env, ARM_FEATURE_THUMB_DIV);
83 }
84 if (arm_feature(env, ARM_FEATURE_ARM_DIV)) {
85 set_feature(env, ARM_FEATURE_THUMB_DIV);
86 }
87 if (arm_feature(env, ARM_FEATURE_VFP4)) {
88 set_feature(env, ARM_FEATURE_VFP3);
89 }
90 if (arm_feature(env, ARM_FEATURE_VFP3)) {
91 set_feature(env, ARM_FEATURE_VFP);
92 }
93}
94
777dc784
PM
95/* CPU models */
96
97static void arm926_initfn(Object *obj)
98{
99 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
100 set_feature(&cpu->env, ARM_FEATURE_V5);
101 set_feature(&cpu->env, ARM_FEATURE_VFP);
777dc784 102 cpu->midr = ARM_CPUID_ARM926;
325b3cef 103 cpu->reset_fpsid = 0x41011090;
64e1671f 104 cpu->ctr = 0x1dd20d2;
777dc784
PM
105}
106
107static void arm946_initfn(Object *obj)
108{
109 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
110 set_feature(&cpu->env, ARM_FEATURE_V5);
111 set_feature(&cpu->env, ARM_FEATURE_MPU);
777dc784 112 cpu->midr = ARM_CPUID_ARM946;
64e1671f 113 cpu->ctr = 0x0f004006;
777dc784
PM
114}
115
116static void arm1026_initfn(Object *obj)
117{
118 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
119 set_feature(&cpu->env, ARM_FEATURE_V5);
120 set_feature(&cpu->env, ARM_FEATURE_VFP);
121 set_feature(&cpu->env, ARM_FEATURE_AUXCR);
777dc784 122 cpu->midr = ARM_CPUID_ARM1026;
325b3cef 123 cpu->reset_fpsid = 0x410110a0;
64e1671f 124 cpu->ctr = 0x1dd20d2;
777dc784
PM
125}
126
127static void arm1136_r2_initfn(Object *obj)
128{
129 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
130 set_feature(&cpu->env, ARM_FEATURE_V6);
131 set_feature(&cpu->env, ARM_FEATURE_VFP);
777dc784 132 cpu->midr = ARM_CPUID_ARM1136_R2;
325b3cef 133 cpu->reset_fpsid = 0x410120b4;
bd35c355
PM
134 cpu->mvfr0 = 0x11111111;
135 cpu->mvfr1 = 0x00000000;
64e1671f 136 cpu->ctr = 0x1dd20d2;
777dc784
PM
137}
138
139static void arm1136_initfn(Object *obj)
140{
141 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
142 set_feature(&cpu->env, ARM_FEATURE_V6K);
143 set_feature(&cpu->env, ARM_FEATURE_V6);
144 set_feature(&cpu->env, ARM_FEATURE_VFP);
777dc784 145 cpu->midr = ARM_CPUID_ARM1136;
325b3cef 146 cpu->reset_fpsid = 0x410120b4;
bd35c355
PM
147 cpu->mvfr0 = 0x11111111;
148 cpu->mvfr1 = 0x00000000;
64e1671f 149 cpu->ctr = 0x1dd20d2;
777dc784
PM
150}
151
152static void arm1176_initfn(Object *obj)
153{
154 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
155 set_feature(&cpu->env, ARM_FEATURE_V6K);
156 set_feature(&cpu->env, ARM_FEATURE_VFP);
157 set_feature(&cpu->env, ARM_FEATURE_VAPA);
777dc784 158 cpu->midr = ARM_CPUID_ARM1176;
325b3cef 159 cpu->reset_fpsid = 0x410120b5;
bd35c355
PM
160 cpu->mvfr0 = 0x11111111;
161 cpu->mvfr1 = 0x00000000;
64e1671f 162 cpu->ctr = 0x1dd20d2;
777dc784
PM
163}
164
165static void arm11mpcore_initfn(Object *obj)
166{
167 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
168 set_feature(&cpu->env, ARM_FEATURE_V6K);
169 set_feature(&cpu->env, ARM_FEATURE_VFP);
170 set_feature(&cpu->env, ARM_FEATURE_VAPA);
777dc784 171 cpu->midr = ARM_CPUID_ARM11MPCORE;
325b3cef 172 cpu->reset_fpsid = 0x410120b4;
bd35c355
PM
173 cpu->mvfr0 = 0x11111111;
174 cpu->mvfr1 = 0x00000000;
64e1671f 175 cpu->ctr = 0x1dd20d2;
777dc784
PM
176}
177
178static void cortex_m3_initfn(Object *obj)
179{
180 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
181 set_feature(&cpu->env, ARM_FEATURE_V7);
182 set_feature(&cpu->env, ARM_FEATURE_M);
777dc784
PM
183 cpu->midr = ARM_CPUID_CORTEXM3;
184}
185
186static void cortex_a8_initfn(Object *obj)
187{
188 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
189 set_feature(&cpu->env, ARM_FEATURE_V7);
190 set_feature(&cpu->env, ARM_FEATURE_VFP3);
191 set_feature(&cpu->env, ARM_FEATURE_NEON);
192 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
777dc784 193 cpu->midr = ARM_CPUID_CORTEXA8;
325b3cef 194 cpu->reset_fpsid = 0x410330c0;
bd35c355
PM
195 cpu->mvfr0 = 0x11110222;
196 cpu->mvfr1 = 0x00011100;
64e1671f 197 cpu->ctr = 0x82048004;
777dc784
PM
198}
199
200static void cortex_a9_initfn(Object *obj)
201{
202 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
203 set_feature(&cpu->env, ARM_FEATURE_V7);
204 set_feature(&cpu->env, ARM_FEATURE_VFP3);
205 set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
206 set_feature(&cpu->env, ARM_FEATURE_NEON);
207 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
208 /* Note that A9 supports the MP extensions even for
209 * A9UP and single-core A9MP (which are both different
210 * and valid configurations; we don't model A9UP).
211 */
212 set_feature(&cpu->env, ARM_FEATURE_V7MP);
777dc784 213 cpu->midr = ARM_CPUID_CORTEXA9;
325b3cef 214 cpu->reset_fpsid = 0x41033090;
bd35c355
PM
215 cpu->mvfr0 = 0x11110222;
216 cpu->mvfr1 = 0x01111111;
64e1671f 217 cpu->ctr = 0x80038003;
777dc784
PM
218}
219
220static void cortex_a15_initfn(Object *obj)
221{
222 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
223 set_feature(&cpu->env, ARM_FEATURE_V7);
224 set_feature(&cpu->env, ARM_FEATURE_VFP4);
225 set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
226 set_feature(&cpu->env, ARM_FEATURE_NEON);
227 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
228 set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
229 set_feature(&cpu->env, ARM_FEATURE_V7MP);
230 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
777dc784 231 cpu->midr = ARM_CPUID_CORTEXA15;
325b3cef 232 cpu->reset_fpsid = 0x410430f0;
bd35c355
PM
233 cpu->mvfr0 = 0x10110222;
234 cpu->mvfr1 = 0x11111111;
64e1671f 235 cpu->ctr = 0x8444c004;
777dc784
PM
236}
237
238static void ti925t_initfn(Object *obj)
239{
240 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
241 set_feature(&cpu->env, ARM_FEATURE_V4T);
242 set_feature(&cpu->env, ARM_FEATURE_OMAPCP);
777dc784 243 cpu->midr = ARM_CPUID_TI925T;
64e1671f 244 cpu->ctr = 0x5109149;
777dc784
PM
245}
246
247static void sa1100_initfn(Object *obj)
248{
249 ARMCPU *cpu = ARM_CPU(obj);
581be094 250 set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
777dc784
PM
251 cpu->midr = ARM_CPUID_SA1100;
252}
253
254static void sa1110_initfn(Object *obj)
255{
256 ARMCPU *cpu = ARM_CPU(obj);
581be094 257 set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
777dc784
PM
258 cpu->midr = ARM_CPUID_SA1110;
259}
260
261static void pxa250_initfn(Object *obj)
262{
263 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
264 set_feature(&cpu->env, ARM_FEATURE_V5);
265 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
777dc784 266 cpu->midr = ARM_CPUID_PXA250;
64e1671f 267 cpu->ctr = 0xd172172;
777dc784
PM
268}
269
270static void pxa255_initfn(Object *obj)
271{
272 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
273 set_feature(&cpu->env, ARM_FEATURE_V5);
274 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
777dc784 275 cpu->midr = ARM_CPUID_PXA255;
64e1671f 276 cpu->ctr = 0xd172172;
777dc784
PM
277}
278
279static void pxa260_initfn(Object *obj)
280{
281 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
282 set_feature(&cpu->env, ARM_FEATURE_V5);
283 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
777dc784 284 cpu->midr = ARM_CPUID_PXA260;
64e1671f 285 cpu->ctr = 0xd172172;
777dc784
PM
286}
287
288static void pxa261_initfn(Object *obj)
289{
290 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
291 set_feature(&cpu->env, ARM_FEATURE_V5);
292 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
777dc784 293 cpu->midr = ARM_CPUID_PXA261;
64e1671f 294 cpu->ctr = 0xd172172;
777dc784
PM
295}
296
297static void pxa262_initfn(Object *obj)
298{
299 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
300 set_feature(&cpu->env, ARM_FEATURE_V5);
301 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
777dc784 302 cpu->midr = ARM_CPUID_PXA262;
64e1671f 303 cpu->ctr = 0xd172172;
777dc784
PM
304}
305
306static void pxa270a0_initfn(Object *obj)
307{
308 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
309 set_feature(&cpu->env, ARM_FEATURE_V5);
310 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
311 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
777dc784 312 cpu->midr = ARM_CPUID_PXA270_A0;
64e1671f 313 cpu->ctr = 0xd172172;
777dc784
PM
314}
315
316static void pxa270a1_initfn(Object *obj)
317{
318 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
319 set_feature(&cpu->env, ARM_FEATURE_V5);
320 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
321 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
777dc784 322 cpu->midr = ARM_CPUID_PXA270_A1;
64e1671f 323 cpu->ctr = 0xd172172;
777dc784
PM
324}
325
326static void pxa270b0_initfn(Object *obj)
327{
328 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
329 set_feature(&cpu->env, ARM_FEATURE_V5);
330 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
331 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
777dc784 332 cpu->midr = ARM_CPUID_PXA270_B0;
64e1671f 333 cpu->ctr = 0xd172172;
777dc784
PM
334}
335
336static void pxa270b1_initfn(Object *obj)
337{
338 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
339 set_feature(&cpu->env, ARM_FEATURE_V5);
340 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
341 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
777dc784 342 cpu->midr = ARM_CPUID_PXA270_B1;
64e1671f 343 cpu->ctr = 0xd172172;
777dc784
PM
344}
345
346static void pxa270c0_initfn(Object *obj)
347{
348 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
349 set_feature(&cpu->env, ARM_FEATURE_V5);
350 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
351 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
777dc784 352 cpu->midr = ARM_CPUID_PXA270_C0;
64e1671f 353 cpu->ctr = 0xd172172;
777dc784
PM
354}
355
356static void pxa270c5_initfn(Object *obj)
357{
358 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
359 set_feature(&cpu->env, ARM_FEATURE_V5);
360 set_feature(&cpu->env, ARM_FEATURE_XSCALE);
361 set_feature(&cpu->env, ARM_FEATURE_IWMMXT);
777dc784 362 cpu->midr = ARM_CPUID_PXA270_C5;
64e1671f 363 cpu->ctr = 0xd172172;
777dc784
PM
364}
365
366static void arm_any_initfn(Object *obj)
367{
368 ARMCPU *cpu = ARM_CPU(obj);
581be094
PM
369 set_feature(&cpu->env, ARM_FEATURE_V7);
370 set_feature(&cpu->env, ARM_FEATURE_VFP4);
371 set_feature(&cpu->env, ARM_FEATURE_VFP_FP16);
372 set_feature(&cpu->env, ARM_FEATURE_NEON);
373 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
374 set_feature(&cpu->env, ARM_FEATURE_ARM_DIV);
375 set_feature(&cpu->env, ARM_FEATURE_V7MP);
777dc784
PM
376 cpu->midr = ARM_CPUID_ANY;
377}
378
379typedef struct ARMCPUInfo {
380 const char *name;
381 void (*initfn)(Object *obj);
382} ARMCPUInfo;
383
384static const ARMCPUInfo arm_cpus[] = {
385 { .name = "arm926", .initfn = arm926_initfn },
386 { .name = "arm946", .initfn = arm946_initfn },
387 { .name = "arm1026", .initfn = arm1026_initfn },
388 /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
389 * older core than plain "arm1136". In particular this does not
390 * have the v6K features.
391 */
392 { .name = "arm1136-r2", .initfn = arm1136_r2_initfn },
393 { .name = "arm1136", .initfn = arm1136_initfn },
394 { .name = "arm1176", .initfn = arm1176_initfn },
395 { .name = "arm11mpcore", .initfn = arm11mpcore_initfn },
396 { .name = "cortex-m3", .initfn = cortex_m3_initfn },
397 { .name = "cortex-a8", .initfn = cortex_a8_initfn },
398 { .name = "cortex-a9", .initfn = cortex_a9_initfn },
399 { .name = "cortex-a15", .initfn = cortex_a15_initfn },
400 { .name = "ti925t", .initfn = ti925t_initfn },
401 { .name = "sa1100", .initfn = sa1100_initfn },
402 { .name = "sa1110", .initfn = sa1110_initfn },
403 { .name = "pxa250", .initfn = pxa250_initfn },
404 { .name = "pxa255", .initfn = pxa255_initfn },
405 { .name = "pxa260", .initfn = pxa260_initfn },
406 { .name = "pxa261", .initfn = pxa261_initfn },
407 { .name = "pxa262", .initfn = pxa262_initfn },
408 /* "pxa270" is an alias for "pxa270-a0" */
409 { .name = "pxa270", .initfn = pxa270a0_initfn },
410 { .name = "pxa270-a0", .initfn = pxa270a0_initfn },
411 { .name = "pxa270-a1", .initfn = pxa270a1_initfn },
412 { .name = "pxa270-b0", .initfn = pxa270b0_initfn },
413 { .name = "pxa270-b1", .initfn = pxa270b1_initfn },
414 { .name = "pxa270-c0", .initfn = pxa270c0_initfn },
415 { .name = "pxa270-c5", .initfn = pxa270c5_initfn },
416 { .name = "any", .initfn = arm_any_initfn },
417};
418
dec9c2d4
AF
419static void arm_cpu_class_init(ObjectClass *oc, void *data)
420{
421 ARMCPUClass *acc = ARM_CPU_CLASS(oc);
422 CPUClass *cc = CPU_CLASS(acc);
423
424 acc->parent_reset = cc->reset;
425 cc->reset = arm_cpu_reset;
426}
427
777dc784
PM
428static void cpu_register(const ARMCPUInfo *info)
429{
430 TypeInfo type_info = {
431 .name = info->name,
432 .parent = TYPE_ARM_CPU,
433 .instance_size = sizeof(ARMCPU),
434 .instance_init = info->initfn,
435 .class_size = sizeof(ARMCPUClass),
436 };
437
438 type_register_static(&type_info);
439}
440
dec9c2d4
AF
441static const TypeInfo arm_cpu_type_info = {
442 .name = TYPE_ARM_CPU,
443 .parent = TYPE_CPU,
444 .instance_size = sizeof(ARMCPU),
777dc784
PM
445 .instance_init = arm_cpu_initfn,
446 .abstract = true,
dec9c2d4
AF
447 .class_size = sizeof(ARMCPUClass),
448 .class_init = arm_cpu_class_init,
449};
450
451static void arm_cpu_register_types(void)
452{
777dc784
PM
453 int i;
454
dec9c2d4 455 type_register_static(&arm_cpu_type_info);
777dc784
PM
456 for (i = 0; i < ARRAY_SIZE(arm_cpus); i++) {
457 cpu_register(&arm_cpus[i]);
458 }
dec9c2d4
AF
459}
460
461type_init(arm_cpu_register_types)