master
c 146 lines 3.69 KB
Raw
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 */
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 */
28 const char *current_accel_name(void)
29 {
30 AccelClass *ac = ACCEL_GET_CLASS(current_accel());
31
32 return ac->name;
33 }
34
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 cc->accel_cpu = accel_cpu;
41 if (accel_cpu->cpu_class_init) {
42 accel_cpu->cpu_class_init(cc);
43 }
44 }
45
46 /* initialize the arch-specific accel CpuClass interfaces */
47 static void accel_init_cpu_interfaces(AccelClass *ac)
48 {
49 const char *ac_name; /* AccelClass name */
50 char *acc_name; /* AccelCPUClass name */
51 ObjectClass *acc; /* AccelCPUClass */
52 const char *cpu_resolving_type = target_cpu_type();
53
54 ac_name = object_class_get_name(OBJECT_CLASS(ac));
55 g_assert(ac_name != NULL);
56
57 acc_name = g_strdup_printf("%s-%s", ac_name, cpu_resolving_type);
58 acc = object_class_by_name(acc_name);
59 g_free(acc_name);
60
61 if (acc) {
62 object_class_foreach(accel_init_cpu_int_aux,
63 cpu_resolving_type, false, acc);
64 }
65 }
66
67 void accel_init_interfaces(AccelClass *ac)
68 {
69 accel_init_ops_interfaces(ac);
70 accel_init_cpu_interfaces(ac);
71 }
72
73 bool accel_supports_guest_debug(AccelState *accel)
74 {
75 return accel->gdbstub.sstep_flags & SSTEP_ENABLE;
76 }
77
78 void accel_cpu_instance_init(CPUState *cpu)
79 {
80 if (cpu->cc->accel_cpu && cpu->cc->accel_cpu->cpu_instance_init) {
81 cpu->cc->accel_cpu->cpu_instance_init(cpu);
82 }
83 }
84
85 bool accel_cpu_common_realize(CPUState *cpu, Error **errp)
86 {
87 AccelState *accel = current_accel();
88 AccelClass *acc = ACCEL_GET_CLASS(accel);
89
90 /* target specific realization */
91 if (cpu->cc->accel_cpu
92 && cpu->cc->accel_cpu->cpu_target_realize
93 && !cpu->cc->accel_cpu->cpu_target_realize(cpu, errp)) {
94 return false;
95 }
96
97 /* generic realization */
98 if (acc->cpu_common_realize && !acc->cpu_common_realize(cpu, errp)) {
99 return false;
100 }
101 if (acc->ops
102 && acc->ops->cpu_target_realize
103 && !acc->ops->cpu_target_realize(cpu, errp)) {
104 return false;
105 }
106
107 return true;
108 }
109
110 void accel_cpu_common_unrealize(CPUState *cpu)
111 {
112 AccelState *accel = current_accel();
113 AccelClass *acc = ACCEL_GET_CLASS(accel);
114
115 /* generic unrealization */
116 if (acc->cpu_common_unrealize) {
117 acc->cpu_common_unrealize(cpu);
118 }
119 }
120
121 static const TypeInfo accel_types[] = {
122 {
123 .name = TYPE_ACCEL,
124 .parent = TYPE_OBJECT,
125 .class_size = sizeof(AccelClass),
126 .instance_size = sizeof(AccelState),
127 .abstract = true,
128 },
129 };
130
131 DEFINE_TYPES(accel_types)
132
133 static void register_accel_target_type(void)
134 {
135 g_autofree char *name = g_strconcat("accel-", target_cpu_type(), NULL);
136 const TypeInfo accel_cpu_type = {
137 .name = name,
138 .parent = TYPE_OBJECT,
139 .abstract = true,
140 .class_size = sizeof(AccelCPUClass),
141 };
142
143 type_register_static(&accel_cpu_type);
144 }
145
146 type_init(register_accel_target_type);