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