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 "qemu/qemu-print.h"
23#include "qemu-common.h"
24#include "target/arm/idau.h"
25#include "qemu/module.h"
26#include "qapi/error.h"
27#include "qapi/visitor.h"
28#include "cpu.h"
29#ifdef CONFIG_TCG
30#include "hw/core/tcg-cpu-ops.h"
31#endif
32#include "internals.h"
33#include "exec/exec-all.h"
34#include "hw/qdev-properties.h"
35#if !defined(CONFIG_USER_ONLY)
36#include "hw/loader.h"
37#include "hw/boards.h"
38#endif
39#include "sysemu/sysemu.h"
40#include "sysemu/tcg.h"
41#include "sysemu/hw_accel.h"
42#include "kvm_arm.h"
43#include "disas/capstone.h"
44#include "fpu/softfloat.h"
45
46static void arm_cpu_set_pc(CPUState *cs, vaddr value)
47{
48 ARMCPU *cpu = ARM_CPU(cs);
49 CPUARMState *env = &cpu->env;
50
51 if (is_a64(env)) {
52 env->pc = value;
53 env->thumb = 0;
54 } else {
55 env->regs[15] = value & ~1;
56 env->thumb = value & 1;
57 }
58}
59
60#ifdef CONFIG_TCG
61void arm_cpu_synchronize_from_tb(CPUState *cs,
62 const TranslationBlock *tb)
63{
64 ARMCPU *cpu = ARM_CPU(cs);
65 CPUARMState *env = &cpu->env;
66
67
68
69
70
71 if (is_a64(env)) {
72 env->pc = tb->pc;
73 } else {
74 env->regs[15] = tb->pc;
75 }
76}
77#endif
78
79static bool arm_cpu_has_work(CPUState *cs)
80{
81 ARMCPU *cpu = ARM_CPU(cs);
82
83 return (cpu->power_state != PSCI_OFF)
84 && cs->interrupt_request &
85 (CPU_INTERRUPT_FIQ | CPU_INTERRUPT_HARD
86 | CPU_INTERRUPT_VFIQ | CPU_INTERRUPT_VIRQ
87 | CPU_INTERRUPT_EXITTB);
88}
89
90void arm_register_pre_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
91 void *opaque)
92{
93 ARMELChangeHook *entry = g_new0(ARMELChangeHook, 1);
94
95 entry->hook = hook;
96 entry->opaque = opaque;
97
98 QLIST_INSERT_HEAD(&cpu->pre_el_change_hooks, entry, node);
99}
100
101void arm_register_el_change_hook(ARMCPU *cpu, ARMELChangeHookFn *hook,
102 void *opaque)
103{
104 ARMELChangeHook *entry = g_new0(ARMELChangeHook, 1);
105
106 entry->hook = hook;
107 entry->opaque = opaque;
108
109 QLIST_INSERT_HEAD(&cpu->el_change_hooks, entry, node);
110}
111
112static void cp_reg_reset(gpointer key, gpointer value, gpointer opaque)
113{
114
115 ARMCPRegInfo *ri = value;
116 ARMCPU *cpu = opaque;
117
118 if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS)) {
119 return;
120 }
121
122 if (ri->resetfn) {
123 ri->resetfn(&cpu->env, ri);
124 return;
125 }
126
127
128
129
130
131
132 if (!ri->fieldoffset) {
133 return;
134 }
135
136 if (cpreg_field_is_64bit(ri)) {
137 CPREG_FIELD64(&cpu->env, ri) = ri->resetvalue;
138 } else {
139 CPREG_FIELD32(&cpu->env, ri) = ri->resetvalue;
140 }
141}
142
143static void cp_reg_check_reset(gpointer key, gpointer value, gpointer opaque)
144{
145
146
147
148
149
150 ARMCPRegInfo *ri = value;
151 ARMCPU *cpu = opaque;
152 uint64_t oldvalue, newvalue;
153
154 if (ri->type & (ARM_CP_SPECIAL | ARM_CP_ALIAS | ARM_CP_NO_RAW)) {
155 return;
156 }
157
158 oldvalue = read_raw_cp_reg(&cpu->env, ri);
159 cp_reg_reset(key, value, opaque);
160 newvalue = read_raw_cp_reg(&cpu->env, ri);
161 assert(oldvalue == newvalue);
162}
163
164static void arm_cpu_reset(DeviceState *dev)
165{
166 CPUState *s = CPU(dev);
167 ARMCPU *cpu = ARM_CPU(s);
168 ARMCPUClass *acc = ARM_CPU_GET_CLASS(cpu);
169 CPUARMState *env = &cpu->env;
170
171 acc->parent_reset(dev);
172
173 memset(env, 0, offsetof(CPUARMState, end_reset_fields));
174
175 g_hash_table_foreach(cpu->cp_regs, cp_reg_reset, cpu);
176 g_hash_table_foreach(cpu->cp_regs, cp_reg_check_reset, cpu);
177
178 env->vfp.xregs[ARM_VFP_FPSID] = cpu->reset_fpsid;
179 env->vfp.xregs[ARM_VFP_MVFR0] = cpu->isar.mvfr0;
180 env->vfp.xregs[ARM_VFP_MVFR1] = cpu->isar.mvfr1;
181 env->vfp.xregs[ARM_VFP_MVFR2] = cpu->isar.mvfr2;
182
183 cpu->power_state = s->start_powered_off ? PSCI_OFF : PSCI_ON;
184
185 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
186 env->iwmmxt.cregs[ARM_IWMMXT_wCID] = 0x69051000 | 'Q';
187 }
188
189 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
190
191 env->aarch64 = 1;
192#if defined(CONFIG_USER_ONLY)
193 env->pstate = PSTATE_MODE_EL0t;
194
195 env->cp15.sctlr_el[1] |= SCTLR_UCT | SCTLR_UCI | SCTLR_DZE;
196
197 env->cp15.sctlr_el[1] |= (SCTLR_EnIA | SCTLR_EnIB |
198 SCTLR_EnDA | SCTLR_EnDB);
199
200 env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 2, 3);
201
202 env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 16, 2, 3);
203
204 if (cpu_isar_feature(aa64_sve, cpu)) {
205 env->vfp.zcr_el[1] = MIN(cpu->sve_max_vq - 1, 3);
206 }
207
208
209
210
211 env->cp15.tcr_el[1].raw_tcr = (1ULL << 37);
212
213
214 if (cpu_isar_feature(aa64_mte, cpu)) {
215
216 env->cp15.sctlr_el[1] |= SCTLR_ATA0;
217
218
219
220
221
222
223
224
225 env->cp15.gcr_el1 = 0x1ffff;
226 }
227#else
228
229 if (arm_feature(env, ARM_FEATURE_EL3)) {
230 env->pstate = PSTATE_MODE_EL3h;
231 } else if (arm_feature(env, ARM_FEATURE_EL2)) {
232 env->pstate = PSTATE_MODE_EL2h;
233 } else {
234 env->pstate = PSTATE_MODE_EL1h;
235 }
236 env->pc = cpu->rvbar;
237#endif
238 } else {
239#if defined(CONFIG_USER_ONLY)
240
241 env->cp15.cpacr_el1 = deposit64(env->cp15.cpacr_el1, 20, 4, 0xf);
242#endif
243 }
244
245#if defined(CONFIG_USER_ONLY)
246 env->uncached_cpsr = ARM_CPU_MODE_USR;
247
248 env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30;
249 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
250 env->cp15.c15_cpar = 3;
251 } else if (arm_feature(env, ARM_FEATURE_XSCALE)) {
252 env->cp15.c15_cpar = 1;
253 }
254#else
255
256
257
258
259
260
261 if (arm_feature(env, ARM_FEATURE_EL2) &&
262 !arm_feature(env, ARM_FEATURE_EL3)) {
263 env->uncached_cpsr = ARM_CPU_MODE_HYP;
264 } else {
265 env->uncached_cpsr = ARM_CPU_MODE_SVC;
266 }
267 env->daif = PSTATE_D | PSTATE_A | PSTATE_I | PSTATE_F;
268#endif
269
270 if (arm_feature(env, ARM_FEATURE_M)) {
271#ifndef CONFIG_USER_ONLY
272 uint32_t initial_msp;
273 uint32_t initial_pc;
274 uint8_t *rom;
275 uint32_t vecbase;
276#endif
277
278 if (cpu_isar_feature(aa32_lob, cpu)) {
279
280
281
282
283
284 env->v7m.ltpsize = 4;
285
286 env->v7m.fpdscr[M_REG_NS] = 4 << FPCR_LTPSIZE_SHIFT;
287 env->v7m.fpdscr[M_REG_S] = 4 << FPCR_LTPSIZE_SHIFT;
288 }
289
290 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
291 env->v7m.secure = true;
292 } else {
293
294
295
296
297
298 env->v7m.aircr = R_V7M_AIRCR_BFHFNMINS_MASK;
299
300
301
302
303
304
305
306 env->v7m.nsacr = 0xcff;
307 }
308
309
310
311
312
313 env->v7m.ccr[M_REG_NS] = R_V7M_CCR_STKALIGN_MASK;
314 env->v7m.ccr[M_REG_S] = R_V7M_CCR_STKALIGN_MASK;
315 if (arm_feature(env, ARM_FEATURE_V8)) {
316
317 env->v7m.ccr[M_REG_NS] |= R_V7M_CCR_NONBASETHRDENA_MASK;
318 env->v7m.ccr[M_REG_S] |= R_V7M_CCR_NONBASETHRDENA_MASK;
319 }
320 if (!arm_feature(env, ARM_FEATURE_M_MAIN)) {
321 env->v7m.ccr[M_REG_NS] |= R_V7M_CCR_UNALIGN_TRP_MASK;
322 env->v7m.ccr[M_REG_S] |= R_V7M_CCR_UNALIGN_TRP_MASK;
323 }
324
325 if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
326 env->v7m.fpccr[M_REG_NS] = R_V7M_FPCCR_ASPEN_MASK;
327 env->v7m.fpccr[M_REG_S] = R_V7M_FPCCR_ASPEN_MASK |
328 R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK;
329 }
330
331#ifndef CONFIG_USER_ONLY
332
333 env->regs[14] = 0xffffffff;
334
335 env->v7m.vecbase[M_REG_S] = cpu->init_svtor & 0xffffff80;
336
337
338 vecbase = env->v7m.vecbase[env->v7m.secure];
339 rom = rom_ptr_for_as(s->as, vecbase, 8);
340 if (rom) {
341
342
343
344 initial_msp = ldl_p(rom);
345 initial_pc = ldl_p(rom + 4);
346 } else {
347
348
349
350
351
352 initial_msp = ldl_phys(s->as, vecbase);
353 initial_pc = ldl_phys(s->as, vecbase + 4);
354 }
355
356 env->regs[13] = initial_msp & 0xFFFFFFFC;
357 env->regs[15] = initial_pc & ~1;
358 env->thumb = initial_pc & 1;
359#else
360
361
362
363
364
365 env->v7m.secure = false;
366 env->v7m.nsacr = 0xcff;
367 env->v7m.cpacr[M_REG_NS] = 0xf0ffff;
368 env->v7m.fpccr[M_REG_S] &=
369 ~(R_V7M_FPCCR_LSPEN_MASK | R_V7M_FPCCR_S_MASK);
370 env->v7m.control[M_REG_S] |= R_V7M_CONTROL_FPCA_MASK;
371#endif
372 }
373
374#ifndef CONFIG_USER_ONLY
375
376
377
378
379 if (A32_BANKED_CURRENT_REG_GET(env, sctlr) & SCTLR_V) {
380 env->regs[15] = 0xFFFF0000;
381 }
382
383
384
385
386
387 arm_clear_exclusive(env);
388
389 env->vfp.xregs[ARM_VFP_FPEXC] = 0;
390#endif
391
392 if (arm_feature(env, ARM_FEATURE_PMSA)) {
393 if (cpu->pmsav7_dregion > 0) {
394 if (arm_feature(env, ARM_FEATURE_V8)) {
395 memset(env->pmsav8.rbar[M_REG_NS], 0,
396 sizeof(*env->pmsav8.rbar[M_REG_NS])
397 * cpu->pmsav7_dregion);
398 memset(env->pmsav8.rlar[M_REG_NS], 0,
399 sizeof(*env->pmsav8.rlar[M_REG_NS])
400 * cpu->pmsav7_dregion);
401 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
402 memset(env->pmsav8.rbar[M_REG_S], 0,
403 sizeof(*env->pmsav8.rbar[M_REG_S])
404 * cpu->pmsav7_dregion);
405 memset(env->pmsav8.rlar[M_REG_S], 0,
406 sizeof(*env->pmsav8.rlar[M_REG_S])
407 * cpu->pmsav7_dregion);
408 }
409 } else if (arm_feature(env, ARM_FEATURE_V7)) {
410 memset(env->pmsav7.drbar, 0,
411 sizeof(*env->pmsav7.drbar) * cpu->pmsav7_dregion);
412 memset(env->pmsav7.drsr, 0,
413 sizeof(*env->pmsav7.drsr) * cpu->pmsav7_dregion);
414 memset(env->pmsav7.dracr, 0,
415 sizeof(*env->pmsav7.dracr) * cpu->pmsav7_dregion);
416 }
417 }
418 env->pmsav7.rnr[M_REG_NS] = 0;
419 env->pmsav7.rnr[M_REG_S] = 0;
420 env->pmsav8.mair0[M_REG_NS] = 0;
421 env->pmsav8.mair0[M_REG_S] = 0;
422 env->pmsav8.mair1[M_REG_NS] = 0;
423 env->pmsav8.mair1[M_REG_S] = 0;
424 }
425
426 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
427 if (cpu->sau_sregion > 0) {
428 memset(env->sau.rbar, 0, sizeof(*env->sau.rbar) * cpu->sau_sregion);
429 memset(env->sau.rlar, 0, sizeof(*env->sau.rlar) * cpu->sau_sregion);
430 }
431 env->sau.rnr = 0;
432
433
434
435 env->sau.ctrl = 0;
436 }
437
438 set_flush_to_zero(1, &env->vfp.standard_fp_status);
439 set_flush_inputs_to_zero(1, &env->vfp.standard_fp_status);
440 set_default_nan_mode(1, &env->vfp.standard_fp_status);
441 set_default_nan_mode(1, &env->vfp.standard_fp_status_f16);
442 set_float_detect_tininess(float_tininess_before_rounding,
443 &env->vfp.fp_status);
444 set_float_detect_tininess(float_tininess_before_rounding,
445 &env->vfp.standard_fp_status);
446 set_float_detect_tininess(float_tininess_before_rounding,
447 &env->vfp.fp_status_f16);
448 set_float_detect_tininess(float_tininess_before_rounding,
449 &env->vfp.standard_fp_status_f16);
450#ifndef CONFIG_USER_ONLY
451 if (kvm_enabled()) {
452 kvm_arm_reset_vcpu(cpu);
453 }
454#endif
455
456 hw_breakpoint_update_all(cpu);
457 hw_watchpoint_update_all(cpu);
458 arm_rebuild_hflags(env);
459}
460
461static inline bool arm_excp_unmasked(CPUState *cs, unsigned int excp_idx,
462 unsigned int target_el,
463 unsigned int cur_el, bool secure,
464 uint64_t hcr_el2)
465{
466 CPUARMState *env = cs->env_ptr;
467 bool pstate_unmasked;
468 bool unmasked = false;
469
470
471
472
473
474
475 if (cur_el > target_el) {
476 return false;
477 }
478
479 switch (excp_idx) {
480 case EXCP_FIQ:
481 pstate_unmasked = !(env->daif & PSTATE_F);
482 break;
483
484 case EXCP_IRQ:
485 pstate_unmasked = !(env->daif & PSTATE_I);
486 break;
487
488 case EXCP_VFIQ:
489 if (!(hcr_el2 & HCR_FMO) || (hcr_el2 & HCR_TGE)) {
490
491 return false;
492 }
493 return !(env->daif & PSTATE_F);
494 case EXCP_VIRQ:
495 if (!(hcr_el2 & HCR_IMO) || (hcr_el2 & HCR_TGE)) {
496
497 return false;
498 }
499 return !(env->daif & PSTATE_I);
500 default:
501 g_assert_not_reached();
502 }
503
504
505
506
507
508
509 if ((target_el > cur_el) && (target_el != 1)) {
510
511 if (arm_feature(env, ARM_FEATURE_AARCH64)) {
512
513
514
515
516
517
518 if (target_el == 3 || !secure || (env->cp15.scr_el3 & SCR_EEL2)) {
519 unmasked = true;
520 }
521 } else {
522
523
524
525
526
527 bool hcr, scr;
528
529 switch (excp_idx) {
530 case EXCP_FIQ:
531
532
533
534
535
536
537
538 hcr = hcr_el2 & HCR_FMO;
539 scr = (env->cp15.scr_el3 & SCR_FIQ);
540
541
542
543
544
545
546
547 scr = scr && !((env->cp15.scr_el3 & SCR_FW) && !hcr);
548 break;
549 case EXCP_IRQ:
550
551
552
553
554
555
556
557 hcr = hcr_el2 & HCR_IMO;
558 scr = false;
559 break;
560 default:
561 g_assert_not_reached();
562 }
563
564 if ((scr || hcr) && !secure) {
565 unmasked = true;
566 }
567 }
568 }
569
570
571
572
573
574 return unmasked || pstate_unmasked;
575}
576
577bool arm_cpu_exec_interrupt(CPUState *cs, int interrupt_request)
578{
579 CPUClass *cc = CPU_GET_CLASS(cs);
580 CPUARMState *env = cs->env_ptr;
581 uint32_t cur_el = arm_current_el(env);
582 bool secure = arm_is_secure(env);
583 uint64_t hcr_el2 = arm_hcr_el2_eff(env);
584 uint32_t target_el;
585 uint32_t excp_idx;
586
587
588
589 if (interrupt_request & CPU_INTERRUPT_FIQ) {
590 excp_idx = EXCP_FIQ;
591 target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
592 if (arm_excp_unmasked(cs, excp_idx, target_el,
593 cur_el, secure, hcr_el2)) {
594 goto found;
595 }
596 }
597 if (interrupt_request & CPU_INTERRUPT_HARD) {
598 excp_idx = EXCP_IRQ;
599 target_el = arm_phys_excp_target_el(cs, excp_idx, cur_el, secure);
600 if (arm_excp_unmasked(cs, excp_idx, target_el,
601 cur_el, secure, hcr_el2)) {
602 goto found;
603 }
604 }
605 if (interrupt_request & CPU_INTERRUPT_VIRQ) {
606 excp_idx = EXCP_VIRQ;
607 target_el = 1;
608 if (arm_excp_unmasked(cs, excp_idx, target_el,
609 cur_el, secure, hcr_el2)) {
610 goto found;
611 }
612 }
613 if (interrupt_request & CPU_INTERRUPT_VFIQ) {
614 excp_idx = EXCP_VFIQ;
615 target_el = 1;
616 if (arm_excp_unmasked(cs, excp_idx, target_el,
617 cur_el, secure, hcr_el2)) {
618 goto found;
619 }
620 }
621 return false;
622
623 found:
624 cs->exception_index = excp_idx;
625 env->exception.target_el = target_el;
626 cc->tcg_ops->do_interrupt(cs);
627 return true;
628}
629
630void arm_cpu_update_virq(ARMCPU *cpu)
631{
632
633
634
635
636 CPUARMState *env = &cpu->env;
637 CPUState *cs = CPU(cpu);
638
639 bool new_state = (env->cp15.hcr_el2 & HCR_VI) ||
640 (env->irq_line_state & CPU_INTERRUPT_VIRQ);
641
642 if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VIRQ) != 0)) {
643 if (new_state) {
644 cpu_interrupt(cs, CPU_INTERRUPT_VIRQ);
645 } else {
646 cpu_reset_interrupt(cs, CPU_INTERRUPT_VIRQ);
647 }
648 }
649}
650
651void arm_cpu_update_vfiq(ARMCPU *cpu)
652{
653
654
655
656
657 CPUARMState *env = &cpu->env;
658 CPUState *cs = CPU(cpu);
659
660 bool new_state = (env->cp15.hcr_el2 & HCR_VF) ||
661 (env->irq_line_state & CPU_INTERRUPT_VFIQ);
662
663 if (new_state != ((cs->interrupt_request & CPU_INTERRUPT_VFIQ) != 0)) {
664 if (new_state) {
665 cpu_interrupt(cs, CPU_INTERRUPT_VFIQ);
666 } else {
667 cpu_reset_interrupt(cs, CPU_INTERRUPT_VFIQ);
668 }
669 }
670}
671
672#ifndef CONFIG_USER_ONLY
673static void arm_cpu_set_irq(void *opaque, int irq, int level)
674{
675 ARMCPU *cpu = opaque;
676 CPUARMState *env = &cpu->env;
677 CPUState *cs = CPU(cpu);
678 static const int mask[] = {
679 [ARM_CPU_IRQ] = CPU_INTERRUPT_HARD,
680 [ARM_CPU_FIQ] = CPU_INTERRUPT_FIQ,
681 [ARM_CPU_VIRQ] = CPU_INTERRUPT_VIRQ,
682 [ARM_CPU_VFIQ] = CPU_INTERRUPT_VFIQ
683 };
684
685 if (level) {
686 env->irq_line_state |= mask[irq];
687 } else {
688 env->irq_line_state &= ~mask[irq];
689 }
690
691 switch (irq) {
692 case ARM_CPU_VIRQ:
693 assert(arm_feature(env, ARM_FEATURE_EL2));
694 arm_cpu_update_virq(cpu);
695 break;
696 case ARM_CPU_VFIQ:
697 assert(arm_feature(env, ARM_FEATURE_EL2));
698 arm_cpu_update_vfiq(cpu);
699 break;
700 case ARM_CPU_IRQ:
701 case ARM_CPU_FIQ:
702 if (level) {
703 cpu_interrupt(cs, mask[irq]);
704 } else {
705 cpu_reset_interrupt(cs, mask[irq]);
706 }
707 break;
708 default:
709 g_assert_not_reached();
710 }
711}
712
713static void arm_cpu_kvm_set_irq(void *opaque, int irq, int level)
714{
715#ifdef CONFIG_KVM
716 ARMCPU *cpu = opaque;
717 CPUARMState *env = &cpu->env;
718 CPUState *cs = CPU(cpu);
719 uint32_t linestate_bit;
720 int irq_id;
721
722 switch (irq) {
723 case ARM_CPU_IRQ:
724 irq_id = KVM_ARM_IRQ_CPU_IRQ;
725 linestate_bit = CPU_INTERRUPT_HARD;
726 break;
727 case ARM_CPU_FIQ:
728 irq_id = KVM_ARM_IRQ_CPU_FIQ;
729 linestate_bit = CPU_INTERRUPT_FIQ;
730 break;
731 default:
732 g_assert_not_reached();
733 }
734
735 if (level) {
736 env->irq_line_state |= linestate_bit;
737 } else {
738 env->irq_line_state &= ~linestate_bit;
739 }
740 kvm_arm_set_irq(cs->cpu_index, KVM_ARM_IRQ_TYPE_CPU, irq_id, !!level);
741#endif
742}
743
744static bool arm_cpu_virtio_is_big_endian(CPUState *cs)
745{
746 ARMCPU *cpu = ARM_CPU(cs);
747 CPUARMState *env = &cpu->env;
748
749 cpu_synchronize_state(cs);
750 return arm_cpu_data_is_big_endian(env);
751}
752
753#endif
754
755static int
756print_insn_thumb1(bfd_vma pc, disassemble_info *info)
757{
758 return print_insn_arm(pc | 1, info);
759}
760
761static void arm_disas_set_info(CPUState *cpu, disassemble_info *info)
762{
763 ARMCPU *ac = ARM_CPU(cpu);
764 CPUARMState *env = &ac->env;
765 bool sctlr_b;
766
767 if (is_a64(env)) {
768
769
770
771
772#if defined(CONFIG_ARM_A64_DIS)
773 info->print_insn = print_insn_arm_a64;
774#endif
775 info->cap_arch = CS_ARCH_ARM64;
776 info->cap_insn_unit = 4;
777 info->cap_insn_split = 4;
778 } else {
779 int cap_mode;
780 if (env->thumb) {
781 info->print_insn = print_insn_thumb1;
782 info->cap_insn_unit = 2;
783 info->cap_insn_split = 4;
784 cap_mode = CS_MODE_THUMB;
785 } else {
786 info->print_insn = print_insn_arm;
787 info->cap_insn_unit = 4;
788 info->cap_insn_split = 4;
789 cap_mode = CS_MODE_ARM;
790 }
791 if (arm_feature(env, ARM_FEATURE_V8)) {
792 cap_mode |= CS_MODE_V8;
793 }
794 if (arm_feature(env, ARM_FEATURE_M)) {
795 cap_mode |= CS_MODE_MCLASS;
796 }
797 info->cap_arch = CS_ARCH_ARM;
798 info->cap_mode = cap_mode;
799 }
800
801 sctlr_b = arm_sctlr_b(env);
802 if (bswap_code(sctlr_b)) {
803#ifdef TARGET_WORDS_BIGENDIAN
804 info->endian = BFD_ENDIAN_LITTLE;
805#else
806 info->endian = BFD_ENDIAN_BIG;
807#endif
808 }
809 info->flags &= ~INSN_ARM_BE32;
810#ifndef CONFIG_USER_ONLY
811 if (sctlr_b) {
812 info->flags |= INSN_ARM_BE32;
813 }
814#endif
815}
816
817#ifdef TARGET_AARCH64
818
819static void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
820{
821 ARMCPU *cpu = ARM_CPU(cs);
822 CPUARMState *env = &cpu->env;
823 uint32_t psr = pstate_read(env);
824 int i;
825 int el = arm_current_el(env);
826 const char *ns_status;
827
828 qemu_fprintf(f, " PC=%016" PRIx64 " ", env->pc);
829 for (i = 0; i < 32; i++) {
830 if (i == 31) {
831 qemu_fprintf(f, " SP=%016" PRIx64 "\n", env->xregs[i]);
832 } else {
833 qemu_fprintf(f, "X%02d=%016" PRIx64 "%s", i, env->xregs[i],
834 (i + 2) % 3 ? " " : "\n");
835 }
836 }
837
838 if (arm_feature(env, ARM_FEATURE_EL3) && el != 3) {
839 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
840 } else {
841 ns_status = "";
842 }
843 qemu_fprintf(f, "PSTATE=%08x %c%c%c%c %sEL%d%c",
844 psr,
845 psr & PSTATE_N ? 'N' : '-',
846 psr & PSTATE_Z ? 'Z' : '-',
847 psr & PSTATE_C ? 'C' : '-',
848 psr & PSTATE_V ? 'V' : '-',
849 ns_status,
850 el,
851 psr & PSTATE_SP ? 'h' : 't');
852
853 if (cpu_isar_feature(aa64_bti, cpu)) {
854 qemu_fprintf(f, " BTYPE=%d", (psr & PSTATE_BTYPE) >> 10);
855 }
856 if (!(flags & CPU_DUMP_FPU)) {
857 qemu_fprintf(f, "\n");
858 return;
859 }
860 if (fp_exception_el(env, el) != 0) {
861 qemu_fprintf(f, " FPU disabled\n");
862 return;
863 }
864 qemu_fprintf(f, " FPCR=%08x FPSR=%08x\n",
865 vfp_get_fpcr(env), vfp_get_fpsr(env));
866
867 if (cpu_isar_feature(aa64_sve, cpu) && sve_exception_el(env, el) == 0) {
868 int j, zcr_len = sve_zcr_len_for_el(env, el);
869
870 for (i = 0; i <= FFR_PRED_NUM; i++) {
871 bool eol;
872 if (i == FFR_PRED_NUM) {
873 qemu_fprintf(f, "FFR=");
874
875 eol = true;
876 } else {
877 qemu_fprintf(f, "P%02d=", i);
878 switch (zcr_len) {
879 case 0:
880 eol = i % 8 == 7;
881 break;
882 case 1:
883 eol = i % 6 == 5;
884 break;
885 case 2:
886 case 3:
887 eol = i % 3 == 2;
888 break;
889 default:
890
891 eol = true;
892 break;
893 }
894 }
895 for (j = zcr_len / 4; j >= 0; j--) {
896 int digits;
897 if (j * 4 + 4 <= zcr_len + 1) {
898 digits = 16;
899 } else {
900 digits = (zcr_len % 4 + 1) * 4;
901 }
902 qemu_fprintf(f, "%0*" PRIx64 "%s", digits,
903 env->vfp.pregs[i].p[j],
904 j ? ":" : eol ? "\n" : " ");
905 }
906 }
907
908 for (i = 0; i < 32; i++) {
909 if (zcr_len == 0) {
910 qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64 "%s",
911 i, env->vfp.zregs[i].d[1],
912 env->vfp.zregs[i].d[0], i & 1 ? "\n" : " ");
913 } else if (zcr_len == 1) {
914 qemu_fprintf(f, "Z%02d=%016" PRIx64 ":%016" PRIx64
915 ":%016" PRIx64 ":%016" PRIx64 "\n",
916 i, env->vfp.zregs[i].d[3], env->vfp.zregs[i].d[2],
917 env->vfp.zregs[i].d[1], env->vfp.zregs[i].d[0]);
918 } else {
919 for (j = zcr_len; j >= 0; j--) {
920 bool odd = (zcr_len - j) % 2 != 0;
921 if (j == zcr_len) {
922 qemu_fprintf(f, "Z%02d[%x-%x]=", i, j, j - 1);
923 } else if (!odd) {
924 if (j > 0) {
925 qemu_fprintf(f, " [%x-%x]=", j, j - 1);
926 } else {
927 qemu_fprintf(f, " [%x]=", j);
928 }
929 }
930 qemu_fprintf(f, "%016" PRIx64 ":%016" PRIx64 "%s",
931 env->vfp.zregs[i].d[j * 2 + 1],
932 env->vfp.zregs[i].d[j * 2],
933 odd || j == 0 ? "\n" : ":");
934 }
935 }
936 }
937 } else {
938 for (i = 0; i < 32; i++) {
939 uint64_t *q = aa64_vfp_qreg(env, i);
940 qemu_fprintf(f, "Q%02d=%016" PRIx64 ":%016" PRIx64 "%s",
941 i, q[1], q[0], (i & 1 ? "\n" : " "));
942 }
943 }
944}
945
946#else
947
948static inline void aarch64_cpu_dump_state(CPUState *cs, FILE *f, int flags)
949{
950 g_assert_not_reached();
951}
952
953#endif
954
955static void arm_cpu_dump_state(CPUState *cs, FILE *f, int flags)
956{
957 ARMCPU *cpu = ARM_CPU(cs);
958 CPUARMState *env = &cpu->env;
959 int i;
960
961 if (is_a64(env)) {
962 aarch64_cpu_dump_state(cs, f, flags);
963 return;
964 }
965
966 for (i = 0; i < 16; i++) {
967 qemu_fprintf(f, "R%02d=%08x", i, env->regs[i]);
968 if ((i % 4) == 3) {
969 qemu_fprintf(f, "\n");
970 } else {
971 qemu_fprintf(f, " ");
972 }
973 }
974
975 if (arm_feature(env, ARM_FEATURE_M)) {
976 uint32_t xpsr = xpsr_read(env);
977 const char *mode;
978 const char *ns_status = "";
979
980 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
981 ns_status = env->v7m.secure ? "S " : "NS ";
982 }
983
984 if (xpsr & XPSR_EXCP) {
985 mode = "handler";
986 } else {
987 if (env->v7m.control[env->v7m.secure] & R_V7M_CONTROL_NPRIV_MASK) {
988 mode = "unpriv-thread";
989 } else {
990 mode = "priv-thread";
991 }
992 }
993
994 qemu_fprintf(f, "XPSR=%08x %c%c%c%c %c %s%s\n",
995 xpsr,
996 xpsr & XPSR_N ? 'N' : '-',
997 xpsr & XPSR_Z ? 'Z' : '-',
998 xpsr & XPSR_C ? 'C' : '-',
999 xpsr & XPSR_V ? 'V' : '-',
1000 xpsr & XPSR_T ? 'T' : 'A',
1001 ns_status,
1002 mode);
1003 } else {
1004 uint32_t psr = cpsr_read(env);
1005 const char *ns_status = "";
1006
1007 if (arm_feature(env, ARM_FEATURE_EL3) &&
1008 (psr & CPSR_M) != ARM_CPU_MODE_MON) {
1009 ns_status = env->cp15.scr_el3 & SCR_NS ? "NS " : "S ";
1010 }
1011
1012 qemu_fprintf(f, "PSR=%08x %c%c%c%c %c %s%s%d\n",
1013 psr,
1014 psr & CPSR_N ? 'N' : '-',
1015 psr & CPSR_Z ? 'Z' : '-',
1016 psr & CPSR_C ? 'C' : '-',
1017 psr & CPSR_V ? 'V' : '-',
1018 psr & CPSR_T ? 'T' : 'A',
1019 ns_status,
1020 aarch32_mode_name(psr), (psr & 0x10) ? 32 : 26);
1021 }
1022
1023 if (flags & CPU_DUMP_FPU) {
1024 int numvfpregs = 0;
1025 if (cpu_isar_feature(aa32_simd_r32, cpu)) {
1026 numvfpregs = 32;
1027 } else if (cpu_isar_feature(aa32_vfp_simd, cpu)) {
1028 numvfpregs = 16;
1029 }
1030 for (i = 0; i < numvfpregs; i++) {
1031 uint64_t v = *aa32_vfp_dreg(env, i);
1032 qemu_fprintf(f, "s%02d=%08x s%02d=%08x d%02d=%016" PRIx64 "\n",
1033 i * 2, (uint32_t)v,
1034 i * 2 + 1, (uint32_t)(v >> 32),
1035 i, v);
1036 }
1037 qemu_fprintf(f, "FPSCR: %08x\n", vfp_get_fpscr(env));
1038 }
1039}
1040
1041uint64_t arm_cpu_mp_affinity(int idx, uint8_t clustersz)
1042{
1043 uint32_t Aff1 = idx / clustersz;
1044 uint32_t Aff0 = idx % clustersz;
1045 return (Aff1 << ARM_AFF1_SHIFT) | Aff0;
1046}
1047
1048static void cpreg_hashtable_data_destroy(gpointer data)
1049{
1050
1051
1052
1053
1054
1055
1056 ARMCPRegInfo *r = data;
1057
1058 g_free((void *)r->name);
1059 g_free(r);
1060}
1061
1062static void arm_cpu_initfn(Object *obj)
1063{
1064 ARMCPU *cpu = ARM_CPU(obj);
1065
1066 cpu_set_cpustate_pointers(cpu);
1067 cpu->cp_regs = g_hash_table_new_full(g_int_hash, g_int_equal,
1068 g_free, cpreg_hashtable_data_destroy);
1069
1070 QLIST_INIT(&cpu->pre_el_change_hooks);
1071 QLIST_INIT(&cpu->el_change_hooks);
1072
1073#ifndef CONFIG_USER_ONLY
1074
1075 if (kvm_enabled()) {
1076
1077
1078
1079 qdev_init_gpio_in(DEVICE(cpu), arm_cpu_kvm_set_irq, 4);
1080 } else {
1081 qdev_init_gpio_in(DEVICE(cpu), arm_cpu_set_irq, 4);
1082 }
1083
1084 qdev_init_gpio_out(DEVICE(cpu), cpu->gt_timer_outputs,
1085 ARRAY_SIZE(cpu->gt_timer_outputs));
1086
1087 qdev_init_gpio_out_named(DEVICE(cpu), &cpu->gicv3_maintenance_interrupt,
1088 "gicv3-maintenance-interrupt", 1);
1089 qdev_init_gpio_out_named(DEVICE(cpu), &cpu->pmu_interrupt,
1090 "pmu-interrupt", 1);
1091#endif
1092
1093
1094
1095
1096
1097 cpu->dtb_compatible = "qemu,unknown";
1098 cpu->psci_version = 1;
1099 cpu->kvm_target = QEMU_KVM_ARM_TARGET_NONE;
1100
1101 if (tcg_enabled()) {
1102 cpu->psci_version = 2;
1103 }
1104}
1105
1106static Property arm_cpu_gt_cntfrq_property =
1107 DEFINE_PROP_UINT64("cntfrq", ARMCPU, gt_cntfrq_hz,
1108 NANOSECONDS_PER_SECOND / GTIMER_SCALE);
1109
1110static Property arm_cpu_reset_cbar_property =
1111 DEFINE_PROP_UINT64("reset-cbar", ARMCPU, reset_cbar, 0);
1112
1113static Property arm_cpu_reset_hivecs_property =
1114 DEFINE_PROP_BOOL("reset-hivecs", ARMCPU, reset_hivecs, false);
1115
1116static Property arm_cpu_rvbar_property =
1117 DEFINE_PROP_UINT64("rvbar", ARMCPU, rvbar, 0);
1118
1119#ifndef CONFIG_USER_ONLY
1120static Property arm_cpu_has_el2_property =
1121 DEFINE_PROP_BOOL("has_el2", ARMCPU, has_el2, true);
1122
1123static Property arm_cpu_has_el3_property =
1124 DEFINE_PROP_BOOL("has_el3", ARMCPU, has_el3, true);
1125#endif
1126
1127static Property arm_cpu_cfgend_property =
1128 DEFINE_PROP_BOOL("cfgend", ARMCPU, cfgend, false);
1129
1130static Property arm_cpu_has_vfp_property =
1131 DEFINE_PROP_BOOL("vfp", ARMCPU, has_vfp, true);
1132
1133static Property arm_cpu_has_neon_property =
1134 DEFINE_PROP_BOOL("neon", ARMCPU, has_neon, true);
1135
1136static Property arm_cpu_has_dsp_property =
1137 DEFINE_PROP_BOOL("dsp", ARMCPU, has_dsp, true);
1138
1139static Property arm_cpu_has_mpu_property =
1140 DEFINE_PROP_BOOL("has-mpu", ARMCPU, has_mpu, true);
1141
1142
1143
1144
1145
1146
1147static Property arm_cpu_pmsav7_dregion_property =
1148 DEFINE_PROP_UNSIGNED_NODEFAULT("pmsav7-dregion", ARMCPU,
1149 pmsav7_dregion,
1150 qdev_prop_uint32, uint32_t);
1151
1152static bool arm_get_pmu(Object *obj, Error **errp)
1153{
1154 ARMCPU *cpu = ARM_CPU(obj);
1155
1156 return cpu->has_pmu;
1157}
1158
1159static void arm_set_pmu(Object *obj, bool value, Error **errp)
1160{
1161 ARMCPU *cpu = ARM_CPU(obj);
1162
1163 if (value) {
1164 if (kvm_enabled() && !kvm_arm_pmu_supported()) {
1165 error_setg(errp, "'pmu' feature not supported by KVM on this host");
1166 return;
1167 }
1168 set_feature(&cpu->env, ARM_FEATURE_PMU);
1169 } else {
1170 unset_feature(&cpu->env, ARM_FEATURE_PMU);
1171 }
1172 cpu->has_pmu = value;
1173}
1174
1175unsigned int gt_cntfrq_period_ns(ARMCPU *cpu)
1176{
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195 return NANOSECONDS_PER_SECOND > cpu->gt_cntfrq_hz ?
1196 NANOSECONDS_PER_SECOND / cpu->gt_cntfrq_hz : 1;
1197}
1198
1199void arm_cpu_post_init(Object *obj)
1200{
1201 ARMCPU *cpu = ARM_CPU(obj);
1202
1203
1204
1205
1206
1207 if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
1208 set_feature(&cpu->env, ARM_FEATURE_PMSA);
1209 }
1210
1211 if (arm_feature(&cpu->env, ARM_FEATURE_CBAR) ||
1212 arm_feature(&cpu->env, ARM_FEATURE_CBAR_RO)) {
1213 qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_cbar_property);
1214 }
1215
1216 if (!arm_feature(&cpu->env, ARM_FEATURE_M)) {
1217 qdev_property_add_static(DEVICE(obj), &arm_cpu_reset_hivecs_property);
1218 }
1219
1220 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
1221 qdev_property_add_static(DEVICE(obj), &arm_cpu_rvbar_property);
1222 }
1223
1224#ifndef CONFIG_USER_ONLY
1225 if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
1226
1227
1228
1229 qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el3_property);
1230
1231 object_property_add_link(obj, "secure-memory",
1232 TYPE_MEMORY_REGION,
1233 (Object **)&cpu->secure_memory,
1234 qdev_prop_allow_set_link_before_realize,
1235 OBJ_PROP_LINK_STRONG);
1236 }
1237
1238 if (arm_feature(&cpu->env, ARM_FEATURE_EL2)) {
1239 qdev_property_add_static(DEVICE(obj), &arm_cpu_has_el2_property);
1240 }
1241#endif
1242
1243 if (arm_feature(&cpu->env, ARM_FEATURE_PMU)) {
1244 cpu->has_pmu = true;
1245 object_property_add_bool(obj, "pmu", arm_get_pmu, arm_set_pmu);
1246 }
1247
1248
1249
1250
1251
1252
1253 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)
1254 ? cpu_isar_feature(aa64_fp_simd, cpu)
1255 : cpu_isar_feature(aa32_vfp, cpu)) {
1256 cpu->has_vfp = true;
1257 if (!kvm_enabled()) {
1258 qdev_property_add_static(DEVICE(obj), &arm_cpu_has_vfp_property);
1259 }
1260 }
1261
1262 if (arm_feature(&cpu->env, ARM_FEATURE_NEON)) {
1263 cpu->has_neon = true;
1264 if (!kvm_enabled()) {
1265 qdev_property_add_static(DEVICE(obj), &arm_cpu_has_neon_property);
1266 }
1267 }
1268
1269 if (arm_feature(&cpu->env, ARM_FEATURE_M) &&
1270 arm_feature(&cpu->env, ARM_FEATURE_THUMB_DSP)) {
1271 qdev_property_add_static(DEVICE(obj), &arm_cpu_has_dsp_property);
1272 }
1273
1274 if (arm_feature(&cpu->env, ARM_FEATURE_PMSA)) {
1275 qdev_property_add_static(DEVICE(obj), &arm_cpu_has_mpu_property);
1276 if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
1277 qdev_property_add_static(DEVICE(obj),
1278 &arm_cpu_pmsav7_dregion_property);
1279 }
1280 }
1281
1282 if (arm_feature(&cpu->env, ARM_FEATURE_M_SECURITY)) {
1283 object_property_add_link(obj, "idau", TYPE_IDAU_INTERFACE, &cpu->idau,
1284 qdev_prop_allow_set_link_before_realize,
1285 OBJ_PROP_LINK_STRONG);
1286
1287
1288
1289
1290
1291 object_property_add_uint32_ptr(obj, "init-svtor",
1292 &cpu->init_svtor,
1293 OBJ_PROP_FLAG_READWRITE);
1294 }
1295
1296 qdev_property_add_static(DEVICE(obj), &arm_cpu_cfgend_property);
1297
1298 if (arm_feature(&cpu->env, ARM_FEATURE_GENERIC_TIMER)) {
1299 qdev_property_add_static(DEVICE(cpu), &arm_cpu_gt_cntfrq_property);
1300 }
1301
1302 if (kvm_enabled()) {
1303 kvm_arm_add_vcpu_properties(obj);
1304 }
1305
1306#ifndef CONFIG_USER_ONLY
1307 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64) &&
1308 cpu_isar_feature(aa64_mte, cpu)) {
1309 object_property_add_link(obj, "tag-memory",
1310 TYPE_MEMORY_REGION,
1311 (Object **)&cpu->tag_memory,
1312 qdev_prop_allow_set_link_before_realize,
1313 OBJ_PROP_LINK_STRONG);
1314
1315 if (arm_feature(&cpu->env, ARM_FEATURE_EL3)) {
1316 object_property_add_link(obj, "secure-tag-memory",
1317 TYPE_MEMORY_REGION,
1318 (Object **)&cpu->secure_tag_memory,
1319 qdev_prop_allow_set_link_before_realize,
1320 OBJ_PROP_LINK_STRONG);
1321 }
1322 }
1323#endif
1324}
1325
1326static void arm_cpu_finalizefn(Object *obj)
1327{
1328 ARMCPU *cpu = ARM_CPU(obj);
1329 ARMELChangeHook *hook, *next;
1330
1331 g_hash_table_destroy(cpu->cp_regs);
1332
1333 QLIST_FOREACH_SAFE(hook, &cpu->pre_el_change_hooks, node, next) {
1334 QLIST_REMOVE(hook, node);
1335 g_free(hook);
1336 }
1337 QLIST_FOREACH_SAFE(hook, &cpu->el_change_hooks, node, next) {
1338 QLIST_REMOVE(hook, node);
1339 g_free(hook);
1340 }
1341#ifndef CONFIG_USER_ONLY
1342 if (cpu->pmu_timer) {
1343 timer_free(cpu->pmu_timer);
1344 }
1345#endif
1346}
1347
1348void arm_cpu_finalize_features(ARMCPU *cpu, Error **errp)
1349{
1350 Error *local_err = NULL;
1351
1352 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
1353 arm_cpu_sve_finalize(cpu, &local_err);
1354 if (local_err != NULL) {
1355 error_propagate(errp, local_err);
1356 return;
1357 }
1358
1359
1360
1361
1362
1363
1364 if (!kvm_enabled()) {
1365 arm_cpu_pauth_finalize(cpu, &local_err);
1366 if (local_err != NULL) {
1367 error_propagate(errp, local_err);
1368 return;
1369 }
1370 }
1371 }
1372
1373 if (kvm_enabled()) {
1374 kvm_arm_steal_time_finalize(cpu, &local_err);
1375 if (local_err != NULL) {
1376 error_propagate(errp, local_err);
1377 return;
1378 }
1379 }
1380}
1381
1382static void arm_cpu_realizefn(DeviceState *dev, Error **errp)
1383{
1384 CPUState *cs = CPU(dev);
1385 ARMCPU *cpu = ARM_CPU(dev);
1386 ARMCPUClass *acc = ARM_CPU_GET_CLASS(dev);
1387 CPUARMState *env = &cpu->env;
1388 int pagebits;
1389 Error *local_err = NULL;
1390 bool no_aa32 = false;
1391
1392
1393
1394
1395
1396 if (cpu->host_cpu_probe_failed) {
1397 if (!kvm_enabled()) {
1398 error_setg(errp, "The 'host' CPU type can only be used with KVM");
1399 } else {
1400 error_setg(errp, "Failed to retrieve host CPU features");
1401 }
1402 return;
1403 }
1404
1405#ifndef CONFIG_USER_ONLY
1406
1407
1408
1409
1410 if (arm_feature(env, ARM_FEATURE_M)) {
1411 if (!env->nvic) {
1412 error_setg(errp, "This board cannot be used with Cortex-M CPUs");
1413 return;
1414 }
1415 } else {
1416 if (env->nvic) {
1417 error_setg(errp, "This board can only be used with Cortex-M CPUs");
1418 return;
1419 }
1420 }
1421
1422 {
1423 uint64_t scale;
1424
1425 if (arm_feature(env, ARM_FEATURE_GENERIC_TIMER)) {
1426 if (!cpu->gt_cntfrq_hz) {
1427 error_setg(errp, "Invalid CNTFRQ: %"PRId64"Hz",
1428 cpu->gt_cntfrq_hz);
1429 return;
1430 }
1431 scale = gt_cntfrq_period_ns(cpu);
1432 } else {
1433 scale = GTIMER_SCALE;
1434 }
1435
1436 cpu->gt_timer[GTIMER_PHYS] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
1437 arm_gt_ptimer_cb, cpu);
1438 cpu->gt_timer[GTIMER_VIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
1439 arm_gt_vtimer_cb, cpu);
1440 cpu->gt_timer[GTIMER_HYP] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
1441 arm_gt_htimer_cb, cpu);
1442 cpu->gt_timer[GTIMER_SEC] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
1443 arm_gt_stimer_cb, cpu);
1444 cpu->gt_timer[GTIMER_HYPVIRT] = timer_new(QEMU_CLOCK_VIRTUAL, scale,
1445 arm_gt_hvtimer_cb, cpu);
1446 }
1447#endif
1448
1449 cpu_exec_realizefn(cs, &local_err);
1450 if (local_err != NULL) {
1451 error_propagate(errp, local_err);
1452 return;
1453 }
1454
1455 arm_cpu_finalize_features(cpu, &local_err);
1456 if (local_err != NULL) {
1457 error_propagate(errp, local_err);
1458 return;
1459 }
1460
1461 if (arm_feature(env, ARM_FEATURE_AARCH64) &&
1462 cpu->has_vfp != cpu->has_neon) {
1463
1464
1465
1466
1467 error_setg(errp,
1468 "AArch64 CPUs must have both VFP and Neon or neither");
1469 return;
1470 }
1471
1472 if (!cpu->has_vfp) {
1473 uint64_t t;
1474 uint32_t u;
1475
1476 t = cpu->isar.id_aa64isar1;
1477 t = FIELD_DP64(t, ID_AA64ISAR1, JSCVT, 0);
1478 cpu->isar.id_aa64isar1 = t;
1479
1480 t = cpu->isar.id_aa64pfr0;
1481 t = FIELD_DP64(t, ID_AA64PFR0, FP, 0xf);
1482 cpu->isar.id_aa64pfr0 = t;
1483
1484 u = cpu->isar.id_isar6;
1485 u = FIELD_DP32(u, ID_ISAR6, JSCVT, 0);
1486 cpu->isar.id_isar6 = u;
1487
1488 u = cpu->isar.mvfr0;
1489 u = FIELD_DP32(u, MVFR0, FPSP, 0);
1490 u = FIELD_DP32(u, MVFR0, FPDP, 0);
1491 u = FIELD_DP32(u, MVFR0, FPDIVIDE, 0);
1492 u = FIELD_DP32(u, MVFR0, FPSQRT, 0);
1493 u = FIELD_DP32(u, MVFR0, FPROUND, 0);
1494 if (!arm_feature(env, ARM_FEATURE_M)) {
1495 u = FIELD_DP32(u, MVFR0, FPTRAP, 0);
1496 u = FIELD_DP32(u, MVFR0, FPSHVEC, 0);
1497 }
1498 cpu->isar.mvfr0 = u;
1499
1500 u = cpu->isar.mvfr1;
1501 u = FIELD_DP32(u, MVFR1, FPFTZ, 0);
1502 u = FIELD_DP32(u, MVFR1, FPDNAN, 0);
1503 u = FIELD_DP32(u, MVFR1, FPHP, 0);
1504 if (arm_feature(env, ARM_FEATURE_M)) {
1505 u = FIELD_DP32(u, MVFR1, FP16, 0);
1506 }
1507 cpu->isar.mvfr1 = u;
1508
1509 u = cpu->isar.mvfr2;
1510 u = FIELD_DP32(u, MVFR2, FPMISC, 0);
1511 cpu->isar.mvfr2 = u;
1512 }
1513
1514 if (!cpu->has_neon) {
1515 uint64_t t;
1516 uint32_t u;
1517
1518 unset_feature(env, ARM_FEATURE_NEON);
1519
1520 t = cpu->isar.id_aa64isar0;
1521 t = FIELD_DP64(t, ID_AA64ISAR0, DP, 0);
1522 cpu->isar.id_aa64isar0 = t;
1523
1524 t = cpu->isar.id_aa64isar1;
1525 t = FIELD_DP64(t, ID_AA64ISAR1, FCMA, 0);
1526 cpu->isar.id_aa64isar1 = t;
1527
1528 t = cpu->isar.id_aa64pfr0;
1529 t = FIELD_DP64(t, ID_AA64PFR0, ADVSIMD, 0xf);
1530 cpu->isar.id_aa64pfr0 = t;
1531
1532 u = cpu->isar.id_isar5;
1533 u = FIELD_DP32(u, ID_ISAR5, RDM, 0);
1534 u = FIELD_DP32(u, ID_ISAR5, VCMA, 0);
1535 cpu->isar.id_isar5 = u;
1536
1537 u = cpu->isar.id_isar6;
1538 u = FIELD_DP32(u, ID_ISAR6, DP, 0);
1539 u = FIELD_DP32(u, ID_ISAR6, FHM, 0);
1540 cpu->isar.id_isar6 = u;
1541
1542 if (!arm_feature(env, ARM_FEATURE_M)) {
1543 u = cpu->isar.mvfr1;
1544 u = FIELD_DP32(u, MVFR1, SIMDLS, 0);
1545 u = FIELD_DP32(u, MVFR1, SIMDINT, 0);
1546 u = FIELD_DP32(u, MVFR1, SIMDSP, 0);
1547 u = FIELD_DP32(u, MVFR1, SIMDHP, 0);
1548 cpu->isar.mvfr1 = u;
1549
1550 u = cpu->isar.mvfr2;
1551 u = FIELD_DP32(u, MVFR2, SIMDMISC, 0);
1552 cpu->isar.mvfr2 = u;
1553 }
1554 }
1555
1556 if (!cpu->has_neon && !cpu->has_vfp) {
1557 uint64_t t;
1558 uint32_t u;
1559
1560 t = cpu->isar.id_aa64isar0;
1561 t = FIELD_DP64(t, ID_AA64ISAR0, FHM, 0);
1562 cpu->isar.id_aa64isar0 = t;
1563
1564 t = cpu->isar.id_aa64isar1;
1565 t = FIELD_DP64(t, ID_AA64ISAR1, FRINTTS, 0);
1566 cpu->isar.id_aa64isar1 = t;
1567
1568 u = cpu->isar.mvfr0;
1569 u = FIELD_DP32(u, MVFR0, SIMDREG, 0);
1570 cpu->isar.mvfr0 = u;
1571
1572
1573 u = cpu->isar.mvfr1;
1574 u = FIELD_DP32(u, MVFR1, SIMDFMAC, 0);
1575 cpu->isar.mvfr1 = u;
1576 }
1577
1578 if (arm_feature(env, ARM_FEATURE_M) && !cpu->has_dsp) {
1579 uint32_t u;
1580
1581 unset_feature(env, ARM_FEATURE_THUMB_DSP);
1582
1583 u = cpu->isar.id_isar1;
1584 u = FIELD_DP32(u, ID_ISAR1, EXTEND, 1);
1585 cpu->isar.id_isar1 = u;
1586
1587 u = cpu->isar.id_isar2;
1588 u = FIELD_DP32(u, ID_ISAR2, MULTU, 1);
1589 u = FIELD_DP32(u, ID_ISAR2, MULTS, 1);
1590 cpu->isar.id_isar2 = u;
1591
1592 u = cpu->isar.id_isar3;
1593 u = FIELD_DP32(u, ID_ISAR3, SIMD, 1);
1594 u = FIELD_DP32(u, ID_ISAR3, SATURATE, 0);
1595 cpu->isar.id_isar3 = u;
1596 }
1597
1598
1599 if (arm_feature(env, ARM_FEATURE_V8)) {
1600 if (arm_feature(env, ARM_FEATURE_M)) {
1601 set_feature(env, ARM_FEATURE_V7);
1602 } else {
1603 set_feature(env, ARM_FEATURE_V7VE);
1604 }
1605 }
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
1616 no_aa32 = !cpu_isar_feature(aa64_aa32, cpu);
1617 }
1618
1619 if (arm_feature(env, ARM_FEATURE_V7VE)) {
1620
1621
1622
1623
1624
1625
1626
1627
1628 assert(!tcg_enabled() || no_aa32 ||
1629 cpu_isar_feature(aa32_arm_div, cpu));
1630 set_feature(env, ARM_FEATURE_LPAE);
1631 set_feature(env, ARM_FEATURE_V7);
1632 }
1633 if (arm_feature(env, ARM_FEATURE_V7)) {
1634 set_feature(env, ARM_FEATURE_VAPA);
1635 set_feature(env, ARM_FEATURE_THUMB2);
1636 set_feature(env, ARM_FEATURE_MPIDR);
1637 if (!arm_feature(env, ARM_FEATURE_M)) {
1638 set_feature(env, ARM_FEATURE_V6K);
1639 } else {
1640 set_feature(env, ARM_FEATURE_V6);
1641 }
1642
1643
1644
1645
1646 set_feature(env, ARM_FEATURE_VBAR);
1647 }
1648 if (arm_feature(env, ARM_FEATURE_V6K)) {
1649 set_feature(env, ARM_FEATURE_V6);
1650 set_feature(env, ARM_FEATURE_MVFR);
1651 }
1652 if (arm_feature(env, ARM_FEATURE_V6)) {
1653 set_feature(env, ARM_FEATURE_V5);
1654 if (!arm_feature(env, ARM_FEATURE_M)) {
1655 assert(!tcg_enabled() || no_aa32 ||
1656 cpu_isar_feature(aa32_jazelle, cpu));
1657 set_feature(env, ARM_FEATURE_AUXCR);
1658 }
1659 }
1660 if (arm_feature(env, ARM_FEATURE_V5)) {
1661 set_feature(env, ARM_FEATURE_V4T);
1662 }
1663 if (arm_feature(env, ARM_FEATURE_LPAE)) {
1664 set_feature(env, ARM_FEATURE_V7MP);
1665 }
1666 if (arm_feature(env, ARM_FEATURE_CBAR_RO)) {
1667 set_feature(env, ARM_FEATURE_CBAR);
1668 }
1669 if (arm_feature(env, ARM_FEATURE_THUMB2) &&
1670 !arm_feature(env, ARM_FEATURE_M)) {
1671 set_feature(env, ARM_FEATURE_THUMB_DSP);
1672 }
1673
1674
1675
1676
1677
1678 assert(arm_feature(&cpu->env, ARM_FEATURE_AARCH64) ||
1679 !cpu_isar_feature(aa32_vfp_simd, cpu) ||
1680 !arm_feature(env, ARM_FEATURE_XSCALE));
1681
1682 if (arm_feature(env, ARM_FEATURE_V7) &&
1683 !arm_feature(env, ARM_FEATURE_M) &&
1684 !arm_feature(env, ARM_FEATURE_PMSA)) {
1685
1686
1687
1688 pagebits = 12;
1689 } else {
1690
1691
1692
1693 pagebits = 10;
1694 }
1695 if (!set_preferred_target_page_bits(pagebits)) {
1696
1697
1698
1699
1700 error_setg(errp, "This CPU requires a smaller page size than the "
1701 "system is using");
1702 return;
1703 }
1704
1705
1706
1707
1708
1709
1710 if (cpu->mp_affinity == ARM64_AFFINITY_INVALID) {
1711 cpu->mp_affinity = arm_cpu_mp_affinity(cs->cpu_index,
1712 ARM_DEFAULT_CPUS_PER_CLUSTER);
1713 }
1714
1715 if (cpu->reset_hivecs) {
1716 cpu->reset_sctlr |= (1 << 13);
1717 }
1718
1719 if (cpu->cfgend) {
1720 if (arm_feature(&cpu->env, ARM_FEATURE_V7)) {
1721 cpu->reset_sctlr |= SCTLR_EE;
1722 } else {
1723 cpu->reset_sctlr |= SCTLR_B;
1724 }
1725 }
1726
1727 if (!arm_feature(env, ARM_FEATURE_M) && !cpu->has_el3) {
1728
1729
1730
1731 unset_feature(env, ARM_FEATURE_EL3);
1732
1733
1734
1735
1736 cpu->isar.id_pfr1 &= ~0xf0;
1737 cpu->isar.id_aa64pfr0 &= ~0xf000;
1738 }
1739
1740 if (!cpu->has_el2) {
1741 unset_feature(env, ARM_FEATURE_EL2);
1742 }
1743
1744 if (!cpu->has_pmu) {
1745 unset_feature(env, ARM_FEATURE_PMU);
1746 }
1747 if (arm_feature(env, ARM_FEATURE_PMU)) {
1748 pmu_init(cpu);
1749
1750 if (!kvm_enabled()) {
1751 arm_register_pre_el_change_hook(cpu, &pmu_pre_el_change, 0);
1752 arm_register_el_change_hook(cpu, &pmu_post_el_change, 0);
1753 }
1754
1755#ifndef CONFIG_USER_ONLY
1756 cpu->pmu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, arm_pmu_timer_cb,
1757 cpu);
1758#endif
1759 } else {
1760 cpu->isar.id_aa64dfr0 =
1761 FIELD_DP64(cpu->isar.id_aa64dfr0, ID_AA64DFR0, PMUVER, 0);
1762 cpu->isar.id_dfr0 = FIELD_DP32(cpu->isar.id_dfr0, ID_DFR0, PERFMON, 0);
1763 cpu->pmceid0 = 0;
1764 cpu->pmceid1 = 0;
1765 }
1766
1767 if (!arm_feature(env, ARM_FEATURE_EL2)) {
1768
1769
1770
1771
1772 cpu->isar.id_aa64pfr0 &= ~0xf00;
1773 cpu->isar.id_pfr1 &= ~0xf000;
1774 }
1775
1776#ifndef CONFIG_USER_ONLY
1777 if (cpu->tag_memory == NULL && cpu_isar_feature(aa64_mte, cpu)) {
1778
1779
1780
1781
1782 cpu->isar.id_aa64pfr1 =
1783 FIELD_DP64(cpu->isar.id_aa64pfr1, ID_AA64PFR1, MTE, 0);
1784 }
1785#endif
1786
1787
1788
1789
1790 if (!cpu->has_mpu) {
1791 cpu->pmsav7_dregion = 0;
1792 }
1793 if (cpu->pmsav7_dregion == 0) {
1794 cpu->has_mpu = false;
1795 }
1796
1797 if (arm_feature(env, ARM_FEATURE_PMSA) &&
1798 arm_feature(env, ARM_FEATURE_V7)) {
1799 uint32_t nr = cpu->pmsav7_dregion;
1800
1801 if (nr > 0xff) {
1802 error_setg(errp, "PMSAv7 MPU #regions invalid %" PRIu32, nr);
1803 return;
1804 }
1805
1806 if (nr) {
1807 if (arm_feature(env, ARM_FEATURE_V8)) {
1808
1809 env->pmsav8.rbar[M_REG_NS] = g_new0(uint32_t, nr);
1810 env->pmsav8.rlar[M_REG_NS] = g_new0(uint32_t, nr);
1811 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
1812 env->pmsav8.rbar[M_REG_S] = g_new0(uint32_t, nr);
1813 env->pmsav8.rlar[M_REG_S] = g_new0(uint32_t, nr);
1814 }
1815 } else {
1816 env->pmsav7.drbar = g_new0(uint32_t, nr);
1817 env->pmsav7.drsr = g_new0(uint32_t, nr);
1818 env->pmsav7.dracr = g_new0(uint32_t, nr);
1819 }
1820 }
1821 }
1822
1823 if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
1824 uint32_t nr = cpu->sau_sregion;
1825
1826 if (nr > 0xff) {
1827 error_setg(errp, "v8M SAU #regions invalid %" PRIu32, nr);
1828 return;
1829 }
1830
1831 if (nr) {
1832 env->sau.rbar = g_new0(uint32_t, nr);
1833 env->sau.rlar = g_new0(uint32_t, nr);
1834 }
1835 }
1836
1837 if (arm_feature(env, ARM_FEATURE_EL3)) {
1838 set_feature(env, ARM_FEATURE_VBAR);
1839 }
1840
1841 register_cp_regs_for_features(cpu);
1842 arm_cpu_register_gdb_regs_for_features(cpu);
1843
1844 init_cpreg_list(cpu);
1845
1846#ifndef CONFIG_USER_ONLY
1847 MachineState *ms = MACHINE(qdev_get_machine());
1848 unsigned int smp_cpus = ms->smp.cpus;
1849 bool has_secure = cpu->has_el3 || arm_feature(env, ARM_FEATURE_M_SECURITY);
1850
1851
1852
1853
1854
1855 if (cpu->tag_memory != NULL) {
1856 cs->num_ases = 3 + has_secure;
1857 } else {
1858 cs->num_ases = 1 + has_secure;
1859 }
1860
1861 if (has_secure) {
1862 if (!cpu->secure_memory) {
1863 cpu->secure_memory = cs->memory;
1864 }
1865 cpu_address_space_init(cs, ARMASIdx_S, "cpu-secure-memory",
1866 cpu->secure_memory);
1867 }
1868
1869 if (cpu->tag_memory != NULL) {
1870 cpu_address_space_init(cs, ARMASIdx_TagNS, "cpu-tag-memory",
1871 cpu->tag_memory);
1872 if (has_secure) {
1873 cpu_address_space_init(cs, ARMASIdx_TagS, "cpu-tag-memory",
1874 cpu->secure_tag_memory);
1875 }
1876 }
1877
1878 cpu_address_space_init(cs, ARMASIdx_NS, "cpu-memory", cs->memory);
1879
1880
1881 if (cpu->core_count == -1) {
1882 cpu->core_count = smp_cpus;
1883 }
1884#endif
1885
1886 if (tcg_enabled()) {
1887 int dcz_blocklen = 4 << cpu->dcz_blocksize;
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898 assert(dcz_blocklen <= TARGET_PAGE_SIZE);
1899
1900
1901
1902
1903
1904
1905 if (cpu_isar_feature(aa64_mte, cpu)) {
1906 assert(dcz_blocklen >= 2 * TAG_GRANULE);
1907 }
1908 }
1909
1910 qemu_init_vcpu(cs);
1911 cpu_reset(cs);
1912
1913 acc->parent_realize(dev, errp);
1914}
1915
1916static ObjectClass *arm_cpu_class_by_name(const char *cpu_model)
1917{
1918 ObjectClass *oc;
1919 char *typename;
1920 char **cpuname;
1921 const char *cpunamestr;
1922
1923 cpuname = g_strsplit(cpu_model, ",", 1);
1924 cpunamestr = cpuname[0];
1925#ifdef CONFIG_USER_ONLY
1926
1927
1928
1929 if (!strcmp(cpunamestr, "any")) {
1930 cpunamestr = "max";
1931 }
1932#endif
1933 typename = g_strdup_printf(ARM_CPU_TYPE_NAME("%s"), cpunamestr);
1934 oc = object_class_by_name(typename);
1935 g_strfreev(cpuname);
1936 g_free(typename);
1937 if (!oc || !object_class_dynamic_cast(oc, TYPE_ARM_CPU) ||
1938 object_class_is_abstract(oc)) {
1939 return NULL;
1940 }
1941 return oc;
1942}
1943
1944static Property arm_cpu_properties[] = {
1945 DEFINE_PROP_UINT32("psci-conduit", ARMCPU, psci_conduit, 0),
1946 DEFINE_PROP_UINT64("midr", ARMCPU, midr, 0),
1947 DEFINE_PROP_UINT64("mp-affinity", ARMCPU,
1948 mp_affinity, ARM64_AFFINITY_INVALID),
1949 DEFINE_PROP_INT32("node-id", ARMCPU, node_id, CPU_UNSET_NUMA_NODE_ID),
1950 DEFINE_PROP_INT32("core-count", ARMCPU, core_count, -1),
1951 DEFINE_PROP_END_OF_LIST()
1952};
1953
1954static gchar *arm_gdb_arch_name(CPUState *cs)
1955{
1956 ARMCPU *cpu = ARM_CPU(cs);
1957 CPUARMState *env = &cpu->env;
1958
1959 if (arm_feature(env, ARM_FEATURE_IWMMXT)) {
1960 return g_strdup("iwmmxt");
1961 }
1962 return g_strdup("arm");
1963}
1964
1965#ifdef CONFIG_TCG
1966static struct TCGCPUOps arm_tcg_ops = {
1967 .initialize = arm_translate_init,
1968 .synchronize_from_tb = arm_cpu_synchronize_from_tb,
1969 .cpu_exec_interrupt = arm_cpu_exec_interrupt,
1970 .tlb_fill = arm_cpu_tlb_fill,
1971 .debug_excp_handler = arm_debug_excp_handler,
1972
1973#if !defined(CONFIG_USER_ONLY)
1974 .do_interrupt = arm_cpu_do_interrupt,
1975 .do_transaction_failed = arm_cpu_do_transaction_failed,
1976 .do_unaligned_access = arm_cpu_do_unaligned_access,
1977 .adjust_watchpoint_address = arm_adjust_watchpoint_address,
1978 .debug_check_watchpoint = arm_debug_check_watchpoint,
1979#endif
1980};
1981#endif
1982
1983static void arm_cpu_class_init(ObjectClass *oc, void *data)
1984{
1985 ARMCPUClass *acc = ARM_CPU_CLASS(oc);
1986 CPUClass *cc = CPU_CLASS(acc);
1987 DeviceClass *dc = DEVICE_CLASS(oc);
1988
1989 device_class_set_parent_realize(dc, arm_cpu_realizefn,
1990 &acc->parent_realize);
1991
1992 device_class_set_props(dc, arm_cpu_properties);
1993 device_class_set_parent_reset(dc, arm_cpu_reset, &acc->parent_reset);
1994
1995 cc->class_by_name = arm_cpu_class_by_name;
1996 cc->has_work = arm_cpu_has_work;
1997 cc->dump_state = arm_cpu_dump_state;
1998 cc->set_pc = arm_cpu_set_pc;
1999 cc->gdb_read_register = arm_cpu_gdb_read_register;
2000 cc->gdb_write_register = arm_cpu_gdb_write_register;
2001#ifndef CONFIG_USER_ONLY
2002 cc->get_phys_page_attrs_debug = arm_cpu_get_phys_page_attrs_debug;
2003 cc->asidx_from_attrs = arm_asidx_from_attrs;
2004 cc->vmsd = &vmstate_arm_cpu;
2005 cc->virtio_is_big_endian = arm_cpu_virtio_is_big_endian;
2006 cc->write_elf64_note = arm_cpu_write_elf64_note;
2007 cc->write_elf32_note = arm_cpu_write_elf32_note;
2008#endif
2009 cc->gdb_num_core_regs = 26;
2010 cc->gdb_core_xml_file = "arm-core.xml";
2011 cc->gdb_arch_name = arm_gdb_arch_name;
2012 cc->gdb_get_dynamic_xml = arm_gdb_get_dynamic_xml;
2013 cc->gdb_stop_before_watchpoint = true;
2014 cc->disas_set_info = arm_disas_set_info;
2015
2016#ifdef CONFIG_TCG
2017 cc->tcg_ops = &arm_tcg_ops;
2018#endif
2019}
2020
2021#ifdef CONFIG_KVM
2022static void arm_host_initfn(Object *obj)
2023{
2024 ARMCPU *cpu = ARM_CPU(obj);
2025
2026 kvm_arm_set_cpu_features_from_host(cpu);
2027 if (arm_feature(&cpu->env, ARM_FEATURE_AARCH64)) {
2028 aarch64_add_sve_properties(obj);
2029 }
2030 arm_cpu_post_init(obj);
2031}
2032
2033static const TypeInfo host_arm_cpu_type_info = {
2034 .name = TYPE_ARM_HOST_CPU,
2035 .parent = TYPE_AARCH64_CPU,
2036 .instance_init = arm_host_initfn,
2037};
2038
2039#endif
2040
2041static void arm_cpu_instance_init(Object *obj)
2042{
2043 ARMCPUClass *acc = ARM_CPU_GET_CLASS(obj);
2044
2045 acc->info->initfn(obj);
2046 arm_cpu_post_init(obj);
2047}
2048
2049static void cpu_register_class_init(ObjectClass *oc, void *data)
2050{
2051 ARMCPUClass *acc = ARM_CPU_CLASS(oc);
2052
2053 acc->info = data;
2054}
2055
2056void arm_cpu_register(const ARMCPUInfo *info)
2057{
2058 TypeInfo type_info = {
2059 .parent = TYPE_ARM_CPU,
2060 .instance_size = sizeof(ARMCPU),
2061 .instance_align = __alignof__(ARMCPU),
2062 .instance_init = arm_cpu_instance_init,
2063 .class_size = sizeof(ARMCPUClass),
2064 .class_init = info->class_init ?: cpu_register_class_init,
2065 .class_data = (void *)info,
2066 };
2067
2068 type_info.name = g_strdup_printf("%s-" TYPE_ARM_CPU, info->name);
2069 type_register(&type_info);
2070 g_free((void *)type_info.name);
2071}
2072
2073static const TypeInfo arm_cpu_type_info = {
2074 .name = TYPE_ARM_CPU,
2075 .parent = TYPE_CPU,
2076 .instance_size = sizeof(ARMCPU),
2077 .instance_align = __alignof__(ARMCPU),
2078 .instance_init = arm_cpu_initfn,
2079 .instance_finalize = arm_cpu_finalizefn,
2080 .abstract = true,
2081 .class_size = sizeof(ARMCPUClass),
2082 .class_init = arm_cpu_class_init,
2083};
2084
2085static void arm_cpu_register_types(void)
2086{
2087 type_register_static(&arm_cpu_type_info);
2088
2089#ifdef CONFIG_KVM
2090 type_register_static(&host_arm_cpu_type_info);
2091#endif
2092}
2093
2094type_init(arm_cpu_register_types)
2095