xref: /openbmc/qemu/accel/accel-common.c (revision 842e7eecd4446957c5edf0c65e5e41fadea2f015)
1802c4dafSPhilippe Mathieu-Daudé /*
2802c4dafSPhilippe Mathieu-Daudé  * QEMU accel class, components common to system emulation and user mode
3802c4dafSPhilippe Mathieu-Daudé  *
4802c4dafSPhilippe Mathieu-Daudé  * Copyright (c) 2003-2008 Fabrice Bellard
5802c4dafSPhilippe Mathieu-Daudé  * Copyright (c) 2014 Red Hat Inc.
6802c4dafSPhilippe Mathieu-Daudé  *
7802c4dafSPhilippe Mathieu-Daudé  * SPDX-License-Identifier: MIT
8802c4dafSPhilippe Mathieu-Daudé  */
9802c4dafSPhilippe Mathieu-Daudé 
10802c4dafSPhilippe Mathieu-Daudé #include "qemu/osdep.h"
11802c4dafSPhilippe Mathieu-Daudé #include "qemu/accel.h"
12802c4dafSPhilippe Mathieu-Daudé #include "qemu/target-info.h"
13802c4dafSPhilippe Mathieu-Daudé #include "accel/accel-cpu.h"
14802c4dafSPhilippe Mathieu-Daudé #include "accel-internal.h"
15802c4dafSPhilippe Mathieu-Daudé 
16802c4dafSPhilippe Mathieu-Daudé /* Lookup AccelClass from opt_name. Returns NULL if not found */
17802c4dafSPhilippe Mathieu-Daudé AccelClass *accel_find(const char *opt_name)
18802c4dafSPhilippe Mathieu-Daudé {
19802c4dafSPhilippe Mathieu-Daudé     char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name);
20802c4dafSPhilippe Mathieu-Daudé     AccelClass *ac = ACCEL_CLASS(module_object_class_by_name(class_name));
21802c4dafSPhilippe Mathieu-Daudé     g_free(class_name);
22802c4dafSPhilippe Mathieu-Daudé     return ac;
23802c4dafSPhilippe Mathieu-Daudé }
24802c4dafSPhilippe Mathieu-Daudé 
25802c4dafSPhilippe Mathieu-Daudé /* Return the name of the current accelerator */
26802c4dafSPhilippe Mathieu-Daudé const char *current_accel_name(void)
27802c4dafSPhilippe Mathieu-Daudé {
28802c4dafSPhilippe Mathieu-Daudé     AccelClass *ac = ACCEL_GET_CLASS(current_accel());
29802c4dafSPhilippe Mathieu-Daudé 
30802c4dafSPhilippe Mathieu-Daudé     return ac->name;
31802c4dafSPhilippe Mathieu-Daudé }
32802c4dafSPhilippe Mathieu-Daudé 
33802c4dafSPhilippe Mathieu-Daudé static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque)
34802c4dafSPhilippe Mathieu-Daudé {
35802c4dafSPhilippe Mathieu-Daudé     CPUClass *cc = CPU_CLASS(klass);
36802c4dafSPhilippe Mathieu-Daudé     AccelCPUClass *accel_cpu = opaque;
37802c4dafSPhilippe Mathieu-Daudé 
38802c4dafSPhilippe Mathieu-Daudé     /*
39802c4dafSPhilippe Mathieu-Daudé      * The first callback allows accel-cpu to run initializations
40802c4dafSPhilippe Mathieu-Daudé      * for the CPU, customizing CPU behavior according to the accelerator.
41802c4dafSPhilippe Mathieu-Daudé      *
42802c4dafSPhilippe Mathieu-Daudé      * The second one allows the CPU to customize the accel-cpu
43802c4dafSPhilippe Mathieu-Daudé      * behavior according to the CPU.
44802c4dafSPhilippe Mathieu-Daudé      *
45802c4dafSPhilippe Mathieu-Daudé      * The second is currently only used by TCG, to specialize the
46802c4dafSPhilippe Mathieu-Daudé      * TCGCPUOps depending on the CPU type.
47802c4dafSPhilippe Mathieu-Daudé      */
48802c4dafSPhilippe Mathieu-Daudé     cc->accel_cpu = accel_cpu;
49802c4dafSPhilippe Mathieu-Daudé     if (accel_cpu->cpu_class_init) {
50802c4dafSPhilippe Mathieu-Daudé         accel_cpu->cpu_class_init(cc);
51802c4dafSPhilippe Mathieu-Daudé     }
52802c4dafSPhilippe Mathieu-Daudé     if (cc->init_accel_cpu) {
53802c4dafSPhilippe Mathieu-Daudé         cc->init_accel_cpu(accel_cpu, cc);
54802c4dafSPhilippe Mathieu-Daudé     }
55802c4dafSPhilippe Mathieu-Daudé }
56802c4dafSPhilippe Mathieu-Daudé 
57802c4dafSPhilippe Mathieu-Daudé /* initialize the arch-specific accel CpuClass interfaces */
58802c4dafSPhilippe Mathieu-Daudé static void accel_init_cpu_interfaces(AccelClass *ac)
59802c4dafSPhilippe Mathieu-Daudé {
60802c4dafSPhilippe Mathieu-Daudé     const char *ac_name; /* AccelClass name */
61802c4dafSPhilippe Mathieu-Daudé     char *acc_name;      /* AccelCPUClass name */
62802c4dafSPhilippe Mathieu-Daudé     ObjectClass *acc;    /* AccelCPUClass */
63802c4dafSPhilippe Mathieu-Daudé     const char *cpu_resolving_type = target_cpu_type();
64802c4dafSPhilippe Mathieu-Daudé 
65802c4dafSPhilippe Mathieu-Daudé     ac_name = object_class_get_name(OBJECT_CLASS(ac));
66802c4dafSPhilippe Mathieu-Daudé     g_assert(ac_name != NULL);
67802c4dafSPhilippe Mathieu-Daudé 
68802c4dafSPhilippe Mathieu-Daudé     acc_name = g_strdup_printf("%s-%s", ac_name, cpu_resolving_type);
69802c4dafSPhilippe Mathieu-Daudé     acc = object_class_by_name(acc_name);
70802c4dafSPhilippe Mathieu-Daudé     g_free(acc_name);
71802c4dafSPhilippe Mathieu-Daudé 
72802c4dafSPhilippe Mathieu-Daudé     if (acc) {
73802c4dafSPhilippe Mathieu-Daudé         object_class_foreach(accel_init_cpu_int_aux,
74802c4dafSPhilippe Mathieu-Daudé                              cpu_resolving_type, false, acc);
75802c4dafSPhilippe Mathieu-Daudé     }
76802c4dafSPhilippe Mathieu-Daudé }
77802c4dafSPhilippe Mathieu-Daudé 
78802c4dafSPhilippe Mathieu-Daudé void accel_init_interfaces(AccelClass *ac)
79802c4dafSPhilippe Mathieu-Daudé {
80802c4dafSPhilippe Mathieu-Daudé     accel_init_ops_interfaces(ac);
81802c4dafSPhilippe Mathieu-Daudé     accel_init_cpu_interfaces(ac);
82802c4dafSPhilippe Mathieu-Daudé }
83802c4dafSPhilippe Mathieu-Daudé 
84802c4dafSPhilippe Mathieu-Daudé void accel_cpu_instance_init(CPUState *cpu)
85802c4dafSPhilippe Mathieu-Daudé {
86802c4dafSPhilippe Mathieu-Daudé     if (cpu->cc->accel_cpu && cpu->cc->accel_cpu->cpu_instance_init) {
87802c4dafSPhilippe Mathieu-Daudé         cpu->cc->accel_cpu->cpu_instance_init(cpu);
88802c4dafSPhilippe Mathieu-Daudé     }
89802c4dafSPhilippe Mathieu-Daudé }
90802c4dafSPhilippe Mathieu-Daudé 
91802c4dafSPhilippe Mathieu-Daudé bool accel_cpu_common_realize(CPUState *cpu, Error **errp)
92802c4dafSPhilippe Mathieu-Daudé {
93802c4dafSPhilippe Mathieu-Daudé     AccelState *accel = current_accel();
94802c4dafSPhilippe Mathieu-Daudé     AccelClass *acc = ACCEL_GET_CLASS(accel);
95802c4dafSPhilippe Mathieu-Daudé 
96802c4dafSPhilippe Mathieu-Daudé     /* target specific realization */
97802c4dafSPhilippe Mathieu-Daudé     if (cpu->cc->accel_cpu
98802c4dafSPhilippe Mathieu-Daudé         && cpu->cc->accel_cpu->cpu_target_realize
99802c4dafSPhilippe Mathieu-Daudé         && !cpu->cc->accel_cpu->cpu_target_realize(cpu, errp)) {
100802c4dafSPhilippe Mathieu-Daudé         return false;
101802c4dafSPhilippe Mathieu-Daudé     }
102802c4dafSPhilippe Mathieu-Daudé 
103802c4dafSPhilippe Mathieu-Daudé     /* generic realization */
104802c4dafSPhilippe Mathieu-Daudé     if (acc->cpu_common_realize && !acc->cpu_common_realize(cpu, errp)) {
105802c4dafSPhilippe Mathieu-Daudé         return false;
106802c4dafSPhilippe Mathieu-Daudé     }
107802c4dafSPhilippe Mathieu-Daudé 
108802c4dafSPhilippe Mathieu-Daudé     return true;
109802c4dafSPhilippe Mathieu-Daudé }
110802c4dafSPhilippe Mathieu-Daudé 
111802c4dafSPhilippe Mathieu-Daudé void accel_cpu_common_unrealize(CPUState *cpu)
112802c4dafSPhilippe Mathieu-Daudé {
113802c4dafSPhilippe Mathieu-Daudé     AccelState *accel = current_accel();
114802c4dafSPhilippe Mathieu-Daudé     AccelClass *acc = ACCEL_GET_CLASS(accel);
115802c4dafSPhilippe Mathieu-Daudé 
116802c4dafSPhilippe Mathieu-Daudé     /* generic unrealization */
117802c4dafSPhilippe Mathieu-Daudé     if (acc->cpu_common_unrealize) {
118802c4dafSPhilippe Mathieu-Daudé         acc->cpu_common_unrealize(cpu);
119802c4dafSPhilippe Mathieu-Daudé     }
120802c4dafSPhilippe Mathieu-Daudé }
121802c4dafSPhilippe Mathieu-Daudé 
122802c4dafSPhilippe Mathieu-Daudé int accel_supported_gdbstub_sstep_flags(void)
123802c4dafSPhilippe Mathieu-Daudé {
124802c4dafSPhilippe Mathieu-Daudé     AccelState *accel = current_accel();
125802c4dafSPhilippe Mathieu-Daudé     AccelClass *acc = ACCEL_GET_CLASS(accel);
126802c4dafSPhilippe Mathieu-Daudé     if (acc->gdbstub_supported_sstep_flags) {
127*842e7eecSPhilippe Mathieu-Daudé         return acc->gdbstub_supported_sstep_flags(accel);
128802c4dafSPhilippe Mathieu-Daudé     }
129802c4dafSPhilippe Mathieu-Daudé     return 0;
130802c4dafSPhilippe Mathieu-Daudé }
131802c4dafSPhilippe Mathieu-Daudé 
132802c4dafSPhilippe Mathieu-Daudé static const TypeInfo accel_types[] = {
133802c4dafSPhilippe Mathieu-Daudé     {
134802c4dafSPhilippe Mathieu-Daudé         .name           = TYPE_ACCEL,
135802c4dafSPhilippe Mathieu-Daudé         .parent         = TYPE_OBJECT,
136802c4dafSPhilippe Mathieu-Daudé         .class_size     = sizeof(AccelClass),
137802c4dafSPhilippe Mathieu-Daudé         .instance_size  = sizeof(AccelState),
138802c4dafSPhilippe Mathieu-Daudé         .abstract       = true,
139802c4dafSPhilippe Mathieu-Daudé     },
140802c4dafSPhilippe Mathieu-Daudé };
141802c4dafSPhilippe Mathieu-Daudé 
142802c4dafSPhilippe Mathieu-Daudé DEFINE_TYPES(accel_types)
143