xref: /qemu/accel/accel-common.c (revision 06b40d250ecfa1633209c2e431a7a38acfd03a98)
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