4 * Copyright (c) 2012 SUSE LINUX Products GmbH
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.
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.
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>
22 #include "qemu-common.h"
24 /* CPUClass::reset() */
25 static void arm_cpu_reset(CPUState
*s
)
27 ARMCPU
*cpu
= ARM_CPU(s
);
28 ARMCPUClass
*acc
= ARM_CPU_GET_CLASS(cpu
);
32 /* TODO Inline the current contents of cpu_state_reset(),
33 once cpu_reset_model_id() is eliminated. */
34 cpu_state_reset(&cpu
->env
);
37 static inline void set_feature(CPUARMState
*env
, int feature
)
39 env
->features
|= 1u << feature
;
42 static void arm_cpu_initfn(Object
*obj
)
44 ARMCPU
*cpu
= ARM_CPU(obj
);
46 cpu_exec_init(&cpu
->env
);
49 void arm_cpu_realize(ARMCPU
*cpu
)
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.
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
);
65 set_feature(env
, ARM_FEATURE_V6
);
68 if (arm_feature(env
, ARM_FEATURE_V6K
)) {
69 set_feature(env
, ARM_FEATURE_V6
);
70 set_feature(env
, ARM_FEATURE_MVFR
);
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
);
78 if (arm_feature(env
, ARM_FEATURE_V5
)) {
79 set_feature(env
, ARM_FEATURE_V4T
);
81 if (arm_feature(env
, ARM_FEATURE_M
)) {
82 set_feature(env
, ARM_FEATURE_THUMB_DIV
);
84 if (arm_feature(env
, ARM_FEATURE_ARM_DIV
)) {
85 set_feature(env
, ARM_FEATURE_THUMB_DIV
);
87 if (arm_feature(env
, ARM_FEATURE_VFP4
)) {
88 set_feature(env
, ARM_FEATURE_VFP3
);
90 if (arm_feature(env
, ARM_FEATURE_VFP3
)) {
91 set_feature(env
, ARM_FEATURE_VFP
);
97 static void arm926_initfn(Object
*obj
)
99 ARMCPU
*cpu
= ARM_CPU(obj
);
100 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
101 set_feature(&cpu
->env
, ARM_FEATURE_VFP
);
102 cpu
->midr
= ARM_CPUID_ARM926
;
103 cpu
->reset_fpsid
= 0x41011090;
106 static void arm946_initfn(Object
*obj
)
108 ARMCPU
*cpu
= ARM_CPU(obj
);
109 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
110 set_feature(&cpu
->env
, ARM_FEATURE_MPU
);
111 cpu
->midr
= ARM_CPUID_ARM946
;
114 static void arm1026_initfn(Object
*obj
)
116 ARMCPU
*cpu
= ARM_CPU(obj
);
117 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
118 set_feature(&cpu
->env
, ARM_FEATURE_VFP
);
119 set_feature(&cpu
->env
, ARM_FEATURE_AUXCR
);
120 cpu
->midr
= ARM_CPUID_ARM1026
;
121 cpu
->reset_fpsid
= 0x410110a0;
124 static void arm1136_r2_initfn(Object
*obj
)
126 ARMCPU
*cpu
= ARM_CPU(obj
);
127 set_feature(&cpu
->env
, ARM_FEATURE_V6
);
128 set_feature(&cpu
->env
, ARM_FEATURE_VFP
);
129 cpu
->midr
= ARM_CPUID_ARM1136_R2
;
130 cpu
->reset_fpsid
= 0x410120b4;
133 static void arm1136_initfn(Object
*obj
)
135 ARMCPU
*cpu
= ARM_CPU(obj
);
136 set_feature(&cpu
->env
, ARM_FEATURE_V6K
);
137 set_feature(&cpu
->env
, ARM_FEATURE_V6
);
138 set_feature(&cpu
->env
, ARM_FEATURE_VFP
);
139 cpu
->midr
= ARM_CPUID_ARM1136
;
140 cpu
->reset_fpsid
= 0x410120b4;
143 static void arm1176_initfn(Object
*obj
)
145 ARMCPU
*cpu
= ARM_CPU(obj
);
146 set_feature(&cpu
->env
, ARM_FEATURE_V6K
);
147 set_feature(&cpu
->env
, ARM_FEATURE_VFP
);
148 set_feature(&cpu
->env
, ARM_FEATURE_VAPA
);
149 cpu
->midr
= ARM_CPUID_ARM1176
;
150 cpu
->reset_fpsid
= 0x410120b5;
153 static void arm11mpcore_initfn(Object
*obj
)
155 ARMCPU
*cpu
= ARM_CPU(obj
);
156 set_feature(&cpu
->env
, ARM_FEATURE_V6K
);
157 set_feature(&cpu
->env
, ARM_FEATURE_VFP
);
158 set_feature(&cpu
->env
, ARM_FEATURE_VAPA
);
159 cpu
->midr
= ARM_CPUID_ARM11MPCORE
;
160 cpu
->reset_fpsid
= 0x410120b4;
163 static void cortex_m3_initfn(Object
*obj
)
165 ARMCPU
*cpu
= ARM_CPU(obj
);
166 set_feature(&cpu
->env
, ARM_FEATURE_V7
);
167 set_feature(&cpu
->env
, ARM_FEATURE_M
);
168 cpu
->midr
= ARM_CPUID_CORTEXM3
;
171 static void cortex_a8_initfn(Object
*obj
)
173 ARMCPU
*cpu
= ARM_CPU(obj
);
174 set_feature(&cpu
->env
, ARM_FEATURE_V7
);
175 set_feature(&cpu
->env
, ARM_FEATURE_VFP3
);
176 set_feature(&cpu
->env
, ARM_FEATURE_NEON
);
177 set_feature(&cpu
->env
, ARM_FEATURE_THUMB2EE
);
178 cpu
->midr
= ARM_CPUID_CORTEXA8
;
179 cpu
->reset_fpsid
= 0x410330c0;
182 static void cortex_a9_initfn(Object
*obj
)
184 ARMCPU
*cpu
= ARM_CPU(obj
);
185 set_feature(&cpu
->env
, ARM_FEATURE_V7
);
186 set_feature(&cpu
->env
, ARM_FEATURE_VFP3
);
187 set_feature(&cpu
->env
, ARM_FEATURE_VFP_FP16
);
188 set_feature(&cpu
->env
, ARM_FEATURE_NEON
);
189 set_feature(&cpu
->env
, ARM_FEATURE_THUMB2EE
);
190 /* Note that A9 supports the MP extensions even for
191 * A9UP and single-core A9MP (which are both different
192 * and valid configurations; we don't model A9UP).
194 set_feature(&cpu
->env
, ARM_FEATURE_V7MP
);
195 cpu
->midr
= ARM_CPUID_CORTEXA9
;
196 cpu
->reset_fpsid
= 0x41033090;
199 static void cortex_a15_initfn(Object
*obj
)
201 ARMCPU
*cpu
= ARM_CPU(obj
);
202 set_feature(&cpu
->env
, ARM_FEATURE_V7
);
203 set_feature(&cpu
->env
, ARM_FEATURE_VFP4
);
204 set_feature(&cpu
->env
, ARM_FEATURE_VFP_FP16
);
205 set_feature(&cpu
->env
, ARM_FEATURE_NEON
);
206 set_feature(&cpu
->env
, ARM_FEATURE_THUMB2EE
);
207 set_feature(&cpu
->env
, ARM_FEATURE_ARM_DIV
);
208 set_feature(&cpu
->env
, ARM_FEATURE_V7MP
);
209 set_feature(&cpu
->env
, ARM_FEATURE_GENERIC_TIMER
);
210 cpu
->midr
= ARM_CPUID_CORTEXA15
;
211 cpu
->reset_fpsid
= 0x410430f0;
214 static void ti925t_initfn(Object
*obj
)
216 ARMCPU
*cpu
= ARM_CPU(obj
);
217 set_feature(&cpu
->env
, ARM_FEATURE_V4T
);
218 set_feature(&cpu
->env
, ARM_FEATURE_OMAPCP
);
219 cpu
->midr
= ARM_CPUID_TI925T
;
222 static void sa1100_initfn(Object
*obj
)
224 ARMCPU
*cpu
= ARM_CPU(obj
);
225 set_feature(&cpu
->env
, ARM_FEATURE_STRONGARM
);
226 cpu
->midr
= ARM_CPUID_SA1100
;
229 static void sa1110_initfn(Object
*obj
)
231 ARMCPU
*cpu
= ARM_CPU(obj
);
232 set_feature(&cpu
->env
, ARM_FEATURE_STRONGARM
);
233 cpu
->midr
= ARM_CPUID_SA1110
;
236 static void pxa250_initfn(Object
*obj
)
238 ARMCPU
*cpu
= ARM_CPU(obj
);
239 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
240 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
241 cpu
->midr
= ARM_CPUID_PXA250
;
244 static void pxa255_initfn(Object
*obj
)
246 ARMCPU
*cpu
= ARM_CPU(obj
);
247 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
248 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
249 cpu
->midr
= ARM_CPUID_PXA255
;
252 static void pxa260_initfn(Object
*obj
)
254 ARMCPU
*cpu
= ARM_CPU(obj
);
255 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
256 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
257 cpu
->midr
= ARM_CPUID_PXA260
;
260 static void pxa261_initfn(Object
*obj
)
262 ARMCPU
*cpu
= ARM_CPU(obj
);
263 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
264 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
265 cpu
->midr
= ARM_CPUID_PXA261
;
268 static void pxa262_initfn(Object
*obj
)
270 ARMCPU
*cpu
= ARM_CPU(obj
);
271 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
272 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
273 cpu
->midr
= ARM_CPUID_PXA262
;
276 static void pxa270a0_initfn(Object
*obj
)
278 ARMCPU
*cpu
= ARM_CPU(obj
);
279 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
280 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
281 set_feature(&cpu
->env
, ARM_FEATURE_IWMMXT
);
282 cpu
->midr
= ARM_CPUID_PXA270_A0
;
285 static void pxa270a1_initfn(Object
*obj
)
287 ARMCPU
*cpu
= ARM_CPU(obj
);
288 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
289 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
290 set_feature(&cpu
->env
, ARM_FEATURE_IWMMXT
);
291 cpu
->midr
= ARM_CPUID_PXA270_A1
;
294 static void pxa270b0_initfn(Object
*obj
)
296 ARMCPU
*cpu
= ARM_CPU(obj
);
297 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
298 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
299 set_feature(&cpu
->env
, ARM_FEATURE_IWMMXT
);
300 cpu
->midr
= ARM_CPUID_PXA270_B0
;
303 static void pxa270b1_initfn(Object
*obj
)
305 ARMCPU
*cpu
= ARM_CPU(obj
);
306 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
307 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
308 set_feature(&cpu
->env
, ARM_FEATURE_IWMMXT
);
309 cpu
->midr
= ARM_CPUID_PXA270_B1
;
312 static void pxa270c0_initfn(Object
*obj
)
314 ARMCPU
*cpu
= ARM_CPU(obj
);
315 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
316 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
317 set_feature(&cpu
->env
, ARM_FEATURE_IWMMXT
);
318 cpu
->midr
= ARM_CPUID_PXA270_C0
;
321 static void pxa270c5_initfn(Object
*obj
)
323 ARMCPU
*cpu
= ARM_CPU(obj
);
324 set_feature(&cpu
->env
, ARM_FEATURE_V5
);
325 set_feature(&cpu
->env
, ARM_FEATURE_XSCALE
);
326 set_feature(&cpu
->env
, ARM_FEATURE_IWMMXT
);
327 cpu
->midr
= ARM_CPUID_PXA270_C5
;
330 static void arm_any_initfn(Object
*obj
)
332 ARMCPU
*cpu
= ARM_CPU(obj
);
333 set_feature(&cpu
->env
, ARM_FEATURE_V7
);
334 set_feature(&cpu
->env
, ARM_FEATURE_VFP4
);
335 set_feature(&cpu
->env
, ARM_FEATURE_VFP_FP16
);
336 set_feature(&cpu
->env
, ARM_FEATURE_NEON
);
337 set_feature(&cpu
->env
, ARM_FEATURE_THUMB2EE
);
338 set_feature(&cpu
->env
, ARM_FEATURE_ARM_DIV
);
339 set_feature(&cpu
->env
, ARM_FEATURE_V7MP
);
340 cpu
->midr
= ARM_CPUID_ANY
;
343 typedef struct ARMCPUInfo
{
345 void (*initfn
)(Object
*obj
);
348 static const ARMCPUInfo arm_cpus
[] = {
349 { .name
= "arm926", .initfn
= arm926_initfn
},
350 { .name
= "arm946", .initfn
= arm946_initfn
},
351 { .name
= "arm1026", .initfn
= arm1026_initfn
},
352 /* What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
353 * older core than plain "arm1136". In particular this does not
354 * have the v6K features.
356 { .name
= "arm1136-r2", .initfn
= arm1136_r2_initfn
},
357 { .name
= "arm1136", .initfn
= arm1136_initfn
},
358 { .name
= "arm1176", .initfn
= arm1176_initfn
},
359 { .name
= "arm11mpcore", .initfn
= arm11mpcore_initfn
},
360 { .name
= "cortex-m3", .initfn
= cortex_m3_initfn
},
361 { .name
= "cortex-a8", .initfn
= cortex_a8_initfn
},
362 { .name
= "cortex-a9", .initfn
= cortex_a9_initfn
},
363 { .name
= "cortex-a15", .initfn
= cortex_a15_initfn
},
364 { .name
= "ti925t", .initfn
= ti925t_initfn
},
365 { .name
= "sa1100", .initfn
= sa1100_initfn
},
366 { .name
= "sa1110", .initfn
= sa1110_initfn
},
367 { .name
= "pxa250", .initfn
= pxa250_initfn
},
368 { .name
= "pxa255", .initfn
= pxa255_initfn
},
369 { .name
= "pxa260", .initfn
= pxa260_initfn
},
370 { .name
= "pxa261", .initfn
= pxa261_initfn
},
371 { .name
= "pxa262", .initfn
= pxa262_initfn
},
372 /* "pxa270" is an alias for "pxa270-a0" */
373 { .name
= "pxa270", .initfn
= pxa270a0_initfn
},
374 { .name
= "pxa270-a0", .initfn
= pxa270a0_initfn
},
375 { .name
= "pxa270-a1", .initfn
= pxa270a1_initfn
},
376 { .name
= "pxa270-b0", .initfn
= pxa270b0_initfn
},
377 { .name
= "pxa270-b1", .initfn
= pxa270b1_initfn
},
378 { .name
= "pxa270-c0", .initfn
= pxa270c0_initfn
},
379 { .name
= "pxa270-c5", .initfn
= pxa270c5_initfn
},
380 { .name
= "any", .initfn
= arm_any_initfn
},
383 static void arm_cpu_class_init(ObjectClass
*oc
, void *data
)
385 ARMCPUClass
*acc
= ARM_CPU_CLASS(oc
);
386 CPUClass
*cc
= CPU_CLASS(acc
);
388 acc
->parent_reset
= cc
->reset
;
389 cc
->reset
= arm_cpu_reset
;
392 static void cpu_register(const ARMCPUInfo
*info
)
394 TypeInfo type_info
= {
396 .parent
= TYPE_ARM_CPU
,
397 .instance_size
= sizeof(ARMCPU
),
398 .instance_init
= info
->initfn
,
399 .class_size
= sizeof(ARMCPUClass
),
402 type_register_static(&type_info
);
405 static const TypeInfo arm_cpu_type_info
= {
406 .name
= TYPE_ARM_CPU
,
408 .instance_size
= sizeof(ARMCPU
),
409 .instance_init
= arm_cpu_initfn
,
411 .class_size
= sizeof(ARMCPUClass
),
412 .class_init
= arm_cpu_class_init
,
415 static void arm_cpu_register_types(void)
419 type_register_static(&arm_cpu_type_info
);
420 for (i
= 0; i
< ARRAY_SIZE(arm_cpus
); i
++) {
421 cpu_register(&arm_cpus
[i
]);
425 type_init(arm_cpu_register_types
)