/*
 * QEMU accel class, components common to system emulation and user mode
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 * Copyright (c) 2014 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qemu/accel.h"

#include "cpu.h"
#include "hw/core/accel-cpu.h"

#ifndef CONFIG_USER_ONLY
#include "accel-system.h"
#endif /* !CONFIG_USER_ONLY */

static const TypeInfo accel_type = {
    .name = TYPE_ACCEL,
    .parent = TYPE_OBJECT,
    .class_size = sizeof(AccelClass),
    .instance_size = sizeof(AccelState),
};

/* 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 */

    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)
{
#ifndef CONFIG_USER_ONLY
    accel_init_ops_interfaces(ac);
#endif /* !CONFIG_USER_ONLY */

    accel_init_cpu_interfaces(ac);
}

void accel_cpu_instance_init(CPUState *cpu)
{
    CPUClass *cc = CPU_GET_CLASS(cpu);

    if (cc->accel_cpu && cc->accel_cpu->cpu_instance_init) {
        cc->accel_cpu->cpu_instance_init(cpu);
    }
}

bool accel_cpu_common_realize(CPUState *cpu, Error **errp)
{
    CPUClass *cc = CPU_GET_CLASS(cpu);
    AccelState *accel = current_accel();
    AccelClass *acc = ACCEL_GET_CLASS(accel);

    /* target specific realization */
    if (cc->accel_cpu && cc->accel_cpu->cpu_target_realize
        && !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_cpu_type = {
    .name = TYPE_ACCEL_CPU,
    .parent = TYPE_OBJECT,
    .abstract = true,
    .class_size = sizeof(AccelCPUClass),
};

static void register_accel_types(void)
{
    type_register_static(&accel_type);
    type_register_static(&accel_cpu_type);
}

type_init(register_accel_types);
