diff options
author | Claudio Fontana <cfontana@suse.de> | 2021-02-04 17:39:26 +0100 |
---|---|---|
committer | Richard Henderson <richard.henderson@linaro.org> | 2021-02-05 10:24:15 -1000 |
commit | fb6916dd6ca8bb4b42d44baba9c67ecaf2279577 (patch) | |
tree | 692eb654bd23ed45bcacc3f993d1d9fd29144f91 /accel | |
parent | b86f59c71552591a17dd21ba8f09654bfa19a31e (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')
-rw-r--r-- | accel/accel-common.c | 44 |
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); |