Browse Source
Various methods of accel-target.c don't use any target-specific knowledge at all and can be built once in the target-agnostic accel-common.c file. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> Reviewed-by: Pierrick Bouvier <pierrick.bouvier@linaro.org> Message-Id: <20250417165430.58213-8-philmd@linaro.org>pull/291/head
3 changed files with 143 additions and 129 deletions
@ -0,0 +1,142 @@ |
|||
/*
|
|||
* QEMU accel class, components common to system emulation and user mode |
|||
* |
|||
* Copyright (c) 2003-2008 Fabrice Bellard |
|||
* Copyright (c) 2014 Red Hat Inc. |
|||
* |
|||
* SPDX-License-Identifier: MIT |
|||
*/ |
|||
|
|||
#include "qemu/osdep.h" |
|||
#include "qemu/accel.h" |
|||
#include "qemu/target-info.h" |
|||
#include "accel/accel-cpu.h" |
|||
#include "accel-internal.h" |
|||
|
|||
/* Lookup AccelClass from opt_name. Returns NULL if not found */ |
|||
AccelClass *accel_find(const char *opt_name) |
|||
{ |
|||
char *class_name = g_strdup_printf(ACCEL_CLASS_NAME("%s"), opt_name); |
|||
AccelClass *ac = ACCEL_CLASS(module_object_class_by_name(class_name)); |
|||
g_free(class_name); |
|||
return ac; |
|||
} |
|||
|
|||
/* Return the name of the current accelerator */ |
|||
const char *current_accel_name(void) |
|||
{ |
|||
AccelClass *ac = ACCEL_GET_CLASS(current_accel()); |
|||
|
|||
return ac->name; |
|||
} |
|||
|
|||
static void accel_init_cpu_int_aux(ObjectClass *klass, void *opaque) |
|||
{ |
|||
CPUClass *cc = CPU_CLASS(klass); |
|||
AccelCPUClass *accel_cpu = opaque; |
|||
|
|||
/*
|
|||
* The first callback allows accel-cpu to run initializations |
|||
* for the CPU, customizing CPU behavior according to the accelerator. |
|||
* |
|||
* The second one allows the CPU to customize the accel-cpu |
|||
* behavior according to the CPU. |
|||
* |
|||
* The second is currently only used by TCG, to specialize the |
|||
* TCGCPUOps depending on the CPU type. |
|||
*/ |
|||
cc->accel_cpu = accel_cpu; |
|||
if (accel_cpu->cpu_class_init) { |
|||
accel_cpu->cpu_class_init(cc); |
|||
} |
|||
if (cc->init_accel_cpu) { |
|||
cc->init_accel_cpu(accel_cpu, 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 */ |
|||
const char *cpu_resolving_type = target_cpu_type(); |
|||
|
|||
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) |
|||
{ |
|||
accel_init_ops_interfaces(ac); |
|||
accel_init_cpu_interfaces(ac); |
|||
} |
|||
|
|||
void accel_cpu_instance_init(CPUState *cpu) |
|||
{ |
|||
if (cpu->cc->accel_cpu && cpu->cc->accel_cpu->cpu_instance_init) { |
|||
cpu->cc->accel_cpu->cpu_instance_init(cpu); |
|||
} |
|||
} |
|||
|
|||
bool accel_cpu_common_realize(CPUState *cpu, Error **errp) |
|||
{ |
|||
AccelState *accel = current_accel(); |
|||
AccelClass *acc = ACCEL_GET_CLASS(accel); |
|||
|
|||
/* target specific realization */ |
|||
if (cpu->cc->accel_cpu |
|||
&& cpu->cc->accel_cpu->cpu_target_realize |
|||
&& !cpu->cc->accel_cpu->cpu_target_realize(cpu, errp)) { |
|||
return false; |
|||
} |
|||
|
|||
/* generic realization */ |
|||
if (acc->cpu_common_realize && !acc->cpu_common_realize(cpu, errp)) { |
|||
return false; |
|||
} |
|||
|
|||
return true; |
|||
} |
|||
|
|||
void accel_cpu_common_unrealize(CPUState *cpu) |
|||
{ |
|||
AccelState *accel = current_accel(); |
|||
AccelClass *acc = ACCEL_GET_CLASS(accel); |
|||
|
|||
/* generic unrealization */ |
|||
if (acc->cpu_common_unrealize) { |
|||
acc->cpu_common_unrealize(cpu); |
|||
} |
|||
} |
|||
|
|||
int accel_supported_gdbstub_sstep_flags(void) |
|||
{ |
|||
AccelState *accel = current_accel(); |
|||
AccelClass *acc = ACCEL_GET_CLASS(accel); |
|||
if (acc->gdbstub_supported_sstep_flags) { |
|||
return acc->gdbstub_supported_sstep_flags(); |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
static const TypeInfo accel_types[] = { |
|||
{ |
|||
.name = TYPE_ACCEL, |
|||
.parent = TYPE_OBJECT, |
|||
.class_size = sizeof(AccelClass), |
|||
.instance_size = sizeof(AccelState), |
|||
.abstract = true, |
|||
}, |
|||
}; |
|||
|
|||
DEFINE_TYPES(accel_types) |
|||
Loading…
Reference in new issue