1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "qemu/osdep.h"
22#include "qapi/error.h"
23#include "cpu.h"
24#ifdef CONFIG_TCG
25#include "hw/core/tcg-cpu-ops.h"
26#endif
27#include "qemu/module.h"
28#if !defined(CONFIG_USER_ONLY)
29#include "hw/loader.h"
30#endif
31#include "sysemu/kvm.h"
32#include "sysemu/hvf.h"
33#include "kvm_arm.h"
34#include "hvf_arm.h"
35#include "qapi/visitor.h"
36#include "hw/qdev-properties.h"
37#include "internals.h"
38
39
40static void aarch64_a57_initfn(Object *obj)
41{
42 ARMCPU *cpu = ARM_CPU(obj);
43
44 cpu->dtb_compatible = "arm,cortex-a57";
45 set_feature(&cpu->env, ARM_FEATURE_V8);
46 set_feature(&cpu->env, ARM_FEATURE_NEON);
47 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
48 set_feature(&cpu->env, ARM_FEATURE_AARCH64);
49 set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
50 set_feature(&cpu->env, ARM_FEATURE_EL2);
51 set_feature(&cpu->env, ARM_FEATURE_EL3);
52 set_feature(&cpu->env, ARM_FEATURE_PMU);
53 cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A57;
54 cpu->midr = 0x411fd070;
55 cpu->revidr = 0x00000000;
56 cpu->reset_fpsid = 0x41034070;
57 cpu->isar.mvfr0 = 0x10110222;
58 cpu->isar.mvfr1 = 0x12111111;
59 cpu->isar.mvfr2 = 0x00000043;
60 cpu->ctr = 0x8444c004;
61 cpu->reset_sctlr = 0x00c50838;
62 cpu->isar.id_pfr0 = 0x00000131;
63 cpu->isar.id_pfr1 = 0x00011011;
64 cpu->isar.id_dfr0 = 0x03010066;
65 cpu->id_afr0 = 0x00000000;
66 cpu->isar.id_mmfr0 = 0x10101105;
67 cpu->isar.id_mmfr1 = 0x40000000;
68 cpu->isar.id_mmfr2 = 0x01260000;
69 cpu->isar.id_mmfr3 = 0x02102211;
70 cpu->isar.id_isar0 = 0x02101110;
71 cpu->isar.id_isar1 = 0x13112111;
72 cpu->isar.id_isar2 = 0x21232042;
73 cpu->isar.id_isar3 = 0x01112131;
74 cpu->isar.id_isar4 = 0x00011142;
75 cpu->isar.id_isar5 = 0x00011121;
76 cpu->isar.id_isar6 = 0;
77 cpu->isar.id_aa64pfr0 = 0x00002222;
78 cpu->isar.id_aa64dfr0 = 0x10305106;
79 cpu->isar.id_aa64isar0 = 0x00011120;
80 cpu->isar.id_aa64mmfr0 = 0x00001124;
81 cpu->isar.dbgdidr = 0x3516d000;
82 cpu->isar.dbgdevid = 0x01110f13;
83 cpu->isar.dbgdevid1 = 0x2;
84 cpu->isar.reset_pmcr_el0 = 0x41013000;
85 cpu->clidr = 0x0a200023;
86 cpu->ccsidr[0] = 0x701fe00a;
87 cpu->ccsidr[1] = 0x201fe012;
88 cpu->ccsidr[2] = 0x70ffe07a;
89 cpu->dcz_blocksize = 4;
90 cpu->gic_num_lrs = 4;
91 cpu->gic_vpribits = 5;
92 cpu->gic_vprebits = 5;
93 cpu->gic_pribits = 5;
94 define_cortex_a72_a57_a53_cp_reginfo(cpu);
95}
96
97static void aarch64_a53_initfn(Object *obj)
98{
99 ARMCPU *cpu = ARM_CPU(obj);
100
101 cpu->dtb_compatible = "arm,cortex-a53";
102 set_feature(&cpu->env, ARM_FEATURE_V8);
103 set_feature(&cpu->env, ARM_FEATURE_NEON);
104 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
105 set_feature(&cpu->env, ARM_FEATURE_AARCH64);
106 set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
107 set_feature(&cpu->env, ARM_FEATURE_EL2);
108 set_feature(&cpu->env, ARM_FEATURE_EL3);
109 set_feature(&cpu->env, ARM_FEATURE_PMU);
110 cpu->kvm_target = QEMU_KVM_ARM_TARGET_CORTEX_A53;
111 cpu->midr = 0x410fd034;
112 cpu->revidr = 0x00000000;
113 cpu->reset_fpsid = 0x41034070;
114 cpu->isar.mvfr0 = 0x10110222;
115 cpu->isar.mvfr1 = 0x12111111;
116 cpu->isar.mvfr2 = 0x00000043;
117 cpu->ctr = 0x84448004;
118 cpu->reset_sctlr = 0x00c50838;
119 cpu->isar.id_pfr0 = 0x00000131;
120 cpu->isar.id_pfr1 = 0x00011011;
121 cpu->isar.id_dfr0 = 0x03010066;
122 cpu->id_afr0 = 0x00000000;
123 cpu->isar.id_mmfr0 = 0x10101105;
124 cpu->isar.id_mmfr1 = 0x40000000;
125 cpu->isar.id_mmfr2 = 0x01260000;
126 cpu->isar.id_mmfr3 = 0x02102211;
127 cpu->isar.id_isar0 = 0x02101110;
128 cpu->isar.id_isar1 = 0x13112111;
129 cpu->isar.id_isar2 = 0x21232042;
130 cpu->isar.id_isar3 = 0x01112131;
131 cpu->isar.id_isar4 = 0x00011142;
132 cpu->isar.id_isar5 = 0x00011121;
133 cpu->isar.id_isar6 = 0;
134 cpu->isar.id_aa64pfr0 = 0x00002222;
135 cpu->isar.id_aa64dfr0 = 0x10305106;
136 cpu->isar.id_aa64isar0 = 0x00011120;
137 cpu->isar.id_aa64mmfr0 = 0x00001122;
138 cpu->isar.dbgdidr = 0x3516d000;
139 cpu->isar.dbgdevid = 0x00110f13;
140 cpu->isar.dbgdevid1 = 0x1;
141 cpu->isar.reset_pmcr_el0 = 0x41033000;
142 cpu->clidr = 0x0a200023;
143 cpu->ccsidr[0] = 0x700fe01a;
144 cpu->ccsidr[1] = 0x201fe00a;
145 cpu->ccsidr[2] = 0x707fe07a;
146 cpu->dcz_blocksize = 4;
147 cpu->gic_num_lrs = 4;
148 cpu->gic_vpribits = 5;
149 cpu->gic_vprebits = 5;
150 cpu->gic_pribits = 5;
151 define_cortex_a72_a57_a53_cp_reginfo(cpu);
152}
153
154static void aarch64_a72_initfn(Object *obj)
155{
156 ARMCPU *cpu = ARM_CPU(obj);
157
158 cpu->dtb_compatible = "arm,cortex-a72";
159 set_feature(&cpu->env, ARM_FEATURE_V8);
160 set_feature(&cpu->env, ARM_FEATURE_NEON);
161 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
162 set_feature(&cpu->env, ARM_FEATURE_AARCH64);
163 set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
164 set_feature(&cpu->env, ARM_FEATURE_EL2);
165 set_feature(&cpu->env, ARM_FEATURE_EL3);
166 set_feature(&cpu->env, ARM_FEATURE_PMU);
167 cpu->midr = 0x410fd083;
168 cpu->revidr = 0x00000000;
169 cpu->reset_fpsid = 0x41034080;
170 cpu->isar.mvfr0 = 0x10110222;
171 cpu->isar.mvfr1 = 0x12111111;
172 cpu->isar.mvfr2 = 0x00000043;
173 cpu->ctr = 0x8444c004;
174 cpu->reset_sctlr = 0x00c50838;
175 cpu->isar.id_pfr0 = 0x00000131;
176 cpu->isar.id_pfr1 = 0x00011011;
177 cpu->isar.id_dfr0 = 0x03010066;
178 cpu->id_afr0 = 0x00000000;
179 cpu->isar.id_mmfr0 = 0x10201105;
180 cpu->isar.id_mmfr1 = 0x40000000;
181 cpu->isar.id_mmfr2 = 0x01260000;
182 cpu->isar.id_mmfr3 = 0x02102211;
183 cpu->isar.id_isar0 = 0x02101110;
184 cpu->isar.id_isar1 = 0x13112111;
185 cpu->isar.id_isar2 = 0x21232042;
186 cpu->isar.id_isar3 = 0x01112131;
187 cpu->isar.id_isar4 = 0x00011142;
188 cpu->isar.id_isar5 = 0x00011121;
189 cpu->isar.id_aa64pfr0 = 0x00002222;
190 cpu->isar.id_aa64dfr0 = 0x10305106;
191 cpu->isar.id_aa64isar0 = 0x00011120;
192 cpu->isar.id_aa64mmfr0 = 0x00001124;
193 cpu->isar.dbgdidr = 0x3516d000;
194 cpu->isar.dbgdevid = 0x01110f13;
195 cpu->isar.dbgdevid1 = 0x2;
196 cpu->isar.reset_pmcr_el0 = 0x41023000;
197 cpu->clidr = 0x0a200023;
198 cpu->ccsidr[0] = 0x701fe00a;
199 cpu->ccsidr[1] = 0x201fe012;
200 cpu->ccsidr[2] = 0x707fe07a;
201 cpu->dcz_blocksize = 4;
202 cpu->gic_num_lrs = 4;
203 cpu->gic_vpribits = 5;
204 cpu->gic_vprebits = 5;
205 cpu->gic_pribits = 5;
206 define_cortex_a72_a57_a53_cp_reginfo(cpu);
207}
208
209static void aarch64_a76_initfn(Object *obj)
210{
211 ARMCPU *cpu = ARM_CPU(obj);
212
213 cpu->dtb_compatible = "arm,cortex-a76";
214 set_feature(&cpu->env, ARM_FEATURE_V8);
215 set_feature(&cpu->env, ARM_FEATURE_NEON);
216 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
217 set_feature(&cpu->env, ARM_FEATURE_AARCH64);
218 set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
219 set_feature(&cpu->env, ARM_FEATURE_EL2);
220 set_feature(&cpu->env, ARM_FEATURE_EL3);
221 set_feature(&cpu->env, ARM_FEATURE_PMU);
222
223
224 cpu->clidr = 0x82000023;
225 cpu->ctr = 0x8444C004;
226 cpu->dcz_blocksize = 4;
227 cpu->isar.id_aa64dfr0 = 0x0000000010305408ull;
228 cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
229 cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
230 cpu->isar.id_aa64mmfr0 = 0x0000000000101122ull;
231 cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
232 cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
233 cpu->isar.id_aa64pfr0 = 0x1100000010111112ull;
234 cpu->isar.id_aa64pfr1 = 0x0000000000000010ull;
235 cpu->id_afr0 = 0x00000000;
236 cpu->isar.id_dfr0 = 0x04010088;
237 cpu->isar.id_isar0 = 0x02101110;
238 cpu->isar.id_isar1 = 0x13112111;
239 cpu->isar.id_isar2 = 0x21232042;
240 cpu->isar.id_isar3 = 0x01112131;
241 cpu->isar.id_isar4 = 0x00010142;
242 cpu->isar.id_isar5 = 0x01011121;
243 cpu->isar.id_isar6 = 0x00000010;
244 cpu->isar.id_mmfr0 = 0x10201105;
245 cpu->isar.id_mmfr1 = 0x40000000;
246 cpu->isar.id_mmfr2 = 0x01260000;
247 cpu->isar.id_mmfr3 = 0x02122211;
248 cpu->isar.id_mmfr4 = 0x00021110;
249 cpu->isar.id_pfr0 = 0x10010131;
250 cpu->isar.id_pfr1 = 0x00010000;
251 cpu->isar.id_pfr2 = 0x00000011;
252 cpu->midr = 0x414fd0b1;
253 cpu->revidr = 0;
254
255
256 cpu->ccsidr[0] = 0x701fe01a;
257 cpu->ccsidr[1] = 0x201fe01a;
258 cpu->ccsidr[2] = 0x707fe03a;
259
260
261 cpu->reset_sctlr = 0x30c50838;
262
263
264 cpu->gic_num_lrs = 4;
265 cpu->gic_vpribits = 5;
266 cpu->gic_vprebits = 5;
267 cpu->gic_pribits = 5;
268
269
270 cpu->isar.mvfr0 = 0x10110222;
271 cpu->isar.mvfr1 = 0x13211111;
272 cpu->isar.mvfr2 = 0x00000043;
273
274
275 cpu->isar.reset_pmcr_el0 = 0x410b3000;
276}
277
278static void aarch64_neoverse_n1_initfn(Object *obj)
279{
280 ARMCPU *cpu = ARM_CPU(obj);
281
282 cpu->dtb_compatible = "arm,neoverse-n1";
283 set_feature(&cpu->env, ARM_FEATURE_V8);
284 set_feature(&cpu->env, ARM_FEATURE_NEON);
285 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
286 set_feature(&cpu->env, ARM_FEATURE_AARCH64);
287 set_feature(&cpu->env, ARM_FEATURE_CBAR_RO);
288 set_feature(&cpu->env, ARM_FEATURE_EL2);
289 set_feature(&cpu->env, ARM_FEATURE_EL3);
290 set_feature(&cpu->env, ARM_FEATURE_PMU);
291
292
293 cpu->clidr = 0x82000023;
294 cpu->ctr = 0x8444c004;
295 cpu->dcz_blocksize = 4;
296 cpu->isar.id_aa64dfr0 = 0x0000000110305408ull;
297 cpu->isar.id_aa64isar0 = 0x0000100010211120ull;
298 cpu->isar.id_aa64isar1 = 0x0000000000100001ull;
299 cpu->isar.id_aa64mmfr0 = 0x0000000000101125ull;
300 cpu->isar.id_aa64mmfr1 = 0x0000000010212122ull;
301 cpu->isar.id_aa64mmfr2 = 0x0000000000001011ull;
302 cpu->isar.id_aa64pfr0 = 0x1100000010111112ull;
303 cpu->isar.id_aa64pfr1 = 0x0000000000000020ull;
304 cpu->id_afr0 = 0x00000000;
305 cpu->isar.id_dfr0 = 0x04010088;
306 cpu->isar.id_isar0 = 0x02101110;
307 cpu->isar.id_isar1 = 0x13112111;
308 cpu->isar.id_isar2 = 0x21232042;
309 cpu->isar.id_isar3 = 0x01112131;
310 cpu->isar.id_isar4 = 0x00010142;
311 cpu->isar.id_isar5 = 0x01011121;
312 cpu->isar.id_isar6 = 0x00000010;
313 cpu->isar.id_mmfr0 = 0x10201105;
314 cpu->isar.id_mmfr1 = 0x40000000;
315 cpu->isar.id_mmfr2 = 0x01260000;
316 cpu->isar.id_mmfr3 = 0x02122211;
317 cpu->isar.id_mmfr4 = 0x00021110;
318 cpu->isar.id_pfr0 = 0x10010131;
319 cpu->isar.id_pfr1 = 0x00010000;
320 cpu->isar.id_pfr2 = 0x00000011;
321 cpu->midr = 0x414fd0c1;
322 cpu->revidr = 0;
323
324
325 cpu->ccsidr[0] = 0x701fe01a;
326 cpu->ccsidr[1] = 0x201fe01a;
327 cpu->ccsidr[2] = 0x70ffe03a;
328
329
330 cpu->reset_sctlr = 0x30c50838;
331
332
333 cpu->gic_num_lrs = 4;
334 cpu->gic_vpribits = 5;
335 cpu->gic_vprebits = 5;
336 cpu->gic_pribits = 5;
337
338
339 cpu->isar.mvfr0 = 0x10110222;
340 cpu->isar.mvfr1 = 0x13211111;
341 cpu->isar.mvfr2 = 0x00000043;
342
343
344 cpu->isar.reset_pmcr_el0 = 0x410c3000;
345}
346
347void arm_cpu_sve_finalize(ARMCPU *cpu, Error **errp)
348{
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364 uint32_t vq_map = cpu->sve_vq.map;
365 uint32_t vq_init = cpu->sve_vq.init;
366 uint32_t vq_supported;
367 uint32_t vq_mask = 0;
368 uint32_t tmp, vq, max_vq = 0;
369
370
371
372
373
374
375
376 if (kvm_enabled()) {
377 if (kvm_arm_sve_supported()) {
378 cpu->sve_vq.supported = kvm_arm_sve_get_vls(CPU(cpu));
379 vq_supported = cpu->sve_vq.supported;
380 } else {
381 assert(!cpu_isar_feature(aa64_sve, cpu));
382 vq_supported = 0;
383 }
384 } else {
385 vq_supported = cpu->sve_vq.supported;
386 }
387
388
389
390
391
392
393 if (vq_map != 0) {
394 max_vq = 32 - clz32(vq_map);
395 vq_mask = MAKE_64BIT_MASK(0, max_vq);
396
397 if (cpu->sve_max_vq && max_vq > cpu->sve_max_vq) {
398 error_setg(errp, "cannot enable sve%d", max_vq * 128);
399 error_append_hint(errp, "sve%d is larger than the maximum vector "
400 "length, sve-max-vq=%d (%d bits)\n",
401 max_vq * 128, cpu->sve_max_vq,
402 cpu->sve_max_vq * 128);
403 return;
404 }
405
406 if (kvm_enabled()) {
407
408
409
410
411 vq_map |= vq_supported & ~vq_init & vq_mask;
412 } else {
413
414 vq_map |= SVE_VQ_POW2_MAP & ~vq_init & vq_mask;
415 }
416 } else if (cpu->sve_max_vq == 0) {
417
418
419
420 if (!cpu_isar_feature(aa64_sve, cpu)) {
421
422 return;
423 }
424
425 if (kvm_enabled()) {
426
427 tmp = vq_init & vq_supported;
428 } else {
429
430 tmp = vq_init & SVE_VQ_POW2_MAP;
431 }
432 vq = ctz32(tmp) + 1;
433
434 max_vq = vq <= ARM_MAX_VQ ? vq - 1 : ARM_MAX_VQ;
435 vq_mask = MAKE_64BIT_MASK(0, max_vq);
436 vq_map = vq_supported & ~vq_init & vq_mask;
437
438 if (max_vq == 0 || vq_map == 0) {
439 error_setg(errp, "cannot disable sve%d", vq * 128);
440 error_append_hint(errp, "Disabling sve%d results in all "
441 "vector lengths being disabled.\n",
442 vq * 128);
443 error_append_hint(errp, "With SVE enabled, at least one "
444 "vector length must be enabled.\n");
445 return;
446 }
447
448 max_vq = 32 - clz32(vq_map);
449 vq_mask = MAKE_64BIT_MASK(0, max_vq);
450 }
451
452
453
454
455
456
457 if (cpu->sve_max_vq != 0) {
458 max_vq = cpu->sve_max_vq;
459 vq_mask = MAKE_64BIT_MASK(0, max_vq);
460
461 if (vq_init & ~vq_map & (1 << (max_vq - 1))) {
462 error_setg(errp, "cannot disable sve%d", max_vq * 128);
463 error_append_hint(errp, "The maximum vector length must be "
464 "enabled, sve-max-vq=%d (%d bits)\n",
465 max_vq, max_vq * 128);
466 return;
467 }
468
469
470 vq_map |= ~vq_init & vq_mask;
471 }
472
473
474
475
476
477
478 assert(max_vq != 0);
479 assert(vq_mask != 0);
480 vq_map &= vq_mask;
481
482
483 tmp = vq_map ^ (vq_supported & vq_mask);
484 if (tmp) {
485 vq = 32 - clz32(tmp);
486 if (vq_map & (1 << (vq - 1))) {
487 if (cpu->sve_max_vq) {
488 error_setg(errp, "cannot set sve-max-vq=%d", cpu->sve_max_vq);
489 error_append_hint(errp, "This CPU does not support "
490 "the vector length %d-bits.\n", vq * 128);
491 error_append_hint(errp, "It may not be possible to use "
492 "sve-max-vq with this CPU. Try "
493 "using only sve<N> properties.\n");
494 } else {
495 error_setg(errp, "cannot enable sve%d", vq * 128);
496 if (vq_supported) {
497 error_append_hint(errp, "This CPU does not support "
498 "the vector length %d-bits.\n", vq * 128);
499 } else {
500 error_append_hint(errp, "SVE not supported by KVM "
501 "on this host\n");
502 }
503 }
504 return;
505 } else {
506 if (kvm_enabled()) {
507 error_setg(errp, "cannot disable sve%d", vq * 128);
508 error_append_hint(errp, "The KVM host requires all "
509 "supported vector lengths smaller "
510 "than %d bits to also be enabled.\n",
511 max_vq * 128);
512 return;
513 } else {
514
515 tmp = SVE_VQ_POW2_MAP & vq_mask & ~vq_map;
516 if (tmp) {
517 vq = 32 - clz32(tmp);
518 error_setg(errp, "cannot disable sve%d", vq * 128);
519 error_append_hint(errp, "sve%d is required as it "
520 "is a power-of-two length smaller "
521 "than the maximum, sve%d\n",
522 vq * 128, max_vq * 128);
523 return;
524 }
525 }
526 }
527 }
528
529
530
531
532
533 if (!cpu_isar_feature(aa64_sve, cpu)) {
534 error_setg(errp, "cannot enable sve%d", max_vq * 128);
535 error_append_hint(errp, "SVE must be enabled to enable vector "
536 "lengths.\n");
537 error_append_hint(errp, "Add sve=on to the CPU property list.\n");
538 return;
539 }
540
541
542 cpu->sve_max_vq = max_vq;
543 cpu->sve_vq.map = vq_map;
544}
545
546static void cpu_max_get_sve_max_vq(Object *obj, Visitor *v, const char *name,
547 void *opaque, Error **errp)
548{
549 ARMCPU *cpu = ARM_CPU(obj);
550 uint32_t value;
551
552
553 if (!cpu_isar_feature(aa64_sve, cpu)) {
554 value = 0;
555 } else {
556 value = cpu->sve_max_vq;
557 }
558 visit_type_uint32(v, name, &value, errp);
559}
560
561static void cpu_max_set_sve_max_vq(Object *obj, Visitor *v, const char *name,
562 void *opaque, Error **errp)
563{
564 ARMCPU *cpu = ARM_CPU(obj);
565 uint32_t max_vq;
566
567 if (!visit_type_uint32(v, name, &max_vq, errp)) {
568 return;
569 }
570
571 if (kvm_enabled() && !kvm_arm_sve_supported()) {
572 error_setg(errp, "cannot set sve-max-vq");
573 error_append_hint(errp, "SVE not supported by KVM on this host\n");
574 return;
575 }
576
577 if (max_vq == 0 || max_vq > ARM_MAX_VQ) {
578 error_setg(errp, "unsupported SVE vector length");
579 error_append_hint(errp, "Valid sve-max-vq in range [1-%d]\n",
580 ARM_MAX_VQ);
581 return;
582 }
583
584 cpu->sve_max_vq = max_vq;
585}
586
587
588
589
590
591
592static void cpu_arm_get_vq(Object *obj, Visitor *v, const char *name,
593 void *opaque, Error **errp)
594{
595 ARMCPU *cpu = ARM_CPU(obj);
596 ARMVQMap *vq_map = opaque;
597 uint32_t vq = atoi(&name[3]) / 128;
598 bool sve = vq_map == &cpu->sve_vq;
599 bool value;
600
601
602 if (sve
603 ? !cpu_isar_feature(aa64_sve, cpu)
604 : !cpu_isar_feature(aa64_sme, cpu)) {
605 value = false;
606 } else {
607 value = extract32(vq_map->map, vq - 1, 1);
608 }
609 visit_type_bool(v, name, &value, errp);
610}
611
612static void cpu_arm_set_vq(Object *obj, Visitor *v, const char *name,
613 void *opaque, Error **errp)
614{
615 ARMVQMap *vq_map = opaque;
616 uint32_t vq = atoi(&name[3]) / 128;
617 bool value;
618
619 if (!visit_type_bool(v, name, &value, errp)) {
620 return;
621 }
622
623 vq_map->map = deposit32(vq_map->map, vq - 1, 1, value);
624 vq_map->init |= 1 << (vq - 1);
625}
626
627static bool cpu_arm_get_sve(Object *obj, Error **errp)
628{
629 ARMCPU *cpu = ARM_CPU(obj);
630 return cpu_isar_feature(aa64_sve, cpu);
631}
632
633static void cpu_arm_set_sve(Object *obj, bool value, Error **errp)
634{
635 ARMCPU *cpu = ARM_CPU(obj);
636 uint64_t t;
637
638 if (value && kvm_enabled() && !kvm_arm_sve_supported()) {
639 error_setg(errp, "'sve' feature not supported by KVM on this host");
640 return;
641 }
642
643 t = cpu->isar.id_aa64pfr0;
644 t = FIELD_DP64(t, ID_AA64PFR0, SVE, value);
645 cpu->isar.id_aa64pfr0 = t;
646}
647
648void arm_cpu_sme_finalize(ARMCPU *cpu, Error **errp)
649{
650 uint32_t vq_map = cpu->sme_vq.map;
651 uint32_t vq_init = cpu->sme_vq.init;
652 uint32_t vq_supported = cpu->sme_vq.supported;
653 uint32_t vq;
654
655 if (vq_map == 0) {
656 if (!cpu_isar_feature(aa64_sme, cpu)) {
657 cpu->isar.id_aa64smfr0 = 0;
658 return;
659 }
660
661
662 vq_map = vq_supported & ~vq_init;
663
664 if (vq_map == 0) {
665 vq = ctz32(vq_supported) + 1;
666 error_setg(errp, "cannot disable sme%d", vq * 128);
667 error_append_hint(errp, "All SME vector lengths are disabled.\n");
668 error_append_hint(errp, "With SME enabled, at least one "
669 "vector length must be enabled.\n");
670 return;
671 }
672 } else {
673 if (!cpu_isar_feature(aa64_sme, cpu)) {
674 vq = 32 - clz32(vq_map);
675 error_setg(errp, "cannot enable sme%d", vq * 128);
676 error_append_hint(errp, "SME must be enabled to enable "
677 "vector lengths.\n");
678 error_append_hint(errp, "Add sme=on to the CPU property list.\n");
679 return;
680 }
681
682 }
683
684 cpu->sme_vq.map = vq_map;
685}
686
687static bool cpu_arm_get_sme(Object *obj, Error **errp)
688{
689 ARMCPU *cpu = ARM_CPU(obj);
690 return cpu_isar_feature(aa64_sme, cpu);
691}
692
693static void cpu_arm_set_sme(Object *obj, bool value, Error **errp)
694{
695 ARMCPU *cpu = ARM_CPU(obj);
696 uint64_t t;
697
698 t = cpu->isar.id_aa64pfr1;
699 t = FIELD_DP64(t, ID_AA64PFR1, SME, value);
700 cpu->isar.id_aa64pfr1 = t;
701}
702
703static bool cpu_arm_get_sme_fa64(Object *obj, Error **errp)
704{
705 ARMCPU *cpu = ARM_CPU(obj);
706 return cpu_isar_feature(aa64_sme, cpu) &&
707 cpu_isar_feature(aa64_sme_fa64, cpu);
708}
709
710static void cpu_arm_set_sme_fa64(Object *obj, bool value, Error **errp)
711{
712 ARMCPU *cpu = ARM_CPU(obj);
713 uint64_t t;
714
715 t = cpu->isar.id_aa64smfr0;
716 t = FIELD_DP64(t, ID_AA64SMFR0, FA64, value);
717 cpu->isar.id_aa64smfr0 = t;
718}
719
720#ifdef CONFIG_USER_ONLY
721
722static void cpu_arm_set_default_vec_len(Object *obj, Visitor *v,
723 const char *name, void *opaque,
724 Error **errp)
725{
726 uint32_t *ptr_default_vq = opaque;
727 int32_t default_len, default_vq, remainder;
728
729 if (!visit_type_int32(v, name, &default_len, errp)) {
730 return;
731 }
732
733
734 if (default_len == -1) {
735 *ptr_default_vq = ARM_MAX_VQ;
736 return;
737 }
738
739 default_vq = default_len / 16;
740 remainder = default_len % 16;
741
742
743
744
745
746 if (remainder || default_vq < 1 || default_vq > 512) {
747 ARMCPU *cpu = ARM_CPU(obj);
748 const char *which =
749 (ptr_default_vq == &cpu->sve_default_vq ? "sve" : "sme");
750
751 error_setg(errp, "cannot set %s-default-vector-length", which);
752 if (remainder) {
753 error_append_hint(errp, "Vector length not a multiple of 16\n");
754 } else if (default_vq < 1) {
755 error_append_hint(errp, "Vector length smaller than 16\n");
756 } else {
757 error_append_hint(errp, "Vector length larger than %d\n",
758 512 * 16);
759 }
760 return;
761 }
762
763 *ptr_default_vq = default_vq;
764}
765
766static void cpu_arm_get_default_vec_len(Object *obj, Visitor *v,
767 const char *name, void *opaque,
768 Error **errp)
769{
770 uint32_t *ptr_default_vq = opaque;
771 int32_t value = *ptr_default_vq * 16;
772
773 visit_type_int32(v, name, &value, errp);
774}
775#endif
776
777static void aarch64_add_sve_properties(Object *obj)
778{
779 ARMCPU *cpu = ARM_CPU(obj);
780 uint32_t vq;
781
782 object_property_add_bool(obj, "sve", cpu_arm_get_sve, cpu_arm_set_sve);
783
784 for (vq = 1; vq <= ARM_MAX_VQ; ++vq) {
785 char name[8];
786 sprintf(name, "sve%d", vq * 128);
787 object_property_add(obj, name, "bool", cpu_arm_get_vq,
788 cpu_arm_set_vq, NULL, &cpu->sve_vq);
789 }
790
791#ifdef CONFIG_USER_ONLY
792
793 object_property_add(obj, "sve-default-vector-length", "int32",
794 cpu_arm_get_default_vec_len,
795 cpu_arm_set_default_vec_len, NULL,
796 &cpu->sve_default_vq);
797#endif
798}
799
800static void aarch64_add_sme_properties(Object *obj)
801{
802 ARMCPU *cpu = ARM_CPU(obj);
803 uint32_t vq;
804
805 object_property_add_bool(obj, "sme", cpu_arm_get_sme, cpu_arm_set_sme);
806 object_property_add_bool(obj, "sme_fa64", cpu_arm_get_sme_fa64,
807 cpu_arm_set_sme_fa64);
808
809 for (vq = 1; vq <= ARM_MAX_VQ; vq <<= 1) {
810 char name[8];
811 sprintf(name, "sme%d", vq * 128);
812 object_property_add(obj, name, "bool", cpu_arm_get_vq,
813 cpu_arm_set_vq, NULL, &cpu->sme_vq);
814 }
815
816#ifdef CONFIG_USER_ONLY
817
818 object_property_add(obj, "sme-default-vector-length", "int32",
819 cpu_arm_get_default_vec_len,
820 cpu_arm_set_default_vec_len, NULL,
821 &cpu->sme_default_vq);
822#endif
823}
824
825void arm_cpu_pauth_finalize(ARMCPU *cpu, Error **errp)
826{
827 int arch_val = 0, impdef_val = 0;
828 uint64_t t;
829
830
831 if ((kvm_enabled() || hvf_enabled()) && cpu->prop_pauth) {
832 if (!cpu_isar_feature(aa64_pauth, cpu)) {
833 error_setg(errp, "'pauth' feature not supported by %s on this host",
834 kvm_enabled() ? "KVM" : "hvf");
835 }
836
837 return;
838 }
839
840
841 if (cpu->prop_pauth) {
842 if (cpu->prop_pauth_impdef) {
843 impdef_val = 1;
844 } else {
845 arch_val = 1;
846 }
847 } else if (cpu->prop_pauth_impdef) {
848 error_setg(errp, "cannot enable pauth-impdef without pauth");
849 error_append_hint(errp, "Add pauth=on to the CPU property list.\n");
850 }
851
852 t = cpu->isar.id_aa64isar1;
853 t = FIELD_DP64(t, ID_AA64ISAR1, APA, arch_val);
854 t = FIELD_DP64(t, ID_AA64ISAR1, GPA, arch_val);
855 t = FIELD_DP64(t, ID_AA64ISAR1, API, impdef_val);
856 t = FIELD_DP64(t, ID_AA64ISAR1, GPI, impdef_val);
857 cpu->isar.id_aa64isar1 = t;
858}
859
860static Property arm_cpu_pauth_property =
861 DEFINE_PROP_BOOL("pauth", ARMCPU, prop_pauth, true);
862static Property arm_cpu_pauth_impdef_property =
863 DEFINE_PROP_BOOL("pauth-impdef", ARMCPU, prop_pauth_impdef, false);
864
865static void aarch64_add_pauth_properties(Object *obj)
866{
867 ARMCPU *cpu = ARM_CPU(obj);
868
869
870 qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_property);
871 if (kvm_enabled() || hvf_enabled()) {
872
873
874
875
876
877
878
879
880 cpu->prop_pauth = cpu_isar_feature(aa64_pauth, cpu);
881 } else {
882 qdev_property_add_static(DEVICE(obj), &arm_cpu_pauth_impdef_property);
883 }
884}
885
886static Property arm_cpu_lpa2_property =
887 DEFINE_PROP_BOOL("lpa2", ARMCPU, prop_lpa2, true);
888
889void arm_cpu_lpa2_finalize(ARMCPU *cpu, Error **errp)
890{
891 uint64_t t;
892
893
894
895
896
897 if (!cpu->prop_lpa2) {
898 return;
899 }
900
901 t = cpu->isar.id_aa64mmfr0;
902 t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 2);
903 t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4, 1);
904 t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 3);
905 t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 3);
906 cpu->isar.id_aa64mmfr0 = t;
907}
908
909static void aarch64_host_initfn(Object *obj)
910{
911#if defined(CONFIG_KVM)
912 ARMCPU *cpu = ARM_CPU(obj);
913 kvm_arm_set_cpu_features_from_host(cpu);
914 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
915 aarch64_add_sve_properties(obj);
916 aarch64_add_pauth_properties(obj);
917 }
918#elif defined(CONFIG_HVF)
919 ARMCPU *cpu = ARM_CPU(obj);
920 hvf_arm_set_cpu_features_from_host(cpu);
921 aarch64_add_pauth_properties(obj);
922#else
923 g_assert_not_reached();
924#endif
925}
926
927
928
929
930
931
932static void aarch64_max_initfn(Object *obj)
933{
934 ARMCPU *cpu = ARM_CPU(obj);
935 uint64_t t;
936 uint32_t u;
937
938 if (kvm_enabled() || hvf_enabled()) {
939
940 aarch64_host_initfn(obj);
941 return;
942 }
943
944
945
946 aarch64_a57_initfn(obj);
947
948
949
950
951
952
953
954
955
956
957
958
959
960 t = FIELD_DP64(0, MIDR_EL1, IMPLEMENTER, 0);
961 t = FIELD_DP64(t, MIDR_EL1, ARCHITECTURE, 0xf);
962 t = FIELD_DP64(t, MIDR_EL1, PARTNUM, 'Q');
963 t = FIELD_DP64(t, MIDR_EL1, VARIANT, 0);
964 t = FIELD_DP64(t, MIDR_EL1, REVISION, 0);
965 cpu->midr = t;
966
967
968
969
970
971 u = cpu->clidr;
972 u = FIELD_DP32(u, CLIDR_EL1, LOUIS, 0);
973 u = FIELD_DP32(u, CLIDR_EL1, LOUU, 0);
974 cpu->clidr = u;
975
976 t = cpu->isar.id_aa64isar0;
977 t = FIELD_DP64(t, ID_AA64ISAR0, AES, 2);
978 t = FIELD_DP64(t, ID_AA64ISAR0, SHA1, 1);
979 t = FIELD_DP64(t, ID_AA64ISAR0, SHA2, 2);
980 t = FIELD_DP64(t, ID_AA64ISAR0, CRC32, 1);
981 t = FIELD_DP64(t, ID_AA64ISAR0, ATOMIC, 2);
982 t = FIELD_DP64(t, ID_AA64ISAR0, RDM, 1);
983 t = FIELD_DP64(t, ID_AA64ISAR0, SHA3, 1);
984 t = FIELD_DP64(t, ID_AA64ISAR0, SM3, 1);
985 t = FIELD_DP64(t, ID_AA64ISAR0, SM4, 1);
986 t = FIELD_DP64(t, ID_AA64ISAR0, DP, 1);
987 t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 1);
988 t = FIELD_DP64(t, ID_AA64ISAR0, TS, 2);
989 t = FIELD_DP64(t, ID_AA64ISAR0, TLB, 2);
990 t = FIELD_DP64(t, ID_AA64ISAR0, RNDR, 1);
991 cpu->isar.id_aa64isar0 = t;
992
993 t = cpu->isar.id_aa64isar1;
994 t = FIELD_DP64(t, ID_AA64ISAR1, DPB, 2);
995 t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 1);
996 t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 1);
997 t = FIELD_DP64(t, ID_AA64ISAR1, LRCPC, 2);
998 t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 1);
999 t = FIELD_DP64(t, ID_AA64ISAR1, SB, 1);
1000 t = FIELD_DP64(t, ID_AA64ISAR1, SPECRES, 1);
1001 t = FIELD_DP64(t, ID_AA64ISAR1, BF16, 1);
1002 t = FIELD_DP64(t, ID_AA64ISAR1, DGH, 1);
1003 t = FIELD_DP64(t, ID_AA64ISAR1, I8MM, 1);
1004 cpu->isar.id_aa64isar1 = t;
1005
1006 t = cpu->isar.id_aa64pfr0;
1007 t = FIELD_DP64(t, ID_AA64PFR0, FP, 1);
1008 t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 1);
1009 t = FIELD_DP64(t, ID_AA64PFR0, RAS, 2);
1010 t = FIELD_DP64(t, ID_AA64PFR0, SVE, 1);
1011 t = FIELD_DP64(t, ID_AA64PFR0, SEL2, 1);
1012 t = FIELD_DP64(t, ID_AA64PFR0, DIT, 1);
1013 t = FIELD_DP64(t, ID_AA64PFR0, CSV2, 2);
1014 t = FIELD_DP64(t, ID_AA64PFR0, CSV3, 1);
1015 cpu->isar.id_aa64pfr0 = t;
1016
1017 t = cpu->isar.id_aa64pfr1;
1018 t = FIELD_DP64(t, ID_AA64PFR1, BT, 1);
1019 t = FIELD_DP64(t, ID_AA64PFR1, SSBS, 2);
1020
1021
1022
1023
1024
1025 t = FIELD_DP64(t, ID_AA64PFR1, MTE, 3);
1026 t = FIELD_DP64(t, ID_AA64PFR1, RAS_FRAC, 0);
1027 t = FIELD_DP64(t, ID_AA64PFR1, SME, 1);
1028 t = FIELD_DP64(t, ID_AA64PFR1, CSV2_FRAC, 0);
1029 cpu->isar.id_aa64pfr1 = t;
1030
1031 t = cpu->isar.id_aa64mmfr0;
1032 t = FIELD_DP64(t, ID_AA64MMFR0, PARANGE, 6);
1033 t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16, 1);
1034 t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN16_2, 2);
1035 t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN64_2, 2);
1036 t = FIELD_DP64(t, ID_AA64MMFR0, TGRAN4_2, 2);
1037 cpu->isar.id_aa64mmfr0 = t;
1038
1039 t = cpu->isar.id_aa64mmfr1;
1040 t = FIELD_DP64(t, ID_AA64MMFR1, VMIDBITS, 2);
1041 t = FIELD_DP64(t, ID_AA64MMFR1, VH, 1);
1042 t = FIELD_DP64(t, ID_AA64MMFR1, HPDS, 1);
1043 t = FIELD_DP64(t, ID_AA64MMFR1, LO, 1);
1044 t = FIELD_DP64(t, ID_AA64MMFR1, PAN, 2);
1045 t = FIELD_DP64(t, ID_AA64MMFR1, XNX, 1);
1046 t = FIELD_DP64(t, ID_AA64MMFR1, HCX, 1);
1047 cpu->isar.id_aa64mmfr1 = t;
1048
1049 t = cpu->isar.id_aa64mmfr2;
1050 t = FIELD_DP64(t, ID_AA64MMFR2, CNP, 1);
1051 t = FIELD_DP64(t, ID_AA64MMFR2, UAO, 1);
1052 t = FIELD_DP64(t, ID_AA64MMFR2, IESB, 1);
1053 t = FIELD_DP64(t, ID_AA64MMFR2, VARANGE, 1);
1054 t = FIELD_DP64(t, ID_AA64MMFR2, ST, 1);
1055 t = FIELD_DP64(t, ID_AA64MMFR2, IDS, 1);
1056 t = FIELD_DP64(t, ID_AA64MMFR2, FWB, 1);
1057 t = FIELD_DP64(t, ID_AA64MMFR2, TTL, 1);
1058 t = FIELD_DP64(t, ID_AA64MMFR2, BBM, 2);
1059 cpu->isar.id_aa64mmfr2 = t;
1060
1061 t = cpu->isar.id_aa64zfr0;
1062 t = FIELD_DP64(t, ID_AA64ZFR0, SVEVER, 1);
1063 t = FIELD_DP64(t, ID_AA64ZFR0, AES, 2);
1064 t = FIELD_DP64(t, ID_AA64ZFR0, BITPERM, 1);
1065 t = FIELD_DP64(t, ID_AA64ZFR0, BFLOAT16, 1);
1066 t = FIELD_DP64(t, ID_AA64ZFR0, SHA3, 1);
1067 t = FIELD_DP64(t, ID_AA64ZFR0, SM4, 1);
1068 t = FIELD_DP64(t, ID_AA64ZFR0, I8MM, 1);
1069 t = FIELD_DP64(t, ID_AA64ZFR0, F32MM, 1);
1070 t = FIELD_DP64(t, ID_AA64ZFR0, F64MM, 1);
1071 cpu->isar.id_aa64zfr0 = t;
1072
1073 t = cpu->isar.id_aa64dfr0;
1074 t = FIELD_DP64(t, ID_AA64DFR0, DEBUGVER, 9);
1075 t = FIELD_DP64(t, ID_AA64DFR0, PMUVER, 5);
1076 cpu->isar.id_aa64dfr0 = t;
1077
1078 t = cpu->isar.id_aa64smfr0;
1079 t = FIELD_DP64(t, ID_AA64SMFR0, F32F32, 1);
1080 t = FIELD_DP64(t, ID_AA64SMFR0, B16F32, 1);
1081 t = FIELD_DP64(t, ID_AA64SMFR0, F16F32, 1);
1082 t = FIELD_DP64(t, ID_AA64SMFR0, I8I32, 0xf);
1083 t = FIELD_DP64(t, ID_AA64SMFR0, F64F64, 1);
1084 t = FIELD_DP64(t, ID_AA64SMFR0, I16I64, 0xf);
1085 t = FIELD_DP64(t, ID_AA64SMFR0, FA64, 1);
1086 cpu->isar.id_aa64smfr0 = t;
1087
1088
1089 aa32_max_features(cpu);
1090
1091#ifdef CONFIG_USER_ONLY
1092
1093
1094
1095
1096 cpu->ctr = 0x80038003;
1097 cpu->dcz_blocksize = 7;
1098#endif
1099
1100 cpu->sve_vq.supported = MAKE_64BIT_MASK(0, ARM_MAX_VQ);
1101 cpu->sme_vq.supported = SVE_VQ_POW2_MAP;
1102
1103 aarch64_add_pauth_properties(obj);
1104 aarch64_add_sve_properties(obj);
1105 aarch64_add_sme_properties(obj);
1106 object_property_add(obj, "sve-max-vq", "uint32", cpu_max_get_sve_max_vq,
1107 cpu_max_set_sve_max_vq, NULL, NULL);
1108 qdev_property_add_static(DEVICE(obj), &arm_cpu_lpa2_property);
1109}
1110
1111static void aarch64_a64fx_initfn(Object *obj)
1112{
1113 ARMCPU *cpu = ARM_CPU(obj);
1114
1115 cpu->dtb_compatible = "arm,a64fx";
1116 set_feature(&cpu->env, ARM_FEATURE_V8);
1117 set_feature(&cpu->env, ARM_FEATURE_NEON);
1118 set_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER);
1119 set_feature(&cpu->env, ARM_FEATURE_AARCH64);
1120 set_feature(&cpu->env, ARM_FEATURE_EL2);
1121 set_feature(&cpu->env, ARM_FEATURE_EL3);
1122 set_feature(&cpu->env, ARM_FEATURE_PMU);
1123 cpu->midr = 0x461f0010;
1124 cpu->revidr = 0x00000000;
1125 cpu->ctr = 0x86668006;
1126 cpu->reset_sctlr = 0x30000180;
1127 cpu->isar.id_aa64pfr0 = 0x0000000101111111;
1128 cpu->isar.id_aa64pfr1 = 0x0000000000000000;
1129 cpu->isar.id_aa64dfr0 = 0x0000000010305408;
1130 cpu->isar.id_aa64dfr1 = 0x0000000000000000;
1131 cpu->id_aa64afr0 = 0x0000000000000000;
1132 cpu->id_aa64afr1 = 0x0000000000000000;
1133 cpu->isar.id_aa64mmfr0 = 0x0000000000001122;
1134 cpu->isar.id_aa64mmfr1 = 0x0000000011212100;
1135 cpu->isar.id_aa64mmfr2 = 0x0000000000001011;
1136 cpu->isar.id_aa64isar0 = 0x0000000010211120;
1137 cpu->isar.id_aa64isar1 = 0x0000000000010001;
1138 cpu->isar.id_aa64zfr0 = 0x0000000000000000;
1139 cpu->clidr = 0x0000000080000023;
1140 cpu->ccsidr[0] = 0x7007e01c;
1141 cpu->ccsidr[1] = 0x2007e01c;
1142 cpu->ccsidr[2] = 0x70ffe07c;
1143 cpu->dcz_blocksize = 6;
1144 cpu->gic_num_lrs = 4;
1145 cpu->gic_vpribits = 5;
1146 cpu->gic_vprebits = 5;
1147 cpu->gic_pribits = 5;
1148
1149
1150 aarch64_add_sve_properties(obj);
1151 cpu->sve_vq.supported = (1 << 0)
1152 | (1 << 1)
1153 | (1 << 3);
1154
1155 cpu->isar.reset_pmcr_el0 = 0x46014040;
1156
1157
1158}
1159
1160static const ARMCPUInfo aarch64_cpus[] = {
1161 { .name = "cortex-a57", .initfn = aarch64_a57_initfn },
1162 { .name = "cortex-a53", .initfn = aarch64_a53_initfn },
1163 { .name = "cortex-a72", .initfn = aarch64_a72_initfn },
1164 { .name = "cortex-a76", .initfn = aarch64_a76_initfn },
1165 { .name = "a64fx", .initfn = aarch64_a64fx_initfn },
1166 { .name = "neoverse-n1", .initfn = aarch64_neoverse_n1_initfn },
1167 { .name = "max", .initfn = aarch64_max_initfn },
1168#if defined(CONFIG_KVM) || defined(CONFIG_HVF)
1169 { .name = "host", .initfn = aarch64_host_initfn },
1170#endif
1171};
1172
1173static bool aarch64_cpu_get_aarch64(Object *obj, Error **errp)
1174{
1175 ARMCPU *cpu = ARM_CPU(obj);
1176
1177 return arm_feature(&cpu->env, ARM_FEATURE_AARCH64);
1178}
1179
1180static void aarch64_cpu_set_aarch64(Object *obj, bool value, Error **errp)
1181{
1182 ARMCPU *cpu = ARM_CPU(obj);
1183
1184
1185
1186
1187
1188 if (value == false) {
1189 if (!kvm_enabled() || !kvm_arm_aarch32_supported()) {
1190 error_setg(errp, "'aarch64' feature cannot be disabled "
1191 "unless KVM is enabled and 32-bit EL1 "
1192 "is supported");
1193 return;
1194 }
1195 unset_feature(&cpu->env, ARM_FEATURE_AARCH64);
1196 } else {
1197 set_feature(&cpu->env, ARM_FEATURE_AARCH64);
1198 }
1199}
1200
1201static void aarch64_cpu_finalizefn(Object *obj)
1202{
1203}
1204
1205static gchar *aarch64_gdb_arch_name(CPUState *cs)
1206{
1207 return g_strdup("aarch64");
1208}
1209
1210static void aarch64_cpu_class_init(ObjectClass *oc, void *data)
1211{
1212 CPUClass *cc = CPU_CLASS(oc);
1213
1214 cc->gdb_read_register = aarch64_cpu_gdb_read_register;
1215 cc->gdb_write_register = aarch64_cpu_gdb_write_register;
1216 cc->gdb_num_core_regs = 34;
1217 cc->gdb_core_xml_file = "aarch64-core.xml";
1218 cc->gdb_arch_name = aarch64_gdb_arch_name;
1219
1220 object_class_property_add_bool(oc, "aarch64", aarch64_cpu_get_aarch64,
1221 aarch64_cpu_set_aarch64);
1222 object_class_property_set_description(oc, "aarch64",
1223 "Set on/off to enable/disable aarch64 "
1224 "execution state ");
1225}
1226
1227static void aarch64_cpu_instance_init(Object *obj)
1228{
1229 ARMCPUClass *acc = ARM_CPU_GET_CLASS(obj);
1230
1231 acc->info->initfn(obj);
1232 arm_cpu_post_init(obj);
1233}
1234
1235static void cpu_register_class_init(ObjectClass *oc, void *data)
1236{
1237 ARMCPUClass *acc = ARM_CPU_CLASS(oc);
1238
1239 acc->info = data;
1240}
1241
1242void aarch64_cpu_register(const ARMCPUInfo *info)
1243{
1244 TypeInfo type_info = {
1245 .parent = TYPE_AARCH64_CPU,
1246 .instance_size = sizeof(ARMCPU),
1247 .instance_init = aarch64_cpu_instance_init,
1248 .class_size = sizeof(ARMCPUClass),
1249 .class_init = info->class_init ?: cpu_register_class_init,
1250 .class_data = (void *)info,
1251 };
1252
1253 type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name);
1254 type_register(&type_info);
1255 g_free((void *)type_info.name);
1256}
1257
1258static const TypeInfo aarch64_cpu_type_info = {
1259 .name = TYPE_AARCH64_CPU,
1260 .parent = TYPE_ARM_CPU,
1261 .instance_size = sizeof(ARMCPU),
1262 .instance_finalize = aarch64_cpu_finalizefn,
1263 .abstract = true,
1264 .class_size = sizeof(AArch64CPUClass),
1265 .class_init = aarch64_cpu_class_init,
1266};
1267
1268static void aarch64_cpu_register_types(void)
1269{
1270 size_t i;
1271
1272 type_register_static(&aarch64_cpu_type_info);
1273
1274 for (i = 0; i < ARRAY_SIZE(aarch64_cpus); ++i) {
1275 aarch64_cpu_register(&aarch64_cpus[i]);
1276 }
1277}
1278
1279type_init(aarch64_cpu_register_types)
1280