1 /*
2 * QEMU accel class, components common to system emulation and user mode
3 *
4 * Copyright (c) 2003-2008 Fabrice Bellard
5 * Copyright (c) 2014 Red Hat Inc.
6 *
7 * SPDX-License-Identifier: MIT
8 */
9
10 #include "qemu/osdep.h"
11 #include "qemu/accel.h"
12 #include "qemu/target-info.h"
13 #include "accel/accel-cpu.h"
14 #include "accel-internal.h"
15
16 /* Lookup AccelClass from opt_name. Returns NULL if not found */
accel_find(const char * opt_name)17 AccelClass *accel_find(const char *opt_name)
18 {
19 char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name);
20 AccelClass *ac = ACCEL_CLASS(module_object_class_by_name(class_name));
21 g_free(class_name);
22 return ac;
23 }
24
25 /* Return the name of the current accelerator */
current_accel_name(void)26 const char *current_accel_name(void)
27 {
28 AccelClass *ac = ACCEL_GET_CLASS(current_accel());
29
30 return ac->name;
31 }
32
accel_init_cpu_int_aux(ObjectClass * klass,void * opaque)33 static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque)
34 {
35 CPUClass *cc = CPU_CLASS(klass);
36 AccelCPUClass *accel_cpu = opaque;
37
38 /*
39 * The first callback allows accel-cpu to run initializations
40 * for the CPU, customizing CPU behavior according to the accelerator.
41 *
42 * The second one allows the CPU to customize the accel-cpu
43 * behavior according to the CPU.
44 *
45 * The second is currently only used by TCG, to specialize the
46 * TCGCPUOps depending on the CPU type.
47 */
48 cc->accel_cpu = accel_cpu;
49 if (accel_cpu->cpu_class_init) {
50 accel_cpu->cpu_class_init(cc);
51 }
52 if (cc->init_accel_cpu) {
53 cc->init_accel_cpu(accel_cpu, cc);
54 }
55 }
56
57 /* initialize the arch-specific accel CpuClass interfaces */
accel_init_cpu_interfaces(AccelClass * ac)58 static void accel_init_cpu_interfaces(AccelClass *ac)
59 {
60 const char *ac_name; /* AccelClass name */
61 char *acc_name; /* AccelCPUClass name */
62 ObjectClass *acc; /* AccelCPUClass */
63 const char *cpu_resolving_type = target_cpu_type();
64
65 ac_name = object_class_get_name(OBJECT_CLASS(ac));
66 g_assert(ac_name != NULL);
67
68 acc_name = g_strdup_printf("%s-%s", ac_name, cpu_resolving_type);
69 acc = object_class_by_name(acc_name);
70 g_free(acc_name);
71
72 if (acc) {
73 object_class_foreach(accel_init_cpu_int_aux,
74 cpu_resolving_type, false, acc);
75 }
76 }
77
accel_init_interfaces(AccelClass * ac)78 void accel_init_interfaces(AccelClass *ac)
79 {
80 accel_init_ops_interfaces(ac);
81 accel_init_cpu_interfaces(ac);
82 }
83
accel_cpu_instance_init(CPUState * cpu)84 void accel_cpu_instance_init(CPUState *cpu)
85 {
86 if (cpu->cc->accel_cpu && cpu->cc->accel_cpu->cpu_instance_init) {
87 cpu->cc->accel_cpu->cpu_instance_init(cpu);
88 }
89 }
90
accel_cpu_common_realize(CPUState * cpu,Error ** errp)91 bool accel_cpu_common_realize(CPUState *cpu, Error **errp)
92 {
93 AccelState *accel = current_accel();
94 AccelClass *acc = ACCEL_GET_CLASS(accel);
95
96 /* target specific realization */
97 if (cpu->cc->accel_cpu
98 && cpu->cc->accel_cpu->cpu_target_realize
99 && !cpu->cc->accel_cpu->cpu_target_realize(cpu, errp)) {
100 return false;
101 }
102
103 /* generic realization */
104 if (acc->cpu_common_realize && !acc->cpu_common_realize(cpu, errp)) {
105 return false;
106 }
107
108 return true;
109 }
110
accel_cpu_common_unrealize(CPUState * cpu)111 void accel_cpu_common_unrealize(CPUState *cpu)
112 {
113 AccelState *accel = current_accel();
114 AccelClass *acc = ACCEL_GET_CLASS(accel);
115
116 /* generic unrealization */
117 if (acc->cpu_common_unrealize) {
118 acc->cpu_common_unrealize(cpu);
119 }
120 }
121
accel_supported_gdbstub_sstep_flags(void)122 int accel_supported_gdbstub_sstep_flags(void)
123 {
124 AccelState *accel = current_accel();
125 AccelClass *acc = ACCEL_GET_CLASS(accel);
126 if (acc->gdbstub_supported_sstep_flags) {
127 return acc->gdbstub_supported_sstep_flags();
128 }
129 return 0;
130 }
131
132 static const TypeInfo accel_types[] = {
133 {
134 .name = TYPE_ACCEL,
135 .parent = TYPE_OBJECT,
136 .class_size = sizeof(AccelClass),
137 .instance_size = sizeof(AccelState),
138 .abstract = true,
139 },
140 };
141
142 DEFINE_TYPES(accel_types)
143