aboutsummaryrefslogtreecommitdiff
path: root/accel/accel-common.c
diff options
context:
space:
mode:
authorClaudio Fontana <cfontana@suse.de>2021-02-04 17:39:26 +0100
committerRichard Henderson <richard.henderson@linaro.org>2021-02-05 10:24:15 -1000
commitfb6916dd6ca8bb4b42d44baba9c67ecaf2279577 (patch)
tree692eb654bd23ed45bcacc3f993d1d9fd29144f91 /accel/accel-common.c
parentb86f59c71552591a17dd21ba8f09654bfa19a31e (diff)
accel: introduce AccelCPUClass extending CPUClass
add a new optional interface to CPUClass, which allows accelerators to extend the CPUClass with additional accelerator-specific initializations. This will allow to separate the target cpu code that is specific to each accelerator, and register it automatically with object hierarchy lookup depending on accelerator code availability, as part of the accel_init_interfaces() initialization step. Signed-off-by: Claudio Fontana <cfontana@suse.de> Message-Id: <20210204163931.7358-19-cfontana@suse.de> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'accel/accel-common.c')
-rw-r--r--accel/accel-common.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/accel/accel-common.c b/accel/accel-common.c
index 6b59873419..9901b0531c 100644
--- a/accel/accel-common.c
+++ b/accel/accel-common.c
@@ -26,6 +26,9 @@
#include "qemu/osdep.h"
#include "qemu/accel.h"
+#include "cpu.h"
+#include "hw/core/accel-cpu.h"
+
#ifndef CONFIG_USER_ONLY
#include "accel-softmmu.h"
#endif /* !CONFIG_USER_ONLY */
@@ -46,16 +49,57 @@ AccelClass *accel_find(const char *opt_name)
return ac;
}
+static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque)
+{
+ CPUClass *cc = CPU_CLASS(klass);
+ AccelCPUClass *accel_cpu = opaque;
+
+ cc->accel_cpu = accel_cpu;
+ if (accel_cpu->cpu_class_init) {
+ accel_cpu->cpu_class_init(cc);
+ }
+}
+
+/* initialize the arch-specific accel CpuClass interfaces */
+static void accel_init_cpu_interfaces(AccelClass *ac)
+{
+ const char *ac_name; /* AccelClass name */
+ char *acc_name; /* AccelCPUClass name */
+ ObjectClass *acc; /* AccelCPUClass */
+
+ ac_name = object_class_get_name(OBJECT_CLASS(ac));
+ g_assert(ac_name != NULL);
+
+ acc_name = g_strdup_printf("%s-%s", ac_name, CPU_RESOLVING_TYPE);
+ acc = object_class_by_name(acc_name);
+ g_free(acc_name);
+
+ if (acc) {
+ object_class_foreach(accel_init_cpu_int_aux,
+ CPU_RESOLVING_TYPE, false, acc);
+ }
+}
+
void accel_init_interfaces(AccelClass *ac)
{
#ifndef CONFIG_USER_ONLY
accel_init_ops_interfaces(ac);
#endif /* !CONFIG_USER_ONLY */
+
+ accel_init_cpu_interfaces(ac);
}
+static const TypeInfo accel_cpu_type = {
+ .name = TYPE_ACCEL_CPU,
+ .parent = TYPE_OBJECT,
+ .abstract = true,
+ .class_size = sizeof(AccelCPUClass),
+};
+
static void register_accel_types(void)
{
type_register_static(&accel_type);
+ type_register_static(&accel_cpu_type);
}
type_init(register_accel_types);