Commit 12a6c15e authored by Igor Mammedov's avatar Igor Mammedov Committed by Eduardo Habkost
Browse files

sparc: convert cpu models to SPARC cpu subclasses



QOMfy cpu models handling introducing propper cpu types
for each cpu model.

Signed-off-by: default avatarIgor Mammedov <imammedo@redhat.com>
Reviewed-by: default avatarPhilippe Mathieu-Daudé <f4bug@amsat.org>
Tested-by: default avatarPhilippe Mathieu-Daudé <f4bug@amsat.org>
Message-Id: <1503592308-93913-3-git-send-email-imammedo@redhat.com>
Signed-off-by: default avatarEduardo Habkost <ehabkost@redhat.com>
parent 3e2cf187
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@
#define SPARC_CPU_GET_CLASS(obj) \
    OBJECT_GET_CLASS(SPARCCPUClass, (obj), TYPE_SPARC_CPU)

typedef struct sparc_def_t sparc_def_t;
/**
 * SPARCCPUClass:
 * @parent_realize: The parent class' realize handler.
@@ -49,6 +50,7 @@ typedef struct SPARCCPUClass {

    DeviceRealize parent_realize;
    void (*parent_reset)(CPUState *cpu);
    sparc_def_t *cpu_def;
} SPARCCPUClass;

typedef struct SPARCCPU SPARCCPU;
+81 −39
Original line number Diff line number Diff line
@@ -25,8 +25,6 @@

//#define DEBUG_FEATURES

static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model);

/* CPUClass::reset() */
static void sparc_cpu_reset(CPUState *s)
{
@@ -111,17 +109,9 @@ static int cpu_sparc_register(SPARCCPU *cpu, const char *cpu_model)
{
    CPUSPARCState *env = &cpu->env;
    char *s = g_strdup(cpu_model);
    char *featurestr, *name = strtok(s, ",");
    sparc_def_t def1, *def = &def1;
    char *featurestr = strtok(s, ",");
    Error *err = NULL;

    if (cpu_sparc_find_by_name(def, name) < 0) {
        g_free(s);
        return -1;
    }

    env->def = g_memdup(def, sizeof(*def));

    featurestr = strtok(NULL, ",");
    sparc_cpu_parse_features(CPU(cpu), featurestr, &err);
    g_free(s);
@@ -130,18 +120,18 @@ static int cpu_sparc_register(SPARCCPU *cpu, const char *cpu_model)
        return -1;
    }

    env->version = def->iu_version;
    env->fsr = def->fpu_version;
    env->nwindows = def->nwindows;
    env->version = env->def->iu_version;
    env->fsr = env->def->fpu_version;
    env->nwindows = env->def->nwindows;
#if !defined(TARGET_SPARC64)
    env->mmuregs[0] |= def->mmu_version;
    env->mmuregs[0] |= env->def->mmu_version;
    cpu_sparc_set_id(env, 0);
    env->mxccregs[7] |= def->mxcc_version;
    env->mxccregs[7] |= env->def->mxcc_version;
#else
    env->mmu_version = def->mmu_version;
    env->maxtl = def->maxtl;
    env->version |= def->maxtl << 8;
    env->version |= def->nwindows - 1;
    env->mmu_version = env->def->mmu_version;
    env->maxtl = env->def->maxtl;
    env->version |= env->def->maxtl << 8;
    env->version |= env->def->nwindows - 1;
#endif
    return 0;
}
@@ -149,8 +139,18 @@ static int cpu_sparc_register(SPARCCPU *cpu, const char *cpu_model)
SPARCCPU *cpu_sparc_init(const char *cpu_model)
{
    SPARCCPU *cpu;
    ObjectClass *oc;
    char *str, *name;

    str = g_strdup(cpu_model);
    name = strtok(str, ",");
    oc = cpu_class_by_name(TYPE_SPARC_CPU, name);
    g_free(str);
    if (oc == NULL) {
        return NULL;
    }

    cpu = SPARC_CPU(object_new(TYPE_SPARC_CPU));
    cpu = SPARC_CPU(object_new(object_class_get_name(oc)));

    if (cpu_sparc_register(cpu, cpu_model) < 0) {
        object_unref(OBJECT(cpu));
@@ -553,23 +553,6 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features)
    error_report("CPU feature %s not found", flagname);
}

static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *name)
{
    unsigned int i;
    const sparc_def_t *def = NULL;

    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
        if (strcasecmp(name, sparc_defs[i].name) == 0) {
            def = &sparc_defs[i];
        }
    }
    if (!def) {
        return -1;
    }
    memcpy(cpu_def, def, sizeof(*def));
    return 0;
}

static void sparc_cpu_parse_features(CPUState *cs, char *features,
                                     Error **errp)
{
@@ -796,6 +779,36 @@ static bool sparc_cpu_has_work(CPUState *cs)
           cpu_interrupts_enabled(env);
}

static char *sparc_cpu_type_name(const char *cpu_model)
{
    char *name = g_strdup_printf("%s-" TYPE_SPARC_CPU, cpu_model);
    char *s = name;

    /* SPARC cpu model names happen to have whitespaces,
     * as type names shouldn't have spaces replace them with '-'
     */
    while ((s = strchr(s, ' '))) {
        *s = '-';
    }

    return name;
}

static ObjectClass *sparc_cpu_class_by_name(const char *cpu_model)
{
    ObjectClass *oc;
    char *typename;

    if (cpu_model == NULL) {
        return NULL;
    }

    typename = sparc_cpu_type_name(cpu_model);
    oc = object_class_by_name(typename);
    g_free(typename);
    return oc;
}

static void sparc_cpu_realizefn(DeviceState *dev, Error **errp)
{
    CPUState *cs = CPU(dev);
@@ -825,6 +838,7 @@ static void sparc_cpu_initfn(Object *obj)
{
    CPUState *cs = CPU(obj);
    SPARCCPU *cpu = SPARC_CPU(obj);
    SPARCCPUClass *scc = SPARC_CPU_GET_CLASS(obj);
    CPUSPARCState *env = &cpu->env;

    cs->env_ptr = env;
@@ -832,6 +846,8 @@ static void sparc_cpu_initfn(Object *obj)
    if (tcg_enabled()) {
        gen_intermediate_code_init(env);
    }

    env->def = g_memdup(scc->cpu_def, sizeof(*scc->cpu_def));
}

static void sparc_cpu_uninitfn(Object *obj)
@@ -854,6 +870,7 @@ static void sparc_cpu_class_init(ObjectClass *oc, void *data)
    scc->parent_reset = cc->reset;
    cc->reset = sparc_cpu_reset;

    cc->class_by_name = sparc_cpu_class_by_name;
    cc->has_work = sparc_cpu_has_work;
    cc->do_interrupt = sparc_cpu_do_interrupt;
    cc->cpu_exec_interrupt = sparc_cpu_exec_interrupt;
@@ -888,14 +905,39 @@ static const TypeInfo sparc_cpu_type_info = {
    .instance_size = sizeof(SPARCCPU),
    .instance_init = sparc_cpu_initfn,
    .instance_finalize = sparc_cpu_uninitfn,
    .abstract = false,
    .abstract = true,
    .class_size = sizeof(SPARCCPUClass),
    .class_init = sparc_cpu_class_init,
};

static void sparc_cpu_cpudef_class_init(ObjectClass *oc, void *data)
{
    SPARCCPUClass *scc = SPARC_CPU_CLASS(oc);
    scc->cpu_def = data;
}

static void sparc_register_cpudef_type(const struct sparc_def_t *def)
{
    char *typename = sparc_cpu_type_name(def->name);
    TypeInfo ti = {
        .name = typename,
        .parent = TYPE_SPARC_CPU,
        .class_init = sparc_cpu_cpudef_class_init,
        .class_data = (void *)def,
    };

    type_register(&ti);
    g_free(typename);
}

static void sparc_cpu_register_types(void)
{
    int i;

    type_register_static(&sparc_cpu_type_info);
    for (i = 0; i < ARRAY_SIZE(sparc_defs); i++) {
        sparc_register_cpudef_type(&sparc_defs[i]);
    }
}

type_init(sparc_cpu_register_types)