/*
 * Vhost-user GPIO virtio device
 *
 * Copyright (c) 2022 Viresh Kumar <viresh.kumar@linaro.org>
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "hw/qdev-properties.h"
#include "hw/virtio/virtio-bus.h"
#include "hw/virtio/vhost-user-gpio.h"
#include "qemu/error-report.h"
#include "standard-headers/linux/virtio_ids.h"
#include "trace.h"

#define VHOST_NVQS 2

/* Features required from VirtIO */
static const int feature_bits[] = {
    VIRTIO_F_VERSION_1,
    VIRTIO_F_NOTIFY_ON_EMPTY,
    VIRTIO_RING_F_INDIRECT_DESC,
    VIRTIO_RING_F_EVENT_IDX,
    VIRTIO_GPIO_F_IRQ,
    VIRTIO_F_RING_RESET,
    VHOST_INVALID_FEATURE_BIT
};

static void vu_gpio_get_config(VirtIODevice *vdev, uint8_t *config)
{
    VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);

    memcpy(config, &gpio->config, sizeof(gpio->config));
}

static int vu_gpio_config_notifier(struct vhost_dev *dev)
{
    VHostUserGPIO *gpio = VHOST_USER_GPIO(dev->vdev);

    memcpy(dev->vdev->config, &gpio->config, sizeof(gpio->config));
    virtio_notify_config(dev->vdev);

    return 0;
}

const VhostDevConfigOps gpio_ops = {
    .vhost_dev_config_notifier = vu_gpio_config_notifier,
};

static int vu_gpio_start(VirtIODevice *vdev)
{
    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
    VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
    struct vhost_dev *vhost_dev = &gpio->vhost_dev;
    int ret, i;

    if (!k->set_guest_notifiers) {
        error_report("binding does not support guest notifiers");
        return -ENOSYS;
    }

    ret = vhost_dev_enable_notifiers(vhost_dev, vdev);
    if (ret < 0) {
        error_report("Error enabling host notifiers: %d", ret);
        return ret;
    }

    ret = k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, true);
    if (ret < 0) {
        error_report("Error binding guest notifier: %d", ret);
        goto err_host_notifiers;
    }

    /*
     * Before we start up we need to ensure we have the final feature
     * set needed for the vhost configuration. The backend may also
     * apply backend_features when the feature set is sent.
     */
    vhost_ack_features(&gpio->vhost_dev, feature_bits, vdev->guest_features);

    ret = vhost_dev_start(&gpio->vhost_dev, vdev, false);
    if (ret < 0) {
        error_report("Error starting vhost-user-gpio: %d", ret);
        goto err_guest_notifiers;
    }
    gpio->started_vu = true;

    /*
     * guest_notifier_mask/pending not used yet, so just unmask
     * everything here. virtio-pci will do the right thing by
     * enabling/disabling irqfd.
     */
    for (i = 0; i < gpio->vhost_dev.nvqs; i++) {
        vhost_virtqueue_mask(&gpio->vhost_dev, vdev, i, false);
    }

    /*
     * As we must have VHOST_USER_F_PROTOCOL_FEATURES (because
     * VHOST_USER_GET_CONFIG requires it) we need to explicitly enable
     * the vrings.
     */
    g_assert(vhost_dev->vhost_ops &&
             vhost_dev->vhost_ops->vhost_set_vring_enable);
    ret = vhost_dev->vhost_ops->vhost_set_vring_enable(vhost_dev, true);
    if (ret == 0) {
        return 0;
    }

    error_report("Failed to start vrings for vhost-user-gpio: %d", ret);

err_guest_notifiers:
    k->set_guest_notifiers(qbus->parent, gpio->vhost_dev.nvqs, false);
err_host_notifiers:
    vhost_dev_disable_notifiers(&gpio->vhost_dev, vdev);

    return ret;
}

static void vu_gpio_stop(VirtIODevice *vdev)
{
    VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
    BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
    VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
    struct vhost_dev *vhost_dev = &gpio->vhost_dev;
    int ret;

    if (!gpio->started_vu) {
        return;
    }
    gpio->started_vu = false;

    if (!k->set_guest_notifiers) {
        return;
    }

    vhost_dev_stop(vhost_dev, vdev, false);

    ret = k->set_guest_notifiers(qbus->parent, vhost_dev->nvqs, false);
    if (ret < 0) {
        error_report("vhost guest notifier cleanup failed: %d", ret);
        return;
    }

    vhost_dev_disable_notifiers(vhost_dev, vdev);
}

static void vu_gpio_set_status(VirtIODevice *vdev, uint8_t status)
{
    VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
    bool should_start = virtio_device_should_start(vdev, status);

    trace_virtio_gpio_set_status(status);

    if (!gpio->connected) {
        return;
    }

    if (vhost_dev_is_started(&gpio->vhost_dev) == should_start) {
        return;
    }

    if (should_start) {
        if (vu_gpio_start(vdev)) {
            qemu_chr_fe_disconnect(&gpio->chardev);
        }
    } else {
        vu_gpio_stop(vdev);
    }
}

static uint64_t vu_gpio_get_features(VirtIODevice *vdev, uint64_t features,
                                     Error **errp)
{
    VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);

    return vhost_get_features(&gpio->vhost_dev, feature_bits, features);
}

static void vu_gpio_handle_output(VirtIODevice *vdev, VirtQueue *vq)
{
    /*
     * Not normally called; it's the daemon that handles the queue;
     * however virtio's cleanup path can call this.
     */
}

static void vu_gpio_guest_notifier_mask(VirtIODevice *vdev, int idx, bool mask)
{
    VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);

    /*
     * Add the check for configure interrupt, Use VIRTIO_CONFIG_IRQ_IDX -1
     * as the macro of configure interrupt's IDX, If this driver does not
     * support, the function will return
     */

    if (idx == VIRTIO_CONFIG_IRQ_IDX) {
        return;
    }

    vhost_virtqueue_mask(&gpio->vhost_dev, vdev, idx, mask);
}

static struct vhost_dev *vu_gpio_get_vhost(VirtIODevice *vdev)
{
    VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
    return &gpio->vhost_dev;
}

static void do_vhost_user_cleanup(VirtIODevice *vdev, VHostUserGPIO *gpio)
{
    virtio_delete_queue(gpio->command_vq);
    virtio_delete_queue(gpio->interrupt_vq);
    g_free(gpio->vhost_vqs);
    virtio_cleanup(vdev);
    vhost_user_cleanup(&gpio->vhost_user);
}

static int vu_gpio_connect(DeviceState *dev, Error **errp)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
    struct vhost_dev *vhost_dev = &gpio->vhost_dev;
    int ret;

    if (gpio->connected) {
        return 0;
    }

    vhost_dev_set_config_notifier(vhost_dev, &gpio_ops);
    gpio->vhost_user.supports_config = true;

    gpio->vhost_dev.nvqs = VHOST_NVQS;
    gpio->vhost_dev.vqs = gpio->vhost_vqs;

    ret = vhost_dev_init(vhost_dev, &gpio->vhost_user,
                         VHOST_BACKEND_TYPE_USER, 0, errp);
    if (ret < 0) {
        return ret;
    }

    gpio->connected = true;

    /* restore vhost state */
    if (virtio_device_started(vdev, vdev->status)) {
        vu_gpio_start(vdev);
    }

    return 0;
}

static void vu_gpio_event(void *opaque, QEMUChrEvent event);

static void vu_gpio_disconnect(DeviceState *dev)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);

    if (!gpio->connected) {
        return;
    }
    gpio->connected = false;

    vu_gpio_stop(vdev);
    vhost_dev_cleanup(&gpio->vhost_dev);

    /* Re-instate the event handler for new connections */
    qemu_chr_fe_set_handlers(&gpio->chardev,
                             NULL, NULL, vu_gpio_event,
                             NULL, dev, NULL, true);
}

static void vu_gpio_event(void *opaque, QEMUChrEvent event)
{
    DeviceState *dev = opaque;
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VHostUserGPIO *gpio = VHOST_USER_GPIO(vdev);
    Error *local_err = NULL;

    switch (event) {
    case CHR_EVENT_OPENED:
        if (vu_gpio_connect(dev, &local_err) < 0) {
            qemu_chr_fe_disconnect(&gpio->chardev);
            return;
        }
        break;
    case CHR_EVENT_CLOSED:
        /* defer close until later to avoid circular close */
        vhost_user_async_close(dev, &gpio->chardev, &gpio->vhost_dev,
                               vu_gpio_disconnect, vu_gpio_event);
        break;
    case CHR_EVENT_BREAK:
    case CHR_EVENT_MUX_IN:
    case CHR_EVENT_MUX_OUT:
        /* Ignore */
        break;
    }
}

static int vu_gpio_realize_connect(VHostUserGPIO *gpio, Error **errp)
{
    VirtIODevice *vdev = &gpio->parent_obj;
    DeviceState *dev = &vdev->parent_obj;
    struct vhost_dev *vhost_dev = &gpio->vhost_dev;
    int ret;

    ret = qemu_chr_fe_wait_connected(&gpio->chardev, errp);
    if (ret < 0) {
        return ret;
    }

    /*
     * vu_gpio_connect() may have already connected (via the event
     * callback) in which case it will just report success.
     */
    ret = vu_gpio_connect(dev, errp);
    if (ret < 0) {
        qemu_chr_fe_disconnect(&gpio->chardev);
        return ret;
    }
    g_assert(gpio->connected);

    ret = vhost_dev_get_config(vhost_dev, (uint8_t *)&gpio->config,
                               sizeof(gpio->config), errp);

    if (ret < 0) {
        error_report("vhost-user-gpio: get config failed");

        qemu_chr_fe_disconnect(&gpio->chardev);
        vhost_dev_cleanup(vhost_dev);
        return ret;
    }

    return 0;
}

static void vu_gpio_device_realize(DeviceState *dev, Error **errp)
{
    ERRP_GUARD();

    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VHostUserGPIO *gpio = VHOST_USER_GPIO(dev);
    int retries, ret;

    if (!gpio->chardev.chr) {
        error_setg(errp, "vhost-user-gpio: chardev is mandatory");
        return;
    }

    if (!vhost_user_init(&gpio->vhost_user, &gpio->chardev, errp)) {
        return;
    }

    virtio_init(vdev, VIRTIO_ID_GPIO, sizeof(gpio->config));

    gpio->command_vq = virtio_add_queue(vdev, 256, vu_gpio_handle_output);
    gpio->interrupt_vq = virtio_add_queue(vdev, 256, vu_gpio_handle_output);
    gpio->vhost_vqs = g_new0(struct vhost_virtqueue, VHOST_NVQS);

    gpio->connected = false;

    qemu_chr_fe_set_handlers(&gpio->chardev, NULL, NULL, vu_gpio_event, NULL,
                             dev, NULL, true);

    retries = VU_REALIZE_CONN_RETRIES;
    g_assert(!*errp);
    do {
        if (*errp) {
            error_prepend(errp, "Reconnecting after error: ");
            error_report_err(*errp);
            *errp = NULL;
        }
        ret = vu_gpio_realize_connect(gpio, errp);
    } while (ret < 0 && retries--);

    if (ret < 0) {
        do_vhost_user_cleanup(vdev, gpio);
    }

    return;
}

static void vu_gpio_device_unrealize(DeviceState *dev)
{
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VHostUserGPIO *gpio = VHOST_USER_GPIO(dev);

    vu_gpio_set_status(vdev, 0);
    qemu_chr_fe_set_handlers(&gpio->chardev, NULL, NULL, NULL, NULL, NULL, NULL,
                             false);
    vhost_dev_cleanup(&gpio->vhost_dev);
    do_vhost_user_cleanup(vdev, gpio);
}

static const VMStateDescription vu_gpio_vmstate = {
    .name = "vhost-user-gpio",
    .unmigratable = 1,
};

static Property vu_gpio_properties[] = {
    DEFINE_PROP_CHR("chardev", VHostUserGPIO, chardev),
    DEFINE_PROP_END_OF_LIST(),
};

static void vu_gpio_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

    device_class_set_props(dc, vu_gpio_properties);
    dc->vmsd = &vu_gpio_vmstate;
    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
    vdc->realize = vu_gpio_device_realize;
    vdc->unrealize = vu_gpio_device_unrealize;
    vdc->get_features = vu_gpio_get_features;
    vdc->get_config = vu_gpio_get_config;
    vdc->set_status = vu_gpio_set_status;
    vdc->guest_notifier_mask = vu_gpio_guest_notifier_mask;
    vdc->get_vhost = vu_gpio_get_vhost;
}

static const TypeInfo vu_gpio_info = {
    .name = TYPE_VHOST_USER_GPIO,
    .parent = TYPE_VIRTIO_DEVICE,
    .instance_size = sizeof(VHostUserGPIO),
    .class_init = vu_gpio_class_init,
};

static void vu_gpio_register_types(void)
{
    type_register_static(&vu_gpio_info);
}

type_init(vu_gpio_register_types)
