mirror of https://github.com/xemu-project/xemu.git
target/riscv/tcg: introduce tcg_cpu_instance_init()
tcg_cpu_instance_init() will be the 'cpu_instance_init' impl for the TCG accelerator. It'll be called from within riscv_cpu_post_init(), via accel_cpu_instance_init(), similar to what happens with KVM. In fact, to preserve behavior, the implementation will be similar to what riscv_cpu_post_init() already does. In this patch we'll move riscv_cpu_add_user_properties() and riscv_init_max_cpu_extensions() and all their dependencies to tcg-cpu.c. All multi-extension properties code was moved. The 'multi_ext_user_opts' hash table was also moved to tcg-cpu.c since it's a TCG only structure, meaning that we won't have to worry about initializing a TCG hash table when running a KVM CPU anymore. riscv_cpu_add_user_properties() will remain in cpu.c for now due to how much code it requires to be moved at the same time. We'll do that in the next patch. Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com> Reviewed-by: Andrew Jones <ajones@ventanamicro.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20230925175709.35696-16-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
parent
f51d03b01f
commit
fce8bb5d08
|
@ -162,9 +162,6 @@ static const struct isa_ext_data isa_edata_arr[] = {
|
||||||
ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
|
ISA_EXT_DATA_ENTRY(xventanacondops, PRIV_VERSION_1_12_0, ext_XVentanaCondOps),
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Hash that stores user set extensions */
|
|
||||||
static GHashTable *multi_ext_user_opts;
|
|
||||||
|
|
||||||
bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)
|
bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset)
|
||||||
{
|
{
|
||||||
bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
|
bool *ext_enabled = (void *)&cpu->cfg + ext_offset;
|
||||||
|
@ -194,12 +191,6 @@ int cpu_cfg_ext_get_min_version(uint32_t ext_offset)
|
||||||
g_assert_not_reached();
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
|
|
||||||
{
|
|
||||||
return g_hash_table_contains(multi_ext_user_opts,
|
|
||||||
GUINT_TO_POINTER(ext_offset));
|
|
||||||
}
|
|
||||||
|
|
||||||
const char * const riscv_int_regnames[] = {
|
const char * const riscv_int_regnames[] = {
|
||||||
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
|
"x0/zero", "x1/ra", "x2/sp", "x3/gp", "x4/tp", "x5/t0", "x6/t1",
|
||||||
"x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
|
"x7/t2", "x8/s0", "x9/s1", "x10/a0", "x11/a1", "x12/a2", "x13/a3",
|
||||||
|
@ -280,9 +271,6 @@ static const char * const riscv_intr_names[] = {
|
||||||
"reserved"
|
"reserved"
|
||||||
};
|
};
|
||||||
|
|
||||||
static void riscv_cpu_add_user_properties(Object *obj);
|
|
||||||
static void riscv_init_max_cpu_extensions(Object *obj);
|
|
||||||
|
|
||||||
const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
|
const char *riscv_cpu_get_trap_name(target_ulong cause, bool async)
|
||||||
{
|
{
|
||||||
if (async) {
|
if (async) {
|
||||||
|
@ -1206,32 +1194,9 @@ static bool riscv_cpu_is_dynamic(Object *cpu_obj)
|
||||||
return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
|
return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
|
|
||||||
{
|
|
||||||
return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool riscv_cpu_has_user_properties(Object *cpu_obj)
|
|
||||||
{
|
|
||||||
if (kvm_enabled() &&
|
|
||||||
object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_HOST) != NULL) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return riscv_cpu_is_dynamic(cpu_obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void riscv_cpu_post_init(Object *obj)
|
static void riscv_cpu_post_init(Object *obj)
|
||||||
{
|
{
|
||||||
accel_cpu_instance_init(CPU(obj));
|
accel_cpu_instance_init(CPU(obj));
|
||||||
|
|
||||||
if (tcg_enabled() && riscv_cpu_has_user_properties(obj)) {
|
|
||||||
riscv_cpu_add_user_properties(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (riscv_cpu_has_max_extensions(obj)) {
|
|
||||||
riscv_init_max_cpu_extensions(obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void riscv_cpu_init(Object *obj)
|
static void riscv_cpu_init(Object *obj)
|
||||||
|
@ -1240,8 +1205,6 @@ static void riscv_cpu_init(Object *obj)
|
||||||
qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
|
qdev_init_gpio_in(DEVICE(obj), riscv_cpu_set_irq,
|
||||||
IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
|
IRQ_LOCAL_MAX + IRQ_LOCAL_GUEST_MAX);
|
||||||
#endif /* CONFIG_USER_ONLY */
|
#endif /* CONFIG_USER_ONLY */
|
||||||
|
|
||||||
multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct RISCVCPUMisaExtConfig {
|
typedef struct RISCVCPUMisaExtConfig {
|
||||||
|
@ -1527,119 +1490,6 @@ Property riscv_cpu_options[] = {
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
|
|
||||||
void *opaque, Error **errp)
|
|
||||||
{
|
|
||||||
const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
|
|
||||||
bool value;
|
|
||||||
|
|
||||||
if (!visit_type_bool(v, name, &value, errp)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
isa_ext_update_enabled(RISCV_CPU(obj), multi_ext_cfg->offset, value);
|
|
||||||
|
|
||||||
g_hash_table_insert(multi_ext_user_opts,
|
|
||||||
GUINT_TO_POINTER(multi_ext_cfg->offset),
|
|
||||||
(gpointer)value);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cpu_get_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
|
|
||||||
void *opaque, Error **errp)
|
|
||||||
{
|
|
||||||
const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
|
|
||||||
bool value = isa_ext_is_enabled(RISCV_CPU(obj), multi_ext_cfg->offset);
|
|
||||||
|
|
||||||
visit_type_bool(v, name, &value, errp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cpu_add_multi_ext_prop(Object *cpu_obj,
|
|
||||||
const RISCVCPUMultiExtConfig *multi_cfg)
|
|
||||||
{
|
|
||||||
object_property_add(cpu_obj, multi_cfg->name, "bool",
|
|
||||||
cpu_get_multi_ext_cfg,
|
|
||||||
cpu_set_multi_ext_cfg,
|
|
||||||
NULL, (void *)multi_cfg);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Set def val directly instead of using
|
|
||||||
* object_property_set_bool() to save the set()
|
|
||||||
* callback hash for user inputs.
|
|
||||||
*/
|
|
||||||
isa_ext_update_enabled(RISCV_CPU(cpu_obj), multi_cfg->offset,
|
|
||||||
multi_cfg->enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void riscv_cpu_add_multiext_prop_array(Object *obj,
|
|
||||||
const RISCVCPUMultiExtConfig *array)
|
|
||||||
{
|
|
||||||
const RISCVCPUMultiExtConfig *prop;
|
|
||||||
|
|
||||||
g_assert(array);
|
|
||||||
|
|
||||||
for (prop = array; prop && prop->name; prop++) {
|
|
||||||
cpu_add_multi_ext_prop(obj, prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Add CPU properties with user-facing flags.
|
|
||||||
*
|
|
||||||
* This will overwrite existing env->misa_ext values with the
|
|
||||||
* defaults set via riscv_cpu_add_misa_properties().
|
|
||||||
*/
|
|
||||||
static void riscv_cpu_add_user_properties(Object *obj)
|
|
||||||
{
|
|
||||||
#ifndef CONFIG_USER_ONLY
|
|
||||||
riscv_add_satp_mode_properties(obj);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
riscv_cpu_add_misa_properties(obj);
|
|
||||||
|
|
||||||
riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_extensions);
|
|
||||||
riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_vendor_exts);
|
|
||||||
riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_experimental_exts);
|
|
||||||
|
|
||||||
for (Property *prop = riscv_cpu_options; prop && prop->name; prop++) {
|
|
||||||
qdev_property_add_static(DEVICE(obj), prop);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The 'max' type CPU will have all possible ratified
|
|
||||||
* non-vendor extensions enabled.
|
|
||||||
*/
|
|
||||||
static void riscv_init_max_cpu_extensions(Object *obj)
|
|
||||||
{
|
|
||||||
RISCVCPU *cpu = RISCV_CPU(obj);
|
|
||||||
CPURISCVState *env = &cpu->env;
|
|
||||||
const RISCVCPUMultiExtConfig *prop;
|
|
||||||
|
|
||||||
/* Enable RVG, RVJ and RVV that are disabled by default */
|
|
||||||
riscv_cpu_set_misa(env, env->misa_mxl, env->misa_ext | RVG | RVJ | RVV);
|
|
||||||
|
|
||||||
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
|
|
||||||
isa_ext_update_enabled(cpu, prop->offset, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* set vector version */
|
|
||||||
env->vext_ver = VEXT_VERSION_1_00_0;
|
|
||||||
|
|
||||||
/* Zfinx is not compatible with F. Disable it */
|
|
||||||
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zfinx), false);
|
|
||||||
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zdinx), false);
|
|
||||||
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zhinx), false);
|
|
||||||
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zhinxmin), false);
|
|
||||||
|
|
||||||
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zce), false);
|
|
||||||
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcmp), false);
|
|
||||||
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcmt), false);
|
|
||||||
|
|
||||||
if (env->misa_mxl != MXL_RV32) {
|
|
||||||
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcf), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static Property riscv_cpu_properties[] = {
|
static Property riscv_cpu_properties[] = {
|
||||||
DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
|
DEFINE_PROP_BOOL("debug", RISCVCPU, cfg.debug, true),
|
||||||
|
|
||||||
|
|
|
@ -710,7 +710,6 @@ enum riscv_pmu_event_idx {
|
||||||
|
|
||||||
/* used by tcg/tcg-cpu.c*/
|
/* used by tcg/tcg-cpu.c*/
|
||||||
void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en);
|
void isa_ext_update_enabled(RISCVCPU *cpu, uint32_t ext_offset, bool en);
|
||||||
bool cpu_cfg_ext_is_user_set(uint32_t ext_offset);
|
|
||||||
bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset);
|
bool isa_ext_is_enabled(RISCVCPU *cpu, uint32_t ext_offset);
|
||||||
int cpu_cfg_ext_get_min_version(uint32_t ext_offset);
|
int cpu_cfg_ext_get_min_version(uint32_t ext_offset);
|
||||||
void riscv_cpu_set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext);
|
void riscv_cpu_set_misa(CPURISCVState *env, RISCVMXL mxl, uint32_t ext);
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "pmu.h"
|
#include "pmu.h"
|
||||||
#include "time_helper.h"
|
#include "time_helper.h"
|
||||||
#include "qapi/error.h"
|
#include "qapi/error.h"
|
||||||
|
#include "qapi/visitor.h"
|
||||||
#include "qemu/accel.h"
|
#include "qemu/accel.h"
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/log.h"
|
#include "qemu/log.h"
|
||||||
|
@ -31,6 +32,15 @@
|
||||||
#include "hw/core/tcg-cpu-ops.h"
|
#include "hw/core/tcg-cpu-ops.h"
|
||||||
#include "tcg/tcg.h"
|
#include "tcg/tcg.h"
|
||||||
|
|
||||||
|
/* Hash that stores user set extensions */
|
||||||
|
static GHashTable *multi_ext_user_opts;
|
||||||
|
|
||||||
|
static bool cpu_cfg_ext_is_user_set(uint32_t ext_offset)
|
||||||
|
{
|
||||||
|
return g_hash_table_contains(multi_ext_user_opts,
|
||||||
|
GUINT_TO_POINTER(ext_offset));
|
||||||
|
}
|
||||||
|
|
||||||
static void riscv_cpu_synchronize_from_tb(CPUState *cs,
|
static void riscv_cpu_synchronize_from_tb(CPUState *cs,
|
||||||
const TranslationBlock *tb)
|
const TranslationBlock *tb)
|
||||||
{
|
{
|
||||||
|
@ -570,6 +580,144 @@ static bool tcg_cpu_realize(CPUState *cs, Error **errp)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void cpu_set_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
|
||||||
|
void *opaque, Error **errp)
|
||||||
|
{
|
||||||
|
const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
|
||||||
|
bool value;
|
||||||
|
|
||||||
|
if (!visit_type_bool(v, name, &value, errp)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
isa_ext_update_enabled(RISCV_CPU(obj), multi_ext_cfg->offset, value);
|
||||||
|
|
||||||
|
g_hash_table_insert(multi_ext_user_opts,
|
||||||
|
GUINT_TO_POINTER(multi_ext_cfg->offset),
|
||||||
|
(gpointer)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cpu_get_multi_ext_cfg(Object *obj, Visitor *v, const char *name,
|
||||||
|
void *opaque, Error **errp)
|
||||||
|
{
|
||||||
|
const RISCVCPUMultiExtConfig *multi_ext_cfg = opaque;
|
||||||
|
bool value = isa_ext_is_enabled(RISCV_CPU(obj), multi_ext_cfg->offset);
|
||||||
|
|
||||||
|
visit_type_bool(v, name, &value, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cpu_add_multi_ext_prop(Object *cpu_obj,
|
||||||
|
const RISCVCPUMultiExtConfig *multi_cfg)
|
||||||
|
{
|
||||||
|
object_property_add(cpu_obj, multi_cfg->name, "bool",
|
||||||
|
cpu_get_multi_ext_cfg,
|
||||||
|
cpu_set_multi_ext_cfg,
|
||||||
|
NULL, (void *)multi_cfg);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set def val directly instead of using
|
||||||
|
* object_property_set_bool() to save the set()
|
||||||
|
* callback hash for user inputs.
|
||||||
|
*/
|
||||||
|
isa_ext_update_enabled(RISCV_CPU(cpu_obj), multi_cfg->offset,
|
||||||
|
multi_cfg->enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void riscv_cpu_add_multiext_prop_array(Object *obj,
|
||||||
|
const RISCVCPUMultiExtConfig *array)
|
||||||
|
{
|
||||||
|
const RISCVCPUMultiExtConfig *prop;
|
||||||
|
|
||||||
|
g_assert(array);
|
||||||
|
|
||||||
|
for (prop = array; prop && prop->name; prop++) {
|
||||||
|
cpu_add_multi_ext_prop(obj, prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Add CPU properties with user-facing flags.
|
||||||
|
*
|
||||||
|
* This will overwrite existing env->misa_ext values with the
|
||||||
|
* defaults set via riscv_cpu_add_misa_properties().
|
||||||
|
*/
|
||||||
|
static void riscv_cpu_add_user_properties(Object *obj)
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_USER_ONLY
|
||||||
|
riscv_add_satp_mode_properties(obj);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
riscv_cpu_add_misa_properties(obj);
|
||||||
|
|
||||||
|
riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_extensions);
|
||||||
|
riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_vendor_exts);
|
||||||
|
riscv_cpu_add_multiext_prop_array(obj, riscv_cpu_experimental_exts);
|
||||||
|
|
||||||
|
for (Property *prop = riscv_cpu_options; prop && prop->name; prop++) {
|
||||||
|
qdev_property_add_static(DEVICE(obj), prop);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The 'max' type CPU will have all possible ratified
|
||||||
|
* non-vendor extensions enabled.
|
||||||
|
*/
|
||||||
|
static void riscv_init_max_cpu_extensions(Object *obj)
|
||||||
|
{
|
||||||
|
RISCVCPU *cpu = RISCV_CPU(obj);
|
||||||
|
CPURISCVState *env = &cpu->env;
|
||||||
|
const RISCVCPUMultiExtConfig *prop;
|
||||||
|
|
||||||
|
/* Enable RVG, RVJ and RVV that are disabled by default */
|
||||||
|
riscv_cpu_set_misa(env, env->misa_mxl, env->misa_ext | RVG | RVJ | RVV);
|
||||||
|
|
||||||
|
for (prop = riscv_cpu_extensions; prop && prop->name; prop++) {
|
||||||
|
isa_ext_update_enabled(cpu, prop->offset, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set vector version */
|
||||||
|
env->vext_ver = VEXT_VERSION_1_00_0;
|
||||||
|
|
||||||
|
/* Zfinx is not compatible with F. Disable it */
|
||||||
|
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zfinx), false);
|
||||||
|
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zdinx), false);
|
||||||
|
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zhinx), false);
|
||||||
|
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zhinxmin), false);
|
||||||
|
|
||||||
|
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zce), false);
|
||||||
|
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcmp), false);
|
||||||
|
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcmt), false);
|
||||||
|
|
||||||
|
if (env->misa_mxl != MXL_RV32) {
|
||||||
|
isa_ext_update_enabled(cpu, CPU_CFG_OFFSET(ext_zcf), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool riscv_cpu_has_max_extensions(Object *cpu_obj)
|
||||||
|
{
|
||||||
|
return object_dynamic_cast(cpu_obj, TYPE_RISCV_CPU_MAX) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool riscv_cpu_has_user_properties(Object *cpu_obj)
|
||||||
|
{
|
||||||
|
return object_dynamic_cast(cpu_obj, TYPE_RISCV_DYNAMIC_CPU) != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tcg_cpu_instance_init(CPUState *cs)
|
||||||
|
{
|
||||||
|
RISCVCPU *cpu = RISCV_CPU(cs);
|
||||||
|
Object *obj = OBJECT(cpu);
|
||||||
|
|
||||||
|
if (riscv_cpu_has_user_properties(obj)) {
|
||||||
|
multi_ext_user_opts = g_hash_table_new(NULL, g_direct_equal);
|
||||||
|
riscv_cpu_add_user_properties(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (riscv_cpu_has_max_extensions(obj)) {
|
||||||
|
riscv_init_max_cpu_extensions(obj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void tcg_cpu_init_ops(AccelCPUClass *accel_cpu, CPUClass *cc)
|
static void tcg_cpu_init_ops(AccelCPUClass *accel_cpu, CPUClass *cc)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -588,6 +736,7 @@ static void tcg_cpu_accel_class_init(ObjectClass *oc, void *data)
|
||||||
AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
|
AccelCPUClass *acc = ACCEL_CPU_CLASS(oc);
|
||||||
|
|
||||||
acc->cpu_class_init = tcg_cpu_class_init;
|
acc->cpu_class_init = tcg_cpu_class_init;
|
||||||
|
acc->cpu_instance_init = tcg_cpu_instance_init;
|
||||||
acc->cpu_target_realize = tcg_cpu_realize;
|
acc->cpu_target_realize = tcg_cpu_realize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue