/*
 * QEMU S390x floating interrupt controller (flic)
 *
 * Copyright 2014 IBM Corp.
 * Author(s): Jens Freimann <jfrei@linux.vnet.ibm.com>
 *            Cornelia Huck <cornelia.huck@de.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 "qemu/error-report.h"
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "hw/sysbus.h"
#include "hw/s390x/ioinst.h"
#include "hw/s390x/s390_flic.h"
#include "hw/qdev-properties.h"
#include "hw/s390x/css.h"
#include "trace.h"
#include "qapi/error.h"
#include "hw/s390x/s390-virtio-ccw.h"

S390FLICStateClass *s390_get_flic_class(S390FLICState *fs)
{
    static S390FLICStateClass *class;

    if (!class) {
        /* we only have one flic device, so this is fine to cache */
        class = S390_FLIC_COMMON_GET_CLASS(fs);
    }
    return class;
}

QEMUS390FLICState *s390_get_qemu_flic(S390FLICState *fs)
{
    static QEMUS390FLICState *flic;

    if (!flic) {
        /* we only have one flic device, so this is fine to cache */
        flic = QEMU_S390_FLIC(fs);
    }
    return flic;
}

S390FLICState *s390_get_flic(void)
{
    static S390FLICState *fs;

    if (!fs) {
        fs = S390_FLIC_COMMON(object_resolve_path_type("",
                                                       TYPE_S390_FLIC_COMMON,
                                                       NULL));
    }
    return fs;
}

void s390_flic_init(void)
{
    DeviceState *dev;

    if (kvm_enabled()) {
        dev = qdev_new(TYPE_KVM_S390_FLIC);
        object_property_add_child(qdev_get_machine(), TYPE_KVM_S390_FLIC,
                                  OBJECT(dev));
    } else {
        dev = qdev_new(TYPE_QEMU_S390_FLIC);
        object_property_add_child(qdev_get_machine(), TYPE_QEMU_S390_FLIC,
                                  OBJECT(dev));
    }
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
}

static int qemu_s390_register_io_adapter(S390FLICState *fs, uint32_t id,
                                         uint8_t isc, bool swap,
                                         bool is_maskable, uint8_t flags)
{
    /* nothing to do */
    return 0;
}

static int qemu_s390_io_adapter_map(S390FLICState *fs, uint32_t id,
                                    uint64_t map_addr, bool do_map)
{
    /* nothing to do */
    return 0;
}

static int qemu_s390_add_adapter_routes(S390FLICState *fs,
                                        AdapterRoutes *routes)
{
    return -ENOSYS;
}

static void qemu_s390_release_adapter_routes(S390FLICState *fs,
                                             AdapterRoutes *routes)
{
}

static int qemu_s390_clear_io_flic(S390FLICState *fs, uint16_t subchannel_id,
                           uint16_t subchannel_nr)
{
    QEMUS390FLICState *flic  = s390_get_qemu_flic(fs);
    QEMUS390FlicIO *cur, *next;
    uint8_t isc;

    g_assert(qemu_mutex_iothread_locked());
    if (!(flic->pending & FLIC_PENDING_IO)) {
        return 0;
    }

    /* check all iscs */
    for (isc = 0; isc < 8; isc++) {
        if (QLIST_EMPTY(&flic->io[isc])) {
            continue;
        }

        /* search and delete any matching one */
        QLIST_FOREACH_SAFE(cur, &flic->io[isc], next, next) {
            if (cur->id == subchannel_id && cur->nr == subchannel_nr) {
                QLIST_REMOVE(cur, next);
                g_free(cur);
            }
        }

        /* update our indicator bit */
        if (QLIST_EMPTY(&flic->io[isc])) {
            flic->pending &= ~ISC_TO_PENDING_IO(isc);
        }
    }
    return 0;
}

static int qemu_s390_modify_ais_mode(S390FLICState *fs, uint8_t isc,
                                     uint16_t mode)
{
    QEMUS390FLICState *flic  = s390_get_qemu_flic(fs);

    switch (mode) {
    case SIC_IRQ_MODE_ALL:
        flic->simm &= ~AIS_MODE_MASK(isc);
        flic->nimm &= ~AIS_MODE_MASK(isc);
        break;
    case SIC_IRQ_MODE_SINGLE:
        flic->simm |= AIS_MODE_MASK(isc);
        flic->nimm &= ~AIS_MODE_MASK(isc);
        break;
    default:
        return -EINVAL;
    }

    return 0;
}

static int qemu_s390_inject_airq(S390FLICState *fs, uint8_t type,
                                 uint8_t isc, uint8_t flags)
{
    QEMUS390FLICState *flic = s390_get_qemu_flic(fs);
    S390FLICStateClass *fsc = s390_get_flic_class(fs);
    bool flag = flags & S390_ADAPTER_SUPPRESSIBLE;
    uint32_t io_int_word = (isc << 27) | IO_INT_WORD_AI;

    if (flag && (flic->nimm & AIS_MODE_MASK(isc))) {
        trace_qemu_s390_airq_suppressed(type, isc);
        return 0;
    }

    fsc->inject_io(fs, 0, 0, 0, io_int_word);

    if (flag && (flic->simm & AIS_MODE_MASK(isc))) {
        flic->nimm |= AIS_MODE_MASK(isc);
        trace_qemu_s390_suppress_airq(isc, "Single-Interruption Mode",
                                      "NO-Interruptions Mode");
    }

    return 0;
}

static void qemu_s390_flic_notify(uint32_t type)
{
    CPUState *cs;

    /*
     * We have to make all CPUs see CPU_INTERRUPT_HARD, so they might
     * consider it. We will kick all running CPUs and only relevant
     * sleeping ones.
     */
    CPU_FOREACH(cs) {
        S390CPU *cpu = S390_CPU(cs);

        cs->interrupt_request |= CPU_INTERRUPT_HARD;

        /* ignore CPUs that are not sleeping */
        if (s390_cpu_get_state(cpu) != S390_CPU_STATE_OPERATING &&
            s390_cpu_get_state(cpu) != S390_CPU_STATE_LOAD) {
            continue;
        }

        /* we always kick running CPUs for now, this is tricky */
        if (cs->halted) {
            /* don't check for subclasses, CPUs double check when waking up */
            if (type & FLIC_PENDING_SERVICE) {
                if (!(cpu->env.psw.mask & PSW_MASK_EXT)) {
                    continue;
                }
            } else if (type & FLIC_PENDING_IO) {
                if (!(cpu->env.psw.mask & PSW_MASK_IO)) {
                    continue;
                }
            } else if (type & FLIC_PENDING_MCHK_CR) {
                if (!(cpu->env.psw.mask & PSW_MASK_MCHECK)) {
                    continue;
                }
            }
        }
        cpu_interrupt(cs, CPU_INTERRUPT_HARD);
    }
}

uint32_t qemu_s390_flic_dequeue_service(QEMUS390FLICState *flic)
{
    uint32_t tmp;

    g_assert(qemu_mutex_iothread_locked());
    g_assert(flic->pending & FLIC_PENDING_SERVICE);
    tmp = flic->service_param;
    flic->service_param = 0;
    flic->pending &= ~FLIC_PENDING_SERVICE;

    return tmp;
}

/* caller has to free the returned object */
QEMUS390FlicIO *qemu_s390_flic_dequeue_io(QEMUS390FLICState *flic, uint64_t cr6)
{
    QEMUS390FlicIO *io;
    uint8_t isc;

    g_assert(qemu_mutex_iothread_locked());
    if (!(flic->pending & CR6_TO_PENDING_IO(cr6))) {
        return NULL;
    }

    for (isc = 0; isc < 8; isc++) {
        if (QLIST_EMPTY(&flic->io[isc]) || !(cr6 & ISC_TO_ISC_BITS(isc))) {
            continue;
        }
        io = QLIST_FIRST(&flic->io[isc]);
        QLIST_REMOVE(io, next);

        /* update our indicator bit */
        if (QLIST_EMPTY(&flic->io[isc])) {
            flic->pending &= ~ISC_TO_PENDING_IO(isc);
        }
        return io;
    }

    return NULL;
}

void qemu_s390_flic_dequeue_crw_mchk(QEMUS390FLICState *flic)
{
    g_assert(qemu_mutex_iothread_locked());
    g_assert(flic->pending & FLIC_PENDING_MCHK_CR);
    flic->pending &= ~FLIC_PENDING_MCHK_CR;
}

static void qemu_s390_inject_service(S390FLICState *fs, uint32_t parm)
{
    QEMUS390FLICState *flic = s390_get_qemu_flic(fs);

    g_assert(qemu_mutex_iothread_locked());
    /* multiplexing is good enough for sclp - kvm does it internally as well */
    flic->service_param |= parm;
    flic->pending |= FLIC_PENDING_SERVICE;

    qemu_s390_flic_notify(FLIC_PENDING_SERVICE);
}

static void qemu_s390_inject_io(S390FLICState *fs, uint16_t subchannel_id,
                                uint16_t subchannel_nr, uint32_t io_int_parm,
                                uint32_t io_int_word)
{
    const uint8_t isc = IO_INT_WORD_ISC(io_int_word);
    QEMUS390FLICState *flic = s390_get_qemu_flic(fs);
    QEMUS390FlicIO *io;

    g_assert(qemu_mutex_iothread_locked());
    io = g_new0(QEMUS390FlicIO, 1);
    io->id = subchannel_id;
    io->nr = subchannel_nr;
    io->parm = io_int_parm;
    io->word = io_int_word;

    QLIST_INSERT_HEAD(&flic->io[isc], io, next);
    flic->pending |= ISC_TO_PENDING_IO(isc);

    qemu_s390_flic_notify(ISC_TO_PENDING_IO(isc));
}

static void qemu_s390_inject_crw_mchk(S390FLICState *fs)
{
    QEMUS390FLICState *flic = s390_get_qemu_flic(fs);

    g_assert(qemu_mutex_iothread_locked());
    flic->pending |= FLIC_PENDING_MCHK_CR;

    qemu_s390_flic_notify(FLIC_PENDING_MCHK_CR);
}

bool qemu_s390_flic_has_service(QEMUS390FLICState *flic)
{
    /* called without lock via cc->has_work, will be validated under lock */
    return !!(flic->pending & FLIC_PENDING_SERVICE);
}

bool qemu_s390_flic_has_io(QEMUS390FLICState *flic, uint64_t cr6)
{
    /* called without lock via cc->has_work, will be validated under lock */
    return !!(flic->pending & CR6_TO_PENDING_IO(cr6));
}

bool qemu_s390_flic_has_crw_mchk(QEMUS390FLICState *flic)
{
    /* called without lock via cc->has_work, will be validated under lock */
    return !!(flic->pending & FLIC_PENDING_MCHK_CR);
}

bool qemu_s390_flic_has_any(QEMUS390FLICState *flic)
{
    g_assert(qemu_mutex_iothread_locked());
    return !!flic->pending;
}

static void qemu_s390_flic_reset(DeviceState *dev)
{
    QEMUS390FLICState *flic = QEMU_S390_FLIC(dev);
    QEMUS390FlicIO *cur, *next;
    int isc;

    g_assert(qemu_mutex_iothread_locked());
    flic->simm = 0;
    flic->nimm = 0;
    flic->pending = 0;

    /* remove all pending io interrupts */
    for (isc = 0; isc < 8; isc++) {
        QLIST_FOREACH_SAFE(cur, &flic->io[isc], next, next) {
            QLIST_REMOVE(cur, next);
            g_free(cur);
        }
    }
}

bool ais_needed(void *opaque)
{
    S390FLICState *s = opaque;

    return s->ais_supported;
}

static const VMStateDescription qemu_s390_flic_vmstate = {
    .name = "qemu-s390-flic",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = ais_needed,
    .fields = (VMStateField[]) {
        VMSTATE_UINT8(simm, QEMUS390FLICState),
        VMSTATE_UINT8(nimm, QEMUS390FLICState),
        VMSTATE_END_OF_LIST()
    }
};

static void qemu_s390_flic_instance_init(Object *obj)
{
    QEMUS390FLICState *flic = QEMU_S390_FLIC(obj);
    int isc;

    for (isc = 0; isc < 8; isc++) {
        QLIST_INIT(&flic->io[isc]);
    }
}

static void qemu_s390_flic_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);
    S390FLICStateClass *fsc = S390_FLIC_COMMON_CLASS(oc);

    dc->reset = qemu_s390_flic_reset;
    dc->vmsd = &qemu_s390_flic_vmstate;
    fsc->register_io_adapter = qemu_s390_register_io_adapter;
    fsc->io_adapter_map = qemu_s390_io_adapter_map;
    fsc->add_adapter_routes = qemu_s390_add_adapter_routes;
    fsc->release_adapter_routes = qemu_s390_release_adapter_routes;
    fsc->clear_io_irq = qemu_s390_clear_io_flic;
    fsc->modify_ais_mode = qemu_s390_modify_ais_mode;
    fsc->inject_airq = qemu_s390_inject_airq;
    fsc->inject_service = qemu_s390_inject_service;
    fsc->inject_io = qemu_s390_inject_io;
    fsc->inject_crw_mchk = qemu_s390_inject_crw_mchk;
}

static Property s390_flic_common_properties[] = {
    DEFINE_PROP_UINT32("adapter_routes_max_batch", S390FLICState,
                       adapter_routes_max_batch, ADAPTER_ROUTES_MAX_GSI),
    DEFINE_PROP_END_OF_LIST(),
};

static void s390_flic_common_realize(DeviceState *dev, Error **errp)
{
    S390FLICState *fs = S390_FLIC_COMMON(dev);
    uint32_t max_batch = fs->adapter_routes_max_batch;

    if (max_batch > ADAPTER_ROUTES_MAX_GSI) {
        error_setg(errp, "flic property adapter_routes_max_batch too big"
                   " (%d > %d)", max_batch, ADAPTER_ROUTES_MAX_GSI);
        return;
    }

    fs->ais_supported = s390_has_feat(S390_FEAT_ADAPTER_INT_SUPPRESSION);
}

static void s390_flic_class_init(ObjectClass *oc, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(oc);

    device_class_set_props(dc, s390_flic_common_properties);
    dc->realize = s390_flic_common_realize;
}

static const TypeInfo qemu_s390_flic_info = {
    .name          = TYPE_QEMU_S390_FLIC,
    .parent        = TYPE_S390_FLIC_COMMON,
    .instance_size = sizeof(QEMUS390FLICState),
    .instance_init = qemu_s390_flic_instance_init,
    .class_init    = qemu_s390_flic_class_init,
};


static const TypeInfo s390_flic_common_info = {
    .name          = TYPE_S390_FLIC_COMMON,
    .parent        = TYPE_SYS_BUS_DEVICE,
    .instance_size = sizeof(S390FLICState),
    .class_init    = s390_flic_class_init,
    .class_size    = sizeof(S390FLICStateClass),
};

static void qemu_s390_flic_register_types(void)
{
    type_register_static(&s390_flic_common_info);
    type_register_static(&qemu_s390_flic_info);
}

type_init(qemu_s390_flic_register_types)

static bool adapter_info_so_needed(void *opaque)
{
    return css_migration_enabled();
}

const VMStateDescription vmstate_adapter_info_so = {
    .name = "s390_adapter_info/summary_offset",
    .version_id = 1,
    .minimum_version_id = 1,
    .needed = adapter_info_so_needed,
    .fields = (VMStateField[]) {
        VMSTATE_UINT32(summary_offset, AdapterInfo),
        VMSTATE_END_OF_LIST()
    }
};

const VMStateDescription vmstate_adapter_info = {
    .name = "s390_adapter_info",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_UINT64(ind_offset, AdapterInfo),
        /*
         * We do not have to migrate neither the id nor the addresses.
         * The id is set by css_register_io_adapter and the addresses
         * are set based on the IndAddr objects after those get mapped.
         */
        VMSTATE_END_OF_LIST()
    },
    .subsections = (const VMStateDescription * []) {
        &vmstate_adapter_info_so,
        NULL
    }
};

const VMStateDescription vmstate_adapter_routes = {

    .name = "s390_adapter_routes",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_STRUCT(adapter, AdapterRoutes, 1, vmstate_adapter_info,
                       AdapterInfo),
        VMSTATE_END_OF_LIST()
    }
};
