master
c 755 lines 28.4 KB
Raw
1 /*
2 * QEMU ARM TCG-only CPUs.
3 *
4 * Copyright (c) 2012 SUSE LINUX Products GmbH
5 *
6 * This code is licensed under the GNU GPL v2 or later.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "qemu/osdep.h"
12 #include "qemu/units.h"
13 #include "cpu.h"
14 #include "accel/tcg/cpu-ops.h"
15 #include "internals.h"
16 #if !defined(CONFIG_USER_ONLY)
17 #include "hw/core/boards.h"
18 #endif
19 #include "cpregs.h"
20
21
22 static void arm926_initfn(Object *obj)
23 {
24 ARMCPU *cpu = ARM_CPU(obj);
25
26 cpu->dtb_compatible = "arm,arm926";
27 set_feature(&cpu->env, ARM_FEATURE_V5);
28 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
29 set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
30 cpu->midr = 0x41069265;
31 cpu->reset_fpsid = 0x41011090;
32 cpu->ctr = 0x1dd20d2;
33 cpu->reset_sctlr = 0x00050078;
34
35 /*
36 * ARMv5 does not have the ID_ISAR registers, but we can still
37 * set the field to indicate Jazelle support within QEMU.
38 */
39 FIELD_DP32_IDREG(&cpu->isar, ID_ISAR1, JAZELLE, 1);
40 /*
41 * Similarly, we need to set MVFR0 fields to enable vfp and short vector
42 * support even though ARMv5 doesn't have this register.
43 */
44 cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
45 cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
46 cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
47 }
48
49 static void arm946_initfn(Object *obj)
50 {
51 ARMCPU *cpu = ARM_CPU(obj);
52
53 cpu->dtb_compatible = "arm,arm946";
54 set_feature(&cpu->env, ARM_FEATURE_V5);
55 set_feature(&cpu->env, ARM_FEATURE_PMSA);
56 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
57 cpu->midr = 0x41059461;
58 cpu->ctr = 0x0f004006;
59 cpu->reset_sctlr = 0x00000078;
60 }
61
62 static void arm1026_initfn(Object *obj)
63 {
64 ARMCPU *cpu = ARM_CPU(obj);
65
66 cpu->dtb_compatible = "arm,arm1026";
67 set_feature(&cpu->env, ARM_FEATURE_V5);
68 set_feature(&cpu->env, ARM_FEATURE_AUXCR);
69 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
70 set_feature(&cpu->env, ARM_FEATURE_CACHE_TEST_CLEAN);
71 cpu->midr = 0x4106a262;
72 cpu->reset_fpsid = 0x410110a0;
73 cpu->ctr = 0x1dd20d2;
74 cpu->reset_sctlr = 0x00050078;
75 cpu->reset_auxcr = 1;
76
77 /*
78 * ARMv5 does not have the ID_ISAR registers, but we can still
79 * set the field to indicate Jazelle support within QEMU.
80 */
81 FIELD_DP32_IDREG(&cpu->isar, ID_ISAR1, JAZELLE, 1);
82 /*
83 * Similarly, we need to set MVFR0 fields to enable vfp and short vector
84 * support even though ARMv5 doesn't have this register.
85 */
86 cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSHVEC, 1);
87 cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPSP, 1);
88 cpu->isar.mvfr0 = FIELD_DP32(cpu->isar.mvfr0, MVFR0, FPDP, 1);
89
90 {
91 /* The 1026 had an IFAR at c6,c0,0,1 rather than the ARMv6 c6,c0,0,2 */
92 ARMCPRegInfo ifar = {
93 .name = "IFAR", .cp = 15, .crn = 6, .crm = 0, .opc1 = 0, .opc2 = 1,
94 .access = PL1_RW,
95 .fieldoffset = offsetof(CPUARMState, cp15.ifar_ns),
96 .resetvalue = 0
97 };
98 define_one_arm_cp_reg(cpu, &ifar);
99 }
100 }
101
102 static void arm1136_r2_initfn(Object *obj)
103 {
104 ARMCPU *cpu = ARM_CPU(obj);
105 ARMISARegisters *isar = &cpu->isar;
106 /*
107 * What qemu calls "arm1136_r2" is actually the 1136 r0p2, ie an
108 * older core than plain "arm1136". In particular this does not
109 * have the v6K features.
110 * These ID register values are correct for 1136 but may be wrong
111 * for 1136_r2 (in particular r0p2 does not actually implement most
112 * of the ID registers).
113 */
114
115 cpu->dtb_compatible = "arm,arm1136";
116 set_feature(&cpu->env, ARM_FEATURE_V6);
117 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
118 set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
119 set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
120 cpu->midr = 0x4107b362;
121 cpu->reset_fpsid = 0x410120b4;
122 cpu->isar.mvfr0 = 0x11111111;
123 cpu->isar.mvfr1 = 0x00000000;
124 cpu->ctr = 0x1dd20d2;
125 cpu->reset_sctlr = 0x00050078;
126 SET_IDREG(isar, ID_PFR0, 0x111);
127 SET_IDREG(isar, ID_PFR1, 0x1);
128 SET_IDREG(isar, ID_DFR0, 0x2);
129 SET_IDREG(isar, ID_AFR0, 0x3);
130 SET_IDREG(isar, ID_MMFR0, 0x01130003);
131 SET_IDREG(isar, ID_MMFR1, 0x10030302);
132 SET_IDREG(isar, ID_MMFR2, 0x01222110);
133 SET_IDREG(isar, ID_ISAR0, 0x00140011);
134 SET_IDREG(isar, ID_ISAR1, 0x12002111);
135 SET_IDREG(isar, ID_ISAR2, 0x11231111);
136 SET_IDREG(isar, ID_ISAR3, 0x01102131);
137 SET_IDREG(isar, ID_ISAR4, 0x141);
138 cpu->reset_auxcr = 7;
139 }
140
141 static void arm1136_initfn(Object *obj)
142 {
143 ARMCPU *cpu = ARM_CPU(obj);
144 ARMISARegisters *isar = &cpu->isar;
145
146 cpu->dtb_compatible = "arm,arm1136";
147 set_feature(&cpu->env, ARM_FEATURE_V6K);
148 set_feature(&cpu->env, ARM_FEATURE_V6);
149 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
150 set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
151 set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
152 cpu->midr = 0x4117b363;
153 cpu->reset_fpsid = 0x410120b4;
154 cpu->isar.mvfr0 = 0x11111111;
155 cpu->isar.mvfr1 = 0x00000000;
156 cpu->ctr = 0x1dd20d2;
157 cpu->reset_sctlr = 0x00050078;
158 SET_IDREG(isar, ID_PFR0, 0x111);
159 SET_IDREG(isar, ID_PFR1, 0x1);
160 SET_IDREG(isar, ID_DFR0, 0x2);
161 SET_IDREG(isar, ID_AFR0, 0x3);
162 SET_IDREG(isar, ID_MMFR0, 0x01130003);
163 SET_IDREG(isar, ID_MMFR1, 0x10030302);
164 SET_IDREG(isar, ID_MMFR2, 0x01222110);
165 SET_IDREG(isar, ID_ISAR0, 0x00140011);
166 SET_IDREG(isar, ID_ISAR1, 0x12002111);
167 SET_IDREG(isar, ID_ISAR2, 0x11231111);
168 SET_IDREG(isar, ID_ISAR3, 0x01102131);
169 SET_IDREG(isar, ID_ISAR4, 0x141);
170 cpu->reset_auxcr = 7;
171 }
172
173 static void arm1176_initfn(Object *obj)
174 {
175 ARMCPU *cpu = ARM_CPU(obj);
176 ARMISARegisters *isar = &cpu->isar;
177
178 cpu->dtb_compatible = "arm,arm1176";
179 set_feature(&cpu->env, ARM_FEATURE_V6K);
180 set_feature(&cpu->env, ARM_FEATURE_VAPA);
181 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
182 set_feature(&cpu->env, ARM_FEATURE_CACHE_DIRTY_REG);
183 set_feature(&cpu->env, ARM_FEATURE_CACHE_BLOCK_OPS);
184 set_feature(&cpu->env, ARM_FEATURE_EL3);
185 cpu->midr = 0x410fb767;
186 cpu->reset_fpsid = 0x410120b5;
187 cpu->isar.mvfr0 = 0x11111111;
188 cpu->isar.mvfr1 = 0x00000000;
189 cpu->ctr = 0x1dd20d2;
190 cpu->reset_sctlr = 0x00050078;
191 SET_IDREG(isar, ID_PFR0, 0x111);
192 SET_IDREG(isar, ID_PFR1, 0x11);
193 SET_IDREG(isar, ID_DFR0, 0x33);
194 SET_IDREG(isar, ID_AFR0, 0);
195 SET_IDREG(isar, ID_MMFR0, 0x01130003);
196 SET_IDREG(isar, ID_MMFR1, 0x10030302);
197 SET_IDREG(isar, ID_MMFR2, 0x01222100);
198 SET_IDREG(isar, ID_ISAR0, 0x0140011);
199 SET_IDREG(isar, ID_ISAR1, 0x12002111);
200 SET_IDREG(isar, ID_ISAR2, 0x11231121);
201 SET_IDREG(isar, ID_ISAR3, 0x01102131);
202 SET_IDREG(isar, ID_ISAR4, 0x01141);
203 cpu->reset_auxcr = 7;
204 }
205
206 static void arm11mpcore_initfn(Object *obj)
207 {
208 ARMCPU *cpu = ARM_CPU(obj);
209 ARMISARegisters *isar = &cpu->isar;
210
211 cpu->dtb_compatible = "arm,arm11mpcore";
212 set_feature(&cpu->env, ARM_FEATURE_V6K);
213 set_feature(&cpu->env, ARM_FEATURE_VAPA);
214 set_feature(&cpu->env, ARM_FEATURE_MPIDR);
215 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
216 cpu->midr = 0x410fb022;
217 cpu->reset_fpsid = 0x410120b4;
218 cpu->isar.mvfr0 = 0x11111111;
219 cpu->isar.mvfr1 = 0x00000000;
220 cpu->ctr = 0x1d192992; /* 32K icache 32K dcache */
221 SET_IDREG(isar, ID_PFR0, 0x111);
222 SET_IDREG(isar, ID_PFR1, 0x1);
223 SET_IDREG(isar, ID_DFR0, 0);
224 SET_IDREG(isar, ID_AFR0, 0x2);
225 SET_IDREG(isar, ID_MMFR0, 0x01100103);
226 SET_IDREG(isar, ID_MMFR1, 0x10020302);
227 SET_IDREG(isar, ID_MMFR2, 0x01222000);
228 SET_IDREG(isar, ID_ISAR0, 0x00100011);
229 SET_IDREG(isar, ID_ISAR1, 0x12002111);
230 SET_IDREG(isar, ID_ISAR2, 0x11221011);
231 SET_IDREG(isar, ID_ISAR3, 0x01102131);
232 SET_IDREG(isar, ID_ISAR4, 0x141);
233 cpu->reset_auxcr = 1;
234 }
235
236 static const ARMCPRegInfo cortexa8_cp_reginfo[] = {
237 { .name = "L2LOCKDOWN", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 0,
238 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
239 { .name = "L2AUXCR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
240 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
241 };
242
243 static void cortex_a8_initfn(Object *obj)
244 {
245 ARMCPU *cpu = ARM_CPU(obj);
246 ARMISARegisters *isar = &cpu->isar;
247
248 cpu->dtb_compatible = "arm,cortex-a8";
249 set_feature(&cpu->env, ARM_FEATURE_V7);
250 set_feature(&cpu->env, ARM_FEATURE_NEON);
251 /*
252 * The Cortex-A8 doesn't have CPACR.ASEDIS and HCPTR.TASE,
253 * so don't set ARM_FEATURE_NEON_TRAPS.
254 */
255 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
256 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
257 set_feature(&cpu->env, ARM_FEATURE_EL3);
258 set_feature(&cpu->env, ARM_FEATURE_PMU);
259 cpu->midr = 0x410fc080;
260 cpu->reset_fpsid = 0x410330c0;
261 cpu->isar.mvfr0 = 0x11110222;
262 cpu->isar.mvfr1 = 0x00011111;
263 cpu->ctr = 0x82048004;
264 cpu->reset_sctlr = 0x00c50078;
265 SET_IDREG(isar, ID_PFR0, 0x1031);
266 SET_IDREG(isar, ID_PFR1, 0x11);
267 SET_IDREG(isar, ID_DFR0, 0x400);
268 SET_IDREG(isar, ID_AFR0, 0);
269 SET_IDREG(isar, ID_MMFR0, 0x31100003);
270 SET_IDREG(isar, ID_MMFR1, 0x20000000);
271 SET_IDREG(isar, ID_MMFR2, 0x01202000);
272 SET_IDREG(isar, ID_MMFR3, 0x11);
273 SET_IDREG(isar, ID_ISAR0, 0x00101111);
274 SET_IDREG(isar, ID_ISAR1, 0x12112111);
275 SET_IDREG(isar, ID_ISAR2, 0x21232031);
276 SET_IDREG(isar, ID_ISAR3, 0x11112131);
277 SET_IDREG(isar, ID_ISAR4, 0x00111142);
278 cpu->isar.dbgdidr = 0x15141000;
279 SET_IDREG(isar, CLIDR, (1 << 27) | (2 << 24) | 3);
280 cpu->ccsidr[0] = 0xe007e01a; /* 16k L1 dcache. */
281 cpu->ccsidr[1] = 0x2007e01a; /* 16k L1 icache. */
282 cpu->ccsidr[2] = 0xf0000000; /* No L2 icache. */
283 cpu->reset_auxcr = 2;
284 cpu->isar.reset_pmcr_el0 = 0x41002000;
285 define_arm_cp_regs(cpu, cortexa8_cp_reginfo);
286 }
287
288 static const ARMCPRegInfo cortexa9_cp_reginfo[] = {
289 /*
290 * power_control should be set to maximum latency. Again,
291 * default to 0 and set by private hook
292 */
293 { .name = "A9_PWRCTL", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 0,
294 .access = PL1_RW, .resetvalue = 0,
295 .fieldoffset = offsetof(CPUARMState, cp15.c15_power_control) },
296 { .name = "A9_DIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 1,
297 .access = PL1_RW, .resetvalue = 0,
298 .fieldoffset = offsetof(CPUARMState, cp15.c15_diagnostic) },
299 { .name = "A9_PWRDIAG", .cp = 15, .crn = 15, .crm = 0, .opc1 = 0, .opc2 = 2,
300 .access = PL1_RW, .resetvalue = 0,
301 .fieldoffset = offsetof(CPUARMState, cp15.c15_power_diagnostic) },
302 { .name = "NEONBUSY", .cp = 15, .crn = 15, .crm = 1, .opc1 = 0, .opc2 = 0,
303 .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
304 /* TLB lockdown control */
305 { .name = "TLB_LOCKR", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 2,
306 .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP },
307 { .name = "TLB_LOCKW", .cp = 15, .crn = 15, .crm = 4, .opc1 = 5, .opc2 = 4,
308 .access = PL1_W, .resetvalue = 0, .type = ARM_CP_NOP },
309 { .name = "TLB_VA", .cp = 15, .crn = 15, .crm = 5, .opc1 = 5, .opc2 = 2,
310 .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
311 { .name = "TLB_PA", .cp = 15, .crn = 15, .crm = 6, .opc1 = 5, .opc2 = 2,
312 .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
313 { .name = "TLB_ATTR", .cp = 15, .crn = 15, .crm = 7, .opc1 = 5, .opc2 = 2,
314 .access = PL1_RW, .resetvalue = 0, .type = ARM_CP_CONST },
315 };
316
317 static void cortex_a9_initfn(Object *obj)
318 {
319 ARMCPU *cpu = ARM_CPU(obj);
320 ARMISARegisters *isar = &cpu->isar;
321
322 cpu->dtb_compatible = "arm,cortex-a9";
323 set_feature(&cpu->env, ARM_FEATURE_V7);
324 set_feature(&cpu->env, ARM_FEATURE_NEON);
325 set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS);
326 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
327 set_feature(&cpu->env, ARM_FEATURE_EL3);
328 set_feature(&cpu->env, ARM_FEATURE_PMU);
329 /*
330 * Note that A9 supports the MP extensions even for
331 * A9UP and single-core A9MP (which are both different
332 * and valid configurations; we don't model A9UP).
333 */
334 set_feature(&cpu->env, ARM_FEATURE_V7MP);
335 set_feature(&cpu->env, ARM_FEATURE_CBAR);
336 set_feature(&cpu->env, ARM_FEATURE_D32DIS);
337 cpu->midr = 0x410fc090;
338 cpu->reset_fpsid = 0x41033090;
339 cpu->isar.mvfr0 = 0x11110222;
340 cpu->isar.mvfr1 = 0x01111111;
341 cpu->ctr = 0x80038003;
342 cpu->reset_sctlr = 0x00c50078;
343 SET_IDREG(isar, ID_PFR0, 0x1031);
344 SET_IDREG(isar, ID_PFR1, 0x11);
345 SET_IDREG(isar, ID_DFR0, 0x000);
346 SET_IDREG(isar, ID_AFR0, 0);
347 SET_IDREG(isar, ID_MMFR0, 0x00100103);
348 SET_IDREG(isar, ID_MMFR1, 0x20000000);
349 SET_IDREG(isar, ID_MMFR2, 0x01230000);
350 SET_IDREG(isar, ID_MMFR3, 0x00002111);
351 SET_IDREG(isar, ID_ISAR0, 0x00101111);
352 SET_IDREG(isar, ID_ISAR1, 0x13112111);
353 SET_IDREG(isar, ID_ISAR2, 0x21232041);
354 SET_IDREG(isar, ID_ISAR3, 0x11112131);
355 SET_IDREG(isar, ID_ISAR4, 0x00111142);
356 cpu->isar.dbgdidr = 0x35141000;
357 SET_IDREG(isar, CLIDR, (1 << 27) | (1 << 24) | 3);
358 cpu->ccsidr[0] = 0xe00fe019; /* 16k L1 dcache. */
359 cpu->ccsidr[1] = 0x200fe019; /* 16k L1 icache. */
360 cpu->isar.reset_pmcr_el0 = 0x41093000;
361 define_arm_cp_regs(cpu, cortexa9_cp_reginfo);
362 }
363
364 #ifndef CONFIG_USER_ONLY
365 static uint64_t a15_l2ctlr_read(CPUARMState *env, const ARMCPRegInfo *ri)
366 {
367 MachineState *ms = MACHINE(qdev_get_machine());
368
369 /*
370 * Linux wants the number of processors from here.
371 * Might as well set the interrupt-controller bit too.
372 */
373 return ((ms->smp.cpus - 1) << 24) | (1 << 23);
374 }
375 #endif
376
377 static const ARMCPRegInfo cortexa15_cp_reginfo[] = {
378 #ifndef CONFIG_USER_ONLY
379 { .name = "L2CTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 2,
380 .access = PL1_RW, .resetvalue = 0, .readfn = a15_l2ctlr_read,
381 .writefn = arm_cp_write_ignore, },
382 #endif
383 { .name = "L2ECTLR", .cp = 15, .crn = 9, .crm = 0, .opc1 = 1, .opc2 = 3,
384 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
385 };
386
387 static void cortex_a7_initfn(Object *obj)
388 {
389 ARMCPU *cpu = ARM_CPU(obj);
390 ARMISARegisters *isar = &cpu->isar;
391
392 cpu->dtb_compatible = "arm,cortex-a7";
393 set_feature(&cpu->env, ARM_FEATURE_V7VE);
394 set_feature(&cpu->env, ARM_FEATURE_NEON);
395 set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS);
396 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
397 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
398 set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
399 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
400 set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
401 set_feature(&cpu->env, ARM_FEATURE_EL2);
402 set_feature(&cpu->env, ARM_FEATURE_EL3);
403 set_feature(&cpu->env, ARM_FEATURE_PMU);
404 set_feature(&cpu->env, ARM_FEATURE_D32DIS);
405 cpu->midr = 0x410fc075;
406 cpu->reset_fpsid = 0x41023075;
407 cpu->isar.mvfr0 = 0x10110222;
408 cpu->isar.mvfr1 = 0x11111111;
409 cpu->ctr = 0x84448003;
410 cpu->reset_sctlr = 0x00c50078;
411 SET_IDREG(isar, ID_PFR0, 0x00001131);
412 SET_IDREG(isar, ID_PFR1, 0x00011011);
413 SET_IDREG(isar, ID_DFR0, 0x02010555);
414 SET_IDREG(isar, ID_AFR0, 0x00000000);
415 SET_IDREG(isar, ID_MMFR0, 0x10101105);
416 SET_IDREG(isar, ID_MMFR1, 0x40000000);
417 SET_IDREG(isar, ID_MMFR2, 0x01240000);
418 SET_IDREG(isar, ID_MMFR3, 0x02102211);
419 /*
420 * a7_mpcore_r0p5_trm, page 4-4 gives 0x01101110; but
421 * table 4-41 gives 0x02101110, which includes the arm div insns.
422 */
423 SET_IDREG(isar, ID_ISAR0, 0x02101110);
424 SET_IDREG(isar, ID_ISAR1, 0x13112111);
425 SET_IDREG(isar, ID_ISAR2, 0x21232041);
426 SET_IDREG(isar, ID_ISAR3, 0x11112131);
427 SET_IDREG(isar, ID_ISAR4, 0x10011142);
428 cpu->isar.dbgdidr = 0x3515f005;
429 cpu->isar.dbgdevid = 0x01110f13;
430 cpu->isar.dbgdevid1 = 0x1;
431 SET_IDREG(isar, CLIDR, 0x0a200023);
432 cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
433 cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
434 cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
435 cpu->isar.reset_pmcr_el0 = 0x41072000;
436 define_arm_cp_regs(cpu, cortexa15_cp_reginfo); /* Same as A15 */
437 }
438
439 static void cortex_a15_initfn(Object *obj)
440 {
441 ARMCPU *cpu = ARM_CPU(obj);
442 ARMISARegisters *isar = &cpu->isar;
443
444 cpu->dtb_compatible = "arm,cortex-a15";
445 set_feature(&cpu->env, ARM_FEATURE_V7VE);
446 set_feature(&cpu->env, ARM_FEATURE_NEON);
447 set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS);
448 set_feature(&cpu->env, ARM_FEATURE_THUMB2EE);
449 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
450 set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
451 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
452 set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
453 set_feature(&cpu->env, ARM_FEATURE_EL2);
454 set_feature(&cpu->env, ARM_FEATURE_EL3);
455 set_feature(&cpu->env, ARM_FEATURE_PMU);
456 /* r4p0 cpu, not requiring expensive tlb flush errata */
457 cpu->midr = 0x414fc0f0;
458 cpu->revidr = 0x0;
459 cpu->reset_fpsid = 0x410430f0;
460 cpu->isar.mvfr0 = 0x10110222;
461 cpu->isar.mvfr1 = 0x11111111;
462 cpu->ctr = 0x8444c004;
463 cpu->reset_sctlr = 0x00c50078;
464 SET_IDREG(isar, ID_PFR0, 0x00001131);
465 SET_IDREG(isar, ID_PFR1, 0x00011011);
466 SET_IDREG(isar, ID_DFR0, 0x02010555);
467 SET_IDREG(isar, ID_AFR0, 0x00000000);
468 SET_IDREG(isar, ID_MMFR0, 0x10201105);
469 SET_IDREG(isar, ID_MMFR1, 0x20000000);
470 SET_IDREG(isar, ID_MMFR2, 0x01240000);
471 SET_IDREG(isar, ID_MMFR3, 0x02102211);
472 SET_IDREG(isar, ID_ISAR0, 0x02101110);
473 SET_IDREG(isar, ID_ISAR1, 0x13112111);
474 SET_IDREG(isar, ID_ISAR2, 0x21232041);
475 SET_IDREG(isar, ID_ISAR3, 0x11112131);
476 SET_IDREG(isar, ID_ISAR4, 0x10011142);
477 cpu->isar.dbgdidr = 0x3515f021;
478 cpu->isar.dbgdevid = 0x01110f13;
479 cpu->isar.dbgdevid1 = 0x0;
480 SET_IDREG(isar, CLIDR, 0x0a200023);
481 cpu->ccsidr[0] = 0x701fe00a; /* 32K L1 dcache */
482 cpu->ccsidr[1] = 0x201fe00a; /* 32K L1 icache */
483 cpu->ccsidr[2] = 0x711fe07a; /* 4096K L2 unified cache */
484 cpu->isar.reset_pmcr_el0 = 0x410F3000;
485 define_arm_cp_regs(cpu, cortexa15_cp_reginfo);
486 }
487
488 static const ARMCPRegInfo cortexr5_cp_reginfo[] = {
489 /* Dummy the TCM region regs for the moment */
490 { .name = "BTCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
491 .access = PL1_RW, .type = ARM_CP_CONST },
492 { .name = "ATCM", .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
493 .access = PL1_RW, .type = ARM_CP_CONST },
494 { .name = "DCACHE_INVAL", .cp = 15, .opc1 = 0, .crn = 15, .crm = 5,
495 .opc2 = 0, .access = PL1_W, .type = ARM_CP_NOP },
496 };
497
498 static void cortex_r5_initfn(Object *obj)
499 {
500 ARMCPU *cpu = ARM_CPU(obj);
501 ARMISARegisters *isar = &cpu->isar;
502
503 set_feature(&cpu->env, ARM_FEATURE_V7);
504 set_feature(&cpu->env, ARM_FEATURE_V7MP);
505 set_feature(&cpu->env, ARM_FEATURE_PMSA);
506 set_feature(&cpu->env, ARM_FEATURE_PMU);
507 cpu->midr = 0x411fc153; /* r1p3 */
508 SET_IDREG(isar, ID_PFR0, 0x0131);
509 SET_IDREG(isar, ID_PFR1, 0x001);
510 SET_IDREG(isar, ID_DFR0, 0x010400);
511 SET_IDREG(isar, ID_AFR0, 0x0);
512 SET_IDREG(isar, ID_MMFR0, 0x0210030);
513 SET_IDREG(isar, ID_MMFR1, 0x00000000);
514 SET_IDREG(isar, ID_MMFR2, 0x01200000);
515 SET_IDREG(isar, ID_MMFR3, 0x0211);
516 SET_IDREG(isar, ID_ISAR0, 0x02101111);
517 SET_IDREG(isar, ID_ISAR1, 0x13112111);
518 SET_IDREG(isar, ID_ISAR2, 0x21232141);
519 SET_IDREG(isar, ID_ISAR3, 0x01112131);
520 SET_IDREG(isar, ID_ISAR4, 0x0010142);
521 SET_IDREG(isar, ID_ISAR5, 0x0);
522 SET_IDREG(isar, ID_ISAR6, 0x0);
523 cpu->mp_is_up = true;
524 cpu->pmsav7_dregion = 16;
525 cpu->isar.reset_pmcr_el0 = 0x41151800;
526 define_arm_cp_regs(cpu, cortexr5_cp_reginfo);
527 }
528
529 static const ARMCPRegInfo cortex_r52_cp_reginfo[] = {
530 { .name = "CPUACTLR", .cp = 15, .opc1 = 0, .crm = 15,
531 .access = PL1_RW, .type = ARM_CP_CONST | ARM_CP_64BIT, .resetvalue = 0 },
532 { .name = "IMP_ATCMREGIONR",
533 .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 0,
534 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
535 { .name = "IMP_BTCMREGIONR",
536 .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 1,
537 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
538 { .name = "IMP_CTCMREGIONR",
539 .cp = 15, .opc1 = 0, .crn = 9, .crm = 1, .opc2 = 2,
540 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
541 { .name = "IMP_CSCTLR",
542 .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 0,
543 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
544 { .name = "IMP_BPCTLR",
545 .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 1,
546 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
547 { .name = "IMP_MEMPROTCLR",
548 .cp = 15, .opc1 = 1, .crn = 9, .crm = 1, .opc2 = 2,
549 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
550 { .name = "IMP_SLAVEPCTLR",
551 .cp = 15, .opc1 = 0, .crn = 11, .crm = 0, .opc2 = 0,
552 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
553 { .name = "IMP_PERIPHREGIONR",
554 .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 0,
555 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
556 { .name = "IMP_FLASHIFREGIONR",
557 .cp = 15, .opc1 = 0, .crn = 15, .crm = 0, .opc2 = 1,
558 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
559 { .name = "IMP_BUILDOPTR",
560 .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 0,
561 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
562 { .name = "IMP_PINOPTR",
563 .cp = 15, .opc1 = 0, .crn = 15, .crm = 2, .opc2 = 7,
564 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
565 { .name = "IMP_QOSR",
566 .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 1,
567 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
568 { .name = "IMP_BUSTIMEOUTR",
569 .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 2,
570 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
571 { .name = "IMP_INTMONR",
572 .cp = 15, .opc1 = 1, .crn = 15, .crm = 3, .opc2 = 4,
573 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
574 { .name = "IMP_ICERR0",
575 .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 0,
576 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
577 { .name = "IMP_ICERR1",
578 .cp = 15, .opc1 = 2, .crn = 15, .crm = 0, .opc2 = 1,
579 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
580 { .name = "IMP_DCERR0",
581 .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 0,
582 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
583 { .name = "IMP_DCERR1",
584 .cp = 15, .opc1 = 2, .crn = 15, .crm = 1, .opc2 = 1,
585 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
586 { .name = "IMP_TCMERR0",
587 .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 0,
588 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
589 { .name = "IMP_TCMERR1",
590 .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 1,
591 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
592 { .name = "IMP_TCMSYNDR0",
593 .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 2,
594 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
595 { .name = "IMP_TCMSYNDR1",
596 .cp = 15, .opc1 = 2, .crn = 15, .crm = 2, .opc2 = 3,
597 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
598 { .name = "IMP_FLASHERR0",
599 .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 0,
600 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
601 { .name = "IMP_FLASHERR1",
602 .cp = 15, .opc1 = 2, .crn = 15, .crm = 3, .opc2 = 1,
603 .access = PL1_RW, .type = ARM_CP_CONST, .resetvalue = 0 },
604 { .name = "IMP_CDBGDR0",
605 .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 0,
606 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
607 { .name = "IMP_CBDGBR1",
608 .cp = 15, .opc1 = 3, .crn = 15, .crm = 0, .opc2 = 1,
609 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
610 { .name = "IMP_TESTR0",
611 .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 0,
612 .access = PL1_R, .type = ARM_CP_CONST, .resetvalue = 0 },
613 { .name = "IMP_TESTR1",
614 .cp = 15, .opc1 = 4, .crn = 15, .crm = 0, .opc2 = 1,
615 .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
616 { .name = "IMP_CDBGDCI",
617 .cp = 15, .opc1 = 0, .crn = 15, .crm = 15, .opc2 = 0,
618 .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
619 { .name = "IMP_CDBGDCT",
620 .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 0,
621 .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
622 { .name = "IMP_CDBGICT",
623 .cp = 15, .opc1 = 3, .crn = 15, .crm = 2, .opc2 = 1,
624 .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
625 { .name = "IMP_CDBGDCD",
626 .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 0,
627 .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
628 { .name = "IMP_CDBGICD",
629 .cp = 15, .opc1 = 3, .crn = 15, .crm = 4, .opc2 = 1,
630 .access = PL1_W, .type = ARM_CP_NOP, .resetvalue = 0 },
631 };
632
633
634 static void cortex_r52_initfn(Object *obj)
635 {
636 ARMCPU *cpu = ARM_CPU(obj);
637 ARMISARegisters *isar = &cpu->isar;
638
639 set_feature(&cpu->env, ARM_FEATURE_V8);
640 set_feature(&cpu->env, ARM_FEATURE_EL2);
641 set_feature(&cpu->env, ARM_FEATURE_PMSA);
642 set_feature(&cpu->env, ARM_FEATURE_NEON);
643 set_feature(&cpu->env, ARM_FEATURE_NEON_TRAPS);
644 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
645 set_feature(&cpu->env, ARM_FEATURE_BACKCOMPAT_CNTFRQ);
646 set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
647 set_feature(&cpu->env, ARM_FEATURE_AUXCR);
648 cpu->midr = 0x411fd133; /* r1p3 */
649 cpu->revidr = 0x00000000;
650 cpu->reset_fpsid = 0x41034023;
651 cpu->isar.mvfr0 = 0x10110222;
652 cpu->isar.mvfr1 = 0x12111111;
653 cpu->isar.mvfr2 = 0x00000043;
654 cpu->ctr = 0x8144c004;
655 cpu->reset_sctlr = 0x30c50838;
656 SET_IDREG(isar, ID_PFR0, 0x00000131);
657 SET_IDREG(isar, ID_PFR1, 0x10111001);
658 SET_IDREG(isar, ID_DFR0, 0x03010006);
659 SET_IDREG(isar, ID_AFR0, 0x00000000);
660 SET_IDREG(isar, ID_MMFR0, 0x00211040);
661 SET_IDREG(isar, ID_MMFR1, 0x40000000);
662 SET_IDREG(isar, ID_MMFR2, 0x01200000);
663 SET_IDREG(isar, ID_MMFR3, 0xf0102211);
664 SET_IDREG(isar, ID_MMFR4, 0x00000010);
665 SET_IDREG(isar, ID_ISAR0, 0x02101110);
666 SET_IDREG(isar, ID_ISAR1, 0x13112111);
667 SET_IDREG(isar, ID_ISAR2, 0x21232142);
668 SET_IDREG(isar, ID_ISAR3, 0x01112131);
669 SET_IDREG(isar, ID_ISAR4, 0x00010142);
670 SET_IDREG(isar, ID_ISAR5, 0x00010001);
671 cpu->isar.dbgdidr = 0x77168000;
672 SET_IDREG(isar, CLIDR, (1 << 27) | (1 << 24) | 0x3);
673 cpu->ccsidr[0] = 0x700fe01a; /* 32KB L1 dcache */
674 cpu->ccsidr[1] = 0x201fe00a; /* 32KB L1 icache */
675
676 cpu->pmsav7_dregion = 16;
677 cpu->pmsav8r_hdregion = 16;
678
679 define_arm_cp_regs(cpu, cortex_r52_cp_reginfo);
680 }
681
682 static void cortex_r5f_initfn(Object *obj)
683 {
684 ARMCPU *cpu = ARM_CPU(obj);
685
686 cortex_r5_initfn(obj);
687 cpu->isar.mvfr0 = 0x10110221;
688 cpu->isar.mvfr1 = 0x00000011;
689 }
690
691 static void ti925t_initfn(Object *obj)
692 {
693 ARMCPU *cpu = ARM_CPU(obj);
694 set_feature(&cpu->env, ARM_FEATURE_V4T);
695 set_feature(&cpu->env, ARM_FEATURE_OMAPCP);
696 cpu->midr = ARM_CPUID_TI925T;
697 cpu->ctr = 0x5109149;
698 cpu->reset_sctlr = 0x00000070;
699 }
700
701 static void sa1100_initfn(Object *obj)
702 {
703 ARMCPU *cpu = ARM_CPU(obj);
704
705 cpu->dtb_compatible = "intel,sa1100";
706 set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
707 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
708 cpu->midr = 0x4401A11B;
709 cpu->reset_sctlr = 0x00000070;
710 }
711
712 static void sa1110_initfn(Object *obj)
713 {
714 ARMCPU *cpu = ARM_CPU(obj);
715 set_feature(&cpu->env, ARM_FEATURE_STRONGARM);
716 set_feature(&cpu->env, ARM_FEATURE_DUMMY_C15_REGS);
717 cpu->midr = 0x6901B119;
718 cpu->reset_sctlr = 0x00000070;
719 }
720
721 static const ARMCPUInfo arm_tcg_cpus[] = {
722 { .name = "arm926", .initfn = arm926_initfn },
723 { .name = "arm946", .initfn = arm946_initfn },
724 { .name = "arm1026", .initfn = arm1026_initfn },
725 /*
726 * What QEMU calls "arm1136-r2" is actually the 1136 r0p2, i.e. an
727 * older core than plain "arm1136". In particular this does not
728 * have the v6K features.
729 */
730 { .name = "arm1136-r2", .initfn = arm1136_r2_initfn },
731 { .name = "arm1136", .initfn = arm1136_initfn },
732 { .name = "arm1176", .initfn = arm1176_initfn },
733 { .name = "arm11mpcore", .initfn = arm11mpcore_initfn },
734 { .name = "cortex-a7", .initfn = cortex_a7_initfn },
735 { .name = "cortex-a8", .initfn = cortex_a8_initfn },
736 { .name = "cortex-a9", .initfn = cortex_a9_initfn },
737 { .name = "cortex-a15", .initfn = cortex_a15_initfn },
738 { .name = "cortex-r5", .initfn = cortex_r5_initfn },
739 { .name = "cortex-r5f", .initfn = cortex_r5f_initfn },
740 { .name = "cortex-r52", .initfn = cortex_r52_initfn },
741 { .name = "ti925t", .initfn = ti925t_initfn },
742 { .name = "sa1100", .initfn = sa1100_initfn },
743 { .name = "sa1110", .initfn = sa1110_initfn },
744 };
745
746 static void arm_tcg_cpu_register_types(void)
747 {
748 size_t i;
749
750 for (i = 0; i < ARRAY_SIZE(arm_tcg_cpus); ++i) {
751 arm_cpu_register(&arm_tcg_cpus[i]);
752 }
753 }
754
755 type_init(arm_tcg_cpu_register_types)