/*
 * 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)));
    cpu->env.cpu_model_str = cpu_model;

    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)
