/*
 * QEMU Moxie CPU
 *
 * Copyright (c) 2013 Anthony Green
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "cpu.h"
#include "qemu-common.h"
#include "migration/vmstate.h"
#include "machine.h"

static void moxie_cpu_set_pc(CPUState *cs, vaddr value)
{
    MoxieCPU *cpu = MOXIE_CPU(cs);

    cpu->env.pc = value;
}

static void moxie_cpu_reset(CPUState *s)
{
    MoxieCPU *cpu = MOXIE_CPU(s);
    MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(cpu);
    CPUMoxieState *env = &cpu->env;

    mcc->parent_reset(s);

    memset(env, 0, offsetof(CPUMoxieState, breakpoints));
    env->pc = 0x1000;

    tlb_flush(env, 1);
}

static void moxie_cpu_realizefn(DeviceState *dev, Error **errp)
{
    CPUState *cs = CPU(dev);
    MoxieCPUClass *mcc = MOXIE_CPU_GET_CLASS(dev);

    qemu_init_vcpu(cs);
    cpu_reset(cs);

    mcc->parent_realize(dev, errp);
}

static void moxie_cpu_initfn(Object *obj)
{
    CPUState *cs = CPU(obj);
    MoxieCPU *cpu = MOXIE_CPU(obj);
    static int inited;

    cs->env_ptr = &cpu->env;
    cpu_exec_init(&cpu->env);

    if (tcg_enabled() && !inited) {
        inited = 1;
        moxie_translate_init();
    }
}

static ObjectClass *moxie_cpu_class_by_name(const char *cpu_model)
{
    ObjectClass *oc;

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

    oc = object_class_by_name(cpu_model);
    if (oc != NULL && (!object_class_dynamic_cast(oc, TYPE_MOXIE_CPU) ||
                       object_class_is_abstract(oc))) {
        return NULL;
    }
    return oc;
}

static void moxie_cpu_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    CPUClass *cc = CPU_CLASS(oc);
    MoxieCPUClass *mcc = MOXIE_CPU_CLASS(oc);

    mcc->parent_realize = dc->realize;
    dc->realize = moxie_cpu_realizefn;

    mcc->parent_reset = cc->reset;
    cc->reset = moxie_cpu_reset;

    cc->class_by_name = moxie_cpu_class_by_name;

    cc->do_interrupt = moxie_cpu_do_interrupt;
    cc->dump_state = moxie_cpu_dump_state;
    cc->set_pc = moxie_cpu_set_pc;
#ifndef CONFIG_USER_ONLY
    cc->get_phys_page_debug = moxie_cpu_get_phys_page_debug;
    cc->vmsd = &vmstate_moxie_cpu;
#endif
}

static void moxielite_initfn(Object *obj)
{
    /* Set cpu feature flags */
}

static void moxie_any_initfn(Object *obj)
{
    /* Set cpu feature flags */
}

typedef struct MoxieCPUInfo {
    const char *name;
    void (*initfn)(Object *obj);
} MoxieCPUInfo;

static const MoxieCPUInfo moxie_cpus[] = {
    { .name = "MoxieLite",      .initfn = moxielite_initfn },
    { .name = "any",            .initfn = moxie_any_initfn },
};

MoxieCPU *cpu_moxie_init(const char *cpu_model)
{
    MoxieCPU *cpu;
    ObjectClass *oc;

    oc = moxie_cpu_class_by_name(cpu_model);
    if (oc == NULL) {
        return NULL;
    }
    cpu = MOXIE_CPU(object_new(object_class_get_name(oc)));

    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);

    return cpu;
}

static void cpu_register(const MoxieCPUInfo *info)
{
    TypeInfo type_info = {
        .parent = TYPE_MOXIE_CPU,
        .instance_size = sizeof(MoxieCPU),
        .instance_init = info->initfn,
        .class_size = sizeof(MoxieCPUClass),
    };

    type_info.name = g_strdup_printf("%s-" TYPE_MOXIE_CPU, info->name);
    type_register(&type_info);
    g_free((void *)type_info.name);
}

static const TypeInfo moxie_cpu_type_info = {
    .name = TYPE_MOXIE_CPU,
    .parent = TYPE_CPU,
    .instance_size = sizeof(MoxieCPU),
    .instance_init = moxie_cpu_initfn,
    .class_size = sizeof(MoxieCPUClass),
    .class_init = moxie_cpu_class_init,
};

static void moxie_cpu_register_types(void)
{
    int i;
    type_register_static(&moxie_cpu_type_info);
    for (i = 0; i < ARRAY_SIZE(moxie_cpus); i++) {
        cpu_register(&moxie_cpus[i]);
    }
}

type_init(moxie_cpu_register_types)
