/*
 * CPU models for s390x - System Emulation-only
 *
 * Copyright 2016 IBM Corp.
 *
 * Author(s): David Hildenbrand <dahi@linux.vnet.ibm.com>
 *
 * This work is licensed under the terms of the GNU GPL, version 2 or (at
 * your option) any later version. See the COPYING file in the top-level
 * directory.
 */

#include "qemu/osdep.h"
#include "cpu.h"
#include "s390x-internal.h"
#include "kvm/kvm_s390x.h"
#include "sysemu/kvm.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qapi/qobject-input-visitor.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qapi-commands-machine-target.h"

static void list_add_feat(const char *name, void *opaque);

static void check_unavailable_features(const S390CPUModel *max_model,
                                       const S390CPUModel *model,
                                       strList **unavailable)
{
    S390FeatBitmap missing;

    /* check general model compatibility */
    if (max_model->def->gen < model->def->gen ||
        (max_model->def->gen == model->def->gen &&
         max_model->def->ec_ga < model->def->ec_ga)) {
        list_add_feat("type", unavailable);
    }

    /* detect missing features if any to properly report them */
    bitmap_andnot(missing, model->features, max_model->features,
                  S390_FEAT_MAX);
    if (!bitmap_empty(missing, S390_FEAT_MAX)) {
        s390_feat_bitmap_to_ascii(missing, unavailable, list_add_feat);
    }
}

struct CpuDefinitionInfoListData {
    CpuDefinitionInfoList *list;
    S390CPUModel *model;
};

static void create_cpu_model_list(ObjectClass *klass, void *opaque)
{
    struct CpuDefinitionInfoListData *cpu_list_data = opaque;
    CpuDefinitionInfoList **cpu_list = &cpu_list_data->list;
    CpuDefinitionInfo *info;
    char *name = g_strdup(object_class_get_name(klass));
    S390CPUClass *scc = S390_CPU_CLASS(klass);

    /* strip off the -s390x-cpu */
    g_strrstr(name, "-" TYPE_S390_CPU)[0] = 0;
    info = g_new0(CpuDefinitionInfo, 1);
    info->name = name;
    info->has_migration_safe = true;
    info->migration_safe = scc->is_migration_safe;
    info->q_static = scc->is_static;
    info->q_typename = g_strdup(object_class_get_name(klass));
    /* check for unavailable features */
    if (cpu_list_data->model) {
        Object *obj;
        S390CPU *sc;
        obj = object_new_with_class(klass);
        sc = S390_CPU(obj);
        if (sc->model) {
            info->has_unavailable_features = true;
            check_unavailable_features(cpu_list_data->model, sc->model,
                                       &info->unavailable_features);
        }
        object_unref(obj);
    }

    QAPI_LIST_PREPEND(*cpu_list, info);
}

CpuDefinitionInfoList *qmp_query_cpu_definitions(Error **errp)
{
    struct CpuDefinitionInfoListData list_data = {
        .list = NULL,
    };

    list_data.model = get_max_cpu_model(NULL);

    object_class_foreach(create_cpu_model_list, TYPE_S390_CPU, false,
                         &list_data);

    return list_data.list;
}

static void cpu_model_from_info(S390CPUModel *model, const CpuModelInfo *info,
                                const char *info_arg_name, Error **errp)
{
    Error *err = NULL;
    const QDict *qdict;
    const QDictEntry *e;
    Visitor *visitor;
    ObjectClass *oc;
    S390CPU *cpu;
    Object *obj;

    oc = cpu_class_by_name(TYPE_S390_CPU, info->name);
    if (!oc) {
        error_setg(errp, "The CPU definition \'%s\' is unknown.", info->name);
        return;
    }
    if (S390_CPU_CLASS(oc)->kvm_required && !kvm_enabled()) {
        error_setg(errp, "The CPU definition '%s' requires KVM", info->name);
        return;
    }
    obj = object_new_with_class(oc);
    cpu = S390_CPU(obj);

    if (!cpu->model) {
        error_setg(errp, "Details about the host CPU model are not available, "
                         "it cannot be used.");
        object_unref(obj);
        return;
    }

    if (info->props) {
        g_autofree const char *props_name = g_strdup_printf("%s.props",
                                                            info_arg_name);

        visitor = qobject_input_visitor_new(info->props);
        if (!visit_start_struct(visitor, props_name, NULL, 0, errp)) {
            visit_free(visitor);
            object_unref(obj);
            return;
        }
        qdict = qobject_to(QDict, info->props);
        for (e = qdict_first(qdict); e; e = qdict_next(qdict, e)) {
            if (!object_property_set(obj, e->key, visitor, &err)) {
                break;
            }
        }
        if (!err) {
            visit_check_struct(visitor, &err);
        }
        visit_end_struct(visitor, NULL);
        visit_free(visitor);
        if (err) {
            error_propagate(errp, err);
            object_unref(obj);
            return;
        }
    }

    /* copy the model and throw the cpu away */
    memcpy(model, cpu->model, sizeof(*model));
    object_unref(obj);
}

static void qdict_add_disabled_feat(const char *name, void *opaque)
{
    qdict_put_bool(opaque, name, false);
}

static void qdict_add_enabled_feat(const char *name, void *opaque)
{
    qdict_put_bool(opaque, name, true);
}

/* convert S390CPUDef into a static CpuModelInfo */
static void cpu_info_from_model(CpuModelInfo *info, const S390CPUModel *model,
                                bool delta_changes)
{
    QDict *qdict = qdict_new();
    S390FeatBitmap bitmap;

    /* always fallback to the static base model */
    info->name = g_strdup_printf("%s-base", model->def->name);

    if (delta_changes) {
        /* features deleted from the base feature set */
        bitmap_andnot(bitmap, model->def->base_feat, model->features,
                      S390_FEAT_MAX);
        if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
            s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
        }

        /* features added to the base feature set */
        bitmap_andnot(bitmap, model->features, model->def->base_feat,
                      S390_FEAT_MAX);
        if (!bitmap_empty(bitmap, S390_FEAT_MAX)) {
            s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_enabled_feat);
        }
    } else {
        /* expand all features */
        s390_feat_bitmap_to_ascii(model->features, qdict,
                                  qdict_add_enabled_feat);
        bitmap_complement(bitmap, model->features, S390_FEAT_MAX);
        s390_feat_bitmap_to_ascii(bitmap, qdict, qdict_add_disabled_feat);
    }

    if (!qdict_size(qdict)) {
        qobject_unref(qdict);
    } else {
        info->props = QOBJECT(qdict);
    }

    /* features flagged as deprecated */
    bitmap_zero(bitmap, S390_FEAT_MAX);
    s390_get_deprecated_features(bitmap);

    bitmap_and(bitmap, bitmap, model->def->full_feat, S390_FEAT_MAX);
    s390_feat_bitmap_to_ascii(bitmap, &info->deprecated_props, list_add_feat);
    info->has_deprecated_props = !!info->deprecated_props;
}

CpuModelExpansionInfo *qmp_query_cpu_model_expansion(CpuModelExpansionType type,
                                                      CpuModelInfo *model,
                                                      Error **errp)
{
    Error *err = NULL;
    CpuModelExpansionInfo *expansion_info = NULL;
    S390CPUModel s390_model;
    bool delta_changes = false;

    /* convert it to our internal representation */
    cpu_model_from_info(&s390_model, model, "model", &err);
    if (err) {
        error_propagate(errp, err);
        return NULL;
    }

    if (type == CPU_MODEL_EXPANSION_TYPE_STATIC) {
        delta_changes = true;
    } else if (type != CPU_MODEL_EXPANSION_TYPE_FULL) {
        error_setg(errp, "The requested expansion type is not supported.");
        return NULL;
    }

    /* convert it back to a static representation */
    expansion_info = g_new0(CpuModelExpansionInfo, 1);
    expansion_info->model = g_malloc0(sizeof(*expansion_info->model));
    cpu_info_from_model(expansion_info->model, &s390_model, delta_changes);
    return expansion_info;
}

static void list_add_feat(const char *name, void *opaque)
{
    strList **last = (strList **) opaque;

    QAPI_LIST_PREPEND(*last, g_strdup(name));
}

CpuModelCompareInfo *qmp_query_cpu_model_comparison(CpuModelInfo *infoa,
                                                     CpuModelInfo *infob,
                                                     Error **errp)
{
    Error *err = NULL;
    CpuModelCompareResult feat_result, gen_result;
    CpuModelCompareInfo *compare_info;
    S390FeatBitmap missing, added;
    S390CPUModel modela, modelb;

    /* convert both models to our internal representation */
    cpu_model_from_info(&modela, infoa, "modela", &err);
    if (err) {
        error_propagate(errp, err);
        return NULL;
    }
    cpu_model_from_info(&modelb, infob, "modelb", &err);
    if (err) {
        error_propagate(errp, err);
        return NULL;
    }
    compare_info = g_new0(CpuModelCompareInfo, 1);

    /* check the cpu generation and ga level */
    if (modela.def->gen == modelb.def->gen) {
        if (modela.def->ec_ga == modelb.def->ec_ga) {
            /* ec and corresponding bc are identical */
            gen_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
        } else if (modela.def->ec_ga < modelb.def->ec_ga) {
            gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
        } else {
            gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
        }
    } else if (modela.def->gen < modelb.def->gen) {
        gen_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
    } else {
        gen_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
    }
    if (gen_result != CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
        /* both models cannot be made identical */
        list_add_feat("type", &compare_info->responsible_properties);
    }

    /* check the feature set */
    if (bitmap_equal(modela.features, modelb.features, S390_FEAT_MAX)) {
        feat_result = CPU_MODEL_COMPARE_RESULT_IDENTICAL;
    } else {
        bitmap_andnot(missing, modela.features, modelb.features, S390_FEAT_MAX);
        s390_feat_bitmap_to_ascii(missing,
                                  &compare_info->responsible_properties,
                                  list_add_feat);
        bitmap_andnot(added, modelb.features, modela.features, S390_FEAT_MAX);
        s390_feat_bitmap_to_ascii(added, &compare_info->responsible_properties,
                                  list_add_feat);
        if (bitmap_empty(missing, S390_FEAT_MAX)) {
            feat_result = CPU_MODEL_COMPARE_RESULT_SUBSET;
        } else if (bitmap_empty(added, S390_FEAT_MAX)) {
            feat_result = CPU_MODEL_COMPARE_RESULT_SUPERSET;
        } else {
            feat_result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
        }
    }

    /* combine the results */
    if (gen_result == feat_result) {
        compare_info->result = gen_result;
    } else if (feat_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
        compare_info->result = gen_result;
    } else if (gen_result == CPU_MODEL_COMPARE_RESULT_IDENTICAL) {
        compare_info->result = feat_result;
    } else {
        compare_info->result = CPU_MODEL_COMPARE_RESULT_INCOMPATIBLE;
    }
    return compare_info;
}

CpuModelBaselineInfo *qmp_query_cpu_model_baseline(CpuModelInfo *infoa,
                                                    CpuModelInfo *infob,
                                                    Error **errp)
{
    Error *err = NULL;
    CpuModelBaselineInfo *baseline_info;
    S390CPUModel modela, modelb, model;
    uint16_t cpu_type;
    uint8_t max_gen_ga;
    uint8_t max_gen;

    /* convert both models to our internal representation */
    cpu_model_from_info(&modela, infoa, "modela", &err);
    if (err) {
        error_propagate(errp, err);
        return NULL;
    }

    cpu_model_from_info(&modelb, infob, "modelb", &err);
    if (err) {
        error_propagate(errp, err);
        return NULL;
    }

    /* features both models support */
    bitmap_and(model.features, modela.features, modelb.features, S390_FEAT_MAX);

    /* detect the maximum model not regarding features */
    if (modela.def->gen == modelb.def->gen) {
        if (modela.def->type == modelb.def->type) {
            cpu_type = modela.def->type;
        } else {
            cpu_type = 0;
        }
        max_gen = modela.def->gen;
        max_gen_ga = MIN(modela.def->ec_ga, modelb.def->ec_ga);
    } else if (modela.def->gen > modelb.def->gen) {
        cpu_type = modelb.def->type;
        max_gen = modelb.def->gen;
        max_gen_ga = modelb.def->ec_ga;
    } else {
        cpu_type = modela.def->type;
        max_gen = modela.def->gen;
        max_gen_ga = modela.def->ec_ga;
    }

    model.def = s390_find_cpu_def(cpu_type, max_gen, max_gen_ga,
                                  model.features);

    /* models without early base features (esan3) are bad */
    if (!model.def) {
        error_setg(errp, "No compatible CPU model could be created as"
                   " important base features are disabled");
        return NULL;
    }

    /* strip off features not part of the max model */
    bitmap_and(model.features, model.features, model.def->full_feat,
               S390_FEAT_MAX);

    baseline_info = g_new0(CpuModelBaselineInfo, 1);
    baseline_info->model = g_malloc0(sizeof(*baseline_info->model));
    cpu_info_from_model(baseline_info->model, &model, true);
    return baseline_info;
}

void apply_cpu_model(const S390CPUModel *model, Error **errp)
{
    static S390CPUModel applied_model;
    static bool applied;

    /*
     * We have the same model for all VCPUs. KVM can only be configured before
     * any VCPUs are defined in KVM.
     */
    if (applied) {
        if (model && memcmp(&applied_model, model, sizeof(S390CPUModel))) {
            error_setg(errp, "Mixed CPU models are not supported on s390x.");
        }
        return;
    }

    if (kvm_enabled()) {
        if (!kvm_s390_apply_cpu_model(model, errp)) {
            return;
        }
    }

    applied = true;
    if (model) {
        applied_model = *model;
    }
}
