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