/*
 * CPU features/facilities for s390x
 *
 * Copyright IBM Corp. 2016, 2018
 * Copyright Red Hat, Inc. 2019
 *
 * Author(s): David Hildenbrand <david@redhat.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 "qemu/module.h"
#include "cpu_features.h"

#define DEF_FEAT(_FEAT, _NAME, _TYPE, _BIT, _DESC) \
    [S390_FEAT_##_FEAT] = {                        \
        .name = _NAME,                             \
        .type = S390_FEAT_TYPE_##_TYPE,            \
        .bit = _BIT,                               \
        .desc = _DESC,                             \
    },
static const S390FeatDef s390_features[S390_FEAT_MAX] = {
    #include "cpu_features_def.inc.h"
};
#undef DEF_FEAT

const S390FeatDef *s390_feat_def(S390Feat feat)
{
    return &s390_features[feat];
}

S390Feat s390_feat_by_type_and_bit(S390FeatType type, int bit)
{
    S390Feat feat;

    for (feat = 0; feat < ARRAY_SIZE(s390_features); feat++) {
        if (s390_features[feat].type == type &&
            s390_features[feat].bit == bit) {
            return feat;
        }
    }
    return S390_FEAT_MAX;
}

void s390_init_feat_bitmap(const S390FeatInit init, S390FeatBitmap bitmap)
{
    int i, j;

    for (i = 0; i < (S390_FEAT_MAX / 64 + 1); i++) {
        if (init[i]) {
            for (j = 0; j < 64; j++) {
                if (init[i] & 1ULL << j) {
                    set_bit(i * 64 + j, bitmap);
                }
            }
        }
    }
}

void s390_fill_feat_block(const S390FeatBitmap features, S390FeatType type,
                          uint8_t *data)
{
    S390Feat feat;
    int bit_nr;

    switch (type) {
    case S390_FEAT_TYPE_STFL:
        if (test_bit(S390_FEAT_ZARCH, features)) {
            /* Features that are always active */
            set_be_bit(2, data);   /* z/Architecture */
            set_be_bit(138, data); /* Configuration-z-architectural-mode */
        }
        break;
    case S390_FEAT_TYPE_PTFF:
    case S390_FEAT_TYPE_KMAC:
    case S390_FEAT_TYPE_KMC:
    case S390_FEAT_TYPE_KM:
    case S390_FEAT_TYPE_KIMD:
    case S390_FEAT_TYPE_KLMD:
    case S390_FEAT_TYPE_PCKMO:
    case S390_FEAT_TYPE_KMCTR:
    case S390_FEAT_TYPE_KMF:
    case S390_FEAT_TYPE_KMO:
    case S390_FEAT_TYPE_PCC:
    case S390_FEAT_TYPE_PPNO:
    case S390_FEAT_TYPE_KMA:
    case S390_FEAT_TYPE_KDSA:
    case S390_FEAT_TYPE_SORTL:
    case S390_FEAT_TYPE_DFLTCC:
        set_be_bit(0, data); /* query is always available */
        break;
    default:
        break;
    };

    feat = find_first_bit(features, S390_FEAT_MAX);
    while (feat < S390_FEAT_MAX) {
        if (s390_features[feat].type == type) {
            bit_nr = s390_features[feat].bit;
            /* big endian on uint8_t array */
            set_be_bit(bit_nr, data);
        }
        feat = find_next_bit(features, S390_FEAT_MAX, feat + 1);
    }
}

void s390_add_from_feat_block(S390FeatBitmap features, S390FeatType type,
                              uint8_t *data)
{
    int nr_bits, le_bit;

    switch (type) {
    case S390_FEAT_TYPE_STFL:
       nr_bits = 16384;
       break;
    case S390_FEAT_TYPE_PLO:
    case S390_FEAT_TYPE_SORTL:
    case S390_FEAT_TYPE_DFLTCC:
       nr_bits = 256;
       break;
    default:
       /* all cpu subfunctions have 128 bit */
       nr_bits = 128;
    };

    le_bit = find_first_bit((unsigned long *) data, nr_bits);
    while (le_bit < nr_bits) {
        /* convert the bit number to a big endian bit nr */
        S390Feat feat = s390_feat_by_type_and_bit(type, BE_BIT_NR(le_bit));
        /* ignore unknown bits */
        if (feat < S390_FEAT_MAX) {
            set_bit(feat, features);
        }
        le_bit = find_next_bit((unsigned long *) data, nr_bits, le_bit + 1);
    }
}

void s390_feat_bitmap_to_ascii(const S390FeatBitmap features, void *opaque,
                               void (*fn)(const char *name, void *opaque))
{
    S390FeatBitmap bitmap, tmp;
    S390FeatGroup group;
    S390Feat feat;

    bitmap_copy(bitmap, features, S390_FEAT_MAX);

    /* process whole groups first */
    for (group = 0; group < S390_FEAT_GROUP_MAX; group++) {
        const S390FeatGroupDef *def = s390_feat_group_def(group);

        bitmap_and(tmp, bitmap, def->feat, S390_FEAT_MAX);
        if (bitmap_equal(tmp, def->feat, S390_FEAT_MAX)) {
            bitmap_andnot(bitmap, bitmap, def->feat, S390_FEAT_MAX);
            fn(def->name, opaque);
        }
    }

    /* report leftovers as separate features */
    feat = find_first_bit(bitmap, S390_FEAT_MAX);
    while (feat < S390_FEAT_MAX) {
        fn(s390_feat_def(feat)->name, opaque);
        feat = find_next_bit(bitmap, S390_FEAT_MAX, feat + 1);
    };
}

#define FEAT_GROUP_INIT(_name, _group, _desc)        \
    {                                                \
        .name = _name,                               \
        .desc = _desc,                               \
        .init = { S390_FEAT_GROUP_LIST_ ## _group }, \
    }

/* indexed by feature group number for easy lookup */
static S390FeatGroupDef s390_feature_groups[] = {
    FEAT_GROUP_INIT("plo", PLO, "Perform-locked-operation facility"),
    FEAT_GROUP_INIT("tods", TOD_CLOCK_STEERING, "Tod-clock-steering facility"),
    FEAT_GROUP_INIT("gen13ptff", GEN13_PTFF, "PTFF enhancements introduced with z13"),
    FEAT_GROUP_INIT("msa", MSA, "Message-security-assist facility"),
    FEAT_GROUP_INIT("msa1", MSA_EXT_1, "Message-security-assist-extension 1 facility"),
    FEAT_GROUP_INIT("msa2", MSA_EXT_2, "Message-security-assist-extension 2 facility"),
    FEAT_GROUP_INIT("msa3", MSA_EXT_3, "Message-security-assist-extension 3 facility"),
    FEAT_GROUP_INIT("msa4", MSA_EXT_4, "Message-security-assist-extension 4 facility"),
    FEAT_GROUP_INIT("msa5", MSA_EXT_5, "Message-security-assist-extension 5 facility"),
    FEAT_GROUP_INIT("msa6", MSA_EXT_6, "Message-security-assist-extension 6 facility"),
    FEAT_GROUP_INIT("msa7", MSA_EXT_7, "Message-security-assist-extension 7 facility"),
    FEAT_GROUP_INIT("msa8", MSA_EXT_8, "Message-security-assist-extension 8 facility"),
    FEAT_GROUP_INIT("msa9", MSA_EXT_9, "Message-security-assist-extension 9 facility"),
    FEAT_GROUP_INIT("msa9_pckmo", MSA_EXT_9_PCKMO, "Message-security-assist-extension 9 PCKMO subfunctions"),
    FEAT_GROUP_INIT("mepochptff", MULTIPLE_EPOCH_PTFF, "PTFF enhancements introduced with Multiple-epoch facility"),
    FEAT_GROUP_INIT("esort", ENH_SORT, "Enhanced-sort facility"),
    FEAT_GROUP_INIT("deflate", DEFLATE_CONVERSION, "Deflate-conversion facility"),
};

const S390FeatGroupDef *s390_feat_group_def(S390FeatGroup group)
{
    return &s390_feature_groups[group];
}

static void init_groups(void)
{
    int i;

    /* init all bitmaps from gnerated data initially */
    for (i = 0; i < ARRAY_SIZE(s390_feature_groups); i++) {
        s390_init_feat_bitmap(s390_feature_groups[i].init,
                              s390_feature_groups[i].feat);
    }
}

type_init(init_groups)
