/*
 *  Copyright (C) International Business Machines  Corp., 2005
 *  Author(s): Anthony Liguori <aliguori@us.ibm.com>
 *
 *  Copyright (C) Red Hat 2007
 *
 *  Xen Console
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; under version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/cutils.h"
#include <sys/select.h>
#include <termios.h>

#include "qapi/error.h"
#include "system/system.h"
#include "chardev/char-fe.h"
#include "hw/xen/xen-backend.h"
#include "hw/xen/xen-bus-helper.h"
#include "hw/qdev-properties.h"
#include "hw/qdev-properties-system.h"
#include "hw/xen/interface/io/console.h"
#include "hw/xen/interface/io/xs_wire.h"
#include "hw/xen/interface/grant_table.h"
#include "hw/i386/kvm/xen_primary_console.h"
#include "trace.h"

struct buffer {
    uint8_t *data;
    size_t consumed;
    size_t size;
    size_t capacity;
    size_t max_capacity;
};

struct XenConsole {
    struct XenDevice  xendev;  /* must be first */
    XenEventChannel   *event_channel;
    int               dev;
    struct buffer     buffer;
    char              *fe_path;
    unsigned int      ring_ref;
    void              *sring;
    CharBackend       chr;
    int               backlog;
};
typedef struct XenConsole XenConsole;

#define TYPE_XEN_CONSOLE_DEVICE "xen-console"
OBJECT_DECLARE_SIMPLE_TYPE(XenConsole, XEN_CONSOLE_DEVICE)

static bool buffer_append(XenConsole *con)
{
    struct buffer *buffer = &con->buffer;
    XENCONS_RING_IDX cons, prod, size;
    struct xencons_interface *intf = con->sring;

    cons = intf->out_cons;
    prod = intf->out_prod;
    xen_mb();

    size = prod - cons;
    if ((size == 0) || (size > sizeof(intf->out)))
        return false;

    if ((buffer->capacity - buffer->size) < size) {
        buffer->capacity += (size + 1024);
        buffer->data = g_realloc(buffer->data, buffer->capacity);
    }

    while (cons != prod)
        buffer->data[buffer->size++] = intf->out[
            MASK_XENCONS_IDX(cons++, intf->out)];

    xen_mb();
    intf->out_cons = cons;
    xen_device_notify_event_channel(XEN_DEVICE(con), con->event_channel, NULL);

    if (buffer->max_capacity &&
        buffer->size > buffer->max_capacity) {
        /* Discard the middle of the data. */

        size_t over = buffer->size - buffer->max_capacity;
        uint8_t *maxpos = buffer->data + buffer->max_capacity;

        memmove(maxpos - over, maxpos, over);
        buffer->data = g_realloc(buffer->data, buffer->max_capacity);
        buffer->size = buffer->capacity = buffer->max_capacity;

        if (buffer->consumed > buffer->max_capacity - over)
            buffer->consumed = buffer->max_capacity - over;
    }
    return true;
}

static void buffer_advance(struct buffer *buffer, size_t len)
{
    buffer->consumed += len;
    if (buffer->consumed == buffer->size) {
        buffer->consumed = 0;
        buffer->size = 0;
    }
}

static int ring_free_bytes(XenConsole *con)
{
    struct xencons_interface *intf = con->sring;
    XENCONS_RING_IDX cons, prod, space;

    cons = intf->in_cons;
    prod = intf->in_prod;
    xen_mb();

    space = prod - cons;
    if (space > sizeof(intf->in))
        return 0; /* ring is screwed: ignore it */

    return (sizeof(intf->in) - space);
}

static int xencons_can_receive(void *opaque)
{
    XenConsole *con = opaque;
    return ring_free_bytes(con);
}

static void xencons_receive(void *opaque, const uint8_t *buf, int len)
{
    XenConsole *con = opaque;
    struct xencons_interface *intf = con->sring;
    XENCONS_RING_IDX prod;
    int i, max;

    max = ring_free_bytes(con);
    /* The can_receive() func limits this, but check again anyway */
    if (max < len)
        len = max;

    prod = intf->in_prod;
    for (i = 0; i < len; i++) {
        intf->in[MASK_XENCONS_IDX(prod++, intf->in)] =
            buf[i];
    }
    xen_wmb();
    intf->in_prod = prod;
    xen_device_notify_event_channel(XEN_DEVICE(con), con->event_channel, NULL);
}

static bool xencons_send(XenConsole *con)
{
    ssize_t len, size;

    size = con->buffer.size - con->buffer.consumed;
    if (qemu_chr_fe_backend_connected(&con->chr)) {
        len = qemu_chr_fe_write(&con->chr,
                                con->buffer.data + con->buffer.consumed,
                                size);
    } else {
        len = size;
    }
    if (len < 1) {
        if (!con->backlog) {
            con->backlog = 1;
        }
    } else {
        buffer_advance(&con->buffer, len);
        if (con->backlog && len == size) {
            con->backlog = 0;
        }
    }
    return len > 0;
}

/* -------------------------------------------------------------------- */

static bool con_event(void *_xendev)
{
    XenConsole *con = XEN_CONSOLE_DEVICE(_xendev);
    bool done_something;

    if (xen_device_backend_get_state(&con->xendev) != XenbusStateConnected) {
        return false;
    }

    done_something = buffer_append(con);

    if (con->buffer.size - con->buffer.consumed) {
        done_something |= xencons_send(con);
    }
    return done_something;
}

/* -------------------------------------------------------------------- */

static bool xen_console_connect(XenDevice *xendev, Error **errp)
{
    ERRP_GUARD();
    XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
    unsigned int port, limit;

    if (xen_device_frontend_scanf(xendev, "ring-ref", "%u",
                                  &con->ring_ref) != 1) {
        error_setg(errp, "failed to read ring-ref");
        return false;
    }

    if (xen_device_frontend_scanf(xendev, "port", "%u", &port) != 1) {
        error_setg(errp, "failed to read remote port");
        return false;
    }

    if (xen_device_frontend_scanf(xendev, "limit", "%u", &limit) == 1) {
        con->buffer.max_capacity = limit;
    }

    con->event_channel = xen_device_bind_event_channel(xendev, port,
                                                       con_event,
                                                       con,
                                                       errp);
    if (!con->event_channel) {
        return false;
    }

    switch (con->dev) {
    case 0:
        /*
         * The primary console is special. For real Xen the ring-ref is
         * actually a GFN which needs to be mapped as foreignmem.
         */
        if (xen_mode != XEN_EMULATE) {
            xen_pfn_t mfn = (xen_pfn_t)con->ring_ref;
            con->sring = qemu_xen_foreignmem_map(xendev->frontend_id, NULL,
                                                 PROT_READ | PROT_WRITE,
                                                 1, &mfn, NULL);
            if (!con->sring) {
                error_setg(errp, "failed to map console page");
                return false;
            }
            break;
        }

        /*
         * For Xen emulation, we still follow the convention of ring-ref
         * holding the GFN, but we map the fixed GNTTAB_RESERVED_CONSOLE
         * grant ref because there is no implementation of foreignmem
         * operations for emulated mode. The emulation code which handles
         * the guest-side page and event channel also needs to be informed
         * of the backend event channel port, in order to reconnect to it
         * after a soft reset.
         */
        xen_primary_console_set_be_port(
            xen_event_channel_get_local_port(con->event_channel));
        con->ring_ref = GNTTAB_RESERVED_CONSOLE;
        /* fallthrough */
    default:
        con->sring = xen_device_map_grant_refs(xendev,
                                               &con->ring_ref, 1,
                                               PROT_READ | PROT_WRITE,
                                               errp);
        if (!con->sring) {
            error_prepend(errp, "failed to map console grant ref: ");
            return false;
        }
        break;
    }

    trace_xen_console_connect(con->dev, con->ring_ref, port,
                              con->buffer.max_capacity);

    qemu_chr_fe_set_handlers(&con->chr, xencons_can_receive,
                             xencons_receive, NULL, NULL, con, NULL,
                             true);
    return true;
}

static void xen_console_disconnect(XenDevice *xendev, Error **errp)
{
    XenConsole *con = XEN_CONSOLE_DEVICE(xendev);

    trace_xen_console_disconnect(con->dev);

    qemu_chr_fe_set_handlers(&con->chr, NULL, NULL, NULL, NULL,
                             con, NULL, true);

    if (con->event_channel) {
        xen_device_unbind_event_channel(xendev, con->event_channel,
                                        errp);
        con->event_channel = NULL;

        if (xen_mode == XEN_EMULATE && !con->dev) {
            xen_primary_console_set_be_port(0);
        }
    }

    if (con->sring) {
        if (!con->dev && xen_mode != XEN_EMULATE) {
            qemu_xen_foreignmem_unmap(con->sring, 1);
        } else {
            xen_device_unmap_grant_refs(xendev, con->sring,
                                        &con->ring_ref, 1, errp);
        }
        con->sring = NULL;
    }
}

static void xen_console_frontend_changed(XenDevice *xendev,
                                         enum xenbus_state frontend_state,
                                         Error **errp)
{
    ERRP_GUARD();
    enum xenbus_state backend_state = xen_device_backend_get_state(xendev);

    switch (frontend_state) {
    case XenbusStateInitialised:
    case XenbusStateConnected:
        if (backend_state == XenbusStateConnected) {
            break;
        }

        xen_console_disconnect(xendev, errp);
        if (*errp) {
            break;
        }

        if (!xen_console_connect(xendev, errp)) {
            xen_device_backend_set_state(xendev, XenbusStateClosing);
            break;
        }

        xen_device_backend_set_state(xendev, XenbusStateConnected);
        break;

    case XenbusStateClosing:
        xen_device_backend_set_state(xendev, XenbusStateClosing);
        break;

    case XenbusStateClosed:
    case XenbusStateUnknown:
        xen_console_disconnect(xendev, errp);
        if (*errp) {
            break;
        }

        xen_device_backend_set_state(xendev, XenbusStateClosed);
        break;

    default:
        break;
    }
}

static char *xen_console_get_name(XenDevice *xendev, Error **errp)
{
    XenConsole *con = XEN_CONSOLE_DEVICE(xendev);

    if (con->dev == -1) {
        XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
        char fe_path[XENSTORE_ABS_PATH_MAX + 1];
        int idx = (xen_mode == XEN_EMULATE) ? 0 : 1;
        char *value;

        /* Theoretically we could go up to INT_MAX here but that's overkill */
        while (idx < 100) {
            if (!idx) {
                snprintf(fe_path, sizeof(fe_path),
                         "/local/domain/%u/console", xendev->frontend_id);
            } else {
                snprintf(fe_path, sizeof(fe_path),
                         "/local/domain/%u/device/console/%u",
                         xendev->frontend_id, idx);
            }
            value = qemu_xen_xs_read(xenbus->xsh, XBT_NULL, fe_path, NULL);
            if (!value) {
                if (errno == ENOENT) {
                    con->dev = idx;
                    goto found;
                }
                error_setg(errp, "cannot read %s: %s", fe_path,
                           strerror(errno));
                return NULL;
            }
            free(value);
            idx++;
        }
        error_setg(errp, "cannot find device index for console device");
        return NULL;
    }
 found:
    return g_strdup_printf("%u", con->dev);
}

static void xen_console_unrealize(XenDevice *xendev)
{
    XenConsole *con = XEN_CONSOLE_DEVICE(xendev);

    trace_xen_console_unrealize(con->dev);

    /* Disconnect from the frontend in case this has not already happened */
    xen_console_disconnect(xendev, NULL);

    qemu_chr_fe_deinit(&con->chr, false);
}

static void xen_console_realize(XenDevice *xendev, Error **errp)
{
    ERRP_GUARD();
    XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
    Chardev *cs = qemu_chr_fe_get_driver(&con->chr);
    unsigned int u;

    if (!cs) {
        error_setg(errp, "no backing character device");
        return;
    }

    if (con->dev == -1) {
        error_setg(errp, "no device index provided");
        return;
    }

    /*
     * The Xen primary console is special. The ring-ref is actually a GFN to
     * be mapped directly as foreignmem (not a grant ref), and the guest port
     * was allocated *for* the guest by the toolstack. The guest gets these
     * through HVMOP_get_param and can use the console long before it's got
     * XenStore up and running. We cannot create those for a true Xen guest,
     * but we can for Xen emulation.
     */
    if (!con->dev) {
        if (xen_mode == XEN_EMULATE) {
            xen_primary_console_create();
        } else if (xen_device_frontend_scanf(xendev, "ring-ref", "%u", &u)
                   != 1 ||
                   xen_device_frontend_scanf(xendev, "port", "%u", &u) != 1) {
            error_setg(errp, "cannot create primary Xen console");
            return;
        }
    }

    trace_xen_console_realize(con->dev, object_get_typename(OBJECT(cs)));

    if (CHARDEV_IS_PTY(cs)) {
        /* Strip the leading 'pty:' */
        xen_device_frontend_printf(xendev, "tty", "%s", cs->filename + 4);
    }

    /* No normal PV driver initialization for the primary console under Xen */
    if (!con->dev && xen_mode != XEN_EMULATE) {
        xen_console_connect(xendev, errp);
    }
}

static char *console_frontend_path(struct qemu_xs_handle *xenstore,
                                   unsigned int dom_id, unsigned int dev)
{
    if (!dev) {
        return g_strdup_printf("/local/domain/%u/console", dom_id);
    } else {
        return g_strdup_printf("/local/domain/%u/device/console/%u", dom_id,
                               dev);
    }
}

static char *xen_console_get_frontend_path(XenDevice *xendev, Error **errp)
{
    XenConsole *con = XEN_CONSOLE_DEVICE(xendev);
    XenBus *xenbus = XEN_BUS(qdev_get_parent_bus(DEVICE(xendev)));
    char *ret = console_frontend_path(xenbus->xsh, xendev->frontend_id,
                                      con->dev);

    if (!ret) {
        error_setg(errp, "failed to create frontend path");
    }
    return ret;
}


static const Property xen_console_properties[] = {
    DEFINE_PROP_CHR("chardev", XenConsole, chr),
    DEFINE_PROP_INT32("idx", XenConsole, dev, -1),
};

static void xen_console_class_init(ObjectClass *class, void *data)
{
    DeviceClass *dev_class = DEVICE_CLASS(class);
    XenDeviceClass *xendev_class = XEN_DEVICE_CLASS(class);

    xendev_class->backend = "console";
    xendev_class->device = "console";
    xendev_class->get_name = xen_console_get_name;
    xendev_class->realize = xen_console_realize;
    xendev_class->frontend_changed = xen_console_frontend_changed;
    xendev_class->unrealize = xen_console_unrealize;
    xendev_class->get_frontend_path = xen_console_get_frontend_path;

    device_class_set_props(dev_class, xen_console_properties);
}

static const TypeInfo xen_console_type_info = {
    .name = TYPE_XEN_CONSOLE_DEVICE,
    .parent = TYPE_XEN_DEVICE,
    .instance_size = sizeof(XenConsole),
    .class_init = xen_console_class_init,
};

static void xen_console_register_types(void)
{
    type_register_static(&xen_console_type_info);
}

type_init(xen_console_register_types)

/* Called to instantiate a XenConsole when the backend is detected. */
static void xen_console_device_create(XenBackendInstance *backend,
                                      QDict *opts, Error **errp)
{
    ERRP_GUARD();
    XenBus *xenbus = xen_backend_get_bus(backend);
    const char *name = xen_backend_get_name(backend);
    unsigned long number;
    char *fe = NULL, *type = NULL, *output = NULL;
    char label[32];
    XenDevice *xendev = NULL;
    XenConsole *con;
    Chardev *cd = NULL;
    struct qemu_xs_handle *xsh = xenbus->xsh;

    if (qemu_strtoul(name, NULL, 10, &number) || number > INT_MAX) {
        error_setg(errp, "failed to parse name '%s'", name);
        goto fail;
    }

    trace_xen_console_device_create(number);

    fe = console_frontend_path(xsh, xen_domid, number);
    if (fe == NULL) {
        error_setg(errp, "failed to generate frontend path");
        goto fail;
    }

    if (xs_node_scanf(xsh, XBT_NULL, fe, "type", errp, "%ms", &type) != 1) {
        error_prepend(errp, "failed to read console device type: ");
        goto fail;
    }

    if (strcmp(type, "ioemu")) {
        error_setg(errp, "declining to handle console type '%s'",
                   type);
        goto fail;
    }

    xendev = XEN_DEVICE(qdev_new(TYPE_XEN_CONSOLE_DEVICE));
    con = XEN_CONSOLE_DEVICE(xendev);

    con->dev = number;

    snprintf(label, sizeof(label), "xencons%ld", number);

    if (xs_node_scanf(xsh, XBT_NULL, fe, "output", NULL, "%ms", &output) == 1) {
        /*
         * FIXME: sure we want to support implicit
         * muxed monitors here?
         */
        cd = qemu_chr_new_mux_mon(label, output, NULL);
        if (!cd) {
            error_setg(errp, "console: No valid chardev found at '%s': ",
                       output);
            goto fail;
        }
    } else if (number) {
        cd = serial_hd(number);
        if (!cd) {
            error_prepend(errp, "console: No serial device #%ld found: ",
                          number);
            goto fail;
        }
    } else {
        /* No 'output' node on primary console: use null. */
        cd = qemu_chr_new(label, "null", NULL);
        if (!cd) {
            error_setg(errp, "console: failed to create null device");
            goto fail;
        }
    }

    if (!qemu_chr_fe_init(&con->chr, cd, errp)) {
        error_prepend(errp, "console: failed to initialize backing chardev: ");
        goto fail;
    }

    if (qdev_realize_and_unref(DEVICE(xendev), BUS(xenbus), errp)) {
        xen_backend_set_device(backend, xendev);
        goto done;
    }

    error_prepend(errp, "realization of console device %lu failed: ",
                  number);

 fail:
    if (xendev) {
        object_unparent(OBJECT(xendev));
    }
 done:
    g_free(fe);
    free(type);
    free(output);
}

static void xen_console_device_destroy(XenBackendInstance *backend,
                                       Error **errp)
{
    ERRP_GUARD();
    XenDevice *xendev = xen_backend_get_device(backend);
    XenConsole *con = XEN_CONSOLE_DEVICE(xendev);

    trace_xen_console_device_destroy(con->dev);

    object_unparent(OBJECT(xendev));
}

static const XenBackendInfo xen_console_backend_info  = {
    .type = "console",
    .create = xen_console_device_create,
    .destroy = xen_console_device_destroy,
};

static void xen_console_register_backend(void)
{
    xen_backend_register(&xen_console_backend_info);
}

xen_backend_init(xen_console_register_backend);
